Skip to content

Latest commit

 

History

History
2319 lines (2009 loc) · 150 KB

File metadata and controls

2319 lines (2009 loc) · 150 KB

Changelog

All notable changes to Clauderizer are documented here.

[2.0.3] — 2026-07-31

The findings register driven to zero — four fixes, one pin lifted.

  • cz_onboard no longer hides the project's real docs (H-34, high). spec_candidates filtered by filename against the template set, so a mature repo's own ARCHITECTURE.md, REQUIREMENTS.md, VISION.md — the exact documents onboarding exists to surface — were silently dropped, and the failure read as "nothing to onboard from". Ownership is now judged from content (an untouched engine scaffold is excluded; authored prose is offered), and the conventional docs/ directory is scanned even when [paths] docs is customised. On the repo that exposed it: 1 candidate → 25.
  • mcp pin lifted to mcp>=1.2 (H-31, high). mcp 2.0 renamed FastMCP rather than removing it; _server_class() now resolves either SDK newest-first. The full suite passes on both majors — 1635 under mcp 1.27.2 and under mcp 2.0.0.
  • A wrapper invoking a nonexistent absolute path is drift (H-32, medium). doctor now exits 2 instead of nudging. Narrow by design: only an absolute path makes a checkable claim.
  • cz_add_lesson accepts scope="project" (H-35, medium) and defaults to it when no gameplan is active, closing the asymmetry with cz_add_decision.

Suite 1623 → 1635, green on both mcp majors.

[2.0.2] — 2026-07-31

Two defects found by upgrading a real repo on published 2.0.1 — the kind only a live walk surfaces.

  • A drifted procedure doc can now heal. refresh_procedure_doc triggered on the config stamp rather than on the doc's own version. A repo whose docs/gameplans/GAMEPLAN-PROCEDURE.md drifted while its stamp stayed current could never recover: the stamp matched the engine, so nothing refreshed, and doctor failed its MAJOR check forever on a file the engine owns. The trigger is now the doc's version — which _procedure_doc_version() had been computing all along with no caller consulting it. Bites any repo touched by the withdrawn 3.0.0, whose procedure doc was left at 2.0.0.
  • doctor no longer advertises an action upgrade does not perform. With the docs-layout separation dormant in 2.0.1, doctor still told you to run clauderize upgrade to separate your docs — and upgrade reported 0 mechanical update(s). A shipped instruction that no-ops is the dangling-claim class this project keeps building detectors for. The split-layout branch stays, since it reports real state and forked stubs.

Suite 1622 → 1623. Procedure stays 1.13.0; the separation remains dormant.

[2.0.1] — 2026-07-31

doctor certifies what it launched on the local leg too. 1.14.0 retired "MCP server launchable" — a shutil.which presence check standing in for identity — but the replacement handshake only ever ran for portable wiring. A repo wired to a machine-local absolute path (any venv, pipx or uv tool install) still certified presence and called it green: H-20's false green, surviving in the branch nobody looked at.

  • Identity now runs on local wiring whenever the host of record is native and the server can therefore be spawned, falling back to the launchability probe only when identity is genuinely unmeasurable — a cross-host target we cannot execute (D-010/L-59). A skewed local install now warns by name.
  • Found by a fresh-process test driving the real CLI (L-60: the test process' import graph is not the CLI's execution leg). That test also exposed why it hid for three releases: conftest sets CLAUDERIZER_NO_SPAWN_PROBE suite-wide, so no in-process test could have exercised the probe end-to-end, and a naive subprocess test inherits the guard and passes while measuring nothing. Armed red against the pre-fix branch.
  • Fixed: _procedure_drift rendered m.group(0) — the whole regex match — so a MAJOR mismatch printed host procedure vProcedure version**: 2.0.0.
  • D-083 — no version floor in the emitted .mcp.json (resolves an open item from 2026-07-24). A floor couples a committed, twelve-host config to release cadence, and bounds only downward, so an older repo meeting a newer engine sails through. The handshake catches skew both directions.

One visible change for NEW repos

clauderize init no longer scaffolds generic doc names — ARCHITECTURE, VISION, TESTING, SECURITY, SCHEMA, DEPLOYMENT, REQUIREMENTS, INCIDENTS, DATASOURCES, ENGINEERING-PRINCIPLES — into your docs/. Those are the project's, and every measured naming collision lived there. They remain available via clauderize init --seed-project-docs. Existing repos are unaffected: a repo's recorded module list is preserved, so nothing appears or disappears on upgrade.

Also present but dormant

The engine/project doc separation (docs/clauderizer/) is implemented and tested but inert: docs_layout defaults to legacy, the identity default resolves every path exactly where it always did, and nothing migrates. It ships as capability, not as behaviour, and will be activated in a release of its own.

Suite 1599 → 1622. Procedure stays 1.13.0 — nothing procedural changed.

[3.1.0] — 2026-07-30 — YANKED

Withdrawn from PyPI. Released and yanked the same day: the version number was wrong. The engine/project doc separation is a breaking layout change that was never signed off as a major, and cutting 3.x stranded six live repos on a layout no installable engine could read. The content survives on main — dormant — and the doctor fix ships properly in 2.0.1 above. Recorded rather than deleted: these existed on the index and someone may have resolved them.

doctor certifies what it launched on the LOCAL leg too. 1.14.0 retired "MCP server launchable" — a shutil.which presence check standing in for identity — but the replacement handshake only ever ran for portable wiring. A repo wired to a machine-local absolute path (any venv, pipx or uv tool install, which is the common case the moment a standalone exists on the box) still certified presence and called it green. That is H-20's false green, surviving in the branch nobody looked at.

  • Identity now runs on local wiring whenever the host of record is native and the server can therefore be spawned, falling back to the launchability probe only when identity is genuinely unmeasurable — a cross-host target we cannot execute (D-010/L-59). A skewed local install now warns by name instead of passing.
  • Found by a fresh-process test, not by reading. clauderize doctor is now driven through a real subprocess (L-60: the test process' import graph is not the CLI's execution leg). That test also exposed why this went unnoticed for three releases: conftest sets CLAUDERIZER_NO_SPAWN_PROBE suite-wide, so no in-process test could ever have exercised the probe end-to-end. The new tests lift only that guard, and were armed red against the pre-fix branch.
  • D-083 — no version floor in the emitted .mcp.json (resolves the workflow-critique O-02 that had been open since 2026-07-24). A floor couples a committed, twelve-host config to release cadence, so a teammate whose index cannot satisfy it gets a resolution failure where they had a warning — the wrong direction. It also bounds only downward, so the real 3.0.0 hazard, an older repo meeting a newer engine, sails straight through it. The handshake catches skew in both directions, which is why D-060's warning stays the mechanism. (The shipped pre-release ==-pin is not a floor: it exists because an unpinned resolve only ever sees stable and would hand the repo to a different engine entirely.)

Suite 1618 → 1622. No procedure change; PROCEDURE_VERSION stays 2.0.0.

[3.0.0] — 2026-07-30 — YANKED

Clauderizer's docs stop living in yours. Engine memory moves to docs/clauderizer/, and the engine stops scaffolding generic names into your namespace entirely. This is a breaking layout change with an automatic migration — read the upgrade note below before running it.

This realizes D-039, recorded 2026-06-23: "two documentation layers — agent working-memory vs human product docs; never conflate them." That decision's own Consequences predicted "a future initiative will audit where the two were conflated and rectify." The code never did it, so the engine kept scaffolding ARCHITECTURE.md, SECURITY.md and GLOSSARY.md straight into the project's docs/, with nothing marking which files were whose. Measured across five real repos: a film-production project had FILM-PROCEDURE.md and VOICE-CASTING-PROCEDURE.md sitting beside engine DECISIONS/INVARIANTS/ LESSONS; another owned its own SECURITY.md while the saas manifest claimed that exact name.

Ownership is structural now (D-080)

  • Every doc has an owner the engine reasons about — engine, project, or product — and ownership determines location. docs/clauderizer/ holds the working-memory corpus (DECISIONS, INVARIANTS, LESSONS, HARDENING, SKILLS, ENFORCEMENT, the Clauderizer glossary) plus the tracked entity directories. An unrecognized name is project-owned, and that default is the point: a doc the engine has never heard of is yours.
  • The engine stops claiming generic names. ARCHITECTURE, VISION, TESTING, SECURITY, DEPLOYMENT, SCHEMA, REQUIREMENTS, INCIDENTS, DATASOURCES, ENGINEERING-PRINCIPLES are yours — still offered via clauderize init --seed-project-docs, never taken by default. A fresh standard init went from 8 docs (3 of them yours) to 5, touching nothing in your namespace.
  • Two glossaries is the intended shape, not a workaround: Clauderizer's vocabulary in docs/clauderizer/GLOSSARY.md, your domain's in docs/GLOSSARY.md. They are never merged.
  • docs/gameplans/ stays put — on a measured reason, not taste. It holds GAMEPLAN-PROCEDURE.md, the file _procedure_drift reads; relocating it would destroy the one loud signal an older engine trips on a migrated repo.
  • Ownership landed via an identity default (L-41): engine_docs_root defaulted to the project docs directory, so the whole generalization shipped with a byte-identical digest and zero files moved before the migration deliberately flipped it.

The untangle

clauderize upgrade performs the migration. No file is ever split, merged, or rewritten — only moved or created. A doc holding your content at a name the engine also uses is left byte-identical where it is and a fresh engine copy is written alongside. git mv stages renames so history survives. Entry counts are conserved tree-wide (INVARIANT-03). Idempotent; upgrade --report lists every verdict first.

Upgrading from 2.x — the one rule that matters

Upgrade every install that WRITES to a repo before you migrate it — teammates, CI, and any agent session or MCP server started earlier. Restart them.

An install older than 3.0 still resolves the pre-migration paths, so a tracked write from it lands in the stub and the corpus forks. This was measured, not theorized (H-33): during this release's own development, a cz_add_decision through a still-running 2.0.0 MCP server appended D-001 to a stub while the real register ended at D-081 — a duplicate id in an append-only corpus, with nothing raised.

3.0.0 contains that rather than preventing it, because nothing shipped here can change an already-published engine's behaviour:

  • Each stub carries a high-water sentinel id, so an old engine allocating from it gets D-900001 — an id that cannot collide with a real one and is obvious on sight.
  • clauderize doctor reports a forked stub as drift (exit 2), naming the orphan ids and the register they belong in. The merge is left to judgment, never automated (INVARIANT-05).
  • PROCEDURE_VERSION bumps to 2.0.0, so an older engine's MAJOR-mismatch check fires loudly instead of silently reporting an empty corpus — the failure mode measured in this release's own P0 probe, where a migrated repo showed status silent, both doctor checks green, and 0 decisions visible.

Also

  • docs/UPGRADING.md gains a 2.x → 3.0 section leading with the ordering rule.
  • Fixed: _procedure_drift rendered m.group(0) — the whole regex match — so a MAJOR mismatch printed host procedure vProcedure version**: 2.0.0. The loudest signal the tool has, garbled, in shipped 2.0.0.
  • Fixed: a local from . import assets inside one modernize.apply() branch made the name function-local for the entire function, breaking the procedure-doc refresh with an UnboundLocalError.

Verification

Suite 1599 → 1617 (7 skips). Dogfooded on this repo and five real consumer projects (viderizer, phasekeep, clauderizer-site, marketing-studio, arena-security-audit): every digest still renders with real gameplan state, zero drift, entries conserved in all six, git recorded renames, and every project's own docs left untouched — viderizer ends with a film glossary and a Clauderizer glossary, which is the whole point.

The prose seam is pinned by a ratchet rather than sweep discipline (L-65): a test fails if shipped prose points an engine-owned doc at the project's namespace, and a companion test fails if the sweep over-reached the other way. Two exclusions are deliberate — GLOSSARY exists in both namespaces by design, and the procedure's changelog narrates past states where history records the paths of its own time.

Known and deliberate: H-31 (mcp pinned <2; adapting to the 2.x SDK is unowned follow-up) and H-32 (a dead absolute hook path reports advisory rather than drift) remain open.

[2.0.0] — 2026-07-30

2.0 finals, and the last thing it shipped was the upgrade path itself. The mechanism set is exactly what 2.0.0b1 froze — the two alphas and the beta are the evidence, and nothing in that set changed here. What changed is the thing none of them had been tested on: a real 1.13.0 → 2.0 upgrade, walked with the actual published 1.13.0 wheel instead of a fresh init.

  • An upgrade delivers new doc modules, not just new stamps. 2.0 added docs/GLOSSARY.md and docs/ENFORCEMENT.md to every size manifest, and 77b5135 fixed the dangling-pointer class for fresh inits only. On an existing repo the two docs never arrived: config.merge_missing keeps the repo's non-empty modules list, init scaffolds from config.modules alone, and the mechanical tier had no add-a-module action — so the refreshed stanza (CLAUDE.md/AGENTS.md) pointed at docs/ENFORCEMENT.md and the new clauderizer-fleet skill pointed at docs/GLOSSARY.md with neither file on disk, while doctor printed ✓ corpus modernized to procedure v1.12.0 over it. Measured, not theorized: the live walk is what found it. The mechanical tier now carries ensure_modules_current — additive, writing each doc only when absent (INVARIANT-03), idempotent (a second pass reports 0 mechanical), and recorded in the config so the delivery happens once. The stated trade-off: the manifest is the size's contract, so a module a user deliberately deleted comes back — as one visible line that upgrade --report shows before anything is written. This is ensure_gitignore_current's own D-042 tier-1 reasoning, one level up — "without this the whole policy fix reaches zero existing installs, and every install in the world already ran init" — applied to the case that comment did not cover.
  • The class got the detector it never had (D-069). doctor gained engine-referenced docs present: every docs/<NAME>.md the engine's own wiring names (the shipped stanza, the shipped skills — never the user's prose) is checked against what the repo's manifest promises to scaffold. Docs created on demand by a blessed write (docs/LESSONS.md, docs/SKILLS.md) are declared ON_DEMAND_DOCS and never flagged, so a repo with no lessons yet is correct rather than broken.
  • Plus the CI-time ratchet that would have caught 2.0's own defect before release: engine wiring may only reference a doc some size manifest scaffolds or that is declared on-demand. Armed against the real historical tree — grafted onto 77b5135^ it fails naming docs/ENFORCEMENT.md (from the shipped stanza), the exact pre-fix state.
  • docs/UPGRADING.md gets a 1.x → 2.0 section, and its mechanical-tier list is now complete (it had been silently missing the gitignore and kinds-overlay actions too). Procedure 1.13.0.
  • The 1.14.5 CHANGELOG entry is restored to main. 1.14.5 was cut from a hotfix branch that was never merged back, so this file jumped 1.14.4 → 2.0.0a1 while 1.14.5 was what pip install clauderizer actually resolved. The version-single-sourcing audit could not see it: that check compares the top entry against __version__, and a hole further down is invisible to it.

Upgrading from 1.x

init + upgrade + doctor — and do not skip upgrade, which is what delivers the two new docs. Otherwise 2.0 is additive: no cz_* tool was removed or renamed (67 → 68), no config key changed, requires-python stays >=3.11, the core engine keeps zero runtime dependencies, and the mechanisms priced too expensive to default on (per-call cz_state stamps, wind-down budgets) stay dormant by measured verdict. The one semantic break for downstream consumers is unchanged from 2.0.0a1: pass_rate reads as goal-met rate, with deferrals visible beside it rather than laundered into it.

Verification

  • Suite 1571 → 1582 passing (7 skips). The delivery tests were armed behaviorally red on the pre-fix tree — 3 red via modernize.report/apply alone, APIs present on both trees (pinning the import path, since an editable install otherwise serves the fixed source into a pre-fix worktree: H-27's own class, met while arming a guard against it). The CI ratchet was armed against the real historical tree at 77b5135^. Two guards are green on both trees by design: manifest/template consistency, and silence on a already-current corpus (INVARIANT-08 drop-nothing).
  • Dogfooded on this repo, whose own config was missing both modules while the docs existed: upgrade added the modules and left docs/GLOSSARY.md and docs/ENFORCEMENT.md byte-unmodified — the never-clobber property shown rather than asserted.
  • Three of this repo's own ratchets fired on this change and were paid, not widened: the subsystem-doc seam (both new public callables documented), the separator class (both literals triaged message with the reason), and the procedure-changelog pin — which turned out to freeze PROCEDURE_VERSION at exactly 1.12.0, failing any later procedure bump for a mechanism it does not touch; it now asserts >= 1.12.

Shipped with a named gap

  • H-31 remains open, deliberately. mcp stays constrained >=1.2,<2; the hotfix half shipped as 1.14.5, but adapting to the mcp 2.x SDK — then lifting the pin with tests against both majors — is unowned follow-up work. 2.0.0 ships the pin as the honest contract, not the adaptation.

[2.0.0b1] — 2026-07-30

The promotion IS the release: zero code changes over 2.0.0a2. Two alphas survived first-party dogfood and a real foreign-repo deployment inside 48 hours — fourteen mechanisms graduated-or-dormant by measured verdicts (D-077/D-078/D-079), both field-reported defects fixed and republished within a day (O-05/O-06), the a1 wiring caveat closed, and the worldwide mcp-2.0 break hotfixed on the stable line along the way. Beta means: the 2.0 mechanism set and its defaults are frozen for the 2.0.0 line — what remains before final is telemetry accrual on the armed signals (gap-conversion, reinforce re-derivation, recording coverage → the budgets re-vote) and bug fixes only. Still a PEP 440 pre-release: pip/uvx resolve it only with --pre (or ==2.0.0b1); stable installs keep getting 1.14.5.

[2.0.0a2] — 2026-07-29

The field-report alpha: everything here was earned by the first real 2.0.0a1 deployments — the documented wiring caveat closed at init time, plus the two defects the first foreign-repo transition surfaced (O-05/O-06). Pre-release semantics unchanged: pip/uvx resolve only with --pre.

  • Proposals explain themselves before offering "dismiss" (O-05): every generated modernize proposal now carries a what line saying what the flagged thing IS (a QA gate, a deliverable, a standing condition, …), and the modernize report and cz_dream's blocked-on-triage state carry the triage semantics verbatim (dismiss = personal gitignored seen-it that returns on material change; defer = snooze; nothing edits the repo or disables a check). Born from a field session where the human rightly refused to dismiss an unexplained gate proposal.
  • A zero baseline is anomaly-shaped, not a fact (O-06): when the measured test count is 0, the digest's baseline line and preflight's tests gate (now warn, never fail) say so with one voice — a runner that exits 0 while collecting nothing is usually a broken runner. Born from a field session where "Baseline: 0 tests" had normalized a Node-24-broken suite (CLI included) into invisibility for weeks.
  • Init warns when the target is $HOME: HOME/.claude/settings.json is the per-user global settings file, so a hook wired there runs in every session on the machine and every repo under HOME becomes a nested install. Warn loudly, proceed anyway (a deliberate home-as-repo setup stays legal).
  • Pre-release engines pin their portable wiring (portable_from_spec): every portable/committable command (.mcp.json, host emitters, the Grok hook string, the kimi-desktop entry, the uvx fallback) now emits clauderizer[mcp]==<version> when the running engine is a PEP 440 pre-release — an unpinned resolve only sees stable, so alpha-inited repos were silently served by the older stable engine (the documented 2.0.0a1 caveat, now closed at init time). Stable engines keep the bare spec. __version__ stays 2.0.0a1 until a2 actually publishes, so pins always reference a version that exists.
  • The audit's CHANGELOG version parser speaks PEP 440 (2.0.0a1 no longer reads as 2.0.0 — the false version-drift finding at the alpha's own close).
  • clauderizer-fleet guidance: partition step now prefers real portfolio work over seeded toys (with the D-079 rationale), and the worker briefing's first act is verifying the branch point against the briefed baseline.

[2.0.0a1] — 2026-07-28

The measured alpha: fourteen externally-vetted mechanisms, built advisory-first under binding conditions, then graduated — or deliberately kept dormant — by an evidence matrix instead of by taste. This is a PEP 440 pre-release: pip and uvx resolve it only with an explicit --pre (or an exact ==2.0.0a1 pin); existing installs keep resolving 1.14.4 until 2.0.0 finals. Every verdict below is recorded with its figures in D-077 (Fractal ten), D-078 (jcode four) and D-079 (fleet-vs-solo); the committed matrix instruments live in the gameplan directory (matrix-p5-harness.py, matrix-p5-results.json). Mechanism ideas were vetted from Fractal and jcode on code evidence only — no outcome numbers from either project appear here or in any release material, by rule (D-070/D-075).

Graduated as shipped defaults (matrix figures behind each)

  • Honest terminal vocabulary (P0): phases close deferred with a reason — a first-class, non-laundered ending; completing with unchecked exit criteria draws an advisory (never a block, no flags — INVARIANT-05). ABANDONED/EXITED arrive as aliases; there is no fourth status token.
  • Unknowable-never-zero epistemics (P0): an unmeasurable probe reports UNKNOWN and demotes the verdict to pass-with-warnings — it never counts as a pass and never fabricates a zero.
  • Stranded-state heal-on-proof (P1): a provably-dead session claimant (POSIX liveness probe, mcp-transport stamps only, display-only read path) surfaces a judgment menu — adopt / continue / close honestly. Matrix: 0 false positives across A-alive, own-pid, cross-host and cli-transport controls; detection on the dead claimant.
  • Interrupted-session backstop (P1): fires only when a phase is in_progress AND non-docs commits landed since the tracker anchor AND every closing write is absent AND the session ledger cannot vouch for the claimant — errs silent. Matrix: fire/quiet geometry 4/4 (fires on seeded abandonment; quiet on healthy close, live claimant, no-work).
  • Refusal journal (P1 writer, P3 reader): failed ops append to a gitignored local journal; cz_mine_failures consumes it as a second source and cz_corpus_health counts it — the journal is read, not just written (D-069).
  • Seen-vs-open receipts (P3): reading cz_get / resolving findings, open items and criteria appends engagement receipts; the digest splits open ids into never-engaged vs engaged-but-open. Receipts sidecar classification: .clauderizer/seen.local.jsonl is a machine-local, rebuildable, gitignored sidecar — the sole sanctioned append on a read op (D-073); display, never authority; with no sidecar the digest is byte-identical to the pre-receipts shape (drop-nothing, D-068). Matrix: split correct at the production seam, pre-sidecar byte-silence pinned.
  • Two-speed consolidation with merge-base (P3): curator/miner proposals join one id+ledger queue; dismissed candidates are suppressed with suppressed_count reported and an all_proposals unfiltered read; a recurrence re-arms a dismissal. Production-exercised by a live curator iteration during the alpha itself.
  • Merge-integrity audit (P4): the single most recent docs-touching merge is audited from git evidence alone (merge parents + merge-base + blob compare, O(1) subprocess cost) for lost-update and committed-conflict-marker damage. The advisory-silent restriction lifts with this release: seeded-fault protocol measured 3/3 detection, 0/4 clean-merge false positives, healthy digest byte-identical, plus a production true-negative. The squash blind spot stands: squash merges are invisible to this audit, stated in the module and the finding wording — no issue-catching claim beyond true merges.
  • Enforcement ladder (P4): docs/ENFORCEMENT.md maps every discipline to hard-NORMALIZE / advisory / instructions-floor with capabilities derived from session host facts, never config flags; a 15-op CLI-vs-MCP transport-parity matrix pins zero undocumented divergences.
  • Memory-gap detection (P8, from jcode): when cz_analyze finds zero relevant decisions AND invariants for a contentful probe, the tool result says so with a record-it-now nudge; a text-free gap event ({kind, surface, gameplan, phase, date, query_terms-count} — never probe text) lands in telemetry and cz_corpus_health counts it. Never a digest line (INVARIANT-08). Gap-conversion rate ships armed; its production value is an honest null until post-publish telemetry accrues.
  • Reinforce-instead-of-duplicate (P8, from jcode): the write-time near-duplicate advisory offers a third verb beside consolidate/append — cz_reinforce_lesson (new tool; the MCP surface is now 68 tools) strengthens the EXISTING lesson with a compact tracked trailer (*(reinforced xN, last <date>)*) through the single grammar-safe renderer, plus a telemetry event. Strength is curator EVIDENCE (with the inverse reading: a lesson repeatedly re-derived may be worded so it does not land), never ranking authority (D-013/D-063). Deterministic Jaccard on the canonical tokenizer (INVARIANT-09); nothing auto-reinforces. First production use happened during the alpha's own matrix phase.
  • Negative-space close-outs (P7/P8, from jcode): completion reports and phase summaries declare "What I did not check"; the fleet briefing contract requires it of workers (hub judgment sends back reports lacking it — never an engine gate); the engine-side detector is explicitly deferred-unenforced (L-68 clause 5).
  • Fleet pattern, productized (P7): clauderizer-fleet ships as a wheel skill (dual-copy seam test), docs/GLOSSARY.md is the canonical vocabulary, and the hub-and-spoke law is on the enforcement ladder. The "more agents = better" thesis is now measured and BOUNDED (D-079): on the same seeded task, fleet and solo tied on quality (zero defects in both under independent adversarial verification) while the fleet ran 1.57× faster wall-clock at ~1.7× total compute, 0 LockHeld / 0 collisions — N buys wall-clock on genuinely independent phases; quality comes from the discipline, and the skill's guidance now says exactly that.

Kept documented-dormant, with the figures that keep them so

  • Per-call live-state stamp (P2, INVARIANT-10): figures-only, change-triggered cz_state notices on tool results. Geometry verified exact (session-first emission + write-result emission, identical reads silent, status-shaped ops excluded, zero when unarmed) — but the slow-FS row prices default-on out: +0.1 ms/op on ext4 vs +58 ms/op (+86%) on WSL DrvFs. Stays env-armed (CLAUDERIZER_STATE_STAMP=1, per-process, sanctioned for fleet/experiment legs) until a cheaper read path earns a re-vote.
  • Reserve-window wind-down budgets (P2): > Budget: N sessions declarations (gameplan + phase tiers, distinct-DATE stints, WIND_DOWN derived at read time, reserve fraction a constant, no flags). Capability proven live (ops-mode and a real kimi CLI session both recorded stints; the wind-down advisory renders with phase-aware wording) — but recording coverage measured FIRST was 0.0 over the alpha's own development sessions (the serving-engine gap, H-30), so production wind-down math would be fiction today. Dormant with a post-publish re-measure gate.

Named gaps (recorded, not claimed)

  • jcode-host verification: unverifiable in the build environment (no binary, no toolchain, no session credential) — the row ships open with a verification-session recipe instead of a wiring claim.
  • Live under-adhering-host and live-Cursor matrix arms: named gaps with reasons; the seeded-fixture legs cover the shapes they would produce.

Semantics

  • pass_rate now reads as goal-met rate: with deferred a first-class logged outcome, a deferred phase is an honest non-goal-met ending, not a laundered complete — dashboards consuming outcome telemetry should read pass_rate as "phases that met their goal", with deferrals visible beside it.

Fresh-repo parity

  • Every init size now scaffolds docs/GLOSSARY.md (core memory + fleet vocabulary, seeded generic with a Domain section to fill) and docs/ENFORCEMENT.md (the four-tier ladder for the engine's shipped disciplines) — the shipped stanza and the fleet skill reference both by path, and until now a fresh repo received the pointers without the files (found by smoke-testing a fresh init during this release's own gate; the L-65 dangling-claim class).

Upstream break contained: mcp 2.0

  • mcp is now constrained >=1.2,<2. mcp 2.0.0 (released 2026-07-28) removes mcp.server.fastmcp, which broke every fresh clauderizer[mcp] resolution on the planet the same day — caught by doctor's capability-based MCP identity probe and by CI's job-granularity gate on this release's own commits. Adapting to the mcp 2.x SDK is tracked as follow-up work; the pin is the honest immediate contract.
  • First-ever full-matrix CI on the alpha's code also surfaced four platform-latent test assumptions (real-pid liveness probes are POSIX semantics; PID-reuse detection reads Linux /proc) — now capability-gated skips with the win32/no-proc arms pinned by their existing monkeypatched tests — and a Windows-blind spot in the transport-parity harness itself (root anchoring never matched JSON-escaped backslash paths); the normalizer now replaces escaped root forms and the assertion names diverging keys.

Hardening shipped with the alpha

  • Version stamps never ratchet backward (H-30, observed live during the alpha's own build): a serving engine older than the repo's procedure stamp no longer restamps it downward — clauderize upgrade / cz_modernize surface the skew as an advisory proposal instead, and the apply path refuses the downward write outright. An unparseable stamp still reads as legacy and stamps forward. The deeper half — op results certifying which engine build served them — is routed to the engine-identity work, not silently dropped.
  • Write-guard removals echo to the writer (H-29): when the sanitizer strips leaked tool-call framing or unbalanced closing tags from prose, the write result now carries a sanitizer_advisory naming the removed fragments with the code-span rewrite nudge — at the REGISTRY seam, so every transport sees it at the moment a rewrite is cheap. Code-spanned literals still survive untouched; the advisory never blocks the (sanitized) write.

Verification

  • Suite grew 1330 → 1561 passing (7 skips) across the alpha; every new guard was armed once (violation injected, red observed, reverted). Transport-parity, enforcement-ladder, dual-copy skill seam, procedure-version parity and README tool-list pins are all live.

[1.14.5] — 2026-07-28

Restored to this file 2026-07-30: 1.14.5 was cut from a hotfix branch that was never merged back to main, so the entry existed only on the v1.14.5 tag while main's CHANGELOG jumped 1.14.4 → 2.0.0a1 — with 1.14.5 being what pip install clauderizer actually resolved. The code fix (the mcp<2 constraint) reached main independently in 8fc9c22.

Hotfix: the mcp dependency is now constrained >=1.2,<2. mcp 2.0.0 (released 2026-07-28) removes mcp.server.fastmcp, which broke every fresh clauderizer[mcp] install the same day — the MCP server died at import and doctor's identity handshake reported no serverInfo (H-31). This release also ships the 1.14.4 feature set below: 1.14.4 was staged in-tree but never tagged or published, so its first appearance on any registry is inside this version. Adapting to the mcp 2.x SDK is deliberate follow-up work; the pin is the honest immediate contract.

[1.14.4] — 2026-07-26

release-check asks whether the code passes, not just whether the version is free. The four registries answer "is this version claimed anywhere". None of them answers "does this code work on the platforms it says it supports" — and that is the question that has actually bitten: 0.14.0 and 1.14.2 both shipped with Windows cells red. L-51 sweep (2) named the rule for three releases and it stayed discipline. 1.14.3 verified CI by hand only because a phase exit criterion said to; nothing in the ritual would have stopped a tag otherwise (H-28).

  • CI green on this commit (every job) joins the ritual, gated at JOB granularity on purpose. GitHub reports a workflow as success when a matrix cell is skipped, so the workflow conclusion is exactly the false green this module exists to refuse. Every job of every run for the exact HEAD sha is enumerated and the run's own conclusion is never read — pinned by a test that feeds it a failure run whose every job succeeded and asserts the verdict still comes from the job set alone.
  • Green means success; everything else is not-green. A skipped, cancelled, timed_out, failure, stale, startup_failure, neutral or action_required job fails and is named; a still-running workflow fails (tagging mid-run is the race); no run at all for the commit fails, because the absence of a run is a definite fact about the code you are about to tag, not an unknown. gh missing or the API unreachable is unverifiable, and a repo with no workflows is skip — absence of CI is not a failure.
  • The false-positive surface is stated, not implied. A repo with a job-level if: will see that job reported as a skipped cell and go red. That is the deliberate trade: unverifiable renders as "OK with unverifiable check(s)", which is too soft for a missing Windows cell. Every offending job is named so the choice is actionable.

Suite 1311 → 1327. Demonstrated behaviorally red first: the same repo and the same CI reality (workflow success, Windows cell skipped) exits 0 on the pre-fix tree and 2 on this one, probed through release_check.run() alone — an API present on both trees.

[1.14.3] — 2026-07-25

The frozen debt gets paid, and the lesson gets an enforcer. 1.14.2 froze two debts visibly rather than laundering them into a passing check — 32 modules with no subsystem doc, and a separator-shaped assertion class L-51 had described for three releases. Freezing was the right call then; it is not a resting place. Both are paid here, and the ratchets close behind them.

  • The separator class is machine-rejectable, at the point of the mistake. 1.14.2 shipped three Windows cells red on assert "uv/archive-v0" in m["serving_path"] — with L-51 already recorded, and already surfaced to the session that wrote the line. Surfacing was not enough. tests/test_separator_claims.py flags the two shapes the source itself gives evidence for: the compared-against value announcing itself a path (serving_path, a bare str(); .as_posix() exempt as the sanctioned fix), and a literal that is a fragment of an absolute-path literal in the same module. The second rule exists because the fix commit had to change two lines, and ... in digest announces nothing — catching only the obvious one would have missed half the regression. Verified against the real pre-fix blob: 2 of 2 flagged.
  • The triage found 40, not 24. The count that scoped the work came from grepping assert "…/…" in …; an AST scan sees single-quoted literals, a second literal on one line, the arms of an or chain, and not in forms. All 40 are classified in writing — why each slash holds on Windows, not a count — and ratcheted both directions. Zero are platform claims: f9f8343 had already fixed the only real instance, and that is said plainly rather than dressed up as repair work. The false-positive floor is a test (11 shapes plus the whole real corpus), not a claim.
  • The exemption list goes from 32 to zero. nesting.py and engine_identity.py were both written after the doc ratchet existed and neither was ever seen by it — which is what an exemption list does. All 32 modules now carry a subsystem doc, each a tracked entity with real dependency edges, every one at 0 undocumented public callables including ops with 73. The tightness is discontinuous, not incremental: at zero exemptions the same test flips from "the debt cannot grow" to "a new module with no doc fails immediately". Both ratchets were arm-tested against a real violation.

Suite 1232 → 1311. Every new guard demonstrated behaviorally red first — the separator detector against the pre-fix blob at f9f8343^, the doc ratchet against the pre-1.14.3 doc set, both using only APIs present on both trees.

[1.14.2] — 2026-07-25

The backlog goes to zero, and the register gets a detector. 1.14.1 closed two findings and opened four — one of them high — which is the same write-only shape D-069 exists to catch, one level up: a register that lists open findings but has no signal that they are aging reads an item carried across four releases exactly like one opened an hour ago. All six open findings are resolved here.

  • H-27 (high) — the process says when it is not the build the working tree describes. .mcp.json wires the published command by design, so in a session that edits the engine every cz_* write runs the release while the fix sits green in the tree; 1.14.1's write guard executed for zero tool writes on the day it was written. engine_identity.serving_build compares the running module's import path and version against the repo's src/ — self-introspection, no spawn, hook-safe. The path is the disambiguator: during 1.14.1 both sides reported the same version while being different builds.
  • H-25 — planning surfaces the lessons that govern planning. Ranking ran only per phase, so L-11 had reached nothing, ever — and that zero was being read as evidence of low value rather than of where the ranker was wired. cz_create_gameplan now ranks the corpus against the goal and logs the surfacing through the same blessed telemetry write.
  • H-26 — the nudge measures the cost it names. It thresholded a COUNT while naming TOKENS; a coverage-gated re-distill then cut 26 → 20 entries and made the corpus larger. It now fires on the block's token weight and says outright that consolidation may not reduce it. Plus the meta-fix: open findings carry an age, so a carried finding stops reading like a fresh one.
  • H-16 — a symlinked parent directory. The leaf guard passed cleanly while the write landed outside the repo; the whole ancestor chain is walked now, proven in both directions.
  • H-21 — a superseded gameplan can be closed. deferred joins the phase-row vocabulary and is threaded through the lifecycle, the open set and the completion branch together. All-deferred reports deferred, never complete.
  • H-24 — subsystem docs get a gating seam. Two strict ratchets: undocumented public callables per subsystem may only go down, and the set of modules with no subsystem doc may only shrink. No invented target, and no advisory — an advisory that never fails is rot with a progress bar. Existing debt is frozen visibly (79 callables, 32 unmapped modules) rather than laundered into a passing check.

Suite 1164 → 1232. Every new test demonstrated behaviorally red first.

[1.14.1] — 2026-07-25

The ending protocol gets a detector. 1.14.0's own execution produced the argument for this patch: a discipline this system asks an agent to perform must have a machine-checked signal that notices when it has not been performed, or it is a hope (D-069).

  • Memory-lag detection (H-22). 1.14.0 implemented, tested and pushed two entire phases across eight commits while its phase table still read "not started", and nothing anywhere emitted a signal — every other discipline here has a detector (cascade hygiene, unchecked exit criteria, unresolved open items, corpus redundancy, wiring drift). rituals/memory_lag.py now derives the claim from git rather than from the tracker asserting itself (D-065): the anchor is the last commit that touched the phase tracker, and the signal is work landing past it while the tracker still says the phase has not begun. The digest emits a ⚠ Memory lag: line naming the phase and the commit count, and cz_preflight surfaces the identical sentence as a warn that never fails the ritual (INVARIANT-05; D-024 keeps pre-flight blocking for its own checks). Conditionally emitted — a repo whose memory is current renders byte-identically to 1.14.0 (INVARIANT-08). Verified against this repo's own history at eac1c9a: it fires on the failure that motivated it.

  • Nested clauderized repos stop contradicting each other (H-23). /home/ccusce is itself a clauderized repo containing /home/ccusce/Clauderizer, so two SessionStart hooks fired and the outer one announced "No active gameplan" about a repo that was mid-release — the first thing in that session's context, read past for an entire release. INVARIANT-08's at-most-once guarantee is an in-memory per-process signal, which nesting defeats structurally. nesting.py resolves it by ownership instead: for any session cwd exactly one install is the owner (the nearest clauderized ancestor), and a non-owner stays silent — decided fresh from the hook payload's cwd on every event, across every handler, with no persisted or cross-process flag (INVARIANT-05/08). Scope is deliberately narrow: an install falls silent only when the session's owner is a proper descendant of its own root, so a session elsewhere — or a host that sends no cwd — behaves exactly as in 1.14.0 (INVARIANT-07). clauderize doctor now names nested installs by path (and, from inside, the clauderized ancestor), and clauderize init under an existing install warns and proceeds rather than silently creating a second one. Verified live on the authoring machine, where the scan found ten nested installs under one home directory.

  • The write guard 1.14.0 specified and did not ship. Its Phase 5 criterion 12 required a write-time guard against tool-call markup in structured-write arguments; grep for it returned zero, and four malformed writes are now in append-only memory — the fourth landing while the finding about the first three was being recorded. The guard now runs at the mutations render boundary that every cz_* write already flows through, on two unambiguous signals: the tool-call vocabulary itself (parameter / invoke / function_calls, bare or antml:-prefixed) and unbalanced closing tags — </context> with nothing opening it. Balance-detection is what lets a body legitimately containing <div>…</div> through untouched, which a field-name blocklist could never promise, and code spans and fenced blocks are skipped exactly as the read side has done since 1.14.0. Per D-066 it normalizes, never rejects: the tags are scaffolding, so removing them loses no content (INVARIANT-03) and no mutation gains a hard block (INVARIANT-05). The four live entries — D-052, D-062, H-19, H-23 — are read off disk as the acceptance corpus and are deliberately not retro-edited; they are append-only, they parse, and repair belongs to the amendment op.

  • The graph stops hiding what it failed to load. model.from_file returned a bare None for an unreadable entity doc — the same value it returns for ordinary prose — so a BOM'd entity (the L-24 class: PowerShell and several Windows editors write UTF-8 BOM by default, and the frontmatter fence anchors at offset zero) simply stopped existing, and every consumer then reasoned about a DAG that was quietly missing a node. It now returns a Drop record carrying the path and a machine-readable reason, and graph.index.build accumulates both drops and duplicate-id collisions (last-wins is unchanged; the shadowed file is merely no longer invisible). Graph.integrity() reports the accounting — entities_indexed + dropped + collisions == entities_on_disk — and cz_corpus_health and clauderize doctor both surface it by path. Classification is deliberately conservative: a doc with no frontmatter, or with frontmatter carrying neither id nor type, is ordinary prose and reports nothing, so the count stays actionable.

  • cz_cascade on an unknown entity returns ok:false, instead of ok:true with zero dependents. That old answer was indistinguishable from a real leaf, which made a dropped doc read as safely cascaded and silently voided D-018; when a drop plausibly explains the missing id, the error names it.

  • init spawn-tests the portable command it actually writes (task 4.6, carried from 1.14.0). The H-04 guard probed the commands composed at step 0b but never PORTABLE_COMMAND, so init certified wiring it did not write and wrote wiring it never certified. The new probe is deliberately advisory — it warns and never raises WiringRefused — because the portable form is uvx --from clauderizer[mcp], which needs the network on a cold cache: an offline or proxied first run must still install, and simply learn in-band that this leg is uncertified.

  • Two findings recorded during the close-out, both found by using the system rather than testing it. H-27 (high): the MCP server is wired to uvx --from clauderizer[mcp] — the published build — so in a session that edits the engine, every cz_* write runs the release while the fix sits green in the working tree; the Phase 2 guard above executed for zero tool writes on the day it was written, and engine_stale cannot see this because it compares source mtimes and an installed package's are install-time. H-26 (medium): the lesson-bloat nudge thresholds on a COUNT while naming TOKENS as the cost — a coverage-gated re-distill took the corpus 26 → 20 entries and made it 1.1% larger, because the handoff renders the top five in full and a synthesis outranks its own sources.

[1.14.0] — 2026-07-25

Evidence you actually traversed. One phenomenon wearing nine costumes: the engine asserted things from evidence it never read. A findings register that reported every entry active because its parser matched nothing and the reader defaulted. A curator that proposed deleting a lesson because a gitignored file was absent. A doctor that reported "launchable" from shutil.which. A release gate that reported "wiring verified" from a substring match. Each of those defenses was built after a real incident, recorded, declared resolved — and was live again, because nothing diffed a claim against its source.

So this release ships no new capability and no tuning. It makes the existing defenses fire, and pins each one to its source with a test that was demonstrated red on the pre-fix tree before it went green. Suite 1002 → 1074.

  • The entry-status grammar is single-sourced in markdown/sections.py; analyze, listing and graph/abstract_index all import it, and entry_status() reports whether a status was parsed or defaulted. Three readers each had their own pattern and only one tolerated the - **Status**: bullet that add_finding emits, so cz_list_findings reported all findings active with date: null against a file recording 17 resolved. Code spans are stripped first, so an entry that quotes the register's shape is not read as declaring it. cz_corpus_health gained a per-register parse reconciliation, and open findings now surface in cz_critique and the digest.
  • One atomic, symlink-refusing write path. writer.write_atomic — sibling temp, preserved mode, os.replace, bounded Windows retry — is now the only byte-write for tracked content. Four sites bypassed markdown/writer.py entirely and therefore never ran refuse_if_symlink, which is how a planted symlink made cz_write_handoff write outside the repo and report success. A write that fails now leaves the target byte-identical; it previously truncated it. Measured on Windows: a held handle denies the replace and the write raises — safe, and reported, rather than silently destructive.
  • Well-formedness at the write boundary. A title containing a newline plus a heading used to forge a real entry, absorb the true entry's body, and burn hundreds of ids in an append-only corpus with no repair op. Caller strings are now normalized at all five render sites: single-line fields collapsed, column-zero markdown escaped, table cells escaped (closing a resurrected phase-table defect), empty titles given a visible placeholder. Normalize, never reject — no write is lost and no mutation gains a hard block.
  • The curator no longer proposes deletion without evidence. telemetry.jsonl is gitignored into every repo while docs/LESSONS.md is committed, so on any fresh clone, teammate machine or CI runner every lesson read as never-surfaced and the curator proposed obsoleting the entire corpus (measured: 25 of 25, including one promoted the day before). That arm is gone — as D-063 had already decided and nobody had coded. The count is still reported; only the deletion proposal is gone, and cz_loop_step now distinguishes "nothing measured" from "corpus healthy".
  • doctor certifies engine identity, not presence. The portable .mcp.json most consumers get was routed to shutil.which, so "MCP server launchable" meant a string resolved on PATH. It now completes an MCP initialize handshake, reports the served version, and warns (exit 3) on a skew — which is how a repo could run its hook on one engine while its MCP client was served another. The wiring contract launches too. Memoized: warm ~1.0s, cold ~2.7s.
  • Foreign config survives. Every JSON writer did except JSONDecodeError: data = {} and then rewrote the whole file, so a UTF-8 BOM — PowerShell's default — silently deleted every co-resident MCP server. Now decoded utf-8-sig and refused rather than rewritten, per host, so one unparseable JSONC config warns and skips instead of aborting the install.
  • Per-machine state is gitignored, team memory is tracked. Six more paths join the ignore set, and clauderize upgrade adds them to a repo set up on an older version — without touching a byte of docs/. A .gitignore line does not untrack, so doctor names any still-tracked path with the exact git rm --cached command. Pre-flight's baseline moved to a gitignored sidecar: a check must not dirty the tree it gates on.
  • The handoff drops nothing. It renders the most relevant lessons in full and an index of every active lesson — 5 of 25 became 25 of 25. Three lessons this release depended on had never reached a single phase.
  • The release gate sweeps the remote registries. cz_audit checked three local files that one commit edits together, so they agreed by construction; it passed on a version that existed on zero remote registries. It now sweeps remote tags, GitHub Releases and PyPI, reporting unverified rather than a false green when a registry is unreachable.
  • cz_mine_failures no longer guesses. Its fallback matched any transcript directory merely ending with this repo's folder name, so mining from a repo with no transcripts of its own scanned an unrelated project's sessions.

Procedure 1.9.0. Known and deliberate: H-16 (symlinked parent directory, with a recorded compatibility rationale) and H-21 (a superseded gameplan cannot be closed) remain open.

[Unreleased — superseded by 1.14.0] — the July doc pass

Documentation truth repair. A six-agent audit of the engine found several places where the docs claimed behavior the code does not have. Those claims are corrected now, ahead of the code fixes they describe, because a false claim is worse than a missing feature — a reader who trusts it stops checking. Procedure bumped to 1.9.0. No engine behavior changed in this entry.

  • docs/TRUST.md — the one-paragraph summary said init writes "into your repo only"; it now states the bespoke auto-write host exception up front instead of only 110 lines later. The local-only journal list was wrong: proposals.dream.jsonl and dreams.watermark.json are not gitignored by init today, and neither are revision.json or the hook wrapper — the gap is named, with the manual workaround, rather than papered over. The "review the wiring" note now says plainly which files carry your username. And clauderize release-check is described as the required manual step 3 of the release ritual rather than a gate that "gates every release" — it is in no CI workflow (H-19).
  • docs/TRUST.md + SECURITY.md — first disclosure that cz_mine_failures reads agent-harness session transcripts from outside the repo (default ~/.claude/projects/<slug>/, overridable via CLAUDERIZER_TRANSCRIPTS_DIR) and returns excerpts of your own prompts into agent context. Read-only, explicitly invoked, never from a hook — but previously undocumented in both files.
  • docs/CROSS-HOST.md §7 — the wiring contract was described as launching the server and round-tripping cz_status via a host-simulator. It is a static shape check (valid JSON, well-formed entry, path-safe, names clauderizer-mcp). Corrected to say so, and to point at where a real handshake proof does exist.
  • README.md — the identity-not-launchability claim now distinguishes where it holds (split-host and auto-write hosts, via a real MCP handshake) from where it does not yet (the ordinary portable .mcp.json, which is checked only for presence on PATH — D-060), with a one-line command a reader can run to check for themselves. The adoption section now tells you which three files carry machine-specific paths before you make your first commit.
  • GAMEPLAN-PROCEDURE.md → 1.9.0 — "Execute a Phase" no longer instructs reading every prior handoff (it contradicted the cumulative-handoff design and the document's own anti-pattern #2). "Complete a Phase" and the coordinator checklist are now cz_* calls rather than hand-edits of the trackers, which the blessed-writes rule forbids. bin/cascade / bin/regen-graph — tooling that never existed — are replaced by cz_cascade / cz_resolve_cascade, and the "write the cascade report by hand" recipe is gone. Phase-count guidance is now 2–8 (measured: median 5 across 47 gameplans) rather than the aspirational 5–25. The Outputs Registry now warns at the instruction that the file is committed to git and must not carry credentials or account-scoped identifiers.
  • clauderizer-dream skill (both the shipped template and the rendered copy) — corrected the claim that the proposal store and watermark are gitignored local-only state, and noted what that means on a shared repo.

[1.13.0] — 2026-07-24

The dreaming loop (gameplan 2026-07-23-dreaming-loop, D-058/D-059): per-exchange experiential capture + an offline dreamer that distills the journal into staged, triaged memory proposals — transcripts are never retained (token cost + PII). Procedure bumped to 1.8.0 ("Dream Notes").

  • cz_add_dream: after each substantive exchange the agent leaves a 2–4 sentence note (kind: friction | gap | surprise | correction | drift | win, plus refs) in gitignored, append-only .clauderizer/dreams.jsonl. Validate-then-append: 600-char/4-sentence/8-ref caps and a PII deny-list (emails, secret-token shapes, absolute home paths) — an append-only journal cannot be redacted retroactively. Content-hash dedupe; gameplan/phase default to the active gameplan's current phase. init now gitignores dreams.jsonl AND telemetry.jsonl (pre-existing gap) in target repos.
  • cz_dream (read-only): two-condition gate — blocked_on_triage while staged dream proposals sit untriaged (dreaming never piles onto unactioned output), not_ripe under 10 unconsumed notes — then a BOUNDED bundle: canonical-tokenizer clustering (dream threshold 0.25 vs the 0.40 lesson near-dup), top-8 clusters / 3 exemplars with a named dropped tail, corpus-health + lesson-signal + one-hop graph joins, self-reported est_tokens. Deterministic given caller-fixed today.
  • cz_dream_propose / cz_handle_dream_proposal: judged proposals land durably in .clauderizer/proposals.dream.jsonl (content-hash dreamprop: ids — restaging is a no-op) and THEN the watermark consumes every reviewed note (crash-safe ordering; kill-and-resume proven by test). Dream proposals ride the SAME producer-agnostic triage as modernize's (one pending count, one digest line — "(N dream)" only when present; dismiss/defer unchanged).
  • Ritual & surfacing: the CLAUDE/AGENTS stanza and GAMEPLAN-PROCEDURE §"Dream Notes" teach the capture ritual; the digest gains a quiet-when-empty Dreams: N note(s) awaiting the dreamer. gauge (unconsumed only); the pre-compact reminder names cz_add_dream; cz_loop_step surfaces the dream state for loop gameplans; the clauderizer-dream skill (S-09) drives triage-first → dream-if-ripe → one staged batch, with the headless clauderize ops variant inline. Dream capture depends on NO hook event — it reaches every host (CROSS-HOST §5b).
  • The adoption plea (A-004): when notes accumulate with NO dream schedule registered and nothing pending triage, the session-start digest carries a plain-English plea — what dreaming is (auto-collected notes → a short offline pass → proposed memory fixes you approve or reject; nothing changes without review), exact scheduling paths (a Claude Code daily routine running /clauderizer-dream, or cron + claude -p), and its own retirement: cz_register_dream_schedule records {method, cadence, command} to a per-user gitignored self-report (method="manual" quiets it for hand-run loops — a D-052-style verdict, never a toggle; clearing revives the plea).
  • Dogfooded end-to-end in its own build: 12 real notes → ripe dream → 4 staged → 3 accepted into tracked memory + 1 dismissed → loop at rest. The loop caught two real defects mid-eval (a dead phase-default fallback; the gauge counting consumed notes) — both fixed + test-pinned. Measured: ~51 tok/note, ~2k-tok bundle, ~1,051 tok per accepted proposal vs a 4.6M-token raw transcript corpus whose deterministic slices yielded 0 unique durable memories (D-023's detector-C zero recall reconfirmed). README's MCP surface (drifted 14 tools) corrected to 66 and now test-pinned against TOOL_NAMES.

[1.12.0] — 2026-07-19

The external read contract (gameplan 2026-07-19-phasekeep-contract-asks): the JSON surface external clients consume — driven by the PhaseKeep coverage audit (its m0 gameplan, O-02..O-16), which found 33 write ops against 15 reads and every append-only register write-only. All additions are additive (contract schema 1.0).

  • schema_version on every payload (O-05): every ops-registry result — CLI ops batches, MCP tools, and the status/gameplans/focus --json verbs, which now route through the same stamped dispatch — carries "schema_version": "1.0". Compatibility rules: additive → minor, breaking → major; clients ignore unknown fields and degrade explicitly on a major mismatch.
  • Monotonic memory revision (O-03): .clauderizer/revision.json ({schema_version, epoch, revision}, atomic replace) — blessed CONTRACT SURFACE, the near-free poll target. Bumped by every memory write (markdown mutations, cascade reports, handoffs, focus flips) at the byte-writer choke points; no-op rewrites never bump. epoch re-mints on file recreation so pollers key on (epoch, revision). Rides in status --json as revision; cz_revision is the transport-uniform read.
  • Eleven listing reads (O-06..O-14): cz_list_open_items (full records: text, phase tag, resolution + date), cz_list_decisions / cz_list_invariants / cz_list_findings (supersession links both ways, scope, audience), cz_list_lessons (curation state incl. obsolete/promoted, category, evidence), cz_list_corrections, cz_list_amendments, cz_phase_detail (every gameplan's phase table with per-criterion exit-criteria state, computed approval staleness, dates, goal, assignment), cz_list_cascade_reports (per-dependent verdicts + the shared pending predicate), cz_docs_index + cz_doc (frontmatter-stripped canonical-doc reads). One registry: CLI and MCP expose them identically.
  • Assignments, provisional (O-02, phasekeep proposal 13.3/16.7): cz_assign / cz_assignments — gameplan default (> Assignee: header), per-phase override (**Assigned**: line), and the per-project manager role ([assignment] in config.toml). Deliberately minimal; revisitable when the first external consumer lands.
  • ops --list --json (O-15): the machine-readable op enumeration (name, writes flag, summary, required/optional) — introspection without regexing column text.
  • Structured graph pins (O-16): cz_graph_query entities carry depends_on_pins ({target, constraint}) beside the target@constraint strings.
  • Marker-block losslessness (the PhaseKeep O-04 field failure): a re-init no longer deletes project content found INSIDE the managed CLAUDE.md/AGENTS.md block — an H1-headed section there is moved below the block under a visible banner, and init says so. Regression-covered either side of the markers.

[1.11.0] — 2026-07-18

Opt-in: serve a WSL-hosted repo from the Kimi Work desktop app (gameplan 2026-07-18-kimi-desktop-serve-wsl-repo-via-repo-cwd-pin, D-057). The D-055 --repo "forward path" is now verified and automatic: the daimon runtime honors a per-server cwd, so the server can spawn from a Windows-safe cwd and read a WSL repo over its \\wsl.localhost UNC path (file I/O over UNC works; only the process cwd may not be UNC — D-054).

  • clauderize init --serve-wsl-here — run inside a WSL-hosted repo opened in the Windows desktop, it pins the daimon to serve THAT repo: {command: …clauderizer-mcp.exe, args: ["--repo", "\\wsl.localhost\<distro>\…"], cwd: "C:\Users\<you>"}. A clear no-op off the WSL-repo + Windows-desktop combo.
  • Durable across the app's config wipe. The pin is recorded in a clauderizer-serve.json sidecar beside the daimon mcp.json; the app regenerates mcp.json but leaves the sidecar, so init/doctor/status self-heal re-compose the pin (and re-probe a fresh exe path).
  • doctor reports which repo the pin serves and the one tradeoff — a single per-user file means the desktop serves that repo for every project opened in the app — then handshake-verifies the pinned command. uninstall clears the pin.
  • Strictly opt-in; the default is unchanged (repo-agnostic .exe for Windows-hosted repos + the UNC read-your-way-out guidance for WSL repos). Verified live end-to-end: the pinned command's cz_status served a real WSL repo over UNC.

[1.10.0] — 2026-07-17

End-to-end repair of the Kimi Work desktop (daimon runtime) MCP wiring, verified live on Windows 11 + WSL2 (gameplan 2026-07-17-kimi-desktop-wiring-end-to-end-repair, D-055 — supersedes the bare-uvx-for-Windows clause of D-053).

  • Windows-native command composition. The daimon entry no longer composes a bare uvx for a Windows host (the app bundles uv.exe but not uvx.exe, so it can never spawn). init now probes for a Windows-native clauderizer-mcp.exe (pipx venv Scripts, .local\bin / uv tool dir) and registers its absolute path with args: []. From WSL it stats the /mnt/c mirror and registers the translated C:\ spelling. No clauderizer-mcp.exe? It drops the setup guide instead of a dead entry.
  • Self-healing registration. The app regenerates its runtime mcp.json on project switch and merges from no persistent source, so init, doctor, and status now re-apply the entry (idempotent — a no-op when current). Not from any hook (INVARIANT-06) nor the MCP read path (L-03). CLAUDERIZER_NO_KIMI_DESKTOP=1 still opts out everywhere.
  • doctor smoke-tests the command end-to-end. It spawns the composed command from a non-repo cwd, completes an MCP initialize handshake, and asserts serverInfo.name == "clauderizer" — so a broken command fails loudly instead of looking registered. Fails on a bad handshake; honestly unverifiable for a target this host can't reach (never a false green).
  • clauderizer-mcp --repo <path> / $CLAUDERIZER_REPO. Repo discovery is now decoupled from the process cwd, so a host that can't spawn with the repo as its cwd (a Windows desktop serving a \\wsl.localhost UNC repo) can still point the server at the right repo. Precedence: --repo > $CLAUDERIZER_REPO > cwd.
  • Sharper WSL-repo guidance. For a WSL-hosted repo opened on the Windows desktop, init/doctor clarify that the registered .exe still serves Windows-hosted repos and only this WSL repo can't be served (UNC-cwd spawn limit, D-054), and the guide names --repo as the forward path. Docs updated (setup guide per-topology + persistence finding, TRUST, CROSS-HOST).
  • Reusable bespoke auto-write host framework (D-056). The kimi-desktop machinery is now a framework so future agent hosts of the same shape are covered by reuse, not re-implementation: a BespokeHost base + BESPOKE_HOSTS registry over host-agnostic primitives — mcp_probe (the MCP initialize-handshake capability probe) and winhost (Windows/WSL command composition). init/doctor/status/uninstall iterate the registry generically; a new host is a BespokeHost subclass + one registry line (recipe in CROSS-HOST.md). clauderize doctor --deep opts into the handshake for the project-config auto-write hosts too. No behavior change for kimi-desktop.

Also fixed (surfaced by the Windows CI matrix while shipping this release):

  • Windows write-lock contention. _acquire_file caught only FileExistsError, but Windows raises PermissionError (EACCES) for an O_EXCL create under contention — so a concurrent writer could error instead of retrying and waiting its turn. It now treats a PermissionError while the lock file exists as contention (a genuine ACL failure with no lock present still surfaces).

Claude Code wiring (.mcp.json, .claude/settings.json hooks) is unchanged.

[1.9.1] — 2026-07-17

A read-your-way-out playbook for Kimi Work desktop sessions on a WSL repo, plus a doctor warning (gameplan 2026-07-17-kimi-desktop-unc-recovery-playbook, D-054).

  • A WSL-hosted repo opened in the Windows desktop app can't run the shell or launch the MCP server — Windows cannot spawn a process with a \\wsl.localhost (UNC) working directory (cmd.exe literally says "UNC paths are not supported"). The bundled bash is fine; only process spawning is blocked. Since file tools still work over UNC, clauderize init now drops an agent playbook into .clauderizer/kimi-desktop-mcp-setup.md for that combo — why it fails, how to keep working (read docs/ directly with your file tools), and the two real fixes: put the repo on the Windows filesystem, or use Kimi Code CLI inside WSL (where K3 is available). clauderize doctor warns loudly for the combo.
  • No wsl.exe-wrapper MCP command is shipped — verified it can't help (it dies on the same UNC cwd; the fix belongs in the desktop app, which should execute via wsl.exe inside the distro).

[1.9.0] — 2026-07-17

The Kimi Work desktop app (daimon runtime) is now a first-class host — the cz_* tools reach desktop sessions with no manual step (gameplan 2026-07-17-kimi-desktop-daimon-host-mcp-autowrite, D-053).

  • New kimi-desktop host. The desktop app embeds kimi-code via a "daimon" runtime and loads MCP servers only from its per-user runtime-home mcp.json — never the project .mcp.json/.kimi-code/mcp.json, and with no hook surface, so the MCP server is its only orientation lane. clauderize init now auto-registers the clauderizer server there — the single deliberate exception to Clauderizer's "never auto-write a global config" rule (D-031), justified purely by UX. Kept narrow: detected-only (never creates the app's dirs), non-destructive + atomic, and a repo-agnostic command (the server serves whichever repo you open in the app — one entry covers every repo).
  • Cross-platform, best-effort: Windows (%APPDATA%\…), macOS (~/Library/Application Support/…), Linux (~/.config/…), and the common repo-in-WSL + app-on-Windows setup (a bare uvx that runs on Windows, with a loud PATH warning). macOS/Linux daimon paths are best-effort candidates.
  • clauderize doctor reports it (registered / detected-but-unwired / not installed) and warns loudly (missing uvx, unwritable config). clauderize uninstall removes it surgically. Set CLAUDERIZER_NO_KIMI_DESKTOP=1 to skip.
  • Found and fixed via a live debugging session on a real desktop install.

[1.8.1] — 2026-07-16

Memory-maintenance hotpatch (gameplan 2026-07-16-hotpatch-lesson-redistill-and-proposal-triage).

  • Fix (H-18): obsoleted lessons with parentheses in their reason silently kept riding every handoff. The lesson-state marker parser (markdown/lesson_state.py) required a paren-free payload, so a reason like (obsolete 2026-06-09: superseded (see L-50)) failed to match and the line read as active — inflating the memory gauge and re-surfacing a pruned lesson in every roll-up. The payload now tolerates one level of nested parentheses while keeping the end-anchor and post-keyword word boundary, so mid-text mentions stay inert (regression test in tests/test_lesson_state.py).
  • Project-lesson corpus re-distilled 34 → 19 (docs/LESSONS.md), back under the 20-lesson handoff threshold: seven thematic syntheses (L-50–L-56) absorb clusters of one-principle-across-war-stories lessons; sources marked obsolete, never deleted (INVARIANT-03). This is dogfood memory for the Clauderizer repo itself, not shipped package content.
  • Curator loop self-arms. The standing-curator loop gameplan now declares a standing condition (conditions.<gid>.toml) that proposes an iteration when active lessons drift back over 20 — resolving the no_standing_conditions advisory. Advisory-only; nothing auto-runs (INVARIANT-05/06).

[1.8.0] — 2026-07-16

Advisory upgrade proposals are now triageable — they no longer pile up or vanish into terminal scrollback (gameplan 2026-07-16-advisory-proposal-triage-at-session-start, D-052).

  • Persistent triage — handle / dismiss / defer. Each cz_modernize proposal now carries a stable id, and a per-user, gitignored ledger (.clauderizer/proposals.local.toml) records dismissals (hidden until the proposal materially changes → a new id) and deferrals (snoozed to a date). New tools cz_dismiss_proposal and cz_defer_proposal.
  • Surfaced at session start; terse at upgrade. The session digest shows a one-line "N upgrade proposals awaiting triage" — only when some are pending, and riding the single digest (no second injection, INVARIANT-08). clauderize upgrade is now terse: the mechanical work in full, the advisory proposals as a count + a pointer, not a wall of suggestions (--json/cz_modernize still list them).
  • A clauderizer-modernize skill walks you through them one at a time — ask-first, then handle (do the work) / dismiss / defer per proposal. It's the agent-driven answer to "upgrade should finish the job," while the engine still never invents your project's content (D-042 / INVARIANT-05): the mechanical tier auto-applies, the memory tier is proposed for you to action.

[1.7.0] — 2026-07-16

Two things: Kimi Code CLI becomes a first-class auto-write host (out-of-the-box MCP for the Kimi K3 model), and Clauderizer now audits its own work after every gameplan (cz_audit).

Self-audit after every gameplan (gameplan 2026-07-16-self-audit-ritual-after-every-gameplan, D-051)

  • New cz_audit gate — an advisory (INVARIANT-05) work/release self-audit, distinct from cz_critique (which audits memory coherence). Mechanical signals: version single-sourcing (pyproject vs the package __version__ vs the top CHANGELOG entry — a mismatch a stale editable install hides), an uncommitted working tree, and unresolved cascades/open items. Judgment checklist for what a green suite can't prove: verify in a clean environment (not a stale editable install), re-audit every consumer of a changed entity (including untracked ones — uninstall, CLI, docs claims), and claim only what you verified. Read-only, stdlib-only, never blocks.
  • Runs at every gameplan close — the shipped clauderizer-close-gameplan skill and GAMEPLAN-PROCEDURE.md (bumped to procedure v1.7.0) invoke cz_audit before the post-mortem, so every install audits its own work.
  • Born from a real miss caught during this very release: a version bumped in pyproject.toml but left stale in __init__.py, green locally on a stale editable venv, exposed only by a clean CI install. cz_audit's headline check (plus an install-independent guard test) now catches exactly that.

Kimi Code CLI host (gameplan 2026-07-16-kimi-code-truth-up-k3-mcp-autowrite)

  • kimi host repointed to Kimi Code CLI (D-049) — the successor to the legacy Kimi CLI, and the host that serves Kimi K3. Its MCP is now auto-written to the project-level .kimi-code/mcp.json (mcpServers key, non-destructive, the same shape as Cursor) instead of being guide-only. Bare clauderize init registers the clauderizer server with zero manual steps; detect_host_target, the wiring-contract sweep, and the path-safety audit all cover it. This applies D-031's project-config branch — the earlier guide-only status was only because Kimi CLI had no project MCP config; Kimi Code CLI now ships one.
  • Session-start hooks stay guide-only (TOML in ~/.kimi-code/config.toml, the zero-runtime-dep invariant forbids a stdlib TOML rewrite). The single-sourced .clauderizer/kimi-setup.md carries the [[hooks]] snippet for the four digest-relevant events (SessionStart, UserPromptSubmit, PreCompact, PostCompact — verified to inject stdout on exit 0) and documents skills exposure: Kimi Code CLI reads .kimi-code/skills/.agents/skills, not .claude/skills.
  • Orientation is honest about kimi (D-050). Clauderizer auto-wires kimi's MCP but not its hooks, and Kimi Code CLI's AGENTS.md read-status is unverified — so kimi is treated as hook-less for injection routing: the P7 server bootstrap (a one-line status note on the first tool call) is its automatic orientation, exactly like Grok. Removing kimi from the hook-host set is behaviorally inert today (a kimi session sets no marker → resolves to unknown → the bootstrap already fires) but makes best_tier/delivers_status_via_hook honest and prevents a dark-session footgun if kimi runtime detection is ever added.
  • Uninstall fix: clauderize uninstall --host kimi now also removes the bespoke .clauderizer/kimi-setup.md guide (it is specially named, not the <host>-mcp-setup.md convention, so it was previously orphaned).
  • Note on the split: the legacy Kimi CLI (~/.kimi/, pip) and its successor Kimi Code CLI (.kimi-code/, npm) are distinct products; the kimi host id now targets the successor.

[1.6.0] — 2026-07-09

Multi-host default + Grok Build TUI — one init for every supported agent.

Multi-host default wiring (gameplan 2026-07-09-multi-host-default-wiring)

  • Bare clauderize init wires every supported agent (D-046) — Claude Code hooks
    • all auto-write MCP configs + guide-only setup docs. Non-destructive, path-safe (uvx --from "clauderizer[mcp]" clauderizer-mcp). Multi-AI repos need no per-tool re-init.
  • --host <name> is a scope filter, not exclusive identity. Config records enabled = ["*"] (or a concrete list); legacy configs without enabled load as multi.
  • Runtime session-agent detection (D-047) — env markers (GROK_AGENT, CLAUDECODE, Cursor/Codex signals, …). When unknown, multi-safe hook-less default so P7 bootstrap still fires; never suppress bootstrap solely because Claude files exist on disk.
  • Doctor configure-on-demand (D-048) — per-host readiness + human steps (Grok /hooks-trust, Amp approve, TOML guides); advisory only (INVARIANT-05).
  • Decisions D-046, D-047, D-048.

Grok Build TUI host-target (gameplan 2026-07-09-grok-build-tui-host-support)

  • grok first-class host — portable .mcp.json, governance .grok/hooks/, honesty guide. Hook→ctx=no (best_tier 4 + P7). Never in _HOOK_HOSTS. 12 hosts in matrix.

[1.5.3] — 2026-07-02

Field patch — three gameplan-machinery bugs found while authoring a multi-gameplan portfolio through clauderize ops on a hand-written corpus.

  • No more double-dated ids (fix). cz_create_gameplan prefixes names with today's date; a name that already starts with an ISO date ("2026-07-02-x") produced "2026-07-02-2026-07-02-x". A pre-dated name is now used as-is — which also lets you pin a date. Every id remains dated, standing loop gameplans included; undated ids aren't supported.
  • A typo can no longer mint a shadow gameplan (fix). cz_add_phase with an unknown gameplan_id silently scaffolded a bare GAMEPLAN.md the portfolio then tracked. All gameplan-scoped writes (cz_add_phase, cz_add_lesson, cz_add_open_item, cz_set_exit_criteria, cz_add_correction, cz_add_amendment, cz_transition_phase) now hard-error on an unknown id and list the known gameplans; creation stays exclusively cz_create_gameplan's job.
  • Decorated phase statuses parse; misses explain themselves (fix). Hand-written tracker rows like "🟡 READY — kickoff" or "⬜ GATED (deps)" made phases invisible. Status words now match on word boundaries with synonyms (DONE/COMPLETED → complete, GATED/WAITING/PAUSED → blocked, PENDING/TODO → not started), tracker rows need only three columns (| number | name | status | — dates are written only when the row has those columns), and a failed transition now reports what the trackers actually contain plus the accepted vocabulary instead of a bare "not found".

[1.5.2] — 2026-07-02

Field patch — four bugs from the first native-Windows (pipx) installation, all reported by an agent dogfooding a real project the same day.

  • Windows console crash (fix). On cp1252 consoles, printing the CLI's ✓/✗/⚙/⚠ glyphs raised UnicodeEncodeError — including inside error handlers, so commands died mid-report. clauderize and clauderizer-hook now switch their output streams to degrade unencodable characters (?) instead of crashing; genuinely UTF-8 consoles are untouched, and the MCP server's protocol channel is deliberately left alone. PYTHONIOENCODING=utf-8 is no longer needed.
  • Inline frontmatter lists (fix). Hand-written depends_on: [] (or [a, b]) parsed as a raw string, and consumers iterating it saw its characters — phantom dependencies named [ and ] in the graph. Inline flow lists now parse as real lists and round-trip.
  • Heading-title tolerance (fix). Appending a decision into a hand-written document whose heading carried a suffix ("Decisions (newest first)") created a duplicate ## Decisions section at end-of-file. Section lookup now matches exact titles first, then case-insensitive, then a title-prefix with a word boundary — so entries land inside the section you already have. (Ordering within the section still appends; a newest-first insertion preference is a possible future option, deliberately out of scope here.)
  • --run-cmd help (fix). The text now says what it is: a launcher prefix for the engine's commands (like uvx --from clauderizer), not a path to a single binary.

[1.5.1] — 2026-07-02

Docs patch — no behavior change. The README gains "Speak the language — words that do things": the operative vocabulary (gameplan, phase, handoff, ritual, cascade, pre-flight, decision, invariant, lesson, approve, standing condition, onboard, upgrade, append-only, …) with what each word means here and what saying it makes happen. These words are handles bound to specific tools; speaking them steers an agent onto the rails. Cut as a release because PyPI bakes the README per version — this puts the vocabulary on the package page.

[1.5.0] — 2026-07-01

Onboarding — a repo that already has real documentation now gets a path from "placeholder scaffolds next to my actual specs" to seeded memory. (Version lines, kept straight: this is engine 1.5.0, and it carries procedure 1.6.0 — the methodology document's own, separate version.)

  • cz_onboard — a read-only bundle: which Clauderizer docs are still scaffold placeholders (structure-based detection that survives template wording changes; the append-only logs are never targets), which existing files look like specs (README, root design/spec docs, docs/*.md the engine doesn't own — paths and sizes only, capped), and a prompt describing how to seed: rewrite the placeholder prose docs directly, record subsystems/features with cz_upsert_entity, record decisions and rules already in force with cz_add_decision/cz_add_invariant citing the source file. The engine detects and prompts; it never seeds anything itself.
  • clauderizer-onboard skill — ships with the other skills at init; walks the agent through the read-and-seed flow with distill-don't-transcribe judgment notes.
  • Surfaced on both delivery paths — clauderize init prints one advisory when unseeded docs and spec candidates coexist, and already-initialized repos learn about onboarding from clauderize upgrade (a new advisory proposal), per the modernization contract: mechanical things apply, memory things are proposed.

New tool: cz_onboard (surface 44 → 45).

[1.4.1] — 2026-07-01

Wording patch — no behavior change. The engine's package version (1.4.x) and the procedure version it carries (1.5.x, the methodology document's own line) near-collided numerically in 1.4.0, and the modernization messages phrased the comparison as "corpus procedure 1.4.0 vs engine 1.5.0" — which reads like a version skew or a phantom 1.5.0 release. The status digest, clauderize doctor, the modernize report, and the tool description now say the engine carries a procedure version and spell out that it is a separate line from the package version. Caught by the project's own maintainer within the hour of 1.4.0 — exactly the confusion decision D4 predicted.

[1.4.0] — 2026-07-01

General modernization — the release where upgrading the engine delivers its improvements to your repo, plus four additive memory/gameplan capabilities distilled from the heaviest multi-campaign deployment. Everything is opt-in by shape: a repo that uses none of it behaves exactly as 1.3.1 (procedure 1.4.0 → 1.5.0, MINOR).

  • clauderize upgrade — corpus modernization. The config now carries the procedure version the repo was last brought up to (stamped by init). When a newer engine meets an older corpus, the status digest and clauderize doctor say so in one line, and clauderize upgrade closes the gap in two tiers: mechanical updates apply for you (the config stamp and migrations, missing per-kind gate example files, the engine-owned GAMEPLAN-PROCEDURE.md refresh — all visible in git diff), while memory-shaped improvements are only proposed (unwired QA gates, near-duplicate invariants that look scope-taggable, campaigns without deliverable entities, loops without standing conditions) — your decisions, invariants, and lessons are never auto-edited. This also makes 1.3.1's preflight.<kind>.toml.example real: the hint referenced an example file that nothing actually scaffolded; upgrade now writes it.
  • Scoped memory. cz_add_invariant accepts a scope (project-wide, or one gameplan's — a campaign's brand rules stop leaking into every other gameplan's context) and an audience label; cz_add_lesson accepts an audience. Reads filter — cz_analyze and the handoff's governing-invariants list skip other gameplans' scoped rules, and cz_next_phase_context(audience=...) returns one working role's view — but the canonical files and the written handoff always carry everything. The write-time near-duplicate advisory now covers invariants too (same single tokenizer and threshold), and curation never proposes consolidating across scopes or audiences.
  • Approval criteria — sign-offs bound to content. An exit criterion of the form APPROVAL: <artifact-path> — <description> plus the new cz_approve_gate records a human approval as the artifact's content hash. Every later read recomputes it: edit the artifact and the approval reads as stale — in check-off, phase completion, and pre-flight — until re-approved. A hand-ticked box never counts. Surfaced everywhere, enforced nowhere.
  • Deliverables for campaign-style gameplans. A kind may define a deliverable lifecycle (the campaign kind ships concept → spec-approved → produced → assembled → qa → shipped); each deliverable — a film, a short, a deck, never an individual rendered file — is a tracked entity with a gameplan field. cz_gameplans gameplan_id=... renders the deliverables board; the digest adds at most a one-line rollup ("Deliverables: 3/6 shipped").
  • Standing conditions. A loop or campaign gameplan may declare threshold probes in .clauderizer/conditions.<gameplan-id>.toml (exit 0 = met). They run only when status is explicitly asked for — never on a timer, never from the session-start hook — and a met condition surfaces one line: "iteration proposed". The engine proposes; you decide.
  • Cross-gameplan consumes, pinned. The handoff's "Consumes" section now shows each consumed entity's version alongside its status, and the whole chain — declare, render, cross-axis change, pending cross-ref on the portfolio card — is covered by an end-to-end test.

New tools: cz_approve_gate, cz_modernize (surface 42 → 44). New CLI subcommand: clauderize upgrade.

[1.3.1] — 2026-06-28

Integrity patch — coherence, test, and documentation hardening from a read-only audit at 1.3.0. No new features and no user-facing behavior regression; the tool surface stays 42.

  • One canonical tokenizer (fix). The corpus-health redundancy metric (behind cz_corpus_health / cz_curate / cz_lesson_health / cz_loop_step) had its own divergent token splitter at threshold 0.6, while the write-time near-duplicate advisory used the canonical tokenizer at 0.40 — two different definitions of "near-duplicate lesson". They are now single-sourced: one tokenizer (analyze._tokens) and one threshold (0.40), shared with the abstract index and relevance ranking. A guard test prevents a third fork from reappearing. Advisory output only (INVARIANT-05); it now reports an honest count on a consistent basis rather than a divergent one.
  • Coherence fixes. The L-NN lesson-line grammar is single-sourced (the handoff ranker and telemetry now parse through the one shared parser); analyze.suggest_edges gained a size guard so its O(n²) pair scan can't tax the hot prompt-submit hook on a large entity graph; cz_get documents that it never mutates canonical markdown (only the disposable cache).
  • No false-green campaign QA. A campaign preflight gate that is declared but unwired now warns ("declared but did not run") and lowers the verdict to "pass with warnings" instead of silently reading green; an example .clauderizer/preflight.campaign.toml.example ships.
  • Test integrity. Replaced tautological "is-it-read-only" assertions (which checked a registry flag, not behavior) with a behavioral gate that runs each read-only op and proves it mutates no tracked file; the MCP discoverability test now asserts the full tool surface; added tests for the SessionStart digest's advertised tool list and the per-kind preflight real-subprocess path; scrubbed a machine-specific path (and username) from a test.
  • Docs. ARCHITECTURE.md and VISION.md now describe the 1.2.0 (concurrent, multi-axis gameplans) and 1.3.0 (abstract index) feature sets; docs/subsystems/mcp-server.md version refreshed.

[1.3.0] — 2026-06-28

Fast retrieval — a deterministic abstract index over the memory corpus, so an agent reads exactly the entry it needs instead of loading whole files.

Memory is markdown and stays that way: this adds a disposable, rebuilt-from-markdown index that makes retrieval cheap without embeddings or any new runtime dependency (INVARIANT-01 — markdown is canonical; the index is a derived cache).

  • cz_get(id) — addressable single-entry fetch. Resolve one decision (D-NNN), invariant (INVARIANT-NN), finding (H-NN), or lesson (L-NN) by id — its full body read from canonical markdown on demand — instead of loading a whole corpus file. Read-only.
  • Abstracts on cz_analyze. Each ranked hit now carries a one-line abstract (a pointer, not the body), so the agent can often answer without a follow-up fetch. A pre-registered cost experiment on this repo's real corpus measured a 48.3% mean payload-token reduction per lookup at equal answer accuracy — deterministic, no live LLM.
  • Write-time near-duplicate-lesson advisory. cz_add_lesson surfaces existing project lessons the new one strongly overlaps (length-normalized Jaccard) and nudges consolidation instead of appending — advisory only, never blocks (INVARIANT-05); the corpus stays append-only (INVARIANT-03).
  • Upgrade path. clauderize init and clauderize reindex build/refresh the gitignored abstract index idempotently; clauderize doctor detects a missing or schema-stale cache and advises reindex (read-only — the runtime self-heals on first use).

New tool: cz_get (surface 41 → 42).

[1.2.0] — 2026-06-27

Concurrent multi-axis gameplans — run several long-lived gameplans in one repo at once.

A repo is no longer limited to a single active gameplan. You can drive a code gameplan and a marketing campaign (or any number of axes) in parallel, each advanced in its own sessions, without losing the others. Fully back-compatible: a single-gameplan repo behaves exactly as before (proven by a byte-identical golden snapshot of the status digest).

  • Focus + portfolio. One gameplan is the focus — the default target for status, do-phase, handoff, and preflight. Switch it with cz_focus / clauderize focus <id>; see every open gameplan with cz_gameplans / clauderize gameplans. The status digest grows a portfolio block automatically once a second gameplan is open. The set of open gameplans is derived from each gameplan's phase table, not stored; only the one focus pointer persists (the config migrates [active_gameplan] → [focus], with read-fallback for old repos).
  • Kinds as data. Every gameplan has a kind — driven (code), loop (maintenance), campaign (creative), or a custom kind in .clauderizer/kinds/<name>.toml. A kind sets the vocabulary, the first phase, and the preflight checks. The vocabulary is display-only: a campaign reads in stages and assets in digests and handoffs while the on-disk structure stays identical, so every parser and tool is unchanged.
  • Per-kind preflight. A campaign's preflight runs its own QA gates (virality, brand-lint, duration, …) — generic shell commands wired in .clauderizer/preflight.<kind>.toml — instead of tests/build. Clauderizer ships the run-named-gates mechanism; you supply the checks. An unwired gate skips with a hint.
  • Cross-gameplan dependencies. Declare that one axis consumes an artifact another produces with cz_consumes; changing that artifact then cascades across gameplans — the consuming axis gets a pending cross-ref its own cascade check catches. Memory scoping is explicit: project invariants/ADRs are shared, a gameplan's decisions/lessons are local, and consumed artifacts surface in the handoff's "Consumes" section.

New tools: cz_focus, cz_gameplans, cz_consumes (surface 38 → 41). New CLI verbs: clauderize focus, clauderize gameplans. Procedure version 1.3.0 → 1.4.0. Also includes the H-17 preflight fix (detect the project venv so the test command resolves under uvx/pipx).

[1.1.1] — 2026-06-25

Documentation only — no change to engine behavior.

A README section on updating. The uvx --refresh update path — refresh the engine, then re-run init to refresh the wiring — was documented only in UPGRADING.md; the README now spells it out inline, so the most common question ("how do I get the latest version?") is answered where people first look. PyPI bakes the README into each release, so this patch is what carries the new section onto the project page.

[1.1.0] — 2026-06-24

A new capability for the self-critique gate — and the first behavior feature since 1.0.0.

cz_critique now checks for two self-judgment biases. The self-critique gate already graded a target against Coverage, Coherence, and Grounding. Because the thing being critiqued is always your own work, it now also surfaces two failure modes a self-judge is prone to (drawn from the CALM judge-bias study):

  • Self-enhancement — an open item closed with a hollow note ("done", "looks good") that cites nothing concrete, or a "ready to ship / no gaps remain" claim made while real gaps are still open.
  • Authority — a lesson whose evidence leans on an unverifiable citation (a paper, a URL, a bare "verified") instead of provenance that resolves in the repo (a commit, a path, a test count).

Both are advisory, like the rest of the gate: the engine surfaces the candidates and you decide. Each check is guarded so it stays quiet on sound work — a citation that also points at a commit, or a terse note that cites a file, is not flagged. No new dependency; the checks are plain deterministic text rules. Validated up front against a labeled fixture of 32 critiques with adversarial near-misses: the new checks catch every planted bias the old rubric scored clean, with no false flags on the sound ones.

[1.0.5] — 2026-06-23

Documentation readability and a hardening completion. No change to tool behavior.

Cleaner docs and tool descriptions. The human-facing docs (TRUST, TROUBLESHOOTING, the gameplan procedure) and the cz_* tool descriptions carried internal cross-reference codes — decision, finding, and lesson IDs — that meant nothing to a reader; leftover working-memory shorthand. They are rewritten in plain prose with no loss of meaning; code references, format examples, and the ID-scheme definitions stay. A stale "hardening findings H-01..H-09 resolved" line that would have become wrong if updated is now stated as the tracker's standing discipline rather than a drifting count.

Harden — no engine write follows a symlink (H-13). A pre-planted symlink in a hostile cloned working tree could have redirected an engine-owned write (.mcp.json, a per-host config like .cursor/mcp.json, the .claude/settings.json hooks, the hook wrapper, .gitignore, or a tracked doc) to a path outside the repo. Every engine write now refuses a symlinked target instead of following it — the link is never followed or deleted; you review and remove it. (The deeper symlinked-parent-directory case is tracked as H-16 for a future containment pass.)

Cleaner release-check and CLI output. The release-check verdicts and CLI messages no longer print internal finding codes in their explanations.

[1.0.4] — 2026-06-23

Follow-up polish from the stranger-readiness dogfood — the rough edges left after 1.0.3's critical fixes. Nothing breaking; everything additive.

Discover the CLI's operations. clauderize ops --list now prints every operation — what it does, whether it writes, and its required arguments — and clauderize ops --schema <op> shows one operation's full arguments. Previously you had to know the operation names by heart, and the error for an unknown one pointed at a dead reference. The list is read from the same registry the MCP tools use, so the command line and the agent tools can't drift apart.

uvx clauderizer … works now. The package is named clauderizer but the command was only clauderize, so the obvious first thing a newcomer typed failed. There is now a clauderizer command alias too; clauderize remains the canonical name.

Clearer cascade resolution. When you resolve a cascade, the result now says exactly what is left to close it — a verdict for each dependent, plus a one-line summary of the edits — instead of silently staying "pending". And a manual cascade for a change that a status transition already cascaded no longer writes a duplicate review report; it reuses the open one.

Preflight tells you when its test gate is asleep. If a project was set up before it had any code, its language profile is "generic" and the test/build checks quietly skip. Preflight now notices when the project looks like a real language (say a pyproject.toml has since appeared) and points you at re-detecting it, instead of staying a silent no-op.

Retire an entity without deleting it. Transition a subsystem or feature to retired (or obsolete) with cz_transition_status: it stays in the graph for history but drops out of active relevance surfacing — the supported alternative to hand-deleting a tracked file.

Smaller fixes. The MCP server reports Clauderizer's own version in its handshake (not the underlying SDK's); amendment fields passed as lists render as a readable list instead of a raw ['…']; and a stale "cascade pending" note no longer lingers on amendments.

[1.0.3] — 2026-06-23

Fix — zero-install MCP server (H-14). clauderize init wired the MCP server as uvx -q --from clauderizer clauderizer-mcp, but mcp is an optional extra, so the zero-install (uvx/pipx) path never installed it: the server printed the missing-package notice and refused to serve, leaving a fresh Claude Code session with the SessionStart hook but no cz_* MCP tools. The uvx fallback now requests the extra for the server command only (--from clauderizer[mcp]); the hook and CLI stay extra-free. Surfaced by a pet/standard/saas stranger-readiness dogfood — invisible in dev setups that already have mcp installed.

Fix — doctor no longer false-greens a broken MCP wiring (H-15). The "MCP server launchable" verdict probes --version, which answers without importing the mcp SDK, so it stayed green even when the wired command could never serve. clauderize doctor now also statically flags a --from clauderizer MCP wiring missing the [mcp] extra.

[1.0.2] — 2026-06-22

License. Relicensed from MIT to the Apache License 2.0 — the same permissive terms, plus an explicit patent grant and a trademark clause. Replaces LICENSE with the full Apache 2.0 text, adds a NOTICE, and updates the pyproject license field + OSI classifier and the README. No code changes; copyright remains "Clauderizer contributors".

[1.0.1] — 2026-06-22

Docs. Corrects the README's maturity section, which still read "beta, with receipts" after the 1.0 flip — now "1.0, stable" against the G1–G7 gates; drops a stale "Pre-1.0" line in SECURITY.md. PyPI renders the long-description per version, so the README fix ships as a patch. No engine changes.

[1.0.0] — 2026-06-22

1.0 — stable. Promotes 1.0.0rc1 to the first stable release; no engine changes from the rc. All 1.0 readiness gates (G1–G7, docs/RELEASING.md) hold — G6's cold-start was re-validated fresh on the reference host: in a new session both the SessionStart hook and the MCP transport fired cold, cz_discover_skills ran end-to-end, and the live cz_status matched the injected digest. Classifier flips 4 - Beta → 5 - Production/Stable. Ships with a human-first README (hero, animated demo, before/after, how-it-works).

[1.0.0rc1] — 2026-06-22

First 1.0 release candidate. Exercises the G1–G7 readiness gates (docs/RELEASING.md) in the wild before the final 1.0.0; the classifier stays Development Status :: 4 - Beta until 1.0.0 closes the G6 cold-start residual. Suite 573 → 601.

Project skill-awareness. A project now tracks the Agent Skills available in its environment as first-class, surfaced memory, mirroring the lesson lifecycle. Read-only discovery proposes, the agent confirms, and the skills relevant to a phase ride into its handoff focused by relevance. Propose-confirm, never auto-mutation (INVARIANT-05); the auto-PR idea (open a PR when a public skill is found) was explicitly dropped (D3).

Added

  • docs/SKILLS.md — a compact, append-only project skill inventory (lazy-created from template, like LESSONS.md). markdown/skill_state.py is the one grammar (states active | obsolete | superseded).
  • cz_register_skill / cz_obsolete_skill — register a skill (S-NN, idempotent on name) / mark one obsolete in place (append-only).
  • cz_discover_skills — read-only: scans the local skill directories, parses each SKILL.md's name + description, and proposes the unregistered ones (like cz_curate).
  • Relevance surfacing — the handoff carries a "Skills for This Phase" block ranked by the existing lexical analyzer (top-k, or nothing when none overlap — focused, not a dump); the status gauge reports an active-skill count.

Tool surface 35 → 38. Also corrects the README MCP-surface list, which had drifted to 31 (missing the 0.17.0 read-only loop ops).

[0.17.0] — 2026-06-21

The empirical self-improvement loop. Adds the telemetry substrate + curator that let Clauderizer's memory improve itself under its own constitution — autonomous in cadence, supervised in mutation (propose-confirm, never auto-mutation; INVARIANT-05). Deterministic, stdlib-only, no ML (D-018). Suite 548 → 573.

Added

  • Memory telemetry (.clauderizer/telemetry.jsonl, append-only): which lessons/invariants a handoff surfaced (cz_write_handoff) and each phase's outcome + exit-criteria checked/total (cz_transition_phase). Never written from a hook (INVARIANT-06).
  • cz_corpus_health — active-lesson count, lexical-redundancy estimate, never-surfaced count, pass-rate (read-only).
  • cz_lesson_health — per-lesson utility (recent-success fraction), failure-risk, recency, and an advisory signal (read-only).
  • cz_curate — proposes consolidate/obsolete/flag/promote with evidence + the blessed cz_* op to apply each (propose-only, like cz_mine_failures).
  • cz_loop_step — one loop-gameplan iteration: convergence metric + proposals + a converged flag + a spawn-driven-gameplan escape hatch.
  • Loop gameplans (cz_create_gameplan(kind="loop")) — a first-class standing, iterative maintenance type; GAMEPLAN-PROCEDURE.md → v1.3.0.
  • Empirical-gated promotion (recurrence + correlation) + typed edge suggestions (redundant/related) + a preemptive-risk cascade for shaky upstream entities.

Tool surface 31 → 35. All new analysis ops are read-only and advisory (INVARIANT-05).

[0.16.0] — 2026-06-21

Universal host support — the cross-host & cross-model substrate. Generalizes Clauderizer beyond Claude Code + kimi to ~11 agentic coding hosts via the AGENTS.md + MCP substrate, without regressing Claude Code parity (INVARIANT-07). Design + verified capability matrix in docs/CROSS-HOST.md. Still Development Status :: 4 - Beta. Suite 446 → 548.

Added

  • Host-target axis & injection ladder. New host_target config axis (D-028) and the injection-parity ladder (Tier-1 hook → Tier-3 MCP prompt → Tier-4 AGENTS.md floor; Tier-2 retired, D-034). In-memory at-most-once delivery signal (INVARIANT-08) + write-first self-correction; session.best_tier().
  • Host-neutral floor. The shared stanza no longer assumes a SessionStart hook; it tells hook-less hosts to call cz_status first (P2).
  • MCP prompts. cz-status / cz-next-phase surface as slash commands on prompt-capable hosts (Cursor, Copilot, Continue, Gemini, Zed).
  • Per-host wiring emitters (hosttargets.py): non-destructive, portable (uvx) MCP registration for Cursor/Copilot/Continue/Zed/Gemini/Cline/Amp; native-instructions floor for Continue & Gemini; hook setup guides for hook-capable hosts; guide-only for TOML/global (Codex/Windsurf/kimi). Wiring-contract verification + path-safety audit (D-032).
  • Server-side session bootstrap (P7): the MCP server attaches a compact status note to the first non-status tool result on a hook-less host, in a separate clauderizer_status field (never corrupting the tool's own result, D-027), deduped via the P1 signal.
  • clauderize init --host <name> + --list-hosts (P8): finally wires the emitters through the user-facing command — sets host_target, branches init (claude-code byte-identical per INVARIANT-07; other hosts get their MCP config + AGENTS.md floor + hook/MCP setup guides), cheap auto-detection, a friendly error listing valid hosts. clauderize uninstall now reverses the full footprint (MCP keys + hooks + marker stanzas + skills + .clauderizer/), --host scopes to one; docs/ always preserved.
  • doctor is host-aware — verifies the CONFIGURED host's wiring, not just Claude Code, and names the right repair (init --host <name>) when host_target was stripped.

Hardened (P9–P13)

  • The dogfood .mcp.json/.claude/settings.json and any machine-specific committable wiring are gitignored, not leaked (O-06, H-11); cross-host hook event names (windsurf pre_user_prompt, amp agent.start, …) routed correctly; a corrupt config.toml degrades to a clean ConfigError instead of crashing the CLI; an op↔engine signature guard (O-08); uninstall is symlink-safe (H-12). Independent seam + security reviews.
  • Config round-trip preserves unmodeled fields. Config.load/to_toml capture and re-emit any keys/sections the engine doesn't model, so a config rewrite (init, the active-gameplan flip, or an older engine) never silently drops a field — closing the host_target-strip class found in real-host testing.

Verified

  • Wiring contract (every auto-write host's emitted config is well-formed, path-safe, and launches clauderizer-mcp) — in CI for all auto-write hosts.
  • Real-host consumption — confirmed on 2 real hosts: Cursor (Remote-WSL; the prompts surface as slash commands) and VS Code / Copilot, both reading the clauderize-emitted config.
  • Cross-model — Cursor's Composer 2.5 Fast (a non-Claude model) drove a full gameplan end-to-end; adherence findings recorded — it leaned on the clauderize ops CLI fallback (validating L-05) and also hand-edited tracked docs, which drove the doctor + config preservation fixes above. Per-host consumption beyond these two remains a manual spot-check.
  • Dropped from scope: Roo Code (repo archived 2026-05-15), Aider (no native MCP client yet).

[0.15.0] — 2026-06-21

Empirical memory gains (Beta 2). A gain-gated initiative: every feature was proven against a deterministic + agent-eval harness or parked. Test suite 400 → 446; no breaking changes; still Development Status :: 4 - Beta.

Added

  • Focused handoff lessons. The cumulative handoff now carries the top-k project lessons most relevant to the phase (ranked, front-loaded) plus a pointer to the canonical full set in docs/LESSONS.md, instead of dumping all of them. Measured: handoff −55% tokens at equal agent-eval accuracy (focused 5/6 = full 5/6), ranker recall@5 = 100%. Relevance-focus + pointer-to-canonical, never truncation.
  • DAG integrity validation (graph/validate.py) — deterministic dangling-edge + cycle (iterative Tarjan SCC) detection over the project DAG, surfaced advisorily via the status drift channel. Closes a gap where pin_violations skipped unknown targets, so dangling depends_on edges went silently undetected. 100% detection, 0 false positives on the fixture battery.
  • Edge-suggester. cz_analyze now surfaces plausibly-missing depends_on edges from distinctive-token overlap (the structural complement of the D-018 existing-edge walk), agent-confirmed, with a markdown-canonical rejected-pair memory (not_related_to frontmatter). Precision 0.75 on a labeled fixture; advisory only.
  • Decision supersession lifecycle. cz_add_decision(supersedes=…) now writes a bidirectional Superseded by back-ref, a Status field (active/superseded/deprecated), and dates; analyze demotes superseded decisions below their replacement via a secondary sort key (lexical score untouched). Stale-fact contradiction rate 1.0 → 0.0. Append-only (annotated, never deleted).
  • Focused governing-invariant surfacing. The handoff now surfaces the top-k phase-relevant invariants (the must-hold rules), focused — never an always-all dump.
  • Memory-eval harness (tests/benchmarks/) — deterministic metrics (recall@k, nDCG, MRR, contradiction, abstention, token estimate, DAG validity) plus a focused-vs-full agent-eval; the gain-gate the above were measured against.

Changed

  • docs/LESSONS.md re-distilled. Nine overlapping project lessons consolidated into four syntheses (L-22–L-25), gated on a coverage proof (every original concept still retrievable in the ranker top-k): 21 → 16 active, rollup −20%, append-only (sources marked obsolete, never deleted).

[0.14.2] — 2026-06-20

Windows lock robustness (H-10). locking._release_file now retries the unlink before falling back to stale takeover, so a finished writer can't orphan its own lock when Windows raises a sharing violation while another process is mid-read of the lock file. Previously the orphaned lock left a second writer waiting up to ~30s for stale takeover and surfacing a spurious (retryable) LockHeld. POSIX is unaffected (unlink succeeds on open files). This fixes the flaky test_concurrent_writer_processes_lose_nothing on Windows CI cells at the source; a deterministic regression test (test_release_retries_unlink_past_transient_oserror) pins the retry. No API or behavior change on the happy path.

[0.14.1] — 2026-06-20

Documentation accuracy pass. No behavior change — the engine is identical to 0.14.0 apart from one docstring. This release ships the corrected README (the PyPI long-description) and a repo-wide docs overhaul.

Fixed (drift)

  • README MCP surface now lists all 31 tools (was 24): the discipline-gate and analysis tools added in 0.11.0–0.13.0 (cz_add_open_item / cz_resolve_open_item, cz_set_exit_criteria / cz_check_exit_criterion, cz_analyze, cz_critique, cz_mine_failures) were missing. standard pre-flight corrected to 8 checks (handoff_presence); release-check added to the CLI reference.
  • The 0.14.0 lifecycle additions (the UserPromptSubmit hook, the AGENTS.md stanza, .clauderizer/kimi-setup.md) are now reflected in the stranger docs — docs/TRUST.md (what init writes / what executes), SECURITY.md, and, most consequentially, docs/UPGRADING.md, whose uninstall script now removes the UserPromptSubmit hook and the AGENTS.md stanza instead of leaving them behind.
  • docs/ARCHITECTURE.md gate provenance (adds D-018); the preflight.py docstring no longer hardcodes "7-check".

Added (docs)

  • All seven docs/subsystems/*.md bodies written (graph, markdown-core, mcp-server, mutations, profiles, rituals, scaffold) — previously stubs that ARCHITECTURE.md delegates prose to — plus docs/VISION.md, docs/features/init-cli.md, and a real docs/TESTING.md (baseline 403 tests).
  • L-21 (project lesson): reference docs drift together on a hook-taxonomy or tool-surface change — sweep the README MCP surface and TRUST/UPGRADING/SECURITY together; append-only history records the old counts on purpose.

[0.14.0] — 2026-06-19

kimi-code lifecycle integration (gameplan 2026-06-19-kimi-lifecycle-integration): Clauderizer's durable memory now surfaces at more lifecycle points than cold start, and init can target AGENTS.md-aware hosts (kimi-code, Codex) — adapting the hook taxonomy that kimi-code and Claude Code share. Everything new is read-only and exits 0 (INVARIANT-06), with no enable/disable flag (INVARIANT-05); the core stays stdlib-only.

Added — an event-dispatching hook (D-025)

  • clauderizer-hook now dispatches on hook_event_name (read from stdin) to read-only handlers, falling back to the SessionStart digest on empty/garbage/non- object stdin — the exact shape the hardened no-arg digest probe sends, so the H-08/H-09 legs are untouched. --version/--help still answer the identity probe before any stdin or repo read. New handlers:
    • UserPromptSubmit runs the analyze gate (D-016/D-018) against the prompt and surfaces the most relevant recorded decisions/invariants + one-hop graph gaps — a pointer into canonical memory (D-013), silent when nothing is relevant.
    • PreCompact reminds the agent to record anything discovered-but-unsaved before context is summarized; PostCompact re-injects the digest so the workflow survives compaction (the kimi path — Claude Code instead re-fires SessionStart with source=compact, D1).
    • SessionStart is now source-aware (frames a post-compaction / post-clear re-entry). sessionstart.py became a back-compat shim; the entry point now targets clauderizer.hook.dispatch:main.

Added — Claude Code wiring of the new events

  • clauderize init registers UserPromptSubmit alongside SessionStart (same wrapper command), idempotently, preserving foreign hooks per event and migrating the pre-0.14 SessionStart-only shape. PreCompact/PostCompact are deliberately not registered on Claude Code — it drops their stdout (D1).

Added — AGENTS.md stanza + a non-destructive kimi host target (D2)

  • init injects the same Clauderizer stanza into AGENTS.md (one source, so it cannot drift from CLAUDE.md), so kimi-code (KIMI_AGENTS_MD) and other AGENTS.md-aware harnesses get the memory pointer. Clauderizer's skills already work in kimi-code, which reads .claude/skills/.
  • init emits .clauderizer/kimi-setup.md — a non-destructive guide with [[hooks]] entries for all four events (kimi-code injects every hook's stdout) and MCP-registration guidance. It never edits the global ~/.kimi/config.toml. subsys.scaffold 0.6.0 → 0.7.0.

Notes

  • New project decision D-025 and INVARIANT-06 (every hook handler is read-only and exits 0, generalizing INVARIANT-04 to all events). kimi-code's MCP-server TOML schema is undocumented upstream (tracked as gameplan open item O-01), so the kimi MCP step is guided rather than auto-wired.

[0.13.0] — 2026-06-19

Headroom-borrowed ideas (gameplan 2026-06-19-headroom-borrowed-ideas): three ideas adapted from the Headroom project (chopratejas/headroom) were each tested as a falsifiable hypothesis with a machine-checkable keep/discard metric — two kept, two discarded. The core stays stdlib-only, deterministic, no ML (D-014/D-018).

Added — relevance-ranked lesson pointers in the handoff (idea #2a, D-021)

  • The handoff now surfaces a "Most Relevant Lessons for This Phase" block — the top-k lessons ranked by the existing keyword + entity-id ranker (analyze.rank_relevant, no ML) against the current phase's breakdown, placed ABOVE the unchanged cumulative list and only when active lessons exceed k (=5). It reorders nothing and drops nothing — a pointer into canonical memory (D-013), so every lesson still propagates (D-009 + the incomplete-propagation anti-pattern). subsys.rituals 0.6.0 → 0.7.0.

Added — cz_mine_failures, a failure-miner (idea #3, D-023)

  • cz_mine_failures scans Claude Code session transcripts (JSONL) for failure→fix patterns — a tool error then a same-tool success, a pytest fail→pass, or a short explicit user correction — and PROPOSES draft cz_add_correction / cz_add_lesson entries for the agent to confirm. Read-only, deterministic, stdlib-only; invoked, never auto-firing, no enable/disable flag (D-015/INVARIANT-05). is_error is unreliable for shell failures, so errors are detected by content signatures; benign search-tool errors and tool-protocol hiccups are denied to protect precision (~80% on a labeled sample of real transcripts). subsys.mcp-server 0.4.1 → 0.5.0.

Evaluated and discarded (with evidence)

  • Prefix-stabilizing the SessionStart digest (idea #1, à la Headroom CacheAligner) — DISCARD (D-020). The reorder lifts the stable-prefix proxy 65→786 chars, but the digest is only ~888 chars (~222 tok), is rendered once per session, and stable-first ordering buries the actionable state — a negligible, unobservable gain for a real readability cost.
  • Truncating the cumulative lessons tail (idea #2b) — DISCARD (D-022). Reintroduces incomplete-propagation for marginal savings; cz_consolidate_lessons is the safe size lever.

Hardened (post-close verification)

  • A second, independent adversarial pass on the miner fixed three crash vectors reachable via cz_mine_failures on real transcripts — non-UTF-8 bytes (UnicodeDecodeError), an unhashable tool_use_id, and a non-str text block (TypeError) — by extending tolerance past JSON validity to shape validity (open(..., errors="replace"), isinstance guards, a per-file net in mine_dir). Also one precision fix: [1-9]\d* failed (not \d+), so a clean "0 failed" run is no longer mined as a failure — 3 fewer false positives on the real corpus (C-01, C-02).
  • New handoff_presence preflight check — cz_preflight now blocks when the phase table implies a handoff should exist (phase 0, or any phase whose predecessor is COMPLETE) but the file is absent on disk — so a gameplan can no longer close with dangling handoff links undetected. The failure message spells out the recovery: reply regenerate to rebuild each from the graph via cz_write_handoff (lossless — a handoff is derived state), or waive once. Configurable: list it in preflight_advisory to downgrade to a warning for intentionally single-session gameplans. Suite → 352 passed, 4 skipped.

[0.12.0] — 2026-06-18

STORM-inspired curation (D-017): methods from Stanford OVAL's STORM/Co-STORM, imported as deterministic engine-surfacing + skill guidance — never as runtime dependencies (the core stays stdlib-only; the agent reasons, the engine surfaces).

Added — the analyze-gate gap-finder (D-018)

  • cz_analyze now surfaces an adjacent set — Co-STORM's "moderator" move. After ranking the most-relevant decisions/invariants (contradiction-judgment), it walks the project graph ONE hop from what the text touches — entities named in the text, plus entities introduced_by a surfaced decision (the only structural link from a flat-doc ADR into the graph) — and surfaces the neighbors nothing has connected to the text yet: gaps, not contradictions. Structural, not semantic — no embeddings, no new dependency (the complement to D-013's optional semantic recall); empty when nothing in the graph relates (an honest negative). Reaches the agent through both the MCP tool and clauderize ops; the prompt now invites gap-judgment alongside contradiction/supersession-judgment.

Added — provenance on lessons and decisions (STORM citations)

  • cz_add_lesson and cz_add_decision accept an optional evidence citing the concrete provenance behind the entry (commit, file:line, phase, benchmark, doc). Lessons render it inline as *(evidence: …)* — placed so the lesson-state grammar never misreads it — so it rides into every handoff rollup; decisions render an Evidence field. Additive and backward-compatible (omitted ⇒ byte-identical output to today); the MCP tool schema auto-derives the new param from the function signature.

Added — the self-critique gate (D-019)

  • cz_critique — a reference-free, advisory rubric over a target (a phase, the gameplan, or a handoff). It composes the deterministic signals the engine already computes into three dimensions — Coverage (unresolved open items, unchecked exit criteria, incomplete phases), Coherence (graph drift, pending cascades), Grounding (lessons lacking provenance) — and surfaces them with a grading prompt for the agent. STORM grades drafts with a reference-free LLM-judge rubric; adapted to the surface-don't-decide law, the engine assembles the gaps and the agent grades — it never scores or blocks (INVARIANT-05). Stdlib only, no embeddings; reachable via MCP and clauderize ops.

Changed — perspective-guided planning (skill)

  • The clauderizer-new-gameplan skill now interrogates a goal from multiple named perspectives (security, performance, ops/release, testing, cost, failure-modes, prerequisite-chains) before phases are drafted — STORM's perspective-guided question asking — run as a cheap fan-out (a faster model per lens, the strong model for synthesis), with findings routed into decisions, phases, and tracked open items, and the goal vetted via cz_analyze's gap-finder. It now also derives lenses from related graph entities (cz_graph_query), not only the fixed list; and the close-gameplan (post-mortem) and do-phase (handoff) skills gained an outline-before-synthesize step for long-form writing.

Suite 289 → 304. Still deferred, each tracked as an open item: the Co-STORM hierarchical lesson "mind map" (changes the lesson data model), the consecutive-same-intent staleness counter (noise risk), and the mind-map's deterministic graph cleanup (singleton-collapse may be unsafe on a retention graph) — see the storm-self-critique-gate gameplan (O-01/O-02).

[0.11.0] — 2026-06-18

Three spec-kit-inspired discipline gates — clarify, exit-criteria, analyze — land as five new tools (24 → 29), all advisory, judgment-based, and config-free. Borrowed from GitHub's spec-kit and adapted to Clauderizer's grain (the engine surfaces, the agent rules — never a hard block).

Added — discipline gates (D-015 / D-016 / INVARIANT-05)

Three gates that surface findings in the tool result for the agent to rule on — they never hard-block a mutation/phase transition and add no config flags. The model is cz_cascade's: the engine finds and reports; it does not decide.

  • Clarify gate — cz_add_open_item / cz_resolve_open_item: auto-numbered O-NN open items in a gameplan's "Open Items"; cz_status reports the unresolved ones, and cz_transition_phase→complete surfaces those relevant to the phase (tagged to it, or untagged).
  • Exit-criteria gate — cz_set_exit_criteria / cz_check_exit_criterion: a phase's - [ ] exit criteria become machine-checkable; completing a phase surfaces the unchecked ones, with test-ish criteria auto-linked to the measured baseline test count (scaffold placeholders are ignored).
  • Analyze gate — cz_analyze surfaces the existing decisions/invariants most relevant (lexical: keyword + entity-id overlap — no new dependency) to a piece of text, for the agent to judge contradiction/supersession; cz_add_decision now enriches its result with related/possibly-superseded entries.
  • Tool surface 24 → 29; every gate tool is reachable via both MCP and clauderize ops (registry parity enforced). Suite 270 → 289.

[0.10.0] — 2026-06-10

Beta. Development Status :: 4 - Beta — the flip itself is beta gate B6 (D-012), shipped via the release ritual with B1–B5 already satisfied by dated artifacts (docs/RELEASING.md carries the evidence table). This release bundles the alpha-to-beta-evidence, stranger-readiness, and beta-flip burn-down work: the suite runs — and passes — on machines and repos that are not the author's; a stranger can adopt, upgrade, trust, debug, and remove Clauderizer from the published docs alone; and the codebase now carries structural guards for the failure classes that earned the gates. Suite 255 → 270.

Added (beta-flip burn-down)

  • The bare-IO tripwire (tests/test_io_discipline.py): no text-mode read_text/write_text/open without encoding= anywhere in src or tests — it caught three stragglers on its first sweep. Same class: subprocess output decoding pinned to utf-8 in preflight's runner and release-check's git wrapper (win32 locale decode could mojibake or raise).
  • Engine-staleness nudge: cz_status from a long-lived MCP server now warns when the engine source on disk is newer than the running process — "restart the session, or use clauderize ops (fresh process) for writes."
  • release-check: "README names the ritual" — a README whose release section never mentions clauderize release-check fails staging (the G7-drift-between-sibling-docs tripwire).

Fixed (stranger-readiness)

  • The quickstart command — uvx clauderize init resolved no such package (uvx derives the package from the command name); every occurrence is now uvx --from clauderizer clauderize init, and the README carries a zero-install note for bare clauderize commands.
  • init no longer wires uvx ephemeral-cache paths. Run via uvx, init used to register console scripts from uv's cache — uv cache clean then killed the MCP registration and every digest until a re-init. Resolution now refuses cache-resident paths (_under_uv_cache) and wires the durable absolutized uvx -q --from clauderizer … form, which survives cache cleans by re-resolving on demand. The -q matters on its own: cold-cache uv progress noise used to ride the hook wrapper's stderr-rerouting into session context — in front of the --version identity line probes parse.

Added (stranger-readiness)

  • The stranger docs, all executable rather than aspirational: docs/UPGRADING.md (upgrades are two moves; the five-step uninstall keeps docs/ — walked live, both doctor nudges verified verbatim), docs/TRUST.md (what init writes, what executes when, the cloned-repo scenario, supply chain — every claim cites grep-verified code), SECURITY.md, and docs/TROUBLESHOOTING.md (the "no digest" ladder, the breadcrumb decoder, doctor's exit contract — every quoted string verified against src).
  • quickstart.yml — the README's exact install path executed against the PUBLISHED package on a clean runner, every push plus weekly, with a doc-drift grep and a self-arming cache-clean assertion.
  • README repositioned: "Git-native working memory for coding agents", the adoption wedge, a "Maturity: alpha, with receipts" section linking the public beta gates, absolute doc links, and a maintainers' release section that now follows the ritual it used to contradict.

Earlier in the same arc (alpha-to-beta-evidence, B1–B4):

Fixed

  • win32, found by executing the platform instead of monkeypatching it: init resolves win32 console scripts (clauderizer-*.exe) beside the interpreter; the generated wrappers are written with byte-exact newlines (text-mode IO corrupted hook.cmd to \r\r\n and broke init idempotency on win32; hook.sh written from a win32 host now stays \n — the distro's sh chokes on \r); doctor's wrapper-freshness compare reads bytes (universal-newline normalization made a healthy win32 wrapper read permanently stale); doctor resolves distro-spelled wrapper registrations (/home/… or /C:/…) to the repo-local file instead of failing the presence check.
  • Unborn-branch diagnosis (found by the node-profile live loop): a fresh git init with zero commits — the first state a brand-new adopter runs preflight in — no longer reads as "not a git repo"; branch checks now discriminate via rev-parse --is-inside-work-tree and report an honest "no commits yet (unborn branch)" skip.

Added

  • CI proves the OS matrix (B2): tests run on ubuntu, macos, AND windows runners × py3.11–3.13, with the native win32 cmd wrapper EXECUTED on real Windows (live tests: digest passthrough, dead-engine breadcrumb, unreachable-repo breadcrumb, hostile-cwd cd /d anchor).
  • .gitattributes (eol=lf) — newlines are content (L-01); autocrlf runners no longer rewrite fixtures.
  • Beta gates B1–B6 in docs/RELEASING.md (D-012) with a dated evidence table; B1–B4 satisfied.

Infrastructure

  • Both workflows bumped off deprecated Node-20 actions (checkout@v5, setup-uv@v6, upload/download-artifact@v5).

[0.9.0] — 2026-06-10

The harness-truth-and-release-ritual work: every claim the system makes about its own wiring is now backed by a leg something actually traversed, and the release ritual is a checked command instead of a remembered procedure. Closes H-08 and H-09 — the findings tracker is all-resolved through H-09. Suite 215 → 255.

Fixed

  • H-08 — the SessionStart digest survives the Windows harness. The registered command uses //-led paths (shape C, D2): wsl.exe -d <distro> //bin/sh //<repo>/.clauderizer/hook.sh. Git Bash's MSYS2 conversion skips //-led arguments as UNC-form, Linux collapses // to /, and the shape carries zero quote surface so cmd.exe and PowerShell pass it verbatim (evidence artifact: scripts/wiring_matrix.ps1, hostile-cwd by default; shape A sh -c 'exec …' is the documented fallback). Restart-validated in-band: the first real cold start after the rewire delivered the digest (transcript hook_success attachment — shape C verbatim, exit 0, 388ms).
  • H-09 — the digest no longer depends on the executor's working directory. The generated wrapper anchors itself (cd '<repo>') before delegating and reports an unreachable repo as a stdout breadcrumb instead of silence (cmd.exe structurally cannot hold a UNC cwd; any harness may spawn hooks from a fixed directory).

Added

  • Doctor traverses the consumer leg (D-010). For windows-wsl hosts the SessionStart verdict now spawns the registered command STRING through the harness's executor (Git Bash, when reachable) from a non-repo cwd, with paired probes — --version for engine identity (it answers before repo discovery, so it is anchor-blind) plus the no-arg digest for the H-09 anchor — and names the traversed leg in its claim. Executor unreachable → honest "unverifiable" (exit 3), never green. The old direct-argv probe stayed green through the entire H-08 outage; a live regression test pins that exact false green.
  • clauderize release-check (O3/D-011) — push-then-release ordering (origin/ == HEAD via ls-remote) and the four version registries (local tags, remote tags, GitHub Releases, PyPI queried directly — never uvx cache) checked as a command (exit 0/2/3), plus the publish.yml tag==source gate marker. Every skew shape that double-claimed 0.7.0/0.8.0 is individually proven to fire in tests.
  • docs/RELEASING.md — the mechanical release ritual (release-check exit 0 as the hard precondition) and the seven 1.0 readiness gates (G1–G7).
  • [memory] config (O1/O2) — active_lessons_warn (default 12) and project_lessons_warn (default 20): the memory-bloat nudges move from hardcoded constants to config; the status digest's gauge reads them.
  • init's registered-hook spawn-test is the hostile-cwd digest probe — an un-anchored wrapper can no longer register (it would be silent exactly the way the real executor chain made it).

[0.8.0] — 2026-06-10

The agent-autonomy release: the recording machinery now works — and fails — out loud, from any host, under any concurrency, with or without MCP. Every change closes a named finding from the 0.6.0 live tests (H-05, L-05, H-04, H-01 residue, the stale-uvx thread).

Added

  • Advisory write lock (.clauderizer/write.lock) — every tracked write serializes at the mutation choke point: O_EXCL acquire with holder metadata, stale takeover (~30s), clear retryable LockHeld error naming the holder. N concurrent writer processes now yield N sequential IDs and N surviving appends (closes H-05). Reads stay lock-free.
  • clauderize ops <file.json|-> — CLI write parity: a JSON batch of [{op, args}, ...] executes against the same registry the MCP server dispatches; op names and schemas are exactly the cz_* tool names. Every tracked write is now reachable without an MCP client (closes L-05); the ad-hoc shim patterns are retired.
  • Session host of record — config records which host spawns sessions (native | windows-wsl:<distro>); init composes host-appropriate wiring (wsl.exe shim, command/args split) and spawn-tests every command before writing (refuses the H-04 clauderize clauderizer-mcp mis-composition with nothing written); doctor verifies launchability for the recorded host or honestly reports "unverifiable from this host" (exit 3 — never a false green). Closes H-04.
  • Cold-start breadcrumb wrapper — init registers a thin always-spawns wrapper (.clauderizer/hook.sh, hook.cmd on native win32) as the SessionStart command; any engine failure becomes a stdout breadcrumb ([Clauderizer] engine unreachable: … — run clauderize doctor) instead of silence (closes H-01's residue). Doctor checks wrapper presence and freshness against the engine path.
  • Wiring identity verification (D5) — doctor's round-trip launch checks now require the wiring to identify its engine: the probed --version output must claim the same version as the engine answering doctor. Catches pinned-stale wiring that launches fine (a uvx --from clauderizer[mcp]==0.5.0 pin passes every exit-code probe — demonstrated live, recorded as H-06) and a dead engine behind the always-exit-0 hook wrapper (whose breadcrumb previously read as a green hook verdict).

Fixed

  • cz_add_amendment dangling cascade pointer — amendment entries cited _cascade-reports/<date>-A-NNN.md, a per-amendment filename no code path creates under any setting. The Cascade report line now renders only when the amendments ritual is enabled, and as an honest pending pointer (cascade reports are per-entity files). A-001 in the 0.6.0 gameplan healed to cite the per-entity report that actually holds its cascade evidence. Procedure 1.2.0 → 1.2.1 documents the conditional line.

Infrastructure

  • publish.yml refuses tag/version skew (H-07) — the release workflow now fails fast when the Release tag and the tagged tree's pyproject.toml version disagree, instead of building the wrong artifacts and dying as a PyPI duplicate that nothing on the Releases page surfaces.

Known issues

  • H-08 (open) — on Windows-harness hosts the SessionStart digest never reaches session context: the harness executes hook commands through Git Bash, whose MSYS2 path conversion rewrites the shim's /bin/sh argument to a nonexistent C:/Program Files/Git/usr/bin/sh (exit 127 below the wrapper, so no breadcrumb either). Engine, wrapper, and doctor are green when invoked directly; the wiring fix (an MSYS-conversion-immune command shape) is scheduled for the next gameplan. See docs/HARDENING.md H-08.

[0.7.0] — 2026-06-09 (version retired — never published)

A v0.7.0 GitHub Release was cut from a commit whose source still declared 0.6.0; its PyPI publish failed as a duplicate, so no installable 0.7.0 exists anywhere (H-07). The work intended for this number ships as 0.8.0; the workflow gate above makes that failure shape impossible to repeat silently.

[0.6.0] — 2026-06-09

Closes the engine-robustness cluster from the two prior post-mortems plus the cold-start findings H-01..H-03. The through-line is structure over substrings: every defect came from the engine writing or reading markdown by line/substring heuristics — tables appended as paragraphs, IDs counted in prose, lesson state inferred from anywhere-in-line markers.

Added

  • cz_add_output — blessed write for the PHASE-STATUS Outputs Registry (per-phase fenced blocks; same-key upserts rewrite in place). The registry had sat at its scaffold placeholder through two closed gameplans for want of this write.
  • cz_add_phase_summary — blessed write for the index's Per-Phase Completion Summaries (one block per phase; re-recording replaces it).
  • Tracker header write-backs — cz_transition_phase / cz_add_phase now refresh > Status: / > Last updated: on both trackers and GAMEPLAN.md's Status (Planning → Executing → Complete) from the live phase table. Both closed gameplans had read "Phase 0 ready" since the day they finished.
  • doctor engine-identity checks — installed dist-info must match the running source __version__ (caught live: an editable install reporting 0.3.0 under 0.5.0 source), and when the repo is the clauderizer source, the running engine must match the repo's pyproject version (stale uvx/pipx cache while dogfooding).
  • CLI fallback breadcrumb — the CLAUDE.md stanza now says what to do when the cz_* tools are absent: clauderize doctor / clauderize status (a cold session previously couldn't tell broken wiring from no Clauderizer).

Changed

  • Anchored ID numbering — next_numbered_id counts only entry anchors (### <ID> — headings, **<ID>.** bold entries). Scaffold placeholder prose and cross-references no longer shift sequences (one gameplan's decisions had numbered D3..D9, skipping D6, because template prose and a citation of another gameplan's D6 were counted).
  • Structural table writes — tracker phase rows go through a table-aware writer (markdown/tables.py) that rebuilds the block contiguously on every blessed touch; trackers fractured by the old paragraph-append healed in place, no migration script. Rendered markdown is valid for humans again, not just for the engine's own tolerant parser.
  • Collision-proof cascade reports — filenames carry a zero-padded -NN sequence per date+entity (never timestamps), so same-day cascades of one entity coexist instead of silently overwriting; pending_cascades orders chronologically (legacy unsuffixed names rank as sequence 0).
  • Lesson state is a grammar, not a substring — one parser (markdown/lesson_state.py) reads the trailing (obsolete …) / (promoted …) markers (or legacy ~~strikethrough~~); the gauge, handoff roll-ups, and obsolete/promote/consolidate all share it. A lesson whose text mentions "(obsolete" counts as active everywhere.
  • Preflight runs profile commands in the engine's own environment — the running interpreter's bin dir leads PATH, so a venv-installed engine finds its own pytest/ruff without shell activation (pytest: not found observed live on a venv-wired engine).
  • A completed gameplan's digest says (handoff n/a: gameplan complete) instead of silently dropping the promised size estimate.

[0.5.0] — 2026-06-09

Closes review finding 5 (context economics): cumulative memory grew monotonically — handoffs carried every lesson forever, lessons died with their gameplan at close, and nothing measured the bundle. Per ADR D-009 the answer is consolidation pressure, never caps: three blessed writes plus visibility, with the audit trail intact.

Added

  • cz_consolidate_lessons — synthesize N overlapping lessons into one; each source is marked (obsolete: consolidated into #N) and every future handoff carries one line instead of many. All sources validated before anything is written.
  • cz_promote_lesson — promote an enduring lesson into a compact, on-demand docs/LESSONS.md as an L-NN entry with provenance; the source is marked (promoted <date>: L-NN) and stops rolling up individually. Handoffs gain a "Project Lessons (distilled)" section that rides across gameplans — lessons finally outlive the gameplan that learned them.
  • Memory gauge — cz_status / the SessionStart digest report Memory: N active lessons, M project (~K tok handoff) and nudge toward consolidate/promote/obsolete past ACTIVE_LESSONS_WARN (12, a documented constant). Bloat is a visible state, not a silent failure mode.
  • cz_obsolete_lesson accepts L-NN ids, so the project list is curated with the same rules (its number parameter is now a string).
  • Close-gameplan skill: a lesson-curation step (consolidate, then promote deliberately — not in bulk); do-phase nudges consolidation when the list repeats itself.

[0.4.0] — 2026-06-09

Closes the discipline seams from the 2026-06-09 external review: the places where the workflow still depended on agents hand-editing tracked docs because the blessed write was missing, destructive, or never ran.

Added

  • cz_resolve_cascade — record per-dependent verdicts + the Updates applied/deferred sections on a cascade report. Previously, clearing the cascade_hygiene preflight check required a forbidden hand-edit — the rules banned the only way to make progress. Defaults to the latest pending report; partial resolution keeps it pending (status_bundle.pending_cascades is now the public, shared predicate).
  • cz_obsolete_lesson — mark an accumulated lesson (obsolete <date>: <reason>) through a tool. The line stays in the log (append-only memory); handoff roll-ups stop carrying it, so cumulative handoffs can shrink without a hand-edit.
  • Baseline write-back — a green cz_preflight run that measures a test count now refreshes the active gameplan's "Current baseline test count" line (anti-pattern #7, stale references, applied to the system itself: this repo's own hook said "0 tests" while 84 passed).
  • Completed-gameplan status — a gameplan whose phases are all complete now reports "all N phase(s) COMPLETE" with close-out guidance instead of the confusing "no in-progress or ready phase found".
  • doctor: lock-file check — flags a profile.lock.toml that doesn't parse (whose overrides were being silently ignored).

Changed

  • Marker-protected handoffs (D-008) — cz_write_handoff owns only a <!-- clauderizer:handoff --> marker block; regeneration replaces the block and preserves everything outside it byte-for-byte. Fresh handoffs add an agent-owned "Phase Notes" scaffold; legacy generated skeletons are migrated wholesale; unrecognized files are preserved verbatim below the block. cz_next_phase_context returns the merged view, so a context fetch includes on-disk enrichment.
  • Skills no longer instruct hand-edits anywhere: cascade/do-phase route through cz_resolve_cascade, record routes risks through cz_add_finding.

Fixed

  • Profile.to_lock_toml emitted invalid TOML for profiles whose baseline regex contains backslashes (e.g. python's (\d+) passed) — and since load_for_repo falls back silently on parse errors, every python-profile lock written by init was being ignored in its entirety. Lock values are now TOML-escaped, with a round-trip regression test across all packaged profiles.

[0.3.0] — 2026-06-05

Fixes the state-mutation surface — the gaps a second dogfooding session found where structured state drifted because the blessed write was missing or destructive.

Added

  • cz_transition_phase — phases finally get a lifecycle write (not_started/ready/in_progress/complete/blocked/failed, with aliases + auto-dated Started/Completed). Without it, cz_status froze at "Phase 0" on finished work because nothing could advance a phase. The single highest-leverage fix.
  • cz_resolve_finding — update a finding's status + dated resolution note in HARDENING.md, satisfying its own "mark resolved, never delete" policy through a blessed path instead of a forbidden hand-edit.
  • Drift hint — cz_status / the SessionStart digest now flag entities still planned while phases are complete ("⚠ Drift: … cz_transition_status to reconcile"). Conservative: fires only when there's completed work and untouched entities.
  • init --workflow {code,docs,audit} + preflight_advisory config — makes clean_tree (and, for audits, tests) advisory rather than fatal, so a deliverable-accumulating workflow stops failing preflight on every resume.

Fixed

  • init resolves the engine command from the running interpreter's bin dir (sys.executable) before falling back to PATH/uvx — reliable for venv/WSL even when the bin dir isn't on PATH.
  • init no longer clobbers profile.lock.toml on re-run — per-project command overrides (read back by detect.load_for_repo) are preserved. Delete the lock to re-derive it.

[0.2.1] — 2026-06-05

Fixed

  • Require Python ≥ 3.11. The engine uses the stdlib tomllib, which only exists from 3.11, so 0.2.0 crashed on import under 3.10 despite advertising >=3.10. Corrected requires-python, classifiers, and the CI matrix. (Keeps the zero-runtime-dependency promise rather than pulling in a tomli backport.)

[0.2.0] — 2026-06-05

First release published to PyPI.

Packaging

  • Fixed the wheel build: removed a force-include table that collided with packages, which broke uv build / python -m build. The templates/, profiles/, and skills/ data dirs are bundled via packages and verified present in the wheel.
  • Core install is dependency-free; the MCP server is the clauderizer[mcp] extra.

Added

  • cz_add_finding / mutations.add_finding (alias add_risk) — record structured security/audit findings into the append-only HARDENING.md tracker.
  • doctor now probes that the MCP server and SessionStart hook commands are actually executable, not just registered — a green check on a non-launchable setup is worse than no check.
  • detect.load_for_repo() overlays a project-local profile.lock.toml, so per-project test/build/lint/typecheck overrides take effect (the lock was previously write-only).

Changed

  • init wiring now prefers installed console scripts (venv/pipx) and only falls back to uvx, fixing the Windows→WSL / venv drop-in path.
  • Re-running init with a changed invocation now replaces the SessionStart hook instead of appending a duplicate.
  • cz_next_phase_context is side-effect-free: it assembles the handoff in memory (handoff.assemble(..., write=False)) and returns it as handoff_md; only cz_write_handoff persists a file.
  • The first real entry in a doc section now replaces the scaffold _(…)_ placeholder instead of stacking beneath it.

Fixed

  • SessionStart hook errors print to stdout (visible in session context) instead of stderr, where silent failure was the dangerous kind.

[0.1.0] — 2026-05-30

Initial release. A drop-in, MCP-native successor to the markdown "gameplan system": same conceptual model (gameplan → phase → task, a long-lived Project DAG, post-hoc cascade, cumulative handoffs, append-only memory), delivered as an active system instead of a procedure followed by hand.

Added

  • Markdown core — zero-dependency frontmatter parser, section/marker editing, and a single idempotent mutation path (markdown/writer.py).
  • Project DAG — graph index (cached to a disposable index.json), dependent/ dependency queries, and semver pin-violation detection.
  • Cascade — post-hoc forward walk that writes a judgment-based report (dependents marked "needs review"). Replaces the never-built bin/cascade.
  • Rituals as operations — preflight (the 7 checks run for real against host profile commands), cumulative handoff assembly, and the status digest.
  • Structured mutations — decisions, invariants, lessons, corrections, gameplans, phases, amendments, entities, and status transitions (auto-cascade).
  • MCP server — 15 self-describing tools + resources over stdio (optional mcp extra).
  • Configurability — pet / standard / saas size dial and host-language profiles (Node, Python, Go, Ruby, generic) as pure data.
  • Drop-in — clauderize init (idempotent), status, doctor, reindex, mcp; a SessionStart hook for automatic cold-start; six Claude Code skills.
  • Test suite: 57 tests covering markdown round-trips, the graph, cascade, rituals, mutations, init idempotency, profiles, and the live MCP tools.