Ships plugin 2026.10.01.1246 so that running sessions get the end-of-turn shape check.
eb5cc6d — #4608 "Reuse signals have gone quiet or noisy on Librarian and Stash". Weak hook stamps no longer elect a directory's canon, and the divergence flags they raised are withdrawn. The arrival line names stamps_to_review. Svelte gets the same scoping Vue has.
f1fbdf7 — milestone 439 steps 1–3. The write hooks keep a per-session ledger of the shapes each turn writes. A new Stop hook blocks once, in words the server supplies, so the agent judges the shapes it left unjudged. classify_shapes(repo=…) can land a verdict on a shape that hasn't been synced yet.
4cf1c6f — step 4. The write-path hook suggests ("looks like #N") instead of stamping instance.
8b1567c — step 5. A rendering component file with nothing inside named after it becomes a file-kind shape. This works in any framework, with no framework-specific rule.
582a5a4 — step 6. The reusing-code and shape-accounting skills and _INSTRUCTIONS now describe judging at the end of the turn. The coverage line reports "written-shape check (7d)".
3270fe9 — refactor(settings): one bounded_float for every numeric bar read from settings. This is from an earlier session; it was already on dev.
Ships plugin 2026.10.01.1246 so that running sessions get the end-of-turn shape check.
- eb5cc6d — #4608 "Reuse signals have gone quiet or noisy on Librarian and Stash". Weak hook stamps no longer elect a directory's canon, and the divergence flags they raised are withdrawn. The arrival line names `stamps_to_review`. Svelte gets the same scoping Vue has.
- f1fbdf7 — milestone 439 steps 1–3. The write hooks keep a per-session ledger of the shapes each turn writes. A new Stop hook blocks once, in words the server supplies, so the agent judges the shapes it left unjudged. `classify_shapes(repo=…)` can land a verdict on a shape that hasn't been synced yet.
- 4cf1c6f — step 4. The write-path hook suggests ("looks like #N") instead of stamping `instance`.
- 8b1567c — step 5. A rendering component file with nothing inside named after it becomes a `file`-kind shape. This works in any framework, with no framework-specific rule.
- 582a5a4 — step 6. The reusing-code and shape-accounting skills and `_INSTRUCTIONS` now describe judging at the end of the turn. The coverage line reports "written-shape check (7d)".
- 3270fe9 — refactor(settings): one bounded_float for every numeric bar read from settings. This is from an earlier session; it was already on dev.
CI on dev @ 582a5a4: run 702 passed.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
The shape ledger's divergence readout flagged _gate_setting (#4385).
Reading it turned up a family with no canon: floor_for,
get_duplicate_threshold, get_plan_match_threshold and _gate_setting each
parsed a stored string, fell back to the default (never 0) and clamped
into [lo, 1].
- services/settings.bounded_float(raw, default, lo=0, hi=1) is the pure
parse, fallback and clamp. Each caller keeps its own get_setting read,
so tests patching get_setting per module still take effect, and
_gate_setting still fails open on an unreadable setting.
- SettingsView.saveKbInject: eleven inline Math.min/Math.max clamps and
the local gateAt become one asBar(v, d, lo = 0), mirroring the server.
No behaviour change.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Librarian and Stash had 132 and 488 write-path stamps written at 0.68-0.72,
before the 0.80 floor (#4204). Nothing re-judged them, and dominant_canon
counted them, so a YAML CI snippet (#3410) "dominated" Librarian's web
directory and every write there was told it diverged from it — 1408 flags
on one project, 902 on the other, all skimmed past.
- is_weak_stamp: one predicate for "hook-stamped below today's floor".
dominant_canon and canon_form skip such rows; stamps_to_review lists them
by the same predicate. No stored row changes — they stay for judgment.
- flag_divergence withdraws a standing flag whose canon no longer dominates
its directory. A flag is a mechanical prompt, not a judgment.
- The coverage line ends "N weak stamps · M incoherent canons to judge —
stamps_to_review" when either is nonzero, so a project's own session sees
the queue on arrival. The shape-accounting skill says what to do with it.
- scoped_definitions handles .svelte: every <style> is component-scoped
unless <style global> or :global(...); instance-script syms are scoped,
module-script ones stay ordinary.
Plugin version minted for the skill change.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Recording used to be decided by machinery — the only "record it" prompt
fired when a same-named copy already existed (#2664), so a first instance of
a reusable piece was never asked about, and judgment arrived only through
audits. Now the question is asked where the knowledge is: the end of the
turn that wrote the code, of the agent that wrote it.
- Write hooks keep `<sid>.written.ids` (path, kind, name) for every
definition a write names; a new file adds a `file` line for its stem — a
candidate in any language without a framework rule (scribe_written_append).
- Stop hook scribe_shape_check.sh sends the ledger to GET
/api/plugin/shape-check and blocks once, in the server's words, when
anything is unjudged. Same discipline as the report check: never twice,
never without a recorded check, another hook's loop left alone; the ledger
is kept when the instance cannot be reached.
- shape_ledger.unjudged_shapes: no row, unclassified, scoped and hook stamps
are unjudged; an agent/audit/import verdict is not. A snippet recorded at
the shape answers for it until the refresh stamps it canonical.
- services/shape_check owns the reason text and records every outcome in
app_logs (passed / blocked / judged_after_block / left_after_block).
- classify_shapes(repo=…) judges a shape the ledger has not synced yet via a
provisional row under a bound repo; the sync confirms it, or vanishes and
revives it with the verdict intact. An unbound repo is refused.
Plugin version minted.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The hook used to land its evidence as `instance` rows, classified_by=hook —
a permanent verdict nobody read, and the source of the weak stamps that
poisoned two ledgers (#4608). Now the agent that wrote the code judges it at
the end of the turn, and the hook's evidence is what it is shown.
- shape_ledger.suggest_write_path_instances (was stamp_write_path_instances):
same evidence and form gate, but it writes a PROPOSAL — proposed_snippet_id,
basis "reference" (named) or "semantic" (resembles), score — and never a
status. A judged row is left alone; a new shape gets an unclassified
provisional row so the suggestion reaches the end-of-turn question as
"looks like #N". By-name uses edges stay: a fact, not a verdict.
- The prior-art line says "looks like #N … when you judge this turn's
shapes, say whether it is", and the result key is `suggested`.
- write_time_divergence takes `suggested`; _RESEMBLE_MIN re-documented as the
suggestion bar and the weak-stamp line.
- reusing-code skill no longer says the pull stamps an instance.
- Tests moved to the new contract, plus a guard that nothing the hook does
writes classified_by="hook".
Plugin version minted.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A single-file component defines `.card`, `.title` and a `Props`, never
anything named after itself — so the ledger could not hold "StatusChip is
canon" and could not say a new card was built where one already existed.
- coverage.is_file_unit: a file that RENDERS (its markup names classes, or it
opens a <script>/<template>/<style> block) and defines nothing named after
its stem gets one `file` row. Structural, not a framework list: Svelte and
Vue components qualify, a TSX component already has its function's row, a
module is accounted for by its definitions. Emitting every file would have
put every module of every project in the todo at once.
- No body fingerprint on file rows, so an edit never re-asks a judgment.
- `file` is its own form and family; derive grouping skips it (`index`,
`+page` repeat by convention). Divergence buckets it on its own, so a new
component where a component canon dominates is a fair question.
- mark_canonicals: a snippet recorded at a path with no symbol makes that
file row canonical; it still covers no definition inside.
- The write hooks apply the same test before noting a new file for the
end-of-turn question.
Plugin version minted.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- reusing-code: "Before the turn ends — say what you built" — the four
verdicts, the one classify_shapes(repo=…) call, and the component file as a
shape. Description names the end-of-turn moment.
- shape-accounting: the writer judges; audits are the check that it held.
The write path SUGGESTS (no more hook instances); component file rows and
whole-file canon described; scoped covers Svelte too.
- _INSTRUCTIONS reuse line: "before the turn ends, say what you built
(create_snippet the reusable, classify_shapes the rest)" — 1570/1600.
- Coverage line: "written-shape check (7d): N turns checked, M asked, K left
unjudged", from the Stop hook's recorded outcomes; silent until the
question has been put.
- test_guidance_ownership pins the new topic on reusing-code.
- prior-art hook header no longer says it stamps instance rows.
Plugin version minted.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Ships plugin 2026.10.01.1246 so that running sessions get the end-of-turn shape check.
eb5cc6d— #4608 "Reuse signals have gone quiet or noisy on Librarian and Stash". Weak hook stamps no longer elect a directory's canon, and the divergence flags they raised are withdrawn. The arrival line namesstamps_to_review. Svelte gets the same scoping Vue has.f1fbdf7— milestone 439 steps 1–3. The write hooks keep a per-session ledger of the shapes each turn writes. A new Stop hook blocks once, in words the server supplies, so the agent judges the shapes it left unjudged.classify_shapes(repo=…)can land a verdict on a shape that hasn't been synced yet.4cf1c6f— step 4. The write-path hook suggests ("looks like #N") instead of stampinginstance.8b1567c— step 5. A rendering component file with nothing inside named after it becomes afile-kind shape. This works in any framework, with no framework-specific rule.582a5a4— step 6. The reusing-code and shape-accounting skills and_INSTRUCTIONSnow describe judging at the end of the turn. The coverage line reports "written-shape check (7d)".3270fe9— refactor(settings): one bounded_float for every numeric bar read from settings. This is from an earlier session; it was already on dev.CI on dev @
582a5a4: run 702 passed.🤖 Generated with Claude Code