fix: address post-merge review of #3603 — two wrong guarantees, two fence bugs#3605
Conversation
Review comments on #3603 landed after it merged: seven from CodeRabbit and four from Codex. Two of the Codex findings are guarantees that were wrong in a way that matters, and two are real defects in the fence scanners. **The PII-safe log guarantee was overstated.** I documented `error-safe-<date>.log` as recording only the error's runtime type, so it could be shared without leaking user-authored content. `safeErrorDescription` renders `'<message> (errorType=<Type>)'` — the caller's `message` goes in **verbatim**. What the file actually omits is the raw exception string and the stack trace (whose frames carry absolute paths and the system username). So it is shareable *because callers are required to treat a log message as telemetry, never content* — the contract `DomainLogger` states — not because the sink sanitises anything. Put a task title in `message` and it is in the shareable log. **`DerivedAgentState` is on the wake critical path after all.** I had trusted the composite's own header — "Drives no production read; B6 flips reads onto this fold" — but that sentence predates the cutover it predicted. `AgentSyncService.reconciledAgentState` is called at the start of every task, project, event, improver and day-agent wake; it folds markers and links over the cached row so a value lost to last-writer-wins self-heals before the agent decides anything. The concept now describes that, with the two boundaries that make it precise — the merge is not a blind "log wins", and UI/service reads do stay on the raw cache — and the stale header comment is corrected. That is the third time a stale source comment seeded a wrong claim here, after `database_config_flags.dart` and the six-catalog ARB list. Two fence defects, both verified by fixture before and after: - **A mixed closing run closed a block.** `closesFence` checked only the first character and the length, and the regex class allowed `` `~~ `` — so a malformed run closed a ``` block and the remainder of the file rendered as code while the check reported clean. CommonMark requires a uniform run. - **Blockquoted fences were skipped in silence.** CommonMark strips container prefixes before recognising a fence, so `> ```mermaid` is a real diagram. Both scanners now strip blockquote markers, and the checker unwraps the body too — otherwise mermaid is handed `> > A --> B`. List-item containers are still not modelled, which is now stated rather than implied. CodeRabbit's findings, all valid: - `knowledge/log.md`'s single 2026-07-26 entry had accumulated ten bullets across the day, several recording claims that a later bullet in the same entry reversed — the privacy overshoot, "TaskStatus's five states", and expiry as merely "reported". Rewritten as the net outcome, and the convention now says a date's entry records that rather than the churn. - The duplicated live/terminal split is **seven** files, not six. - `verified` accepts either a mapping or a list; the doc named only `verified[].by`, which is the validator's message label, not the shape an author writes. - `day_entries` was described as both "every persisted recording" and "newest 32". Both are true at different stages — `loadForDay` is unbounded, the section caps — and the two passages now say so. - The Matrix zero-cache-limit lead-in still read as a present-tense assertion. Not changed: Gemini's comment reports that its consumer review product has been sunset, and codecov is unchanged at 99.15%.
|
Caution The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased. |
|
Warning Review limit reached
Next review available in: 1 minute Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (9)
📝 WalkthroughWalkthroughThe change tightens Mermaid fence parsing for container-prefixed Markdown and mixed delimiters, adds edge-case tests, and updates knowledge documentation, metadata, maintenance logs, projection behavior, wake prompts, sync handling, and task-status guidance. ChangesKnowledge bundle validation
Estimated code review effort: 3 (Moderate) | ~25 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #3605 +/- ##
=======================================
Coverage 99.15% 99.15%
=======================================
Files 1785 1785
Lines 131174 131174
=======================================
Hits 130062 130062
Misses 1112 1112
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
knowledge/features/agents/projection.md (1)
33-36: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winDo not describe the raw cache as self-healing.
AgentRepository.getAgentStatereturns the cached row; the suppliedlib/features/agents/sync/agent_sync_service.dartimplementation performs self-healing only inreconciledAgentState. Change this wording to “eventual; wake-path reconciliation is self-healing” to preserve the distinction.Also applies to: 96-98
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@knowledge/features/agents/projection.md` around lines 33 - 36, The projection documentation incorrectly describes the raw cache as self-healing. Update the wording around the “same event set, two arrival orders” diagram and the corresponding text at the other referenced section to say the cache is eventual, while wake-path reconciliation is self-healing; preserve the distinction between AgentRepository.getAgentState and reconciledAgentState.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@tool/okf/check_mermaid.mjs`:
- Around line 95-96: Make blockquote/container stripping conditional on the
fence opener: in check_mermaid.mjs, update the line normalization around
stripContainers and the delimiter/body handling near the sibling site so
prefixes are removed only when the active fence was opened with matching
containers, while preserving literal > content and > ``` in unquoted top-level
fences; apply the equivalent opener-tied behavior in okf_validator.dart at its
reported site, and add regression tests for literal > content in unquoted
top-level fences.
---
Outside diff comments:
In `@knowledge/features/agents/projection.md`:
- Around line 33-36: The projection documentation incorrectly describes the raw
cache as self-healing. Update the wording around the “same event set, two
arrival orders” diagram and the corresponding text at the other referenced
section to say the cache is eventual, while wake-path reconciliation is
self-healing; preserve the distinction between AgentRepository.getAgentState and
reconciledAgentState.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 1e2088b8-ed4c-4e0f-a4ed-3e4def083b96
📒 Files selected for processing (12)
knowledge/architecture/logging-and-diagnostics.mdknowledge/conventions/knowledge-bundle.mdknowledge/features/agents/projection.mdknowledge/features/daily_os_next/wake-prompt.mdknowledge/features/sync/receive-path.mdknowledge/features/tasks/data-model.mdknowledge/log.mdlib/features/agents/projection/derived_agent_state.darttest/tool/okf/okf_validator_test.darttool/okf/check_mermaid.mjstool/okf/check_mermaid_test.mjstool/okf/okf_validator.dart
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 405b9567e8
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
…m round two Both bots independently found the same defect in the fix from the previous commit, and it is the worst kind: a **false green**. **Container stripping ran on every line, including inside an open fence.** A top-level fence whose body contained a literal `` > ``` `` had that marker stripped and the line then read as the close, so an unclosed fence was reported as a cleanly parsed block — verified by fixture before and after. CommonMark treats fence content as literal; only the container a fence was opened *under* belongs to its body. Both scanners now capture the opener's prefix and strip exactly that, and both suites pin the literal-`>` case. Four content findings, each checked against the code: - **The logging diagram still labelled the safe log "runtime type only — shareable"** while the prose two paragraphs below said the guarantee is conditional. A reader trusting the diagram would still be told to share a file that can contain task titles. The node now states what the sink actually does: no raw error, no stack trace, message kept verbatim. - **The reconcile is not history-independent.** I wrote that it "loads markers, not the full message log, so its cost does not grow with an agent's history". `getMessagesByKind(agentId, system)` passes no limit — `limit ?? -1` — and a milestone marker is appended on every completed wake, so the read and the fold grow with the number of wakes. Much smaller than the full log, still linear. - **`knowledge/log.md`'s net-outcome entry still carried the superseded claim** that `DerivedAgentState` drives no production read — written before the same commit corrected it, which is precisely the contradiction that rewrite was supposed to remove. - **The terminal-status inventory was wrong again**, and the shape was the problem: seven files became thirteen once the sealed-type tests were counted. Replaced with the five *idioms* and how to find them all, since a count in prose will keep drifting. Called out the quietest site — `_findResolution` returning null makes a wake run read as unresolved rather than erroring, so a new terminal status would silently distort the charts. Tests: 96 Dart, 19 mermaid-checker.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 0c6966dafc
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
… a fixed comment
Two findings on the previous commit, both mine.
**Recording the container as literal prefix text broke valid quoted fences.** The
marker's trailing space is optional in CommonMark, so `>flowchart TD` and `>``` `
under a `> ```mermaid` opener are the same container — but `startsWith('> ')`
matched neither, so the Dart validator reported a valid block as **unclosed** and
the JS scanner passed `>flowchart TD` to mermaid. Reproduced by fixture, then fixed
by tracking the opener's **depth** and stripping that many markers regardless of
spacing. Both suites now pin the varying-spacing case, and the literal-`>`-inside-a-
top-level-fence case still behaves — the two pull in opposite directions, so both
are asserted together.
**The projection concept sent readers to verify a sentence the same commit
deleted.** It said the composite's header "still says it drives no production read"
after that header had been corrected. Rewritten as history — the sentence outlived
the cutover it predicted, which is why it misled this concept twice — with
`agent_sync_service.dart` named as the authority for the read path.
Tests: 97 Dart, 20 mermaid-checker.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: dd365cc981
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| rejected rather than ignored. | ||
| * **Enforcement**: Mermaid is parsed in CI by mermaid itself | ||
| ([`tool/okf/check_mermaid.mjs`](../tool/okf/check_mermaid.mjs), 15 tests), since | ||
| there is no Dart parser. It accepts every CommonMark fence form, treats a |
There was a problem hiding this comment.
Scan Mermaid fences nested inside list items
When a Mermaid fence is nested beneath a list item whose content indentation is four or more columns, such as a multi-digit ordered item, CommonMark still treats it as a fenced block, but check_mermaid.mjs only recognizes 0–3 leading spaces and explicitly does not strip list containers. The checker therefore reports zero parsed blocks and can let an invalid diagram pass, contradicting this new “every CommonMark fence form” guarantee; model list containers or enforce and accurately document a top-level-only restriction.
AGENTS.md reference: AGENTS.md:L95-L97
Useful? React with 👍 / 👎.
| final candidate = _containerDepth(trimmedEnd); | ||
| final match = _fenceOpenPattern.firstMatch( | ||
| _stripDepth(trimmedEnd, candidate), |
There was a problem hiding this comment.
Exclude YAML frontmatter from fence scanning
When a valid multiline frontmatter value contains a quoted fence example, such as description: | followed by an indented > ````, this new container stripping recognizes it as a Markdown opener even though it is YAML, because _validateConceptpasses the entire file rather thandocument.body. The Dart validator then reports a spurious unclosed fence, and the JavaScript scanner has the same whole-file behavior for > ```mermaid`; scan only the body while retaining its starting-line offset.
Useful? React with 👍 / 👎.
Addresses the review comments that landed on #3603 after it merged — seven from
CodeRabbit, four from Codex. Ten were valid; each was checked against the code
before changing anything.
Docs and tooling only — no runtime change, so no CHANGELOG entry.
Two guarantees that were wrong
The PII-safe log.
error-safe-<date>.logwas documented as recording only theerror's runtime type, so it could be shared without leaking user-authored content.
safeErrorDescriptionrenders'<message> (errorType=<Type>)'— the caller'smessagegoes in verbatim. What the file omits is the raw exception string and thestack trace (whose frames carry absolute paths and the system username). So it is
shareable because callers must treat a log message as telemetry, never content,
which is the contract
DomainLoggerstates — not because the sink sanitises it.DerivedAgentStateis on the wake critical path. The composite's own headersays "Drives no production read; B6 flips reads onto this fold", and I trusted it.
That sentence predates the cutover it predicted:
AgentSyncService.reconciledAgentStateis called at the start of every task,project, event, improver and day-agent wake, folding markers and links over the
cached row so a value lost to last-writer-wins self-heals before the agent decides
anything. The concept now documents that, plus the two boundaries that keep it
precise — the merge is not a blind "log wins", and UI/service reads do stay on the
raw cache — and the stale header comment is fixed at source.
That is the third time a stale source comment seeded a wrong claim in this work,
after
database_config_flags.dartand AGENTS.md's six-catalog ARB list. Each timethe fix now includes the comment.
Two fence defects
Both verified by fixture before and after, and pinned by tests.
and the length only, and the character class allowed
`~~— so a malformedrun closed a ``` block and the rest of the file rendered as code while the check
reported clean. CommonMark requires a uniform run.
prefixes before recognising a fence, so
> ```mermaidis a real diagram. Bothscanners strip blockquote markers now, and the checker unwraps the body too —
otherwise mermaid receives
> > A --> Band reports no diagram type. List-itemcontainers remain unmodelled, which is now stated rather than implied.
Content corrections
knowledge/log.md's single2026-07-26entry had grown ten bullets across theday, several recording claims a later bullet in the same entry reversed — the
privacy overshoot, "TaskStatus's five states", expiry as merely "reported". It is
now the net outcome, and the convention says a date's entry records that rather
than the churn.
TaskStatussplit is duplicated across seven files, notsix.
verifiedaccepts either a{ by, at }mapping or a list of them; the doc namedonly
verified[].by, which is the validator's message label rather than the shapean author writes.
day_entrieswas described as both "every persisted recording" and "newest 32".Both are true at different stages —
loadForDayis unbounded, the prompt sectioncaps — and both passages now say which.
reads as a 7.0.0 finding not re-verified on 8.x.
Verification
make knowledge_check(89 concepts, 131 diagrams), strict mode, 95 validator tests,18 mermaid-checker tests, analyzer, formatter.
Summary by CodeRabbit
Documentation
Bug Fixes