chore(memory): promote strong-fit configuration drafts from memory-pipeline for review - #130
Conversation
1979c05 to
6a2742a
Compare
sugat009
left a comment
There was a problem hiding this comment.
Requesting changes, though to be clear the fix is upstream and not something to patch by hand here. This seeder faithfully promotes what the distillation pipeline generated, so nothing is wrong with the promotion itself. The problem is in the drafts the pipeline produced, and I verified it against the live medic/cht-core API for every draft in this PR.
The defect: issueNumber / issueUrl name the merge PR, not the resolved issue
One precise note up front, because the intuitive version of this is not what is happening: issueNumber and issueUrl always agree with each other (the URL is literally /issues/<issueNumber>). The bug is that in 4 of 10 drafts here, that shared number is a pull request, so /issues/N silently redirects to /pull/N. The real resolved issue survives only in the PR-title slug. For example:
10198-fix8026-validate-empty-branding-doc.mdstoresissueNumber: 10198/issueUrl: .../issues/10198, but 10198 is the merge PR ("fix(#8026): validate empty branding doc"). The real issue is #8026 (closed): "Admin app fails to updatebrandingif existing document is malformed".9407-fix9406-disable-unsupported-languages.mdstoresissueNumber: 9407/issueUrl: .../issues/9407, but 9407 is the merge PR ("fix(#9406): disable unsupported languages"). The real issue is #9406 (closed): "Update default configurations to disable unsupported languages".
This is the same scraper behaviour flagged on #121, and it is pipeline-wide: across the four clean seeders, 60 of 107 drafts are affected.
Why request-changes rather than merge-and-fix-later
This corpus is the agent's memory of resolved issues (consumed by the Context Analysis Agent, see #135). A reference that resolves to a PR instead of the issue is simply wrong data, and it specifically defeats #135's planned de-duplication by issue id, since the "id" ends up being the PR id. Regenerating the drafts after the upstream fix will rewrite most of these files anyway, so merging now would churn the corpus twice.
Suggested fix (at the source, not file by file)
- Fix the distiller/scraper to take the resolved issue from the
type(#N):PR title (the filename slug already extracts it correctly), and keep the PR number insource_prwhere it belongs. - Regenerate and re-promote this domain's drafts.
- Add de-duplication by real issue id (also a #135 acceptance item).
Open to discussing the approach. Once the drafts carry the real issue references, this should be a quick re-review.
…ly, configuration) Deterministic relink via #129's relink-issues tool: drafts whose identity keys recorded the merge PR now point at the resolved issue. Frontmatter id/issueNumber/issueUrl lines only; bodies untouched. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Per sugat009's review on #130: the 4 mislinked identity keys were fixed by the relink commit; this follow-up verifies and polishes the corpus. All 10 PR-to-issue mappings verified against the live cht-core API (0 mismatches) — including 10555, whose issueNumber 10556 is a genuine body closing ref ("Closes #10556", the pt-BR translations request), not a distiller artifact. Also: scrub reviewer/process narrative and classifier seed references from 7 files (technical content kept, attribution removed), and add the optional source_prs schema definition (identical to the other seeders). No duplicate issueNumbers; validate-schema 74/74. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1720724 to
f80479e
Compare
|
@sugat009 Same as the others. Rebased onto main and addressed the review: identity keys relinked via #129's tool (4 files, same treatment as merged #129); all 10 PR→issue mappings re-verified against the cht-core API, zero mismatches. The deterministic relink supersedes the "regenerate and re-promote" suggestion — #129's merge established that approach. Also scrubbed process narrative from the prose and added the optional source_prs schema field used by the sibling seeders' duplicate collapses. |
sugat009
left a comment
There was a problem hiding this comment.
Content re-review. Identity/dedup/schema clean. Remaining (mostly distillation fidelity):
- issue (accuracy):
10604,8722,11021carry wrong/fabricated technical detail (inline). - nitpick (leakage):
9696Domain Rationale ("…the seed", "explicit strong fit"); strip. - nitpick:
9696↔9727are an in-batch RTL/translations pair (issues#9682/#9683) butrelated_issuesdoesn't cross-link them; backfill.
Cross-cutting (whole promote batch, not blocking this PR alone): filenames still encode the PR number while frontmatter is issue-keyed, and two draft schemas coexist (machine-distilled vs hand-authored) — worth a cleanup pass. Full detail + re-runnable Verify commands are in my consolidated review notes.
Every claim in these ten drafts was checked against the medic/cht-core commit it
was distilled from, using word-bounded `git grep`, `git diff-tree --name-status`
and `git ls-tree`. 124 claims verified true; the corrections below are the ones
the source contradicted. Reviewer-flagged items are marked [R].
10604 — the draft described the wrong bug and the wrong fix:
- [R] the view is `medic-client/doc_by_type`; `docs_by_type` exists nowhere
(0 hits at 06d2e3abe and on master; the real view has 22).
- [R] no migration ever changed a view path. #10255 (de02d8421) removed the
`translations` special case from the doc_by_type map, so the view stopped
emitting `['translations', doc.enabled]` and its `{code,name}` value; that PR
updated two admin controllers but missed the languages service.
- the fix did not repoint at a "current view path" — it replaced the query with
an allDocs range scan over the `messages-` prefix and projects off `row.doc`;
the lodash/core import was dropped.
- the spec was ADDED, not updated (diff-tree says A) — the service had no spec.
- dropped `related_workflows: [data-migration]`; no migration is involved.
8722 — [R] `add-branding-doc.js` was DELETED and replaced by
add-cht-branding-doc.js, not "added alongside, preserving the original"; the
replacement upserts and only overwrites attachments whose digest still matches
the old Medic assets. Removed the deleted file from entities, marked A/D in
Related Files, and dropped the anachronistic `ui-extensions` workflow tag (that
workstream first appears 2026-03-30; this anchor is 2023-11-28).
11021 — [R] `updateServiceWorker()` is defined and exported in config-watcher.js
itself (line 140/208), not imported from ui-extension.js, which exports only
getScript/getAllProperties. The documented test command was also broken:
`@medic/environment` exits(1) without COUCH_URL and db stubbing needs
UNIT_TEST_ENV=1, so the repo script `npm run unit-api` is the correct form.
The `ui-extension:` literal is deliberately left alone — that PR postdates the
local checkout and master has no PREFIXES.UI_EXTENSION, so either spelling could
be right.
9727 — `language.service.ts` does not read the rtl property off a doc; it holds
an in-memory registry. translation-loader.provider.ts reads `doc.rtl` and calls
setRtlLanguage. Dropped the anachronistic ui-extensions tag.
10278 — one line was added, in the attachment path only; the load path was
untouched. Also spelled out the two real guard forms (`res && res.resources` in
admin JS, `res?.resources ?? {}` in webapp TS).
10198 — the controller scaffolds one empty `resources` object and guards the
favicon/icon assignments; template safety comes from new ng-if attributes, not
from scaffolded keys.
9696/9727 — stripped classifier scaffolding from 9696's Domain Rationale and
cross-linked the RTL/translations pair in related_issues, both as requested in
review.
Verification: 124 claims confirmed against source, 0 contradicted. The
remaining unverifiable claims are confined to 11021 and 11057, whose source PR
numbers do not resolve to any commit in cht-core; nothing in either draft was
edited on the strength of a claim that could not be checked.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…in cht-core
This draft describes the config-watcher gaining a UI-extension doc-id branch that
calls updateServiceWorker(), and presents it as completed and tested. That code
is not in cht-core.
git grep -n "startsWith" origin/master -- api/src/services/config-watcher.js
:167 change.id.startsWith(PREFIXES.TRANSLATIONS)
:171 change.id.startsWith('form:')
There is no UI-extension branch, and no commit anywhere in the repository
references the issue the draft claims to close. PREFIXES.UI_EXTENSION does now
exist in shared-libs/constants, so the work may be in flight, but nothing has
landed.
This is the same class as a draft distilled from an issue rather than a merged
PR: a memory asserting behaviour the codebase does not have is worse than no
memory, because an agent consuming the corpus cannot tell the difference. Better
re-distilled once the change merges.
Removing it also retires the one place on this branch where a correction had to
be guessed — the draft's 'ui-extension:' literal could not be checked, since
master carries no PREFIXES.UI_EXTENSION usage to compare against.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
Re-verified every factual claim in these drafts against the cht-core commit each was distilled from, rather than only the three items raised in review. Confirmed against source, with 13 corrections applied and one draft removed. After the removal the branch stands at 110 verified claims and no contradicted ones. These scripts from WIP were used. Each correction below has the command that establishes it. 10604 — the draft described the wrong cause and the wrong fixBeyond the view name, two larger problems: There was no view-path migration. The stated root cause never happened — the view was never renamed or removed and is still present with ~20 consumers. What actually broke the page is #10255 removing the git -C $CORE log --format='%h %ci %s' 06d2e3abe2 -- ddocs/medic-db/medic-client/views/doc_by_type/
# de02d8421 2025-09-09 chore(#8157): remove use of translationdoc.enabled (#10255)
git -C $CORE show de02d8421 -- ddocs/medic-db/medic-client/views/doc_by_type/map.js
# removes: if (doc.type === 'translations') { emit(['translations', doc.enabled], {code,name}); return; }That PR updated The fix is not a path correction. It abandons the view entirely: git -C $CORE show 06d2e3abe2 -- admin/src/js/services/languages.js
# - .query('medic-client/doc_by_type', { key: ['translations', true] })
# + .allDocs({ start_key: 'messages-', end_key: 'messages-', include_docs: true })
# - return _.map(result.rows, 'value');
# + return result.rows.map(row => ({ code: row.doc.code, name: row.doc.name }));And the spec was added, not updated — the service had no test before this PR: git -C $CORE diff-tree --no-commit-id --name-status -r 06d2e3abe2
# M admin/src/js/services/languages.js
# A admin/tests/unit/services/languages.spec.jsThe view name is corrected to 8722 — the migration was deleted, not preservedgit -C $CORE diff-tree -M --no-commit-id --name-status -r d93b9162e2 -- api/src/migrations/
# D api/src/migrations/add-branding-doc.js
# A api/src/migrations/add-cht-branding-doc.jsCorrected, the deleted file removed from git -C $CORE log --all --reverse --format='%h %ci' -- api/src/services/ui-extension.js | head -19727 — rtl resolution misattributedgit -C $CORE grep -n -F -w setRtlLanguage 2175676e28
# providers/translation-loader.provider.ts:50 doc.rtl && this.languageService.setRtlLanguage(locale)
# services/language.service.ts:107 setRtlLanguage(code) { ... }
10278 / 10198 — scope overstatedgit -C $CORE show 9b26cbd0e2 -- admin/src/js/controllers/images-partners.js | grep '^+' | grep -v '^+++'
# exactly one added line, inside addAttachment; the load path is untouched
git -C $CORE show d9b2ef5750 -- admin/src/templates/images_branding.html | grep '^+' | grep -v '^+++'
# ng-if="favicon" / ng-if="icon" ← where template safety actually comes from, not scaffolded keysReview nitpicksClassifier scaffolding stripped from 9696's Domain Rationale, and 9696 ↔ 9727 cross-linked in What was confirmed correct110 claims verified positively across the nine remaining drafts, not merely "no error found" — Related-File membership with A/M/D status on every draft, and every named symbol located in the file the draft attributes it to. The strongest were 9727 (23), 8722 (20), 10604 (15 after correction), 10278 (14), 10198 (13). Nine claims remain unverifiable, all in 11057. Drafts whose provenance I could not verifyTwo drafts had no resolvable anchor, and this is not clone staleness: their PR numbers are stamped nowhere in history, even on a same-day clone. One is removed; the other is flagged. 11021 — removed from this PR: the described feature is not in cht-core. git -C $CORE grep -n "startsWith" origin/master -- api/src/services/config-watcher.js
# :167 change.id.startsWith(PREFIXES.TRANSLATIONS)
# :171 change.id.startsWith('form:') ← no UI-extension branch
git -C $CORE log --all --oneline --fixed-strings --grep="#11018" # empty
Removing it also retired the one correction on this branch that would have had to be guessed: the draft's 11057 — mechanism real, attribution wrong. git -C $CORE grep -n -F -w weight origin/master -- webapp/src/ts/services/header-tabs.service.ts # :23 :32 :41
git -C $CORE log --oneline -1 origin/master -- webapp/src/ts/services/header-tabs.service.ts
# 180c29ecf feat(#10224): support ui-extensions (#11050)The weight ordering is real, but it arrived in #11050, not #11057. Worth confirming the Nothing in 11057 was edited on the strength of an unverifiable claim — its substance checks out, only its |
…ding fixes (configuration)
- 10604: the doc_by_type consumer count is scoped to the fix's era (18 files);
#10822 (57ea9228b, 2026-07-01) has since moved consumers off the view and
narrowed its index to form/user-settings — present-tense master claim was stale
- 11057: provenance is real, not doubtful — PR #11057 merged into the
10224-ui-extensions feature branch; its merge commit IS source_sha (46c8f7c8e),
unreachable from master only because the epic squashed via #11050 (180c29ecf).
Added source_prs [#11057, #11050] and a Related Issues note so anchors resolve
from a master clone
- 10278: 'browserify-compatibility const was documented' -> the reviewer-suggested
?. one-liner broke the admin browserify build (review thread), explaining the
divergent admin/webapp guard spellings
- 10555: AI disclosure is a PR-description section, not a file comment; strip
triage vocabulary ('catch-all') from the Domain Rationale
- 8722: complete (added)/(deleted) annotations on the logo asset Related Files
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Before the re-review starts: I audited my own verification comment above and found two wrong conclusions in it, plus one stale claim it let through. Corrections landed in 3cd4124; The "unresolvable anchors" were real all along — my clone-scoped tooling was the problemI wrote that 11057 and 11021 "had no resolvable anchor" and doubted curl -s https://api.github.com/repos/medic/cht-core/pulls/11057 | jq '{state, merged, base: .base.ref, merge_commit_sha}'
# "closed", true, "10224-ui-extensions", "46c8f7c8e43a969d9ecd12c65d3816b19664fd63" ← exactly the draft's source_sha
git -C $CORE log -1 --format='%h %ci %s' 180c29ecf
# 180c29ecf 2026-06-22 feat(#10224): support ui-extensions (#11050) ← how it reached masterThe nine claims I logged as "unverifiable, all in 11057" are now verified, all true, against both the PR diff and current master: git -C $CORE grep -n -w weight origin/master -- webapp/src/ts/services/header-tabs.service.ts
# :23–:57 defaults · :133 header_tabs app-settings override · :150 UI-extension weight · :162,:185 sorts
git -C $CORE grep -n SidebarTab origin/master -- webapp/src/ts/components/sidebar-menu/sidebar-menu.component.ts
# :23,:50 — the sidebar refactor (hardcoded TAB_MENU_OPTIONS → pre-ordered SidebarTab list) survived the squashBlockers #10672/#10901 and the forum request are verbatim in issue #10908's body; cht-docs#2213 and the "most unit tests by Claude" disclosure are verbatim in PR #11057's. Draft change in 3cd4124: 11021 stays dropped, but for a corrected reason. It was not the smsparser case — the work was real, merged into the epic, and tested. It was superseded during the epic's evolution: the #11050 squash lands no UI-extension dispatch in curl -s https://api.github.com/repos/medic/cht-core/pulls/11021 | jq '{state, merged, base: .base.ref}'
# "closed", true, "10224-ui-extensions"
git -C $CORE show 180c29ecf -- api/src/services/config-watcher.js
# removals only: extensionLibs require, isLibChange dispatch, handleLibsChangesOne claim my pass verified against the wrong era — now time-scoped10604 said the view "still exists on master with roughly fifteen consumers" (my comment above said ~20). Both figures were measured at the source commit and are stale on today's master: #10822 (2026-07-01) narrowed git -C $CORE grep -l doc_by_type 06d2e3abe2 | wc -l # 18 — at the fix
git -C $CORE grep -l doc_by_type origin/master | wc -l # 0 — today
git -C $CORE log -1 --format='%h %ci %s' 57ea9228b
# 57ea9228b 2026-07-01 feat(#10638): not indexing common documents in doc_by_type (#10822)The draft sentence is now era-scoped: 18 referencing files at the time of the fix, with the #10822 note for current master. Three wording fixes in the same commit
Updated tally, from a fresh |
FOURTH false-positive class, proven live on the promote-configuration review (#130): a PR merged into a FEATURE branch that later squash-merged onto master leaves no trace a clone can see. The child's merge commit lives only on the deleted branch and no squash subject carries its number, so both local strategies failed and nine TRUE claims in the 11057 draft degraded to unverifiable — and the same blind spot produced a wrong "not in cht-core" provenance diagnosis on 11021's removal. resolveAnchor now takes the repo slug and, when the clone alone cannot name the commit, asks the GitHub API which LOCAL commit carries the PR: - merged PR whose merge commit is in the clone but whose subject has no "(#N)" stamp (the SSO cluster) -> anchored directly; - merged into a feature branch -> one hop: the PR whose HEAD is that branch (pulls?head=owner:branch) supplies the squash the clone can see (11057 -> 10224-ui-extensions -> #11050 / 180c29ecf). Resolution only — adjudication never leaves git, a sha the clone lacks is never anchored to, and every failure (gh missing, curl down, rate limit, unmerged PR) degrades to the existing unverifiable semantics rather than a defect or a crash. gh is tried first for the authenticated rate limit; anonymous curl is the fallback. Anchors resolved this way carry a note surfaced in claims.json and REPORT.md; --no-api-resolve keeps a run fully offline. Grounding against an epic squash reuses the sibling-union over-approximation already accepted for source_prs: file-touched sees the union of every child's changes and statuses reflect the landed state. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
sugat009
left a comment
There was a problem hiding this comment.
Round 3 on the reworked head. All five findings from my last round are verified fixed: the 10604 rewrite is now the model for how these drafts should read (correct view name, accurate description of the allDocs replacement, time-scoped staleness), 8722 states the add-branding-doc.js deletion correctly, the 9696/9727 cross-links landed, the scaffolding is gone, and deleting 11021 rather than correcting it was the right call, since the hook it documented never reached master.
Requesting changes on the two residual items plus two nitpicks inline. Both residuals are the same secondary-section staleness pattern flagged in more volume on #120.
…nd it (configuration) Sugat's two residuals and two nitpicks, plus the same class found systematically rather than only where he pointed. 10198 — the draft contradicted itself in four places on the one mechanism the grounding pass corrected. Solution says template safety comes from the new ng-if attributes 'not from scaffolded keys', while summary, Code Patterns and Design Choices all still credited the scaffolding. Only Testing was flagged in review; a coherence pass over the whole file found the rest. All four now agree: reads are guarded so missing images stay undefined, the template hides them with ng-if, and the single scaffolded 'resources' object exists because the submit path writes into it. Also drops the stale 'One related case is not covered' artifact — the merged spec covers both the empty-doc and null-resources cases. 10278 — resource-icons.service.ts and resource-icon.service.spec.ts were replaced by custom-resource.service.* in #11050 (180c29ecf), so both were named in the present tense for paths that no longer exist. Time-scoped in 10604's style, with a paths note covering every mention rather than the four lines review listed. 11057 — source_prs dropped. #11050 resolves #10224, not this draft's #10908, so it never satisfied the field's 'All PR refs that resolve to this issue'. Nothing is lost: the API resolver anchors this draft by hopping from #11057's base branch, and the epic provenance was already prose in Related Issues. lastUpdated bumped on 10198, 9696, 9727 (review) and 9407 (found by the new stale-timestamp check, which compares the stamp to the file's last commit rather than eyeballing which drafts moved). Gate: validate-schema 73 passed / 0 failed; verify-drafts --online 0 blocking / 0 warnings; check-coherence 0 contradictions. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…dit (configuration) - 9407: the stamp was set to the date of its last CONTENT commit (2026-07-16), but setting it is itself an edit, so the branch's own stale-timestamp check then failed the file. The rule that actually holds is 'touch the file, stamp it today'. - 10278: my (replaced by custom-resource.service.ts in #11050) suffix on an entities entry made a machine-readable path non-bare, which any downstream consumer matching on paths would miss. Reverted to the bare path; the caveat already lives in the Code Patterns note and the Related Files annotation, where prose belongs. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…eading, not probing Round 3 on #120/#130 was almost entirely defects no existing layer could see. Each class below is now checked mechanically, with the LLM confined to identifying candidates that code then verifies. SELF-CONTRADICTION (new Layer 3, check-coherence.ts). A grounding pass corrects the sections that assert mechanism against code and leaves the interpretive ones asserting what it just disproved, so both halves ground independently while the document tells two stories. 10198 says template safety comes from ng-if attributes 'not from scaffolded keys' in Solution and that the controller 'scaffolds the minimum keys the template requires' in Design Choices. The model may only IDENTIFY pairs and must quote both sides verbatim; verifyContradictions drops any pair whose quotes do not occur in the file, so a hallucinated finding cannot land. DRIFT (claim-probes.ts). resource-icons.service.ts was real when its PR shipped and is gone today: checking only the anchor certifies it, checking only master refutes it, and both are wrong — the claim is true, the tense is not. A claim that grounds at its anchor is now re-checked against master and flagged when the draft names a dead entity with no temporal qualifier. Exits 3, not 1: nothing is disproven, so 'ungrounded' keeps meaning 'this is wrong'. CROSS-REFERENCE ACCURACY (verify-drafts.ts, --online). #10754 sat in Related Issues glossed as 'Scheduled task duplicate processing'; it is 'Cookies not being sent with secure: true'. Every #N there is now classified and its gloss compared to the real title, with only total disjointness reported so paraphrase stays free. PRs cited as issues warn unless labelled 'PR #N'. SNIPPET FIDELITY (claim-probes.ts). The 4278 fence was a composite of two real helpers, so every symbol in it probed clean while the block existed nowhere. Fences are matched against every file the draft names, whitespace- and comment-insensitively, with elision markers as segment boundaries. STALE TIMESTAMPS (verify-drafts.ts). lastUpdated must not predate the file's last commit; 13 rewritten drafts kept their old stamp. Also: the extraction prompt no longer turns a REMOVAL claim ('removed the parseResponseBody helper') into an existence probe, which cost a false flag last run; gh-classify gains describeNumber for titles; Draft carries its absolute path so git pathspecs work when scanning a sibling worktree. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
All four items are fixed, and chasing the cause behind them turned up one more instance of the same class in a draft you had not flagged — that one is the reason this reply is longer than four lines. Head is Your items10198 Testing — your suggestion, verbatim. The merged spec does cover both cases ( 10278 present-tense dead path — time-scoped in 10604's style, and the drift check found the problem was wider than the four lines you cited: git -C $CORE cat-file -e origin/master:webapp/src/ts/services/resource-icons.service.ts || echo absent
git -C $CORE log --oneline --diff-filter=D -1 -- webapp/src/ts/services/resource-icons.service.ts
# 180c29ecf feat(#10224): support ui-extensions (#11050)11057 lastUpdated — 10198, 9696 and 9727 bumped. A stale-timestamp check now enforces this ( The item you did not flagFollowing your diagnosis as a class rather than a checklist, I built a check for it — an LLM identifies contradicting pairs and must quote both sides verbatim, then the script verifies mechanically that both quotes occur in the file and discards any that do not. Run blind across all nine configuration drafts it found exactly one thing, in 10198, which the round-2 grounding pass had half-corrected:
The summary and Code Patterns carried the same stale mechanism. Verified against Gate
Two things I would rather say than have you find:
|
…argets) Same class the reviewer identified on #120 and #130: the grounding pass corrected the sections that assert mechanism against code and left summary and Design Choices asserting what it had just disproved. Every pair below was found by check-coherence over two passes and then verified against cht-core; in each case the corrected body was right and the stale side was rewritten to match it. - 10362: summary said the service is 'wired into task state' and Design Choices said it consumes task state, while Code Patterns says it reads no NgRx state - it subscribes to contactsMarkedAsDirty and fetches docs. - 10480: summary said the counter mirrors the unread-count pattern; Code Patterns says the PR generalises that flow (setUnreadCount became setBubbleCounter). Testing credited the rules-engine integration test with 'the count computation'; the engine contributes the showTask predicate (index.js:117) and the count is computed in the webapp. - 9232: summary said the filter appears only for multi-facility users and single-facility users see no change; Solution says there is no facility-count term, so everyone with a facility list gets it. - 9553: summary said the fix reconciles state against the configuration; the body says isStale only checks the blob has targets and aggregate keys and never reads the configured targets. Solution also said turnover re-scopes/resets emissions; Code Patterns says they are preserved. - 9705: Design Choices claimed the fix throws on WRITE errors; the change is to a read catch-all, and the file's one bulkDocs still only console.errors. - 10623: Design Choices said the filters were reused rather than built; overdue-filter and task-type-filter are new components, both on master. - 8932: summary called the flashed text 'empty-state messages'; Root Cause shows they are end-of-list messages gated on has-items being true. - 10371: Design Choices claimed a new reusable telemetry test util; tests/utils/telemetry.js pre-existed and was modified. - 10324: summary said targets analytics had no way to review prior periods; Problem says target-aggregates already had that filter since #9317. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
sugat009
left a comment
There was a problem hiding this comment.
Approving. All four round-3 comments verified fixed at b8004ca:
- 10198's stale "One related case is not covered by the fix" is gone, replaced with accurate coverage of both the empty-doc and null-resources cases.
- 10278 is now properly time-scoped, with a "Note on paths" paragraph naming
custom-resource.service.ts, PR #11050 and commit 180c29ecf, and both Related Files entries annotated. This is the 10604 pattern applied correctly, and it is the model I would point the other domain branches at. - 11057's stray
source_prsentry for #11050 is removed. - The three stale
lastUpdatedvalues are bumped to 2026-07-30.
Zero residual findings. CI green at b8004ca.
…y-pipeline for review (#123) * chore(memory): promote strong-fit tasks-and-targets drafts for review * fix(#135): relink id/issueNumber/issueUrl to real issues (metadata-only, tasks-and-targets) Deterministic relink via #129's relink-issues tool: drafts whose identity keys recorded the merge PR now point at the resolved issue. Frontmatter id/issueNumber/issueUrl lines only; bodies untouched. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(#135): collapse duplicate clusters + review fixes (tasks-and-targets) Per sugat009's review on #123: fix the hallucinated identity on 9232 — its stored key was medic/care-teams#137 mis-stamped as cht-core; the memory is now keyed cht-core-9231 (PR title scope) with the care-teams Related Issues lines dropped. Collapse the 3 clusters to one memory per issue with source_prs[]: 9231 (9232+9282+9317 sequential facets), 9431 (9486 + 4.13.x sibling 9549), and 9552 (9553+9555+9569+9570 — the two distinct sub-fixes attributed separately, backport lines noted). Drop 8838 (closes no tracked issue — skip-and-flag policy). Cross-domain dedup: 9099 (#6543 facet) moves to the authentication canonical; 10432 (#10344) to the contacts corpus's existing memory; 9975 (#9974) to the forms corpus's existing memory — refs recorded there in touch-ups. Forced fits re-annotated weak (10390 datasource, 8932 cross-component, 10786 telemetry pipeline). Process narrative scrubbed from 11 files (named reviewers, CI-status and AI-change chronology). All 35 mappings verified (live cht-core API + the reviewer's own closingIssuesReferences audit for rate-limited cluster members); validate-schema 89/89; no duplicate issueNumbers. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(#136): ground tasks-and-targets drafts against cht-core source Every factual claim in the twenty-five drafts on this branch was checked against the cht-core commit it was distilled from. 319 claims confirmed; 71 corrections applied. Each correction was re-checked by a second pass instructed to refute it. Two drafts on this branch contradicted each other, and the source settled both: BACKPORT LINE. 9553 said the fix "was backported to the 4.1.x line (PR #9555)" while its sibling 9486 said 4.13.x. The backport commit c8a7f13ad is titled "...for 4.13.x (#9555)" and is an ancestor of origin/4.13.x but not of origin/4.1.x. 9553 corrected; 9486 was already right. TASK ORDERING. 10362 said tasks are "ordered by due date and then priority"; 9980 said priority descending with due date as tie-break. The shared comparator in shared-libs/task-utils runs a priority cascade first and only reaches compareDates() when priorities are invalid or equal, so 9980 is right and 10362 was inverted. Corrected in 10362. 10362 was wrong in three further ways: the notifications are Android device notifications delivered through globalThis.medicmobile_android, not in-app ones, and are inert in a browser; the new service reads no NgRx state, only RulesEngineService.contactsMarkedAsDirty; and the ordering comparator was not new logic but an extraction of an existing private function out of the tasks reducer. Also corrected: 10772 described its e2e spec as added when the commit modified it (only the target config was added), plus prior-state overstatements, A/M status confusions and telemetry key inexactness across the branch. Left unedited deliberately: 10390's cht-datasource module names, which conflict with 10423's but cannot be checked because its own commit is unrecoverable; and 10436's Mocha-harness attribution, for the same reason. Six proposed corrections did not survive re-checking. 108 claims remain unverifiable, chiefly on drafts whose PR numbers appear nowhere in cht-core history. Nothing was edited on the strength of a claim that could not be checked. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix(#136): bump lastUpdated on all 25 drafts (tasks-and-targets) Every draft in the batch was edited by the relink, dedup and grounding commits without its stamp moving, so all 25 failed the stale-timestamp check. Stamped today rather than with each file's last content-change date: the stamp edit is itself a commit, so a content date fails on the very commit that sets it - the rule learned twice on the configuration and messaging branches. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix(#136): time-scope four drafts whose epic renamed their files (tasks-and-targets) 10324, 10371, 10436 and 10507 all merged into the 10140_previous-month-targets feature branch and reached master only in that epic's squash, #10423 (622c625427). The epic reshaped them on the way: - the e2e directory was renamed analytics/ -> targets/, so the tests/e2e/default/analytics/analytics.wdio-spec.js these drafts name is tests/e2e/default/targets/analytics.wdio-spec.js on master; - webapp/src/ts/libs/config.ts, created by 10507 and renamed by 10436, does not exist on master at all - only .mocharc.js survives of the mocha harness, and the subtitle handling now lives in rules-engine.service.ts; - RulesEngineService.fetchTargets() is spelled as a bare fetchTargets() on the service (rules-engine.service.ts:501) and really did gain the reporting-period argument this draft describes. Every path is accurate for its own PR, which is why grounding at the anchor passed them; they are wrong only as directions for a reader looking at master today. Each now says so, with the landed location where there is one. This is the drift class the probe was built for, arriving in bulk because five drafts share one epic. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix(#136): twelve self-contradictions across nine drafts (tasks-and-targets) Same class the reviewer identified on #120 and #130: the grounding pass corrected the sections that assert mechanism against code and left summary and Design Choices asserting what it had just disproved. Every pair below was found by check-coherence over two passes and then verified against cht-core; in each case the corrected body was right and the stale side was rewritten to match it. - 10362: summary said the service is 'wired into task state' and Design Choices said it consumes task state, while Code Patterns says it reads no NgRx state - it subscribes to contactsMarkedAsDirty and fetches docs. - 10480: summary said the counter mirrors the unread-count pattern; Code Patterns says the PR generalises that flow (setUnreadCount became setBubbleCounter). Testing credited the rules-engine integration test with 'the count computation'; the engine contributes the showTask predicate (index.js:117) and the count is computed in the webapp. - 9232: summary said the filter appears only for multi-facility users and single-facility users see no change; Solution says there is no facility-count term, so everyone with a facility list gets it. - 9553: summary said the fix reconciles state against the configuration; the body says isStale only checks the blob has targets and aggregate keys and never reads the configured targets. Solution also said turnover re-scopes/resets emissions; Code Patterns says they are preserved. - 9705: Design Choices claimed the fix throws on WRITE errors; the change is to a read catch-all, and the file's one bulkDocs still only console.errors. - 10623: Design Choices said the filters were reused rather than built; overdue-filter and task-type-filter are new components, both on master. - 8932: summary called the flashed text 'empty-state messages'; Root Cause shows they are end-of-list messages gated on has-items being true. - 10371: Design Choices claimed a new reusable telemetry test util; tests/utils/telemetry.js pre-existed and was modified. - 10324: summary said targets analytics had no way to review prior periods; Problem says target-aggregates already had that filter since #9317. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix(#136): drift and two wrong file statuses (tasks-and-targets) Real defects: - 9553 called target-accuracy.wdio-spec.js an added e2e spec; it was modified. Its migrateStaleState sentence is also attributed to #9553, but the symbol enters in the #9569/#9570 follow-up - it is absent at dc47c51e4 and present on master at target-state.js:124. - 9980 called tasks.spec.ts added; diff-tree says modified. Drift - true at the anchor, gone from master, now time-scoped: - 10362's shared-libs/task-utils/test/order-by-due-date-and-priority.js, removed by #10701. - 9232's analytics-target-aggregates-sidebar-filter component and spec, folded into the shared analytics sidebar filter by the same #10140 epic that reshaped four other drafts in this batch; its modules.module.ts, dissolved by the Angular 19 standalone migration (#9759); and the can_view_old_filter_and_search / can_view_old_action_bar permissions, both retired from master. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix(#136): keep 9232 entities a bare path (tasks-and-targets) My drift annotation landed on the entities entry rather than the Related Files line - replace(...,1) hits the frontmatter occurrence first - and the colon inside it made YAML parse the item as a map, so validate-schema went 88/1. Reverted to the bare path, annotation moved to Related Files where prose belongs. Same mistake as 10278 on the configuration branch; entities is machine-readable and any downstream consumer matching on paths would miss an annotated one. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix(#136): the two contradictions that survived three passes (tasks-and-targets) Both had resisted an earlier fix because I corrected one statement and left a third one standing - the same one-section-at-a-time failure this whole exercise is about. 9232 made three incompatible claims about what gates the filter UI. The summary said multi-facility users only; I corrected it to 'has a facility list at all', which was also wrong; Code Patterns still said 'only when facility_id resolves to multiple facilities'. What Solution actually documents is canDisplayFilterButton() gating on !isAdmin plus the legacy permissions being absent, with facility count controlling only the radio group inside the sidebar. All four statements now say that. 9553 said the interval-turnover migration fires 'when the persisted reporting interval no longer matches the current CalendarInterval' while Code Patterns says it reuses the shape check rather than comparing intervals. My previous edit fixed the emissions half of that sentence and left the trigger clause. Rewritten: load() runs the shape check on every hydration. Also time-scoped the two legacy permission constants where they are quoted, both retired from master. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix(#136): cross-reference glosses and PR labels (tasks-and-targets) From the online audit, which this branch had never had - an earlier attempt rate-limited 23 of 25 drafts, and record caching (baeb04b) is what made a complete 25-draft scan fit the 60/hour anonymous budget. It finished with 0 unverified. Blocking: - 9486 cited #9432 as 'recalculate tasks/targets automatically on document or state changes (debounced)'. #9432 is 'Merge ensureTaskFreshness and ensureTargetFreshness into single event' - a performance issue about folding two 120-second background refreshes into one, not about triggering on document changes. - 9718 cited #9486 as an issue describing 'prior work improving recalculation'. #9486 is a PR, 'feat(#9431): always aggregate and store targets'. Now labelled and titled. Also: #6209's gloss was fair but vague enough to trip the weak-overlap warning, so it now carries the real title; and 9232's #9267/#9283/#9305 are PRs cited as issues, now labelled PR #N. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix(#136): five more partial-fix mismatches (tasks-and-targets) Three of these five exist because an earlier commit in this same PR corrected one section and left a sibling asserting the old thing - the failure mode this whole exercise is about, committed by the person fixing it, twice now. Recording that plainly: - 9232: my summary rewrite said the facility radio group is the only element gated on facility count; Design Choices, Solution, Code Patterns and Testing all also list the per-aggregate facility indicator. - 9705: I corrected Design Choices to the read-side catch-all and left the summary saying errors were swallowed 'while saving' with 'failed writes'. - 9553: I corrected Testing to 'modified not created' for the e2e target-accuracy spec and left Solution saying the spec was added. Two were pre-existing: - 10436's summary attributed the wrong-subtitle defect to both analytics pages; Problem confines it to target-aggregates. - 9980's Design Choices claimed changes were 'confined to the webapp' while Solution lists config/default/tasks.js, which is not in the webapp. Coherence over three passes went 5/2/2 before these fixes to 2/3/0 after the previous round, with 9232 and 9553 dropping from every pass to one - the sampling behaviour is why the gate is three passes and not one. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix(#136): two drafts called modified specs 'added' (tasks-and-targets) Both are real imprecision the exhaustive pass caught, not tool artifacts: - 10390 lists five mocha specs as added for the new datasource module. Three were; test/qualifier.spec.ts and test/index.spec.ts already existed and PR #10390 extended them. - 10786 says it 'added sentinel replications.spec.js and mocha purger.spec.js coverage'. The coverage was added, but both spec files pre-existed and were modified. Reworded to 'extended the existing'. Small, but the whole point of the corpus is that a reader can trust a file list, and 'added' versus 'extended' is exactly the sort of detail an agent would act on. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix(#136): three contradictions the x3 coherence gate surfaced (tasks-and-targets) 9705 recurred in all three passes, which is the signal that separates a real finding from sampling noise - and it was mine. My earlier summary said the catch-all 'swallowed every error into a synthesised default document'. The code at the anchor's parent is 'if (err.status === 404)': only a 404 produced a fresh doc, every other rejection fell through returning nothing. So the failure mode was worse than the summary claimed - neither a document nor an error - and the Root Cause section had it right all along. Summary and Design Choices now match it. 9486 said aggregation was 'only triggered when the user navigated to certain pages', which its own Root Cause refutes: a mark-contacts-dirty change-feed hook already existed pre-fix (confirmed at dc3ef42ab^). What was missing was aggregation and persistence, not the trigger. Reworded. 9553 named handleIntervalTurnover in three places with no temporal qualifier; #9714 removed interval turnover from master altogether, so the function is gone. Time-scoped. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix(#136): disambiguate which 9486 file got the change subscription Code Patterns listed both key files and then appended '(change subscription + debounce)', which reads as applying to both. The Solution says db-sync changed only to make inProgressSync awaitable, and the diff agrees - three lines, no subscription. Reordered so each file carries its own parenthetical. Found by one coherence pass of three. By the protocol that is sampling noise rather than a robust finding, but a single-pass finding was real once before on this branch (9022), so they get read rather than dismissed. The other single-pass finding this round was a genuine model error: its own rationale said 'the first is not a contradiction of the second' and it reported the pair anyway - the documented limit of a gate that proves quotes exist, not that they conflict. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix(#136): an off-by-one and a wrong file status (tasks-and-targets) Both single-pass findings, both real - which is why single-pass findings get read here rather than written off as sampling noise. 8772's summary says the short-circuit fires 'when the key count exceeds 500'. The guard is 'if (!params?.keys || params.keys.length < MAX_QUERY_KEYS) return' with MAX_QUERY_KEYS = 500, so it fires at 500 or more, not above 500. A reader implementing against this would put the boundary in the wrong place. 10423 calls shared-libs/cht-datasource/test/target.spec.ts a modified datasource target module; diff-tree at 622c625427 reports A. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix(#136): 'Added/updated' hid four added files, and 'future' hid today 10423 wrote 'Added/updated mocha unit tests for ...' over a list of four files that diff-tree reports as A, A, A, A. The hedge made the extractor guess per file and made a reader unable to tell which. All four were added, so the sentence now says so. 10480's Design Choices says the bubble counts 'Overdue' and due 'Today' tasks, while the Solution said 'tasks due in the future are intentionally excluded' - and a task due later today is in the future. Reworded to 'due after today', with the due-today case stated explicitly. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix(#136): twelve more claims the exhaustive pass caught (tasks-and-targets) Repeated ground and coherence passes over the same twenty-five drafts, on the standing rule that recurrence proves a finding real while a single appearance proves nothing. Every item below was checked against cht-core or the issue text, not reasoned about. Wrong facts: - 10362 named the comparator `order-by-due-date-and-priority` in two sections. That is its test file; the export is orderByDueDateAndPriority. - 11142 put FreetextFilterComponent in the tasks module. It lives in components/filters/freetext-filter/ and the Tasks page reuses it. - 10436's Testing called two page objects and both e2e helpers new; diff-tree says both page objects were modified and only targets-helper-functions.js was added. - 10623's Code Patterns credited reports and messages with dropping the duplicated lineage filter and omitted tasks.component.ts, which dropped its own removeUserFacility call in the same PR. Summaries left behind by earlier corrections, the class this branch is supposed to be closing: - 9232 called a regression a missing feature. #9231 says multi-facility users could not view aggregate targets at all in 4.9.0. - 10480 said the unread-count flow was generalised to carry the task count. setBubbleCounter still carries only reports and messages; getBubbleCounter spreads those and adds a task count off another slice. - 8772 stated the short-circuit condition and then its inverse in the same parenthetical. Both true, unreadable together, and two passes read it as a contradiction. Tense, where a file did not survive the 10140 epic: - 10507 called libs/config.ts a helper it introduced and updated at once, and gave it a present-tense home the same draft denies. - 10436 named it twice more unscoped. - 10390 had no "paths are as of this PR" banner at all, despite ten of the twenty-one files its PR touched being target-interval.* names that exist nowhere in cht-core. It gets the banner; the vocabulary rewrite belongs to the data-access work. - 10371's Code Patterns implied one component records both open and selection telemetry. analytics-filter.component.ts records only :open. 10480 also now says why a task due today counts: the due date is parsed date-only, so it sits at midnight, and #3943 asks for exactly overdue and due-today. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix(#136): three more, all found by repeating the same passes - 10423's Testing listed eight test files under one "Added". Six were added; the two e2e WDIO specs already existed and were modified. Both ground passes agreed on this one. - 10324's Testing opened the same way and is worse: its PR adds no test file at all. Every spec named was modified, and the sidebar-filter spec was renamed rather than created. - 9553's summary blamed "a CHT upgrade that changes target configuration". Root Cause blames the #9486 persisted-shape change and the code agrees — isStale is `(state) => !state || !state.targets || !state.aggregate`, a shape check that never reads configuration. added-versus-modified is now five of the findings on this branch. It is caught only when extraction samples the sentence, because deciding it means scoping "Added X, Y and Z" across a coordinated list. A regex attempt at that flagged 126 of 164 mentions, including one sentence reading "(modified, not created)", so it was dropped in favour of running more passes. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix(#136): bump lastUpdated on the three drafts edited today verify-drafts compares lastUpdated against the file mtime; the previous commit landed after the date rolled over. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix(#136): two the fourth round of passes surfaced - 10362's Domain Rationale said the implementation "centers on the task pipeline (new task-notifications service, tasks reducer, ...)" while its own Solution says the reducer is not consumed by the service and was only changed to import a comparator. The reducer comes out of the list. Same class as the rest of this branch: an interpretive section left asserting what the grounding pass had already disproved. - 9232 wrote "added new translation keys (api/resources/translations/messages-en.properties)". The keys are new; the file is not, and the parenthetical reads as though it were. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix(#136): 9553 had interval turnover reading the wrong interval Solution said the migrated emissions are rewrapped "so handleIntervalTurnover can read them against the active interval", while Design Choices said the same function writes the PREVIOUS interval's target doc. Design Choices is right. handleIntervalTurnover returns early when stateCalculatedAt falls inside the current interval, and otherwise aggregates against calendarInterval.getInterval(monthStartDate, stateCalculatedAt) — the interval the stale state belongs to — and stores that as the target doc. Reading against the active interval is the one thing it never does. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix(#136): the 9553 interval fix introduced two unscoped anchor-era symbols e1d0df4 corrected which interval handleIntervalTurnover reads, and in doing so named calendarInterval.getInterval and stateCalculatedAt — both real at the anchor, both gone from master because #9718 (also in this batch) removed the interval-turnover mechanism entirely. The drift check flagged them in three of the last four passes. One scoping clause covers the sentence and points the reader at the 9718 draft, which documents the removal. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix(#136): the five items from review 4845979803 (tasks-and-targets) Each was re-derived from the PRs' own diffs and cht-core master before editing, not taken on the reviewer's word. All five checked out. 9553 - the symptom was inverted. Issue #9552 reports a crash, not wrong numbers: `Object.keys(state.targets)` in aggregateStoredTargetEmissions throws `TypeError: Cannot convert undefined or null to object` because a pre-#9486 blob is a bare targets map. Interval detection was never the defect -- handleIntervalTurnover already did `moment(stateCalculatedAt).isBetween(...)` and `calendarInterval.getInterval(...)` at fe795fb^, and #9569 added no interval logic at all (+1 line in rules-state-store.js, +9/-4 in target-state.js, rest tests). Title, summary, Problem, Root Cause, Solution, Testing and Related Issues now all tell the crash story; the e2e case is named ('should handle old format of the rules-state-store') instead of being called a configuration change. 10436 - the harness attribution was backwards. This PR *removed* the mocha pieces #10507 had added: config.spec.ts +0/-103, tsconfig.mocha.json +0/-9, .mocharc.js +0/-2, libs/config.ts +0/-26, all deletions. webapp/tsconfig.spec.json is the webapp-root karma tsconfig, is on master, and only gained sinon-chai types here. `getValueFromFunction` was deleted outright (zero-hit on master), not folded -- its role is now getReportingMonth in rules-engine.service.ts, which this PR added. 10362 - `orderByDueDateAndPriority` is not a task-utils export on master. task-utils exports only setTaskState; the comparator is at reducers/tasks.ts:15 and the service imports it from @mm-reducers/tasks. #10701 moved it back, its description saying task-utils is for report SMS tasks, not rules-engine tasks. The draft now records the round trip and names master's location. 10324 - the radio labels are both wrong and the contrast is imaginary. Both filters render `targets.this_month.subtitle` / `targets.last_month.subtitle` = "This month" / "Last month"; "Previous month" is zero-hit in messages-en and is only the ReportingPeriod.PREVIOUS enum value. 10371 - the telemetry segment is `:reporting-period`, matching collectFilterSelectionTelemetry('reporting-period') and the key its own Solution already quoted. Two more on these same drafts, from sweeping the class rather than the instance. 10371 carried the identical epic-rename misattribution filed only against 10324: the e2e analytics/ -> targets/ rename was #10480 (bed454652) on master, not the #10423 squash. And 10324 credited itself with the sidebar's `telemetryKey` input, which it never touches -- #10371 added it; 10324 added userFacilities and showFacilityFilter. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix(#136): name which PR deleted libs/config.ts, in the draft that added it 10436's correction leaves 10507 as the only other draft describing webapp/src/ts/libs/config.ts, and it attributed the file's disappearance to "the epic" generically. It was #10436 specifically, later in the same epic, which also removed the two mocha pieces 10507 lists in Related Files. Naming the deleting PR makes the pair agree and gives a reader one hop to the whole story. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix(#136): four contradictions the gate found outside the review's five Re-running the full gate over the reworked branch surfaced these on drafts the round-4 review did not name. Each adjudicated against cht-core before rewriting. 9486 - three passes, because the first two fixes were themselves wrong. The summary said targets were computed "only ... when visiting specific pages", which its own Root Cause contradicts with two 120s ensure-freshness debounces (`ENSURE_FRESHNESS_SECS = 120` at dc3ef42ab^, used twice). Correcting that to "a 120s debounce" then contradicted the same line's "two separate" -- and correcting *that* left Problem claiming nothing ran on incoming changes while Root Cause said the hook called updateEmissionsFor per change. At dc3ef42ab^ that function only does `rulesStateStore.markDirty(contactIds)`: it invalidates, it does not recompute. Problem now says exactly that. 9705 - the Problem opened by locating the swallowed error on the write, while the summary, the next sentence, Root Cause, Solution and Design Choices all locate it on the read that precedes the write. The read is right; the opener is now neutral about which call failed. 10390 - Domain Rationale said "all changed files are shared-libs/cht-datasource plus one API controller", but the PR also changes api/src/routing.js, adds integration tests under the top-level tests/integration/ tree, and touches .mocharc.js and package.json. Reworded to state the scope without under-counting. 8932 - the title called the flashed strings "empty states" while Root Cause shows both are gated on the has-items flag being true (`hasTasks`, `hasContacts`), which makes them end-of-list messages, the opposite of an empty state. Title and the two tags follow. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Promotes 10 strong-fit
configurationdrafts fromagent-memory/_pending/intoagent-memory/domains/configuration/issues/for squad content review.Categories: feature (6), bug (4)
Themes: translations & RTL support, branding/partners doc validation, header-tab ordering, UI-extension service-worker rebuilds.
All 10 carry
domainFit: strong+ a## Domain Rationalesection. 18 weak-fit drafts deferred to Stream C —configurationwas a catch-all in this run (64% weak), so this PR is intentionally the distilled minority.seeding-claude-cli-v2(feat(#108): seeding pipeline - CLI provider, domain-rationale, infrastructure domain, concurrency #119) — retarget tomainafter the schema lands.validate-schema: passing, 0 failures.