Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
137 changes: 137 additions & 0 deletions docs/dream-cycle/2026-09-23-grounding-quality-report.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
# Dream Cycle 2026-09-23 — grounding-quality reconciliation

DEEP=`grounding-quality`, SCAN=`retrieval-precision`,`citation-binding` (slot 3 of 5,
`20260923 % 5 == 3`). No bonus deep dive tonight (`% 25` = 23, `% 75` = 48, both non-zero).

## Rotation / Ledger Check

`docs/dream-cycle/LEDGER.md` on `main` still ends at 2026-08-31 — expected, not a gap: the ledger
row ships in the candidate PR by convention and nothing on this surface has merged since #178
(2026-08-26). Re-checked recent fates directly rather than assuming:

- **#142/#143, #147/#148, #149/#150** (2026-08-19/20): MERGED.
- **#178** (2026-08-26): MERGED — the last dream-cycle merge of any kind, 28 days ago.
- **#154/#155**: PR closed unmerged, change landed on `main` directly via `420854b`.
- Every `dream/*` PR opened 2026-09-01 through tonight — 25 PRs (#269 through #317) — remains open
and draft. Confirmed via GitHub MCP `search_pull_requests` against `head:dream/*`, not assumed.

### This surface specifically (grounding-quality), last 4 prior nights

| Date | PR | Finding | Status on `main` today |
|---|---|---|---|
| 2026-09-03 | #237 (closed unmerged) | Citation-header rank hijack (relative +1 offset); filed issue #236, ADR-0076/0087 Proposed | **Still live** — `kb/verify-citation.mjs:38-39`'s own comment still says "not airtight against a document engineered to predict and spoof the exact next rank"; ADR-0087 not on `main`; issue #236 still open |
| 2026-09-08 | #270 | `gradeQuestion()`'s `routed` metric blind to right-repo-wrong-file citations; adds `expectPath` | Integrated — `scripts/eval-brain.mjs:85-87` uses `routedRepo` for `routed` today |
| 2026-09-13 | #287 | Recovers ADR-0076 as ADR-0087 (byte-for-byte, after a renumbering collision) | **Not integrated** — `docs/adr/0087-*.md` absent from `main`; #287 still open |
| 2026-09-18 | #297 | Recovers PR #239: `provenance`/`pass` case still read `top?.repo` instead of `routedRepo` | **Not integrated** — verified live tonight, see below |

## Verification performed tonight (not re-derived from memory)

```
$ grep -n "routedRepo\|top?.repo !== 'ruv-gists'" scripts/eval-brain.mjs
85: const routedRepo = receipt?.repo ?? top?.repo ?? null;
86: const routed = !!(grounded && q.expectRepo?.length && routedRepo
87: && repoMatchesExpected(routedRepo, q.expectRepo, repoAliases));
95: return { grounded, routed: null, abstained, pass: !!grounded && !abstained && (top?.repo !== 'ruv-gists' || bannerPresent) };
```

Line 95's `provenance` stratum `pass` computation still reads the raw top-ranked citation
(`top?.repo`) instead of the same `routedRepo` the function already computes at line 85 — exactly
the defect PR #297 (2026-09-18) already fixes, TEETH-verified, adversarially critiqued CLEAR, and
confirmed rebased onto current `main` (`git merge-base --is-ancestor origin/main origin/dream/2026-09-18-grounding-quality-provenance-receipt`
→ true, zero commits behind). **This is not a new finding** — it is issue #239's original gap,
never a tracking issue under this repo's ISSUE DISPOSITION OVERRIDE (a verified fix is a work
record), sitting unmerged for 5 days with a ready, current, non-conflicting fix.

`docs/adr/0076-memory-full-integration.md` and `docs/adr/0086-corpus-seed-pipeline-consolidation.md`
exist on `main` under those numbers (unrelated content, confirmed by reading both); ADR-0087's slot
is free on `main`, consistent with #287's own account of the two renumbering collisions.

Targeted regression check (both grounding-quality-surface test files, current `main`,
zero diff applied): `npx vitest run tests/unit/eval-brain-gate.test.mjs
tests/unit/verify-citation.test.mjs` → **45/45 pass**. `npm run claims:verify`: 3 PASS / 4 SKIP
(brain-dependent claims skip loudly — standard composition, unchanged from every prior night).
`npm run eval:gate`: `EVALUATED=blocked` — `no brain at /root/.cache/ruvnet-brain/kb` (container
never materializes a corpus; not a credentials block, `OPENROUTER_API_KEY` is present).

No new grounding-quality defect was found tonight distinct from the three already tracked above.

## Hypothesis

None reached the freeze-then-evaluate stage — this is a reconciliation night (same precedent as
PR #269, 2026-09-08). Per STEP 5-9: `EVALUATED=no / VERDICT=INCONCLUSIVE / reason=no new testable
hypothesis; the surface's known findings are already tracked in open, currently-mergeable PRs
(#270 integrated, #287 and #297 still open) awaiting human review, and re-deriving them again
tonight would be pure duplicate work`.

## Darwin Lineage

Not run — no candidate diff, no continuous parameter to evolve.

## Evidence

OBSERVATION (re-read `scripts/eval-brain.mjs`, `kb/verify-citation.mjs`, ADR namespace on current
`main`) → MEASUREMENT (grep + targeted test run, both reproduced live tonight, not assumed from
prior nights' reports) → INFERENCE (#297's fix still applies cleanly; #287's ADR slot is still
free) → DECISION (no new work; reconcile and record).

## Reward-Hack Check

N/A — no benchmark, threshold, or gold answer touched; no candidate code shipped tonight.

## Security Review

No new attack surface. Reconfirms, rather than newly discloses, the citation-rank-hijack gap
tracked in issue #236 / ADR-0087: `kb/verify-citation.mjs`'s own docstring still names it unresolved
line-for-line as it did on 2026-09-13. Nothing in tonight's read-only verification touched the
evaluator, the held-out set, or any gold answer.

## Recommendation (read this first — unchanged from the last several nights, now more urgent)

This engine never merges and this session has no authority to change that. Recorded, not acted on:

1. **25 open `dream/*` PRs (#269–#317), 100% draft, zero merged since #178 (2026-08-26) — 28 days.**
Ordinary `fix/`/`release/` PRs from the same window (#302, #306, #307, #309, #310, #315) merged
normally, so this is specific to the dream-cycle track, not general review capacity.
2. **Issue #236** (2026-09-03, citation-header rank hijack) needs a human Option A/B decision on
ADR-0087 — itself sitting unmerged in PR #287 for 10 days, so the decision document a reviewer
would need to read isn't even visible on `main`.
3. **PR #297** is a ready, TEETH-verified, zero-conflict fix for a real scoring-attribution bug
still live on `main` tonight (confirmed above) — the single lowest-effort, highest-confidence
merge available on this surface right now.

## ADR

None created — no architectural decision reached tonight.

## Gist

LOCAL — no `gh` CLI or gist-creation MCP tool available this session (same limitation every prior
Dream Cycle night on this repo has recorded).

## Issue

`NONE` — per this repo's ISSUE DISPOSITION OVERRIDE: nothing new, reproduced, and unresolved
surfaced tonight; every finding above already has an open issue (#236) or an open, verified,
non-duplicate fix PR (#287, #297). A run without a new issue is a valid completed run.

## Witness

```
SESSION_COMMIT = e89ea1ba167d9252ec99910304f534c8da5ca0ab
REPORT_HASH = f909c798b8f6099d4fd6a8bd7650fcf43b1cef6bd3337a736b216fa5521ae7fc
WITNESS = 7c152e1df8480839c4b5d2e7627a7912fe9cc8f1dd196747d761dd9cd41dd263
```

Verifier procedure: (1) check out commit `e89ea1b`; (2) `sha256sum` this report file at the state
before this section was filled in and confirm it matches `REPORT_HASH` (the hash covers the
pre-stamp bytes, per this pipeline's STEP 16 ordering); (3) `printf '%s%s' "$REPORT_HASH"
"$SESSION_COMMIT" | sha256sum` and confirm it matches `WITNESS`; (4) re-run
`grep -n "routedRepo\|top?.repo !== 'ruv-gists'" scripts/eval-brain.mjs` against that commit and
confirm line 95 still reads `top?.repo`; (5) re-run `npx vitest run tests/unit/eval-brain-gate.test.mjs
tests/unit/verify-citation.test.mjs` and confirm 45/45 pass.

## Merge Policy

**Human review required.** `autoMerge: false` per `dream.config.json` (ADR-068) — the decision, not
a default. This session never self-merges and never autonomously promotes candidate state. Draft,
by design.
1 change: 1 addition & 0 deletions docs/dream-cycle/LEDGER.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,4 @@ running behavior changed. See [deployment verification](OPERATING-POLICY.md).
| 2026-08-28 | grounding-quality | `kb/verify-citation.mjs`'s `parseCitations()` trusted any text shaped like the reader's own citation-block format (`#N repo=... / path : ... / title: ...`) wherever it appeared in `forge-ask-all.mjs`'s stdout — including inside a retrieved document's own raw, unescaped "full document" dump. A retrieved document that itself quotes or discusses this exact format (this very file's pre-fix header comment was one concrete instance) gets parsed as an EXTRA, fabricated citation; if that citation's path happens to resolve, `verifyGrounding()` reports `grounded: true` off a citation the retriever never returned. Fixed by bounding each citation's `path`/`title` extraction to its own span (stop at the next real header) and requiring strictly sequential ranks (`#1, #2, …`, the reader's own real invariant, since `forge-ask-all.mjs` always numbers hits `#${i+1}` with no gaps) | #185 | #186 | yes | ACCEPT | New TEETH tests fail on pre-candidate code exactly as predicted (fabricated-citation injection, cross-block path bleed, out-of-sequence rank, end-to-end false-`grounded:true`), 20/20 pass post-fix. `test:unit` byte-identical failure set baseline vs candidate (3 files/4 tests of 3596, all pre-existing `chmod`/EACCES-under-root fixtures, confirmed unrelated by re-running against baseline directly). `test:integration` 5/38 files fail, all pre-existing `sqlite3`/`@xenova/transformers` infra blockers, none referencing the changed file (grep-confirmed); both-hosts conformance gate green, 5/5. `eval:gate` itself EVALUATED=blocked: `no brain at /root/.cache/ruvnet-brain/kb` (this container never materializes a corpus — confirmed independently via `restore-local-ingests.mjs`/`brain-score.mjs`/`store-root.mjs`, all `stores 0 dark 0`); LLM_EVAL=blocked too (no model-provider key). Self-critique CLEAR: fix only ever makes grounding checks stricter, never more lenient; disclosed one residual risk (a maximally adversarial document predicting the exact next expected rank would still be accepted — needs a structural wire-format fix, out of scope tonight) | 552aad71b3858c769ebceed2e665ad2ef85f4fb6c1d5bc014e47692c508c981f | #142/#143 (08-19), #147/#148, #149/#150 (08-20): all MERGED. #154/#155 (08-21): PR closed unmerged, change landed on `main` via `420854b`. #175/#176, #177/#178 (08-26, both this repeated brain-currency surface): still open/draft as of tonight. Separately: of the 14 most-recent `dream/*` PRs checked tonight via GitHub MCP, **zero have merged since 2026-08-20/21** (#157, #159, #160, #162, #164, #167, #168, #169, #172, #174, #175, #176, #182, #184 all open) — the review backlog #175/#176 first flagged on 2026-08-26 is still growing; tonight's candidate was deliberately kept tiny (2 files, ~100 lines) in response |
| 2026-08-28 | grounding-quality | CONCURRENT NIGHT — a separate firing of this same routine (same SLOT=3/DEEP) landed first as #185/#186 (`kb/verify-citation.mjs`'s `parseCitations()` citation-block spoofing fix); this row is this session's independent, non-overlapping finding: `scripts/eval-brain.mjs`'s `gradeQuestion()`, the scoring function behind the frozen 120-question `npm run eval:gate` held-out set, computed the `routed` credit ("does a by-description query reach the store that actually holds the answer," `brain-score.mjs`'s own wording) from the raw top-ranked `citations[0]`, discarding `verifyGrounding()`'s own `receipt.repo` — the citation it actually verified as resolving on disk, which `citationResolves()` can accept at a lower rank than #1 when the top citation is unverified. This let a genuinely correctly-routed answer score as a routing failure (top fabricated, real hit lower-ranked) or a wrongly-credited pass (top coincidentally names the expected repo but never resolved, a different repo actually grounded it). Fix threads `receipt` through the one call site; `routedRepo = receipt?.repo ?? top?.repo ?? null` preserves identical behavior for the two other, receipt-less callers. Pushed to a suffixed branch, `dream/2026-08-28-grounding-quality-routed-receipt`, rebased onto #186's tip, to avoid colliding with the concurrent firing's branch and its identically-named report file | #187 | (opening now) | yes | ACCEPT | New TEETH test fails on pre-candidate code (`expected false to be true`), 16/16 pass post-fix — independently reproduced by the orchestrating session via `git stash`/`pop`, not merely the candidate's own claim. `test:unit` byte-identical failure set baseline vs candidate (4 files/4 tests of 3592→3593, all pre-existing chmod/EACCES-under-root fixtures: `advocacy-ignored`, `advocacy-outcomes`, `hook-shim-fallback-once`, `user-settings`); `test:integration` 5 failed files/9 failed tests/240 passed/11 skipped/53 todo of 313, matching the 2026-08-26 ledger row's own documented baseline exactly; `claims:verify` 3 PASS/4 SKIP, independently re-run by the orchestrating session. Blast radius independently re-grepped: `gradeQuestion` has exactly 3 call sites repo-wide; the 2 other callers never construct `receipt`, so both fall back to identical prior behavior. `eval:gate` EVALUATED=blocked (`no brain at /root/.cache/ruvnet-brain/kb`, same pre-existing condition). Self-critique CLEAR: fix corrects the metric in both directions (raises an undercounted true positive, lowers an overcounted false positive), so it cannot be a one-directional score inflator | f9910b34d073f887d0354af981ae04d697f5f4b9710e7440cd21b633424dd1c8 | #142/#143 (08-19), #147/#148, #149/#150 (08-20): all MERGED. #154/#155 (08-21): landed on `main` via `420854b`. #178 (08-26): MERGED (confirmed via GitHub MCP `list_pull_requests`, `merged_at` set, commit `7a19fd2` in `git log main`). #180 (`fix/integration-timeout`, non-dream but related): also MERGED (`git log main` commit `2af5bfd`). All other dream-cycle PRs opened 2026-08-22 through 2026-08-27 (#157, #159, #162, #164, #167, #168, #172, #174, #176, #182, #184 — 11 total) remain open/draft as of tonight — only 1 of 12 dream-cycle PRs in that window has merged; the backlog first flagged 2026-08-26 is now larger, not smaller |
| 2026-08-31 | brain-currency | CONCURRENT NIGHT — a separate firing of this same routine (same SLOT=1/DEEP) landed first as #212/#213 (`kb/forge-currency.mjs`'s `brainKnownSet()` sourcing the wrong root directory); this row is this session's independent, non-overlapping finding: `scripts/source-coverage.mjs`'s `artifactEvidence()` computed `cardPresent` via a direct name match against capability-card headings (`cardStores.has(store)`), missing stores reachable only through a `kb/repo-aliases.json` alias (the standing example: `metaharness`, card-listed only under `## agent-harness-generator`). The exact same conflation was already fixed twice in this codebase (ADR-058) — `kb/store-root.mjs`'s `darkStores()` and `scripts/brain-score.mjs`'s `readCoverage()` — but never migrated to this third, sibling computation, which feeds the committed `data/source-coverage.json`/`docs/RUVNET-COVERAGE.md` (ADR-069). Fixed by importing the router's own alias resolver (`repositoryNames` from `kb/card-lane.mjs`) instead of a raw Set lookup, mirroring the two prior fixes | #214 | #215 | yes | ACCEPT | New TEETH test fails on pre-candidate code (`expected false to be true`, reproduced via `git stash` with the function temporarily exported unchanged), 20/20 pass post-candidate, covering the alias case, the canonical-name case, and a false-positive guard (unrelated store, no alias/card, stays `false`). `test:unit` 3718/3909 pass, 4 failures = the exact chmod/EACCES-under-root container artifact already documented pre-existing in the 2026-08-26/2026-08-28 rows. `test:integration` baseline vs candidate byte-identical, 5 failed files/9 failed tests (pre-existing `sqlite3`/`@xenova/transformers` infra); one extra failure in a single candidate run reproduced under 3-way concurrent resource contention, confirmed passing 3/3 in isolation on baseline (load-flake, unrelated advocacy-dial subsystem). `qa:pr` convergence lane fixed via regenerated `data/convergence-manifest.json` (committed in this PR); docs lane's 52 violations reproduced identically on baseline (pre-existing). `eval:gate` EVALUATED=blocked (`no brain at /root/.cache/ruvnet-brain/kb`, container never materializes a corpus — not a credentials block, `OPENROUTER_API_KEY` present). `claims:verify` 3 PASS/4 SKIP as usual. Independent critic (separate agent, not the candidate's author) verdict CLEAR after checking benchmark/threshold non-involvement, cherry-picking, perf, blast radius (gist call site unaffected), security, and double-normalization correctness | b85b4caa263f6f2d568026acc09c6dcf6073b95e0824e16802705ac97001e90e | #142/#143, #147/#148, #149/#150 (all 2026-08-19/20): MERGED. #178 (2026-08-26): MERGED. #154/#155 (2026-08-21): closed unmerged, change landed on `main` directly via `420854b`. #157, #159, #162, #164, #167, #168, #172, #174, #176, #182, #184, #186, #192, #194 (2026-08-22 through 2026-08-30): all still open/draft as of tonight — zero merged since #178 (2026-08-26), a growing review backlog worth the owner's attention (also flagged in prior rows since 2026-08-26). #212/#213 (2026-08-31, concurrent): open draft as of this row, on branch `dream/2026-08-31-brain-currency`; this session's branch was renamed to `dream/2026-08-31-brain-currency-source-coverage-alias` to avoid the collision. GIST: LOCAL — no `gh` CLI or gist-creation tool available this session; not fabricated |
| 2026-09-23 | grounding-quality | RECONCILIATION, no new finding. Re-verified live on current `main` (`e89ea1b`) rather than assumed: (1) issue #236's citation-header rank-hijack is still live — `kb/verify-citation.mjs:38-39`'s own comment still names it unresolved; its decision doc, ADR-0087 (PR #287), is still unmerged so the ADR isn't even on `main` for a reviewer to read; (2) PR #297's fix (2026-09-18) for `gradeQuestion()`'s `provenance` case reading `top?.repo` instead of the already-computed `routedRepo` is still unmerged, still applies cleanly to current `main` (confirmed via `git merge-base --is-ancestor`), and the defect it fixes is still live at `scripts/eval-brain.mjs:95` today; (3) PR #270's `routed`/`expectPath` fix (2026-09-08) IS integrated — `routedRepo` is used at lines 85-87. Deliberately did not re-implement #297's already-verified fix a second time — that would be pure duplicate work, the pattern driving this exact backlog. Full detail: `docs/dream-cycle/2026-09-23-grounding-quality-report.md` | NONE | (opening now) | no | INCONCLUSIVE | No hypothesis reached the freeze-then-evaluate stage (STEP 5-9: not testable as a new candidate tonight — reason: no new defect, existing fixes already open and current). Targeted regression check only: `npx vitest run tests/unit/eval-brain-gate.test.mjs tests/unit/verify-citation.test.mjs` 45/45 pass on unmodified `main`. `npm run claims:verify` 3 PASS/4 SKIP (standard composition). `npm run eval:gate` EVALUATED=blocked (`no brain at /root/.cache/ruvnet-brain/kb`, container never materializes a corpus; not a credentials block, `OPENROUTER_API_KEY` present) | 7c152e1df8480839c4b5d2e7627a7912fe9cc8f1dd196747d761dd9cd41dd263 | #142/#143, #147/#148, #149/#150 (08-19/20), #178 (08-26): MERGED — confirmed via GitHub MCP. #154/#155: closed unmerged, landed on `main` via `420854b`. Every `dream/*` PR opened 2026-09-01 through tonight — 25 PRs, #269 through #317 — is open/draft: **zero merged since #178, now 28 days**. Ordinary `fix/`/`release/` PRs in the same window (#302, #306, #307, #309, #310, #315) merged normally — the gap is specific to the dream-cycle track. Issue #236 (2026-09-03, security-relevant rank-hijack) has waited 20 days for a human ADR-0087 Option A/B decision. PR #297 (5 days old) is a ready, zero-conflict, TEETH-verified fix for a real bug still live on `main` tonight — flagged as the lowest-effort merge available on this surface |
Loading