# nobrainer-tech-flow 2.4.0: ask before risky commands, and see whether the proof still matches

Release date: 2026-10-19.

nobrainer-tech-flow can ask before risky commands and shows whether its proof still
matches your files. The guards are optional and Claude Code only. The rest is
instruction and helper changes for every client.

## What changes

### Optional Claude Code guards

`scripts/install.py --client claude --guards` previews, then with `--apply` adds hooks to
the Claude Code user settings. The preview names only the hooks it would add or remove
and the settings path, never other settings. `--undo --apply` removes only hooks whose
command is exactly one the installer generates. Each change keeps a new backup file, readable
only by you, and never overwrites an existing one. The hooks run
`skills/nobrainer-tech-flow/scripts/flow_guard.py` through the skill link.

- PreToolUse asks before `rm -r` (also `/bin/rm`) outside temporary folders,
  `git push --force`, `-f`, `--force-with-lease` or a `+branch` refspec,
  `git reset --hard`, `git clean -f`, `vercel --prod`, `npm publish`,
  `terraform apply` or `destroy`, `kubectl delete` and `gh release create`, also with
  global options before the subcommand (`git -C dir push -f`, `npm -w pkg publish`,
  `terraform -chdir=infra apply`, `kubectl -n prod delete`, `gh -R owner/repo release
  create`). A relative `rm` target counts as temporary only when the session's working
  folder is temporary and the command does not change folder first, and a path counts
  by where its links lead, so a temporary folder that links to a project is the project.
  An `rm -r` whose arguments it cannot read, and a single command line too long to check
  (over 2,000 characters) that names one of these tools, are asked about as well. It
  asks; it never denies.
- Stop and SubagentStop block once when a turn that changed files or ran commands ends
  with no `Proof:` or `Checked:` line and no `UNVERIFIED`.
- Both fail open on input they cannot read. They are off by default, POSIX only in this
  version, and the plugin hooks stay SessionStart only.
- Limits: the guard reads command text. A command behind `sh -c`, a variable or an alias
  can pass, other tools such as `pnpm publish` are not matched, and a risky phrase inside
  a quoted string can ask without need. It is a seatbelt, not a security boundary.

### Evidence receipts

`skills/nobrainer-sessions/scripts/evidence_receipt.py` runs one command through the
bounded runner and records a declared input scope before and after. `check` reports
`CURRENT`, `STALE`, `CHANGED_DURING_RUN` or `UNAVAILABLE` without re-running anything.
Python 3.11+ and POSIX only; receipts are unsigned and output is stored unredacted. See
[the reference](../../skills/nobrainer-sessions/references/evidence-receipt.md).

The closeout now carries `current for <input snapshot/time or UNKNOWN>`, and a worker's
`RETURN` line starts with the outcome as the worker understood it.

### Proof contract

- Build reports `TEST_SENSITIVITY: PROVEN | PARTLY_PROVEN | NOT_PROVEN | NOT_APPLICABLE`
  for a behavior-preserving rewrite, after seeding one deliberate fault per changed
  behavior class. `NOT_PROVEN` leaves the preservation claim `UNVERIFIED`.
- Review keeps a "no behavior change" claim open when `TEST_SENSITIVITY` is missing or
  `NOT_PROVEN`, and does not accept `STALE` or `CHANGED_DURING_RUN` evidence as proof of
  the current artifact.
- Model routing: routine units get the lowest effort that still meets acceptance, workers
  share an assignment prefix with the unit-specific part last (cache reuse is plausible
  but unmeasured), and a unit that reaches its `BUDGET` stops and reports partial results.
- Security: a plaintext `.env` or credential file in a workspace an agent can read counts
  as secret exposure.
- Correction hooks: a deterministic failure that a native check can catch gets that check
  as the prevention; a prose rule only when no mechanism fits.

### Instruction debt and one session rule

Skill doctor gains a `REPORT_ONLY` instruction-debt audit. `context_candidates.py` reads
an owner-supplied, redacted history JSON and proposes repeated instructions with the
history rows they came from; the audit maps accepted candidates to exact `file:line`,
and the owner approves each change. The visible-session rule now has
one canonical home in the entry module, and the Dispatcher and Team modules link to it
instead of restating it.

### Distribution

- The README first screen leads with the Claude Code and Codex plugin installs, then the
  Git install for any client.
- The Codex marketplace is renamed `nobrainer-tech-skills-dev` -> `nobrainer-tech`, like
  the Claude one. If you added it under the old name, follow the
  [migration guide](../MIGRATION_TO_FLOW.md) to remove it and add it again; otherwise the
  old and new plugin stay enabled side by side.
- Manifests describe one workflow of 18 modules that ends with an evidence handoff.
- The npm package is still not published on npm. The `npx` commands in
  [INSTALL.md](../INSTALL.md#npm-command) work only after publication.

## Verification record

Live client run on 2026-10-18: the guards on Claude Code 2.1.302 with temporary
`--settings` in a throwaway sandbox. The Stop hook blocked once and the agent added a
`Proof:` line. The PreToolUse "ask" fired for `git push --force` in default and
`bypassPermissions` modes; in `-p` mode, where nobody can answer, it became a denial.

Local checks on this checkout (macOS, Python 3.14.5):

- `python3 scripts/validate_skills.py` and `python3 scripts/validate_skills.py --suite`:
  both passed.
- `tests.test_adapters`, `tests.test_suite`, `tests.test_npm_distribution` and
  `tests.test_update_check`: 101 tests passed, run without the one test that starts a
  nested full discovery.
- `python3 -m unittest discover -s tests` on the final commit: 514 tests passed with 5
  platform-specific skips.
- Two independent review rounds on the whole change, then repeated reviews of the guard,
  the settings backup and the receipts; every finding is fixed with a test that failed
  before the fix.
- `git diff --check` and a staged-change secret scan with the repository's gitleaks
  configuration found nothing.

These checks prove local behavior and package metadata. They do not prove publication,
a fresh target-client import or a performance gain.

## Scope and distribution

No benchmark was run and no model is imposed. The module set stays at eighteen. The
native plugin 2.4.0 will carry the same files; plugin export, publication and
target-client import each need their own readback. npm registry publication is still
pending; source release files and a locally packed tarball do not establish registry
availability.

## Rollback

Return to the reviewed v2.3.2 source through the documented preview and undo flow. Remove
the guards first with `scripts/install.py --client claude --guards --undo --apply`; they
point at the skill link, so an old checkout leaves them doing nothing. A Codex user who
moved to the new marketplace name keeps it, or removes it and re-adds the old name.
