Skip to content

compiler-parity: validateConfig() accepts blank slot deep/scan entries (issue #104) - #105

Draft
ruvnet wants to merge 3 commits into
mainfrom
dream/2026-09-10-compiler-parity
Draft

compiler-parity: validateConfig() accepts blank slot deep/scan entries (issue #104)#105
ruvnet wants to merge 3 commits into
mainfrom
dream/2026-09-10-compiler-parity

Conversation

@ruvnet

@ruvnet ruvnet commented Sep 10, 2026

Copy link
Copy Markdown
Owner

Nightly Dream Cycle, 2026-09-10. DEEP=compiler-parity, SCAN=config-schema,golden-snapshots. Full report: docs/dream-cycle/2026-09-10-compiler-parity-report.md. Issue: #104.

Correction (mid-session, see commit e389f02): this branch was originally opened against a stale local main ref (7933c35) that had diverged ~50 commits from the real origin/main (3edd426) — including PRs #24, #29, #79, #55, #11, #21, #33, #46, which this session's earlier evidence review had wrongly recorded as still open. Caught via mergeable_state: dirty immediately after opening this PR. The branch is now merged onto the real origin/main; every claim below is re-verified against the true history and the corrected docs/dream-cycle/2026-09-10-compiler-parity-report.md. The underlying finding was unaffected — it remained true and non-duplicate against the real merged history.

Hypothesis

Given a dream.config whose slots[i].scan array contains an empty-string or whitespace-only entry, or whose slots[i].deep is whitespace-only, extending validateConfig() to reject blank surface names in both fields should make validateConfig report ok: false for such configs, with compile() never reachable with a blank SCAN=/DEEP= line for any config that passes validation — subject to 0 regressions and no change to any currently-valid config's result. Frozen before implementation; not modified after.

Candidate

packages/compile/src/config.tsvalidateConfig()'s per-slot loop: !s.deep!s.deep || !s.deep.trim(); add a per-entry s.scan.forEach check rejecting blank/whitespace scan[j]. packages/compile/src/index.test.ts — 3 new tests. One conceptual change, 8 lines of logic + 19 lines of tests.

This exact defect class was already found and fixed three times in this repo's compiler-parity rotation, all three now confirmed merged into main: cron minute field (PR #24), adrConvention shape (issue #28/PR #29), bonusModuli values (issue #78/PR #79). Verified this candidate does not duplicate any of them by reading config.ts at the true main tip (3edd426) — it already has the adrConvention/bonusModuli checks, but still lacks the slots[].deep/scan[] blank-string check this PR adds.

Reproduced live against real main @ 3edd426 before writing the fix:

$ node -e "... cfg.slots[0].scan = ['', 'tests']; validateConfig(cfg) ..."
{"ok":true,"errors":[],"warnings":[]}
compiled SCAN line -> "   SCAN=,tests"

Evaluation Receipt

Real evaluator: npm test (vitest run && npm run test:governance).

Baseline (true main @ 3edd426, clean worktree rebuild) Candidate
vitest 616 619 (+3, 0 removed/modified)
governance 81 81
Total 697 700
Lint clean clean
Build clean (8 pkgs) clean (8 pkgs)

Live: post-fix validateConfig returns ok:false with a specific per-slot error for both the blank-scan and whitespace-deep case. Self-hosted dream.config.json compile output confirmed byte-identical against a clean baseline git worktree rebuild of 3edd426 (it was already well-formed — no behavior change for the real config).

Baseline

True parent commit 3edd426f6c9c4b1e80235f7447dc863e749345cc (main, verified via git fetch origin main + a clean git worktree rebuild, not a stale local ref). 697/697 tests green (616 vitest + 81 governance), clean build (8 packages), clean lint.

Darwin Lineage

Not run — DARWIN=not-applicable. Single deterministic blank-string-check parameterization on an existing validation loop, no evolvable population — same judgment as every prior single-function compiler-parity fix in this ledger (#11, #29, #79).

Evidence

OBSERVATION (grade A, live pre-fix reproduction against real main@3edd426) → OBSERVATION (grade A, read config.ts at true main tip — confirms adrConvention/bonusModuli checks already merged, slots[].deep/scan[] gap still open) → MEASUREMENT (grade A, 697→700 tests, 0 regressions, re-measured via clean worktree) → MEASUREMENT (grade A, self-hosted config byte-identical against true baseline) → INFERENCE (independent critic, fresh subagent, confirmed bug real by stashing the fix and re-testing — run before the stale-base correction, conclusions unaffected since the diff itself didn't change) → DECISION (scope to deep/scan only, not the critic-flagged residual gap in labels/ledgerPath/competitors/etc.) → REJECTION (did not resubmit adrConvention #29 or bonusModuli #79, confirmed already merged, not just "open" as first believed).

Reward-Hack Check

Independent critic (fresh subagent, no shared authoring context, given only git diff + full repo read access): CLEAR.

  • Confirmed the bug is real by stashing only config.ts and re-testing against the pre-fix version.
  • Confirmed both new tests are non-vacuous: they fail against the stashed pre-fix code, pass post-fix.
  • No reward-hacking signals: no .only/.skip, no snapshot/gold-data edits, no threshold changes, no undocumented cache.
  • Confirmed no regression: metaharness fixture and self-hosted dream.config.json both still validate cleanly post-fix.
  • Flagged (informational, not blocking): other interpolated DreamConfig string fields (labels, competitors, ledgerPath, branchPrefix, evaluatorEntrypoints.*, controlPlaneProbes, extraDisciplines) remain unvalidated for blank/whitespace entries — correctly out of scope for this narrow candidate; recorded as a legitimate next-night direction.

Security Review

Pure string-validation tightening inside an existing validator — no new I/O, no LLM/prompt-injection surface, no MCP/tool-authority change, no credential exposure, no filesystem/network-scope change. Strictly narrows what previously validated ok:true; cannot newly accept anything previously rejected.

Regression Analysis

0 pre-existing tests modified or removed. All 697 baseline tests pass unchanged; 3 new vitest tests added. npm run lint clean. npm run build clean (8 packages, no wasm/NAPI degradation to record tonight).

ADR

None — bug fix to existing config-validation behavior (a validator missing one of its intended checks), not a new architectural decision. Same precedent as PR #24/#29/#79.

Gist

No gh CLI or gist-creation MCP tool available this session (consistent with every prior night). GIST=LOCAL. Full report committed at docs/dream-cycle/2026-09-10-compiler-parity-report.md.

Issue

#104 (body being corrected to match — see issue comment)

Witness

report_sha256 : 1c9ec5548ffab1370fadcaf24961a5779b0eaf52690b9314a6483d5e572bec2b
session_commit: 3edd426f6c9c4b1e80235f7447dc863e749345cc
witness       : 2a3fe805af29fc4895d301ae8272ee94423a9af80e34fbc5a18e4fb50a0805e6

Verify: sha256sum the committed report's content up to (not including) its own ## Witness section, then printf '%s%s' "<that hash>" "3edd426f6c9c4b1e80235f7447dc863e749345cc" | sha256sum must equal the witness above (cross-checked live via node packages/cli/dist/bin.js witness stamp).

Merge Policy

Draft — human review required. This PR does not carry the automerge-safe label. The session never merges and never self-promotes.


🤖 Generated with Claude Code

https://claude.ai/code/session_01QXtKpy19GfqPGwpPG9iAk6


Generated by Claude Code

validateConfig() checked slot.deep truthiness and slot.scan array length,
but never checked that individual scan entries (or deep) are non-blank
after trimming. A config with scan: ['', 'tests'] or deep: '   ' passed
validation cleanly and compile() then silently emitted a corrupted line
(SCAN=,tests / DEEP=   ). Same defect class as the cron-minute-field
(#24), adrConvention-shape (#28/#29) and bonusModuli-value (#78/#79)
compiler-parity fixes, scoped to the one remaining gap in the same
validator.

npm test: 98->101 (+3), 0 regressions. Self-hosted dream.config.json
compile output byte-identical before/after.

Dream Cycle 2026-09-10. DEEP=compiler-parity. Issue #104.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QXtKpy19GfqPGwpPG9iAk6
References issue #104 and PR #105 (both now known after PR creation).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QXtKpy19GfqPGwpPG9iAk6
The branch was accidentally built on a stale local main ref (7933c35)
that had diverged ~50 commits from the real origin/main (3edd426),
including several compiler-parity fixes this session's earlier evidence
review had wrongly recorded as still open (#29, #79, among others).
Caught via mergeable_state=dirty on PR #105 right after opening it.

Merges the real origin/main in, resolves the LEDGER.md and
index.test.ts conflicts (both additive, no semantic conflict), and
corrects the ledger row + report to reflect the true baseline and
accurate test counts (616+81=697 -> 619+81=700, +3, 0 regressions,
re-measured against a clean git-worktree rebuild of the real
origin/main tip, not the stale ref). The underlying finding (blank
slots[].deep/scan[] entries pass validateConfig) remained valid and
non-duplicate against the real merged history.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QXtKpy19GfqPGwpPG9iAk6
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants