Commit Graph
209 Commits
Author SHA1 Message Date
bastien 4a450ea6bc feat(effort): five shifter skills, lib/effort-shift.md, model-gate second axis 2026-09-28 19:32:26 +02:00
bastien 94189adbc6 feat(effort): entry effort level on the 31 user-invoked skills (spec D3)
A/B /reconcile headless — BEFORE requests=18 output=12374 thinking=3135 effort={'high'} duration_ms=96518 / AFTER requests=15 output=9038 thinking=2248 effort={'low'} duration_ms=78410
2026-09-28 19:11:21 +02:00
bastien 9223fda99f feat(effort): pin effort on the 20 repo-authored agents (BDR-077 second axis) 2026-09-28 18:59:49 +02:00
bastien ddea411491 chore(config): superpowers citers by bare name, routing map, docs, settings
Every superpowers-prefixed skill call in ship-feature, init-project, tour,
deploy, audit-delta, plugin-advisor and lib/analyze-before-plan now names
the vendored skill directly. finishing-a-development-branch is described
as the upstream skill this config does not vendor (gitflow finish is the
integration path). CLAUDE.global.md Skill routing maps the four
non-vendored skills the vendored text still references. settings.json
loses the plugin key and its marketplace block; README, USAGE,
plugin-advisor and the profile skill describe superpowers as vendored
skills, always on, zero plugin cost. CHANGELOG entry with a known
residual.
2026-09-28 14:54:53 +02:00
bastien bd3e525bb3 feat(design-gate): ask for 21st login and wait instead of skipping
The design gate checked the 21st CLI with command -v only, so an
installed-but-signed-out CLI read as READY and every 21st step failed
downstream. tool_active now probes 21st whoami through a three-state
function: signed in (TWENTYFIRST_TOKEN or API_KEY_21ST set, or 'Logged in
as'), signed out (exact 'Not logged in'), unknown (rc != 0, timeout,
unexpected output). Signed out is a new verdict, SIGN-IN REQUIRED, exit
12: design-gate.md tells the orchestrator to ask the user to run
! 21st login, end the turn, re-run the gate on their reply, and to skip
21st only on an explicit 'proceed without 21st', never silently. Unknown
surfaces as exit 11 with the whoami diagnostic and a CLI-runtime remedy,
so a node/PATH failure can never loop on a sign-in prompt. INCOMPLETE
still wins. Hermetic suite lib/tests/design-tool-gate.test.sh (stub CLI,
fixture repo through DESIGN_GATE_REPO_OVERRIDE) covers every state.
2026-09-28 12:51:55 +02:00
bastien 4c86d6dc70 chore(config): security-guidance Stop review off, plugins off, routing and docs
settings.json: ENABLE_STOP_REVIEW=0 (the plugin's own switch: no more
Opus call on every turn that changes code, 0 findings in 6 days, 1
recorded false positive; the regex layer and the commit/push agentic
review stay on), brightdata-plugin@synced false (keyless-useless, its MCP
skill would hijack WebFetch/WebSearch), frontend-design official plugin
entry gone (uninstalled: byte-identical to the managed copy).

CLAUDE.global.md routes Ship/PR to ship-feature (gstack ship takes
origin/HEAD = main as base), drops ship/context-save from the gstack-off
list and 21st-ui-review from the design review line (trio is max-only).
deploy's table no longer points at land-and-deploy/setup-deploy.
plugin-advisor.md describes security-guidance's real mechanics. CHANGELOG
Unreleased entry with a Known residual section.
2026-09-28 11:49:01 +02:00
bastien f83f8f755b feat(profiles): prune the gstack catalog, add max, honor a removed denylist
Nine gstack skills leave every profile (ship is trunk-based on Gitea,
land-and-deploy auto-merges and deploys, setup-deploy, autoplan reads
paths that do not exist here, context-save has no restore, learn is an
unused parallel store, careful and guard hooks never fired, design-shotgun
needs an absent OpenAI key). lib/gstack-removed.sh is the single denylist;
profile.sh gstack on and toggle-external.sh enable gstack skip it.

full now carries everything every other profile carries (user rule), minus
the parked make-pdf, diagram and 21st-ai/ui-explore/ui-review, which live
in the new max profile together with pr-review-toolkit. The 21st trio also
leaves web, web-full and design (redundant with impeccable + ui-ux-pro-max).

lib/tests/profile-census.test.sh asserts the invariants live and on a
baseline fixture plus one mutant per invariant; gstack-removed.test.sh
covers both restore paths.
2026-09-28 11:48:44 +02:00
bastien ba14b5ea03 feat(skills): site-motion, site-level scroll and transition choreography
Personal skill distilling the MengTo motion pack invariants (LRN-141):
gates first (reduced motion renders final states, content visible without
JS, compositor-only, offscreen pause), one smooth-scroll engine with the
Lenis/ScrollTrigger sync, Astro ClientRouter lifecycle, numbered recipes
(reveal, scrub, sticky stack, video and image scrub, TreeWalker split,
progressive blur, marquee, WebGL budgets), upstream pitfalls, checklist.
Routed into the Build UI chain of CLAUDE.global.md and lib/design-gate.md.
2026-09-28 01:40:01 +02:00
bastien 0d035fcab6 feat(profile): default profile = full; reset applies it, current is label-driven
No profile selected (.active-profile absent, empty or legacy "none") now
means the `full` profile is in force: DEFAULT_PROFILE declared once in
lib/profile.sh, resolved by active_profile(); the statusline reads the
constant and shows `full` instead of `?`; `gstack off` trims to it instead
of erroring. `reset` goes to the default profile (= `set full`: enables its
list, parks any non-listed gstack or managed item). `current` names the
active label and scores that profile only, saying `default — not applied
yet` until a set/apply/reset wrote the cache; the "none" sentinel and the
cross-profile best-guess scan are gone (they keyed on the parked-gstack
count, which says nothing under BDR-030's gstack-off default). Hermetic
suite lib/tests/profile-default.test.sh (29 checks) seeds gstack as OFF like
a real tree. Citers updated: profile SKILL, Makefile help, plugin-advisor
PROFILE line + reset paragraph, toggle-external header.
2026-09-25 16:28:21 +02:00
bastien d82c06f572 refactor(doctrine): C2 coherence — 30 doctrine/skill tensions resolved, doctrine wins (BDR-099)
One ask policy; mandated executors exempt from the delegation rule; skill plan satisfies the planning rule; journal line exempt from the approval gate; chore = maintenance without new behaviour; small fix on develop = bugfix; BDR-068 written as the one auto-finish exception; deploy routes to /deploy. Skills and agents follow: hotfix types by base + skips the design gate on trivial; capitalize/close create missing registries; commit-change asks the branch type; doc/seo/web-validate/refactor branch through the aiguillage; tour reports BREAKING fixes as needs-decision and runs doc-syncer two-mode; client-handover applies audit bundles from its main loop behind one gate; init-project/onboard use the 200-file graphify signal and bootstrap memory; release-candidate gates the tag push only; push wording aligned with the BDR-095 hooks; stale pointers fixed (§ Language, .gsd/ROADMAP.md, handover script path, design-gate lists).
2026-09-24 20:25:40 +02:00
bastien 68c9df354b feat(gitflow): remove the origin copy of a branch once its merge is verified
`gitflow_delete` now ends with `_gitflow_delete_remote`: after the local
copy is gone, the remote tip is read with `ls-remote --exit-code`, checked
against develop/main with the same ancestor test, and only then removed
with `push origin --delete`. Same contract as the pushes (BDR-095): best
effort, warn never fail. No origin, `GITFLOW_NO_PUSH=1` or
`gitflow.autopush false` skip it; an unreachable origin or a remote tip
holding commits the bases lack keeps the remote branch, loudly. A base is
never targeted, by construction and by an explicit guard.

The static deny on hand `git push --delete` stays: it matches the Bash
tool's command string, the lib is the sanctioned path. Prose (hard_deny,
environment), doctrine, gitflow SKILL (table, op, warning row),
SETTINGS.md and CHANGELOG updated. T24: 9 checks (finish removes the
copy, bases untouched, unmerged remote tip kept, never pushed silent,
unreachable origin loud, autopush opt-out). 161/163, the 2 failures are
the pre-existing T16a (gitleaks absent on this host).
2026-09-24 11:50:16 +02:00
bastien 32d8f981df feat(gitflow): delete a branch only after a verified merge, main/develop undeletable
Since BDR-095 `start` sets an auto-pushed upstream, so `git branch -d`
checked "merged into origin/<branch>" (always true, the post-commit hook
keeps it in sync) instead of "merged into develop". T22a proves it: an
unmerged feature with its upstream in sync is deleted by `-d` alone.

- `gitflow_delete` is the single delete path (finish + CLI `delete`):
  refuses main/develop (rc 6) and any branch that is not an ancestor of
  develop or main (rc 5, `gitflow_merged_into_base`, fail closed when
  neither base exists), then `-d` as a second layer. CLI `merged`, `hooks`.
- Fourth generated hook `reference-transaction`: in the `prepared` call,
  a deletion of refs/heads/main or refs/heads/develop exits 1, whatever
  issued it (branch -d/-D, update-ref -d, rename, script, sub-agent).
  `git config gitflow.protect false` opts a foreign clone out.
- `GITFLOW_HOOKS` is the one hook list: write/emit/reconcile, T19d and
  doctor.sh (`gitflow.sh hooks`) read it. `.githooks/` and `githooks/`
  regenerated with the fourth hook.
- settings.json: static deny on hand `git branch -d/--delete/-dr/-rd` and
  on renames of main/develop; hard_deny "Branch deletion by hand"; the
  Disarming entry covers all four hooks and `gitflow.*` config; the
  protected-branches environment line states the rule.
- Doctrine (CLAUDE.global.md gitflow section), gitflow SKILL (`delete`
  op, rc 5/6 rows, common mistake), guard-bash spec T8w flips to deny,
  SETTINGS.md, README, CHANGELOG.
- Tests: T22 (12) lib guard incl. the premise proof, T23 (11) hook;
  T19 covers the fourth hook. 152/154, the 2 failures are the
  pre-existing T16a (gitleaks absent on this host).
2026-09-24 11:35:01 +02:00
bastien 7c05f75eab feat(21st): replace the magic MCP with the @21st-dev CLI + skill pack
Upstream supersedes `@21st-dev/magic` with `@21st-dev/cli` (bin `21st`):
same endpoint, `21st login` in place of an API key, no MCP process loaded
into every session.

- install-plugins.sh Step 8.7: `npm i -g @21st-dev/cli` (pinned in
  plugins.lock.json), staged `21st skills install`, TTY-only login offer,
  pack disabled by default. update-all.sh 7.4 refreshes both.
- The documented `21st install-skill` cannot be used: the installer refuses
  to follow a symlink on the target path and `~/.claude/skills` is one. The
  install runs under a throwaway HOME and the result moves into
  skills-external/21st-* (gitignored), symlinked on demand.
- toggle-external.sh manages `21st` as a pack (names globbed from
  skills-external/21st-*, parked under plain names). `magic` is gone.
- The 5 design skills join design/web/web-full/full and MANAGED_EXTERNALS;
  21st-registry and 21st-design-sync stay parked. MANAGED_MCPS is now empty
  and profile.sh's dead magic branches are removed.
- Design gate: GATE-BLOCK gains `21st` (required-manual, magic's old slot)
  and `21st-ui-build`; PATH repair extended to the npm global bin.
- settings.json: the 4 mcp__magic__* ask entries go; the outward-facing
  21st verbs land in autoMode.soft_deny, the tier that holds under auto
  mode (LRN-153).
- Docs: README, CLAUDE.global.md, design-gate.md, profile SKILL.md,
  .env.example, .gitleaks.toml, link.sh. BDR-093, LRN-158.

Tests: profile-set-managed 17/17, make test green except 2 pre-existing
gitflow FAILs (gitleaks binary absent on this host), shellcheck clean.
2026-09-22 02:53:31 +00:00
Bastien Chanot 55d6874aa6 feat(deploy): one physical line per command + post-deploy tests block
Every checklist command is emitted on exactly one line, however long; a
legacy backslash continuation in the runbook is joined at instantiation,
and bootstrap / learn patches write runbook lines the same way. After the
checklist the hand-back carries a Post-deploy tests block derived from the
delta diff: by-hand checks tied to delta files plus Suggestions for gaps.
Cold-resume re-display and re-hand-back regenerate both.

RED/GREEN on a scratch runbook: 4/4 baseline runs reproduced the
continuation verbatim and printed no tests; 4/4 runs on the edited skill
joined it and printed the block in the recipe's shape.
2026-09-17 16:43:06 +02:00
Bastien Chanot a1357a6ab5 feat(ship-feature,init-project): pass B at the plan and design steps 2026-09-16 22:13:42 +02:00
Bastien Chanot 97591ca737 feat(hotfix): pass B at LOCATE, class-tagged BLOCKED relayed as a question 2026-09-16 22:13:32 +02:00
Bastien Chanot 590482b622 feat(bugfix): pass B at FIX PLAN, NEED-DECISION routed on class 2026-09-16 22:13:16 +02:00
Bastien Chanot 6d9a3497a2 feat(feat): pass B at PLAN, NEED-DECISION routed on class 2026-09-16 22:13:06 +02:00
Bastien Chanot 80ccdafe0e chore(config): untrack the vendored graphify skill, prune the project-local settings override
graphify: `graphify claude install` (install-plugins.sh STEP graphify)
writes SKILL.md, references/ and .graphify_version straight into the repo,
because ~/.claude/skills is a symlink to skills/. Every `pipx upgrade
graphifyy` therefore dirtied the tree and cost a `chore(graphify): sync
vendored skill X -> Y` commit. Now gitignored and untracked; a fresh clone
gets them back from `make plugin`. test-prompts.json is hand-written for
darwin and stays tracked. The accepted trade-off, documented in CLAUDE.md,
is that an upstream release can change the skill's prompt with no diff to
review.

settings.local.json (gitignored, so not in this commit) went from 14.6 KB
to 6.2 KB. It was a near-complete shadow copy of the global settings at a
higher precedence tier, which hid its own drift until the global moved.
Two entries were actively defeating BDR-090, merged an hour earlier:

  - local `deny` still carried rsync / kill -9 / killall / pkill, the four
    rules deliberately moved out of global deny. deny wins across sources,
    so autoMode.soft_deny was a dead letter in this repo.
  - local `allow` carried `sed *`, `cp *` and `python3 -`. An allow rule
    short-circuits the classifier, punching a hole through the same
    soft_deny rules.

deny and ask are dropped whole (102 and 27 of their entries duplicated the
global; ask gates nothing under defaultMode auto). allow went 185 -> 98:
81 duplicates plus six policy conflicts, the three above and
Read(//home/bchanot/**), WebSearch, and a leftover command-injection test
payload that had been allowlisted verbatim. Every non-permissions key was
a verbatim copy of the global, including a hooks block whose only original
entry pointed at hooks/config-protection.sh, a script that exists nowhere.
2026-09-15 19:55:09 +02:00
Bastien Chanot e157a98e0b fix(hotfix): rewrap RULES bullet — census greps the no-verifier phrase on one line 2026-08-26 22:40:04 +02:00
Bastien Chanot 6eac7fbca9 fix(hotfix): batch-skeptic residuals — RULES restore mandate file-scoped; hotfixer FILE(S) marks created files (new) 2026-08-26 22:28:31 +02:00
Bastien Chanot b5ce280fc0 fix(fixtures): plugin-check expects PLUGIN CHECK block + real plugin names; onboard archetype nextjs-app-router 2026-08-26 21:59:56 +02:00
Bastien Chanot 6c69ae1670 fix(prune-memory,code-clean): stale v1-untested note reflects real tests/; executor attribution code-cleaner (refactorer inline); audit-only fixture matches flow 2026-08-26 21:59:40 +02:00
Bastien Chanot ad4985f410 fix(security-auditor,close): hotfix no-verifier carve-out documented; close enumerates STEP 5C + --no-push passthrough 2026-08-26 21:59:08 +02:00
Bastien Chanot ab75fc5e1f fix(harden): severity rule defers to the calibrated guide; SSL Labs late-finalize gets an assigned actor (main loop edits HARDEN.md row) 2026-08-26 20:35:35 +02:00
Bastien Chanot 1743f7683f fix(init-project,commit-change,tour): allowed-tools +Agent+Skill; conflict grep covers all unmerged codes; report-only never commits 2026-08-26 20:35:06 +02:00
Bastien Chanot 6eceedb8d3 fix(hotfix): revert paths — stash-create PRE snapshot + file-scoped restore (git restore . wiped tolerated user edits); security gate fresh-dispatch only 2026-08-26 20:34:45 +02:00
Bastien Chanot 796b52ea6b optimize gitflow r1-amend: judge-suggested precisions (re-checkout source before re-run; purge warning is pre-merge, finish continues) 2026-08-26 19:59:24 +02:00
Bastien Chanot 056f82b25f optimize gitflow: d3 — mechanical failure table keyed to lib return codes (rc=4 conflict resume, rc=2/3/1 start paths, best-effort purge, socle abort) 2026-08-26 19:57:21 +02:00
Bastien Chanot 9428b86880 optimize status-reporter r2: d5 — passive cost sourced from doctor.sh constants (skeptic's find), count-only fallback kept 2026-08-26 19:44:03 +02:00
Bastien Chanot a3f1624b15 optimize status-reporter: d5 — unproducible token field replaced by /plugin-check deferral; dead ROADMAP.md row rewritten for post-ADR-013 gsd layout 2026-08-26 19:35:46 +02:00
Bastien Chanot e9c6bf52fa optimize analyze-system: d1 triggers in skill description + d2 ordered TASKS mapped to OUTPUT sections in analyzer 2026-08-26 19:22:36 +02:00
Bastien Chanot e92becf609 optimize profile: d3 — failure-mode table (script absent, unknown name/verb rc=1, partial toggle, split plugin leg, current-contradiction) + fixture de-drift 2026-08-26 19:11:18 +02:00
Bastien Chanot c0a2a8069d optimize refactor-system: d4 — no-tests STOP gate (agent) + user arbitration loop (dispatcher) + mid-run test-failure revert; code-cleaner inline carve-out 2026-08-26 19:05:29 +02:00
Bastien Chanot 4d72d4aa12 optimize pdf-translate: d3/d8 — failure-mode table (deps, oversize, 0-output, illisible, missing design-html/browse, QA divergence, stale workdir) 2026-08-26 15:18:38 +02:00
Bastien Chanot 663b6cbe22 optimize skills-perso: d8 — detection rebuilt on link.sh symlink convention (8/32 -> 31/31) 2026-08-26 11:17:16 +02:00
Bastien Chanot a871ce5acb feat(darwin): Phase 0.5 — test-prompts for 7 promptless skills + campaign plan 2026-08-25 20:23:46 +02:00
Bastien Chanot 543b0c811a feat(tour): multi-project parallel fan-out — one runner per repo
Two or more project paths dispatch one general-purpose runner per repo,
all in a single message, instead of processing repos one by one. The
runner inherits the session model — no pin, it carries tour's reflection
(fix decisions, convergence) — and every agent inside keeps its defined
tier (security-auditor sonnet, Phase B opus, doc-syncer sonnet). A dead
or mute runner becomes an explicit RUNNER FAILED summary row; the gated
capitalize offer stays in the main loop, never in a runner.

Bounded LRN-083 derogation recorded in BDR-084: the per-project fix loop
moves into its runner, but nothing a runner decides touches shared state
— independent repos, per-repo chore branches, branches left unmerged for
human review exactly as inline. Mechanics proven before building: nested
probe, 3 sub-agent windows all overlapping, 9.1s vs ~18s sequential.

Census §12: 6 locks, flip-tested. Single-project path unchanged.
2026-08-24 14:18:59 +02:00
Bastien Chanot 33f5356c82 feat(gates): wire GATE 0 into the four orchestrator skill restatements
The include is authoritative, but feat/bugfix/ship-feature/init-project
each restate the verify loop inline — an orchestrator following the
restatement alone would have skipped the floor. Each now carries the
GATE 0 bullet ahead of GATE 1 (4 new structure locks, flip-tested).
The contract-interview weight table stops promising a hotfix oracle
nothing executes: hotfix runs no floor, the hotfixer runs the suite
itself. CHANGELOG extended with the wiring + the RED result.
2026-08-24 13:36:32 +02:00
Bastien Chanot 8008d8233c feat(profile): set symmetric on managed externals + MCPs (BDR-079)
- MANAGED_EXTERNALS (emil-design-eng, frontend-design,
  design-motion-principles, impeccable) + MANAGED_MCPS (magic):
  cmd_set now trims both when the profile does not list them —
  design leftovers no longer survive a 'set backend'
- cmd_set refactored to 4 symmetric trim helpers; nothing outside
  the MANAGED_* allowlists is ever auto-toggled (darwin-skill manual)
- enable_skill external: from-source fallback (ln -sf
  skills-external/<name>), mirrors toggle-external.sh
- stale usage() NOTE + SKILL.md updated to the both-ways reality
- hermetic test: 16 checks, fixture repo + fake claude shim (gstack
  on-demand, from-source, park/restore, magic add/remove, non-managed
  untouched); shellcheck + full make test green
2026-07-20 14:47:53 +02:00
Bastien Chanot b7026e4bda feat(ctx7): coverage extension — fast-libs single source + reminder hook + executor briefs (BDR-078)
- lib/fast-libs.sh: detect/cache-status verbs, JS+Python manifests,
  7-day cache freshness, LC_ALL=C sort — replaces 3 hardcoded lists
  (ship-feature 0c, init-project 5c, onboard 3.5)
- hooks/ctx7-reminder.sh: once-per-session UserPromptSubmit nudge when
  the project carries fast-libs and .ctx7-cache/ is missing/stale
- find-docs: before-writing-code trigger + cache-first rule; dist is
  machine-owned (gitignored) so the durable patch lives in
  install-plugins.sh STEP ctx7 (idempotent, grep-guarded)
- feater/bugfixer briefs: fast-lib docs rule (fresh cache read, else
  2-topic ctx7 fetch, else NOTES cache miss + proceed)
- tests: lib/tests/fast-libs.test.sh (11 checks); shellcheck + full
  make test green (review-guards 5/0)
2026-07-20 10:45:06 +02:00
Bastien Chanot 444c79acb2 fix(routing): W6 ronde — 6 findings closed (README bootstrap path, 2 census gaps, 3 stale refs)
Fresh-opus whole-chantier ronde (17fbe51..HEAD, EVAL-023 style): axes
severed-wires / gate-regressions / fail-open PROVEN CLEAN (all 7 new
handoffs traced end-to-end both sides). Fixed: init 5b now dispatches the
FULL-AUDIT path (auto-mode gated a missing README as SIGNIFICANT →
[CREATE-AUTO] unconditional restored, sole greenfield README path);
census locks added for /geo ERROR CONTRACT + never-re-derive (deleting
the fail-closed handler would have stayed green), doc-audit
model=opus override x5 flows, SYNTH REPORT grammar; doc-syncer ex-STEP-8
prose repointed to the dispatcher gate; plugin-advisor anim rows read
the PROBE REPORT ANIM field (no Bash anymore); client-handover 9.7
cleans the transient draft. Census caught one more line-wrapped lock
before it shipped vacuous. 133 pass / 0 fail, make test exit 0.
2026-07-19 23:56:58 +02:00
Bastien Chanot 07253e093c feat(doctrine): W6 — prose sweep + BDR-077 + LRN-137 + plan execution notes
LRN-113 whole-surface sweep: client-handover x2 + commit-change prose
repointed to the two-mode reality; code-cleaner/status historic notes
kept (accurate). Memory: BDR-077 (full architecture), LRN-137
(mode-based re-tiering + fail-safe pin rule), journal. Plan carries
as-built EXECUTION NOTES.
2026-07-19 23:44:24 +02:00
Bastien Chanot 9e4ebb4cf4 feat(agents): W5 seo/geo 3-mode pipelines — collect sonnet / judge opus pin / template sonnet (BDR-077)
seo-analyzer + geo-analyzer gain MODE: collect|judge|template around the
dispatcher (mode-based, zero body-text moves — seo-data fetch-wiring
locks survive; opus pin kept = fail-safe direction, a forgotten override
over-tiers but never downgrades judgment). Run-scoped gitignored
signals handoff (.audit/*-signals-<RUNID>.md + COLLECTION COMPLETE
sentinel), judge fails closed on absent/mismatched/unsealed signals.
/seo rewired to 3 phases (domains parallel per phase) + DISPATCHER ERROR
CONTRACT (mute/ERROR judge never carried into templating; retry once,
escalate); /geo same single-domain; legacy no-MODE single-shot kept on
the opus pin for /harden narrow-scope + /onboard report-only. Dropped
/geo's 'ask and I relay' fiction (dispatched agents cannot ask).
In-wave smokes PASSED disk-verified: collect signals+sentinel; judge
ERROR-verdict on wrong RUNID; real judge = honest N/A + deterministic
engine + full scoring grammar; template = complete envelope + verbatim
sentinel + zero re-derivation. Census §18 (125 pass — one vacuous
line-wrapped lock caught by the census itself and fixed), make test
exit 0.
2026-07-19 23:23:10 +02:00
Bastien Chanot 5e8bb0c22e feat(routing): W3 tier moves — validator-analyzer opus→sonnet, commit-changer propose=opus override (BDR-077)
validator-analyzer tiered down (deterministic validator-runner + fixed
deduction tables — no deep judgment; supersedes its BDR-076 opus pin).
commit-changer: MODE propose dispatched model="opus" (narrative
reconstruction + capitalize routing = judgment), MODE apply on the sonnet
pin. Typed-pin precedence smoke PASSED: sonnet-pinned verifier dispatched
model="haiku" ran on claude-haiku-4-5 — call-site wins, documented +
now behaviorally proven. Census §11 flip + §16 (106 pass), make test
exit 0.
2026-07-19 22:45:00 +02:00
Bastien Chanot 18075a38db feat(agents): W2/S2 doc pipeline two-mode + last inline conversions (BDR-077)
doc-syncer: ONE agent, TWO dispatch modes around the dispatcher's gate —
MODE: audit (model="opus" call-site override, READ-ONLY, drafts + PATCH
PLAN) / MODE: patch (sonnet pin, applies the APPROVED plan, shape oracle
w/ revert-on-fail, emits CHANGE SUMMARY + PATCHED_FILES). Deviation from
plan's 2-file split, per the challenge's own commit-changer mode
precedent: zero text duplication, zero lock moves. Fixes a LATENT DEFECT:
/doc dispatched an agent whose STEP 8 gate could never fire (dispatched
agents cannot ask) — the gate now lives in the dispatcher (DISPATCHER
PROTOCOL section). doc-commit.md consumes the patcher's CHANGE SUMMARY
(the in-thread context now crosses the dispatch boundary, LRN-126).
Consumers rewired: /doc (audit→gate→patch→commit), onboard (audit
report-only, opus), doc-commit steps in bugfix/hotfix/feat/ship-feature/
init-project(5b+10c); scaffolder loses PHASE 6 (README = init 5b's job);
scaffolder + onboarder now DISPATCHED in init-project/onboard (pins live,
was inline on session model). In-wave planted-drift smoke PASSED
end-to-end, disk-verified (audit caught npm-run-dev drift → [MINOR] plan
→ patch applied → summary crossed). Census §14-15 (103 pass), make test
exit 0. Typed plugin-probe dispatch resolution verified post-restart.
2026-07-19 22:28:09 +02:00
Bastien Chanot 74528a6910 feat(agents): W2/S1 plugin split — probe (sonnet) + advisor reasoner (opus) + plugin-gate include (BDR-077)
plugin-advisor keeps its name, becomes the opus REASONER: PHASE 1 bash
extracted to new plugin-probe (sonnet, facts-only PROBE REPORT), PHASE 4
apply + checkpoint hoisted to new lib/plugin-gate.md (main-loop include,
doc-commit.md x6 pattern). Fail-closed: advisor ERRORs on missing report.
4 consumers rewired (plugin-check, onboard, init-project, ship-feature).
In-wave planted-input smoke PASSED: probe report complete w/ fallbacks;
advisor consumed every planted field (monorepo per-package note, fast-libs
ctx7 reco) with zero re-detection; ERROR verdict on absent report.
Census §13 (81 pass). Note: new subagent_type registers next session —
resolution re-check before wave merge.
2026-07-19 20:57:10 +02:00
Bastien Chanot 3f7c754239 feat(routing): W1 no-inherit — fable skill-runners, opus review dispatches, dispatch-tier doctrine (BDR-077)
No dispatched agent inherits the session model anymore:
- client-handover-writer's 7 general-purpose skill-runner dispatch sites
  carry model: "fable" (+ normative rule; spike-verified alias — resolves
  claude-fable-5, enum-validated, loud failure, never silent fallback)
- ship-feature STEP 6 + init-project STEP 10 code-review dispatches carry
  model: "opus" (was: inherit — the leak the maps exposed)
- model-gate.md §4: dispatch-tier doctrine (typed = frontmatter pin,
  built-ins = explicit model= at every call site)
- census §12 (66 pass), make test green
2026-07-19 19:51:06 +02:00
Bastien Chanot 354ff2644f feat(agents): pin dispatched judgment agents to opus — Fable = inline reflection only (BDR-076)
Reverses the BDR-066 rejected alternative (opus pins on audit agents):
session default is now Fable, so inherit burned Fable quota on every
dispatched audit/challenge. analyzer, plan-challenger, seo/geo/
validator-analyzer pinned model: opus; onboard's 6 general-purpose
audit dispatches carry model="opus"; tour Phase B repointed.
interviewer + client-handover-writer stay unpinned (inline-load only,
a pin there is inert). settings.json default: claude-fable-5[1m].
Census flipped: model-routing §3 + new §11 (61 pass), loops-light 35,
full make test green.
2026-07-19 17:38:55 +02:00
Bastien Chanot 311ea14789 feat(skills): wire hotfix into plan-challenge under a logic-only guard
STEP 1.8 (Option B): skip purely cosmetic fixes (CSS/copy/typo), run the 3-lens
challenge only when the fix touches control flow/behaviour (off-by-one, wrong
operator, behaviour-changing config, execution-altering import); a BLOCKER means
it was never a hotfix -> escalate to /bugfix. 12th orchestrator wired.

- skills/hotfix/SKILL.md          — STEP 1.8 guarded challenge
- lib/tests/plan-challenger.test.sh — lock hotfix into the census (43 assertions)
2026-07-18 23:08:52 +02:00