Adopt AI_INFRA 2026-07-13 broadcast ab6c387e (presence-not-age selector, type=update) + directed 6c32df89 rec-3, via /fable-clone 5-lane reviewer ensemble (wf_b621aac4-f0b) -> spec -> /fable-real deep-pass (PASS-WITH-FIXES, M1+M2 applied) -> HMW execute (em-main solo; governance single-writer D9). D2 (hmw.js): unknown-role fail-soft-WARN -> up-front STOP-HARD throw (before parallel; preserves null/'' role-less inherit-lead path). node --check + stub 7/7. Doc-sync 5 live lines (ultra-on/README/harness-11-engine/runbook). D3 (memory-archive-gate.ps1): value_protect advisory-flag -> pre-selection HARD-SKIP (value-primary; heading-only spans; non-contiguous byte accum) + value-floor WARN. Fault-inject ALL PASS + real regression A7 242/242. DRY-RUN. D1 (reinject-ledger.md): presence re-verify stamp + 3 honest-notes + BUILD-GAP. Re-verify: reinject (i) + MFE age-band (iii) already COMPLIANT; only the archive-gate age-trace needed hardening. D3 = defense-in-depth codify, NOT leak-closure (9-token grep unchanged; em-main value-scan stays the guarantee). adap-report + email AI_INFRA (8b9dc5165d5a); inbox STAGE-2 processed. No new User-Mark (codify-only). #53 garble x1 (lane-4) recovered from disk, 0 loss. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
13 KiB
sub-reviewer-5 — LENS 5: SCOPE-DISCIPLINE / anti-over-engineering / honest-notes
VERDICT: COMPLIANT (memory-selector already meets the 3 function-floors → quick re-verify only, NO rewrite). The ONLY real code change in this run is Part B (hmw.js fail-soft→stop-hard), which is a legitimately-directed in-scope MUST. My lane's value = guarding the other 4 lanes against over-reach: the archive-gate oldest-first ordering is a RED-FLAG-SHAPED construct but is functionally gated (value_protect + keep_floor + DRY-RUN + em-main), so it is at most a bounded SHOULD, never a MUST/rewrite.
Run: 2026-07-13-presence-not-age-adopt · lane 5 of 5 · floorPoint = scope-discipline (meta).
0. What the broadcast actually asks (the scope contract I am enforcing)
Broadcast ab6c387e (disk AI_INFRA/broadcasts/outbox/all/2026-07-13-...reinject.md) is type: update, self-labelled repeatedly as a SMALL delta:
- §1 L20 "bản cập-nhật (type: update), KHÔNG phải một quy-tắc mới"; L26 "re-verify đúng phần bộ chọn — KHÔNG cần adopt lại toàn-bộ vòng bộ-nhớ từ đầu".
- §5 three honest-notes (L90/L92/L94): (1) basis = ONE occurrence already fixed = proactive-prevention, NOT a spreading incident; (2) SPECIFIC-APPLICATION not new rule → already-presence-based = quick re-verify only; (3) floor = FUNCTION not FORM → filenames/structure self-determined, do NOT copy hub org.
- §6 L102 "Nếu bộ chọn đã đúng → ghi một dòng xác-nhận... 'đã re-verify, không có gì đổi'".
So the default expected outcome is "already-compliant + one-line re-verify". Any lane proposing a script rewrite bears a heavy burden of proof.
1. Evidence — SE is ALREADY presence-based on all 3 floors
Floor (i) reinject-by-absence — COMPLIANT (0 change)
.claude/governance/reinject-ledger.md L3 + L12: trigger is floor-rot = "item ĐÃ-từng-tồn-tại ∩ CÒN-giá-trị ∩ RỚT-khỏi-L1" (B3 test). That is a pure coverage-gap / presence predicate — age is not a term in it. L12 explicitly routes the two non-presence cases away from reinject: "chưa-từng-dựng = build-gap", "hết-giá-trị = cold-archive". Drop-date-column test: the B3 predicate never reads a date, so behavior is invariant → presence-clean.
Floor (ii) archive value-gate — COMPLIANT-BY-FUNCTION (value-gate EXISTS)
memory-budget.json archive_gate.value_protect.patterns (L38-41) + the mark it cites, RC-pqhuy1987-20-06-2026-10-29-11 (verified present, ACTIVE-MARKS.md L17, Active-High, anh-confirm S79: "time/age/recency-decay = false-proxy … kiến-trúc KHÔNG dựa cũ … archive-gate"). The value-axis gate is already implemented and already anchored to the exact mark the broadcast descends from. keep_floor_entries=5 (L36) is a recency PROTECT-floor (protects newest-5 from being drained) — it is a floor that prevents cutting, NOT a selector that cuts by age; the budget _note L39 states this orthogonality explicitly ("keep_floor protects NEWEST-n … value_protect protects HIGH-VALUE regardless of age … archival cuts LOW-VALUE, NOT FIFO-by-date").
Floor (iii) self-check for age-rank — one real red-flag-SHAPE, but downstream-gated
scripts/memory-archive-gate.ps1 PASS-1 PLANNER L137-165 literally computes "Move oldest entries one-by-one" (for ($move = 1; $move -le ($entryCount - $keepFloor); $move++), cutting at markers[$move]). This is an age-RANK ordering by the broadcast's own drop-date test (remove entry order → cannot compute moveCount → behavior changes). BUT: (a) whole script is DRY-RUN, header L7 "FLAG-ONLY … Does NOT move/edit"; (b) value_protect scans the moved prefix and FLAGS high-value entries "KEEP in L1 regardless of age" (L167-191); (c) the actual archive DECISION is em-main (human), L56/L190 "ADVISORY FLAG ONLY - em-main decides (no auto-exclude)". So the decision layer is value-gated; oldest-first is a proposal-ordering heuristic inside a dry-run, not the cool-down decision.
scripts/mfe-eval.ps1 age-band L183-188: "age-band : FLAG old-but-still-required, NEVER cut (mark RC-...10-29-11)", ">30d old but still Active … -> KEPT (status-driven, age-blind)". This is presence-clean already (age = surfacing flag, drop only on status-change).
2. Ranked proposed-change table (my core deliverable)
| # | Proposed change | Necessity | Rationale (scope-discipline) |
|---|---|---|---|
| A | Write the presence-not-age re-verify note (1 paragraph) into docs (ledger honest-nac §6.5 or reinject-ledger footer) confirming floors i/ii/iii met + citing keep_floor/value_protect/DRY-RUN + mark …29-11 | MUST | Broadcast §6 L102/L105 requires a written confirmation + the 3 honest-notes. Doc-only, cheap, zero code risk. |
| B | Keep all 3 honest-notes verbatim-in-substance in the spec (ONE-occurrence proactive-prevention · specific-application-not-rule · function-not-form/no-copy-hub) | MUST | Broadcast §5 L104 "Giữ đủ ba ghi-chú trung-thực". Free, and it is the anti-over-reach anchor itself. |
| C | Part B — hmw.js invalid-role fail-soft-WARN → STOP-HARD + ask owner, mirrored to commands/ultra-on.md doc |
MUST | Directed 6c32df89 §2.3 REC-3 (in-scope, real silent-break class fixed hub-side today w/ 5-case sim). See §4 for minimal form. |
| D | In memory-archive-gate.ps1, compute the value-protect / keep-floor exclusion BEFORE the oldest-first ordering, so the candidate set = (entries − floor − value-protected) and the PLAN is value-gated-then-ordered rather than ordered-then-flagged |
SHOULD (optional) | Tightens self-check (iii) at the FORM level using pieces that already exist (~10 LOC reorder). NOT a MUST: DRY-RUN + human + existing advisory flag already deliver the function. Guard: must NOT balloon into a value-SCORING engine — that violates function-not-form. |
| E | Alias-removal (directed §2.3 "check if SE has a similar alias to remove") | SKIP / verify-N-A | SE has no conversational-vs-ensemble alias split. fable-real.md + fable-clone.md are 2 distinct engines by design (fable-clone.md L34 "2 engine GIỮ từ H19"), not aliases. Correct outcome = "verified none". Lane 4 owns the definitive call. |
| F | Rewrite reinject-ledger / build a coverage-scanner / rewrite archive-gate to delete oldest-first | SKIP (over-eng) | Violates §5 note-2 (quick re-verify) + note-3 (function-not-form). Floor (i) already presence-by-construction. |
| G | Remove/weaken keep_floor_entries or the mfe age-band as "age-based selectors" |
SKIP — ANTI-REGRESSION GUARD | keep_floor is a recency PROTECT floor (never cuts by age); mfe age-band is already FLAG-never-cut. Removing either would HARM (drain-below-floor / lose surfacing) and would MISREAD the mark. Explicitly flag if any lane proposes this. |
3. The crux tension (self-refutation of my COMPLIANT verdict)
Strongest case AGAINST "COMPLIANT / no MUST on the memory side": The broadcast self-check (iii) is literal — "any place that SORTS/FILTERS by … oldest-first to DECIDE … cool-down = RED FLAG → redesign to presence." memory-archive-gate.ps1 L138/L153-162 DOES sort oldest-first to produce the archive proposal, and value_protect is advisory-only, no auto-exclude (L55-56, L190). So the computed plan (move $moveCount oldest, L182) is FIFO-shaped and the value-gate is a flag appended AFTER — not a gate that alters the move-set. Under the drop-date test the planner's behavior changes → age is used for RANK → by the broadcast's own words this is a red flag that "cần sửa".
Why I still settle COMPLIANT (not NEEDS-FIX): The broadcast's target is the cool-down DECISION, not every heuristic that touches order inside a dry-run. In SE the decision-maker is em-main (human), the value-gate (value_protect + mark …29-11) is in that human's loop, and the script never cuts (DRY-RUN, exit-0-unless-pointer-broken L293-295). Function-floor (ii) — "archive passes through a value-gate" — is satisfied at the decision layer. The oldest-first is a proposal-ordering, and the honest fix is not a rewrite but the bounded reorder in row D (make the value-gate precede the ordering so the PLAN is value-gated-first). That is a SHOULD, and even it is optional. Calling this a MUST/rewrite would itself violate the scope-discipline the broadcast demands (note-2 quick-re-verify, note-3 function-not-form). Net: the red-flag SHAPE is real and worth one honest sentence in the spec + optional row-D tightening — it is NOT a spreading defect and NOT a rewrite trigger.
4. Part B in-scope confirmation + minimal form (guard against ballooning)
Part B is NOT part of broadcast ab6c387e; it comes from directed reply 6c32df89 §2.3 REC-3. Bundling two same-day AI_INFRA items into one run is reasonable batching, not harmful scope-creep — but the spec MUST keep Part B in a clearly-separated section so the "quick, no-rewrite" presence-not-age re-verify is not conflated with an actual code change.
Current state (2 fail-soft spots, only #2 is the target):
hmw.jsL106const role = VALID_ROLES.includes(raw) ? raw : undefined+ L107 WARN + L145agentType: role || undefined→ invalid role silently runs the DEFAULT subagent (the silent-break class the hub hit).hmw.jsL46-49 resolveModel is about MODEL inherit for invalid role — leave the role-LESS legitimate path (!role && !rawRole, L49 governed-ultracode default) UNTOUCHED.
Minimal in-scope form (Lane 4 owns the exact diff; I only bound it): add a pre-flight validation BEFORE parallel() (after the checkpointApproved throw ~L85), mirroring the existing throw pattern L83-85:
// Part B (directed 6c32df89 REC-3): role specified-but-∉-whitelist = STOP-HARD, ask owner.
// (role-LESS by design stays legal — governed-ultracode default, L49.)
const badRoles = A.taskList
.map(t => t && t.role)
.filter(r => r != null && !VALID_ROLES.includes(r))
if (badRoles.length > 0) {
throw new Error(`hmw: role(s) ∉ VALID_ROLES: ${[...new Set(badRoles)].join(', ')} — `
+ `STOP-HARD (directed REC-3): báo anh bổ sung vai vào VALID_ROLES hoặc sửa typo. `
+ `KHÔNG rơi-lặng về default subagent.`)
}
Precision guard (scope-discipline): the predicate is r != null && !includes(r) — it must fire ONLY on a specified-but-invalid role, never on the legitimate null role-less path. Doc mirror: commands/ultra-on.md L21 + L26 currently document "role lạ → default subagent + WARN (fail-soft)"; these two lines MUST be updated to "STOP-HARD + hỏi anh" or the doc will lie about the engine. Do NOT expand Part B into a rework of resolveModel, the model-tier system, or VALID_ROLES membership.
5. Measurable acceptance criteria
- Spec contains all 3 honest-notes (grep the spec for: "one/ONE occurrence" + "proactive-prevention"; "specific-application"/"not a new rule"; "function not form"/"do NOT copy hub"). 3/3 present = PASS.
- Presence re-verify note written to a git-tracked doc citing floors i/ii/iii +
keep_floor+value_protect+ markRC-pqhuy1987-20-06-2026-10-29-11. Exists + cites the mark = PASS. - Zero deletion of
keep_floor_entries,value_protect, or the mfe age-band in the final diff (git diffshows these lines intact). Any removal = FAIL (row G regression). - Part B:
hmw.jsthrows on a specified-but-invalid role (fault-inject: taskList[{role:'not-a-role'}]→ hard error, run aborts BEFORE any spawn) AND a role-LESS task ({role:null}) STILL runs (no throw). Both = PASS.commands/ultra-on.mdL21/L26 no longer say "fail-soft/default subagent". - No script rewrite:
memory-archive-gate.ps1diff is either empty, or (row D) a bounded reorder < ~15 LOC that introduces NO value-scoring/ranking numeric. Larger diff = scope-fail. - Alias: spec records "verified N/A — fable-real/fable-clone are distinct engines, no alias" OR a concrete alias found by Lane 4. Fabricated alias-removal = FAIL.
6. Bottom line for the synthesizer
- Memory-selector (floors i/ii/iii): already functionally compliant → MUST = write the re-verify note + keep 3 honest-notes (docs only). SHOULD = optional row-D reorder. SKIP = any script rewrite / ledger rebuild / keep_floor-or-age-band removal.
- Part B (hmw.js): in-scope MUST, minimal pre-flight throw + doc mirror, precision-guarded to spare the role-less path.
- Alias: verify-N/A, do not fabricate.
- The single biggest risk in this run is a lane over-reading self-check (iii) into a rewrite of
memory-archive-gate.ps1. Hold that at SHOULD-optional; the DRY-RUN + human + value_protect + mark already satisfy the FUNCTION.