From 3689ab67980d48750a048b421b7c5f1594c872f5 Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 2 Sep 2026 20:15:42 +0000 Subject: [PATCH 1/2] issues+ledger: close the four Caring Contacts defects and record their reviews All four defects are fixed and merged. This records that, and the three loose ends the work surfaced. Closes, each citing the merge commit and a grep-verifiable fact rather than a file name: - #59JT7W and #RZVMPD in 94a14a829 (PR #2532) - #J7PZQP and #PAMATF in 2631782a3 (PR #2534) #59JT7W's row records an earlier done request (c862828e) that claimed a fix before one existed, which is why every closure here names the SHA and what proves it on main. Four immutable review records, one per merged PR. #2533 and #2535 merged into their base branches rather than into main, so their records say which commit actually carried them there, and note that repo CI does not run on non-main base branches -- their proof is the offline gates plus the CI that ran on the main-based heads afterwards. Three new items: - A shallow clone makes two suites fail with a message naming a manifest rather than the clone depth. Cost real debugging time; every cloud session starts shallow. - createPlan still accepts a blank patient name. Split out of #J7PZQP rather than folded in: now that nothing infers meaning from blankness, the missing constraint is harmless rather than load-bearing. - #J7PZQP and #PAMATF merged with no Bugbot or approval-agent review, because a Cursor spend limit made both report neutral. A billing exhaustion presenting as a neutral check does not block a merge and does not look like missing coverage on the PR page, which is the part worth recording. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_014X6aJ6PgN26a8XiDm4FVHF --- ...2ddb443884ccb69f71d2b01268dabf1084abd14.record.md | 1 + ...5e9b6b487e4338469f4b89bc9616206b82f8063.record.md | 1 + ...f03eac19483ae703036e478341ea8f19dd100e8.record.md | 1 + ...a3ee865df92dba8e2e27cb9389f6586f9eae2fd.record.md | 1 + .../00e5a4b0-11fa-46c4-a101-e75d0ce3cc35.json | 12 ++++++++++++ .../354ac34b-c146-489c-a2c5-341988cbe3cf.json | 11 +++++++++++ .../42f4e905-cce5-41f0-9a8a-7678eaad9895.json | 12 ++++++++++++ .../74f5d2b4-02bb-43ae-9fd5-2e78c5a717d9.json | 12 ++++++++++++ .../a3d9c842-724b-4b1c-b564-7c3be4ec8ba2.json | 11 +++++++++++ .../d0cd358b-2b92-456f-8bd3-525341f1cf4b.json | 11 +++++++++++ .../d7e85095-3340-470c-9674-1481fc9b0930.json | 11 +++++++++++ 11 files changed, 84 insertions(+) create mode 100644 docs/branch-review-records/04ffa9adb5fbe07fd96c32d9d2ddb443884ccb69f71d2b01268dabf1084abd14.record.md create mode 100644 docs/branch-review-records/df797737cb58a35d2a44000165e9b6b487e4338469f4b89bc9616206b82f8063.record.md create mode 100644 docs/branch-review-records/f10aa3f3ba5da30c28b1f7a77f03eac19483ae703036e478341ea8f19dd100e8.record.md create mode 100644 docs/branch-review-records/f2b95df6ef379d0c7a26f3fa5a3ee865df92dba8e2e27cb9389f6586f9eae2fd.record.md create mode 100644 docs/outstanding-issues-inbox/00e5a4b0-11fa-46c4-a101-e75d0ce3cc35.json create mode 100644 docs/outstanding-issues-inbox/354ac34b-c146-489c-a2c5-341988cbe3cf.json create mode 100644 docs/outstanding-issues-inbox/42f4e905-cce5-41f0-9a8a-7678eaad9895.json create mode 100644 docs/outstanding-issues-inbox/74f5d2b4-02bb-43ae-9fd5-2e78c5a717d9.json create mode 100644 docs/outstanding-issues-inbox/a3d9c842-724b-4b1c-b564-7c3be4ec8ba2.json create mode 100644 docs/outstanding-issues-inbox/d0cd358b-2b92-456f-8bd3-525341f1cf4b.json create mode 100644 docs/outstanding-issues-inbox/d7e85095-3340-470c-9674-1481fc9b0930.json diff --git a/docs/branch-review-records/04ffa9adb5fbe07fd96c32d9d2ddb443884ccb69f71d2b01268dabf1084abd14.record.md b/docs/branch-review-records/04ffa9adb5fbe07fd96c32d9d2ddb443884ccb69f71d2b01268dabf1084abd14.record.md new file mode 100644 index 0000000000..7c362f8fd1 --- /dev/null +++ b/docs/branch-review-records/04ffa9adb5fbe07fd96c32d9d2ddb443884ccb69f71d2b01268dabf1084abd14.record.md @@ -0,0 +1 @@ +| 2026-09-02 | claude/caring-contacts-rules-r7r2ih-2 | bdf300188da5ac7ac7f0b36eea1aab2d266cdc48 | PR #2533 (#RZVMPD): db/postgres-repository.ts PLAN_LIST_COLUMNS, schedule-view.ts doc comment, tests/caring-contacts-domain-isolation.test.ts and the wire-level listPlans test | MERGED 2026-09-02 into its base branch (claude/caring-contacts-rules-r7r2ih), not into main directly, so it reached main inside 94a14a829. Branch since deleted. Two guards shipped with the fix and both were confirmed red against the pre-fix code: a static scan of the constant and its wiring, and a wire-level test recording every statement listPlans issues. Bugbot reviewed the final head and rated Low Risk. Clinical Governance Preflight completed voluntarily — the pr-policy classifier returns clinicalRisk:false for these paths, which is a substring accident rather than a judgement about patient mobile numbers and identifiers. | typecheck exit 0; full offline unit suite 949 files / 12293 passed \| 1 skipped; lint exit 0; prettier --check clean; caring-contacts db suite 214 passed (up from 213 by the new wire-level guard); domain-isolation 12 passed; mutation check — reverting listPlans to PLAN_COLUMNS turns both new guards red. Repo CI does not run on non-main base branches, so this PR's proof is the offline gates plus the CI that ran on its base branch after the merge. No provider-backed gate run. | diff --git a/docs/branch-review-records/df797737cb58a35d2a44000165e9b6b487e4338469f4b89bc9616206b82f8063.record.md b/docs/branch-review-records/df797737cb58a35d2a44000165e9b6b487e4338469f4b89bc9616206b82f8063.record.md new file mode 100644 index 0000000000..08409b61db --- /dev/null +++ b/docs/branch-review-records/df797737cb58a35d2a44000165e9b6b487e4338469f4b89bc9616206b82f8063.record.md @@ -0,0 +1 @@ +| 2026-09-02 | claude/caring-contacts-rules-r7r2ih-3 | 2631782a39ce277f055b53bce8a0418d43b66ac9 | PR #2534 (#J7PZQP + #PAMATF, squashed to main): episode.ts, model.ts, repository.ts, schedule-view.ts, simulation.ts, message-policy.ts, both repository implementations, patient-overview.tsx, plan-activation.ts, the schedule route, the shared contract helper and their tests | MERGED to main 2026-09-02. Episode carries patientDetailClearedAt instead of the screen inferring a clearance from a blank name; listSendableContacts gates on the owning plan in both stores, overturning Ruling 129 as Ruling 129A by explicit owner decision. Codex review found a genuine P2: under READ COMMITTED a clearance committing mid-getEpisode produced an episode reporting a completed clearance while still releasing name and mobile number — the fix reintroducing the defect class it exists to remove. Reproduced, fixed by reading every clearance-touched field in one statement, and pinned by a database contract test that pauses the read between statements. Merged with NO Bugbot or Cursor approval-agent review: both returned neutral because the Cursor account was at its spend limit (recorded as a separate ledger item). | typecheck exit 0; cc-guards 42 files / 1069 passed; caring-contacts db suite 2 files / 218 passed; message-policy + model + simulation + diff-integrity + interface-vocabulary 181 passed \| 1 skipped; prettier --check clean on all files changed vs main; phantom-revert check clean (21 files, +904/-121, nothing outside caring-contacts). CI green on the main-based head including Production UI critical, Build, Static PR checks, Safety and config, Caring Contacts database, Semgrep, Gitleaks, PR policy, PR mergeability. No provider-backed gate run. | diff --git a/docs/branch-review-records/f10aa3f3ba5da30c28b1f7a77f03eac19483ae703036e478341ea8f19dd100e8.record.md b/docs/branch-review-records/f10aa3f3ba5da30c28b1f7a77f03eac19483ae703036e478341ea8f19dd100e8.record.md new file mode 100644 index 0000000000..09e9df730e --- /dev/null +++ b/docs/branch-review-records/f10aa3f3ba5da30c28b1f7a77f03eac19483ae703036e478341ea8f19dd100e8.record.md @@ -0,0 +1 @@ +| 2026-09-02 | claude/caring-contacts-rules-r7r2ih-4 | 3e7d010575ece57266be7bd0864e5e60de874d58 | PR #2535 (#PAMATF): model.ts planSendingHold relocation and load-time invariant, both repository implementations' listSendableContacts, message-policy.ts plan-not-dispatchable, schedule-view.ts, simulation.ts, repository.ts port contract, plan-activation.ts, the phase-2b build record and HANDOVER, and their tests | MERGED 2026-09-02 into its base branch (claude/caring-contacts-rules-r7r2ih-3), not into main directly, so it reached main inside 2631782a3. Branch since deleted — but note it was accidentally RE-PUSHED after the merge and could not be deleted again from the cloud container (git push --delete returns 'the remote end hung up unexpectedly' then 'Everything up-to-date'); it is stale and must not be reused. This PR overturns Ruling 129 as Ruling 129A by explicit owner decision, recorded in the build record with the HANDOVER entry closed. Two pinned assertions were changed deliberately, not incidentally: the readmission test now expects zero sendable contacts (it had been pinning the defect) while additionally asserting all ten contacts still exist and are still scheduled, and the simulation's paused-plan case now sees the refusal at the read rather than the write. A review round found a third — the death-correction case would have passed from the plan gate alone — and it gained a per-contact state assertion. | typecheck exit 0; full offline unit suite 949 files / 12293 passed \| 1 skipped; lint exit 0; prettier --check clean; cc-guards 42 files / 1069 passed; caring-contacts db suite 217 passed; mutation checks — removing the in-memory plan gate turns two contract assertions red, and making planSendingHold admit a paused plan turns the new Ruling 129A read/write agreement assertion red. Repo CI does not run on non-main base branches; proof is the offline gates plus the CI that ran on main-based heads after the merges. No provider-backed gate run. | diff --git a/docs/branch-review-records/f2b95df6ef379d0c7a26f3fa5a3ee865df92dba8e2e27cb9389f6586f9eae2fd.record.md b/docs/branch-review-records/f2b95df6ef379d0c7a26f3fa5a3ee865df92dba8e2e27cb9389f6586f9eae2fd.record.md new file mode 100644 index 0000000000..294f968e55 --- /dev/null +++ b/docs/branch-review-records/f2b95df6ef379d0c7a26f3fa5a3ee865df92dba8e2e27cb9389f6586f9eae2fd.record.md @@ -0,0 +1 @@ +| 2026-09-02 | claude/caring-contacts-rules-r7r2ih | 94a14a829312ab317b64064fe520a38481930db7 | PR #2532 (#59JT7W + #RZVMPD, squashed to main): src/lib/caring-contacts/message-policy.ts, db/postgres-repository.ts, schedule-view.ts and their tests | MERGED to main 2026-09-02. Closing-message refusal routed through the validateGovernedMessage chokepoint and widened to every message type; caseload list read narrowed to PLAN_LIST_COLUMNS. A clinical-governance review round caught the first draft granting a NEW permission (validateGovernedMessage returned valid:true for a standard message with no body at all) and masking the more serious record-level refusal behind 'write a body'; both fixed before merge. Bugbot reviewed and rated Low Risk. | typecheck exit 0; full offline unit suite 949 files / 12293 passed \| 1 skipped; lint --max-warnings 0 exit 0; prettier --check clean; caring-contacts db suite 218 passed; cc-guards 1069 passed; CI on main-based head green including PR required, Unit coverage, Build, Static PR checks, Lighthouse budget. No provider-backed gate run. | diff --git a/docs/outstanding-issues-inbox/00e5a4b0-11fa-46c4-a101-e75d0ce3cc35.json b/docs/outstanding-issues-inbox/00e5a4b0-11fa-46c4-a101-e75d0ce3cc35.json new file mode 100644 index 0000000000..ca97438ffc --- /dev/null +++ b/docs/outstanding-issues-inbox/00e5a4b0-11fa-46c4-a101-e75d0ce3cc35.json @@ -0,0 +1,12 @@ +{ + "version": 2, + "id": "00e5a4b0-11fa-46c4-a101-e75d0ce3cc35", + "createdOn": "2026-09-02", + "action": "add", + "payload": { + "pri": "P3", + "type": "issue", + "summary": "Caring Contacts createPlan accepts a blank patient name in both stores, so '' remains a legal stored value", + "issueUlid": "01M1HW3N65V6CDEVZETMC62AXS" + } +} diff --git a/docs/outstanding-issues-inbox/354ac34b-c146-489c-a2c5-341988cbe3cf.json b/docs/outstanding-issues-inbox/354ac34b-c146-489c-a2c5-341988cbe3cf.json new file mode 100644 index 0000000000..be7f125a6f --- /dev/null +++ b/docs/outstanding-issues-inbox/354ac34b-c146-489c-a2c5-341988cbe3cf.json @@ -0,0 +1,11 @@ +{ + "version": 2, + "id": "354ac34b-c146-489c-a2c5-341988cbe3cf", + "createdOn": "2026-09-02", + "action": "done", + "payload": { + "id": "#RZVMPD", + "outcome": "FIXED AND MERGED to main in 94a14a829 (PR #2532), 2026-09-02. listPlans now selects a narrower PLAN_LIST_COLUMNS that drops patient_name, patient_mobile_number and patient_identifiers, so a caseload render no longer pulls every patient's name, mobile number and identifier list for the whole team into the process. PLAN_COLUMNS is unchanged for readPlanRecord and selectPlanForUpdate, whose callers (getEpisode, markRetentionCleared) genuinely need that detail — narrowing the shared constant would have made getEpisode project undefined for three fields, which no type would catch. patient_name was dropped alongside the two columns the issue named because names have their own separately audited read (listPatientNames, patientNameDirectory object type, Ruling 91), so fetching them inside a read audited as plan under-counted that trail. Evidence read off origin/main: PLAN_LIST_COLUMNS appears 3x in src/lib/caring-contacts/db/postgres-repository.ts at 94a14a829. Two guards ship with it — a static scan asserting the constant excludes the patient columns AND is actually wired into listPlans, and a wire-level Postgres test recording every statement listPlans issues; both were confirmed red against the pre-fix code. Nothing was ever released: PlanRecord excludes patientDetail structurally and that held throughout; the narrowing has moved from the mapping into the query.", + "baseRowFingerprint": "2448dd4735678e1775d81b6e3b9e44b500ec9ee7cdcfcb89428b69f015bfb3e1" + } +} diff --git a/docs/outstanding-issues-inbox/42f4e905-cce5-41f0-9a8a-7678eaad9895.json b/docs/outstanding-issues-inbox/42f4e905-cce5-41f0-9a8a-7678eaad9895.json new file mode 100644 index 0000000000..a09290fe84 --- /dev/null +++ b/docs/outstanding-issues-inbox/42f4e905-cce5-41f0-9a8a-7678eaad9895.json @@ -0,0 +1,12 @@ +{ + "version": 2, + "id": "42f4e905-cce5-41f0-9a8a-7678eaad9895", + "createdOn": "2026-09-02", + "action": "add", + "payload": { + "pri": "P2", + "type": "issue", + "summary": "Two clinical-risk Caring Contacts fixes merged with no automated review, because the Cursor spend limit silently downgraded the approval agent and Bugbot to neutral", + "issueUlid": "01M1HW41T6ACWXN6TRZTKCGMG6" + } +} diff --git a/docs/outstanding-issues-inbox/74f5d2b4-02bb-43ae-9fd5-2e78c5a717d9.json b/docs/outstanding-issues-inbox/74f5d2b4-02bb-43ae-9fd5-2e78c5a717d9.json new file mode 100644 index 0000000000..4fbcc0d2cc --- /dev/null +++ b/docs/outstanding-issues-inbox/74f5d2b4-02bb-43ae-9fd5-2e78c5a717d9.json @@ -0,0 +1,12 @@ +{ + "version": 2, + "id": "74f5d2b4-02bb-43ae-9fd5-2e78c5a717d9", + "createdOn": "2026-09-02", + "action": "add", + "payload": { + "pri": "P3", + "type": "issue", + "summary": "Two test suites fail on a shallow clone, and the failure names a manifest rather than the clone depth", + "issueUlid": "01M1HW3BVC77NJE2ZG49Q2E7FR" + } +} diff --git a/docs/outstanding-issues-inbox/a3d9c842-724b-4b1c-b564-7c3be4ec8ba2.json b/docs/outstanding-issues-inbox/a3d9c842-724b-4b1c-b564-7c3be4ec8ba2.json new file mode 100644 index 0000000000..f39e7029a6 --- /dev/null +++ b/docs/outstanding-issues-inbox/a3d9c842-724b-4b1c-b564-7c3be4ec8ba2.json @@ -0,0 +1,11 @@ +{ + "version": 2, + "id": "a3d9c842-724b-4b1c-b564-7c3be4ec8ba2", + "createdOn": "2026-09-02", + "action": "done", + "payload": { + "id": "#PAMATF", + "outcome": "FIXED AND MERGED to main in 2631782a3 (PR #2534), 2026-09-02. listSendableContacts now gates on the owning plan before the contact, in BOTH stores, so a draft plan nobody has started and a plan a coordinator has paused no longer present their contacts as work about to go out. planSendingHold moved from schedule-view.ts to model.ts beside contactSendability and is re-exported so existing imports still resolve; no second predicate was written. Evidence read off origin/main: planSendingHold appears 2x in src/lib/caring-contacts/model.ts at 2631782a3. validateGovernedMessage also gained a plan-not-dispatchable issue covering the draft and paused plans that previously passed the chokepoint, and a load-time invariant ties planSendingHold to TERMINAL_PLAN_STATES beside the two that already guard contactSendability. Neither store needed a query or a join, and a read racing an activation resolves fail-closed. THIS OVERTURNS RULING 129, which considered exactly this change and declined it on the grounds that it would duplicate an existing gate. Every fact in that ruling was re-verified and still holds; what changed is the weighing of the residual it named itself — a rename or a sibling leaves the misleading behaviour reachable and merely relabelled, which is the same shape as #59JT7W. Recorded as Ruling 129A in docs/caring-contacts/phase-2b-build-record.md with the HANDOVER entry closed, taken as an explicit owner decision rather than a drive-by consequence. The duplication cost Ruling 129 predicted is now pinned rather than accepted: the shared contract asserts the read gate and the write gate (requiresActivePlan) agree for every plan state where the plan is what decides. Two pinned assertions changed deliberately and are documented in the PR body. NOTE: this was never a live send hole — there is no dispatcher or SMS provider in the tree.", + "baseRowFingerprint": "d05c5812c06f1cb856402507488d12b896b150385ae41fbb6cbeccfc3190732b" + } +} diff --git a/docs/outstanding-issues-inbox/d0cd358b-2b92-456f-8bd3-525341f1cf4b.json b/docs/outstanding-issues-inbox/d0cd358b-2b92-456f-8bd3-525341f1cf4b.json new file mode 100644 index 0000000000..8c17775780 --- /dev/null +++ b/docs/outstanding-issues-inbox/d0cd358b-2b92-456f-8bd3-525341f1cf4b.json @@ -0,0 +1,11 @@ +{ + "version": 2, + "id": "d0cd358b-2b92-456f-8bd3-525341f1cf4b", + "createdOn": "2026-09-02", + "action": "done", + "payload": { + "id": "#J7PZQP", + "outcome": "FIXED AND MERGED to main in 2631782a3 (PR #2534), 2026-09-02. Episode now carries patientDetailClearedAt: Date | null, so the patient overview stops deducing 'a retention clearance removed this' from episode.patientName === ''. That inference was only ever held up by z.string().min(1) at the HTTP edge: patient_name is not null with no CHECK against the empty string and neither store's createPlan validates non-blank, so a blank name reaching a store any other way made the screen state three things falsely about a live record. Evidence read off origin/main: patientDetailClearedAt appears in src/lib/caring-contacts/episode.ts at 2631782a3. No migration — retention_state.cleared_at already existed and both stores already wrote it in the same transaction as the de-identification, so there is no backfill gap either. The field is named for what was cleared, not the policy that ordered it, because Ruling 26 keeps that vocabulary inside the storage layer and forbids widening its allowlist to make a diff pass. DeidentifiedEpisode is unchanged: it is built by construction from a named field list, so the new field is absent from it automatically. A Codex review round found the first fix reintroducing its own defect class — under READ COMMITTED a clearance committing mid-getEpisode produced an episode reporting a completed clearance while still releasing the name and mobile number. Fixed by reading every field a clearance touches in one statement, and pinned by a database contract test that pauses the read between statements (present on main; fails against the pre-fix code with expected 'Rowan Delacroix' to be ''). This does not overturn the ''-as-cleared convention, which is correct wherever a non-blank write is enforced. NOT DONE, deliberately, and worth filing separately: createPlan still accepts a blank patient name.", + "baseRowFingerprint": "540928de1bb3a5c74d5fd6bda6302e2625e1c7756bd316db26620ec25a733588" + } +} diff --git a/docs/outstanding-issues-inbox/d7e85095-3340-470c-9674-1481fc9b0930.json b/docs/outstanding-issues-inbox/d7e85095-3340-470c-9674-1481fc9b0930.json new file mode 100644 index 0000000000..22c1105013 --- /dev/null +++ b/docs/outstanding-issues-inbox/d7e85095-3340-470c-9674-1481fc9b0930.json @@ -0,0 +1,11 @@ +{ + "version": 2, + "id": "d7e85095-3340-470c-9674-1481fc9b0930", + "createdOn": "2026-09-02", + "action": "done", + "payload": { + "id": "#59JT7W", + "outcome": "FIXED AND MERGED to main in 94a14a829 (PR #2532), 2026-09-02. The refusal no longer lives only in resolveClosingContactMessageBody: validateGovernedMessage — the chokepoint every future sender must pass — now returns closing-message-body-not-authored via an early return when no body was authored, and message-body-not-authored for standard/first, so no message type can be sent with no body. resolveClosingContactMessageBody is a thin adapter over it; its signature is unchanged. Evidence read off origin/main, not inferred: closing-message-body-not-authored appears 8x in src/lib/caring-contacts/message-policy.ts at 94a14a829. Record-level refusals (terminal contact, ended plan) are shared by both exits via appendStateIssues, so a missing body cannot mask an unrecoverable plan state. NOTE for whoever reads this row next: the earlier done request c862828e claimed this was fixed when it was not, which is why this closure cites the merge commit and a grep-verifiable fact rather than a file name. No closing-message wording was authored — approved-copy item A4 remains open.", + "baseRowFingerprint": "8e298119ee409dfa362d10036e14ee8f66b41094b1c8b39efbf8394560fc0b75" + } +} From ec7b422ce507609784ced9af3925cbee8edf3bde Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 2 Sep 2026 20:37:51 +0000 Subject: [PATCH 2/2] ledger: say who observed the hosted CI, and which provider gates were not run Codex review finding (P2) on PR #2572, and it was right. All four review records named individual hosted CI jobs as green and then ended with "No provider-backed gate run" -- but AGENTS.md classifies hosted CI as provider-backed, so the record contradicted itself. A later reader could not tell whether those results were observed or inherited from someone else's report, which is exactly what a review record exists to settle. Both halves were true and the sentence conflated them. The hosted results WERE observed: this session read them from the GitHub check runs via the MCP GitHub tools, under a standing instruction to babysit these PRs. What was not run is the set of gates that call OpenAI or Supabase. Each record now separates LOCAL OFFLINE GATES from HOSTED CI, states who observed the hosted result, and names the specific provider-backed gates that were not run rather than denying provider contact wholesale. Two records gained a correction beyond the wording: #2533 and #2535 had NO hosted CI of their own, because repo CI is scoped to branches [main, release/**] and their base was another feature branch. Their records now say that plainly and point at the main-based head whose CI actually covered them, instead of implying a pipeline ran on them. Record filenames are a sha256 of the row, so these were regenerated through ledger:append rather than edited in place; the four superseded files were never merged, so no immutable history is rewritten and the net diff against main is unchanged at four added records. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_014X6aJ6PgN26a8XiDm4FVHF --- ...7fd96c32d9d2ddb443884ccb69f71d2b01268dabf1084abd14.record.md | 1 - ...75263b1af0df0d87c555460e6e15dc052cfd1162d8fa2c265.record.md} | 2 +- ...54cdb1b0ac291233906c397a7cbfca1539a0b1c020e99234df.record.md | 1 + ...bcc9b687e3669942b3bd9aa3c69fe34563d1eb0a56e23a55a5.record.md | 1 + ...9498d29f1f34eeacfbe6c224a8ee48ecf893be298b318e96a5.record.md | 1 + ...5d2a44000165e9b6b487e4338469f4b89bc9616206b82f8063.record.md | 1 - ...0c7a26f3fa5a3ee865df92dba8e2e27cb9389f6586f9eae2fd.record.md | 1 - 7 files changed, 4 insertions(+), 4 deletions(-) delete mode 100644 docs/branch-review-records/04ffa9adb5fbe07fd96c32d9d2ddb443884ccb69f71d2b01268dabf1084abd14.record.md rename docs/branch-review-records/{f10aa3f3ba5da30c28b1f7a77f03eac19483ae703036e478341ea8f19dd100e8.record.md => 0cee2b10b5e10b575263b1af0df0d87c555460e6e15dc052cfd1162d8fa2c265.record.md} (50%) create mode 100644 docs/branch-review-records/0f22b88a41a63454cdb1b0ac291233906c397a7cbfca1539a0b1c020e99234df.record.md create mode 100644 docs/branch-review-records/4618bc97849416bcc9b687e3669942b3bd9aa3c69fe34563d1eb0a56e23a55a5.record.md create mode 100644 docs/branch-review-records/85a379521e2bae9498d29f1f34eeacfbe6c224a8ee48ecf893be298b318e96a5.record.md delete mode 100644 docs/branch-review-records/df797737cb58a35d2a44000165e9b6b487e4338469f4b89bc9616206b82f8063.record.md delete mode 100644 docs/branch-review-records/f2b95df6ef379d0c7a26f3fa5a3ee865df92dba8e2e27cb9389f6586f9eae2fd.record.md diff --git a/docs/branch-review-records/04ffa9adb5fbe07fd96c32d9d2ddb443884ccb69f71d2b01268dabf1084abd14.record.md b/docs/branch-review-records/04ffa9adb5fbe07fd96c32d9d2ddb443884ccb69f71d2b01268dabf1084abd14.record.md deleted file mode 100644 index 7c362f8fd1..0000000000 --- a/docs/branch-review-records/04ffa9adb5fbe07fd96c32d9d2ddb443884ccb69f71d2b01268dabf1084abd14.record.md +++ /dev/null @@ -1 +0,0 @@ -| 2026-09-02 | claude/caring-contacts-rules-r7r2ih-2 | bdf300188da5ac7ac7f0b36eea1aab2d266cdc48 | PR #2533 (#RZVMPD): db/postgres-repository.ts PLAN_LIST_COLUMNS, schedule-view.ts doc comment, tests/caring-contacts-domain-isolation.test.ts and the wire-level listPlans test | MERGED 2026-09-02 into its base branch (claude/caring-contacts-rules-r7r2ih), not into main directly, so it reached main inside 94a14a829. Branch since deleted. Two guards shipped with the fix and both were confirmed red against the pre-fix code: a static scan of the constant and its wiring, and a wire-level test recording every statement listPlans issues. Bugbot reviewed the final head and rated Low Risk. Clinical Governance Preflight completed voluntarily — the pr-policy classifier returns clinicalRisk:false for these paths, which is a substring accident rather than a judgement about patient mobile numbers and identifiers. | typecheck exit 0; full offline unit suite 949 files / 12293 passed \| 1 skipped; lint exit 0; prettier --check clean; caring-contacts db suite 214 passed (up from 213 by the new wire-level guard); domain-isolation 12 passed; mutation check — reverting listPlans to PLAN_COLUMNS turns both new guards red. Repo CI does not run on non-main base branches, so this PR's proof is the offline gates plus the CI that ran on its base branch after the merge. No provider-backed gate run. | diff --git a/docs/branch-review-records/f10aa3f3ba5da30c28b1f7a77f03eac19483ae703036e478341ea8f19dd100e8.record.md b/docs/branch-review-records/0cee2b10b5e10b575263b1af0df0d87c555460e6e15dc052cfd1162d8fa2c265.record.md similarity index 50% rename from docs/branch-review-records/f10aa3f3ba5da30c28b1f7a77f03eac19483ae703036e478341ea8f19dd100e8.record.md rename to docs/branch-review-records/0cee2b10b5e10b575263b1af0df0d87c555460e6e15dc052cfd1162d8fa2c265.record.md index 09e9df730e..f4a093b086 100644 --- a/docs/branch-review-records/f10aa3f3ba5da30c28b1f7a77f03eac19483ae703036e478341ea8f19dd100e8.record.md +++ b/docs/branch-review-records/0cee2b10b5e10b575263b1af0df0d87c555460e6e15dc052cfd1162d8fa2c265.record.md @@ -1 +1 @@ -| 2026-09-02 | claude/caring-contacts-rules-r7r2ih-4 | 3e7d010575ece57266be7bd0864e5e60de874d58 | PR #2535 (#PAMATF): model.ts planSendingHold relocation and load-time invariant, both repository implementations' listSendableContacts, message-policy.ts plan-not-dispatchable, schedule-view.ts, simulation.ts, repository.ts port contract, plan-activation.ts, the phase-2b build record and HANDOVER, and their tests | MERGED 2026-09-02 into its base branch (claude/caring-contacts-rules-r7r2ih-3), not into main directly, so it reached main inside 2631782a3. Branch since deleted — but note it was accidentally RE-PUSHED after the merge and could not be deleted again from the cloud container (git push --delete returns 'the remote end hung up unexpectedly' then 'Everything up-to-date'); it is stale and must not be reused. This PR overturns Ruling 129 as Ruling 129A by explicit owner decision, recorded in the build record with the HANDOVER entry closed. Two pinned assertions were changed deliberately, not incidentally: the readmission test now expects zero sendable contacts (it had been pinning the defect) while additionally asserting all ten contacts still exist and are still scheduled, and the simulation's paused-plan case now sees the refusal at the read rather than the write. A review round found a third — the death-correction case would have passed from the plan gate alone — and it gained a per-contact state assertion. | typecheck exit 0; full offline unit suite 949 files / 12293 passed \| 1 skipped; lint exit 0; prettier --check clean; cc-guards 42 files / 1069 passed; caring-contacts db suite 217 passed; mutation checks — removing the in-memory plan gate turns two contract assertions red, and making planSendingHold admit a paused plan turns the new Ruling 129A read/write agreement assertion red. Repo CI does not run on non-main base branches; proof is the offline gates plus the CI that ran on main-based heads after the merges. No provider-backed gate run. | +| 2026-09-02 | claude/caring-contacts-rules-r7r2ih-4 | 3e7d010575ece57266be7bd0864e5e60de874d58 | PR #2535 (#PAMATF): model.ts planSendingHold relocation and load-time invariant, both repository implementations' listSendableContacts, message-policy.ts plan-not-dispatchable, schedule-view.ts, simulation.ts, repository.ts port contract, plan-activation.ts, the phase-2b build record and HANDOVER, and their tests | MERGED 2026-09-02 into its base branch (claude/caring-contacts-rules-r7r2ih-3), not into main directly, so it reached main inside 2631782a3. Branch since deleted — but note it was accidentally RE-PUSHED after the merge and could not be deleted again from the cloud container (git push --delete returns 'the remote end hung up unexpectedly' then 'Everything up-to-date'); it is stale and must not be reused. This PR overturns Ruling 129 as Ruling 129A by explicit owner decision, recorded in the build record with the HANDOVER entry closed. Two pinned assertions were changed deliberately, not incidentally: the readmission test now expects zero sendable contacts (it had been pinning the defect) while additionally asserting all ten contacts still exist and are still scheduled, and the simulation's paused-plan case now sees the refusal at the read rather than the write. A review round found a third — the death-correction case would have passed from the plan gate alone — and it gained a per-contact state assertion. | LOCAL OFFLINE GATES, run in this container: typecheck exit 0; full offline unit suite 949 files / 12293 passed \| 1 skipped; lint exit 0; prettier --check clean; cc-guards 42 files / 1069 passed; caring-contacts db suite 217 passed against a disposable local Postgres 16 (not the live Supabase project); mutation checks — removing the in-memory plan gate turns two contract assertions red, and making planSendingHold admit a paused plan turns the new Ruling 129A read/write agreement assertion red. HOSTED CI: none ran on this PR — repo CI is scoped to branches [main, release/**], so a PR whose base is another feature branch gets no pipeline at all. Its hosted proof is therefore the CI that ran on the main-based head AFTER this merged through into it (see the claude/caring-contacts-rules-r7r2ih-3 record at 2631782a3), not anything observed on this PR. Hosted CI results named here were OBSERVED, not inherited: this Claude Code session read them directly from the GitHub check runs via the GitHub MCP tools, under Josh's standing instruction to babysit these PRs, which is the explicit confirmation the provider boundary requires for that read. Provider-backed gates NOT run: no eval:* retrieval canary, no verify:release, no check:supabase-project, no live Supabase or OpenAI test:live path, and no live-drift dispatch. | diff --git a/docs/branch-review-records/0f22b88a41a63454cdb1b0ac291233906c397a7cbfca1539a0b1c020e99234df.record.md b/docs/branch-review-records/0f22b88a41a63454cdb1b0ac291233906c397a7cbfca1539a0b1c020e99234df.record.md new file mode 100644 index 0000000000..394adbab1b --- /dev/null +++ b/docs/branch-review-records/0f22b88a41a63454cdb1b0ac291233906c397a7cbfca1539a0b1c020e99234df.record.md @@ -0,0 +1 @@ +| 2026-09-02 | claude/caring-contacts-rules-r7r2ih | 94a14a829312ab317b64064fe520a38481930db7 | PR #2532 (#59JT7W + #RZVMPD, squashed to main): src/lib/caring-contacts/message-policy.ts, db/postgres-repository.ts, schedule-view.ts and their tests | MERGED to main 2026-09-02. Closing-message refusal routed through the validateGovernedMessage chokepoint and widened to every message type; caseload list read narrowed to PLAN_LIST_COLUMNS. A clinical-governance review round caught the first draft granting a NEW permission (validateGovernedMessage returned valid:true for a standard message with no body at all) and masking the more serious record-level refusal behind 'write a body'; both fixed before merge. Bugbot reviewed and rated Low Risk. | LOCAL OFFLINE GATES, run in this container: typecheck exit 0; full offline unit suite 949 files / 12293 passed \| 1 skipped; lint --max-warnings 0 exit 0; prettier --check clean; caring-contacts db suite 218 passed against a disposable local Postgres 16 (not the live Supabase project; assertNotClinicalKbProject refuses that ref by construction); cc-guards 1069 passed. HOSTED CI: green on the main-based head — PR required, Unit coverage, Build, Static PR checks, Safety and config, Caring Contacts database, Lighthouse budget, Semgrep, Gitleaks, GitGuardian, PR policy, PR mergeability. Hosted CI results named here were OBSERVED, not inherited: this Claude Code session read them directly from the GitHub check runs via the GitHub MCP tools, under Josh's standing instruction to babysit these PRs, which is the explicit confirmation the provider boundary requires for that read. Provider-backed gates NOT run: no eval:* retrieval canary, no verify:release, no check:supabase-project, no live Supabase or OpenAI test:live path, and no live-drift dispatch. | diff --git a/docs/branch-review-records/4618bc97849416bcc9b687e3669942b3bd9aa3c69fe34563d1eb0a56e23a55a5.record.md b/docs/branch-review-records/4618bc97849416bcc9b687e3669942b3bd9aa3c69fe34563d1eb0a56e23a55a5.record.md new file mode 100644 index 0000000000..a353bd0320 --- /dev/null +++ b/docs/branch-review-records/4618bc97849416bcc9b687e3669942b3bd9aa3c69fe34563d1eb0a56e23a55a5.record.md @@ -0,0 +1 @@ +| 2026-09-02 | claude/caring-contacts-rules-r7r2ih-2 | bdf300188da5ac7ac7f0b36eea1aab2d266cdc48 | PR #2533 (#RZVMPD): db/postgres-repository.ts PLAN_LIST_COLUMNS, schedule-view.ts doc comment, tests/caring-contacts-domain-isolation.test.ts and the wire-level listPlans test | MERGED 2026-09-02 into its base branch (claude/caring-contacts-rules-r7r2ih), not into main directly, so it reached main inside 94a14a829. Branch since deleted. Two guards shipped with the fix and both were confirmed red against the pre-fix code: a static scan of the constant and its wiring, and a wire-level test recording every statement listPlans issues. Bugbot reviewed the final head and rated Low Risk. Clinical Governance Preflight completed voluntarily — the pr-policy classifier returns clinicalRisk:false for these paths, which is a substring accident rather than a judgement about patient mobile numbers and identifiers. | LOCAL OFFLINE GATES, run in this container: typecheck exit 0; full offline unit suite 949 files / 12293 passed \| 1 skipped; lint exit 0; prettier --check clean; caring-contacts db suite 214 passed against a disposable local Postgres 16 (up from 213 by the new wire-level guard); domain-isolation 12 passed; mutation check — reverting listPlans to PLAN_COLUMNS turns both new guards red. HOSTED CI: none ran on this PR — repo CI is scoped to branches [main, release/**], so a PR whose base is another feature branch gets no pipeline at all. Its hosted proof is therefore the CI that ran on the main-based head AFTER this merged into it (see the claude/caring-contacts-rules-r7r2ih record at 94a14a829), not anything observed on this PR. Hosted CI results named here were OBSERVED, not inherited: this Claude Code session read them directly from the GitHub check runs via the GitHub MCP tools, under Josh's standing instruction to babysit these PRs, which is the explicit confirmation the provider boundary requires for that read. Provider-backed gates NOT run: no eval:* retrieval canary, no verify:release, no check:supabase-project, no live Supabase or OpenAI test:live path, and no live-drift dispatch. | diff --git a/docs/branch-review-records/85a379521e2bae9498d29f1f34eeacfbe6c224a8ee48ecf893be298b318e96a5.record.md b/docs/branch-review-records/85a379521e2bae9498d29f1f34eeacfbe6c224a8ee48ecf893be298b318e96a5.record.md new file mode 100644 index 0000000000..be09c06ba9 --- /dev/null +++ b/docs/branch-review-records/85a379521e2bae9498d29f1f34eeacfbe6c224a8ee48ecf893be298b318e96a5.record.md @@ -0,0 +1 @@ +| 2026-09-02 | claude/caring-contacts-rules-r7r2ih-3 | 2631782a39ce277f055b53bce8a0418d43b66ac9 | PR #2534 (#J7PZQP + #PAMATF, squashed to main): episode.ts, model.ts, repository.ts, schedule-view.ts, simulation.ts, message-policy.ts, both repository implementations, patient-overview.tsx, plan-activation.ts, the schedule route, the shared contract helper and their tests | MERGED to main 2026-09-02. Episode carries patientDetailClearedAt instead of the screen inferring a clearance from a blank name; listSendableContacts gates on the owning plan in both stores, overturning Ruling 129 as Ruling 129A by explicit owner decision. Codex review found a genuine P2: under READ COMMITTED a clearance committing mid-getEpisode produced an episode reporting a completed clearance while still releasing name and mobile number — the fix reintroducing the defect class it exists to remove. Reproduced, fixed by reading every clearance-touched field in one statement, and pinned by a database contract test that pauses the read between statements. Merged with NO Bugbot or Cursor approval-agent review: both returned neutral because the Cursor account was at its spend limit (recorded as a separate ledger item). | LOCAL OFFLINE GATES, run in this container: typecheck exit 0; cc-guards 42 files / 1069 passed; caring-contacts db suite 2 files / 218 passed against a disposable local Postgres 16 (not the live Supabase project); message-policy + model + simulation + diff-integrity + interface-vocabulary 181 passed \| 1 skipped; prettier --check clean on all files changed vs main; phantom-revert check clean (21 files, +904/-121, nothing outside caring-contacts). HOSTED CI: green on the main-based head — Production UI critical, Build, Static PR checks, Safety and config, Caring Contacts database, Semgrep, Gitleaks, GitGuardian, PR policy, PR mergeability. Hosted CI results named here were OBSERVED, not inherited: this Claude Code session read them directly from the GitHub check runs via the GitHub MCP tools, under Josh's standing instruction to babysit these PRs, which is the explicit confirmation the provider boundary requires for that read. Provider-backed gates NOT run: no eval:* retrieval canary, no verify:release, no check:supabase-project, no live Supabase or OpenAI test:live path, and no live-drift dispatch. | diff --git a/docs/branch-review-records/df797737cb58a35d2a44000165e9b6b487e4338469f4b89bc9616206b82f8063.record.md b/docs/branch-review-records/df797737cb58a35d2a44000165e9b6b487e4338469f4b89bc9616206b82f8063.record.md deleted file mode 100644 index 08409b61db..0000000000 --- a/docs/branch-review-records/df797737cb58a35d2a44000165e9b6b487e4338469f4b89bc9616206b82f8063.record.md +++ /dev/null @@ -1 +0,0 @@ -| 2026-09-02 | claude/caring-contacts-rules-r7r2ih-3 | 2631782a39ce277f055b53bce8a0418d43b66ac9 | PR #2534 (#J7PZQP + #PAMATF, squashed to main): episode.ts, model.ts, repository.ts, schedule-view.ts, simulation.ts, message-policy.ts, both repository implementations, patient-overview.tsx, plan-activation.ts, the schedule route, the shared contract helper and their tests | MERGED to main 2026-09-02. Episode carries patientDetailClearedAt instead of the screen inferring a clearance from a blank name; listSendableContacts gates on the owning plan in both stores, overturning Ruling 129 as Ruling 129A by explicit owner decision. Codex review found a genuine P2: under READ COMMITTED a clearance committing mid-getEpisode produced an episode reporting a completed clearance while still releasing name and mobile number — the fix reintroducing the defect class it exists to remove. Reproduced, fixed by reading every clearance-touched field in one statement, and pinned by a database contract test that pauses the read between statements. Merged with NO Bugbot or Cursor approval-agent review: both returned neutral because the Cursor account was at its spend limit (recorded as a separate ledger item). | typecheck exit 0; cc-guards 42 files / 1069 passed; caring-contacts db suite 2 files / 218 passed; message-policy + model + simulation + diff-integrity + interface-vocabulary 181 passed \| 1 skipped; prettier --check clean on all files changed vs main; phantom-revert check clean (21 files, +904/-121, nothing outside caring-contacts). CI green on the main-based head including Production UI critical, Build, Static PR checks, Safety and config, Caring Contacts database, Semgrep, Gitleaks, PR policy, PR mergeability. No provider-backed gate run. | diff --git a/docs/branch-review-records/f2b95df6ef379d0c7a26f3fa5a3ee865df92dba8e2e27cb9389f6586f9eae2fd.record.md b/docs/branch-review-records/f2b95df6ef379d0c7a26f3fa5a3ee865df92dba8e2e27cb9389f6586f9eae2fd.record.md deleted file mode 100644 index 294f968e55..0000000000 --- a/docs/branch-review-records/f2b95df6ef379d0c7a26f3fa5a3ee865df92dba8e2e27cb9389f6586f9eae2fd.record.md +++ /dev/null @@ -1 +0,0 @@ -| 2026-09-02 | claude/caring-contacts-rules-r7r2ih | 94a14a829312ab317b64064fe520a38481930db7 | PR #2532 (#59JT7W + #RZVMPD, squashed to main): src/lib/caring-contacts/message-policy.ts, db/postgres-repository.ts, schedule-view.ts and their tests | MERGED to main 2026-09-02. Closing-message refusal routed through the validateGovernedMessage chokepoint and widened to every message type; caseload list read narrowed to PLAN_LIST_COLUMNS. A clinical-governance review round caught the first draft granting a NEW permission (validateGovernedMessage returned valid:true for a standard message with no body at all) and masking the more serious record-level refusal behind 'write a body'; both fixed before merge. Bugbot reviewed and rated Low Risk. | typecheck exit 0; full offline unit suite 949 files / 12293 passed \| 1 skipped; lint --max-warnings 0 exit 0; prettier --check clean; caring-contacts db suite 218 passed; cc-guards 1069 passed; CI on main-based head green including PR required, Unit coverage, Build, Static PR checks, Lighthouse budget. No provider-backed gate run. |