{"v":[{"id":639,"html_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/40#issuecomment-639","pull_request_url":"","issue_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/40","user":{"id":1,"login":"charles","login_name":"","source_id":0,"full_name":"Charles Willgren","email":"charles@noreply.www-s01.apinet.com","avatar_url":"https:\/\/www-s01.apinet.com\/codeforge\/avatars\/d3c894f7297c5a18eb3f6ac837c335b11a00aa9cc0961323771632b1e2d61bb2","html_url":"https:\/\/www-s01.apinet.com\/codeforge\/charles","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2025-12-08T10:03:41-06:00","restricted":false,"active":false,"prohibit_login":false,"location":"","pronouns":"","website":"","description":"","visibility":"public","followers_count":0,"following_count":0,"starred_repos_count":0,"username":"charles"},"original_author":"","original_author_id":0,"body":"Closing: the `apiapp\/` Flutter app has been discontinued, so whether to make it a submodule or fold it in is moot. Forms V2 is a web-only build (docs\/FormsV2Plan.md \u00a73.2). The directory is still untracked in this working tree. Archive or delete it on purpose rather than leaving it there by accident.","assets":[],"created_at":"2026-10-01T09:15:05-05:00","updated_at":"2026-10-01T09:15:05-05:00"},{"id":640,"html_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/41#issuecomment-640","pull_request_url":"","issue_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/41","user":{"id":1,"login":"charles","login_name":"","source_id":0,"full_name":"Charles Willgren","email":"charles@noreply.www-s01.apinet.com","avatar_url":"https:\/\/www-s01.apinet.com\/codeforge\/avatars\/d3c894f7297c5a18eb3f6ac837c335b11a00aa9cc0961323771632b1e2d61bb2","html_url":"https:\/\/www-s01.apinet.com\/codeforge\/charles","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2025-12-08T10:03:41-06:00","restricted":false,"active":false,"prohibit_login":false,"location":"","pronouns":"","website":"","description":"","visibility":"public","followers_count":0,"following_count":0,"starred_repos_count":0,"username":"charles"},"original_author":"","original_author_id":0,"body":"Closing: the `apiapp\/` Flutter app has been discontinued, so no Android release build will be made. Forms V2 is a web-only build (docs\/FormsV2Plan.md \u00a73.2). If a native app is ever started again, release signing has to be settled before the first store upload.","assets":[],"created_at":"2026-10-01T09:15:05-05:00","updated_at":"2026-10-01T09:15:05-05:00"},{"id":641,"html_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/42#issuecomment-641","pull_request_url":"","issue_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/42","user":{"id":1,"login":"charles","login_name":"","source_id":0,"full_name":"Charles Willgren","email":"charles@noreply.www-s01.apinet.com","avatar_url":"https:\/\/www-s01.apinet.com\/codeforge\/avatars\/d3c894f7297c5a18eb3f6ac837c335b11a00aa9cc0961323771632b1e2d61bb2","html_url":"https:\/\/www-s01.apinet.com\/codeforge\/charles","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2025-12-08T10:03:41-06:00","restricted":false,"active":false,"prohibit_login":false,"location":"","pronouns":"","website":"","description":"","visibility":"public","followers_count":0,"following_count":0,"starred_repos_count":0,"username":"charles"},"original_author":"","original_author_id":0,"body":"Closing: the `apiapp\/` Flutter app has been discontinued, so there is no native device layer to harden. Forms V2 is a web-only build and online-only (docs\/FormsV2Plan.md \u00a73.2). The findings here are worth re-reading if a native app is ever started again.","assets":[],"created_at":"2026-10-01T09:15:05-05:00","updated_at":"2026-10-01T09:15:05-05:00"},{"id":642,"html_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/43#issuecomment-642","pull_request_url":"","issue_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/43","user":{"id":1,"login":"charles","login_name":"","source_id":0,"full_name":"Charles Willgren","email":"charles@noreply.www-s01.apinet.com","avatar_url":"https:\/\/www-s01.apinet.com\/codeforge\/avatars\/d3c894f7297c5a18eb3f6ac837c335b11a00aa9cc0961323771632b1e2d61bb2","html_url":"https:\/\/www-s01.apinet.com\/codeforge\/charles","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2025-12-08T10:03:41-06:00","restricted":false,"active":false,"prohibit_login":false,"location":"","pronouns":"","website":"","description":"","visibility":"public","followers_count":0,"following_count":0,"starred_repos_count":0,"username":"charles"},"original_author":"","original_author_id":0,"body":"Closing: the `apiapp\/` Flutter app has been discontinued, so there will be no device release for calls or push to be part of. Email and text alerts through the `notify\/*` subscriptions are unaffected. Any app-side call\/push wiring that is still left in this repo can be deleted as dead code.","assets":[],"created_at":"2026-10-01T09:15:05-05:00","updated_at":"2026-10-01T09:15:05-05:00"},{"id":643,"html_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/46#issuecomment-643","pull_request_url":"","issue_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/46","user":{"id":1,"login":"charles","login_name":"","source_id":0,"full_name":"Charles Willgren","email":"charles@noreply.www-s01.apinet.com","avatar_url":"https:\/\/www-s01.apinet.com\/codeforge\/avatars\/d3c894f7297c5a18eb3f6ac837c335b11a00aa9cc0961323771632b1e2d61bb2","html_url":"https:\/\/www-s01.apinet.com\/codeforge\/charles","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2025-12-08T10:03:41-06:00","restricted":false,"active":false,"prohibit_login":false,"location":"","pronouns":"","website":"","description":"","visibility":"public","followers_count":0,"following_count":0,"starred_repos_count":0,"username":"charles"},"original_author":"","original_author_id":0,"body":"Closing: the `apiapp\/` Flutter app has been discontinued, so none of its flavors (H, B or C) will be built. Forms V2 is a web-only build (docs\/FormsV2Plan.md \u00a73.2).","assets":[],"created_at":"2026-10-01T09:15:05-05:00","updated_at":"2026-10-01T09:15:05-05:00"},{"id":644,"html_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/47#issuecomment-644","pull_request_url":"","issue_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/47","user":{"id":1,"login":"charles","login_name":"","source_id":0,"full_name":"Charles Willgren","email":"charles@noreply.www-s01.apinet.com","avatar_url":"https:\/\/www-s01.apinet.com\/codeforge\/avatars\/d3c894f7297c5a18eb3f6ac837c335b11a00aa9cc0961323771632b1e2d61bb2","html_url":"https:\/\/www-s01.apinet.com\/codeforge\/charles","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2025-12-08T10:03:41-06:00","restricted":false,"active":false,"prohibit_login":false,"location":"","pronouns":"","website":"","description":"","visibility":"public","followers_count":0,"following_count":0,"starred_repos_count":0,"username":"charles"},"original_author":"","original_author_id":0,"body":"Closing: the `apiapp\/` Flutter app has been discontinued. Field staff start a visit from the web app (`\/visits-v2`) under Forms V2, so a native home screen is no longer needed.","assets":[],"created_at":"2026-10-01T09:15:05-05:00","updated_at":"2026-10-01T09:15:05-05:00"},{"id":645,"html_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/21#issuecomment-645","pull_request_url":"","issue_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/21","user":{"id":1,"login":"charles","login_name":"","source_id":0,"full_name":"Charles Willgren","email":"charles@noreply.www-s01.apinet.com","avatar_url":"https:\/\/www-s01.apinet.com\/codeforge\/avatars\/d3c894f7297c5a18eb3f6ac837c335b11a00aa9cc0961323771632b1e2d61bb2","html_url":"https:\/\/www-s01.apinet.com\/codeforge\/charles","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2025-12-08T10:03:41-06:00","restricted":false,"active":false,"prohibit_login":false,"location":"","pronouns":"","website":"","description":"","visibility":"public","followers_count":0,"following_count":0,"starred_repos_count":0,"username":"charles"},"original_author":"","original_author_id":0,"body":"Closing: this design depends on the API HHP app, meaning the `apiapp\/` Flutter app (device binding, biometric gate and the prompt UI), and that app has been discontinued. `push` stays out of `AUTH_FACTOR_BUILT`, so the chooser never offers it. If phone approval comes back with a different app, the safety rules above (number matching, rate limit, audited denial, short expiry, the verdict coming only from the device) still apply.","assets":[],"created_at":"2026-10-01T09:15:05-05:00","updated_at":"2026-10-01T09:15:05-05:00"},{"id":646,"html_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/4#issuecomment-646","pull_request_url":"","issue_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/4","user":{"id":1,"login":"charles","login_name":"","source_id":0,"full_name":"Charles Willgren","email":"charles@noreply.www-s01.apinet.com","avatar_url":"https:\/\/www-s01.apinet.com\/codeforge\/avatars\/d3c894f7297c5a18eb3f6ac837c335b11a00aa9cc0961323771632b1e2d61bb2","html_url":"https:\/\/www-s01.apinet.com\/codeforge\/charles","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2025-12-08T10:03:41-06:00","restricted":false,"active":false,"prohibit_login":false,"location":"","pronouns":"","website":"","description":"","visibility":"public","followers_count":0,"following_count":0,"starred_repos_count":0,"username":"charles"},"original_author":"","original_author_id":0,"body":"Closing as superseded by Forms V2. This issue asked for a printable view of a V1 `form_instance`. V2 instead renders each form onto its original paper from a published placement map and keeps the result in the encrypted document store (`code\/form_v2_artifact.inc.php`, docs\/FormsV2Plan.md \u00a79). No V1 visit was ever started for a real client, so a V1 print path would have nothing to print.","assets":[],"created_at":"2026-10-01T09:15:06-05:00","updated_at":"2026-10-01T09:15:06-05:00"},{"id":647,"html_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/55#issuecomment-647","pull_request_url":"","issue_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/55","user":{"id":1,"login":"charles","login_name":"","source_id":0,"full_name":"Charles Willgren","email":"charles@noreply.www-s01.apinet.com","avatar_url":"https:\/\/www-s01.apinet.com\/codeforge\/avatars\/d3c894f7297c5a18eb3f6ac837c335b11a00aa9cc0961323771632b1e2d61bb2","html_url":"https:\/\/www-s01.apinet.com\/codeforge\/charles","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2025-12-08T10:03:41-06:00","restricted":false,"active":false,"prohibit_login":false,"location":"","pronouns":"","website":"","description":"","visibility":"public","followers_count":0,"following_count":0,"starred_repos_count":0,"username":"charles"},"original_author":"","original_author_id":0,"body":"Closing as superseded by Forms V2. Under V2, the form catalogue is the original paper plus a placement map (`docs\/form-placements\/`) and a prepared interview (`docs\/form-v2-interviews\/`), not hand-authored V1 definitions, and page-tagging the ISP for V1 packets no longer unblocks anything. What remains is tracked in docs\/FormsV2Plan.md (\u00a79, and the missing-originals row of its blocker table).","assets":[],"created_at":"2026-10-01T09:15:06-05:00","updated_at":"2026-10-01T09:15:06-05:00"},{"id":658,"html_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/49#issuecomment-658","pull_request_url":"","issue_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/49","user":{"id":1,"login":"charles","login_name":"","source_id":0,"full_name":"Charles Willgren","email":"charles@noreply.www-s01.apinet.com","avatar_url":"https:\/\/www-s01.apinet.com\/codeforge\/avatars\/d3c894f7297c5a18eb3f6ac837c335b11a00aa9cc0961323771632b1e2d61bb2","html_url":"https:\/\/www-s01.apinet.com\/codeforge\/charles","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2025-12-08T10:03:41-06:00","restricted":false,"active":false,"prohibit_login":false,"location":"","pronouns":"","website":"","description":"","visibility":"public","followers_count":0,"following_count":0,"starred_repos_count":0,"username":"charles"},"original_author":"","original_author_id":0,"body":"Fixed 2026-10-01 by retiring the Forms V1 runtime, and by making the guard fail closed.\n\n* **The hole is gone.** Every endpoint that could reach a `fk_hh_member = 0` instance has been deleted: `formSessionAcquire`, `formSync`, `formFile`, `formAmend`, `formSessionRelease`\/`Break`, `formInstanceGet`\/`Answers`\/`Void`, and the rest of the V1 fill, sync and review runtime. Visits are Forms V2 now.\n* **The rule is fixed where it lived.** `hh_member_pk_in_scope()` (`code\/functions_hhm.inc.php`) now returns **false** for a pk of 0 or less. It used to return true. Every V2 caller already refused a zero itself, so V2 behaves the same. `scripts\/test-access-hygiene.php` now asserts this so it cannot quietly flip back.\n* **When staff or HR forms arrive**, a document about somebody who is not a client needs its own scope rule, for example the attendant's once the attendant record (RolesPlan \u00a77) exists. It must not be an exemption in the client rule. CLAUDE.md says so in the Permissions section.\n\nThe V1 tables (`form_instance` and the others) are kept, with any rows in them, and nothing reads them. Dropping them is a separate decision.\n\nStatus: the change is in the working tree and **not yet committed**. It has been applied to the local dev database only. The production deploy steps are in the docs\/Changelog.md entry for 2026-10-01.","assets":[],"created_at":"2026-10-01T09:52:49-05:00","updated_at":"2026-10-01T09:52:49-05:00"},{"id":861,"html_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/76#issuecomment-861","pull_request_url":"","issue_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/76","user":{"id":3,"login":"connect-bot","login_name":"","source_id":0,"full_name":"","email":"connect-bot@noreply.www-s01.apinet.com","avatar_url":"https:\/\/www-s01.apinet.com\/codeforge\/avatars\/68a2723f7ad70dee2e1415be7488d84b","html_url":"https:\/\/www-s01.apinet.com\/codeforge\/connect-bot","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2026-10-01T08:49:35-05:00","restricted":false,"active":false,"prohibit_login":false,"location":"","pronouns":"","website":"","description":"","visibility":"public","followers_count":0,"following_count":0,"starred_repos_count":0,"username":"connect-bot"},"original_author":"","original_author_id":0,"body":"**Charles W.** _(via Connect)_\n<!-- connect:user=1 -->\n\nThis is a test comment.","assets":[{"id":3,"name":"photo-20261001-131430-1.jpg","size":223494,"download_count":4,"created_at":"2026-10-01T13:14:31-05:00","uuid":"fc4ae3b8-8e92-4711-beed-c73428143432","browser_download_url":"https:\/\/www-s01.apinet.com\/codeforge\/attachments\/fc4ae3b8-8e92-4711-beed-c73428143432","type":"attachment"}],"created_at":"2026-10-01T13:14:30-05:00","updated_at":"2026-10-01T13:14:31-05:00"},{"id":866,"html_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/132#issuecomment-866","pull_request_url":"","issue_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/132","user":{"id":1,"login":"charles","login_name":"","source_id":0,"full_name":"Charles Willgren","email":"charles@noreply.www-s01.apinet.com","avatar_url":"https:\/\/www-s01.apinet.com\/codeforge\/avatars\/d3c894f7297c5a18eb3f6ac837c335b11a00aa9cc0961323771632b1e2d61bb2","html_url":"https:\/\/www-s01.apinet.com\/codeforge\/charles","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2025-12-08T10:03:41-06:00","restricted":false,"active":false,"prohibit_login":false,"location":"","pronouns":"","website":"","description":"","visibility":"public","followers_count":0,"following_count":0,"starred_repos_count":0,"username":"charles"},"original_author":"","original_author_id":0,"body":"Done in 6c07bb9: the idle sign-out is now 15 minutes (was 3). It is one constant, `SESSION_IDLE_TIMEOUT` in `code\/functions_auth.inc.php`. The browser countdown reads its remaining time from `\/do\/sessionCheck`, so the \"Stay Signed In\" warning still appears with 1 minute remaining (after 14 minutes of inactivity). The 12-hour absolute limit is unchanged.\n\nTakes effect once deployed. Note: 3 minutes was the documented HIPAA automatic-logoff setting, so any policy document that states 3 minutes should be updated to say 15.","assets":[],"created_at":"2026-10-01T13:45:51-05:00","updated_at":"2026-10-01T13:48:15-05:00"},{"id":874,"html_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/82#issuecomment-874","pull_request_url":"","issue_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/82","user":{"id":1,"login":"charles","login_name":"","source_id":0,"full_name":"Charles Willgren","email":"charles@noreply.www-s01.apinet.com","avatar_url":"https:\/\/www-s01.apinet.com\/codeforge\/avatars\/d3c894f7297c5a18eb3f6ac837c335b11a00aa9cc0961323771632b1e2d61bb2","html_url":"https:\/\/www-s01.apinet.com\/codeforge\/charles","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2025-12-08T10:03:41-06:00","restricted":false,"active":false,"prohibit_login":false,"location":"","pronouns":"","website":"","description":"","visibility":"public","followers_count":0,"following_count":0,"starred_repos_count":0,"username":"charles"},"original_author":"","original_author_id":0,"body":"## Proposal: use a local copy of the NPPES file, not the live API\n\nCMS publishes the whole NPI registry as a free download (https:\/\/download.cms.gov\/nppes\/NPI_Files.html): a **full file each month**, a **weekly update file**, and a **monthly list of deactivated NPIs**. We can load it into our own table and search that table, so a visit never calls out to anything.\n\n**Import** (`scripts\/import-npi.php`, run on a monthly timer, then weekly for updates):\n- Stream the CSV inside the zip. The full file is about 9 GB with 300+ columns, so read it row by row and keep only what we use.\n- Keep **individuals** (entity type 1) whose practice location is in **Texas**, plus **organisations** (entity type 2) with a pharmacy taxonomy (`3336*`), which covers E1 as well.\n- Columns to keep: NPI, last\/first\/middle name, credential, primary taxonomy (shown as specialty), practice address, city, ZIP, phone, fax, deactivation date.\n- Upsert by NPI. Mark deactivated NPIs inactive rather than deleting them, so an old visit still resolves to the doctor it named.\n- New table `npi_provider` via `migrations\/`. It holds only public data, so it is stored in plaintext with no PHI. Index it on (last name, first name) and ZIP.\n\n**Lookup** (`\/do\/npiSearch`, gated like the visit screens):\n- Staff type a last name and optionally a first name, and can narrow by city or ZIP. We return up to about 20 matches showing name, credential, specialty and city. Staff pick one, address and phone fill in, and staff can still edit them.\n- Searching by name alone isn't precise enough for common surnames. Narrowing by city or ZIP fixes that. Defaulting to the client's own ZIP would also work, and it is safe because the search stays on our server.\n- Store the **NPI** with the answer, not just the address text, so we can trace which record was picked.\n\n**Why a download beats the API:** nothing about the client, not even the doctor's name, leaves our server. Production needs no outbound access at visit time. Search speed doesn't depend on CMS being up. The weekly update file keeps us at most a week behind the registry.\n\nThe open question for the customer still applies: if they keep their own list of doctors, we could load it into the same table as an extra source.","assets":[],"created_at":"2026-10-01T15:22:54-05:00","updated_at":"2026-10-01T15:22:54-05:00"},{"id":875,"html_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/99#issuecomment-875","pull_request_url":"","issue_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/99","user":{"id":1,"login":"charles","login_name":"","source_id":0,"full_name":"Charles Willgren","email":"charles@noreply.www-s01.apinet.com","avatar_url":"https:\/\/www-s01.apinet.com\/codeforge\/avatars\/d3c894f7297c5a18eb3f6ac837c335b11a00aa9cc0961323771632b1e2d61bb2","html_url":"https:\/\/www-s01.apinet.com\/codeforge\/charles","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2025-12-08T10:03:41-06:00","restricted":false,"active":false,"prohibit_login":false,"location":"","pronouns":"","website":"","description":"","visibility":"public","followers_count":0,"following_count":0,"starred_repos_count":0,"username":"charles"},"original_author":"","original_author_id":0,"body":"## Proposal: use the same NPI download as #82\n\nPharmacies are already in the NPPES file proposed in #82: organisations (entity type 2) with a pharmacy taxonomy (`3336*`). The import keeps them in the same `npi_provider` table, so we need no second source and no second import.\n\n**Where the answer comes from, in order:**\n1. **On file.** If the client's last visit recorded a pharmacy, start with that one already selected. VESTA as a source is still the open question for the customer.\n2. **Look it up.** Staff type part of the name. Results are limited to the **client's ZIP or city** first, because a name like \"Walgreens\" or \"CVS\" matches hundreds of stores and only the location tells them apart. Each match shows the name, street address and phone.\n3. Staff pick one. Name and phone fill in, and both can still be edited.\n\n**Details:**\n- Also import the NPPES \"other name\" file, so a store's DBA name (e.g. \"CVS Pharmacy #1234\") can be searched as well as its legal company name.\n- Show the pharmacies this agency has picked before at the top of the results. That gives the requested drop-down of known pharmacies with no separate list to maintain.\n- Store the pharmacy's **NPI** with the answer, as for the doctor.\n- The search runs against our own table, so nothing about the client leaves our server.\n\n**Still needed from the customer:** does VESTA or their own records already hold each client's pharmacy? If so, we prefill from that and use the lookup only when nothing is on file.","assets":[],"created_at":"2026-10-01T15:24:26-05:00","updated_at":"2026-10-01T15:24:26-05:00"},{"id":877,"html_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/99#issuecomment-877","pull_request_url":"","issue_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/99","user":{"id":3,"login":"connect-bot","login_name":"","source_id":0,"full_name":"","email":"connect-bot@noreply.www-s01.apinet.com","avatar_url":"https:\/\/www-s01.apinet.com\/codeforge\/avatars\/68a2723f7ad70dee2e1415be7488d84b","html_url":"https:\/\/www-s01.apinet.com\/codeforge\/connect-bot","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2026-10-01T08:49:35-05:00","restricted":false,"active":false,"prohibit_login":false,"location":"","pronouns":"","website":"","description":"","visibility":"public","followers_count":0,"following_count":0,"starred_repos_count":0,"username":"connect-bot"},"original_author":"","original_author_id":0,"body":"**Charles W.** _(via Connect)_\n<!-- connect:user=1 -->\n\nVESTA does not record (and thus does not export) any pharmacy information. We'll need to record it in our member record (after being accepted by office review) and prefill any future forms from that.","assets":[],"created_at":"2026-10-01T15:59:22-05:00","updated_at":"2026-10-01T15:59:22-05:00"},{"id":878,"html_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/77#issuecomment-878","pull_request_url":"","issue_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/77","user":{"id":1,"login":"charles","login_name":"","source_id":0,"full_name":"Charles Willgren","email":"charles@noreply.www-s01.apinet.com","avatar_url":"https:\/\/www-s01.apinet.com\/codeforge\/avatars\/d3c894f7297c5a18eb3f6ac837c335b11a00aa9cc0961323771632b1e2d61bb2","html_url":"https:\/\/www-s01.apinet.com\/codeforge\/charles","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2025-12-08T10:03:41-06:00","restricted":false,"active":false,"prohibit_login":false,"location":"","pronouns":"","website":"","description":"","visibility":"public","followers_count":0,"following_count":0,"starred_repos_count":0,"username":"charles"},"original_author":"","original_author_id":0,"body":"## Where a shared question is worded differently on each form\n\n19 interview questions fill more than one form. **8 of them are worded differently from form to form**; these are the ones the customer needs to decide on. The other 11 (advance directives, release of records, unable-to-sign reason, rights reviewed) read the same on both consents and on Private Pay, so they need no decision.\n\n| Question on screen today | Wording on each form |\n|---|---|\n| Client's sex | Client Information Sheet: **\"Gender\"** \u00b7 Emergency\/Disaster Form, PAS Service Plan: **\"Sex\"** |\n| Emergency priority class | Client Information Sheet: **\"Classification\"** \u00b7 Emergency\/Disaster Form: **\"What category describes your special needs?\"** |\n| First emergency contact: name | Client Information Sheet: **\"First Emergency Contact \u2014 Contact Person\"** \u00b7 Emergency\/Disaster Form: **\"In case of emergency contact \u2014 Name\"** |\n| First emergency contact: relationship | Client Information Sheet: **\"First Emergency Contact \u2014 Relation\"** \u00b7 Emergency\/Disaster Form: **\"Relationship\"** |\n| First emergency contact: phone | Client Information Sheet: **\"First Emergency Contact \u2014 Phone Number\"** \u00b7 Emergency\/Disaster Form: **\"Phone Number\"** |\n| Level of supervision (RN or non-RN) | PAS Service Plan: **\"Plan of Supervision\"** \u00b7 Form 3040: **\"Level of Supervision\"** |\n| Tasks in the service plan | PAS Service Plan: **\"Service Plan Tasks\"** \u00b7 Coordination of Care: **\"Tasks provided\"** |\n| Other task in the service plan | PAS Service Plan: **\"Service Plan \u2014 Other\"** \u00b7 Coordination of Care: **\"Other (specify)\"** |\n\n### Two things make the decision harder\n\n- **Some wordings don't stand on their own.** \"Phone Number\", \"Relationship\" and \"Classification\" only make sense next to the rest of the paper form. The Emergency\/Disaster Form's wording also reads as a different question from the Client Information Sheet's. So \"one form wins\" would need a rule like \"use the Client Information Sheet's wording, which is the most complete\". Showing each form's wording could be confusing here.\n- **Wording that matches can still be a fragment.** The medical power of attorney's phone line is just **\"Phone\"** on all three forms. \"Which directives\" and \"Reviewed and acknowledged\" also only make sense next to the paragraph above them. Showing the form's wording as the label works there only if the surrounding paper text (already shown underneath) stays visible.\n\n### Source\n\nThe wordings come from the field labels in our form definitions (`docs\/forms\/*.json`), which were transcribed from the paper forms, and the list of shared questions from `FORM_V2_SHARED_ELEMENTS` in `code\/form_v2_shared.inc.php`. They should match the paper closely but may not be exact, so check them against the paper before sending this to the customer.","assets":[],"created_at":"2026-10-01T18:08:58-05:00","updated_at":"2026-10-01T18:08:58-05:00"},{"id":879,"html_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/77#issuecomment-879","pull_request_url":"","issue_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/77","user":{"id":1,"login":"charles","login_name":"","source_id":0,"full_name":"Charles Willgren","email":"charles@noreply.www-s01.apinet.com","avatar_url":"https:\/\/www-s01.apinet.com\/codeforge\/avatars\/d3c894f7297c5a18eb3f6ac837c335b11a00aa9cc0961323771632b1e2d61bb2","html_url":"https:\/\/www-s01.apinet.com\/codeforge\/charles","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2025-12-08T10:03:41-06:00","restricted":false,"active":false,"prohibit_login":false,"location":"","pronouns":"","website":"","description":"","visibility":"public","followers_count":0,"following_count":0,"starred_repos_count":0,"username":"charles"},"original_author":"","original_author_id":0,"body":"## Most of this change does not wait on the customer\n\nThe customer's decision above covers only the **8 shared questions** whose wording differs between forms. In the SOC\/AO interview, **250 questions belong to a single form**, so they can simply take that form's printed wording as their label. That work can go ahead now.\n\nThe example the customer raised is one of these. It is on the PAS Service Plan only (`form.pas-eval-service-plan.duplicate_phc`):\n\n| | Form wording | Our interview today (`docs\/form-v2-interviews\/SOC_AO.json`) |\n|---|---|---|\n| Question | \"Do these services appear to duplicate PHC services?\" | \"Do any of those services overlap with what our attendant will do?\" |\n| Follow-up | \"Comments\" | \"Explain the overlap.\" |\n\nThe follow-up box has the same problem: the form calls it \"Comments\".\n\n**Keep the explanations when the labels change:**\n- The form's own instruction (\"If yes, notify the individual's DADS caseworker before requesting prior approval\u2026\") is already shown under the question and stays there (FormsV2Plan \u00a74.1.2).\n- Our plain-English help line (\"Your judgement: would the client be getting the same help twice?\") can stay as a hint below the form's wording. That way the label matches the paper without losing the explanation.","assets":[],"created_at":"2026-10-01T18:12:22-05:00","updated_at":"2026-10-01T18:12:22-05:00"},{"id":921,"html_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/105#issuecomment-921","pull_request_url":"","issue_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/105","user":{"id":1,"login":"charles","login_name":"","source_id":0,"full_name":"Charles Willgren","email":"charles@noreply.www-s01.apinet.com","avatar_url":"https:\/\/www-s01.apinet.com\/codeforge\/avatars\/d3c894f7297c5a18eb3f6ac837c335b11a00aa9cc0961323771632b1e2d61bb2","html_url":"https:\/\/www-s01.apinet.com\/codeforge\/charles","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2025-12-08T10:03:41-06:00","restricted":false,"active":false,"prohibit_login":false,"location":"","pronouns":"","website":"","description":"","visibility":"public","followers_count":0,"following_count":0,"starred_repos_count":0,"username":"charles"},"original_author":"","original_author_id":0,"body":"**From Frank's notes of the on-site meeting (29 Sep):** this probably gives us the mapping.\n\n> Opposite Answers:\n> Is a change in tasks or hours, or should services end? Yes, No\n> Is the service plan enough to meet clients needs? No, Yes\n\nIn the interview that is `form.forms-3040.change_needed` \u2194 `form.forms-3040.service_plan_adequate`. These are likely Q3b and Q7. Check against the paper before building.\n\nSnag: `service_plan_adequate` has a third option, \"Does not apply\", which has no opposite. Decide whether it goes away once the answer is derived.\n\nDon't mix this up with H6 (#96), \"Does the client need the services?\" (`continues_to_need_services`). That one is a separate always-Yes default.","assets":[],"created_at":"2026-10-02T09:06:26-05:00","updated_at":"2026-10-02T09:06:26-05:00"},{"id":923,"html_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/103#issuecomment-923","pull_request_url":"","issue_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/103","user":{"id":1,"login":"charles","login_name":"","source_id":0,"full_name":"Charles Willgren","email":"charles@noreply.www-s01.apinet.com","avatar_url":"https:\/\/www-s01.apinet.com\/codeforge\/avatars\/d3c894f7297c5a18eb3f6ac837c335b11a00aa9cc0961323771632b1e2d61bb2","html_url":"https:\/\/www-s01.apinet.com\/codeforge\/charles","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2025-12-08T10:03:41-06:00","restricted":false,"active":false,"prohibit_login":false,"location":"","pronouns":"","website":"","description":"","visibility":"public","followers_count":0,"following_count":0,"starred_repos_count":0,"username":"charles"},"original_author":"","original_author_id":0,"body":"**From Frank's notes of the on-site meeting (29 Sep):** the frequency is a drop-down with three values, and each task has a default.\n\n> How often: Drop Down QD - Every Day, QW - Every week, PRN - As Needed\n\n| Task | Default |\n|---|---|\n| Bathing, Dressing, Exercising, Feeding\/Eating, Grooming\/Shaving\/Oral Care, Routine Hair\/Skin Care, Toileting, Transfer, Ambulation, Cleaning, Walking, Meal Preparation, Assist w\/ Self-Admin Med | QD |\n| Laundry, Shopping | QW |\n| Escort | PRN |\n| Blank \"other\" row | drop-down (QD, QW, PRN) |\n\nToday `form.forms-3040.task_*_freq` is **free text** (\"daily, 3 times a week\"). So:\n1. Make it a choice of QD \/ QW \/ PRN, with the defaults above, and only for tasks in the client's VESTA list (S4 #89 \/ A4 #108).\n2. Add the blank \"other\" task row, with its name typed in and its frequency from the drop-down.\n3. Still to ask: with sensible defaults, do we still need to *refuse* QW on a QD task, or is the default enough?","assets":[],"created_at":"2026-10-02T09:06:26-05:00","updated_at":"2026-10-02T09:06:26-05:00"},{"id":926,"html_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/106#issuecomment-926","pull_request_url":"","issue_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/106","user":{"id":1,"login":"charles","login_name":"","source_id":0,"full_name":"Charles Willgren","email":"charles@noreply.www-s01.apinet.com","avatar_url":"https:\/\/www-s01.apinet.com\/codeforge\/avatars\/d3c894f7297c5a18eb3f6ac837c335b11a00aa9cc0961323771632b1e2d61bb2","html_url":"https:\/\/www-s01.apinet.com\/codeforge\/charles","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2025-12-08T10:03:41-06:00","restricted":false,"active":false,"prohibit_login":false,"location":"","pronouns":"","website":"","description":"","visibility":"public","followers_count":0,"following_count":0,"starred_repos_count":0,"username":"charles"},"original_author":"","original_author_id":0,"body":"**From Frank's notes of the on-site meeting (29 Sep):** the exact value to fill.\n\n> Who should the attendant report them to? \u2026 autofill it to the Agency \"Legacy Home Health Agency & main phone number\" Form 3040 Check Off 10-4\n\n* Name: the agency name.\n* Phone: the agency's **main** number. The fact we have is `agency_phone_24h`. Ask whether \"main\" is a different number, and if it is, add it as a system fact.\n* \"Check Off 10-4\" looks like the paper's item number. Record it for G2 (#78).\n\nThe question above it, \"Which health problems must the attendant report?\", is now A7 (#138).","assets":[],"created_at":"2026-10-02T09:06:26-05:00","updated_at":"2026-10-02T09:06:26-05:00"},{"id":929,"html_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/109#issuecomment-929","pull_request_url":"","issue_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/109","user":{"id":1,"login":"charles","login_name":"","source_id":0,"full_name":"Charles Willgren","email":"charles@noreply.www-s01.apinet.com","avatar_url":"https:\/\/www-s01.apinet.com\/codeforge\/avatars\/d3c894f7297c5a18eb3f6ac837c335b11a00aa9cc0961323771632b1e2d61bb2","html_url":"https:\/\/www-s01.apinet.com\/codeforge\/charles","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2025-12-08T10:03:41-06:00","restricted":false,"active":false,"prohibit_login":false,"location":"","pronouns":"","website":"","description":"","visibility":"public","followers_count":0,"following_count":0,"starred_repos_count":0,"username":"charles"},"original_author":"","original_author_id":0,"body":"**From Frank's notes of the on-site meeting (29 Sep):**\n\n> Attendants and supervision: Attendant A-C - Pull from Service Plan?\n\nThis partly answers the question: Attendants A\u2013C on the 3040 come from the service plan (the *Attendants and their hours* step \/ `schedule.attendant_*`). It still has a question mark, so confirm it with the customer.","assets":[],"created_at":"2026-10-02T09:06:26-05:00","updated_at":"2026-10-02T09:06:26-05:00"},{"id":930,"html_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/95#issuecomment-930","pull_request_url":"","issue_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/95","user":{"id":1,"login":"charles","login_name":"","source_id":0,"full_name":"Charles Willgren","email":"charles@noreply.www-s01.apinet.com","avatar_url":"https:\/\/www-s01.apinet.com\/codeforge\/avatars\/d3c894f7297c5a18eb3f6ac837c335b11a00aa9cc0961323771632b1e2d61bb2","html_url":"https:\/\/www-s01.apinet.com\/codeforge\/charles","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2025-12-08T10:03:41-06:00","restricted":false,"active":false,"prohibit_login":false,"location":"","pronouns":"","website":"","description":"","visibility":"public","followers_count":0,"following_count":0,"starred_repos_count":0,"username":"charles"},"original_author":"","original_author_id":0,"body":"**From Frank's notes of the on-site meeting (29 Sep):** the format.\n\n> Change of Tasks, Hours, or Services Ending: Template Elements Notes and Fill in Blanks\n\nSo the answer is a structured template (elements, plus notes and fill-in blanks), not free text. We still need the template's actual elements from the customer.\n\nAlso related: the Yes\/No on this question is the opposite of \"Is the service plan enough\u2026\" (A1, #105).","assets":[],"created_at":"2026-10-02T09:06:26-05:00","updated_at":"2026-10-02T09:06:26-05:00"},{"id":932,"html_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/112#issuecomment-932","pull_request_url":"","issue_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/112","user":{"id":1,"login":"charles","login_name":"","source_id":0,"full_name":"Charles Willgren","email":"charles@noreply.www-s01.apinet.com","avatar_url":"https:\/\/www-s01.apinet.com\/codeforge\/avatars\/d3c894f7297c5a18eb3f6ac837c335b11a00aa9cc0961323771632b1e2d61bb2","html_url":"https:\/\/www-s01.apinet.com\/codeforge\/charles","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2025-12-08T10:03:41-06:00","restricted":false,"active":false,"prohibit_login":false,"location":"","pronouns":"","website":"","description":"","visibility":"public","followers_count":0,"following_count":0,"starred_repos_count":0,"username":"charles"},"original_author":"","original_author_id":0,"body":"**From Frank's notes of the on-site meeting (29 Sep):**\n\n> Drop down with who's signing for Client\n\nThe question of who signs for the client, and on what authority (`shared.release.authority`, \"If someone is signing for the client, what gives them the right to?\"), should be a **drop-down**, not typed. Get the list from the customer (POA, MPOA, guardian, parent\u2026). The POA choice is then what opens the follow-up question this issue is about. Hiding all of it when the client signs is W1 (#111).","assets":[],"created_at":"2026-10-02T09:06:26-05:00","updated_at":"2026-10-02T09:06:26-05:00"},{"id":934,"html_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/90#issuecomment-934","pull_request_url":"","issue_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/90","user":{"id":1,"login":"charles","login_name":"","source_id":0,"full_name":"Charles Willgren","email":"charles@noreply.www-s01.apinet.com","avatar_url":"https:\/\/www-s01.apinet.com\/codeforge\/avatars\/d3c894f7297c5a18eb3f6ac837c335b11a00aa9cc0961323771632b1e2d61bb2","html_url":"https:\/\/www-s01.apinet.com\/codeforge\/charles","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2025-12-08T10:03:41-06:00","restricted":false,"active":false,"prohibit_login":false,"location":"","pronouns":"","website":"","description":"","visibility":"public","followers_count":0,"following_count":0,"starred_repos_count":0,"username":"charles"},"original_author":"","original_author_id":0,"body":"**From Frank's notes of the on-site meeting (29 Sep):**\n\n> Other care the client receives <-> Service plan\n\nThe service plan's \"other services\" and the *Other care the client receives* step (Coordination of Care) are the same information. Filed as K2 (#140): derive the service plan line from Coordination of Care, so \"no providers entered\" answers what prints here.","assets":[],"created_at":"2026-10-02T09:06:26-05:00","updated_at":"2026-10-02T09:06:26-05:00"},{"id":936,"html_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/97#issuecomment-936","pull_request_url":"","issue_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/97","user":{"id":1,"login":"charles","login_name":"","source_id":0,"full_name":"Charles Willgren","email":"charles@noreply.www-s01.apinet.com","avatar_url":"https:\/\/www-s01.apinet.com\/codeforge\/avatars\/d3c894f7297c5a18eb3f6ac837c335b11a00aa9cc0961323771632b1e2d61bb2","html_url":"https:\/\/www-s01.apinet.com\/codeforge\/charles","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2025-12-08T10:03:41-06:00","restricted":false,"active":false,"prohibit_login":false,"location":"","pronouns":"","website":"","description":"","visibility":"public","followers_count":0,"following_count":0,"starred_repos_count":0,"username":"charles"},"original_author":"","original_author_id":0,"body":"**From Frank's notes of the on-site meeting (29 Sep):** confirmed. \"Does the client's schedule vary week to week? No\", answered automatically. The schedule note next to it is H9 (#139).","assets":[],"created_at":"2026-10-02T09:06:26-05:00","updated_at":"2026-10-02T09:06:26-05:00"},{"id":938,"html_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/102#issuecomment-938","pull_request_url":"","issue_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/102","user":{"id":1,"login":"charles","login_name":"","source_id":0,"full_name":"Charles Willgren","email":"charles@noreply.www-s01.apinet.com","avatar_url":"https:\/\/www-s01.apinet.com\/codeforge\/avatars\/d3c894f7297c5a18eb3f6ac837c335b11a00aa9cc0961323771632b1e2d61bb2","html_url":"https:\/\/www-s01.apinet.com\/codeforge\/charles","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2025-12-08T10:03:41-06:00","restricted":false,"active":false,"prohibit_login":false,"location":"","pronouns":"","website":"","description":"","visibility":"public","followers_count":0,"following_count":0,"starred_repos_count":0,"username":"charles"},"original_author":"","original_author_id":0,"body":"**From Frank's notes of the on-site meeting (29 Sep):** \"Task Guide - Review Needed\". Still undecided on their side.","assets":[],"created_at":"2026-10-02T09:06:27-05:00","updated_at":"2026-10-02T09:06:27-05:00"},{"id":939,"html_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/107#issuecomment-939","pull_request_url":"","issue_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/107","user":{"id":1,"login":"charles","login_name":"","source_id":0,"full_name":"Charles Willgren","email":"charles@noreply.www-s01.apinet.com","avatar_url":"https:\/\/www-s01.apinet.com\/codeforge\/avatars\/d3c894f7297c5a18eb3f6ac837c335b11a00aa9cc0961323771632b1e2d61bb2","html_url":"https:\/\/www-s01.apinet.com\/codeforge\/charles","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2025-12-08T10:03:41-06:00","restricted":false,"active":false,"prohibit_login":false,"location":"","pronouns":"","website":"","description":"","visibility":"public","followers_count":0,"following_count":0,"starred_repos_count":0,"username":"charles"},"original_author":"","original_author_id":0,"body":"**From Frank's notes of the on-site meeting (29 Sep):**\n\n> Is this only an orientation or is no attendant assigned yet? Review needed\n\nThis is `form.forms-3040.satisfaction_na_note`. It gates every per-attendant satisfaction and task-performance question, so the decision here changes how much of the 3040 is asked at an SOC.","assets":[],"created_at":"2026-10-02T09:06:27-05:00","updated_at":"2026-10-02T09:06:27-05:00"},{"id":940,"html_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/77#issuecomment-940","pull_request_url":"","issue_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/77","user":{"id":1,"login":"charles","login_name":"","source_id":0,"full_name":"Charles Willgren","email":"charles@noreply.www-s01.apinet.com","avatar_url":"https:\/\/www-s01.apinet.com\/codeforge\/avatars\/d3c894f7297c5a18eb3f6ac837c335b11a00aa9cc0961323771632b1e2d61bb2","html_url":"https:\/\/www-s01.apinet.com\/codeforge\/charles","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2025-12-08T10:03:41-06:00","restricted":false,"active":false,"prohibit_login":false,"location":"","pronouns":"","website":"","description":"","visibility":"public","followers_count":0,"following_count":0,"starred_repos_count":0,"username":"charles"},"original_author":"","original_author_id":0,"body":"## Built on dev (5 Oct 2026). The customer decision is still open\n\n**What changed on the visit screen**\n- Each question is now called what the paper form calls it (taken from the field labels in our form definitions). Our plain-English wording is kept underneath it as an \"Ask: \u2026\" line, so the supervisor still has something natural to read out.\n- **276 of the 316** SOC\/AO questions now carry the form's wording. 16 of those (Form 3040 items 4, 5, 8, 9, 10-5, 10-6, 3B) were set to the paper's exact text, because the definition had shortened it.\n- Example: the PAS Service Plan question now reads **\"Do these services appear to duplicate PHC services?\"**, with \"Ask: Do any of those services overlap with what our attendant will do?\" below it.\n\n**Still waiting on the customer: 40 questions where the forms word it differently**\n- The 8 shared questions in the table above.\n- The client's details that print on many forms. For example, the client's name is worded 14 different ways (\"Individual's Name (please print)\", \"Client Name\", \"Patient Name\"\u2026). The same goes for date of birth, Medicaid number, phone, address and physician.\n- The schedule cells (the ISP says \"Sun\", the 3040 says \"Sunday\").\n\nUntil the customer decides, these keep our wording. The \u24d8 panel on each one lists every form's own wording (\"On this form: 'Gender'\"). Once they decide, the change is a rule in one place (`form_v2_paper_wording()`), not 40 edits.\n\n**Not changed:** the wording of answer *choices* (e.g. \"In person\" \/ \"By telephone\"). Should those go back to the paper's too? That's a question for the customer as well.\n\nTechnical: FormsV2Plan \u00a74.1.3, Changelog 2026-10-05. Interview file key `say` is new and documented in `docs\/form-v2-interviews\/README.md`.","assets":[],"created_at":"2026-10-05T09:24:16-05:00","updated_at":"2026-10-05T09:24:16-05:00"},{"id":941,"html_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/78#issuecomment-941","pull_request_url":"","issue_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/78","user":{"id":1,"login":"charles","login_name":"","source_id":0,"full_name":"Charles Willgren","email":"charles@noreply.www-s01.apinet.com","avatar_url":"https:\/\/www-s01.apinet.com\/codeforge\/avatars\/d3c894f7297c5a18eb3f6ac837c335b11a00aa9cc0961323771632b1e2d61bb2","html_url":"https:\/\/www-s01.apinet.com\/codeforge\/charles","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2025-12-08T10:03:41-06:00","restricted":false,"active":false,"prohibit_login":false,"location":"","pronouns":"","website":"","description":"","visibility":"public","followers_count":0,"following_count":0,"starred_repos_count":0,"username":"charles"},"original_author":"","original_author_id":0,"body":"## Built on dev (5 Oct 2026)\n\n**Only Form 3040 prints question numbers.** I checked every Start of Care blank: the Client Information Sheet, both consents, Coordination of Care, the Emergency\/Disaster plan, 2-1-1, the PAS Service Plan, the Task Guide, Things You May Not Do, the Transfer form, Private Pay and the H2076. None of the others numbers its questions, so for those forms no number is shown, and none is made up.\n\n**On the 3040** the numbers are items 1, 2A, 2B, 2C, 3A, 3B, 4\u20139 and 10-1 to 10-7. They are recorded for all 96 of its numbered fields. The visit screen shows them beside the question, e.g. **\"Form 3040, item 8\"**. The form itself calls them \"items\" (\"items 4 and\/or 5\"). A question that fills several numbered forms would show each one.\n\n**How it's stored:** a `numbering` block in `docs\/form-placements\/forms-3040.json`, carried into the form's map, so the numbers are pinned with the paper. A new revision of the form can renumber it. The Form Explorer shows the number on each box row. Still to do: the data-element list (R1).\n\nTechnical: FormsV2Plan \u00a74.1.3, Changelog 2026-10-05.","assets":[],"created_at":"2026-10-05T09:24:16-05:00","updated_at":"2026-10-05T09:24:16-05:00"},{"id":942,"html_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/77#issuecomment-942","pull_request_url":"","issue_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/77","user":{"id":1,"login":"charles","login_name":"","source_id":0,"full_name":"Charles Willgren","email":"charles@noreply.www-s01.apinet.com","avatar_url":"https:\/\/www-s01.apinet.com\/codeforge\/avatars\/d3c894f7297c5a18eb3f6ac837c335b11a00aa9cc0961323771632b1e2d61bb2","html_url":"https:\/\/www-s01.apinet.com\/codeforge\/charles","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2025-12-08T10:03:41-06:00","restricted":false,"active":false,"prohibit_login":false,"location":"","pronouns":"","website":"","description":"","visibility":"public","followers_count":0,"following_count":0,"starred_repos_count":0,"username":"charles"},"original_author":"","original_author_id":0,"body":"## Answer choices now match the form too (5 Oct 2026, dev)\n\nDecided: choices say what the form says. **\"HDM\"**, not \"Home-delivered meals\". The same goes for DME, DAHS, N\/A, RN \/ Non-RN, NON HCBS, Family Residence, and so on.\n\n- 252 reworded choices were removed from the SOC\/AO interview, so the form's wording shows through.\n- The same rule as the question labels applies: a choice uses the form's wording wherever every form that offers it agrees.\n\n**Three choice lists still keep our wording, because the forms disagree.** These join the 40 questions waiting on the customer:\n- **Emergency priority class:** the Client Information Sheet has a one-line choice (\"Class 1: Bed confined \/ services may not be postponed\"). The disaster plan has a paragraph for each class.\n- **Sex:** the ISP prints \"M\" \/ \"F\", the other forms \"Male\" \/ \"Female\".\n- **Service tasks:** the ISP prints numbered bilingual codes (\"1 - Bathing \/ Ba\u00f1ar\"), the Coordination of Care plain names (\"Bathing\").","assets":[],"created_at":"2026-10-05T09:45:05-05:00","updated_at":"2026-10-05T09:45:05-05:00"},{"id":943,"html_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/127#issuecomment-943","pull_request_url":"","issue_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/127","user":{"id":1,"login":"charles","login_name":"","source_id":0,"full_name":"Charles Willgren","email":"charles@noreply.www-s01.apinet.com","avatar_url":"https:\/\/www-s01.apinet.com\/codeforge\/avatars\/d3c894f7297c5a18eb3f6ac837c335b11a00aa9cc0961323771632b1e2d61bb2","html_url":"https:\/\/www-s01.apinet.com\/codeforge\/charles","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2025-12-08T10:03:41-06:00","restricted":false,"active":false,"prohibit_login":false,"location":"","pronouns":"","website":"","description":"","visibility":"public","followers_count":0,"following_count":0,"starred_repos_count":0,"username":"charles"},"original_author":"","original_author_id":0,"body":"**Built (2026-10-05), not yet committed.**\n\n`scripts\/form-v2-pipeline.php --interview=SOC_AO_V2` (or `--packet=SOC_AO`) runs the whole chain:\n\n- **Import.** The packet's form definitions, placements and signing lines go through the existing importers. The interview comes from `docs\/form-v2-interviews\/`. The import is idempotent: a file that already matches the draft or the published version writes nothing. An interview draft edited on screen is not overwritten unless `--replace` is given.\n- **Publish.** `form_v2_pipeline_run()` publishes the definitions, then the maps, then the interview (through the editor's gate), then a release (`SOC_AO-20261005`, numbered if the code is taken). All of it is one transaction, using the screens' own publishers. It commits only if nothing was refused and the #130 check passes on the release it produced.\n- **Modes.** The default is a dry run: the chain runs and is rolled back, so the output is the actual release rather than a prediction. `--import` writes drafts only. `--apply --as=EMAIL` publishes.\n- **Activation.** `--activate=9,10` activates afterwards. It is refused on production (see #128).\n- **Idempotent.** If the content is the same as the last release, no new release is made.\n\nReview page: `\/admin\/form-v2-publish` (see #130).\n\nTwo limits:\n- The placement proposer reads the *published* definition. A form that gains a new field therefore needs its definition published before its placement can be proposed. The pipeline refuses this case and names it; it does not guess.\n- Packets are not imported or published by the chain. They keep `import-form-packets.php --publish`.\n\nAlso fixed: `form-publish.php` judged a later form's map against the *old* definition when it published several forms in one run, because of a per-request cache.","assets":[],"created_at":"2026-10-05T10:06:03-05:00","updated_at":"2026-10-05T10:06:03-05:00"},{"id":946,"html_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/130#issuecomment-946","pull_request_url":"","issue_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/130","user":{"id":1,"login":"charles","login_name":"","source_id":0,"full_name":"Charles Willgren","email":"charles@noreply.www-s01.apinet.com","avatar_url":"https:\/\/www-s01.apinet.com\/codeforge\/avatars\/d3c894f7297c5a18eb3f6ac837c335b11a00aa9cc0961323771632b1e2d61bb2","html_url":"https:\/\/www-s01.apinet.com\/codeforge\/charles","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2025-12-08T10:03:41-06:00","restricted":false,"active":false,"prohibit_login":false,"location":"","pronouns":"","website":"","description":"","visibility":"public","followers_count":0,"following_count":0,"starred_repos_count":0,"username":"charles"},"original_author":"","original_author_id":0,"body":"**Built (2026-10-05), not yet committed.**\n\n`form_v2_publish_check()` (pure, `code\/form_v2_review.inc.php`) is built on the Form Explorer's model, and three places read it: the Explorer's **Gaps** tab, the CLI (#127) and the new review page. A publish is refused unless all nine checks pass:\n\n1. publish rules\n2. required boxes are asked\n3. every box is filled, or blank for a written reason\n4. no orphan questions\n5. every branch reachable\n6. bindings\n7. paper coverage\n8. every shared answer has a ruling\n9. **every form prints a proof**, using the same rule a kept form uses\n\nThe Gaps tab does not render proofs, so it shows that check as \"not run\", which never counts as a pass.\n\n**Review page `\/admin\/form-v2-publish`** (menu: *Publish an Interview*) shows:\n- the verdict and the check;\n- what publishing does;\n- what changed: questions new, reworded (old and new side by side), moved, asked under another condition or removed, plus changes to the forms and placements;\n- every question in full;\n- one **Publish all of this** button (needs the Approve right).\n\nThe page is a rollback rehearsal of the real publish. The button sends the reviewed release's fingerprint, and the publish refuses if anything changed in between. It never activates.\n\nSOC_AO rehearses clean today: 316 questions, all nine checks pass.\n\nTests: `test-form-v2-review.php` (51) and `test-form-v2-pipeline-state.php` (19).","assets":[],"created_at":"2026-10-05T10:06:03-05:00","updated_at":"2026-10-05T10:06:03-05:00"},{"id":948,"html_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/127#issuecomment-948","pull_request_url":"","issue_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/127","user":{"id":1,"login":"charles","login_name":"","source_id":0,"full_name":"Charles Willgren","email":"charles@noreply.www-s01.apinet.com","avatar_url":"https:\/\/www-s01.apinet.com\/codeforge\/avatars\/d3c894f7297c5a18eb3f6ac837c335b11a00aa9cc0961323771632b1e2d61bb2","html_url":"https:\/\/www-s01.apinet.com\/codeforge\/charles","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2025-12-08T10:03:41-06:00","restricted":false,"active":false,"prohibit_login":false,"location":"","pronouns":"","website":"","description":"","visibility":"public","followers_count":0,"following_count":0,"starred_repos_count":0,"username":"charles"},"original_author":"","original_author_id":0,"body":"**Update: the \"new field\" limitation is gone.**\n\nThe placement and signing-line proposers now read the definition *about to be* published: each form's newest draft wherever it differs from the published version. `--published` restores the old reading.\n\nSo a field added to a form gets its boxes in the same `--import`, and the one-button publish carries the form and its placement together. Publishing still judges each map against the definition published at that moment, which in the pipeline is the one it has just published.\n\nProved on dev:\n- I added a tick box to a draft of *Things Your Attendant May Not Do*.\n- One rehearsal published the definition (\"New field\") and the map (\"Now printed\").\n- The check refused only because the interview didn't ask the new field yet, which is correct.\n\nThe test drafts were removed afterwards. The regression is pinned in `test-form-v2-pipeline-state.php`, which now has 24 checks.","assets":[],"created_at":"2026-10-05T10:12:28-05:00","updated_at":"2026-10-05T10:12:28-05:00"},{"id":949,"html_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/129#issuecomment-949","pull_request_url":"","issue_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/129","user":{"id":1,"login":"charles","login_name":"","source_id":0,"full_name":"Charles Willgren","email":"charles@noreply.www-s01.apinet.com","avatar_url":"https:\/\/www-s01.apinet.com\/codeforge\/avatars\/d3c894f7297c5a18eb3f6ac837c335b11a00aa9cc0961323771632b1e2d61bb2","html_url":"https:\/\/www-s01.apinet.com\/codeforge\/charles","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2025-12-08T10:03:41-06:00","restricted":false,"active":false,"prohibit_login":false,"location":"","pronouns":"","website":"","description":"","visibility":"public","followers_count":0,"following_count":0,"starred_repos_count":0,"username":"charles"},"original_author":"","original_author_id":0,"body":"**Decision: remove the edit screens.** The files are the source of truth, and a correction is a file change.\n\n**Done (2026-10-05):**\n* `\/admin\/form-v2-workflows` (Visit Interviews) and `\/admin\/form-v2-maps` (Form Placement) are off the menu and unrouted (both now 404). They are kept for reference in `archive\/form-v2-editors\/`, with a README covering why and how to bring one back.\n* Their 15 endpoints moved there too: `formV2Workflow{Create,Get,List,NewDraft,Preview,Publish,SaveDraft}`, `formV2Map{Get,List,NewDraft,Preview,Publish,SaveDraft,SuggestSignings}`, and `formV2ReleasePublish` (assembling a release by hand, which the pipeline replaced).\n* **Two things on the interview screen were not editing**, so they stayed live on a new page, `\/admin\/form-v2-releases` (**Paperwork in Use**):\n  * **choosing a release for each agency** (#128). The CLI's `--activate` is refused on production, so without this page nothing could put a release in use;\n  * **retiring an interview, or bringing one back.**\n* Publish an Interview, the Explorer's Gaps tab and `form-v2-pipeline.php` now point there. The library functions are unchanged.\n\nThe route is now: files \u2192 Form Explorer (check) \u2192 Publish an Interview \u2192 Paperwork in Use.","assets":[],"created_at":"2026-10-05T10:24:08-05:00","updated_at":"2026-10-05T10:24:08-05:00"},{"id":952,"html_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/126#issuecomment-952","pull_request_url":"","issue_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/126","user":{"id":1,"login":"charles","login_name":"","source_id":0,"full_name":"Charles Willgren","email":"charles@noreply.www-s01.apinet.com","avatar_url":"https:\/\/www-s01.apinet.com\/codeforge\/avatars\/d3c894f7297c5a18eb3f6ac837c335b11a00aa9cc0961323771632b1e2d61bb2","html_url":"https:\/\/www-s01.apinet.com\/codeforge\/charles","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2025-12-08T10:03:41-06:00","restricted":false,"active":false,"prohibit_login":false,"location":"","pronouns":"","website":"","description":"","visibility":"public","followers_count":0,"following_count":0,"starred_repos_count":0,"username":"charles"},"original_author":"","original_author_id":0,"body":"**Status, 2026-10-05: mostly done by #127\/#130. Two pieces are still open.**\n\nThe **Publish an Interview** page (`\/admin\/form-v2-publish`) already shows what changed between what you are about to publish and the latest release:\n* **Questions:** new, reworded (old and new wording side by side), moved, removed, or asked under a different condition, with an \"Only what changed\" filter (`form_v2_workflow_diff()`).\n* **Forms:** for each form, changes to the definition and to where answers print (`form_v2_form_def_diff()`, `form_v2_map_diff()`).\n* **The release as a whole:** `form_v2_release_compare()` now has a screen.\n\nThat covers \"draft beside published\". It sits on the Publish page rather than the Form Explorer, which is where the review happens.\n\n**Still open:**\n1. **Compare any two releases after they are published** (for example \"what changed between the 1 Oct and 5 Oct releases\"). Today you only see a comparison at publish time. The natural place is beside each release on the new **Paperwork in Use** page (`\/admin\/form-v2-releases`, #129).\n2. **Link each change to the issue that asked for it.** Releases carry free-text notes, and nothing ties a change to an issue. The links could come from the release notes, or from the commit that changed the prepared file.\n\nSmaller point: a prefill change shows up through the question and placement diffs, but it is not called out as a prefill change of its own.","assets":[],"created_at":"2026-10-05T10:32:13-05:00","updated_at":"2026-10-05T10:32:13-05:00"},{"id":954,"html_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/129#issuecomment-954","pull_request_url":"","issue_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/129","user":{"id":1,"login":"charles","login_name":"","source_id":0,"full_name":"Charles Willgren","email":"charles@noreply.www-s01.apinet.com","avatar_url":"https:\/\/www-s01.apinet.com\/codeforge\/avatars\/d3c894f7297c5a18eb3f6ac837c335b11a00aa9cc0961323771632b1e2d61bb2","html_url":"https:\/\/www-s01.apinet.com\/codeforge\/charles","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2025-12-08T10:03:41-06:00","restricted":false,"active":false,"prohibit_login":false,"location":"","pronouns":"","website":"","description":"","visibility":"public","followers_count":0,"following_count":0,"starred_repos_count":0,"username":"charles"},"original_author":"","original_author_id":0,"body":"**Follow-up: the Form Editor is archived too.** `\/admin\/forms-edit` was still live and on the menu in production after the archive deploy. Form definitions are files in `docs\/forms\/`, so the same drift applies.\n\n* The page and its eight endpoints (`formCreate`, `formImport`, `formDef{NewDraft,SaveDraft,Publish,Archive,Get,List}`) moved, unrouted, to `archive\/form-editor\/`, with a README.\n* **Import** with `scripts\/import-forms.php`.\n* **Publish** with `scripts\/form-v2-pipeline.php` or `\/admin\/form-v2-publish` for a form in a visit type, and `scripts\/form-publish.php --forms=CODE --apply --as=EMAIL` for any other form. All three use the same publish gate the editor used.\n\nNot changed: the Visit Packets editor (`\/admin\/form-packets`). It is off the menu but still reachable by URL, and packet definitions are files in `docs\/form-packets\/`.","assets":[],"created_at":"2026-10-05T10:34:31-05:00","updated_at":"2026-10-05T10:34:31-05:00"},{"id":955,"html_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/80#issuecomment-955","pull_request_url":"","issue_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/80","user":{"id":1,"login":"charles","login_name":"","source_id":0,"full_name":"Charles Willgren","email":"charles@noreply.www-s01.apinet.com","avatar_url":"https:\/\/www-s01.apinet.com\/codeforge\/avatars\/d3c894f7297c5a18eb3f6ac837c335b11a00aa9cc0961323771632b1e2d61bb2","html_url":"https:\/\/www-s01.apinet.com\/codeforge\/charles","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2025-12-08T10:03:41-06:00","restricted":false,"active":false,"prohibit_login":false,"location":"","pronouns":"","website":"","description":"","visibility":"public","followers_count":0,"following_count":0,"starred_repos_count":0,"username":"charles"},"original_author":"","original_author_id":0,"body":"Done as part of #77\/#78 (5 Oct 2026).\n\n- **FormsV2Plan:** new \u00a74.1.3 \"The form's wording and numbers are the question's\" explicitly reverses the spoken-label design. A question's label is the paper's wording; our wording moved to `say` (\"Ask: \u2026\"). The \u00a74.1.2 rule that the form's explanatory text must be on screen still stands. \u00a74.1.2 was left as history rather than rewritten, because \u00a74.1.3 overrides it by name.\n- **`docs\/form-v2-interviews\/README.md`:** says the label is the form's own wording (leave `label` out to get it) and `say` is how to ask it aloud.\n- **Project memory** (`feedback_v2_placement_by_claude`): marked superseded 2026-10-05 with the new rule.\n\n**Still open, tracked on #77:** the customer's choice of wording for the 40 questions where the forms disagree, and the three choice lists (emergency class, sex, service tasks). Until then those keep our wording, and the \"which forms\" panel shows each form's own.","assets":[],"created_at":"2026-10-05T11:21:05-05:00","updated_at":"2026-10-05T11:21:05-05:00"},{"id":958,"html_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/79#issuecomment-958","pull_request_url":"","issue_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/79","user":{"id":1,"login":"charles","login_name":"","source_id":0,"full_name":"Charles Willgren","email":"charles@noreply.www-s01.apinet.com","avatar_url":"https:\/\/www-s01.apinet.com\/codeforge\/avatars\/d3c894f7297c5a18eb3f6ac837c335b11a00aa9cc0961323771632b1e2d61bb2","html_url":"https:\/\/www-s01.apinet.com\/codeforge\/charles","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2025-12-08T10:03:41-06:00","restricted":false,"active":false,"prohibit_login":false,"location":"","pronouns":"","website":"","description":"","visibility":"public","followers_count":0,"following_count":0,"starred_repos_count":0,"username":"charles"},"original_author":"","original_author_id":0,"body":"Status, 5 Oct 2026.\n\n**On each question: done** (shipped with #77\/#78). The \u24d8 \"Which forms this goes on\" panel lists every form the answer prints on, that form's own wording, and a link to the blank. The label shows \"Form 3040, item 8\" where the form prints item numbers.\n\n**Visit's list of documents: done in the repo, not yet published.** Rule: a form's number is used only when the filename or the paper itself shows it, in the format **\"Form N \u2013 Name\"**:\n- Form 3040 \u2013 Attendant Orientation \/ Supervisory Visit (filename)\n- Form H2076 \u2013 Authorization to Release Medical Information (printed)\n- Form 2101 \u2013 Authorization for Community Care Services (printed on the faxed copy)\n- Form 3052 \u2013 MD Order (reformatted)\n- Form TDEM 21 \u2013 STEAR, State of Texas Emergency Assistance Registry (blank catalogue only)\n\nThe other SOC forms (consents, Client Information Sheet, Coordination of Care, ISP, etc.) print no number and keep their names. Changed in `docs\/form-packets\/*.json` (the document list), the two definitions, and `code\/form_blanks.inc.php`. `scripts\/test-form-blanks.php` now fails on a numbered title in any other format.\n\n**To apply:** `import-form-packets.php --publish --as=\u2026`, then `form-v2-pipeline.php --packet=SOC_AO --apply --as=\u2026` for the two definition titles. Close once it is visible on a visit.","assets":[],"created_at":"2026-10-05T11:21:06-05:00","updated_at":"2026-10-05T11:21:06-05:00"},{"id":960,"html_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/79#issuecomment-960","pull_request_url":"","issue_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/79","user":{"id":1,"login":"charles","login_name":"","source_id":0,"full_name":"Charles Willgren","email":"charles@noreply.www-s01.apinet.com","avatar_url":"https:\/\/www-s01.apinet.com\/codeforge\/avatars\/d3c894f7297c5a18eb3f6ac837c335b11a00aa9cc0961323771632b1e2d61bb2","html_url":"https:\/\/www-s01.apinet.com\/codeforge\/charles","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2025-12-08T10:03:41-06:00","restricted":false,"active":false,"prohibit_login":false,"location":"","pronouns":"","website":"","description":"","visibility":"public","followers_count":0,"following_count":0,"starred_repos_count":0,"username":"charles"},"original_author":"","original_author_id":0,"body":"Published on dev and confirmed: the form numbers show in the visit's list of documents. Closing.","assets":[],"created_at":"2026-10-05T11:28:03-05:00","updated_at":"2026-10-05T11:28:03-05:00"},{"id":963,"html_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/92#issuecomment-963","pull_request_url":"","issue_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/92","user":{"id":1,"login":"charles","login_name":"","source_id":0,"full_name":"Charles Willgren","email":"charles@noreply.www-s01.apinet.com","avatar_url":"https:\/\/www-s01.apinet.com\/codeforge\/avatars\/d3c894f7297c5a18eb3f6ac837c335b11a00aa9cc0961323771632b1e2d61bb2","html_url":"https:\/\/www-s01.apinet.com\/codeforge\/charles","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2025-12-08T10:03:41-06:00","restricted":false,"active":false,"prohibit_login":false,"location":"","pronouns":"","website":"","description":"","visibility":"public","followers_count":0,"following_count":0,"starred_repos_count":0,"username":"charles"},"original_author":"","original_author_id":0,"body":"**Built, not yet published (5 Oct 2026).**\n\n- Authorized weekly hours are no longer a question. `auth.weekly_hours` is in `FORM_V2_FROZEN_KEYS`, so it prints straight from the visit's copy of the VESTA authorization and no answer can change it. The data dictionary went to version 3, so every interview and release has to be republished.\n- The visit's schedule step shows **\"Authorized: 20.00 hours a week\"**, read-only, under the totals, and says *\"The schedule is X hours over\"* when the schedule adds up to more. This is a notice only. Enforcing the limit is H3.\n- The question is gone from `docs\/form-v2-interviews\/SOC_AO.json`, and the service plan step's intro says where the hours are shown now.\n- **`auth.days_per_week` stays asked.** The customer said the time frame may change, and days per week is the time frame.\n- The Form Explorer shows it as *\"Shown from the authorization, cannot be changed at the visit\"*.\n\n**To finish:** the drafts are imported on dev (`form-v2-pipeline.php --packet=SOC_AO --import --replace`) and the rehearsal passes all nine checks. Next: review and publish on `\/admin\/form-v2-publish`, then choose the release on `\/admin\/form-v2-releases`.","assets":[],"created_at":"2026-10-05T11:39:41-05:00","updated_at":"2026-10-05T11:39:41-05:00"},{"id":964,"html_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/91#issuecomment-964","pull_request_url":"","issue_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/91","user":{"id":1,"login":"charles","login_name":"","source_id":0,"full_name":"Charles Willgren","email":"charles@noreply.www-s01.apinet.com","avatar_url":"https:\/\/www-s01.apinet.com\/codeforge\/avatars\/d3c894f7297c5a18eb3f6ac837c335b11a00aa9cc0961323771632b1e2d61bb2","html_url":"https:\/\/www-s01.apinet.com\/codeforge\/charles","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2025-12-08T10:03:41-06:00","restricted":false,"active":false,"prohibit_login":false,"location":"","pronouns":"","website":"","description":"","visibility":"public","followers_count":0,"following_count":0,"starred_repos_count":0,"username":"charles"},"original_author":"","original_author_id":0,"body":"**Built, not yet published (5 Oct 2026).**\n\n- Times are still entered as start and end. **Each attendant's day has to come out in quarter hours.** The server refuses a `schedule.attendant_N_{day}` cell whose total isn't a multiple of 15 minutes (`FORM_V2_SCHEDULE_STEP_MINUTES`). The refusal says what the times come to: *\"These times come to 1 hour 10 minutes. Each day's hours must come out in quarter hours (1.00, 1.25, 1.50, 1.75), so move a start or end time.\"* Odd minutes that add up are fine (8:10\u20139:25 = 1.25), and a split day is judged on its total.\n- The visit page marks an off-step day in red as it is typed, and shows every hours figure to two decimals (cells, per-attendant week, all-attendant totals).\n- A VESTA schedule day that is off the step isn't carried into the visit. The supervisor sees \"VESTA has \u2026, which could not be used\" and enters it properly.\n- **The printed forms show two decimals.** There's a new `decimals` key on `number` fields, set to 2 on all 30 hours boxes: the 3040 (schedule totals, hours per attendant, authorized hours), the service plan (schedule totals, Total Hours) and both consents (hours per week).\n\n**To finish:** same publish as #92. It needs new versions of the 3040, the service plan and both consent forms, which the pipeline rehearsal already covers.","assets":[],"created_at":"2026-10-05T11:39:42-05:00","updated_at":"2026-10-05T11:39:42-05:00"},{"id":966,"html_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/86#issuecomment-966","pull_request_url":"","issue_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/86","user":{"id":1,"login":"charles","login_name":"","source_id":0,"full_name":"Charles Willgren","email":"charles@noreply.www-s01.apinet.com","avatar_url":"https:\/\/www-s01.apinet.com\/codeforge\/avatars\/d3c894f7297c5a18eb3f6ac837c335b11a00aa9cc0961323771632b1e2d61bb2","html_url":"https:\/\/www-s01.apinet.com\/codeforge\/charles","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2025-12-08T10:03:41-06:00","restricted":false,"active":false,"prohibit_login":false,"location":"","pronouns":"","website":"","description":"","visibility":"public","followers_count":0,"following_count":0,"starred_repos_count":0,"username":"charles"},"original_author":"","original_author_id":0,"body":"**Built, not yet published (5 Oct 2026).**\n\n- The service end date question is removed from `docs\/form-v2-interviews\/SOC_AO.json` and recorded in its `not_asked`, with the customer's reason.\n- Only one form prints it: the service plan's \"End Date (if applicable)\". No form requires it, so the publish check accepts it. It now prints blank, because a value that isn't asked is never projected, even though VESTA has one.\n- The Form Explorer shows it as *\"Not asked: prints blank\"*, with the reason.\n\n**To finish:** same publish as #92 \/ #91.","assets":[],"created_at":"2026-10-05T11:39:42-05:00","updated_at":"2026-10-05T11:39:42-05:00"},{"id":969,"html_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/91#issuecomment-969","pull_request_url":"","issue_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/91","user":{"id":1,"login":"charles","login_name":"","source_id":0,"full_name":"Charles Willgren","email":"charles@noreply.www-s01.apinet.com","avatar_url":"https:\/\/www-s01.apinet.com\/codeforge\/avatars\/d3c894f7297c5a18eb3f6ac837c335b11a00aa9cc0961323771632b1e2d61bb2","html_url":"https:\/\/www-s01.apinet.com\/codeforge\/charles","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2025-12-08T10:03:41-06:00","restricted":false,"active":false,"prohibit_login":false,"location":"","pronouns":"","website":"","description":"","visibility":"public","followers_count":0,"following_count":0,"starred_repos_count":0,"username":"charles"},"original_author":"","original_author_id":0,"body":"**Changed:** a VESTA schedule day that doesn't come out in quarter hours is now **still filled in**. It carries the same message a typed one gets (\"These times come to 1 hour 10 minutes. Each day's hours must come out in quarter hours\u2026\"), shown under the cell and listed on the visit's check. The forms can't be printed for signing until it is fixed. A day the supervisor types off the quarter hour is still refused when saved. The rule lives in one place (`form_v2_visit_value_problem()`), and the save, the check and the page all read it.","assets":[],"created_at":"2026-10-05T11:43:02-05:00","updated_at":"2026-10-05T11:43:02-05:00"},{"id":970,"html_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/92#issuecomment-970","pull_request_url":"","issue_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/92","user":{"id":1,"login":"charles","login_name":"","source_id":0,"full_name":"Charles Willgren","email":"charles@noreply.www-s01.apinet.com","avatar_url":"https:\/\/www-s01.apinet.com\/codeforge\/avatars\/d3c894f7297c5a18eb3f6ac837c335b11a00aa9cc0961323771632b1e2d61bb2","html_url":"https:\/\/www-s01.apinet.com\/codeforge\/charles","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2025-12-08T10:03:41-06:00","restricted":false,"active":false,"prohibit_login":false,"location":"","pronouns":"","website":"","description":"","visibility":"public","followers_count":0,"following_count":0,"starred_repos_count":0,"username":"charles"},"original_author":"","original_author_id":0,"body":"Committed in efc8b74. Closing. To reach the customer, the SOC_AO release still has to be published (`\/admin\/form-v2-publish`) and chosen for each agency (`\/admin\/form-v2-releases`).","assets":[],"created_at":"2026-10-05T11:54:03-05:00","updated_at":"2026-10-05T11:54:03-05:00"},{"id":971,"html_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/91#issuecomment-971","pull_request_url":"","issue_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/91","user":{"id":1,"login":"charles","login_name":"","source_id":0,"full_name":"Charles Willgren","email":"charles@noreply.www-s01.apinet.com","avatar_url":"https:\/\/www-s01.apinet.com\/codeforge\/avatars\/d3c894f7297c5a18eb3f6ac837c335b11a00aa9cc0961323771632b1e2d61bb2","html_url":"https:\/\/www-s01.apinet.com\/codeforge\/charles","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2025-12-08T10:03:41-06:00","restricted":false,"active":false,"prohibit_login":false,"location":"","pronouns":"","website":"","description":"","visibility":"public","followers_count":0,"following_count":0,"starred_repos_count":0,"username":"charles"},"original_author":"","original_author_id":0,"body":"Committed in efc8b74. Closing. To reach the customer, the SOC_AO release still has to be published (`\/admin\/form-v2-publish`, which includes new versions of the 3040, the service plan and both consent forms) and chosen for each agency (`\/admin\/form-v2-releases`).","assets":[],"created_at":"2026-10-05T11:54:03-05:00","updated_at":"2026-10-05T11:54:03-05:00"},{"id":972,"html_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/86#issuecomment-972","pull_request_url":"","issue_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/86","user":{"id":1,"login":"charles","login_name":"","source_id":0,"full_name":"Charles Willgren","email":"charles@noreply.www-s01.apinet.com","avatar_url":"https:\/\/www-s01.apinet.com\/codeforge\/avatars\/d3c894f7297c5a18eb3f6ac837c335b11a00aa9cc0961323771632b1e2d61bb2","html_url":"https:\/\/www-s01.apinet.com\/codeforge\/charles","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2025-12-08T10:03:41-06:00","restricted":false,"active":false,"prohibit_login":false,"location":"","pronouns":"","website":"","description":"","visibility":"public","followers_count":0,"following_count":0,"starred_repos_count":0,"username":"charles"},"original_author":"","original_author_id":0,"body":"Committed in efc8b74. Closing. To reach the customer, the SOC_AO release still has to be published (`\/admin\/form-v2-publish`) and chosen for each agency (`\/admin\/form-v2-releases`).","assets":[],"created_at":"2026-10-05T11:54:03-05:00","updated_at":"2026-10-05T11:54:03-05:00"},{"id":977,"html_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/138#issuecomment-977","pull_request_url":"","issue_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/138","user":{"id":3,"login":"connect-bot","login_name":"","source_id":0,"full_name":"","email":"connect-bot@noreply.www-s01.apinet.com","avatar_url":"https:\/\/www-s01.apinet.com\/codeforge\/avatars\/68a2723f7ad70dee2e1415be7488d84b","html_url":"https:\/\/www-s01.apinet.com\/codeforge\/connect-bot","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2026-10-01T08:49:35-05:00","restricted":false,"active":false,"prohibit_login":false,"location":"","pronouns":"","website":"","description":"","visibility":"public","followers_count":0,"following_count":0,"starred_repos_count":0,"username":"connect-bot"},"original_author":"","original_author_id":0,"body":"**Charles W.** _(via Connect)_\n<!-- connect:user=1 -->\n\nThe form blank includes pre-filled \"Fall or Injury\" and \"Rash or Skin Breakdown\" as those are the health problems the attendant must report. We don't change the wording on the interview but we include those two items. The form is answered yes\/no as an acknowledgement. When generating, put checks on the items on the form if they answer Yes.","assets":[],"created_at":"2026-10-05T11:58:56-05:00","updated_at":"2026-10-05T11:58:56-05:00"},{"id":978,"html_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/138#issuecomment-978","pull_request_url":"","issue_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/138","user":{"id":1,"login":"charles","login_name":"","source_id":0,"full_name":"Charles Willgren","email":"charles@noreply.www-s01.apinet.com","avatar_url":"https:\/\/www-s01.apinet.com\/codeforge\/avatars\/d3c894f7297c5a18eb3f6ac837c335b11a00aa9cc0961323771632b1e2d61bb2","html_url":"https:\/\/www-s01.apinet.com\/codeforge\/charles","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2025-12-08T10:03:41-06:00","restricted":false,"active":false,"prohibit_login":false,"location":"","pronouns":"","website":"","description":"","visibility":"public","followers_count":0,"following_count":0,"starred_repos_count":0,"username":"charles"},"original_author":"","original_author_id":0,"body":"Done in the files (not yet committed or published):\n\n- **Definition** (`docs\/forms\/forms-3040.json`): `ori_report_health_problems` is now a Yes\/No (`checkbox`) instead of free text. Its help text lists the two problems as the paper prints them (Fall or Injury, Rash or Skin Breakdown), so they show with the question.\n- **Interview** (`SOC_AO.json`): the wording is unchanged (\"Which health problems must the attendant report?\"). The help now says to answer Yes once the attendant has been told.\n- **Printing** (`docs\/form-placements\/forms-3040.json`): a Yes puts an X in item 10-4's box (it was not placed before) and a \u2713 beside each of the two printed problems. A No prints nothing. Checked on a proof.\n- **Pipeline fix** found along the way: the interview import was seeded from the *published* definitions but checked against the new ones, so a field whose type changed was refused on every run. The import now reads the definitions about to be published. Pinned in `test-form-v2-pipeline-state`.\n\nDefaulting it to Yes is left to #101, which is still open.\n\nTo ship: `form-v2-pipeline.php --packet=SOC_AO --import` (already rehearsed clean on dev), then review and publish on `\/admin\/form-v2-publish`.","assets":[],"created_at":"2026-10-05T12:06:29-05:00","updated_at":"2026-10-05T12:06:29-05:00"},{"id":984,"html_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/146#issuecomment-984","pull_request_url":"","issue_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/146","user":{"id":1,"login":"charles","login_name":"","source_id":0,"full_name":"Charles Willgren","email":"charles@noreply.www-s01.apinet.com","avatar_url":"https:\/\/www-s01.apinet.com\/codeforge\/avatars\/d3c894f7297c5a18eb3f6ac837c335b11a00aa9cc0961323771632b1e2d61bb2","html_url":"https:\/\/www-s01.apinet.com\/codeforge\/charles","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2025-12-08T10:03:41-06:00","restricted":false,"active":false,"prohibit_login":false,"location":"","pronouns":"","website":"","description":"","visibility":"public","followers_count":0,"following_count":0,"starred_repos_count":0,"username":"charles"},"original_author":"","original_author_id":0,"body":"Fixed in `pages\/admin\/systems-edit.php` (not yet committed).\n\n**What was wrong:** the single \"Vesta Agency ID\" box saved a `vesta_agency_id` system setting that **nothing reads**. The pipeline maps VESTA agency \u2192 system with the constant `HH_AGENCY_SYSTEM` in `code\/functions_hhm.inc.php` (347 + 353 \u2192 11, 524 \u2192 10, 354 \u2192 9). Typing a second ID into the box would have changed nothing.\n\n**What changed:** the box is replaced by a read-only list of every VESTA agency ID that feeds the system, taken from `HH_AGENCY_SYSTEM` and named from `$SITE['agencies']`. For example, system 11 shows `347 LHHA CBR` and `353 LHHA RGV`, with the note \"Set in the data pipeline, not here.\" The save no longer writes the setting. Any old rows are left in place, unread. I checked that system 11 renders correctly on dev.\n\n**Not done:** making the mapping editable on screen. That would mean moving `HH_AGENCY_SYSTEM`, the CLI loaders' local `AGENCY_SYSTEM` copies and `get-reports.js`'s list into the database. If that's wanted, it should be its own issue.\n\nChangelog and UserChangelog updated.","assets":[],"created_at":"2026-10-05T13:27:36-05:00","updated_at":"2026-10-05T13:27:36-05:00"},{"id":985,"html_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/146#issuecomment-985","pull_request_url":"","issue_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/146","user":{"id":1,"login":"charles","login_name":"","source_id":0,"full_name":"Charles Willgren","email":"charles@noreply.www-s01.apinet.com","avatar_url":"https:\/\/www-s01.apinet.com\/codeforge\/avatars\/d3c894f7297c5a18eb3f6ac837c335b11a00aa9cc0961323771632b1e2d61bb2","html_url":"https:\/\/www-s01.apinet.com\/codeforge\/charles","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2025-12-08T10:03:41-06:00","restricted":false,"active":false,"prohibit_login":false,"location":"","pronouns":"","website":"","description":"","visibility":"public","followers_count":0,"following_count":0,"starred_repos_count":0,"username":"charles"},"original_author":"","original_author_id":0,"body":"Closing. The systems editor now lists every VESTA agency ID that feeds a system, read-only, from `HH_AGENCY_SYSTEM`. Making the mapping editable on screen would be a separate issue, if it's wanted.","assets":[],"created_at":"2026-10-05T13:29:54-05:00","updated_at":"2026-10-05T13:29:54-05:00"},{"id":987,"html_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/144#issuecomment-987","pull_request_url":"","issue_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/144","user":{"id":1,"login":"charles","login_name":"","source_id":0,"full_name":"Charles Willgren","email":"charles@noreply.www-s01.apinet.com","avatar_url":"https:\/\/www-s01.apinet.com\/codeforge\/avatars\/d3c894f7297c5a18eb3f6ac837c335b11a00aa9cc0961323771632b1e2d61bb2","html_url":"https:\/\/www-s01.apinet.com\/codeforge\/charles","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2025-12-08T10:03:41-06:00","restricted":false,"active":false,"prohibit_login":false,"location":"","pronouns":"","website":"","description":"","visibility":"public","followers_count":0,"following_count":0,"starred_repos_count":0,"username":"charles"},"original_author":"","original_author_id":0,"body":"Done in ac295e1 (`pages\/admin\/systems-edit.php`):\n\n* **Logo** moved into the right-hand column with the color settings.\n* **Unexplained blank fields** removed. These were eight `office_*` \/ `mailing_*` address settings with no label. The save ignored them and nothing read them; the agency's address is the Address field in the Agency section.\n* **Agency section** is now a compact two-column grid with one shared help line. System Name, Short Name and the VESTA agency IDs share a row, and each color is paired with a small preview swatch.\n* **Help text** no longer mentions form prefill.\n\nThe VESTA agency ID box was then changed to a read-only list in #146.","assets":[],"created_at":"2026-10-05T13:30:31-05:00","updated_at":"2026-10-05T13:30:31-05:00"},{"id":990,"html_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/138#issuecomment-990","pull_request_url":"","issue_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/138","user":{"id":1,"login":"charles","login_name":"","source_id":0,"full_name":"Charles Willgren","email":"charles@noreply.www-s01.apinet.com","avatar_url":"https:\/\/www-s01.apinet.com\/codeforge\/avatars\/d3c894f7297c5a18eb3f6ac837c335b11a00aa9cc0961323771632b1e2d61bb2","html_url":"https:\/\/www-s01.apinet.com\/codeforge\/charles","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2025-12-08T10:03:41-06:00","restricted":false,"active":false,"prohibit_login":false,"location":"","pronouns":"","website":"","description":"","visibility":"public","followers_count":0,"following_count":0,"starred_repos_count":0,"username":"charles"},"original_author":"","original_author_id":0,"body":"Closing: 10-4 is now a Yes\/No reminder, and a Yes ticks the box and checks both printed problems (details above). It reaches visits with the next SOC\/AO publish on `\/admin\/form-v2-publish`. Defaulting it to Yes is tracked in #101.","assets":[],"created_at":"2026-10-05T13:31:49-05:00","updated_at":"2026-10-05T13:31:49-05:00"},{"id":993,"html_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/142#issuecomment-993","pull_request_url":"","issue_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/142","user":{"id":1,"login":"charles","login_name":"","source_id":0,"full_name":"Charles Willgren","email":"charles@noreply.www-s01.apinet.com","avatar_url":"https:\/\/www-s01.apinet.com\/codeforge\/avatars\/d3c894f7297c5a18eb3f6ac837c335b11a00aa9cc0961323771632b1e2d61bb2","html_url":"https:\/\/www-s01.apinet.com\/codeforge\/charles","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2025-12-08T10:03:41-06:00","restricted":false,"active":false,"prohibit_login":false,"location":"","pronouns":"","website":"","description":"","visibility":"public","followers_count":0,"following_count":0,"starred_repos_count":0,"username":"charles"},"original_author":"","original_author_id":0,"body":"Confirmed on production: the agency administrator is set to \"Ambrose Hernandez\". All good \u2014 closing.","assets":[],"created_at":"2026-10-05T14:08:29-05:00","updated_at":"2026-10-05T14:08:29-05:00"},{"id":995,"html_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/87#issuecomment-995","pull_request_url":"","issue_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/87","user":{"id":1,"login":"charles","login_name":"","source_id":0,"full_name":"Charles Willgren","email":"charles@noreply.www-s01.apinet.com","avatar_url":"https:\/\/www-s01.apinet.com\/codeforge\/avatars\/d3c894f7297c5a18eb3f6ac837c335b11a00aa9cc0961323771632b1e2d61bb2","html_url":"https:\/\/www-s01.apinet.com\/codeforge\/charles","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2025-12-08T10:03:41-06:00","restricted":false,"active":false,"prohibit_login":false,"location":"","pronouns":"","website":"","description":"","visibility":"public","followers_count":0,"following_count":0,"starred_repos_count":0,"username":"charles"},"original_author":"","original_author_id":0,"body":"Done in the working tree (not yet committed or published). `shared.supervision_level` is now a fixed value (new derive op `fixed` in `code\/form_v2_shared.inc.php`): it's never asked and always prints **Non-RN**, which is how both the service plan's \"Plan of Supervision\" and the 3040's \"Level of Supervision\" say Supervisor. The question is gone from `docs\/form-v2-interviews\/SOC_AO.json`. Takes effect after `form-v2-pipeline.php --packet=SOC_AO --import --replace` and a publish.","assets":[],"created_at":"2026-10-05T14:17:29-05:00","updated_at":"2026-10-05T14:17:29-05:00"},{"id":996,"html_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/96#issuecomment-996","pull_request_url":"","issue_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/96","user":{"id":1,"login":"charles","login_name":"","source_id":0,"full_name":"Charles Willgren","email":"charles@noreply.www-s01.apinet.com","avatar_url":"https:\/\/www-s01.apinet.com\/codeforge\/avatars\/d3c894f7297c5a18eb3f6ac837c335b11a00aa9cc0961323771632b1e2d61bb2","html_url":"https:\/\/www-s01.apinet.com\/codeforge\/charles","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2025-12-08T10:03:41-06:00","restricted":false,"active":false,"prohibit_login":false,"location":"","pronouns":"","website":"","description":"","visibility":"public","followers_count":0,"following_count":0,"starred_repos_count":0,"username":"charles"},"original_author":"","original_author_id":0,"body":"**Decision (owner, 5 Oct 2026):** remove the question and always print Yes.\n\nDone in the working tree (not yet committed or published). New fixed value `shared.continues_to_need_services` (claims `forms-3040.continues_to_need_services`), which always prints **Yes** on 3A. The question is gone from `SOC_AO.json`. Takes effect after the SOC_AO import and publish.","assets":[],"created_at":"2026-10-05T14:17:29-05:00","updated_at":"2026-10-05T14:17:29-05:00"},{"id":997,"html_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/97#issuecomment-997","pull_request_url":"","issue_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/97","user":{"id":1,"login":"charles","login_name":"","source_id":0,"full_name":"Charles Willgren","email":"charles@noreply.www-s01.apinet.com","avatar_url":"https:\/\/www-s01.apinet.com\/codeforge\/avatars\/d3c894f7297c5a18eb3f6ac837c335b11a00aa9cc0961323771632b1e2d61bb2","html_url":"https:\/\/www-s01.apinet.com\/codeforge\/charles","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2025-12-08T10:03:41-06:00","restricted":false,"active":false,"prohibit_login":false,"location":"","pronouns":"","website":"","description":"","visibility":"public","followers_count":0,"following_count":0,"starred_repos_count":0,"username":"charles"},"original_author":"","original_author_id":0,"body":"Done in the working tree (not yet committed or published). New fixed value `shared.schedule_variable` (claims `forms-3040.schedule_variable`), which always marks **\"Is not variable\"**. No follow-up questions depended on it. The question is gone from `SOC_AO.json`. Takes effect after the SOC_AO import and publish.","assets":[],"created_at":"2026-10-05T14:17:29-05:00","updated_at":"2026-10-05T14:17:29-05:00"},{"id":998,"html_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/139#issuecomment-998","pull_request_url":"","issue_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/139","user":{"id":1,"login":"charles","login_name":"","source_id":0,"full_name":"Charles Willgren","email":"charles@noreply.www-s01.apinet.com","avatar_url":"https:\/\/www-s01.apinet.com\/codeforge\/avatars\/d3c894f7297c5a18eb3f6ac837c335b11a00aa9cc0961323771632b1e2d61bb2","html_url":"https:\/\/www-s01.apinet.com\/codeforge\/charles","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2025-12-08T10:03:41-06:00","restricted":false,"active":false,"prohibit_login":false,"location":"","pronouns":"","website":"","description":"","visibility":"public","followers_count":0,"following_count":0,"starred_repos_count":0,"username":"charles"},"original_author":"","original_author_id":0,"body":"Done in the working tree (not yet committed or published).\n\n1. The paper reads \"ATTENDANT SCHEDULE (for use by provider agency) FWD: ____  Schedule \u2610 Is \u2610 Is not variable\". The blank is a date, which fits \"pulls from Service Plan Start Date\". The paper doesn't spell out \"FWD\".\n2. `forms-3040.schedule_fwd` is now a `date` field prefilled from `auth.service_start_date`, the same value the service plan prints as its Start Date. So it's one question, asked on the service plan step and confirmed against VESTA, and the 3040 prints it as a date (placement `format: date`). The Explorer shows its source as that question. The free-text \"Schedule note (FWD)\" question is removed from `SOC_AO.json`.\n\nTakes effect after the SOC_AO import and publish.","assets":[],"created_at":"2026-10-05T14:17:29-05:00","updated_at":"2026-10-05T14:17:29-05:00"},{"id":999,"html_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/87#issuecomment-999","pull_request_url":"","issue_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/87","user":{"id":1,"login":"charles","login_name":"","source_id":0,"full_name":"Charles Willgren","email":"charles@noreply.www-s01.apinet.com","avatar_url":"https:\/\/www-s01.apinet.com\/codeforge\/avatars\/d3c894f7297c5a18eb3f6ac837c335b11a00aa9cc0961323771632b1e2d61bb2","html_url":"https:\/\/www-s01.apinet.com\/codeforge\/charles","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2025-12-08T10:03:41-06:00","restricted":false,"active":false,"prohibit_login":false,"location":"","pronouns":"","website":"","description":"","visibility":"public","followers_count":0,"following_count":0,"starred_repos_count":0,"username":"charles"},"original_author":"","original_author_id":0,"body":"Deployed to production 5 Oct 2026. Closing.","assets":[],"created_at":"2026-10-05T14:21:35-05:00","updated_at":"2026-10-05T14:21:35-05:00"},{"id":1000,"html_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/96#issuecomment-1000","pull_request_url":"","issue_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/96","user":{"id":1,"login":"charles","login_name":"","source_id":0,"full_name":"Charles Willgren","email":"charles@noreply.www-s01.apinet.com","avatar_url":"https:\/\/www-s01.apinet.com\/codeforge\/avatars\/d3c894f7297c5a18eb3f6ac837c335b11a00aa9cc0961323771632b1e2d61bb2","html_url":"https:\/\/www-s01.apinet.com\/codeforge\/charles","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2025-12-08T10:03:41-06:00","restricted":false,"active":false,"prohibit_login":false,"location":"","pronouns":"","website":"","description":"","visibility":"public","followers_count":0,"following_count":0,"starred_repos_count":0,"username":"charles"},"original_author":"","original_author_id":0,"body":"Deployed to production 5 Oct 2026. Closing.","assets":[],"created_at":"2026-10-05T14:21:35-05:00","updated_at":"2026-10-05T14:21:35-05:00"},{"id":1001,"html_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/97#issuecomment-1001","pull_request_url":"","issue_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/97","user":{"id":1,"login":"charles","login_name":"","source_id":0,"full_name":"Charles Willgren","email":"charles@noreply.www-s01.apinet.com","avatar_url":"https:\/\/www-s01.apinet.com\/codeforge\/avatars\/d3c894f7297c5a18eb3f6ac837c335b11a00aa9cc0961323771632b1e2d61bb2","html_url":"https:\/\/www-s01.apinet.com\/codeforge\/charles","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2025-12-08T10:03:41-06:00","restricted":false,"active":false,"prohibit_login":false,"location":"","pronouns":"","website":"","description":"","visibility":"public","followers_count":0,"following_count":0,"starred_repos_count":0,"username":"charles"},"original_author":"","original_author_id":0,"body":"Deployed to production 5 Oct 2026. Closing.","assets":[],"created_at":"2026-10-05T14:21:35-05:00","updated_at":"2026-10-05T14:21:35-05:00"},{"id":1002,"html_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/139#issuecomment-1002","pull_request_url":"","issue_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/139","user":{"id":1,"login":"charles","login_name":"","source_id":0,"full_name":"Charles Willgren","email":"charles@noreply.www-s01.apinet.com","avatar_url":"https:\/\/www-s01.apinet.com\/codeforge\/avatars\/d3c894f7297c5a18eb3f6ac837c335b11a00aa9cc0961323771632b1e2d61bb2","html_url":"https:\/\/www-s01.apinet.com\/codeforge\/charles","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2025-12-08T10:03:41-06:00","restricted":false,"active":false,"prohibit_login":false,"location":"","pronouns":"","website":"","description":"","visibility":"public","followers_count":0,"following_count":0,"starred_repos_count":0,"username":"charles"},"original_author":"","original_author_id":0,"body":"Deployed to production 5 Oct 2026. Closing.","assets":[],"created_at":"2026-10-05T14:21:35-05:00","updated_at":"2026-10-05T14:21:35-05:00"},{"id":1008,"html_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/78#issuecomment-1008","pull_request_url":"","issue_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/78","user":{"id":1,"login":"charles","login_name":"","source_id":0,"full_name":"Charles Willgren","email":"charles@noreply.www-s01.apinet.com","avatar_url":"https:\/\/www-s01.apinet.com\/codeforge\/avatars\/d3c894f7297c5a18eb3f6ac837c335b11a00aa9cc0961323771632b1e2d61bb2","html_url":"https:\/\/www-s01.apinet.com\/codeforge\/charles","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2025-12-08T10:03:41-06:00","restricted":false,"active":false,"prohibit_login":false,"location":"","pronouns":"","website":"","description":"","visibility":"public","followers_count":0,"following_count":0,"starred_repos_count":0,"username":"charles"},"original_author":"","original_author_id":0,"body":"Deployed to production 5 Oct 2026. The visit screen shows \"Form 3040, item N\" beside each question the 3040 numbers, and the Form Explorer shows the number on each box row. The 3040 is the only Start of Care form that prints question numbers.\n\nThe leftover \"add the numbers to the data-element list (R1)\" isn't needed. That list was a one-off snapshot from 29 Sep, and the Form Explorer replaced it; the Explorer already shows the numbers. Closing.","assets":[],"created_at":"2026-10-05T14:24:13-05:00","updated_at":"2026-10-05T14:24:13-05:00"},{"id":1012,"html_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/89#issuecomment-1012","pull_request_url":"","issue_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/89","user":{"id":1,"login":"charles","login_name":"","source_id":0,"full_name":"Charles Willgren","email":"charles@noreply.www-s01.apinet.com","avatar_url":"https:\/\/www-s01.apinet.com\/codeforge\/avatars\/d3c894f7297c5a18eb3f6ac837c335b11a00aa9cc0961323771632b1e2d61bb2","html_url":"https:\/\/www-s01.apinet.com\/codeforge\/charles","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2025-12-08T10:03:41-06:00","restricted":false,"active":false,"prohibit_login":false,"location":"","pronouns":"","website":"","description":"","visibility":"public","followers_count":0,"following_count":0,"starred_repos_count":0,"username":"charles"},"original_author":"","original_author_id":0,"body":"**Done (5 Oct 2026).** The service plan's tasks are now the tasks authorized in VESTA, and they can't be changed at the visit.\n\n**What the supervisor sees**\n- The service plan step shows \"The tasks the client is authorized for\", read-only, in place of the tick list. It says that a wrong task is fixed by asking the office to correct the authorization in VESTA, the same route as the hours (#92).\n- If VESTA lists no tasks for the client, the step says so instead of showing an empty list.\n\n**What prints**\n- The service plan, the coordination of care form and the task guide (#102) all print from that one list.\n- **\"Other tasks\"** is no longer asked. A task VESTA doesn't list isn't authorized, so the \"Other\" task lines on the service plan and the coordination of care form print blank.\n\n**Checked on dev** (production data, demo client): her 8 VESTA tasks show read-only, and the same 8 print on all three forms.\n\n**Technical:** `auth.service_tasks` joins `FORM_V2_FROZEN_KEYS` (data dictionary 3 \u2192 4). Its shared entry is now source context and also prints on the task guide. A new interview key, `shows`, lets a step display a fixed value read-only. `shared.plan.tasks_other` moves to `not_asked`.\n\n**To go live:** run `form-v2-pipeline.php --packet=SOC_AO --import --replace`, review and publish on `\/admin\/form-v2-publish`, then choose the new release on `\/admin\/form-v2-releases`. Visits already started keep their current paperwork.\n\nNot changed: the 3040's orientation task grid (A4) still asks about every task.","assets":[],"created_at":"2026-10-05T15:31:17-05:00","updated_at":"2026-10-05T15:31:17-05:00"},{"id":1015,"html_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/102#issuecomment-1015","pull_request_url":"","issue_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/102","user":{"id":1,"login":"charles","login_name":"","source_id":0,"full_name":"Charles Willgren","email":"charles@noreply.www-s01.apinet.com","avatar_url":"https:\/\/www-s01.apinet.com\/codeforge\/avatars\/d3c894f7297c5a18eb3f6ac837c335b11a00aa9cc0961323771632b1e2d61bb2","html_url":"https:\/\/www-s01.apinet.com\/codeforge\/charles","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2025-12-08T10:03:41-06:00","restricted":false,"active":false,"prohibit_login":false,"location":"","pronouns":"","website":"","description":"","visibility":"public","followers_count":0,"following_count":0,"starred_repos_count":0,"username":"charles"},"original_author":"","original_author_id":0,"body":"**Decided and done (5 Oct 2026).** This follows from #89: the client's tasks are now VESTA's authorized list. We used both options, one on the screen and one on the paper.\n\n- **On screen: only the client's tasks.** The task guide step lists just the tasks the client is authorized for, each with what the task guide says it includes, so the supervisor goes over only those. Tasks that share a guide (transfer and ambulation, exercising and walking) appear as one line.\n- **On paper: the full guide, with the client's tasks marked.** The printed task guide is one fixed page, so nothing is cut from it. Each of the client's guides gets an X beside its heading. The marks were already measured on the page.\n\n**Checked on dev** (demo client, 8 tasks): the screen shows only her 8 tasks. The printed guide marks guides 01, 02, 05\/5A, 06\/07, 10, 11, 12 and 14.\n\n**Technical:** `task-guide.task_guide_reviewed` is now a target of the frozen `auth.service_tasks` entry, mapped to the guide codes. The step's `shows` carries each task's text as `option_info`.\n\nIt goes live with the same publish as #89.","assets":[],"created_at":"2026-10-05T15:31:17-05:00","updated_at":"2026-10-05T15:31:17-05:00"},{"id":1020,"html_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/127#issuecomment-1020","pull_request_url":"","issue_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/127","user":{"id":1,"login":"charles","login_name":"","source_id":0,"full_name":"Charles Willgren","email":"charles@noreply.www-s01.apinet.com","avatar_url":"https:\/\/www-s01.apinet.com\/codeforge\/avatars\/d3c894f7297c5a18eb3f6ac837c335b11a00aa9cc0961323771632b1e2d61bb2","html_url":"https:\/\/www-s01.apinet.com\/codeforge\/charles","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2025-12-08T10:03:41-06:00","restricted":false,"active":false,"prohibit_login":false,"location":"","pronouns":"","website":"","description":"","visibility":"public","followers_count":0,"following_count":0,"starred_repos_count":0,"username":"charles"},"original_author":"","original_author_id":0,"body":"**Closing \u2014 committed and verified (2026-10-05).**\n\nThe pipeline is on `main` (`ef52232`, `745cfee`, `3bbf2db`): `scripts\/form-v2-pipeline.php`, `code\/form_v2_pipeline.inc.php`, `\/admin\/form-v2-publish`, and `scripts\/test-form-v2-pipeline-state.php` (25 passed, 0 failed).\n\nChecked against the issue:\n- **import \u2192 validate \u2192 publish \u2192 release \u2192 (activate):** one command, one transaction. Activation is refused on production and is #128's.\n- **Dry run by default, `--apply` to write:** yes. The dry run is a rehearsal that gets rolled back.\n- **Idempotent:** an unchanged file writes nothing, and unchanged content makes no new release.\n- **Same checks as the screens, refusals printed:** it uses the screens' own publishers and the #130 check.\n- **Interview publish, release assembly, single command:** all built.\n\nStill outside the chain, on purpose: packets (`import-form-packets.php --publish`).","assets":[],"created_at":"2026-10-05T15:41:54-05:00","updated_at":"2026-10-05T15:41:54-05:00"},{"id":1024,"html_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/130#issuecomment-1024","pull_request_url":"","issue_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/130","user":{"id":1,"login":"charles","login_name":"","source_id":0,"full_name":"Charles Willgren","email":"charles@noreply.www-s01.apinet.com","avatar_url":"https:\/\/www-s01.apinet.com\/codeforge\/avatars\/d3c894f7297c5a18eb3f6ac837c335b11a00aa9cc0961323771632b1e2d61bb2","html_url":"https:\/\/www-s01.apinet.com\/codeforge\/charles","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2025-12-08T10:03:41-06:00","restricted":false,"active":false,"prohibit_login":false,"location":"","pronouns":"","website":"","description":"","visibility":"public","followers_count":0,"following_count":0,"starred_repos_count":0,"username":"charles"},"original_author":"","original_author_id":0,"body":"**Closing \u2014 committed and verified (2026-10-05).**\n\nOn `main` (`ef52232`, `745cfee`, `7e183f9`). `form_v2_publish_check()` in `code\/form_v2_review.inc.php` is the one implementation, and all three places call it:\n- the Explorer's Gaps tab (`backend\/formV2ExplorerGet.php`),\n- the CLI (`code\/form_v2_pipeline.inc.php`, #127),\n- the review page (`\/admin\/form-v2-publish`).\n\nSo the screen and the CLI cannot disagree.\n\nChecked against the issue:\n- **Every field filled, or blank for a recorded reason:** check 3.\n- **Every branch reachable:** check 5.\n- **No orphaned questions:** check 4.\n- **Every shared element has a ruling:** check 8. `test-form-v2-shared.php`: 202 passed, 0 failed.\n- **Every proof PDF renders:** check 9.\n- **Refuses on failure:** the publish commits only if every check passes.\n\nToday's run:\n- `test-form-v2-review.php`: 53 passed, 0 failed.\n- `test-form-v2-pipeline-state.php`: 25 passed, 0 failed.\n- `form-v2-pipeline.php --interview=SOC_AO_V2` rehearsal: all nine checks `ok`, and release `SOC_AO-20261005-5` would be published.","assets":[],"created_at":"2026-10-05T15:43:52-05:00","updated_at":"2026-10-05T15:43:52-05:00"},{"id":1045,"html_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/108#issuecomment-1045","pull_request_url":"","issue_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/108","user":{"id":1,"login":"charles","login_name":"","source_id":0,"full_name":"Charles Willgren","email":"charles@noreply.www-s01.apinet.com","avatar_url":"https:\/\/www-s01.apinet.com\/codeforge\/avatars\/d3c894f7297c5a18eb3f6ac837c335b11a00aa9cc0961323771632b1e2d61bb2","html_url":"https:\/\/www-s01.apinet.com\/codeforge\/charles","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2025-12-08T10:03:41-06:00","restricted":false,"active":false,"prohibit_login":false,"location":"","pronouns":"","website":"","description":"","visibility":"public","followers_count":0,"following_count":0,"starred_repos_count":0,"username":"charles"},"original_author":"","original_author_id":0,"body":"**Done (5 Oct 2026).** The 3040's task questions now come from the client's VESTA tasks, the same list as the service plan, the coordination of care form and the task guide (#89, #102).\n\n**What the supervisor sees**\n- The 3040's task rows are asked only for the tasks the client is authorized for in VESTA. That covers how often each task is done and, when attendants are already working, how each attendant is doing with it.\n- At an orientation, only the frequency of each authorized task is asked, as before.\n- If VESTA lists no tasks, the task grid asks nothing.\n\n**What prints**\n- The rows for the client's tasks print as answered. The other rows on the 3040 print blank.\n\n**Checked on dev** (production data, demo client): her 8 VESTA tasks give 8 frequency questions at an orientation, and 32 questions with attendants working, down from 16 and 64.\n\n**Technical:** each `form.forms-3040.task_{row}_{freq,a,b,c}` question in `SOC_AO.json` is gated on `{\"contains\": [{\"field\": \"auth.service_tasks\"}, \"<task>\"]}`, ANDed with the existing orientation gate on the A\/B\/C ratings. The 3040's 16 rows match `FORM_FACT_SERVICE_TASK_DOMAIN` one to one, which `test-form-v2-workflow` pins. No schema or dictionary change. Commit 61655ab.\n\n**To go live:** it goes out with the same publish as #89: `form-v2-pipeline.php --packet=SOC_AO --import --replace`, review and publish on `\/admin\/form-v2-publish`, then choose the new release on `\/admin\/form-v2-releases`. Visits already started keep their current paperwork.\n\nNot changed: the limit on frequency per task is T3 (#103).","assets":[],"created_at":"2026-10-05T15:55:11-05:00","updated_at":"2026-10-05T15:55:11-05:00"},{"id":1050,"html_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/84#issuecomment-1050","pull_request_url":"","issue_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/84","user":{"id":1,"login":"charles","login_name":"","source_id":0,"full_name":"Charles Willgren","email":"charles@noreply.www-s01.apinet.com","avatar_url":"https:\/\/www-s01.apinet.com\/codeforge\/avatars\/d3c894f7297c5a18eb3f6ac837c335b11a00aa9cc0961323771632b1e2d61bb2","html_url":"https:\/\/www-s01.apinet.com\/codeforge\/charles","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2025-12-08T10:03:41-06:00","restricted":false,"active":false,"prohibit_login":false,"location":"","pronouns":"","website":"","description":"","visibility":"public","followers_count":0,"following_count":0,"starred_repos_count":0,"username":"charles"},"original_author":"","original_author_id":0,"body":"Done in 5e24274. **Plan for emergencies** is now the step right after **Communication and emergency contacts**, before Health, home and needs. The other steps keep their order.\n\nChecked on dev: the interview reseeded cleanly, and a new Start of Care visit for the demo client shows the new order.\n\n**To go live:** `form-v2-pipeline.php --packet=SOC_AO --import --replace`, review and publish on `\/admin\/form-v2-publish`, then choose the release on `\/admin\/form-v2-releases`.\n\nNote: the customer's full section order (O2) may reorder the steps again.","assets":[],"created_at":"2026-10-05T15:57:32-05:00","updated_at":"2026-10-05T15:57:32-05:00"},{"id":1056,"html_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/104#issuecomment-1056","pull_request_url":"","issue_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/104","user":{"id":1,"login":"charles","login_name":"","source_id":0,"full_name":"Charles Willgren","email":"charles@noreply.www-s01.apinet.com","avatar_url":"https:\/\/www-s01.apinet.com\/codeforge\/avatars\/d3c894f7297c5a18eb3f6ac837c335b11a00aa9cc0961323771632b1e2d61bb2","html_url":"https:\/\/www-s01.apinet.com\/codeforge\/charles","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2025-12-08T10:03:41-06:00","restricted":false,"active":false,"prohibit_login":false,"location":"","pronouns":"","website":"","description":"","visibility":"public","followers_count":0,"following_count":0,"starred_repos_count":0,"username":"charles"},"original_author":"","original_author_id":0,"body":"## Found and fixed\n\n**Cause: a hidden layer in the blank Task Guide PDF.** Our placement map and the render were not at fault.\n\nThe blank (`docs\/form-blanks\/task-guide.pdf`) came from a 2021 Adobe Illustrator file. It had two layers, and **\"Layer 1\" was switched off by default**. That hidden layer held an older copy of the page:\n\n- the **previous Legacy logo** (\"Health\/Hospice & PHC\/CBA Agency \u2013 *A Legacy of Caring*\"), in the same corner where the agency logo now prints;\n- a **second copy of the bottom line**, \"This program is only for the Client \u2013 NOT the entire family\", slightly offset so it looked doubled (and second copies of the section headings).\n\nWhether you saw it depended on the viewer. Our proof tooling (poppler) respects \"off\", so every proof looked clean. Apple's built-in PDF viewer and some print paths ignore it and draw the layer. The PDF tool that combines our answers with the blank (qpdf) carried the layer into every review and signed copy. Forcing the layer on reproduced exactly what the customer described.\n\n**Ruled out:** the placement map (proofs and a rebuild of the real review \u2192 signed path draw one logo and one bottom line); stamping twice at signing (the demo-day signed copy drew no logo, as designed); and the in-page form viewer.\n\n## Fix\n- Rebuilt the blank with the hidden layer's content removed and the layer settings dropped. Also removed a damaged page thumbnail of the old page and Illustrator's private data. qpdf now reports no errors; the old file had two damaged streams.\n- The visible page is **pixel-identical** to the old blank, and the text is unchanged, so every measured box stands. Only the fingerprint pin in `docs\/form-placements\/task-guide.json` changed (`e125925c\u2026` \u2192 `3aa2ceb5\u2026`).\n- The map moved onto the new paper and was published; deployed.\n- No other blank has a hidden layer.\n\nVisits prepared before the new release keep their pinned (old) paper, so only new visits get the fix.\n\nThe guard that keeps this from happening again is a separate action item.","assets":[],"created_at":"2026-10-05T16:09:53-05:00","updated_at":"2026-10-05T16:09:53-05:00"},{"id":1123,"html_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/105#issuecomment-1123","pull_request_url":"","issue_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/105","user":{"id":1,"login":"charles","login_name":"","source_id":0,"full_name":"Charles Willgren","email":"charles@noreply.www-s01.apinet.com","avatar_url":"https:\/\/www-s01.apinet.com\/codeforge\/avatars\/d3c894f7297c5a18eb3f6ac837c335b11a00aa9cc0961323771632b1e2d61bb2","html_url":"https:\/\/www-s01.apinet.com\/codeforge\/charles","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2025-12-08T10:03:41-06:00","restricted":false,"active":false,"prohibit_login":false,"location":"","pronouns":"","website":"","description":"","visibility":"public","followers_count":0,"following_count":0,"starred_repos_count":0,"username":"charles"},"original_author":"","original_author_id":0,"body":"Done in 5e9e9f9.\n\n* Confirmed against the paper: 3B is `form.forms-3040.change_needed`, item 7 is `form.forms-3040.service_plan_adequate`.\n* Item 7 is no longer asked. It is a new shared element, `shared.service_plan_adequate`, worked out with a new derived op `map`: 3B Yes prints No on item 7, and 3B No prints Yes. If 3B is unanswered, item 7 prints blank.\n* **N\/A:** dropped, because it has no opposite. Once 3B is answered, item 7 always has an answer.\n* 3B's help now says it also answers item 7.\n* The Form Explorer shows item 7 as worked out from 3B.\n* Tests: `test-form-v2-shared` checks both directions on the real projection. It also checks that the map names every answer 3B offers.\n\n**To go live:** run `form-v2-pipeline.php --packet=SOC_AO --import --replace`, publish on `\/admin\/form-v2-publish`, then choose the release on `\/admin\/form-v2-releases`.","assets":[],"created_at":"2026-10-06T09:44:01-05:00","updated_at":"2026-10-06T09:44:01-05:00"},{"id":1124,"html_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/106#issuecomment-1124","pull_request_url":"","issue_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/106","user":{"id":1,"login":"charles","login_name":"","source_id":0,"full_name":"Charles Willgren","email":"charles@noreply.www-s01.apinet.com","avatar_url":"https:\/\/www-s01.apinet.com\/codeforge\/avatars\/d3c894f7297c5a18eb3f6ac837c335b11a00aa9cc0961323771632b1e2d61bb2","html_url":"https:\/\/www-s01.apinet.com\/codeforge\/charles","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2025-12-08T10:03:41-06:00","restricted":false,"active":false,"prohibit_login":false,"location":"","pronouns":"","website":"","description":"","visibility":"public","followers_count":0,"following_count":0,"starred_repos_count":0,"username":"charles"},"original_author":"","original_author_id":0,"body":"Done in 5e9e9f9.\n\n* `ori_report_to_name` now fills from the agency name (`system.agency_legal_name`).\n* `ori_report_to_phone` now fills from the agency's **main** phone (`system.agency_phone`), as Frank's notes asked. It does not use the 24-hour line the consents print. No new setting was needed.\n* Both questions are removed from the SOC\/AO interview. The 3040 definition is now v6.\n* \"10-4\" was already recorded as the item number (G2).\n\n**To go live:** the same publish as #105. Set each agency's phone on Admin \u2192 Systems. If it is empty, the line prints blank.","assets":[],"created_at":"2026-10-06T09:44:01-05:00","updated_at":"2026-10-06T09:44:01-05:00"},{"id":1126,"html_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/101#issuecomment-1126","pull_request_url":"","issue_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/101","user":{"id":1,"login":"charles","login_name":"","source_id":0,"full_name":"Charles Willgren","email":"charles@noreply.www-s01.apinet.com","avatar_url":"https:\/\/www-s01.apinet.com\/codeforge\/avatars\/d3c894f7297c5a18eb3f6ac837c335b11a00aa9cc0961323771632b1e2d61bb2","html_url":"https:\/\/www-s01.apinet.com\/codeforge\/charles","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2025-12-08T10:03:41-06:00","restricted":false,"active":false,"prohibit_login":false,"location":"","pronouns":"","website":"","description":"","visibility":"public","followers_count":0,"following_count":0,"starred_repos_count":0,"username":"charles"},"original_author":"","original_author_id":0,"body":"Built in 5e9e9f9. I'm leaving this open until Jane confirms the list below.\n\n**How it works:** there is a new interview setting, `starts_as`. When a visit is started, the question already holds that answer, and the record's own value wins if it has one. The screen says under the question: \"Starts as Yes. Change it if that is not what happened.\" That way it stays clear the supervisor is attesting to it. A pre-set answer that is changed never counts as a difference from VESTA.\n\n**Starts as Yes:** these are the things the supervisor did.\n- Disaster plan: went over the agency policies\n- Task Guide: went over the program's scope, the safety instructions, and when to call the supervisor\n- Things You May Not Do: explained that services are only for the client\n- 3040 orientation: the client's health condition; tasks, schedule and safety; reporting events to the supervisor; the complaint procedure given and explained\n- PAS\/PHC and PCS consents: went over the rights\n- PAS\/PHC consent: client told in writing and in person what the attendant can and cannot do\n- Private Pay: attendant instructions; the Obligation of Client and terms\n- Advance directives: client received the agency's information\n\n**Left blank on purpose:** these record what the client decides or says, and a default there would be the agency answering for the client.\n- Consent to services (all three consents)\n- \"Has the client reviewed and approved the service plan\" (PAS\/PHC and Private Pay)\n- 2-1-1: \"Does the client understand them?\"\n- 3040: \"Has the attendant had HIV \/ hepatitis training?\" (a fact about the attendant, not something explained at the visit)\n\n**Jane:** please confirm both lists. Moving a question between them is a one-line change.\n\n**To go live:** the same publish as #105.","assets":[],"created_at":"2026-10-06T09:44:01-05:00","updated_at":"2026-10-06T09:44:01-05:00"},{"id":1130,"html_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/88#issuecomment-1130","pull_request_url":"","issue_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/88","user":{"id":1,"login":"charles","login_name":"","source_id":0,"full_name":"Charles Willgren","email":"charles@noreply.www-s01.apinet.com","avatar_url":"https:\/\/www-s01.apinet.com\/codeforge\/avatars\/d3c894f7297c5a18eb3f6ac837c335b11a00aa9cc0961323771632b1e2d61bb2","html_url":"https:\/\/www-s01.apinet.com\/codeforge\/charles","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2025-12-08T10:03:41-06:00","restricted":false,"active":false,"prohibit_login":false,"location":"","pronouns":"","website":"","description":"","visibility":"public","followers_count":0,"following_count":0,"starred_repos_count":0,"username":"charles"},"original_author":"","original_author_id":0,"body":"**Confirmed:** the customer says this applies to every form, not only the service plan.\n\n**Done in b9d8709.** \"How often will the attendant be supervised?\" is no longer asked on any form. Each form now prints the answer itself:\n\n| Form | Prints |\n|---|---|\n| PAS service plan | \"Every __ Months \/ PRN\" box, with 12 |\n| Form 3040 | \"Q 12 month \/ PRN\" |\n| PCS consent | Other, with \"12 months \/ PRN\" written in (the paper only offers 6 months \/ Other) |\n| Private Pay agreement | Other, with \"12 months \/ PRN\" written in (the paper only offers 6 months \/ 60 days \/ Other) |\n\nHow it works: three new fixed shared values in `code\/form_v2_shared.inc.php` (`shared.supervision_frequency`, `shared.supervision_months`, `shared.supervision_frequency_other`). I removed the eight questions from `docs\/form-v2-interviews\/SOC_AO.json`. The service plan's \"Other\" frequency line is never ticked, so it is listed in `not_asked` and prints blank. Tests are in `test-form-v2-shared`.\n\n**To apply:** run `form-v2-pipeline.php --packet=SOC_AO --import --replace`. I've already done this on dev, and the rehearsal passes all nine checks. Then review and publish on `\/admin\/form-v2-publish`, and choose the release on `\/admin\/form-v2-releases`.","assets":[],"created_at":"2026-10-06T09:49:54-05:00","updated_at":"2026-10-06T09:49:54-05:00"},{"id":1133,"html_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/93#issuecomment-1133","pull_request_url":"","issue_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/93","user":{"id":1,"login":"charles","login_name":"","source_id":0,"full_name":"Charles Willgren","email":"charles@noreply.www-s01.apinet.com","avatar_url":"https:\/\/www-s01.apinet.com\/codeforge\/avatars\/d3c894f7297c5a18eb3f6ac837c335b11a00aa9cc0961323771632b1e2d61bb2","html_url":"https:\/\/www-s01.apinet.com\/codeforge\/charles","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2025-12-08T10:03:41-06:00","restricted":false,"active":false,"prohibit_login":false,"location":"","pronouns":"","website":"","description":"","visibility":"public","followers_count":0,"following_count":0,"starred_repos_count":0,"username":"charles"},"original_author":"","original_author_id":0,"body":"**Decided (Charles, 6 Oct): over is a hard stop; under is allowed, with a warning and a flag on the review page.** Built.\n\n**Over the authorized hours**\n- A schedule change that takes the week over the authorized hours is **not saved**. The supervisor sees why under the day: \"The schedule comes to 22.00 hours a week, 1.00 more than the 21.00 hours authorized. Hours can be moved between days, but the week cannot go over\u2026\"\n- The check lists an over week against the schedule, so **the forms can't be generated** until it fits.\n- If VESTA's own schedule is already over, the visit still opens with it. Any change that brings the week down is accepted, so it can be fixed one day at a time.\n\n**Under the authorized hours**\n- Allowed. The running total beside \"Authorized: N hours a week\" says \"The schedule is X hours under. This is allowed, and the office will see it\u2026\"\n- On **Visit Review** the visit gets a yellow \"Schedule is under the authorized hours\" banner, and the list shows a badge saying \"Hours under authorized\".\n\nAn empty schedule (nothing entered yet) isn't flagged as under. Hours are compared in whole minutes against the pinned `auth.weekly_hours`.\n\nCode: `form_v2_schedule_week()` \/ `form_v2_schedule_total_status()` in `code\/form_v2_visit_rules.inc.php`, enforced in `form_v2_visit_save()` and `form_v2_visit_issues()`. I checked it on dev visit 19 (20 of 21 hours): +2 h was refused, +1 h (exactly 21) was saved and the flag cleared. Nothing needs publishing for this one. It's runtime code and applies on deploy.","assets":[],"created_at":"2026-10-06T10:06:53-05:00","updated_at":"2026-10-06T10:06:53-05:00"},{"id":1134,"html_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/103#issuecomment-1134","pull_request_url":"","issue_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/103","user":{"id":1,"login":"charles","login_name":"","source_id":0,"full_name":"Charles Willgren","email":"charles@noreply.www-s01.apinet.com","avatar_url":"https:\/\/www-s01.apinet.com\/codeforge\/avatars\/d3c894f7297c5a18eb3f6ac837c335b11a00aa9cc0961323771632b1e2d61bb2","html_url":"https:\/\/www-s01.apinet.com\/codeforge\/charles","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2025-12-08T10:03:41-06:00","restricted":false,"active":false,"prohibit_login":false,"location":"","pronouns":"","website":"","description":"","visibility":"public","followers_count":0,"following_count":0,"starred_repos_count":0,"username":"charles"},"original_author":"","original_author_id":0,"body":"**Items 1 and 2 from the notes above are built.** Item 3 is still open.\n\n1. **FREQ is a drop-down: QD \u2014 Every day, QW \u2014 Every week, PRN \u2014 As needed.** Each task starts at its default from Frank's table: Laundry and Shopping start as QW, Escort as PRN, everything else as QD. The supervisor can change it. A row is still asked only when the task is in the client's VESTA list (#108). The paper prints the code (QD \/ QW \/ PRN) in the FREQ cell.\n2. **The blank \"other\" row.** \"Does the attendant do any other task that is not listed?\" is always asked, because it covers what VESTA doesn't list. Once a task is named, its frequency drop-down and A\/B\/C ratings appear. It prints on the paper's unlabelled row under \"Assist w. Self-Admin. Med\" (name on the line, code in FREQ, S\/U in the cells), checked on a rendered proof.\n3. **Still to ask the customer:** now that there are sensible defaults, do we still need to *refuse* QW on a daily task, or is the default enough? Nothing refuses it today.\n\nFiles: `docs\/forms\/forms-3040.json`, `docs\/form-placements\/forms-3040.json`, `docs\/form-v2-interviews\/SOC_AO.json`. A mark can now print a code of up to three capitals (it was one letter), with a fit check so a code can't overflow its cell. Imported to the dev drafts, and the publish rehearsal passes all nine checks. It goes out in the pending SOC_AO release with #88\/#101\/#105\/#106: publish on \/admin\/form-v2-publish, then choose the release on \/admin\/form-v2-releases.","assets":[],"created_at":"2026-10-06T10:06:53-05:00","updated_at":"2026-10-06T10:06:53-05:00"},{"id":1138,"html_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/103#issuecomment-1138","pull_request_url":"","issue_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/103","user":{"id":1,"login":"charles","login_name":"","source_id":0,"full_name":"Charles Willgren","email":"charles@noreply.www-s01.apinet.com","avatar_url":"https:\/\/www-s01.apinet.com\/codeforge\/avatars\/d3c894f7297c5a18eb3f6ac837c335b11a00aa9cc0961323771632b1e2d61bb2","html_url":"https:\/\/www-s01.apinet.com\/codeforge\/charles","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2025-12-08T10:03:41-06:00","restricted":false,"active":false,"prohibit_login":false,"location":"","pronouns":"","website":"","description":"","visibility":"public","followers_count":0,"following_count":0,"starred_repos_count":0,"username":"charles"},"original_author":"","original_author_id":0,"body":"**Also fixed while I was in the grid:** choosing **N\/A** printed nothing on the 3040. That covered every A\/B\/C rating cell, including the new other row, plus items 4, 5, 8 and 9. The service plan's \"N\/A\" other-services box had the same problem. The maps now print \"N\/A\" in the rating cells and an X in the N\/A tick boxes, which I checked on a rendered proof. A test now fails any map whose N\/A box would print nothing. This goes out in the same pending SOC_AO release.","assets":[],"created_at":"2026-10-06T10:12:32-05:00","updated_at":"2026-10-06T10:12:32-05:00"},{"id":1139,"html_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/113#issuecomment-1139","pull_request_url":"","issue_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/113","user":{"id":1,"login":"charles","login_name":"","source_id":0,"full_name":"Charles Willgren","email":"charles@noreply.www-s01.apinet.com","avatar_url":"https:\/\/www-s01.apinet.com\/codeforge\/avatars\/d3c894f7297c5a18eb3f6ac837c335b11a00aa9cc0961323771632b1e2d61bb2","html_url":"https:\/\/www-s01.apinet.com\/codeforge\/charles","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2025-12-08T10:03:41-06:00","restricted":false,"active":false,"prohibit_login":false,"location":"","pronouns":"","website":"","description":"","visibility":"public","followers_count":0,"following_count":0,"starred_repos_count":0,"username":"charles"},"original_author":"","original_author_id":0,"body":"Done in 7f9771e.\n\n**Cause.** On the PCS consent, the PAS\/PHC consent and the Private Pay agreement, the \"Witness 1\" \/ \"Witness 2\" lines were defined as typed text, even though the paper says the witnesses must *sign* there. Because they weren't signatures, no signing claimed the date beside them, so the interview asked for it. The H2076 already had witness signatures and wasn't affected.\n\n**Change.**\n- `witness_1` \/ `witness_2` on those three forms are now signature fields. Their boxes print a drawn signature and are sized like the release signature (checked on proofs of all three forms).\n- Each witness has their own signing line, and the date beside it is stamped when the witness taps Sign.\n- The 12 witness name and date questions are removed from the SOC\/AO interview. The witness gives their name when adopting a signature.\n- Pipeline fix: the interview import read the *published* placements, so a signing line added in the same import was invisible and its date came back as a question. `form_v2_signing_maps()` now prefers a placement's draft during import.\n\n**Until W4 (#114) is done**, the witness lines are owed on every visit. Staff use \"Record why\" on each one when no witness is needed. #114 is where witnesses become required only for an X signature.\n\n**To apply:** the rehearsal on dev passes all nine checks. Publish on `\/admin\/form-v2-publish`, then choose the release on `\/admin\/form-v2-releases`.","assets":[],"created_at":"2026-10-06T10:22:24-05:00","updated_at":"2026-10-06T10:22:24-05:00"},{"id":1141,"html_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/114#issuecomment-1141","pull_request_url":"","issue_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/114","user":{"id":1,"login":"charles","login_name":"","source_id":0,"full_name":"Charles Willgren","email":"charles@noreply.www-s01.apinet.com","avatar_url":"https:\/\/www-s01.apinet.com\/codeforge\/avatars\/d3c894f7297c5a18eb3f6ac837c335b11a00aa9cc0961323771632b1e2d61bb2","html_url":"https:\/\/www-s01.apinet.com\/codeforge\/charles","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2025-12-08T10:03:41-06:00","restricted":false,"active":false,"prohibit_login":false,"location":"","pronouns":"","website":"","description":"","visibility":"public","followers_count":0,"following_count":0,"starred_repos_count":0,"username":"charles"},"original_author":"","original_author_id":0,"body":"Done in c9e7c29 (builds on #113, 7f9771e).\n\n**How it works.** Whether the client signs with an X is decided on the **signing screen**, when the client takes the pen. It is not an interview question.\n- Until the client has adopted a signature, each client line has a **Client signs with an X** button under its Sign button. It opens the client's adoption with a new **Signs with an X** box ticked. The box is also there when adopting from Sign.\n- **X:** the two witness lines become owed on every form that has them: the PAS\/PHC and PCS consents, Private Pay and the H2076. The witnesses give their name and draw a signature, and the date is stamped by their tap (#113).\n- **No X:** the witness lines say \"Only if the client signs with an X.\", are not counted toward finishing, and print blank. Staff no longer have to \"Record why\" on each one.\n- The choice belongs to that printing. If an answer changes and the forms are generated again, it is asked again.\n\n**Technical.**\n- New column `form_v2_visit_signer.signs_with_mark` (`migrations\/20261006_signer-signs-with-mark.sql`).\n- `form_v2_sign_plan()` makes a witness line apply only when the client's adoption carries the mark.\n- `form_v2_sign_adopt()` refuses the mark for anyone but the client.\n- Tests in `test-form-v2-sign-rules` and `test-form-v2-sign-state`.\n\n**Checked on dev.** SOC\/AO was published there, a visit was printed with private pay, and the client adopted an X: 28 \u2192 32 things to do, and the X buttons went away. Witness 1 adopted, signed and was stamped with the tap's time.\n\n**To apply:** `php scripts\/migrate.php --apply`, then publish #113's SOC\/AO release on `\/admin\/form-v2-publish` and choose it on `\/admin\/form-v2-releases`.","assets":[],"created_at":"2026-10-06T11:10:26-05:00","updated_at":"2026-10-06T11:10:26-05:00"},{"id":1153,"html_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/82#issuecomment-1153","pull_request_url":"","issue_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/82","user":{"id":1,"login":"charles","login_name":"","source_id":0,"full_name":"Charles Willgren","email":"charles@noreply.www-s01.apinet.com","avatar_url":"https:\/\/www-s01.apinet.com\/codeforge\/avatars\/d3c894f7297c5a18eb3f6ac837c335b11a00aa9cc0961323771632b1e2d61bb2","html_url":"https:\/\/www-s01.apinet.com\/codeforge\/charles","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2025-12-08T10:03:41-06:00","restricted":false,"active":false,"prohibit_login":false,"location":"","pronouns":"","website":"","description":"","visibility":"public","followers_count":0,"following_count":0,"starred_repos_count":0,"username":"charles"},"original_author":"","original_author_id":0,"body":"## Built (commit 85a2957), not yet on production\n\nBuilt as proposed above, from a local copy of the national provider registry, not the live API.\n\n- **On the visit screen:** \"Who is the client's regular doctor?\" now has a **Find the doctor** button. Staff type part of the name. Results nearest the client's ZIP come first, and they can type a different ZIP or city. Each result shows name, specialty, address, phone and fax. Picking one fills the doctor's name, phone and the PAS service plan's **Physician Address**. Everything stays editable, and \"Not listed? Type it in the box above\" covers anyone missing.\n- **Who is searched:** Texas doctors (MD\/DO), nurse practitioners and physician assistants.\n- **What is kept:** the registry entry that was picked is recorded with the visit, encrypted.\n- **Tried on dev** with the latest weekly registry file. A pick fills all three boxes and saves.\n\n**To go live:** run the migration, load the registry once (`scripts\/import-npi.php --fetch --apply`, after which a weekly timer keeps it current), then republish SOC\/AO. Production needs outbound HTTPS to download.cms.gov for the import.\n\n**Still open:** if the customer keeps their own list of doctors, it can be loaded into the same table. Nothing is built for that yet.","assets":[],"created_at":"2026-10-06T11:42:10-05:00","updated_at":"2026-10-06T11:42:10-05:00"},{"id":1154,"html_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/99#issuecomment-1154","pull_request_url":"","issue_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/99","user":{"id":1,"login":"charles","login_name":"","source_id":0,"full_name":"Charles Willgren","email":"charles@noreply.www-s01.apinet.com","avatar_url":"https:\/\/www-s01.apinet.com\/codeforge\/avatars\/d3c894f7297c5a18eb3f6ac837c335b11a00aa9cc0961323771632b1e2d61bb2","html_url":"https:\/\/www-s01.apinet.com\/codeforge\/charles","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2025-12-08T10:03:41-06:00","restricted":false,"active":false,"prohibit_login":false,"location":"","pronouns":"","website":"","description":"","visibility":"public","followers_count":0,"following_count":0,"starred_repos_count":0,"username":"charles"},"original_author":"","original_author_id":0,"body":"## Lookup built (commit 85a2957); \"on file\" prefill not yet\n\n- **On the visit screen:** the Emergency\/Disaster form's pharmacy question has a **Find the pharmacy** button. It searches the same local registry copy as the doctor lookup (#82), nearest the client first. A store's own name is searchable (\"CVS Pharmacy #1234\"), not only the company's legal name. Picking one fills the pharmacy name and phone.\n- **Known pharmacies:** pharmacies this agency has picked before are listed first and marked \"Used before\". With the name box empty, the list shows just those, so the drop-down of known pharmacies needs no separate list.\n- **Equipment supplier:** the DME supplier on the same form got the same lookup.\n\n**Not built:** saving the pharmacy on the client's record and prefilling future visits from it. As noted above, that should happen only after the office accepts the visit, and there is no office-acceptance step yet. In the meantime, the pick is recorded with the visit (encrypted), so it can be carried over once that step exists.","assets":[],"created_at":"2026-10-06T11:42:10-05:00","updated_at":"2026-10-06T11:42:10-05:00"},{"id":1156,"html_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/137#issuecomment-1156","pull_request_url":"","issue_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/137","user":{"id":1,"login":"charles","login_name":"","source_id":0,"full_name":"Charles Willgren","email":"charles@noreply.www-s01.apinet.com","avatar_url":"https:\/\/www-s01.apinet.com\/codeforge\/avatars\/d3c894f7297c5a18eb3f6ac837c335b11a00aa9cc0961323771632b1e2d61bb2","html_url":"https:\/\/www-s01.apinet.com\/codeforge\/charles","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2025-12-08T10:03:41-06:00","restricted":false,"active":false,"prohibit_login":false,"location":"","pronouns":"","website":"","description":"","visibility":"public","followers_count":0,"following_count":0,"starred_repos_count":0,"username":"charles"},"original_author":"","original_author_id":0,"body":"## Built from the provider registry (commit 85a2957)\n\nThe directory is the same local registry copy as the doctor and pharmacy lookups (#82, #99). The national registry lists agencies with their phone **and fax** numbers, and a weekly update keeps it current, so there is no list for the office to maintain.\n\n**Where the lookup appears:**\n- **Coordination of Care:** each agency under \"Other care the client receives\" has a **Find the agency** button that fills the agency's name, phone and fax:\n  - skilled nursing and home health aide: home health and home care agencies;\n  - therapy: therapy clinics and home health agencies;\n  - dialysis: dialysis centers;\n  - adult day care: adult day care centers.\n- **Transfer form:** the agency the client is transferring from and the agency called. The form has no phone or fax boxes, so only the name is filled.\n\nAgencies this agency has picked before come first, marked \"Used before\". The contact person is still typed, because the registry doesn't list people at an agency.\n\n**For the customer:**\n1. Is putting it on both forms right?\n2. If they have their own list, it can be loaded into the same table alongside the registry.\n3. \"Home health\" here also includes in-home support agencies, where most PAS providers are registered. Please confirm that's what they want.","assets":[],"created_at":"2026-10-06T11:42:10-05:00","updated_at":"2026-10-06T11:42:10-05:00"},{"id":1162,"html_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/93#issuecomment-1162","pull_request_url":"","issue_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/93","user":{"id":1,"login":"charles","login_name":"","source_id":0,"full_name":"Charles Willgren","email":"charles@noreply.www-s01.apinet.com","avatar_url":"https:\/\/www-s01.apinet.com\/codeforge\/avatars\/d3c894f7297c5a18eb3f6ac837c335b11a00aa9cc0961323771632b1e2d61bb2","html_url":"https:\/\/www-s01.apinet.com\/codeforge\/charles","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2025-12-08T10:03:41-06:00","restricted":false,"active":false,"prohibit_login":false,"location":"","pronouns":"","website":"","description":"","visibility":"public","followers_count":0,"following_count":0,"starred_repos_count":0,"username":"charles"},"original_author":"","original_author_id":0,"body":"Deployed to production on 6 Oct. A week over the authorized hours is refused, and a week under is allowed and flagged on Visit Review. Closing.","assets":[],"created_at":"2026-10-06T13:25:35-05:00","updated_at":"2026-10-06T13:25:35-05:00"},{"id":1165,"html_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/140#issuecomment-1165","pull_request_url":"","issue_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/140","user":{"id":1,"login":"charles","login_name":"","source_id":0,"full_name":"Charles Willgren","email":"charles@noreply.www-s01.apinet.com","avatar_url":"https:\/\/www-s01.apinet.com\/codeforge\/avatars\/d3c894f7297c5a18eb3f6ac837c335b11a00aa9cc0961323771632b1e2d61bb2","html_url":"https:\/\/www-s01.apinet.com\/codeforge\/charles","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2025-12-08T10:03:41-06:00","restricted":false,"active":false,"prohibit_login":false,"location":"","pronouns":"","website":"","description":"","visibility":"public","followers_count":0,"following_count":0,"starred_repos_count":0,"username":"charles"},"original_author":"","original_author_id":0,"body":"**Built (not yet published).** The client's other care is now **one question**: a single list at the start of *Other care the client receives*. It fills the Coordination of Care and both pages of the service plan (`shared.other_services` in `code\/form_v2_shared.inc.php`). The choices are None, skilled nursing, home health aide, therapy, dialysis, adult day care (DAHS), medical equipment (DME), meals (HDM), emergency response, transportation and other.\n\n**What each paper ticks.** These need the customer's eye:\n- **Coordination of Care:** SN, HHA, therapy, dialysis, adult day care (as ADC) and other. It has no rows for equipment, meals, emergency response or transportation, so those don't print there. Each row is another agency's care with one contact, and its single Other row can't hold several services. \"None\" prints nothing ticked.\n- **Service plan, page 1** (\"Other Service Individual is Receiving\"): nursing and aide both tick **Skilled Home Health Aide**. Therapy, dialysis and equipment tick **Other**, and its \"Other (specify)\" line is asked. None ticks **None**.\n- **Service plan, page 2** (\"Other Services\"): meals tick **HDM** and None ticks **N\/A**. Anything without its own box ticks **Other**, and \"Other (specify name)\" is asked.\n- The adult day care's agency name is also page 2's DAHS name, so it's asked once.\n\nAll the follow-up questions now sit under the list on one step, and the overlap question is hidden when the answer is None. This also settles S5 (#90): no other services prints **None** and **N\/A**.\n\n**Item 4, the suspected mis-binding: not a fault.** Every interview version (1\u20138), the form definition and the placement bind `other_services_receiving` to page 1's \"Other Service Individual is Receiving\". \"What change is needed, and why?\" is the 3040's `change_needed_detail`. It's the question shown when `change_needed` = yes, on the *Attendants* step.\n\n**To ship:** the drafts are imported on dev and the publish rehearsal passes all nine checks. Next: review and publish on `\/admin\/form-v2-publish`, then choose the release on `\/admin\/form-v2-releases`.","assets":[],"created_at":"2026-10-06T13:44:18-05:00","updated_at":"2026-10-06T13:44:18-05:00"},{"id":1167,"html_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/118#issuecomment-1167","pull_request_url":"","issue_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/118","user":{"id":1,"login":"charles","login_name":"","source_id":0,"full_name":"Charles Willgren","email":"charles@noreply.www-s01.apinet.com","avatar_url":"https:\/\/www-s01.apinet.com\/codeforge\/avatars\/d3c894f7297c5a18eb3f6ac837c335b11a00aa9cc0961323771632b1e2d61bb2","html_url":"https:\/\/www-s01.apinet.com\/codeforge\/charles","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2025-12-08T10:03:41-06:00","restricted":false,"active":false,"prohibit_login":false,"location":"","pronouns":"","website":"","description":"","visibility":"public","followers_count":0,"following_count":0,"starred_repos_count":0,"username":"charles"},"original_author":"","original_author_id":0,"body":"**Most of this was already in place. The gaps are now closed (not yet published).**\n\nAlready built (25 Sep):\n- The agency's details are kept per agency: legal name, toll-free and 24-hour numbers, administrator.\n- Each **branch office's** address, phone, fax and vendor number are kept per branch.\n- Both are maintained by a Superuser at **Superuser Tools \u2192 Systems** (*Branch Offices*), and they fill every form from the client's branch.\n- No interview question asks for any of them.\n\nDone today:\n- **A missing detail is reported.** Nothing marks these fields required, so a missing one printed blank without a word. The visit's check now lists each one that is not on file, with the forms it would print blank on and where to enter it (`form_v2_visit_office_missing()`). Like any check item, it can be skipped.\n- **The 3040's Vendor No. now reads the branch's number**, as the service plan already did. Before, it read the agency's, which is an NPI on file. Which number belongs on which form (vendor or contract) is still #117 (F1).\n\n**Waiting on the customer:**\n1. **The branch details need entering.** Every branch row is blank on the dev database; production not checked. Until they are entered, the service plan and the Coordination of Care print no office address, phone, fax or vendor number, and the check will say so.\n2. **Contract number** prints on no form today. If #117's answer is \"contract number on some forms\", it gets a column beside the vendor number then.\n\nH4 (#94, the coordinator per branch) can live on the same Branch Offices table when it's picked up.","assets":[],"created_at":"2026-10-06T13:44:18-05:00","updated_at":"2026-10-06T13:44:27-05:00"},{"id":1172,"html_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/150#issuecomment-1172","pull_request_url":"","issue_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/150","user":{"id":1,"login":"charles","login_name":"","source_id":0,"full_name":"Charles Willgren","email":"charles@noreply.www-s01.apinet.com","avatar_url":"https:\/\/www-s01.apinet.com\/codeforge\/avatars\/d3c894f7297c5a18eb3f6ac837c335b11a00aa9cc0961323771632b1e2d61bb2","html_url":"https:\/\/www-s01.apinet.com\/codeforge\/charles","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2025-12-08T10:03:41-06:00","restricted":false,"active":false,"prohibit_login":false,"location":"","pronouns":"","website":"","description":"","visibility":"public","followers_count":0,"following_count":0,"starred_repos_count":0,"username":"charles"},"original_author":"","original_author_id":0,"body":"Done in f6e44d8.\n\n**Detection** \u2014 `code\/form_pdf_layers.inc.php`: a scan over qpdf's JSON for layers that start off (`\/D \/OFF`, or `\/BaseState \/OFF`) that the page still uses: a content `\/OC \u2026 BDC` span (including one through a membership dictionary or inside a form XObject), an image\/XObject `\/OC`, or an annotation `\/OC`. A `\/Thumb` is a warning, never a refusal. A layer that is on everywhere passes (`forms-3040` and `things-you-may-not-do` carry `\/OFF []`).\n\n**Where it is caught, all before publishing:**\n- `scripts\/test-form-blanks.php` walks every catalogue blank, plus a real-file fixture and the scan's other shapes. All 15 current blanks pass.\n- `form_v2_template_register()` refuses with a message in words, also for a fingerprint registered before this rule. It fails closed if qpdf is missing. `form-overlay-propose.php` prints the reason and registers nothing.\n- `form-pdf-proof.php` refuses to write the proof that would hide it.\n- The publish proofs (`form-v2-pipeline.php`, `\/admin\/form-v2-publish`) fail the form, so the release is not published.\n\nVerified against the pre-#104 Task Guide: every gate refused it, naming \"Layer 1\" on page 1.\n\n**Cleaning** \u2014 new `scripts\/form-blank-clean-layers.py` (PyMuPDF in venv) merges each page's content streams, cuts the off spans and the thumbnail, and refuses to write unless every page renders pixel-identical. It cleaned the old Task Guide with an identical result. The recipe is in `docs\/form-placements\/README.md`, under \"Hidden layers\".\n\nNote: `things-you-may-not-do.pdf` carries a page thumbnail, which is reported as a note only. I left it alone, because cleaning it changes the fingerprint and needs a re-pin.","assets":[],"created_at":"2026-10-06T13:55:29-05:00","updated_at":"2026-10-06T13:55:29-05:00"},{"id":1179,"html_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/137#issuecomment-1179","pull_request_url":"","issue_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/137","user":{"id":1,"login":"charles","login_name":"","source_id":0,"full_name":"Charles Willgren","email":"charles@noreply.www-s01.apinet.com","avatar_url":"https:\/\/www-s01.apinet.com\/codeforge\/avatars\/d3c894f7297c5a18eb3f6ac837c335b11a00aa9cc0961323771632b1e2d61bb2","html_url":"https:\/\/www-s01.apinet.com\/codeforge\/charles","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2025-12-08T10:03:41-06:00","restricted":false,"active":false,"prohibit_login":false,"location":"","pronouns":"","website":"","description":"","visibility":"public","followers_count":0,"following_count":0,"starred_repos_count":0,"username":"charles"},"original_author":"","original_author_id":0,"body":"**Correction to question 2 above: struck.** The customer asked for the registry lookups so that they *don't* keep their own list. The doctor, pharmacy and agency lookups use only the national provider registry, and no customer list will be loaded.\n\nStill open for the customer:\n1. Is putting it on both forms (Coordination of Care and Transfer) right?\n3. \"Home health\" also includes in-home support agencies, where most PAS providers are registered. Is that what they want?","assets":[],"created_at":"2026-10-06T13:58:42-05:00","updated_at":"2026-10-06T13:58:42-05:00"},{"id":1184,"html_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/145#issuecomment-1184","pull_request_url":"","issue_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/145","user":{"id":1,"login":"charles","login_name":"","source_id":0,"full_name":"Charles Willgren","email":"charles@noreply.www-s01.apinet.com","avatar_url":"https:\/\/www-s01.apinet.com\/codeforge\/avatars\/d3c894f7297c5a18eb3f6ac837c335b11a00aa9cc0961323771632b1e2d61bb2","html_url":"https:\/\/www-s01.apinet.com\/codeforge\/charles","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2025-12-08T10:03:41-06:00","restricted":false,"active":false,"prohibit_login":false,"location":"","pronouns":"","website":"","description":"","visibility":"public","followers_count":0,"following_count":0,"starred_repos_count":0,"username":"charles"},"original_author":"","original_author_id":0,"body":"Done in a3133cc.\n\nThe visit screen (`\/visit-v2`) now has a **Client details** button that opens a panel from the right. It shows what the V1 tray showed: status and branch, personal details, care team, authorizations, attendant schedules, assigned tasks, diagnosis, Medicaid eligibility and recent calendar, plus where the signed forms go (#83). Report flags and agency codes are left out, as they were in V1.\n\n- Served by the new `\/do\/formV2VisitClient`, gated like the other visit endpoints. The client is looked up from the visit, never from an ID in the request, and each view is logged as a PHI read.\n- The panel reloads every time it is opened, and has a Refresh button.\n- Built in `hh_client_sheet()` in `code\/hh_client_sheet.inc.php`.\n\nChecked in the browser on dev with the demo client.","assets":[],"created_at":"2026-10-06T14:27:10-05:00","updated_at":"2026-10-06T14:27:10-05:00"},{"id":1186,"html_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/83#issuecomment-1186","pull_request_url":"","issue_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/83","user":{"id":1,"login":"charles","login_name":"","source_id":0,"full_name":"Charles Willgren","email":"charles@noreply.www-s01.apinet.com","avatar_url":"https:\/\/www-s01.apinet.com\/codeforge\/avatars\/d3c894f7297c5a18eb3f6ac837c335b11a00aa9cc0961323771632b1e2d61bb2","html_url":"https:\/\/www-s01.apinet.com\/codeforge\/charles","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2025-12-08T10:03:41-06:00","restricted":false,"active":false,"prohibit_login":false,"location":"","pronouns":"","website":"","description":"","visibility":"public","followers_count":0,"following_count":0,"starred_repos_count":0,"username":"charles"},"original_author":"","original_author_id":0,"body":"Done in a3133cc.\n\nA new step in the visit, **Sending the forms**, comes just before *Check the answers*. It asks for:\n- the client's email, or \"The client has no email\";\n- optionally, a family member or representative: name, relationship, and email and\/or mobile number.\n\nA representative is refused unless the supervisor confirms that the client chose this person. That confirmation is asked again whenever the person's details change.\n\n**Stored on the client record**, as asked: `hh_member.forms_contact_enc`, one encrypted package, plus who saved it and when (`migrations\/20261006-03_member-forms-contact.sql`). The next visit starts from what is on file, and it also shows in the Client details panel (#145).\n\n**Not an interview question, on purpose.** No form prints it, and the interview only asks what the forms carry. A V2 visit answer also never writes back to the client record. So this is an explicit save of the client's details through `\/do\/formV2VisitContact`. The save is logged without the values.\n\nRules are in `code\/hh_member_contact_rules.inc.php` and tested standalone by `scripts\/test-member-contact-rules.php`.\n\n**Still to do:** sending the forms by email or text is not built yet.\n\n**To apply on production:** `php scripts\/migrate.php --apply`","assets":[],"created_at":"2026-10-06T14:27:10-05:00","updated_at":"2026-10-06T14:27:10-05:00"},{"id":1190,"html_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/111#issuecomment-1190","pull_request_url":"","issue_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/111","user":{"id":1,"login":"charles","login_name":"","source_id":0,"full_name":"Charles Willgren","email":"charles@noreply.www-s01.apinet.com","avatar_url":"https:\/\/www-s01.apinet.com\/codeforge\/avatars\/d3c894f7297c5a18eb3f6ac837c335b11a00aa9cc0961323771632b1e2d61bb2","html_url":"https:\/\/www-s01.apinet.com\/codeforge\/charles","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2025-12-08T10:03:41-06:00","restricted":false,"active":false,"prohibit_login":false,"location":"","pronouns":"","website":"","description":"","visibility":"public","followers_count":0,"following_count":0,"starred_repos_count":0,"username":"charles"},"original_author":"","original_author_id":0,"body":"Built in ce30deb. On dev, not published yet.\n\n**What the forms actually have.** No signature line on the SOC\/AO forms is only for a representative: every client line reads \"Client \/ Authorized Agent\". The \"signing for the client\" content is two typed lines on both consent forms and the Private Pay agreement: the signer's authority (`shared.release.authority`), and why the client cannot sign (`shared.consent.unable_to_sign_reason`).\n\n**What changed**\n- The interview asks **\"Is the client signing the forms themselves?\"** (`visit.client_signs`). It starts at Yes, and the supervisor can change it.\n- The authority and the reason are asked only when the answer is **No**. On Yes they are hidden, and a hidden answer is never printed, so those lines stay blank.\n- Signing must agree with the answer. On Yes, adopting a signature as \"someone signing for the client\" is refused. On No, adopting as the client is refused. The adoption dialog offers only the matching choice. Visits prepared before this release are unaffected.\n- Why this is in the interview rather than at signing, as the X was in #114: these lines are printed before anyone signs.\n- Fixed along the way: loading the interview file silently dropped any question that no form prints. It now keeps the ones the file asks for.\n\n**Checked:** the related tests pass, including new ones for the signing rule and the question loading. The SOC\/AO publish rehearsal shows one new question and two now conditional, and passes all nine checks. Not tested yet: clicking through it in a browser, and refusal of a contradicting signature at the database level. Only the underlying rule has a test.\n\n**To make it live:** review and publish on `\/admin\/form-v2-publish?interview=SOC_AO_V2`, then choose the release on `\/admin\/form-v2-releases`. This publish also carries the #140 and #118 interview changes.\n\n**Open point:** the question starts at Yes, which treats \"who is signing\" as something the supervisor observes rather than a decision the client makes. A wrong Yes is caught at signing. If it should start blank instead, that is a one-line change.","assets":[],"created_at":"2026-10-06T14:41:03-05:00","updated_at":"2026-10-06T14:41:03-05:00"},{"id":1194,"html_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/111#issuecomment-1194","pull_request_url":"","issue_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/111","user":{"id":1,"login":"charles","login_name":"","source_id":0,"full_name":"Charles Willgren","email":"charles@noreply.www-s01.apinet.com","avatar_url":"https:\/\/www-s01.apinet.com\/codeforge\/avatars\/d3c894f7297c5a18eb3f6ac837c335b11a00aa9cc0961323771632b1e2d61bb2","html_url":"https:\/\/www-s01.apinet.com\/codeforge\/charles","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2025-12-08T10:03:41-06:00","restricted":false,"active":false,"prohibit_login":false,"location":"","pronouns":"","website":"","description":"","visibility":"public","followers_count":0,"following_count":0,"starred_repos_count":0,"username":"charles"},"original_author":"","original_author_id":0,"body":"**Open point settled (owner, 6 Oct 2026).** \"Is the client signing the forms themselves?\" starts at **Yes**. **No** means someone else signs for the client. There is no third answer: a client who refuses to sign has no interview, so refusal is never a route through it.\n\nThe build already works this way, so no code changed. The ruling is recorded in `docs\/FormsV2Plan.md`, the interviews README and the Changelog (96356f4).\n\nWhat is left is to publish the release on `\/admin\/form-v2-publish?interview=SOC_AO_V2` and choose it for each agency on `\/admin\/form-v2-releases`.","assets":[],"created_at":"2026-10-06T14:43:16-05:00","updated_at":"2026-10-06T14:43:16-05:00"},{"id":1197,"html_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/111#issuecomment-1197","pull_request_url":"","issue_url":"https:\/\/www-s01.apinet.com\/codeforge\/apiintl\/hhmanager\/issues\/111","user":{"id":1,"login":"charles","login_name":"","source_id":0,"full_name":"Charles Willgren","email":"charles@noreply.www-s01.apinet.com","avatar_url":"https:\/\/www-s01.apinet.com\/codeforge\/avatars\/d3c894f7297c5a18eb3f6ac837c335b11a00aa9cc0961323771632b1e2d61bb2","html_url":"https:\/\/www-s01.apinet.com\/codeforge\/charles","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2025-12-08T10:03:41-06:00","restricted":false,"active":false,"prohibit_login":false,"location":"","pronouns":"","website":"","description":"","visibility":"public","followers_count":0,"following_count":0,"starred_repos_count":0,"username":"charles"},"original_author":"","original_author_id":0,"body":"Live: deployed, and the SOC\/AO release is published and chosen for each agency. A Start of Care visit prepared from now on asks \"Is the client signing the forms themselves?\" (starts at Yes). Visits prepared earlier keep their old interview. Closing.","assets":[],"created_at":"2026-10-06T14:45:48-05:00","updated_at":"2026-10-06T14:45:48-05:00"}]}