Re-review surfaced one new BLOCKER + two CONCERNs + four NITs. Folded:
N1 BLOCKER: `|%s*sh%f[%s]` missed `curl x | sh` (end-of-string canonical
wrapper-bypass — Lua's `%f[%s]` requires transition INTO whitespace,
which doesn't happen at EOL). Replaced with two patterns each for
sh and bash: `|%s*sh%s` (followed by whitespace/args) and
`|%s*sh%s*$` (end-of-string). Same for bash. Verified against 18
wrapper-bypass test cases — all canonical idioms now HALT.
N2 CONCERN: `ci=true` rule flag had no implementation note. Added one
sentence to §5 explaining the matcher lowercases the input string
when ci is set.
N3 CONCERN: §12 commit #5 description was stale — still said
"extends interactive CMD: extraction to consult is_destructive"
which contradicts the R-B3 resolution (Norris-only). Rewrote
commit #5 description to match R-B3, and bundled the
ffi/readline.lua `_bound[seq]:free()` removal into commit #5's
scope with explicit "Phase 1 amendment" callout. Same for the
§12 risk note that still referenced the dropped behavior change.
Other NITs (N4 skip threshold, N5 approved-turn mention, N6 :model
swap interaction, N7 commit-attribution wording) are cosmetic and
will fold in-flight during implement if material.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Independent review surfaced 3 BLOCKERs + 6 CONCERNs + 7 NITs against
the analyze-tier draft. Resolutions applied:
BLOCKERs:
B1 Shell-wrapper bypass — static patterns leaked on bash -c, sh -c,
eval, pipe-to-shell, python -c, xargs|rm. Added 9 wrapper
patterns to §5. Norris HALTs on any wrapper invocation; user
reads the inner before proceed. The patterns are the
conservative floor against the wrapper bypass class.
B2 LLM second-opinion was self-policing — same model class
generating actions then judging them. Switched probe model
from `fast` to `deep` (qwen3-30b). Added re-roll inversion:
if first probe says NO, ask "is this SAFE?". Disagreement
between two probes → HALT. Cheap independent-class insurance.
B3 `is_destructive` would have run on interactive CMD: extraction
— a PHASE0 §6/§10 substrate amendment in disguise. Resolved
Q24: heuristic runs ONLY when norris_active == true. No
substrate change; interactive `confirm_cmd` semantics unchanged.
CONCERNs:
C1 Skip-budget: consecutive_user_skips counter; 3+ similar skips
escalate to abort/force-proceed prompt.
C2 Algorithm-vs-Q25-resolution contradiction: §4 reordered to
dispatch ALL pending actions before checking GOAL: complete.
C3 Norris-goal eviction: goal embedded directly in the dynamic
system-prompt suffix; survives sliding-window eviction.
C4 Readline use-after-free window: M.bind no longer frees old
callbacks; pin for process lifetime (bounded memory cost).
C5 GOAL: complete matcher: line-level scan, exact match after
trim — substrate-aligned with CMD: rigor.
C6 §4 step 4 tightened: auto_approve does NOT bypass destructive
heuristic; tool_call without auto_approve still HALTs even
when destructive-clear (Norris conservative).
NITs deferred or rolled into pattern table:
- chown root-path pattern tightened (NIT 2 in-line)
- Test corpus expansion noted in §12 commit #1 risk
- Other NITs are wording-level
Status: Plan (review folded). Ready for commit #1 (safety static
patterns) once another review pass clears.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Analyze findings folded into the manifest:
A1. \C-n binding can't toggle mid-prompt without rl_insert_text /
rl_redisplay. Solution: bind those (one cdef + 2 wrappers in
ffi/readline.lua) so \C-n inserts ":norris " at the cursor; user
types goal + Enter. Routes through existing meta dispatch.
A2. broker has no max_tokens passthrough. Add opts.max_tokens for
the LLM second-opinion path (terminates at ~2 tokens; verified
proxy honors it).
A3. Phase 2 tool-sub-loop pattern IS the planner shape. safety.norris_step
is the per-iteration extraction; driver loop in repl.lua.
Module-changes table (§3) updated with the rl_insert_text and
max_tokens rows.
Baseline doc (PHASE3-baseline.md, 80 lines) captures:
- LLM second-opinion latency: 425-1162ms per probe, all 5 test
cases correct. Worst-case 16-step Norris = ~20s overhead; with
static-pattern fast-path + session cache, ~5s realistic.
- Module pre-state at commit f26cbd9 (Phase 2 tip): LOC + state
per file before Phase 3 edits.
- Six static-pattern Lua-match sanity checks (all correct).
- Carries: aish#15 (still open), aish#14, aish#32/#33.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>