nobrainer-tech-flow 2.5.0 → 2.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +1 -1
- package/.codex-plugin/plugin.json +1 -1
- package/AGENTS.md +8 -8
- package/CLAUDE.md +8 -8
- package/README.md +78 -36
- package/adapters/bootstrap.md +2 -2
- package/assets/nobrainer-workflow.svg +2 -2
- package/docs/CHAT_PLUGINS.md +4 -2
- package/docs/INSTALL.md +51 -30
- package/docs/SKILL_CURATION.md +6 -6
- package/docs/releases/v2.6.0.md +73 -0
- package/docs/releases/v2.7.0.md +145 -0
- package/gemini-extension.json +1 -1
- package/package.json +1 -1
- package/plugin.json +1 -1
- package/scripts/install.py +3 -1
- package/scripts/install.sh +25 -6
- package/scripts/install_guards.py +29 -13
- package/scripts/install_personalization.py +52 -17
- package/skills/nobrainer-auto-fine-tune/SKILL.md +1 -1
- package/skills/nobrainer-build/SKILL.md +17 -2
- package/skills/nobrainer-security/SKILL.md +10 -0
- package/skills/nobrainer-team/SKILL.md +43 -64
- package/skills/nobrainer-team/references/team-plan.md +7 -6
- package/skills/nobrainer-tech-flow/SKILL.md +13 -13
- package/skills/nobrainer-tech-flow/VERSION +1 -1
- package/skills/nobrainer-tech-flow/references/correction-hooks.md +11 -5
- package/skills/nobrainer-tech-flow/references/daily-update.md +5 -2
- package/skills/nobrainer-tech-flow/references/delivery.md +50 -20
- package/skills/nobrainer-tech-flow/references/long-run-state.md +31 -5
- package/skills/nobrainer-tech-flow/references/model-routing.md +13 -11
- package/skills/nobrainer-tech-flow/references/project-start.md +2 -2
- package/skills/nobrainer-tech-flow/references/routing.md +6 -8
- package/skills/nobrainer-tech-flow/references/setup.md +6 -7
- package/skills/nobrainer-tech-flow/scripts/flow_guard.py +179 -2
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# nobrainer-tech-flow 2.6.0: delegate aggressively, verify by risk
|
|
2
|
+
|
|
3
|
+
Release date: 2026-10-23.
|
|
4
|
+
|
|
5
|
+
This release changes workflow guidance and the update line of the instruction block.
|
|
6
|
+
The setup record and the module set (eighteen) do not change.
|
|
7
|
+
|
|
8
|
+
## What changes
|
|
9
|
+
|
|
10
|
+
- **Aggressive delegation as the default.** `skills/nobrainer-tech-flow/SKILL.md` now opens
|
|
11
|
+
substantial work with "Delegate aggressively": independent units run on parallel native
|
|
12
|
+
subagents through team execution, and MAIN integrates, verifies and refills slots.
|
|
13
|
+
`references/delivery.md` adds the reason (delegation is the default route to a faster
|
|
14
|
+
done), keeps only tiny, tightly coupled, gated or shared-state steps in MAIN, and sets a
|
|
15
|
+
cost rule: delegate a unit when parallel work shortens the time to done more than a
|
|
16
|
+
worker's start-up costs, send a short task packet rather than the whole conversation,
|
|
17
|
+
ask for a concise report, and give narrow, mechanical work to a cheaper model under the
|
|
18
|
+
host's policy. No model is named.
|
|
19
|
+
- **Resend only failed units.** When part of a batch fails, only the failed units go out
|
|
20
|
+
again with their new evidence; accepted units are not rerun.
|
|
21
|
+
- **Verification by blast radius.** `references/delivery.md` scales verification to how
|
|
22
|
+
risky and reversible a change is. Reversible, low-risk changes may proceed on green
|
|
23
|
+
automated tests, review and security checks. CI configuration, credentials,
|
|
24
|
+
security-sensitive paths, data migrations and irreversible effects need an independent
|
|
25
|
+
review and remain owner-gated. An agent's approval never counts as the owner's.
|
|
26
|
+
- **Two build rules.** `skills/nobrainer-build/SKILL.md`: before adding complexity for a
|
|
27
|
+
speculative race or security edge case, name the concrete failure, its likelihood and
|
|
28
|
+
the cost; and in user interfaces, taglines, helper text and secondary labels added to
|
|
29
|
+
explain a screen count as slop, so the layout gets fixed instead.
|
|
30
|
+
|
|
31
|
+
## Daily updates by default, in one line
|
|
32
|
+
|
|
33
|
+
The managed instruction block now carries one short update line, on by default for new
|
|
34
|
+
setups: "Once a day on first use, update nobrainer-tech-flow to its latest verified stable
|
|
35
|
+
release from the canonical source, with a backup; change nothing else and ask if unsure."
|
|
36
|
+
`install_personalization.py --no-auto-update` writes the one-line opt-out instead ("tell
|
|
37
|
+
the owner when a newer stable nobrainer-tech-flow release exists; do not update it
|
|
38
|
+
yourself"); `--auto-update` stays accepted and means the default. With `--keep-options`
|
|
39
|
+
(which `install.py` and the guided setup always pass) the longer lines written before 2.6.0
|
|
40
|
+
become the matching short line: an old update grant stays a grant and the old notify-only
|
|
41
|
+
default stays notify-only, so no existing setup starts updating itself without a choice.
|
|
42
|
+
An update line that is neither recognized grant, for example one edited by hand, becomes
|
|
43
|
+
the notify-only line. `install.sh` follows the same rule when it refreshes an earlier block:
|
|
44
|
+
it rewrites the block in this version's text but keeps notifying unless the block held the
|
|
45
|
+
update line as its own line.
|
|
46
|
+
|
|
47
|
+
## Sources
|
|
48
|
+
|
|
49
|
+
The delegation rule is an owner decision (2026-10-23). The other rules were drawn from the
|
|
50
|
+
owner's recent X bookmarks and checked against the replies under each post; ideas that the
|
|
51
|
+
replies credibly disputed (a "canary" line to detect context decay, a viral prompt with a
|
|
52
|
+
false attribution) were left out.
|
|
53
|
+
|
|
54
|
+
## Verification record
|
|
55
|
+
|
|
56
|
+
Local checks (macOS, Python 3.14.5):
|
|
57
|
+
|
|
58
|
+
- `python3 scripts/validate_skills.py` and `python3 scripts/validate_skills.py --suite`: OK.
|
|
59
|
+
- `skills/nobrainer-tech-flow/SKILL.md` stays within the suite budget (239 lines, 1,749
|
|
60
|
+
words; limits 240 and 1,750).
|
|
61
|
+
- `python3 -m unittest tests.test_suite tests.test_delegation_contract
|
|
62
|
+
tests.test_visible_session_rule`: 81 tests OK.
|
|
63
|
+
- `python3 -m unittest tests.test_shell_installer tests.test_personalization
|
|
64
|
+
tests.test_one_command_installer tests.test_guided_onboarding`: OK, including the new
|
|
65
|
+
cases for the default update line, the opt-out, pre-2.6 blocks, edited or unknown update
|
|
66
|
+
lines and preferences that quote the update wording.
|
|
67
|
+
- `sh -n`, `dash -n` and `shellcheck -S error` on `scripts/install.sh`: clean.
|
|
68
|
+
- `git diff --check`: clean.
|
|
69
|
+
- An independent read-only review found four issues in the update-line handling and its
|
|
70
|
+
documentation (an unrecognized notify-only line could turn into an update grant); all
|
|
71
|
+
were fixed and a second review pass confirmed the fixes.
|
|
72
|
+
|
|
73
|
+
The full suite runs in the Validate workflow for the tagged commit.
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
# nobrainer-tech-flow 2.7.0: delegation where it pays, owner requests in the goal file
|
|
2
|
+
|
|
3
|
+
Release date: 2026-10-25.
|
|
4
|
+
|
|
5
|
+
This release changes workflow guidance and delegation, the optional Claude Code guards,
|
|
6
|
+
`nobrainer-team`, `nobrainer-security` and `nobrainer-build`. The setup record and the module set (eighteen) do not change.
|
|
7
|
+
|
|
8
|
+
## What changes
|
|
9
|
+
|
|
10
|
+
- **Done is defined and visible.** `skills/nobrainer-tech-flow/SKILL.md` now has the
|
|
11
|
+
agent show the owner what done means before substantial work and set it as the
|
|
12
|
+
host-native goal where supported; `references/delivery.md`, `references/project-start.md`
|
|
13
|
+
and `references/long-run-state.md` replace "create a native goal only when explicitly
|
|
14
|
+
requested" with "set the outcome and DoD as the native goal when the host offers one",
|
|
15
|
+
so the owner can see whether the goal is running, paused or stopped. The Markdown goal
|
|
16
|
+
stays the canonical, portable record. The TODO stays visible: the canonical TODO is
|
|
17
|
+
mirrored in the host's plan or todo tool when it has one, otherwise shown as the
|
|
18
|
+
Progress checklist (`SKILL.md`, `references/delivery.md`, `references/setup.md`).
|
|
19
|
+
- **Delegation only where it pays.** `references/delivery.md` "Coordinated team
|
|
20
|
+
execution" now makes one MAIN loop that loads skills on demand the default. A unit
|
|
21
|
+
goes to a native worker only when parallel work, context isolation, independent
|
|
22
|
+
verification or specialization outweighs the cost, and the plan names that condition;
|
|
23
|
+
without one, the unit stays in MAIN. Work is split by context, not by type of work, so
|
|
24
|
+
the worker that changes a feature also writes and runs its tests. The 2.6.0 rules that
|
|
25
|
+
made delegation the default and said a missing measured speedup was no reason to keep
|
|
26
|
+
work in MAIN are removed. An owner or host rule that asks for more delegation still
|
|
27
|
+
controls. `SKILL.md`, `AGENTS.md`, `CLAUDE.md`, `nobrainer-team`,
|
|
28
|
+
`nobrainer-auto-fine-tune`, `references/model-routing.md` (`STANDARD` is now the
|
|
29
|
+
default and `ROUTED` applies only to qualifying units), `references/long-run-state.md`,
|
|
30
|
+
the shared bootstrap, the Copilot instructions, the
|
|
31
|
+
personalization block written by the installers, the README and the workflow diagram
|
|
32
|
+
say the same. The change follows Anthropic's published guidance:
|
|
33
|
+
[when to fold subagents into the main agent loop](https://claude.com/resources/articles/building-agents-when-to-fold-subagents-into-your-main-agent-loop)
|
|
34
|
+
and [when multi-agent systems help](https://www.claude.com/blog/building-multi-agent-systems-when-and-how-to-use-them),
|
|
35
|
+
which reports that multi-agent implementations typically use three to ten times more
|
|
36
|
+
tokens than a single agent for equivalent tasks.
|
|
37
|
+
- **Owner requests go into the goal file as they arrive.** In
|
|
38
|
+
`skills/nobrainer-tech-flow/SKILL.md` the detailed-ledger gate has a new condition: the
|
|
39
|
+
owner keeps adding requests mid-run in one long conversation. A new section of
|
|
40
|
+
`references/long-run-state.md`, "New owner requests", sets the rule. While the ledger is
|
|
41
|
+
active, the agent records each new request or idea before it continues any work, even
|
|
42
|
+
when the request is deferred. The row quotes the owner's words (minus any secret) and
|
|
43
|
+
carries the date and the status `PENDING`, or `READY` when nothing blocks it. When the
|
|
44
|
+
gate first passes mid-conversation, earlier unfinished requests are backfilled. Rows are
|
|
45
|
+
reconciled at every checkpoint, after compaction and at closeout, and none is silently
|
|
46
|
+
dropped. At closeout each row is `ACCEPTED`, `STOPPED` with the owner decision that
|
|
47
|
+
stopped it, or visibly open with its next step. In `references/correction-hooks.md`,
|
|
48
|
+
`OWNER_DECISION_CHANGED` now acts as soon as the change arrives, before other work,
|
|
49
|
+
updates the goal-file row when a ledger is active, and keeps other project instruction
|
|
50
|
+
files from carrying the old rule: under `AUTO_SCOPED` it edits the contradicting line,
|
|
51
|
+
under `ASK` it prepares the exact diff and asks once, and under `OFF` it names the stale
|
|
52
|
+
line in the final report. The goal-file block gains `CURRENT_MILESTONE`: one short-term
|
|
53
|
+
goal derived from `OUTCOME` and the open request rows, small enough to finish and verify
|
|
54
|
+
in the current session. The agent works toward it without waiting, sets the next
|
|
55
|
+
milestone from the open rows when it is accepted, and re-derives it at once when the
|
|
56
|
+
owner changes a decision or a new request changes what matters most; accepting a
|
|
57
|
+
milestone never closes `OUTCOME`. `OWNER_DECISION_CHANGED` resumes on that re-derived
|
|
58
|
+
milestone. The default task-local goal file is
|
|
59
|
+
`.nobrainer/goal.md`, which the context inventory already searches; it should not be
|
|
60
|
+
committed to a public repository. The short restatements of the gate in
|
|
61
|
+
`references/routing.md`, `references/setup.md`, `AGENTS.md`, `CLAUDE.md` and the
|
|
62
|
+
README say the same.
|
|
63
|
+
- **The guards point back to the goal file after compaction.** The optional Claude Code
|
|
64
|
+
guards gain a fourth hook, SessionStart with the matcher `compact|resume|clear`. It
|
|
65
|
+
tells the agent to re-read up to three active Flow goal files: files with a `GOAL_ID:`
|
|
66
|
+
line and a `STATUS` other than `COMPLETE` in the project root, `tasks/`, `docs/` or
|
|
67
|
+
`.nobrainer/`. It prints only each path and a known `STATUS` word, never other
|
|
68
|
+
goal-file text. It follows no symlink, skips unusual file names, stops after 5,000
|
|
69
|
+
folder entries or 200 files, and prints nothing on any error.
|
|
70
|
+
`scripts/install_guards.py` now reports an install from an earlier version as an
|
|
71
|
+
update. If you already use the guards, update your Git checkout to 2.7.0 first, so the
|
|
72
|
+
hooks' `flow_guard.py` knows the new mode, then preview the change with
|
|
73
|
+
`python3 scripts/install.py --client claude --guards`, apply it with `--apply` and
|
|
74
|
+
restart Claude Code. Until then the three earlier hooks keep working unchanged. The hook
|
|
75
|
+
only finds goal files that already exist; it does not write one.
|
|
76
|
+
- **Team uses task-local specialists, not third-party skills.** `nobrainer-team` no
|
|
77
|
+
longer searches for, downloads, installs or runs external skills, and it writes into no
|
|
78
|
+
client's skill folder. When a capability gap remains after curated skills, installed
|
|
79
|
+
skills, project tools and bounded research, MAIN writes a specialist brief (role,
|
|
80
|
+
method from project docs or verified primary sources, allowed actions, write scope,
|
|
81
|
+
acceptance and report) for a native worker. The brief stays in the task plan and is
|
|
82
|
+
discarded afterwards. The module's description now says "task-local specialist briefs".
|
|
83
|
+
- **A clean security result needs more than one pass.** In
|
|
84
|
+
`skills/nobrainer-security/SKILL.md` one model pass counts as a sample of the scope, not
|
|
85
|
+
as coverage. Before `CLEAN`, at least one more independent pass starts from a different
|
|
86
|
+
entry point, trust boundary or data-flow direction; the review stops when a pass adds no
|
|
87
|
+
new verified finding and reports how many passes ran. After a fix, when the defect was
|
|
88
|
+
public or reachable before it, the agent checks the available logs or other evidence for
|
|
89
|
+
exploitation during that exposure window, or lists the window under
|
|
90
|
+
`UNTESTED_OR_INACCESSIBLE_SURFACE`. In `references/delivery.md` the security-sensitive
|
|
91
|
+
paths that need an independent review and stay owner-gated, however small the diff, now
|
|
92
|
+
name authentication, permissions, payments and personal data. Work from an untrusted or
|
|
93
|
+
unknown author never takes the low-risk path, and a user-interface change needs rendered
|
|
94
|
+
evidence, a screenshot or recording, before and after where possible; unit tests alone
|
|
95
|
+
do not prove it.
|
|
96
|
+
- **Stale conventions are reported, not followed silently.** In
|
|
97
|
+
`skills/nobrainer-build/SKILL.md`, when instruction files or docs describe a coding
|
|
98
|
+
convention that the existing code does not follow, the agent follows the convention the
|
|
99
|
+
code uses, unless the instruction is an explicit owner rule or names a deliberate
|
|
100
|
+
migration, and lists each disagreement in its final report. When the code wins, the
|
|
101
|
+
report includes the exact edit that fixes the stale instruction file, applied only as
|
|
102
|
+
the project's `LEARNING_WRITE_POLICY` allows, so the next run does not inherit the stale
|
|
103
|
+
rule; when an owner rule or migration wins, it names the code change required. Owner
|
|
104
|
+
rules on safety, authority and workflow always apply.
|
|
105
|
+
- **Accurate install documentation.** The README lists the free remote MCP server
|
|
106
|
+
(`https://mcp.nobrainer.tech/mcp`, no sign-in, stateless, six read-only tools) as a
|
|
107
|
+
sixth channel and says it does not install the eighteen modules. `docs/CHAT_PLUGINS.md`
|
|
108
|
+
and `docs/INSTALL.md` now say the npm package is published.
|
|
109
|
+
- **Test fixes.** The bounded-runner interrupt test waits until the child's pid file
|
|
110
|
+
holds a number, not only until it exists, which removes an intermittent CI failure.
|
|
111
|
+
A duplicate GitHub transport test that shadowed another one was removed.
|
|
112
|
+
|
|
113
|
+
## The remote MCP server
|
|
114
|
+
|
|
115
|
+
The MCP server in `mcp/` is deployed separately and is not part of the npm package.
|
|
116
|
+
Since 2.6.0 it returns a goal-file block with a renewed contract token when
|
|
117
|
+
`get_flow_step` is called with a contract token and `event: "resume"`, and a scheduled, read-only workflow
|
|
118
|
+
warns three days before the bundled model-advisor benchmark snapshot expires. Its
|
|
119
|
+
guidance cards are still pinned to 2.6.0 and move to this release in a separate change
|
|
120
|
+
after the tag.
|
|
121
|
+
|
|
122
|
+
## Verification record
|
|
123
|
+
|
|
124
|
+
Local checks (macOS, Python 3.14):
|
|
125
|
+
|
|
126
|
+
- `python3 scripts/validate_skills.py` and `python3 scripts/validate_skills.py --suite`: OK.
|
|
127
|
+
- `skills/nobrainer-tech-flow/SKILL.md` stays within the suite budget (239 lines, 1,748
|
|
128
|
+
words; limits 240 and 1,750); `AGENTS.md` and `CLAUDE.md` stay byte-identical within
|
|
129
|
+
theirs (205 lines, 1,615 words; limits 205 and 1,620).
|
|
130
|
+
- `python3 -m unittest tests.test_suite`: 74 tests OK. Every other test module, run
|
|
131
|
+
separately: OK.
|
|
132
|
+
- `git diff --check`: clean.
|
|
133
|
+
- An independent read-only review of this release preparation found three issues: the
|
|
134
|
+
always-loaded instructions went over their word budget, the guard upgrade steps were
|
|
135
|
+
incomplete, and the release text overstated what the request rule guarantees. All three
|
|
136
|
+
were fixed. Two further independent read-only reviews of the delegation, security and
|
|
137
|
+
conventions changes found four low and two medium issues: README summaries that dropped
|
|
138
|
+
conditions, tests that did not protect the exceptions or the cost gate, and the
|
|
139
|
+
delegation-first default still present in `nobrainer-auto-fine-tune` and
|
|
140
|
+
`references/model-routing.md`. All were fixed, and a test now checks that the retired
|
|
141
|
+
delegation defaults do not return on the active surfaces.
|
|
142
|
+
|
|
143
|
+
The changes it ships were each reviewed and passed CI in their own pull requests (#98,
|
|
144
|
+
#101, #109, #110, #111, #112, #113, #115). The full suite runs in the Validate workflow for the
|
|
145
|
+
tagged commit.
|
package/gemini-extension.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nobrainer-tech-flow",
|
|
3
3
|
"description": "From task to done. nobrainer-tech-flow is one workflow of 18 modules for AI coding agents: it scopes the task, delegates ready work, checks the result and hands over the evidence, including what was not checked.",
|
|
4
|
-
"version": "2.
|
|
4
|
+
"version": "2.7.0",
|
|
5
5
|
"contextFileName": "GEMINI.md"
|
|
6
6
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nobrainer-tech-flow",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.7.0",
|
|
4
4
|
"description": "From task to done. nobrainer-tech-flow is one workflow of 18 modules for AI coding agents: it scopes the task, delegates ready work, checks the result and hands over the evidence, including what was not checked.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": ".opencode/plugins/nobrainer-tech-skills.js",
|
package/plugin.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json",
|
|
3
3
|
"name": "nobrainer-tech-flow",
|
|
4
4
|
"description": "From task to done. nobrainer-tech-flow is one workflow of 18 modules for AI coding agents: it scopes the task, delegates ready work, checks the result and hands over the evidence, including what was not checked.",
|
|
5
|
-
"version": "2.
|
|
5
|
+
"version": "2.7.0",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "NoBrainer Tech",
|
|
8
8
|
"url": "https://nobrainer.tech"
|
package/scripts/install.py
CHANGED
|
@@ -4,7 +4,9 @@
|
|
|
4
4
|
Every run is a dry run until --apply. The skills are linked and the managed
|
|
5
5
|
instruction block is written by the same helpers as the manual and guided setups,
|
|
6
6
|
and --undo uses the guided setup's rollback state (as scripts/install.sh does), so
|
|
7
|
-
every path reverses the same way.
|
|
7
|
+
every path reverses the same way. The only standing authorization it writes is the
|
|
8
|
+
default daily update of Flow itself, and an existing block keeps notifying unless it
|
|
9
|
+
already held that update line.
|
|
8
10
|
"""
|
|
9
11
|
|
|
10
12
|
from __future__ import annotations
|
package/scripts/install.sh
CHANGED
|
@@ -4,7 +4,8 @@
|
|
|
4
4
|
# Same flags, locations, conflict rule and setup record as scripts/install.py, so
|
|
5
5
|
# either one can undo what the other did. Every run previews until --apply. The
|
|
6
6
|
# skills are linked to this checkout (never copied), one managed instruction block
|
|
7
|
-
# is added
|
|
7
|
+
# is added. Its only standing authorization is the default daily update of Flow itself;
|
|
8
|
+
# an existing block keeps notifying unless it already held that line. A managed block that is
|
|
8
9
|
# already there is replaced by this version's text when it differs, and everything
|
|
9
10
|
# outside the two markers stays byte for byte, as install.py does. One difference: a
|
|
10
11
|
# block that carries options (a standing authorization, a wiki root or a preference)
|
|
@@ -47,6 +48,12 @@ SEPARATORS=$(printf '\342\200[\250\251]')
|
|
|
47
48
|
TAB=$(printf '\t')
|
|
48
49
|
CR=$(printf '\r')
|
|
49
50
|
|
|
51
|
+
# The update line of the block: on by default; an existing block that only notifies
|
|
52
|
+
# (written with --no-auto-update, or the default before 2.6.0) keeps notifying.
|
|
53
|
+
AUTO_UPDATE_LINE='- Once a day on first use, update nobrainer-tech-flow to its latest verified stable release from the canonical source, with a backup; change nothing else and ask if unsure.'
|
|
54
|
+
NOTIFY_UPDATE_LINE='- Once a day on first use, tell the owner when a newer stable nobrainer-tech-flow release exists; do not update it yourself.'
|
|
55
|
+
update_line=$AUTO_UPDATE_LINE
|
|
56
|
+
|
|
50
57
|
# The block scripts/install_personalization.py writes without options, byte for byte
|
|
51
58
|
# (a test compares them).
|
|
52
59
|
block() {
|
|
@@ -56,12 +63,14 @@ block() {
|
|
|
56
63
|
|
|
57
64
|
- Use the `nobrainer-tech-flow` module as the task entrypoint when this client supports skill invocation, by the exact name this client lists for it. In Codex that is `$nobrainer-tech-flow:nobrainer-tech-flow` when modules are listed under the plugin name, or `$nobrainer-tech-flow` when they are listed plainly. If unavailable, check the documented installation path and report that limitation honestly.
|
|
58
65
|
- On first setup, load `nobrainer-auto-fine-tune` for a read-only capability audit; preserve MAIN model and effort, and mark unverified runtime values `UNKNOWN`.
|
|
59
|
-
- Preserve the user's selected MAIN model and effort. Inspect the host's actual subagent models, capabilities, concurrency and quota; delegate
|
|
66
|
+
- Preserve the user's selected MAIN model and effort. Inspect the host's actual subagent models, capabilities, concurrency and quota; work in one MAIN loop and delegate only units that gain from parallel work, context isolation, independent review or specialization. Keep coordination in MAIN. Never assume a model is available or silently substitute one.
|
|
60
67
|
- Split substantial work into bounded tasks with clear outputs, exclusive write scope, dependencies, and verification. Keep integration and acceptance in MAIN; avoid duplicate or filler tasks.
|
|
61
68
|
- Derive short-term goals from the user's long-term direction (LDD) and define observable completion criteria. At project start, inspect the existing structure and layers, then recommend a fitting approach.
|
|
62
69
|
- At project start, discover whether a relevant wiki exists. If one exists, read its `WIKI.md`, locate relevant `index.md` entries with a targeted search, then read only the relevant pages. Ask before creating a wiki unless project rules or prior authorization already settle it.
|
|
63
70
|
- Assess context and checkpoint at appropriate milestones. Recommend session rotation when it would help; do not restart or archive automatically. When rotation is authorized, use the supported lifecycle, verify exact successor takeover by ID/readback, and archive the old session only after that readback. Do not create recursive visible workers or claim a restart when unsupported.
|
|
64
|
-
|
|
71
|
+
EOF
|
|
72
|
+
printf '%s\n' "$update_line"
|
|
73
|
+
cat <<'EOF'
|
|
65
74
|
- Use `nobrainer-writing` for material writing when available; make technical documentation concrete, source-backed, and technically verified. Preserve facts, use the user's language, and verify at the actual delivery layer.
|
|
66
75
|
<!-- NOBRAINER-TECH-FLOW:END -->
|
|
67
76
|
EOF
|
|
@@ -806,6 +815,12 @@ plan_instructions() {
|
|
|
806
815
|
die 3 "malformed or duplicated nobrainer-tech-flow managed markers in $target"
|
|
807
816
|
fi
|
|
808
817
|
file_status=present
|
|
818
|
+
# An existing block keeps updating only when it holds the update line as its own line;
|
|
819
|
+
# a notify-only, edited or unknown line keeps notifying, so no grant is ever inferred.
|
|
820
|
+
if block_lines "$target" && ! head -n "$block_to" "$target" | tail -n "+$block_from" |
|
|
821
|
+
LC_ALL=C sed 's/[[:space:]]*$//' | grep -a -q -x -F -e "$AUTO_UPDATE_LINE"; then
|
|
822
|
+
update_line=$NOTIFY_UPDATE_LINE
|
|
823
|
+
fi
|
|
809
824
|
# A block of an earlier version is brought up to date, but only one that can be replaced
|
|
810
825
|
# without losing anything: its markers stand on lines of their own, and it holds no option.
|
|
811
826
|
if ! block_is_default && block_lines "$target" && ! block_has_options; then
|
|
@@ -827,6 +842,10 @@ block_lines() {
|
|
|
827
842
|
[ "$block_from" -lt "$block_to" ]
|
|
828
843
|
}
|
|
829
844
|
|
|
845
|
+
update_status() {
|
|
846
|
+
if [ "$update_line" = "$NOTIFY_UPDATE_LINE" ]; then echo CHECK_AND_NOTIFY; else echo AUTHORIZED_SAFE_VERIFIED_ONLY; fi
|
|
847
|
+
}
|
|
848
|
+
|
|
830
849
|
block_is_default() {
|
|
831
850
|
block_lines "$target" || return 1
|
|
832
851
|
_b_text=$(head -n "$block_to" "$target" | tail -n "+$block_from")
|
|
@@ -836,7 +855,7 @@ block_is_default() {
|
|
|
836
855
|
}
|
|
837
856
|
|
|
838
857
|
# block_has_options: the block block_lines found in $target carries something the owner
|
|
839
|
-
# chose: a standing authorization, a wiki root or a preference. Only install.py and
|
|
858
|
+
# chose: a pre-2.6 standing authorization, a wiki root or a preference. Only install.py and
|
|
840
859
|
# scripts/install_personalization.py --keep-options carry those over to a new block.
|
|
841
860
|
block_has_options() {
|
|
842
861
|
head -n "$block_to" "$target" | tail -n "+$block_from" |
|
|
@@ -873,7 +892,7 @@ preview() {
|
|
|
873
892
|
elif [ "$file_status" = refresh ]; then
|
|
874
893
|
block_lines "$target"
|
|
875
894
|
say "UPDATE: nobrainer-tech-flow personalization block"
|
|
876
|
-
say "AUTO_UPDATE:
|
|
895
|
+
say "AUTO_UPDATE: $(update_status)"
|
|
877
896
|
say "AUTO_SESSION_RESTART: ASSESS_CHECKPOINT_RECOMMEND"
|
|
878
897
|
say "PRESERVED: content outside the managed block"
|
|
879
898
|
say "DIFF:"
|
|
@@ -881,7 +900,7 @@ preview() {
|
|
|
881
900
|
block | sed 's/^/+/'
|
|
882
901
|
else
|
|
883
902
|
say "MISSING: nobrainer-tech-flow personalization block"
|
|
884
|
-
say "AUTO_UPDATE:
|
|
903
|
+
say "AUTO_UPDATE: $(update_status)"
|
|
885
904
|
say "AUTO_SESSION_RESTART: ASSESS_CHECKPOINT_RECOMMEND"
|
|
886
905
|
say "DIFF:"
|
|
887
906
|
block | sed 's/^/+/'
|
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
#!/usr/bin/env python3
|
|
2
2
|
"""Preview, add or remove the optional nobrainer-tech-flow guards for Claude Code.
|
|
3
3
|
|
|
4
|
-
The guards are
|
|
5
|
-
that asks before common risky shell commands,
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
4
|
+
The guards are four hooks in the Claude Code user settings.json: a PreToolUse hook
|
|
5
|
+
that asks before common risky shell commands, Stop and SubagentStop hooks that ask
|
|
6
|
+
for a proof line once, and a SessionStart hook that, after compaction, resume or
|
|
7
|
+
clear, names the active Flow goal files to re-read. Every run is a preview until
|
|
8
|
+
--apply, and an install from an earlier version is reported as an update. The hooks
|
|
9
|
+
point at flow_guard.py through the skill link that scripts/install.py created, so
|
|
10
|
+
they keep working when the checkout is updated. Our entries are the hooks whose
|
|
11
|
+
command is exactly one this script generates; --undo --apply removes those and
|
|
12
|
+
nothing else. The preview names only those hooks and the settings path, never other
|
|
13
|
+
settings, which can hold tokens.
|
|
12
14
|
"""
|
|
13
15
|
|
|
14
16
|
from __future__ import annotations
|
|
@@ -28,8 +30,14 @@ from pathlib import Path
|
|
|
28
30
|
ROOT = Path(__file__).resolve().parents[1]
|
|
29
31
|
INSTALL_SKILLS = ROOT / "scripts" / "install_skills.py"
|
|
30
32
|
GUARD = Path("nobrainer-tech-flow") / "scripts" / "flow_guard.py"
|
|
31
|
-
EVENTS = (
|
|
33
|
+
EVENTS = (
|
|
34
|
+
("PreToolUse", "Bash", "pre-tool"),
|
|
35
|
+
("Stop", None, "stop"),
|
|
36
|
+
("SubagentStop", None, "stop"),
|
|
37
|
+
("SessionStart", "compact|resume|clear", "session"),
|
|
38
|
+
)
|
|
32
39
|
TIMEOUT = 10
|
|
40
|
+
DONE = {"add": "INSTALLED", "update": "UPDATED", "remove": "REMOVED"}
|
|
33
41
|
DISCLAIMER = (
|
|
34
42
|
"NOTE: a seatbelt: it asks before common risky commands; it is not a security "
|
|
35
43
|
"boundary, and sh -c or variables bypass it."
|
|
@@ -223,18 +231,26 @@ def run(apply: bool, undo: bool, home: Path | None, rerun: str = "python3 script
|
|
|
223
231
|
print(f"UP TO DATE: the Flow guards are already in {settings_path}; nothing changed")
|
|
224
232
|
return 0
|
|
225
233
|
after = render(updated)
|
|
234
|
+
# Some of our hooks but not exactly the current set, as an install from an earlier
|
|
235
|
+
# version leaves them: an update, never reported as current.
|
|
236
|
+
present = len(listed(settings, guard))
|
|
237
|
+
action = "remove" if undo else "update" if present else "add"
|
|
226
238
|
if not apply:
|
|
227
239
|
hooks = listed(settings if undo else updated, guard)
|
|
228
|
-
|
|
229
|
-
|
|
240
|
+
target = {
|
|
241
|
+
"remove": f"remove {len(hooks)} hooks from {settings_path}",
|
|
242
|
+
"update": f"update the Flow guards in {settings_path} ({present} hooks now, {len(hooks)} after)",
|
|
243
|
+
"add": f"add {len(hooks)} hooks to {settings_path}",
|
|
244
|
+
}[action]
|
|
245
|
+
print(f"PREVIEW: would {target}; other settings keep their values:")
|
|
230
246
|
print("\n".join(hooks))
|
|
231
247
|
if not undo:
|
|
232
248
|
print(DISCLAIMER)
|
|
233
249
|
flags = "--undo --apply" if undo else "--apply"
|
|
234
|
-
print(f"NO_CHANGES: preview only; {
|
|
250
|
+
print(f"NO_CHANGES: preview only; {action} them with: {rerun.replace('{flags}', flags)}")
|
|
235
251
|
return 0
|
|
236
252
|
backup = write(settings_path, before, after)
|
|
237
|
-
print(f"{
|
|
253
|
+
print(f"{DONE[action]}: Flow guards in {settings_path}")
|
|
238
254
|
if backup:
|
|
239
255
|
print(f"BACKUP: {backup}")
|
|
240
256
|
if not undo:
|
|
@@ -27,10 +27,17 @@ LEGACY_FLOW_INSTRUCTIONS = re.compile(
|
|
|
27
27
|
r"\bnobrainer-ultra\b|^\s*#{1,6}\s+NoBrainer(?:[ .]?Tech)?\s+Flow\b",
|
|
28
28
|
re.IGNORECASE | re.MULTILINE,
|
|
29
29
|
)
|
|
30
|
-
# The
|
|
30
|
+
# The lines that carry a standing authorization. --keep-options recognises a grant
|
|
31
31
|
# only as one of these exact lines, never as a phrase somewhere in the block, so free
|
|
32
32
|
# text in a preference cannot forge one.
|
|
33
|
-
AUTO_UPDATE_RULE = "-
|
|
33
|
+
AUTO_UPDATE_RULE = "- Once a day on first use, update nobrainer-tech-flow to its latest verified stable release from the canonical source, with a backup; change nothing else and ask if unsure."
|
|
34
|
+
# The opt-out written by --no-auto-update.
|
|
35
|
+
NOTIFY_UPDATE_RULE = "- Once a day on first use, tell the owner when a newer stable nobrainer-tech-flow release exists; do not update it yourself."
|
|
36
|
+
# Lines written before 2.6.0. --keep-options maps them to the short rules above and
|
|
37
|
+
# keeps the owner's choice: the old grant stays a grant, the old notify-only default
|
|
38
|
+
# stays notify-only.
|
|
39
|
+
LEGACY_AUTO_UPDATE_RULE = "- On the first `nobrainer-tech-flow` use each calendar day, check for a safe verified update when this client exposes a supported check. This setting grants standing authorization to apply a `nobrainer-tech-flow`-only update after verifying the canonical source/version, reviewing the exact changes, and making a recoverable backup. Never apply destructive, unrelated, or uncertain changes; ask the owner first. If the client is inactive or cannot check, do not claim a check occurred."
|
|
40
|
+
LEGACY_NOTIFY_UPDATE_RULE = "- On the first `nobrainer-tech-flow` use each calendar day, check for available updates when this client exposes a supported check and notify the owner; do not apply them automatically. If the client is inactive or cannot check, do not claim a check occurred."
|
|
34
41
|
AUTO_SESSION_RULE = "- This setting grants standing authorization for session rotation only when the host supports creating a fresh successor, context or checkpoint evidence warrants rotation, and no write is in flight. Create the successor, verify exact takeover by ID/readback, and archive the old session only after that readback. Do not create recursive visible workers or claim a restart when unsupported."
|
|
35
42
|
|
|
36
43
|
|
|
@@ -57,6 +64,28 @@ def earlier_grant(existing: str, rule: str, phrase: str, label: str, flag: str)
|
|
|
57
64
|
return False
|
|
58
65
|
|
|
59
66
|
|
|
67
|
+
# Wording of an update grant, current or pre-2.6, used only to warn that an edited one
|
|
68
|
+
# was not kept.
|
|
69
|
+
UPDATE_GRANT_PHRASES = (
|
|
70
|
+
"update nobrainer-tech-flow to its latest verified stable release",
|
|
71
|
+
"grants standing authorization to apply a `nobrainer-tech-flow`-only update",
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def saved_update_choice(existing: str) -> bool:
|
|
76
|
+
"""True only when an existing block holds an update grant as its own line.
|
|
77
|
+
|
|
78
|
+
Anything else, a notify-only line, an edited or unknown one, keeps notifying:
|
|
79
|
+
an update grant is never inferred. Trailing spaces on the line are ignored, and
|
|
80
|
+
a preference that quotes the wording is not a line of its own.
|
|
81
|
+
"""
|
|
82
|
+
|
|
83
|
+
return any(
|
|
84
|
+
re.search(r"(?m)^" + re.escape(rule) + r"[ \t]*\r?$", existing) is not None
|
|
85
|
+
for rule in (AUTO_UPDATE_RULE, LEGACY_AUTO_UPDATE_RULE)
|
|
86
|
+
)
|
|
87
|
+
|
|
88
|
+
|
|
60
89
|
def unsafe_line(value: str) -> bool:
|
|
61
90
|
"""True when ``value`` cannot be one plain Markdown line (or could split into two)."""
|
|
62
91
|
|
|
@@ -85,11 +114,7 @@ def build_block(
|
|
|
85
114
|
if wiki_root is not None
|
|
86
115
|
else "- At project start, discover whether a relevant wiki exists. If one exists, read its `WIKI.md`, locate relevant `index.md` entries with a targeted search, then read only the relevant pages. Ask before creating a wiki unless project rules or prior authorization already settle it."
|
|
87
116
|
)
|
|
88
|
-
update_rule =
|
|
89
|
-
AUTO_UPDATE_RULE
|
|
90
|
-
if auto_update
|
|
91
|
-
else "- On the first `nobrainer-tech-flow` use each calendar day, check for available updates when this client exposes a supported check and notify the owner; do not apply them automatically. If the client is inactive or cannot check, do not claim a check occurred."
|
|
92
|
-
)
|
|
117
|
+
update_rule = AUTO_UPDATE_RULE if auto_update else NOTIFY_UPDATE_RULE
|
|
93
118
|
session_rule = (
|
|
94
119
|
AUTO_SESSION_RULE
|
|
95
120
|
if auto_session_restart
|
|
@@ -105,7 +130,7 @@ def build_block(
|
|
|
105
130
|
|
|
106
131
|
- Use the `nobrainer-tech-flow` module as the task entrypoint when this client supports skill invocation, by the exact name this client lists for it. In Codex that is `$nobrainer-tech-flow:nobrainer-tech-flow` when modules are listed under the plugin name, or `$nobrainer-tech-flow` when they are listed plainly. If unavailable, check the documented installation path and report that limitation honestly.
|
|
107
132
|
- On first setup, load `nobrainer-auto-fine-tune` for a read-only capability audit; preserve MAIN model and effort, and mark unverified runtime values `UNKNOWN`.
|
|
108
|
-
- Preserve the user's selected MAIN model and effort. Inspect the host's actual subagent models, capabilities, concurrency and quota; delegate
|
|
133
|
+
- Preserve the user's selected MAIN model and effort. Inspect the host's actual subagent models, capabilities, concurrency and quota; work in one MAIN loop and delegate only units that gain from parallel work, context isolation, independent review or specialization. Keep coordination in MAIN. Never assume a model is available or silently substitute one.
|
|
109
134
|
- Split substantial work into bounded tasks with clear outputs, exclusive write scope, dependencies, and verification. Keep integration and acceptance in MAIN; avoid duplicate or filler tasks.
|
|
110
135
|
- Derive short-term goals from the user's long-term direction (LDD) and define observable completion criteria. At project start, inspect the existing structure and layers, then recommend a fitting approach.
|
|
111
136
|
{wiki_rule}
|
|
@@ -356,10 +381,16 @@ def parse_args(argv: list[str] | None = None) -> argparse.Namespace:
|
|
|
356
381
|
type=Path,
|
|
357
382
|
help="project wiki root containing WIKI.md; its resolved path is added to the managed instructions",
|
|
358
383
|
)
|
|
359
|
-
parser.
|
|
384
|
+
updates = parser.add_mutually_exclusive_group()
|
|
385
|
+
updates.add_argument(
|
|
360
386
|
"--auto-update",
|
|
361
387
|
action="store_true",
|
|
362
|
-
help="
|
|
388
|
+
help="update nobrainer-tech-flow once a day from its verified stable releases (the default)",
|
|
389
|
+
)
|
|
390
|
+
updates.add_argument(
|
|
391
|
+
"--no-auto-update",
|
|
392
|
+
action="store_true",
|
|
393
|
+
help="only tell the owner about a newer stable release; never update automatically",
|
|
363
394
|
)
|
|
364
395
|
parser.add_argument(
|
|
365
396
|
"--auto-session-restart",
|
|
@@ -374,7 +405,7 @@ def parse_args(argv: list[str] | None = None) -> argparse.Namespace:
|
|
|
374
405
|
"--keep-options",
|
|
375
406
|
action="store_true",
|
|
376
407
|
help=(
|
|
377
|
-
"keep the
|
|
408
|
+
"keep the update, session-restart and wiki-root settings already in the "
|
|
378
409
|
"managed block; flags given on this run are added to them, never removed"
|
|
379
410
|
),
|
|
380
411
|
)
|
|
@@ -429,15 +460,19 @@ def main(argv: list[str] | None = None) -> int:
|
|
|
429
460
|
saved = SAVED_PREFERENCE.search(existing)
|
|
430
461
|
if saved:
|
|
431
462
|
preferences = saved.group(1)
|
|
432
|
-
auto_update = args.
|
|
463
|
+
auto_update = not args.no_auto_update
|
|
433
464
|
auto_session_restart = args.auto_session_restart
|
|
434
465
|
if args.keep_options and existing:
|
|
435
466
|
kept: list[str] = []
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
467
|
+
saved_update = saved_update_choice(existing)
|
|
468
|
+
if not (args.auto_update or args.no_auto_update) and not saved_update:
|
|
469
|
+
auto_update = False
|
|
470
|
+
kept.append("notify-only updates")
|
|
471
|
+
if any(phrase in existing for phrase in UPDATE_GRANT_PHRASES):
|
|
472
|
+
print(
|
|
473
|
+
"NOTE: an earlier update authorization was not kept because its line no longer "
|
|
474
|
+
"matches what this installer writes; pass --auto-update to grant it again"
|
|
475
|
+
)
|
|
441
476
|
if not auto_session_restart and earlier_grant(
|
|
442
477
|
existing,
|
|
443
478
|
AUTO_SESSION_RULE,
|
|
@@ -27,7 +27,7 @@ Keep advertised, configured, callable, and successfully invoked capabilities dis
|
|
|
27
27
|
|
|
28
28
|
For a one-off, low-risk task, use the owner's selected MAIN and current known tools; skip benchmarking and state that routing is uncalibrated. For a recurring workflow, material model choice, or task with meaningful quality/latency/cost tradeoffs, define a small bounded comparison before spending resources.
|
|
29
29
|
|
|
30
|
-
Classify the work by required expertise, context, accuracy, latency, cost sensitivity, confidentiality, dependence between units, and integration effort.
|
|
30
|
+
Classify the work by required expertise, context, accuracy, latency, cost sensitivity, confidentiality, dependence between units, and integration effort. MAIN is the default; calibration compares worker routes only for units that qualify under [team execution](../nobrainer-tech-flow/references/delivery.md#coordinated-team-execution) and have measurable acceptance and disjoint write scope. A missing benchmark does not block a qualifying unit's dispatch. When comparing routes, measure the critical path and observed concurrency, including setup, review and integration; worker count alone proves no benefit.
|
|
31
31
|
|
|
32
32
|
## Run a bounded, comparable calibration
|
|
33
33
|
|
|
@@ -26,6 +26,17 @@ Before the first write, resolve:
|
|
|
26
26
|
- cheapest useful failing proof, target tests, broader verifier/build/runtime;
|
|
27
27
|
- side effects, owner gates, rollback and the `Done clean` condition.
|
|
28
28
|
|
|
29
|
+
When instruction files or docs describe a coding convention the existing code
|
|
30
|
+
does not follow, do not pick one silently. Follow the convention the code uses,
|
|
31
|
+
unless the instruction is an explicit owner rule or names a deliberate migration,
|
|
32
|
+
and list each disagreement in the final report. When the code's convention wins,
|
|
33
|
+
include the exact edit that would bring the stale instruction file in line, and
|
|
34
|
+
apply it only as the project's `LEARNING_WRITE_POLICY` allows
|
|
35
|
+
([correction hooks](../nobrainer-tech-flow/references/correction-hooks.md)), so the
|
|
36
|
+
next run does not inherit the stale rule. When an owner rule or migration wins,
|
|
37
|
+
name the code change it requires instead. Owner rules on safety, authority and
|
|
38
|
+
workflow always apply.
|
|
39
|
+
|
|
29
40
|
Preserve unrelated changes. Use an isolated worktree or disjoint write scope
|
|
30
41
|
when another writer is active. If a missing requirement changes architecture,
|
|
31
42
|
scope, public behavior or safety, stop at `SPEC_CHANGE_PROPOSED`; do not invent it
|
|
@@ -37,7 +48,9 @@ Apply these principles as decision rules, not slogans:
|
|
|
37
48
|
|
|
38
49
|
- `KISS`: choose the simplest complete design that satisfies acceptance.
|
|
39
50
|
- `YAGNI`: do not add extension points, compatibility layers or options for an
|
|
40
|
-
unproven future requirement.
|
|
51
|
+
unproven future requirement. Before adding complexity for a speculative race
|
|
52
|
+
or security edge case, name the concrete failure, its likelihood and the cost;
|
|
53
|
+
add it only when that case is accepted.
|
|
41
54
|
- `DRY`: keep each rule and mutable fact under one owner, but do not abstract
|
|
42
55
|
incidental similarity. Duplication can be cheaper than the wrong coupling.
|
|
43
56
|
- `SOLID`: preserve cohesive responsibilities and stable dependency boundaries;
|
|
@@ -80,7 +93,9 @@ Reject a patch that contains any of the following without explicit acceptance:
|
|
|
80
93
|
- duplicate state owners, speculative abstractions or fallback stacks that make
|
|
81
94
|
failure ambiguous;
|
|
82
95
|
- tests that only assert a mock/fixture while the real contract remains
|
|
83
|
-
unexercised
|
|
96
|
+
unexercised;
|
|
97
|
+
- in user interfaces, taglines, helper text and secondary labels added to explain
|
|
98
|
+
a screen; if the screen needs them, fix the layout.
|
|
84
99
|
|
|
85
100
|
Names should explain intent. Comments should explain only non-obvious why,
|
|
86
101
|
constraints, risk or tradeoffs. Do not create a new README, framework or process
|
|
@@ -137,6 +137,11 @@ constraint, deployment setting, parser behavior or version fact that would make
|
|
|
137
137
|
the path unreachable. Reject generic hardening, style preferences, stale
|
|
138
138
|
advisories for another version and speculative chains missing a necessary step.
|
|
139
139
|
|
|
140
|
+
One model pass samples the scope; it does not prove coverage. Before `CLEAN`,
|
|
141
|
+
run at least one more independent pass that starts from a different entry point,
|
|
142
|
+
trust boundary or data-flow direction. Stop when a pass adds no new verified
|
|
143
|
+
finding, and report how many passes ran.
|
|
144
|
+
|
|
140
145
|
## Handoff and remediation
|
|
141
146
|
|
|
142
147
|
Security review ends with evidence and a fix contract. If remediation is in
|
|
@@ -146,6 +151,11 @@ security trace with fresh evidence. Consequential fixes still require an
|
|
|
146
151
|
independent `nobrainer-review` or release gate; self-authored code is not
|
|
147
152
|
self-approved.
|
|
148
153
|
|
|
154
|
+
A fix closes the path; it does not show the path was never used. When the
|
|
155
|
+
defect was public or reachable before the fix, check the available logs or
|
|
156
|
+
other evidence for exploitation during that exposure window. If that evidence
|
|
157
|
+
is unavailable, list the window under `UNTESTED_OR_INACCESSIBLE_SURFACE`.
|
|
158
|
+
|
|
149
159
|
## Final report
|
|
150
160
|
|
|
151
161
|
```text
|