Commit Graph
100 Commits
Author SHA1 Message Date
Bastien Chanot 3bc6506332 Merge chore/fix-inert-write-deny-rules into develop 2026-07-16 15:04:00 +02:00
Bastien Chanot 56aa3c8a17 chore(memory): BDR-069 + LRN-130 + EVAL-024 — deny-list design pass
- BDR-069: keep broad Edit(**/.env.*), keep .env.example name (option A).
  Rename rejected (~30 refs); glob narrowing rejected (fails open on
  .env.production outside the Next.js convention).
- LRN-130: a deny glob is absolute — allow, `!` negation and PreToolUse
  hooks all fail to exempt it (permissions.md :33/:35/:361, verbatim).
  Only lever = the glob's own shape.
- EVAL-024: the pass shipped one unauthorized weakening (scope inversion +
  framework parochialism) on my own permission boundary, caught by the
  auto-mode classifier rather than self-caught. Reverted pre-commit. Also
  logs a false-positive automated review and a bad subagent glob claim.
2026-07-16 15:02:00 +02:00
Bastien Chanot 960d3f33ea chore(graphify): sync vendored skill 0.9.6 -> 0.9.15
Upstream skill refresh, present in the working tree before this session —
committed here rather than left dangling. Not authored work.

- uv invocation fix: `uv tool run graphifyy python` -> `uv tool run --from
  graphifyy python`. Without --from, uv resolved the command name against
  the package instead of running the interpreter.
- default output is now HTML viz; --obsidian opts into the vault.
- description reworded to trigger on codebase questions generally, not
  only when graphify-out/ already exists.
2026-07-16 14:45:37 +02:00
Bastien Chanot 07ca738b3f fix(settings): Write() deny rules inert — convert to Edit(), close write gaps
Startup emitted 15 warnings: "Write(**/.env) is not matched by file
permission checks — only Edit(path) rules are."

Write(path) rules never matched. The 5 secret-file write bans were dead
config — .env, secrets/**, *.pem, *.key were freely writable. Converting
to Edit() makes them enforced: permissions.md:242 "Edit rules apply to all
built-in tools that edit files", and :244 prescribes exactly this ("add an
Edit deny rule for paths no tool may change").

- settings.json: Write(...) -> Edit(...) on the 5 patterns.
- Mirror the 9 secret patterns Read denied but Edit did not: *.p12, *.pfx,
  id_rsa*, id_ed25519*, .ssh/**, credentials, credentials.json,
  .aws/credentials, .azure/**. Read/Edit parity now 14/14. Claude could
  previously overwrite an SSH private key or ~/.aws/credentials.
- New read-allowed/write-denied class: lockfiles (*.lock,
  package-lock.json, pnpm-lock.yaml, go.sum) + node_modules/**. Reading
  aids diagnosis; hand-editing is always wrong — the package manager
  regenerates them via Bash, which Edit deny does not block.
- templates/settings/SETTINGS.md taught the broken Write() pattern; fixed
  at the source so /onboard stops propagating it.

Rule syntax has no negation and deny beats allow, so deny globs cannot
carry exceptions — see the .env.example conflict noted in the follow-up.
2026-07-16 14:45:26 +02:00
Bastien Chanot 83eba36ac7 chore(memory): journal — v1.1.0 cut + v4.0.0 stale-tag watch-item 2026-07-16 14:06:58 +02:00
Bastien Chanot 21b1e21a2c Merge release/1.1.0 into develop 2026-07-16 13:57:08 +02:00
Bastien Chanot 0543dafa2d chore(release): 1.1.0 — version.txt + CHANGELOG 2026-07-16 13:56:02 +02:00
Bastien Chanot 1b13bac652 Merge feature/close-auto-persist into develop 2026-07-16 13:52:12 +02:00
Bastien Chanot 096418c3e7 feat(capitalize): auto-persist memory to develop on /close + /capitalize (STEP 5C, BDR-068) 2026-07-16 13:51:15 +02:00
Bastien Chanot d36d4d0a58 Merge chore/session-close into develop 2026-07-16 13:42:31 +02:00
Bastien Chanot c41aac6975 chore(memory): LRN-128 LRN-129 EVAL-023 — close ritual 2026-07-16 13:37:43 +02:00
Bastien Chanot fdbe168ad8 chore(memory): BDR-067 — v1.0.0 first public release (versioning reset) + journal + TODO 2026-07-16 13:29:54 +02:00
Bastien Chanot 6c23d6f925 Merge release/1.0.0 into develop 2026-07-16 13:22:29 +02:00
Bastien Chanot b0e2ebc31a chore(release): 1.0.0 — first public release (versioning reset from internal 4.x lineage) 2026-07-16 13:12:10 +02:00
Bastien Chanot 5f159f38d2 Merge bugfix/model-routing-edge-fixes into develop 2026-07-16 12:50:01 +02:00
Bastien Chanot 890e55f789 fix(model-routing): ronde edge fixes — feater applier carve-out, /refactor→sonnet dispatch, /analyze gate, audit-pin guards (F1-F5) 2026-07-16 12:45:07 +02:00
Bastien Chanot d8917bff4c Merge feature/client-handover-dispatch into develop 2026-07-16 12:17:11 +02:00
Bastien Chanot c43f89cede docs(memory): LRN-126 (split severs implicit data paths) + LRN-127 (SDD implementer git-ops discipline) 2026-07-16 12:17:01 +02:00
Bastien Chanot 1947a21237 fix(model-routing): wave-4 review fixes — forward DEPLOY_HINTS + SKIP_SEO in PACKAGE, realign §7/§8 annex numbering (I1/I2/I3) 2026-07-16 12:12:53 +02:00
Bastien Chanot fe1d60fccb chore(model-routing): wave-4 census + docs + BDR-066 (client-handover doc-gen → sonnet) 2026-07-16 11:56:54 +02:00
Bastien Chanot 1dcda2702b feat(model-routing): client-handover MODEL GATE (pipeline orchestrates audits = reflection) 2026-07-16 11:51:57 +02:00
Bastien Chanot 1ec032d2af feat(model-routing): client-handover-writer trimmed to pipeline + delegates doc-gen to sonnet doc-writer
STEP 1-8 preserved byte-for-byte; STEP 9-16 replaced by a doc-gen orchestration
that resolves all interaction (questions, NAP, precheck, overwrite, client-name),
assembles the PACKAGE, and dispatches handover-doc-writer. Dropped the inert
model: opus pin (inherits the big session model via inline-load).
2026-07-16 11:51:10 +02:00
Bastien Chanot a98610f676 feat(model-routing): handover-doc-writer — sonnet gate-free deliverable generator (wave 4) 2026-07-16 11:36:58 +02:00
Bastien Chanot 872225f7d1 docs(model-routing): wave-4 plan (client-handover redaction-only doc-gen dispatch) + TODO 2026-07-16 11:26:42 +02:00
Bastien Chanot e5c7c516d2 Merge feature/model-routing into develop 2026-07-16 11:03:25 +02:00
Bastien Chanot 30f732c08f chore(memory): LRN-125 — no dual-use agent across model tiers (wave-3 lesson) 2026-07-16 11:02:32 +02:00
Bastien Chanot 4294bc2af5 docs(model-routing): USAGE onboard STEP 6 audit → general-purpose (wave-3 consumer sweep, review finding) 2026-07-16 10:41:23 +02:00
Bastien Chanot bed695a6c6 chore(model-routing): wave-3 census + docs + BDR-066 update (bugfix/code-clean split) 2026-07-16 10:34:12 +02:00
Bastien Chanot a7d4df8704 feat(model-routing): /code-clean split — audit+gate inline, code-cleaner = sonnet PHASE-2 executor
code-cleaner is now a pure fix executor (was audit+gate+execute). Reroute the two
read-only-audit consumers (onboard STEP 6, tour Phase B) to a big-model agent
(general-purpose/analyzer) — an audit must stay on the big model, never the sonnet
executor. Refactor now runs on sonnet inside the executor (inline-load pin was inert).
2026-07-16 03:24:51 +02:00
Bastien Chanot 1f7afc1d49 feat(model-routing): /bugfix split — reflection inline, bugfixer = sonnet executor (supersedes BDR-050 bugfix carve-out)
Reroute hotfix's deeper-bug escalation to the /bugfix skill (bugfixer is now a
pure executor, not loadable standalone). loops-light locks repointed to the
bugfix orchestrator + bugfixer-executor shape.
2026-07-15 23:50:34 +02:00
Bastien Chanot 152da63624 docs(model-routing): wave-3 plan (bugfix + code-clean split) + wave-4 stub + TODO 2026-07-15 23:16:52 +02:00
Bastien Chanot 2136953b2a fix(model-routing): commit-changer resolves step→hash refs on apply; edge-case resume notes (release NEED-DECISION, commit-change skip) 2026-07-15 22:05:23 +02:00
Bastien Chanot bc8eede090 chore(model-routing): wave-2 census + docs + BDR-066 update 2026-07-15 21:49:34 +02:00
Bastien Chanot dd7868fc1c fix(model-routing): release-candidate title back to 'orchestrator' to match preserved Overview doctrine 2026-07-15 21:37:23 +02:00
Bastien Chanot da50c38be9 feat(model-routing): /release-candidate dispatches sonnet release-executor, human gates in dispatcher 2026-07-15 21:31:54 +02:00
Bastien Chanot 4217fcfe35 fix(model-routing): keep commit grouping on the sonnet subagent (edit<n> re-dispatches; /feat routes to /commit-change) 2026-07-15 21:24:48 +02:00
Bastien Chanot ab0fafc0ef feat(model-routing): /commit-change dispatch to sonnet commit-changer, gates relocated to dispatcher 2026-07-15 21:09:15 +02:00
Bastien Chanot 29fa962e43 fix(model-routing): /feat Rule 1 downgrade routes to /hotfix skill, not the bare executor agent 2026-07-15 19:46:56 +02:00
Bastien Chanot 45cd86810a feat(model-routing): /hotfix split — reflection inline + gate, hotfixer = sonnet executor (dual-use applier preserved) 2026-07-15 19:28:58 +02:00
Bastien Chanot f36aec370b feat(model-routing): doc/status dispatch their agent (sonnet/haiku pins take effect) 2026-07-15 12:38:12 +02:00
Bastien Chanot 89093a7835 docs(plan): model routing wave 2 — pure-execution + reflection-split skills (doc/status/hotfix/commit-change/release-candidate) 2026-07-15 12:34:20 +02:00
Bastien Chanot 2ad712cfd4 chore(memory): BDR-066 model routing + journal + TODO follow-ups 2026-07-15 12:01:14 +02:00
Bastien Chanot 97088fe59b docs(model-routing): README agent-model table + CHANGELOG entry 2026-07-15 11:54:54 +02:00
Bastien Chanot bd5a603567 test(model-routing): census guard — gate wiring, pins, executor shape (flip-tested) 2026-07-15 11:49:59 +02:00
Bastien Chanot e955c4d050 feat(model-routing): web-validate fix bundle applied via hotfixer at L1 (BDR-061 alignment) 2026-07-15 11:44:53 +02:00
Bastien Chanot 0fbe3103cb feat(model-routing): SDD implementation + review subagents dispatched model sonnet 2026-07-15 11:40:42 +02:00
Bastien Chanot 56c451ea25 feat(model-routing): /feat re-architecture — reflection inline, feater = sonnet executor (partial supersede BDR-050) 2026-07-15 11:33:18 +02:00
Bastien Chanot 1ed77cb3fb feat(model-routing): pin hotfixer sonnet (executor), un-pin analyzer (inherits session) 2026-07-15 11:16:33 +02:00
Bastien Chanot 06413d9eb5 feat(model-routing): wire blocking model gate into 12 reflection orchestrators 2026-07-15 11:11:29 +02:00
Bastien Chanot f2dd361bd5 feat(model-routing): blocking model-gate include (self-check + witness) 2026-07-15 11:06:49 +02:00
Bastien Chanot 9984b75f90 feat(model-routing): model-check witness (big/small/unknown) + flip-tests 2026-07-15 11:00:32 +02:00
Bastien Chanot e5dd804e7e docs(plan): model routing — 10-task implementation plan (client-handover deferred to plan 2) 2026-07-15 10:46:43 +02:00
Bastien Chanot 2864635087 docs(spec): model routing — reflection inline / execution sonnet (design) 2026-07-15 00:08:12 +02:00
Bastien Chanot 166faa1da5 Merge chore/post-merge-cleanup into develop 2026-07-14 18:46:53 +02:00
Bastien Chanot 08ab0575df chore(docs): drop transient spec+plan post-merge; codify artifact lifecycle (BDR-065) 2026-07-14 18:46:43 +02:00
Bastien Chanot 8d70fcb15c chore(memory): BDR-065 + LRN-124 — post-merge capitalize (transient artifacts, scan-report leak-map) 2026-07-14 18:46:43 +02:00
Bastien Chanot d557ee906d Merge chore/untrack-audit-reports into develop 2026-07-14 18:45:22 +02:00
Bastien Chanot 2d54df5e33 Merge feature/claude-global-md-rename into develop 2026-07-14 18:43:36 +02:00
Bastien Chanot 20b90465d8 chore(audit): untrack gitleaks reports; allowlist triaged FP classes
Reports are gitignored (.gitignore:94) but were swept into 17bdd08 —
even redacted they map secret types/locations for anyone with repo
access. Allowlists from the 2026-07-14 cso triage (75 findings → 0,
each class verified empirically): bare 40-hex git SHAs, gitflow-test
synthetic AWS fixture, presigned-URL key ids, expired GitHub image
JWTs, doc placeholders, IDE lock files, two prose literals. Converted
deprecated [allowlist] to [[allowlists]] (gitleaks 8.30 refuses the
mix). Makefile hint no longer suggests committing the reports.
Transcripts/file-history deliberately NOT path-allowlisted (BDR-057).
2026-07-14 18:07:11 +02:00
Bastien Chanot 5842119d2a added audit folder 2026-07-14 17:21:00 +02:00
Bastien Chanot 30d6b031b4 chore(memory): BDR-064 + LRN-122 + LRN-123 — ship-feature claude-global-md-rename 2026-07-14 17:06:29 +02:00
Bastien Chanot e9a38a0268 fix(memory): test covers CLAUDE.global.md guard entry; doctor asserts exact global symlink target 2026-07-14 16:19:29 +02:00
Bastien Chanot 0f23f10767 fix(memory): hook comments and payloads reference the renamed global memory 2026-07-14 04:24:15 +02:00
Bastien Chanot 1534b2202a docs: slim rules/README to a pointer; README tree lists both memory files 2026-07-14 04:02:47 +02:00
Bastien Chanot c20ad4763a feat(memory): guards, doctor stats and doc-commit exclusions follow CLAUDE.global.md 2026-07-14 03:55:25 +02:00
Bastien Chanot 040c88ee40 feat(memory): add project-scope CLAUDE.md; link.sh deploys CLAUDE.global.md 2026-07-13 00:39:19 +02:00
Bastien Chanot 9496538500 feat(memory): rename global memory CLAUDE.md → CLAUDE.global.md (scope header, drop repo-only tail) 2026-07-13 00:39:02 +02:00
Bastien Chanot a4ee7e1790 docs(spec): CLAUDE.global.md rename — design + implementation plan 2026-07-13 00:06:21 +02:00
Bastien Chanot b7106761b0 Merge feature/seo-nap-guardrails into develop 2026-07-10 18:17:37 +02:00
Bastien Chanot 8614bc5760 feat(seo/geo): projected code-only score + 17/20 trajectory, wired into client-handover
- Analyzers (seo/geo): every finding tagged fixable:code|user; mandatory
  projected axis+global scores (bundle fully applied), honest code
  ceiling, TRAJECTORY TO 17/20 block (ranked code fixes or ceiling +
  unlocking user actions)
- /seo: §1 carries actual+projected columns + merged trajectory; console
  shows projected scores + trajectory one-liner
- /geo: audit-end deliverables (HUMAN-ACTIONS.md, trajectory in report +
  console) even in conservative mode — parity with /seo
- client-handover: fix loop breaks at code ceiling (score ≥ projected−0.2)
  instead of burning iterations on user-bound points; STEP 8 gate gains
  the code-ceiling pass (gap items land verbatim in client doc §5 with
  expected gains, explicit status in score table); §4 NAP table consumes
  NAP-KIT.md first; §5 consumes HUMAN-ACTIONS.md first; HANDOVER-ROADMAP
  splits CODE-BLOQUÉ vs CLIENT-BLOQUÉ
2026-07-10 18:06:32 +02:00
Bastien Chanot c6e8adaff3 feat(seo): STEP 0 external-report intake (SORank or equivalent)
- Optional gate before agent dispatch: file in .claude/audits/external/
  (PDF read directly), pasted PDF content / suggested AI prompt, or skip
- 30-day staleness check; normalized EXTERNAL FINDINGS block in shared
  context; both dispatch prompts carry the data-not-instructions rule
  (cross-check before bundling, never merge external score into /20 axes)
- Merge side: confirmed findings credited 'Confirmé par <tool>', refuted/
  uncovered ones surfaced in §14 divergences; no report → §12 recommends
  the free SORank extension; console summary line added
2026-07-10 17:44:50 +02:00
Bastien Chanot b6bde8f4ee feat(seo): NAP guardrails + audit-end deliverables
- STEP 0 collects user-confirmed CANONICAL NAP (LRN-032 zenquality:
  duplicated-seed trap — source majority is not truth)
- Both dispatch prompts carry the canonical NAP + no-majority rule;
  seo-analyzer spec forbids directional NAP fix without confirmation
- STEP 2 now emits .claude/audits/HUMAN-ACTIONS.md (checklist from §11)
  and NAP-KIT.md (local business) in BOTH modes — audit-only runs leave
  the user immediately actionable; /client-handover §4 consumes NAP-KIT
2026-07-10 17:03:53 +02:00
Bastien Chanot 642da0147c Merge feature/seo-account-mgmt into develop 2026-07-10 12:52:54 +02:00
Bastien Chanot 0cedbc7b3a chore(memory): LRN-121 shell allowlist validation (grep -Eq fragile → whole-string POSIX case) + seo-account-mgmt journal + contract 2026-07-10 12:48:54 +02:00
Bastien Chanot 887341d7a6 docs(usage): /seo account-management verbs (connect/accounts/forget) 2026-07-10 12:39:22 +02:00
Bastien Chanot 8bf7459566 feat(seo): account-management verbs (connect/accounts/forget) + connect.sh wrapper
tokenstore remove/clear, fetch.sh forget dispatch, and a connect.sh wrapper
that sources ~/.claude/.env internally and runs from any project. /seo now
routes connect|accounts|forget before the audit flow; Makefile seo-connect
delegates to the wrapper. Labels are guarded to shell-safe ASCII (POSIX case,
whole-string, C-locale) as defense-in-depth; forget output states local
removal is not a Google-side revocation.
2026-07-10 12:38:32 +02:00
Bastien Chanot 61a98d3ae1 Merge bugfix/seo-connect-env-source into develop 2026-07-10 03:51:57 +02:00
Bastien Chanot caa5bed189 fix(seo-data): source ~/.claude/.env in make seo-connect so OAuth creds reach connect.py
The seo-connect target ran connect.py without sourcing ~/.claude/.env, so
GOOGLE_OAUTH_CLIENT_ID/SECRET (documented to live there) never reached
os.environ — connect.py aborted telling the user to set what they had set.
Mirror fetch.sh's sourcing; add a regression lock.
2026-07-10 03:17:06 +02:00
Bastien Chanot 8a1fac02cd Merge chore/doc-sync-gsc-crux into develop 2026-07-10 03:10:07 +02:00
Bastien Chanot e687eae6f9 chore(seo-data): remove transient GSC+CrUX design spec + plan (shipped, documented, capitalized) 2026-07-10 03:05:13 +02:00
Bastien Chanot 504f6f2242 chore(memory): BDR-063 + LRN-119/120 — GSC+CrUX data layer (OAuth token store, fail-open engine contract, SDD merge-base gotcha) 2026-07-10 03:04:17 +02:00
Bastien Chanot 4a15c737d0 docs: README + USAGE + CHANGELOG — GSC+CrUX data layer for /seo FULL 2026-07-10 03:00:14 +02:00
Bastien Chanot bb1fbb2d45 Merge feature/gsc-crux-data-layer into develop 2026-07-10 02:52:45 +02:00
Bastien Chanot cbfd89d6ff docs(seo-data): correct README status enum + doctor/link/queries accuracy 2026-07-10 02:36:33 +02:00
Bastien Chanot c50d2cc5bb docs(seo-data): engine usage + security contract README 2026-07-10 02:29:48 +02:00
Bastien Chanot 15962fcd90 feat(seo): wire GSC+CrUX data into /seo FULL (STEP 0 account select, CWV field, GSC perf) 2026-07-10 02:19:57 +02:00
Bastien Chanot c4bee6aad3 chore(seo-data): install/make/doctor wiring + gitleaks allowlist for token store 2026-07-10 02:10:31 +02:00
Bastien Chanot 7f06533d8b feat(seo-data): OAuth consent + property discovery + pinned deps 2026-07-10 01:45:33 +02:00
Bastien Chanot 39e227f1c8 fix(seo-data): fail-open CLI contract (corrupt store + bad usage always emit JSON) 2026-07-10 01:42:23 +02:00
Bastien Chanot c3a504fbbf feat(seo-data): fetch.sh entrypoint with venv/system fallback and redaction 2026-07-10 01:32:48 +02:00
Bastien Chanot 5a318076fd feat(seo-data): GSC Search Analytics + URL Inspection with lazy OAuth refresh 2026-07-10 01:26:30 +02:00
Bastien Chanot 493ecd8806 fix(seo-data): extract real CrUX origin on 404 retry + drop dead import 2026-07-10 01:23:13 +02:00
Bastien Chanot e214da036d feat(seo-data): CrUX field-data fetch with mock mode and graceful degrade 2026-07-10 01:16:11 +02:00
Bastien Chanot 0f7fd5b678 fix(seo-data): re-assert store dir 0700, chmod lock, drop dead import 2026-07-10 01:11:49 +02:00
Bastien Chanot fb0484954a feat(seo-data): label-keyed atomic OAuth token store 2026-07-10 01:03:50 +02:00
Bastien Chanot 10f20438b1 docs(seo-data): relocate engine test out of gated lib/tests/
config-protection.sh gates lib/tests/* as a guardrail dir; all 8 tasks
edit the engine test. Move it to lib/seo-data/seo-data.test.sh (co-located,
ungated) + extend the make test glob to discover lib/seo-data/*.test.sh.
Root-cause fix, no guardrail weakened. Chosen by user over per-edit bypass.
2026-07-10 00:56:55 +02:00
Bastien Chanot 24b47ce08b fix(seo-data): review-pass hardening on spec+plan
Model-switch re-review found 7 real defects, fixed before any code:
- fail-open contract now covers unexpected errors (403/5xx/DNS/timeout)
  via top-level try/except -> degraded JSON, exit 0 (was: traceback+exit 1)
- test isolation: SEO_DATA_ENV_FILE override so tests never source the
  real vault (degrade tests would hit network on machines with live keys)
- CrUX: None-safe normalizer (missing INP on low-traffic sites) +
  origin-level fallback on page-level 404
- refresh errors split token_revoked (RefreshError) vs network_error
- fixed set-u STORE_MISSING ordering bug in Task 4 test
- Makefile read -p bashism wrapped in bash -c (dash-safe)
- SKILL.md fetch path -> ~/.claude/lib/... (skills run from project dir)
- spec/plan aligned: label not email in accounts output, ok+[] not
  'empty', CrUX history -> YAGNI v2, PageSpeed-key routing rejected v1
  (key would enter subagent context)
2026-07-10 00:43:28 +02:00
Bastien Chanot 159617d766 docs(seo-data): add GSC+CrUX data-layer implementation plan
8 TDD tasks (bash-test convention, offline fixtures, no network):
tokenstore → CrUX → GSC queries/inspect → fetch.sh → OAuth connect →
install/make/doctor/gitleaks wiring → /seo FULL integration → README.
Transient with the spec; delete after ship+doc+capitalize.
2026-07-09 17:35:48 +02:00
Bastien Chanot f853529c7d docs(seo-data): add GSC+CrUX data-layer design spec
Transient design spec for a Google Search Console + CrUX data layer
feeding /seo (+/geo) FULL audits: isolated lib/seo-data engine (Python
venv), OAuth one-shot multi-account (label-keyed token store, scope
webmasters.readonly), per-call account/property isolation, graceful
degradation to anonymous PageSpeed, gitleaks allowlist for the store.
To be removed once the feature is shipped, documented and capitalized.
2026-07-09 15:47:17 +02:00
Bastien Chanot d3e644d78b Merge chore/gitflow-conformity-remediation into develop 2026-07-09 11:43:27 +02:00