diff --git a/docs/branch-review-records/575353430fcae06c9f21bdf48964297e47a5eba6285a23fe534414d846c8d51d.record.md b/docs/branch-review-records/575353430fcae06c9f21bdf48964297e47a5eba6285a23fe534414d846c8d51d.record.md new file mode 100644 index 000000000..208d48c50 --- /dev/null +++ b/docs/branch-review-records/575353430fcae06c9f21bdf48964297e47a5eba6285a23fe534414d846c8d51d.record.md @@ -0,0 +1 @@ +| 2026-08-13 | claude/ledger-tasks-fable-xhl7xb | 6f1cd23a34dca2fa3ae9d676d4dace46fd779d3a | ledger intake: merge-loss capture (4 inbox requests) | clean — additive JSON intake only, no canonical ledger edit | verify:pr-local (all 11 gates, none failed); dry-apply of 23 pending requests against origin/main | diff --git a/docs/outstanding-issues-inbox/210e3db5-f863-4dc8-8d6e-4d75d044e661.json b/docs/outstanding-issues-inbox/210e3db5-f863-4dc8-8d6e-4d75d044e661.json new file mode 100644 index 000000000..35b6552d0 --- /dev/null +++ b/docs/outstanding-issues-inbox/210e3db5-f863-4dc8-8d6e-4d75d044e661.json @@ -0,0 +1,13 @@ +{ + "version": 1, + "id": "210e3db5-f863-4dc8-8d6e-4d75d044e661", + "createdOn": "2026-08-13", + "action": "add", + "payload": { + "pri": "P2", + "type": "task", + "summary": "Re-land PR #1803 (--shadow-tight retirement onto --e1); 67 files on main still use the retired alias", + "detail": "PR #1803 squash-merged as 9d8370a on 2026-08-10, retiring the --shadow-tight role alias onto the --e1 elevation tier across 49 files. All 49 are byte-identical to their pre-#1803 state on main. Independent confirmation that does not rely on blob identity: git grep -l shadow-tight over src/ on main returns 67 files. Cause is the same merge, acf78bf; see the merge-loss detector row filed alongside this one. Commit 6f8c70d 'fix(pr-1815) resolve main merge conflict and keep shadow-tight switch migration' shows the migration was consciously preserved once and reverted again by a later merge in the same chain. Interaction with existing rows: #302 records scripts/design-system-contract-baseline.json pinning legacyShadowAliases at 220 while the checker measures 193 -- that gap is partly this loss, so re-landing #1803 should move the measurement sharply and #302 should be re-measured afterwards rather than actioned on its current numbers. #262 (DS Track A3, design-token debt) is also downstream of this. Next: cherry-pick 9d8370a onto current main and resolve against the token work that has landed since; this is mechanical but wide. Gate: npm run test on the design-token contract tests plus tests/tailwind-merge-config.test.ts, then check:design-system-contract. Stop: do not refresh the design-system contract baseline to absorb the change -- the point is that the measurement moves. Do not bundle with the #1800 re-land; that one carries a clinical governance preflight and this one does not.", + "source": "session 2026-08-13; 9d8370a; acf78bf; 6f8c70d; git grep shadow-tight on origin/main at 63526ee; rows #302 and #262" + } +} diff --git a/docs/outstanding-issues-inbox/31650c87-cfea-4a98-88e1-bd41b44c12b2.json b/docs/outstanding-issues-inbox/31650c87-cfea-4a98-88e1-bd41b44c12b2.json new file mode 100644 index 000000000..fcaac2058 --- /dev/null +++ b/docs/outstanding-issues-inbox/31650c87-cfea-4a98-88e1-bd41b44c12b2.json @@ -0,0 +1,10 @@ +{ + "version": 1, + "id": "31650c87-cfea-4a98-88e1-bd41b44c12b2", + "createdOn": "2026-08-14", + "action": "can\u0063el", + "payload": { + "requestId": "e1506952-64c6-472f-9da4-812f8d69b483", + "reason": "Superseded by request 8621298b-db72-4960-818a-66ae49a3977f, which records that the matcher was subsequently lost from main, distinguishes eight exact blob reversions from three later-evolved files, and moves the one-edit cap into the #1800 re-land." + } +} diff --git a/docs/outstanding-issues-inbox/829597d4-698b-4cc2-9bf4-65310504cba3.json b/docs/outstanding-issues-inbox/829597d4-698b-4cc2-9bf4-65310504cba3.json new file mode 100644 index 000000000..039373294 --- /dev/null +++ b/docs/outstanding-issues-inbox/829597d4-698b-4cc2-9bf4-65310504cba3.json @@ -0,0 +1,13 @@ +{ + "version": 1, + "id": "829597d4-698b-4cc2-9bf4-65310504cba3", + "createdOn": "2026-08-13", + "action": "add", + "payload": { + "pri": "P1", + "type": "rec", + "summary": "No gate detects a merged PR whose content is silently reverted by a later merge resolution", + "detail": "MEASURED 2026-08-13 by blob comparison against origin/main, not by reading merge messages. Method: for every PR merge into main since 2026-08-06, for each file the PR changed, compare origin/main's blob against the file's PRE-merge parent blob. Equality means the PR's change to that file is gone. Seven merged PRs came back positive: #1800 (fuzzy catalogue search plus its tests, 8 files), #1803 (the --shadow-tight to --e1 token retirement, 49 files), #1809 (2 specifier pages), #1811 (2 secondary-navigation test files), #1804 (4 test files), #1796 (worker/validate-runtime.ts), #1815 (1 command-surface file). Six of the seven first show the wiped state at ONE commit, acf78bf 2026-08-11 'Merge remote-tracking branch origin/main into probe2-1815', part of the PR #1815 babysit and unblock chain whose manual conflict resolutions took the stale branch side and reverted whatever had landed on main meanwhile. Confirmation that does not rely on blob identity: --shadow-tight is still referenced in 67 files on main after the PR that retired it merged, and open row #302 independently records legacyShadowAliases pinned at 220 while measuring 193, which is what a lost retirement looks like. WHY NOTHING WENT RED: the reverts took each PR's tests in the same stroke, so no gate had an assertion left to fail. Commit 6f8c70d 'fix(pr-1815) resolve main merge conflict and keep shadow-tight switch migration' shows a human trying to preserve #1803 and a later merge in the same chain undoing it anyway, so care at the keyboard is not the control. Note 55f51ab 'docs(issues) repair three merge losses' repaired the DOCS casualties of this same event; the source-code casualties were never noticed. This is #311's ledger loss-detector generalised from docs to source, which is where it actually bit. Next: add the blob-comparison sweep as a script plus a test, run it against origin/main post-merge or on a schedule, and fail on any file that reverts to its pre-PR blob. Keep the window bounded (for example 14 days) so the check stays cheap. Stop: do not treat a positive as automatically a defect, because a deliberate later revert looks identical at blob level. The check should name the PR and the file and require a human to confirm, exactly as the branch-review ledger does.", + "source": "session 2026-08-13; local blob sweep over origin/main at 63526ee; acf78bf; 6f8c70d; 55f51ab; row #302; row #311" + } +} diff --git a/docs/outstanding-issues-inbox/8621298b-db72-4960-818a-66ae49a3977f.json b/docs/outstanding-issues-inbox/8621298b-db72-4960-818a-66ae49a3977f.json new file mode 100644 index 000000000..ace10e018 --- /dev/null +++ b/docs/outstanding-issues-inbox/8621298b-db72-4960-818a-66ae49a3977f.json @@ -0,0 +1,10 @@ +{ + "version": 1, + "id": "8621298b-db72-4960-818a-66ae49a3977f", + "createdOn": "2026-08-13", + "action": "update", + "payload": { + "id": "#310", + "detail": "NOT REACHABLE ON MAIN AS OF 2026-08-13, AND NOT BECAUSE IT WAS FIXED. The whole matcher is gone: git show origin/main:src/lib/catalog-search.ts | grep -c typoDistanceLimit returns 0, and eight of the 11 files PR #1800 touched are byte-identical to their pre-#1800 state after merge acf78bf. Three files (`src/components/therapy-compass/data/select.ts`, `src/lib/formulation.ts`, and `tests/formulation.test.ts`) contain later unrelated changes, but the fuzzy-search hunks are absent from them too; preserve those newer changes during the re-land. So this row is not currently a live clinical hazard, but it must NOT be closed: the fix belongs in the re-land of #1800, not as a patch to main. See the two rows filed 2026-08-13 for the re-land and for the merge-loss detector. Re-run 2026-08-13 against the algorithm re-confirmed every measurement below, including that citalopram and escitalopram correctly do not match because the substring guard fires first. Original 2026-08-12 measurement retained: MEASURED 2026-08-12 by running the matcher itself, not by reading it. PR #1851 adds Damerau-Levenshtein typo recovery to src/lib/catalog-search.ts (fuzzySearchTokenCount, boundedTypoDistance, typoDistanceLimit) and folds it into the score. The tier term.length >= 8 -> 2 edits is the problem: Damerau counts an adjacent transposition as ONE edit, so fluoxetine -> duloxetine is distance 2 (substitute f->d, transpose lu->ul) and both are 10 characters. Confirmed hits against the PR's own algorithm: **fluoxetine -> duloxetine** (SSRI vs SNRI, different drugs), **prednisone -> prednisolone** (different drugs). Intended cases also confirmed working: sertraline -> setraline, olanzapine -> olanzepine. The existing guards DO hold — SSRI/SNRI, ADHD/ODD, citalopram/escitalopram, clozapine/clonazepam and quetiapine/olanzapine all correctly return no match. ONE MITIGATION, stated so this is not over-read: terms under 5 characters are excluded entirely. The fuzzy trigger is evaluated independently for each candidate record, so the hazard persists when both the exact drug and a two-edit near-match are present: the exact record receives a literal score while the wrong drug can independently receive a fuzzy score and appear as an additional result. Blast radius is wide because catalog-search.ts feeds ELEVEN modules — medications.ts (prescribing), dsm.ts, differentials.ts, differential-stream.ts, universal-search.ts, specifiers-search-index.ts, tools-catalog.ts, form-ranker.ts, service-ranker.ts. TESTED FIX: capping the >=8 tier at 1 edit removes both cross-drug hits and preserves every legitimate typo recovery in the sample — a one-line change to typoDistanceLimit. Next: do not patch main -- there is nothing there to patch. Apply the >= 8 tier cap of 1 edit inside the #1800 re-land, in the same commit, with a test over real catalogue drug names carrying both the exact and the near-match record and asserting the wrong drug is excluded while the exact drug remains. Stop: do not remove fuzzy search outright -- the typo recovery is genuinely useful and the guards are otherwise well judged, and do not close this row on the grounds that the code is currently absent. Note classifyPullRequestFiles returns clinicalRisk true for this path so the governance preflight fires, but ragRanking false, which is correct: this is catalogue ranking, not the pgvector retrieval path." + } +} diff --git a/docs/outstanding-issues-inbox/f23c14ec-e386-4910-ba60-fd488cc0a83b.json b/docs/outstanding-issues-inbox/f23c14ec-e386-4910-ba60-fd488cc0a83b.json new file mode 100644 index 000000000..c84e0c77c --- /dev/null +++ b/docs/outstanding-issues-inbox/f23c14ec-e386-4910-ba60-fd488cc0a83b.json @@ -0,0 +1,13 @@ +{ + "version": 1, + "id": "f23c14ec-e386-4910-ba60-fd488cc0a83b", + "createdOn": "2026-08-13", + "action": "add", + "payload": { + "pri": "P2", + "type": "task", + "summary": "Re-land PR #1800 (fuzzy catalogue search), applying the #310 one-edit cap in the same commit", + "detail": "PR #1800 squash-merged as 022c83b on 2026-08-10 and its entire content is absent from main: git show origin/main:src/lib/catalog-search.ts | grep -c typoDistanceLimit returns 0, eight of its 11 source and test files are byte-identical to their pre-#1800 state. The remaining three (`src/components/therapy-compass/data/select.ts`, `src/lib/formulation.ts`, and `tests/formulation.test.ts`) contain later unrelated changes, but the fuzzy-search hunks are absent from them too; preserve those newer changes during the re-land. Cause and evidence in the merge-loss detector row filed alongside this one. Consequence today is a MISSING FEATURE, not a live hazard: because the matcher is gone, the #310 cross-drug defect is not reachable on main. Do not close #310 on that basis, and do not re-land #1800 unchanged. RE-LAND WITH THE FIX: #310 measured that the tier term.length >= 8 -> 2 edits is the problem, because Damerau scores an adjacent transposition as one edit, so fluoxetine to duloxetine is distance 2 and both are ten characters. Re-run 2026-08-13 against the algorithm confirms it, and confirms prednisone to prednisolone as the second real cross-drug hit. Capping that tier at 1 edit removes both while preserving sertraline to sertralin style recovery. The row's other claims also held on re-run: citalopram and escitalopram do not fuzzy-match, because the substring guard fires first, and clozapine/clonazepam and quetiapine/olanzapine are correctly out of range. Next: cherry-pick 022c83b onto current main, change typoDistanceLimit's >= 8 tier from 2 to 1, and add a test over real catalogue drug names with both the exact and the near-match record present, asserting the wrong drug is excluded while the exact drug remains. Gate: focused Vitest on `tests/catalog-search.test.ts` plus the other four test files #1800 touched. Stop: this path is clinicalRisk true under classifyPullRequestFiles because catalog-search.ts feeds medications.ts and prescribing, so the PR needs a complete Clinical Governance Preflight and must not be bundled with unrelated chores. ragRanking is correctly false; this is catalogue ranking, not pgvector retrieval.", + "source": "session 2026-08-13; 022c83b; origin/main at 63526ee; row #310; algorithm re-run locally against real drug-name pairs" + } +}