forked from bchanot/claude
chore(memory): capitalize review remediation — LRN-113/114/115/116, EVAL-021/022, journal
LRN-113 partial-fix+guard (structural fil rouge), LRN-114 hook-generator drift, LRN-115 analyzer report-grants not dead (FP1, don't re-flag), LRN-116 release fix missing from develop. EVAL-021 the review, EVAL-022 M5 pins trace. Journal 2026-07-08 remediation line. (BDR-062 committed with A6.)
This commit is contained in:
@@ -128,6 +128,10 @@ rules:
|
||||
| LRN-110 | 2026-07-07 | job8: `21st_magic_component_builder` (magic MCP) opens unauth'd 127.0.0.1 callback server, CORS `*`, no token check, 10min window — any local POST lands verbatim in the tool result the model consumes = local prompt-injection channel | any MCP tool that opens a local callback/listener server to receive async results — check auth + origin scoping on the listener, not just the outbound call |
|
||||
| LRN-111 | 2026-07-07 | job8: empty permissions.allow for a risky MCP tool is a VALID posture (not a gap) when transcript census shows zero real invocations — pre-authorizing unused surface buys nothing, ask-gate costs nothing | deciding whether to allowlist any tool/command — check real usage before assuming "no entry = todo" |
|
||||
| LRN-112 | 2026-07-08 | job9: CC nested subagent dispatch SUPPORTED since v2.1.172 (cap 5 levels, `Agent` must be in subagent `tools:`) — "flattens to 1 level" is the pre-2.1.172 regime; live env v2.1.203. Contradicts the operating premise of the whole job1-9 series | a subagent-dispatches-subagent design is VERSION-CONTINGENT, not "broken" — check CC version before flagging; fix = raise floor or re-architect to bundle→L1 |
|
||||
| LRN-113 | 2026-07-08 | partial-pattern-fix = recurring defect of the job1-9 series: fix the cited instance, leave the twins (trailer A1, YAML A4, attribution A5, hook A2). An adversarial review catches twins later; nothing catches them at commit time | any fix of a banned pattern: grep the ENTIRE surface + add a make-test guard (run-review-guards.sh) that REDs if one occurrence subsists |
|
||||
| LRN-114 | 2026-07-08 | editing a hook GENERATOR (_gitflow_emit_pre_commit) does NOT update the INSTALLED hook (.githooks/pre-commit) — silent drift; T10 diffs the allow/block verdict not content, T16 emits fresh in a throwaway repo → job7 gitleaks backstop inert on the repo 8 days | after editing a template-generated artifact: reinstall (install-hook) + a gate that diffs installed==emit |
|
||||
| LRN-115 | 2026-07-08 | analyzer Edit/Write grants (seo/geo/validator) are NOT dead: needed to write the REPORT (VALIDATE/SEO/GEO.md); the "never edit" rule targets CODE, instruction-level (same as the patron) — verified false-positive | do NOT re-flag as a tool-grant defect; a report-only agent keeps Write for its own report |
|
||||
| LRN-116 | 2026-07-08 | memory backfill release→develop: a BLK marked "resolved" can have its RESOLUTION (code) missing from develop — BLK-016 resolved on release but rtk fix e58037c never back-merged → bug LIVE on develop | before backfilling a resolved blocker: verify the fix CODE is on the target branch, not just the registry entry |
|
||||
|
||||
---
|
||||
|
||||
@@ -1149,3 +1153,30 @@ rules:
|
||||
- **context**: the whole job1-9 audit series ran on the premise *"Claude Code aplatit à 1 niveau → un design supposant 2 niveaux de sous-agents est cassé silencieusement."* job9 corrected it via `claude-code-guide` (official docs `code.claude.com/docs/en/agent-sdk/subagents.md`): a running subagent CAN spawn a further subagent IF `Agent` is in its `tools:` (omit it / add to `disallowedTools` to prevent nesting); hard cap **5 levels** ("a subagent 5 levels below main can't spawn further"); nesting **stabilized in v2.1.172** ("let subagents spawn their own subagents") — earlier versions did not support it at all. Live env confirmed **v2.1.203** (user). `claude --version` was unavailable in-sandbox so the report bracketed but could not pin it; the user pinned it.
|
||||
- **future application**: NEVER classify a subagent-dispatches-subagent design as "BROKEN" without checking the CC version. On ≥2.1.172 it works within the 5-level cap; on <2.1.172 it silently no-ops. The actionable finding is a VERSION-FLOOR ([[BDR-060]]) or a version-robust re-architecture (bundle→L1, [[BDR-061]]) — not "it's broken." When an agent must NOT nest, enforce it structurally: drop `Agent` from its `tools:` (done for seo/geo analyzers). Re-audit any prior job1-9 "nested = broken" finding through this lens.
|
||||
- **cousin**: [[BDR-060]] (version floor), [[BDR-061]] (path-b bundle pattern), [[LRN-057]] (subagent invocation idioms).
|
||||
|
||||
## LRN-113 — Partial-pattern-fix is the job1-9 series' recurring defect: grep the whole surface + guard it
|
||||
- **pattern**: fix one cited instance of a banned pattern, leave the twins. Review found 4: trailer stripped from commit-changer only (A1, twins in bugfixer/feater/hotfixer); YAML quoted elsewhere but seo/security-auditor left broken (A4); attribution scrubbed on 3 skills but geo-analyzer missed (A5); gitleaks added to the hook generator but the installed hook not regenerated (A2).
|
||||
- **why it recurs**: the fixer greps for the reported line, fixes it, stops — never enumerates the pattern across the full surface. An adversarial review catches the twins later; nothing catches them at commit time.
|
||||
- **fix**: every pattern-fix ends with (1) a whole-surface grep proving zero residue, (2) a deterministic make-test guard that REDs if any occurrence returns. Shipped `lib/tests/run-review-guards.sh` — G1 trailer, G2 false attribution, G3 strict-YAML, G4 reconcile hermeticity, G5 hook-drift; teeth-verified (planted violation REDs). This is the check that would have caught A1/A4/A5/A2 at make-test time instead of a review.
|
||||
- **future application**: any "fix pattern X" task → grep agents/ lib/ hooks/ templates/ skills/, add/extend a review-guard with teeth.
|
||||
- **cousin**: [[LRN-114]] (hook-drift class), [[LRN-047]] (silent degradation → measure/guard).
|
||||
|
||||
## LRN-114 — Editing a hook generator does not touch the installed hook: reinstall + drift-guard
|
||||
- **pattern**: job7 added the gitleaks scan to `_gitflow_emit_pre_commit` (the GENERATOR), but the installed `.githooks/pre-commit` is only (re)written by `gitflow init`/`install-hook`. job7 never re-installed → the repo's active hook stayed the pre-job7 version (620071b) for 8 days; `git commit` ran no secret scan while the team believed it did.
|
||||
- **why undetected**: T10 (drift test) compares only the hook's allow/block VERDICT, not content; T16 emits a FRESH hook in a throwaway repo, validating the generator, never the installed file. Both green while the installed hook was stale.
|
||||
- **fix**: after editing any template-generated artifact, regenerate the installed copy (`gitflow.sh install-hook`) AND add a content-drift gate — `run-review-guards.sh` G5 diffs installed `.githooks/pre-commit` against `emit-hook`.
|
||||
- **future application**: any generator/template emitting an on-disk artifact needs an "installed == freshly-emitted" test, not just a behavioral one.
|
||||
- **cousin**: [[LRN-113]] (partial-fix + guard), [[LRN-039]] (installers drift hand-curated config).
|
||||
|
||||
## LRN-115 — Analyzer Edit/Write grants are not dead capability: they write the report (false-positive)
|
||||
- **pattern**: a contract audit flagged seo/geo/validator-analyzer holding `Edit`/`Write` while instructed "do NOT apply any Edit/Write" as a defense-in-depth defect. Verified FALSE: those grants write the agent's own REPORT (`.claude/audits/VALIDATE.md`/`SEO.md`/`GEO.md`). The "never edit" rule targets CODE files (the fix-bundle is applied by the dispatcher) and is instruction-level — identical in the patron. Removing Write would break report generation.
|
||||
- **why it matters**: don't "harden" a report-only agent by stripping Write — it needs it for its report. The code/report distinction is instruction-enforced, not tool-enforced, by design.
|
||||
- **future application**: before flagging a tool-grant as dead, check whether the agent uses it for its own output artifact (report), not the forbidden target (code).
|
||||
- **cousin**: [[BDR-061]] (analyzer bundle→L1 contract), [[LRN-113]].
|
||||
|
||||
## LRN-116 — A resolved blocker's FIX can be missing from develop even when the entry backfills cleanly
|
||||
- **pattern**: backfilling release/1.0.0 memory into develop, BLK-016 (rtk PATH-dead) was marked "resolved" via fix e58037c. Checked before backfilling: e58037c (the `~/.cargo/bin`→`~/.local/bin` bridge in install-plugins.sh) was NOT on develop — develop still installed rtk to a cargo bin dir the tool shell can't see → rtk compression was LIVE-broken on develop (~460K tokens/30d). The registry entry looked safe to copy; the underlying fix wasn't there.
|
||||
- **why it matters**: append-only registry backfill is "safe" only for the TEXT; a "resolved" status is a claim about CODE state that must be verified on the target branch, else you assert a resolution that isn't true.
|
||||
- **fix**: ported e58037c to develop (13-line idempotent bridge), THEN backfilled BLK-016 resolved. General: before backmerging a resolved blocker, grep the target for the fix's code signature.
|
||||
- **future application**: gitflow divergence review — enumerate release-only COMMITS that touch code, not just memory; a feature can be parallel-merged while its RC-branch fix is orphaned.
|
||||
- **cousin**: [[LRN-036]] (PATH profile drift), [[LRN-047]] (silent degradation).
|
||||
|
||||
Reference in New Issue
Block a user