{"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"}]}