Skip to content

Coherence improvements: doc-freshness gate, debt visibility, + v0.4.0 ledger affordances - #2

Merged
daniloc merged 4 commits into
mainfrom
coherence-improvements
Jun 22, 2026
Merged

Coherence improvements: doc-freshness gate, debt visibility, + v0.4.0 ledger affordances#2
daniloc merged 4 commits into
mainfrom
coherence-improvements

Conversation

@daniloc

@daniloc daniloc commented Jun 22, 2026

Copy link
Copy Markdown
Owner

Hardens the coherence system and adds three ledger affordances for the editing agent (shipped as coherence-harness v0.4.0, consumed here).

P1–P5 (system hardening)

  • P1 — gate generated-doc freshness in CI (coherence:docs:check) and regenerate the stale AGENTS.md (the Hive ## why trim in 90aa607 had left it stale; CI never caught it).
  • P4/P5 — both ratchets now surface standing baseline debt (the convention/injection sites tolerated against a baseline) with a "toward zero" framing, instead of only blocking growth. Makes validateRegisterToken (Auth's un-anchored consume-time re-validation) visible every run.
  • P2/P3 — docs: the plan to upstream the atlas/convention/injection sidecars into the harness, and the ## why discipline (carry only non-derivable rationale; never restate derivable mechanism).

#1–3 (v0.4.0 ledger affordances)

  • coherence log [refA [refB]] [--strict] — the temporal ledger: structural diff of the invariant/boundary set between two refs (added / removed / rewired chokepoint or oracle), built via throwaway git worktrees.
  • verify --staged / --since <ref> — edit-loop scoping to the components the diff touched.
  • scaffold component / scaffold invariant — round out the write affordances so any of the three lands the complete anchored shape.

New CI gate

PR-only "No dropped boundaries" step: coherence log FETCH_HEAD HEAD --strict fails if a PR silently removes an invariant or boundary anchor — the loss a prose review misses. (Checks-job checkout is now fetch-depth: 0 so the worktree can materialize the base.)

All locally-runnable gates pass: coherence:verify, docs:check, atlas:check, conventions:check, injection-lint:check, typecheck. Clean fast-forward of main.

🤖 Generated with Claude Code

daniloc and others added 4 commits June 21, 2026 20:03
coherence:verify checks claims-vs-code, not docs-vs-specs, so a spec edit
not followed by `coherence docs` lands a stale AGENTS.md silently. That had
already happened: the Hive spec ## why was trimmed in 90aa607 but AGENTS.md
still carried the pre-trim text (CI green throughout).

- Regenerate AGENTS.md + docs/coherence/* from the current spec tree
- Add coherence:docs:check (= `coherence docs --check`, timestamp-normalized
  in-memory diff the harness already supports)
- Wire it into CI next to the atlas:check drift gate

Symmetric with how the trust atlas is already protected from drift.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Aw74Y9LaHUNmgcf9UkCMQd
The convention + injection ratchets only block GROWTH against a baseline, so a
tolerated entry can sit forever, invisible — each one is an un-enshrined
crossing the project means to drain to zero. Make the debt legible on every
run (incl. CI), with a "toward zero" framing:

- conventions:check now lists each baselined convention by name+fan-out, and
  flags any that have left the code (dead baseline weight to drop). This makes
  P5's finding standing: `validateRegisterToken` (Auth's consume-time
  re-validation) is a tracked, un-anchored convention — now printed every run
  rather than buried in conventions-baseline.json.
- injection-lint:check now prints the tolerated interpolation count with a
  per-file breakdown + stale-entry flag.

Ratchets that only block growth let debt ossify; surfacing the count creates
pressure to convert each site to a contract.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Aw74Y9LaHUNmgcf9UkCMQd
P2 — the trust atlas + convention/injection ratchets are coherence-shaped tools
living as repo-local scripts that re-parse the spec tree / graph.json by hand (a
hidden coupling to harness internals). Add a proposal to promote them to
first-class `coherence` subcommands (atlas/conventions/lint-sinks), so they share
the harness's graph build, claim parser, and baseline/--check machinery, and every
consumer inherits them. Includes the migration shape (non-breaking shims first).

P3 — codify the `## why` discipline in the doctrine doc: `## why` carries only the
non-derivable residue (the bug a boundary kills), never the derivable mechanism
(chokepoint/oracle) already carried by the claims and rendered into AGENTS.md/atlas.
Commit 90aa607 applied this by hand; the durable form is a harness lint, scoped in
the P2 doc as the natural companion check.

No new sidecars — both are authored artifacts, deliberately avoiding the sprawl P2
exists to reverse.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Aw74Y9LaHUNmgcf9UkCMQd
…affold)

Consume the three new harness affordances (shipped in coherence-harness v0.4.0):

- coherence:log — structural diff of the invariant/boundary set between refs.
- coherence:verify:staged — verify scoped to the components the working tree touched.
- (scaffold component/invariant available via `npx coherence scaffold`.)

CI gains a PR-only "No dropped boundaries" gate: `coherence log FETCH_HEAD HEAD
--strict` fails if the PR removes an invariant or a boundary anchor — the loss a
prose review misses. Needs full history, so the checks-job checkout is fetch-depth:0.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Aw74Y9LaHUNmgcf9UkCMQd
@daniloc
daniloc merged commit 30c0761 into main Jun 22, 2026
2 of 5 checks passed
daniloc added a commit that referenced this pull request Jun 22, 2026
…nv (#7)

The docs-freshness gate (added with the coherence-improvements work) has been red
since #2 for a reason unrelated to any feature: `coherence docs` stamps two
machine-specific fields into graph.json / _graph.html / _overview.html —
  - a wall-clock `generatedAt` timestamp, and
  - `absRoot`, the ABSOLUTE checkout path (/Users/daniloc/… locally vs
    /home/runner/… in CI)
so the committed artifacts only ever matched the one machine that generated them.
The tool's own `--check` normalizes the timestamp but not absRoot, so CI
(regenerating at a different path) always saw graph.json/_graph.html as stale.

Fix: a tiny post-generate normalize step (scripts/coherence-normalize.mjs) that
collapses the timestamp + absRoot to constants — both derivation-irrelevant (the
graph is derived from the spec tree + code + git history, identical across
checkouts). Wired into:
  - coherence:docs       → generate, then normalize (committed copy is portable)
  - coherence:docs:check → generate, normalize, then `git diff --name-only` the
    four artifacts (deterministic across environments)

Regenerated + normalized the committed docs. coherence:docs:check is green.
(The proper home for this is the coherence tool emitting relative paths — a
candidate for the upstreaming already tracked in coherence-tooling-upstream.md.)

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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.

1 participant