devflow-kit 3.7.0 → 3.8.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/CHANGELOG.md +359 -1
- package/README.md +11 -11
- package/dist/agents/code.md +2 -4
- package/dist/agents/design.md +1 -1
- package/dist/agents/fix.md +6 -7
- package/dist/agents/git.md +1 -1
- package/dist/agents/harden.md +1 -1
- package/dist/agents/refactor.md +2 -4
- package/dist/agents/review.md +4 -4
- package/dist/agents/skim.md +2 -2
- package/dist/agents/triage.md +2 -2
- package/dist/cli/commands/capture.js +1 -1
- package/dist/cli/commands/curation-move-io.js +102 -0
- package/dist/cli/commands/curation-move-step.js +374 -0
- package/dist/cli/commands/{learning.js → curation.js} +302 -99
- package/dist/cli/commands/gate-level-prompts.js +426 -0
- package/dist/cli/commands/gates.js +34 -11
- package/dist/cli/commands/init-seed.js +11 -8
- package/dist/cli/commands/init.js +240 -54
- package/dist/cli/commands/memory.js +2 -2
- package/dist/cli/commands/prompt-io.js +37 -0
- package/dist/cli/commands/uninstall.js +81 -9
- package/dist/cli.js +2 -2
- package/dist/commands/bug-analysis.md +24 -35
- package/dist/commands/code-review.md +32 -36
- package/dist/commands/debug.md +4 -4
- package/dist/commands/dynamic-build.md +25 -24
- package/dist/commands/dynamic-plan.md +4 -4
- package/dist/commands/dynamic-profile.md +4 -4
- package/dist/commands/dynamic-tickets.md +4 -4
- package/dist/commands/explore.md +5 -5
- package/dist/commands/implement.md +52 -81
- package/dist/commands/plan.md +5 -5
- package/dist/commands/release.md +4 -4
- package/dist/commands/research.md +5 -5
- package/dist/commands/resolve.md +28 -30
- package/dist/commands/self-review.md +4 -12
- package/dist/core/assets.js +20 -20
- package/dist/core/curate-tuning-config.js +5 -6
- package/dist/core/curation-move-notice.js +84 -0
- package/dist/core/curation-move-skip.js +36 -0
- package/dist/core/curation-move.js +35 -0
- package/dist/core/curation-queue-cleanup.js +134 -0
- package/dist/core/curation-store.js +98 -0
- package/dist/core/{learning-variants.js → curation-variants.js} +65 -41
- package/dist/core/echo-value.js +11 -5
- package/dist/core/evidence-policy.js +1 -1
- package/dist/core/feature-switch.js +95 -19
- package/dist/core/fs-atomic.js +1 -1
- package/dist/core/gate-level.js +10 -2
- package/dist/core/git.js +16 -14
- package/dist/core/ledger-root.js +82 -22
- package/dist/core/linked-path.js +4 -4
- package/dist/core/manifest-lock.js +238 -0
- package/dist/core/manifest.js +58 -14
- package/dist/core/migrations.js +1 -13
- package/dist/core/observations.js +2 -2
- package/dist/core/plugins.js +15 -15
- package/dist/core/pool.js +26 -0
- package/dist/core/project-paths.js +103 -34
- package/dist/core/queue-drain.js +2 -2
- package/dist/core/tracked-areas.js +35 -0
- package/dist/core/tracker.js +1 -1
- package/dist/{learning-off → curation-off}/agents/code.md +2 -4
- package/dist/{learning-off → curation-off}/agents/fix.md +6 -7
- package/dist/{learning-off → curation-off}/agents/refactor.md +2 -4
- package/dist/{learning-off → curation-off}/agents/review.md +3 -3
- package/dist/{learning-off → curation-off}/agents/triage.md +1 -1
- package/dist/{learning-off → curation-off}/commands/bug-analysis.md +20 -31
- package/dist/{learning-off → curation-off}/commands/code-review.md +29 -33
- package/dist/{learning-off → curation-off}/commands/debug.md +1 -1
- package/dist/{learning-off → curation-off}/commands/dynamic-build.md +22 -21
- package/dist/{learning-off → curation-off}/commands/explore.md +1 -1
- package/dist/{learning-off → curation-off}/commands/implement.md +49 -78
- package/dist/{learning-off → curation-off}/commands/plan.md +1 -1
- package/dist/{learning-off → curation-off}/commands/resolve.md +25 -27
- package/dist/{learning-off → curation-off}/commands/self-review.md +1 -9
- package/dist/hud/components/{learning-counts.js → curation-counts.js} +36 -17
- package/dist/hud/config.js +1 -1
- package/dist/hud/index.js +6 -6
- package/dist/hud/render.js +3 -3
- package/dist/skills/git/references/pr/validate-branch.md +8 -5
- package/dist/skills/git/references/tracker/github/ensure-pr-ready.md +13 -5
- package/dist/skills/git/references/tracker/jira/ensure-pr-ready.md +13 -5
- package/dist/skills/git/references/tracker/linear/ensure-pr-ready.md +13 -5
- package/dist/targets/claude-code/{learning-install.js → curation-install.js} +85 -65
- package/dist/targets/claude-code/installer.js +15 -15
- package/dist/targets/claude-code/language-stamp.js +5 -5
- package/dist/targets/claude-code/post-install.js +2 -2
- package/dist/targets/claude-code/tracker-servers.js +1 -1
- package/package.json +3 -2
- package/src/assets/agents/_partials/_code.mds +11 -11
- package/src/assets/agents/code.mds +2 -2
- package/src/assets/agents/curate.md +8 -8
- package/src/assets/agents/debug.mds +6 -6
- package/src/assets/agents/design.mds +18 -18
- package/src/assets/agents/fix.mds +6 -5
- package/src/assets/agents/git.mds +1 -1
- package/src/assets/agents/harden.mds +7 -7
- package/src/assets/agents/knowledge.mds +23 -23
- package/src/assets/agents/refactor.mds +2 -2
- package/src/assets/agents/research.mds +15 -15
- package/src/assets/agents/review.mds +43 -43
- package/src/assets/agents/skim.mds +11 -11
- package/src/assets/agents/triage.mds +22 -22
- package/src/assets/agents/validate.md +13 -26
- package/src/assets/commands/_partials/_decisions.mds +13 -13
- package/src/assets/commands/_partials/_engine.mds +8 -8
- package/src/assets/commands/_partials/_knowledge.mds +29 -15
- package/src/assets/commands/_partials/_preamble.mds +4 -4
- package/src/assets/commands/_partials/_settings.mds +2 -2
- package/src/assets/commands/_partials/_wave.mds +7 -7
- package/src/assets/commands/bug-analysis.mds +37 -48
- package/src/assets/commands/code-review.mds +46 -50
- package/src/assets/commands/debug.mds +14 -14
- package/src/assets/commands/dynamic-build.mds +38 -37
- package/src/assets/commands/dynamic-plan.mds +22 -22
- package/src/assets/commands/dynamic-profile.mds +2 -2
- package/src/assets/commands/dynamic-tickets.mds +8 -8
- package/src/assets/commands/explore.mds +20 -20
- package/src/assets/commands/implement.mds +77 -98
- package/src/assets/commands/plan.mds +27 -27
- package/src/assets/commands/release.mds +12 -12
- package/src/assets/commands/research.mds +19 -19
- package/src/assets/commands/resolve.mds +56 -50
- package/src/assets/commands/self-review.mds +20 -20
- package/src/assets/mds/git/_ops.mds +3 -1
- package/src/assets/mds/git/_ops_pr.mds +1 -1
- package/src/assets/mds/git/_ops_steps.mds +10 -4
- package/src/assets/mds/git/_pr.mds +7 -4
- package/src/assets/rules/quality.md +1 -0
- package/src/assets/scripts/hooks/background-memory-update +2 -2
- package/src/assets/scripts/hooks/capture-prompt +12 -12
- package/src/assets/scripts/hooks/capture-question +11 -11
- package/src/assets/scripts/hooks/capture-turn +12 -12
- package/src/assets/scripts/hooks/{learning-lock → curation-lock} +2 -2
- package/src/assets/scripts/hooks/curation-move +293 -0
- package/src/assets/scripts/hooks/ensure-devflow-init +45 -13
- package/src/assets/scripts/hooks/ensure-proxy +4 -4
- package/src/assets/scripts/hooks/ensure-root-gitignore +4 -4
- package/src/assets/scripts/hooks/git-marker +81 -0
- package/src/assets/scripts/hooks/json-helper.cjs +134 -51
- package/src/assets/scripts/hooks/json-parse +1 -1
- package/src/assets/scripts/hooks/lib/curation-move.cjs +1582 -0
- package/src/assets/scripts/hooks/lib/{learning-store.cjs → curation-store.cjs} +242 -118
- package/src/assets/scripts/hooks/lib/decisions-format.cjs +3 -3
- package/src/assets/scripts/hooks/lib/mkdir-lock.cjs +24 -7
- package/src/assets/scripts/hooks/lib/project-paths.cjs +132 -39
- package/src/assets/scripts/hooks/lib/render-decisions.cjs +34 -22
- package/src/assets/scripts/hooks/lib/tracked-areas.cjs +259 -0
- package/src/assets/scripts/hooks/memory-worker +1 -1
- package/src/assets/scripts/hooks/pre-compact-memory +6 -16
- package/src/assets/scripts/hooks/queue-append +228 -103
- package/src/assets/scripts/hooks/resolve-project-root +2 -2
- package/src/assets/scripts/hooks/session-start-context +143 -69
- package/src/assets/scripts/hooks/session-start-memory +3 -43
- package/src/assets/scripts/lib/project-config.cjs +12 -5
- package/src/assets/scripts/resolve-base.cjs +1043 -0
- package/src/assets/scripts/resolve-settings.cjs +42 -18
- package/src/assets/skills/agent-references/SKILL.md +5 -2
- package/src/assets/skills/agent-references/references/commands/implement-levels.md +27 -0
- package/src/assets/skills/agent-references/references/commands/implement-revalidate.md +6 -4
- package/src/assets/skills/agent-references/references/commands/resolve-levels.md +24 -0
- package/src/assets/skills/apply-decisions/SKILL.md +1 -1
- package/src/assets/skills/docs-framework/SKILL.md +7 -7
- package/src/assets/skills/docs-framework/references/patterns.md +3 -4
- package/src/assets/skills/quality-gates/SKILL.md +1 -1
- package/src/assets/skills/worktree-support/references/roots.md +2 -2
- package/templates/lint-pack/.lint-pack.conf +86 -0
- package/templates/lint-pack/README.md +190 -0
- package/templates/lint-pack/lint-pack.sh +905 -0
- package/dist/core/learning-queue-cleanup.js +0 -27
- package/dist/core/learning-store.js +0 -61
- /package/dist/{learning-off → curation-off}/agents/debug.md +0 -0
- /package/dist/{learning-off → curation-off}/agents/design.md +0 -0
- /package/dist/{learning-off → curation-off}/agents/harden.md +0 -0
- /package/dist/{learning-off → curation-off}/agents/knowledge.md +0 -0
- /package/dist/{learning-off → curation-off}/agents/research.md +0 -0
- /package/dist/{learning-off → curation-off}/agents/skim.md +0 -0
- /package/dist/{learning-off → curation-off}/commands/dynamic-plan.md +0 -0
- /package/dist/{learning-off → curation-off}/commands/dynamic-profile.md +0 -0
- /package/dist/{learning-off → curation-off}/commands/dynamic-tickets.md +0 -0
- /package/dist/{learning-off → curation-off}/commands/release.md +0 -0
- /package/dist/{learning-off → curation-off}/commands/research.md +0 -0
|
@@ -3,7 +3,7 @@ description: Comprehensive branch review using specialized sub-agents for PR rea
|
|
|
3
3
|
---
|
|
4
4
|
# Code Review Command
|
|
5
5
|
|
|
6
|
-
Run a comprehensive code review of the current branch by spawning parallel review agents, then synthesizing results into PR comments.
|
|
6
|
+
Run a comprehensive code review of the current branch by spawning parallel review agents, then synthesizing results into PR comments.
|
|
7
7
|
|
|
8
8
|
## Usage
|
|
9
9
|
|
|
@@ -27,8 +27,8 @@ Run a comprehensive code review of the current branch by spawning parallel revie
|
|
|
27
27
|
- **More than one listed:** Invoke the `devflow:worktree-support` skill, then Read its `references/discovery.md` from the skill's base directory for the full 7-step algorithm; the canonical protected branch list stays in the skill. Parse the list, filter (skip protected/detached/mid-rebase), dedup by branch, sort by recent commit
|
|
28
28
|
- **Exactly one listed:** load neither the skill nor the reference — that worktree is the only candidate, and Step 0c's Git agent validates its branch
|
|
29
29
|
2. **If `--path` flag provided:** use only that worktree, skip discovery
|
|
30
|
-
**`--path` validation**:
|
|
31
|
-
3. **If only 1 reviewable worktree**: proceed as single-worktree flow
|
|
30
|
+
**`--path` validation**: the path must be a directory in `git worktree list` output; if not, report an error and stop.
|
|
31
|
+
3. **If only 1 reviewable worktree**: proceed as single-worktree flow
|
|
32
32
|
4. **If multiple reviewable worktrees:** report "Found N worktrees with reviewable branches: {list with paths and branches}" and proceed with multi-worktree flow
|
|
33
33
|
|
|
34
34
|
#### Step 0b: Resolve the compliance lens and gate level
|
|
@@ -41,7 +41,7 @@ Run a comprehensive code review of the current branch by spawning parallel revie
|
|
|
41
41
|
node "$HOME/.devflow/scripts/resolve-settings.cjs" "{root}" 2>/dev/null; echo "exit=$?"
|
|
42
42
|
```
|
|
43
43
|
|
|
44
|
-
Accept the output only when it is exactly two lines: `exit=0` last and, before it, one line of the form `TRACKER=<github|jira|linear> TRACKER_SOURCE=<project|personal|machine|default> TRACKER_WARN=<none|mismatch|invalid> SITE=<none|https://<host>> KEY=<none|<key>> REVIEW_PUBLICATION=<off|auto|full> COMPLIANCE=<off|generic|<id>[,<id>…]> MEMORY=<on|off>
|
|
44
|
+
Accept the output only when it is exactly two lines: `exit=0` last and, before it, one line of the form `TRACKER=<github|jira|linear> TRACKER_SOURCE=<project|personal|machine|default> TRACKER_WARN=<none|mismatch|invalid> SITE=<none|https://<host>> KEY=<none|<key>> REVIEW_PUBLICATION=<off|auto|full> COMPLIANCE=<off|generic|<id>[,<id>…]> MEMORY=<on|off> CURATION=<on|off> KNOWLEDGE=<on|off> GATE_LEVEL=<full|standard|lean>` — these fields, in this order, nothing else, where `<host>` is a lowercase dotted host name alone, `<key>` is 2–10 of `A-Z`, `0-9` and `_` starting with a letter, and each `<id>` is one of `gdpr`, `hipaa`, `pci-dss`, `soc2`, `iso-27001`, `sox`. **Anything else** (a non-zero exit, no line, extra text, or a missing, reordered or unlisted field or value) ⇒ use `TRACKER=github TRACKER_SOURCE=default TRACKER_WARN=invalid SITE=none KEY=none REVIEW_PUBLICATION=off COMPLIANCE=generic MEMORY=on CURATION=on KNOWLEDGE=off GATE_LEVEL=full` instead.
|
|
45
45
|
|
|
46
46
|
The accepted line is the only source of these values.
|
|
47
47
|
|
|
@@ -97,20 +97,20 @@ PR_DESCRIPTION_GUIDANCE: {pr_description_guidance}
|
|
|
97
97
|
PR_TEST_PLAN_BLOCK: {PR_TEST_PLAN_BLOCK verbatim, or (none)}
|
|
98
98
|
APPLY_CONVENTIONS: {APPLY_CONVENTIONS}
|
|
99
99
|
Validate branch, commit if needed, push, create PR if needed.
|
|
100
|
-
Return: branch, base_branch, branch-slug, PR#"
|
|
100
|
+
Return: branch, base_branch, base_ref, branch-slug, PR#"
|
|
101
101
|
```
|
|
102
102
|
|
|
103
103
|
In multi-worktree mode, spawn all pre-flight agents **in a single message**.
|
|
104
104
|
|
|
105
105
|
**If BLOCKED:** In single-worktree mode, stop and report. In multi-worktree mode, report the failure but continue with other worktrees.
|
|
106
106
|
|
|
107
|
-
**Extract from response:** `branch`, `base_branch`, `branch_slug`, `pr_number` per worktree.
|
|
107
|
+
**Extract from response:** `branch`, `base_branch`, `base_ref`, `branch_slug`, `pr_number` per worktree. Stop with cause and fix when the Base line reads (rejected) or `branch_slug` does not match the slug pattern above; name the Git agent's fix, never your own, and for the slug the allowed characters, never its value. In multi-worktree mode this blocks only that worktree.
|
|
108
108
|
|
|
109
109
|
**Fetch PR body** (after extracting `pr_number`):
|
|
110
110
|
```bash
|
|
111
111
|
PR_DESCRIPTION=$(gh pr view {pr_number} --json body --jq '.body' 2>/dev/null || echo "(none)")
|
|
112
112
|
```
|
|
113
|
-
If `pr_number` is absent
|
|
113
|
+
If `pr_number` is absent, set `PR_DESCRIPTION` to `(none)`.
|
|
114
114
|
|
|
115
115
|
#### Step 0d: Incremental Detection & Timestamp Setup
|
|
116
116
|
|
|
@@ -120,15 +120,16 @@ If `pr_number` is absent or the command fails, set `PR_DESCRIPTION` to `(none)`.
|
|
|
120
120
|
For each worktree:
|
|
121
121
|
|
|
122
122
|
1. Generate timestamp: `YYYY-MM-DD_HHMM`. If directory already exists (same-minute collision), append seconds (`YYYY-MM-DD_HHMMSS`).
|
|
123
|
-
2.
|
|
124
|
-
3. Check if `{worktree}/.devflow/docs/reviews/{branch-slug}/.last-review-head` exists:
|
|
123
|
+
2. Check if `{gd}/devflow/reviews/{branch-slug}/.last-review-head` exists, `{gd}` being what `git -C "{worktree}" rev-parse --absolute-git-dir` prints:
|
|
125
124
|
- **If yes AND `--full` NOT set:**
|
|
126
|
-
-
|
|
127
|
-
- Verify reachable: `git -C {worktree} cat-file -t {sha}`
|
|
125
|
+
- The stored review head is checked as a commit ID: use it only when it is exactly 40 or 64 lowercase hex, else take the full-range path
|
|
126
|
+
- Verify reachable: `git -C "{worktree}" cat-file -t {sha}` must print `commit` (else take the full-range path)
|
|
128
127
|
- Check if SHA == current HEAD → if so, skip review: "No new commits since last review. Use --full for a full re-review."
|
|
129
128
|
- Set `DIFF_RANGE` to `{last-review-sha}...HEAD`
|
|
130
|
-
- **
|
|
131
|
-
-
|
|
129
|
+
- **Full-range path (no marker, or `--full`):**
|
|
130
|
+
- Stop as for a (rejected) Base line unless `base_ref` is 40 or 64 hex.
|
|
131
|
+
- Set `DIFF_RANGE` to `{base_ref}...HEAD`
|
|
132
|
+
3. Create timestamped review directory: `mkdir -p {worktree}/.devflow/docs/reviews/{branch-slug}/{timestamp}/`
|
|
132
133
|
|
|
133
134
|
#### Step 0e-i: Load Prior Resolution and Count Cycles
|
|
134
135
|
|
|
@@ -199,10 +200,11 @@ List the changed paths into `{REVIEW_DIR}/paths.txt` and print only the line cou
|
|
|
199
200
|
|
|
200
201
|
```bash
|
|
201
202
|
git -C "{WORKTREE_PATH}" diff --name-only --no-renames {DIFF_RANGE} > "{REVIEW_DIR}/paths.txt"
|
|
203
|
+
echo "exit=$?"
|
|
202
204
|
wc -l < "{REVIEW_DIR}/paths.txt"
|
|
203
205
|
```
|
|
204
206
|
|
|
205
|
-
Read `paths.txt` once when the count is about 40 or fewer, and in ranges of about 40 lines (Read with offset and limit) when it is more.
|
|
207
|
+
The `exit=` line is the diff's. A non-zero diff exit stops. Read `paths.txt` once when the count is about 40 or fewer, and in ranges of about 40 lines (Read with offset and limit) when it is more.
|
|
206
208
|
|
|
207
209
|
Set `DIFF_CLASS` by these rules, in order; the first that decides wins:
|
|
208
210
|
|
|
@@ -276,7 +278,7 @@ Write `diff.patch` once per worktree, by redirect:
|
|
|
276
278
|
git -C "{WORKTREE_PATH}" diff --no-color --no-ext-diff --no-textconv {DIFF_RANGE} > "{REVIEW_DIR}/diff.patch"
|
|
277
279
|
```
|
|
278
280
|
|
|
279
|
-
It holds the whole diff of `DIFF_RANGE`. On a `code` diff, add one patch for each language focus in REVIEW_FOCUS_LIST, by the same command with quoted pathspecs from this table:
|
|
281
|
+
It holds the whole diff of `DIFF_RANGE`. A non-zero exit of any patch write stops. On a `code` diff, add one patch for each language focus in REVIEW_FOCUS_LIST, by the same command with quoted pathspecs from this table:
|
|
280
282
|
|
|
281
283
|
```bash
|
|
282
284
|
git -C "{WORKTREE_PATH}" diff --no-color --no-ext-diff --no-textconv {DIFF_RANGE} -- '<pathspec>' ... > "{REVIEW_DIR}/diff-{focus}.patch"
|
|
@@ -388,7 +390,7 @@ Spawn Review agents **in a single message**, one per focus in REVIEW_FOCUS_LIST
|
|
|
388
390
|
| documentation | conditional | devflow:documentation | diff.patch |
|
|
389
391
|
| compliance | diff-driven | devflow:compliance | diff.patch |
|
|
390
392
|
|
|
391
|
-
Review agent count:
|
|
393
|
+
Review agent count: `code` runs 8 core +1-12 at `full`, up to 2 fewer at `standard`, 3-4 at lean; a reduced class or a mix runs 2-6.
|
|
392
394
|
|
|
393
395
|
**Set the compliance focus directive** from `COMPLIANCE_FRAMEWORKS`. `COMPLIANCE_FOCUS_DIRECTIVE` is this one line, with `<ids>` replaced by the value of `COMPLIANCE_FRAMEWORKS`; only the compliance focus's spawn carries it:
|
|
394
396
|
|
|
@@ -412,7 +414,7 @@ Follow devflow:apply-feature-knowledge for FEATURE_KNOWLEDGE — feature-specifi
|
|
|
412
414
|
IMPORTANT: Write report to {worktree_path}/.devflow/docs/reviews/{branch-slug}/{timestamp}/{focus}.md using Write tool"
|
|
413
415
|
```
|
|
414
416
|
|
|
415
|
-
In multi-worktree mode, process worktrees **sequentially**:
|
|
417
|
+
In multi-worktree mode, process worktrees **sequentially**: Phases 1-4 for one worktree, then the next.
|
|
416
418
|
|
|
417
419
|
### Phase 3: Synthesis → Review Comment (Sequential)
|
|
418
420
|
|
|
@@ -455,34 +457,29 @@ Posts the consolidated review-summary comment (marker-deduped by the operation o
|
|
|
455
457
|
**Requires:** BRANCH_INFO, REVIEW_DIR
|
|
456
458
|
|
|
457
459
|
Per worktree, after successful completion:
|
|
458
|
-
1.
|
|
460
|
+
1. In one Bash call run `M="$(git -C "{worktree_path}" rev-parse --absolute-git-dir)/devflow/reviews/{branch-slug}" && mkdir -p "$M" && git -C "{worktree_path}" rev-parse HEAD > "$M/.last-review-head"`. A failed or refused write never stops the run and is not retried another way.
|
|
459
461
|
2. Display results from all agents:
|
|
460
462
|
- Merge recommendation (from Synthesize agent)
|
|
461
463
|
- Issue counts by category (🔴 blocking / ⚠️ should-fix / ℹ️ pre-existing)
|
|
462
464
|
- Review comment status: POSTED / POSTED+TRUNCATED (body exceeded 60k after redaction) / SKIPPED (D7 dedup) / DEGRADED (from Git)
|
|
463
465
|
- Publication status: FULL (private repo) | FULL (config override) | STUB (public repository) | OFF (publication disabled by config) | STUB (visibility undeterminable) | STUB (evidence policy) (from Git agent)
|
|
466
|
+
- Any base `TRACEABILITY: DEGRADED` line from Step 0c, as returned
|
|
464
467
|
- Artifact paths
|
|
465
468
|
|
|
466
469
|
## Architecture
|
|
467
470
|
|
|
468
471
|
```
|
|
469
|
-
/code-review
|
|
472
|
+
/code-review
|
|
470
473
|
│
|
|
471
|
-
├─ Phase 0: Worktree Discovery & Pre-flight
|
|
472
|
-
│ ├─ Step 0a: git worktree list → filter reviewable
|
|
474
|
+
├─ Phase 0: Worktree Discovery & Pre-flight, Steps 0a-0f (Git agent per worktree, parallel)
|
|
473
475
|
│ ├─ Step 0b: Resolve the compliance lens and gate level
|
|
474
|
-
│ ├─ Step 0c: Git agent (ensure-pr-ready) per worktree [parallel]
|
|
475
|
-
│ ├─ Step 0d: Incremental detection + timestamp setup per worktree
|
|
476
|
-
│ ├─ Step 0e-i: Load prior resolution-summary.md
|
|
477
|
-
│ ├─ Step 0e-ii: Convergence assessment (warn only)
|
|
478
|
-
│ └─ Step 0f: Resolve REVIEW_PUBLICATION per worktree (publication gate)
|
|
479
476
|
│
|
|
480
|
-
├─ Per worktree (SEQUENTIAL
|
|
477
|
+
├─ Per worktree (SEQUENTIAL):
|
|
481
478
|
│ │
|
|
482
479
|
│ ├─ Phase 1: Analyze changed files
|
|
483
480
|
│ │ ├─ Classify the diff (paths.txt → DIFF_CLASS)
|
|
484
|
-
│ │ ├─ Choose the focuses
|
|
485
|
-
│ │ └─ Write diff.patch and diff-{focus}.patch
|
|
481
|
+
│ │ ├─ Choose the focuses
|
|
482
|
+
│ │ └─ Write diff.patch and diff-{focus}.patch
|
|
486
483
|
│ │
|
|
487
484
|
│ ├─ Phase 2: Reviews (PARALLEL within worktree), one per REVIEW_FOCUS_LIST focus
|
|
488
485
|
│ │ ├─ code: core (diff.patch), language (diff-{focus}.patch), conditional
|
|
@@ -500,7 +497,7 @@ Per worktree, after successful completion:
|
|
|
500
497
|
| Case | Handling |
|
|
501
498
|
|------|----------|
|
|
502
499
|
| `--full` in multi-worktree mode | Applies to all worktrees (global modifier). It sets the diff range, never the gate level |
|
|
503
|
-
| Review comment already posted | Git agent matches its own marker on the `{cycle, timestamp}` pair → skip silently (D7); a re-review in the same cycle (different timestamp) posts its own comment. The marker's format belongs to the operation
|
|
500
|
+
| Review comment already posted | Git agent matches its own marker on the `{cycle, timestamp}` pair → skip silently (D7); a re-review in the same cycle (different timestamp) posts its own comment. The marker's format belongs to the operation |
|
|
504
501
|
| Docs-only diff | Its Step 1.1 set, narrowed by level |
|
|
505
502
|
| Tests-only diff | Its Step 1.1 set, narrowed by level |
|
|
506
503
|
| Lockfile-only diff | Its Step 1.1 set, narrowed by level |
|
|
@@ -509,7 +506,6 @@ Per worktree, after successful completion:
|
|
|
509
506
|
| A file moved across classes | `--no-renames` lists both paths, so a code path makes the diff `code` |
|
|
510
507
|
| Path listing above about 40 lines | Read in ranges (Step 1.1) |
|
|
511
508
|
| Language files changed, plugin not installed | The focus is absent from the stamped line: not spawned |
|
|
512
|
-
| Public repo (`auto` mode) | Git agent probes visibility, posts counts-only STUB comment; full report stays local |
|
|
513
509
|
| `reviewPublication: off` | Git agent skips posting the review comment (OFF) — except that, only when `EVIDENCE_POLICY` is `required`, Step 0f passes `stub` and a counts-only STUB comment posts |
|
|
514
510
|
|
|
515
511
|
## Backwards Compatibility
|
|
@@ -518,8 +514,8 @@ Per worktree, after successful completion:
|
|
|
518
514
|
|
|
519
515
|
## Principles
|
|
520
516
|
|
|
521
|
-
1. **Orchestration only** - Command spawns agents, doesn't do git/review work itself. The exceptions are the read-only Phase 0 probes (`git worktree list`, `git -C ... branch --show-current`, `git -C ... cat-file -t`), the bounded Phase 1 path listing
|
|
517
|
+
1. **Orchestration only** - Command spawns agents, doesn't do git/review work itself. The exceptions are the read-only Phase 0 probes (`git worktree list`, `git -C ... branch --show-current`, `git -C ... cat-file -t`, `git -C ... rev-parse`), the bounded Phase 1 path listing and the writes (`diff.patch`, `diff-{focus}.patch`, the marker and its `mkdir -p`). These writes print nothing
|
|
522
518
|
2. **Parallel, not background** - Multiple agents in one message, but `run_in_background=false` so phases complete before proceeding
|
|
523
|
-
3. **Git agent for git work** - All git operations go through Git agent, except the exceptions named in Principle 1;
|
|
519
|
+
3. **Git agent for git work** - All git operations go through Git agent, except the exceptions named in Principle 1; its writes print nothing
|
|
524
520
|
4. **Honest reporting** - Display agent outputs directly
|
|
525
521
|
5. **Incremental by default** - Only review new changes unless `--full` specified
|
|
@@ -36,7 +36,7 @@ $ARGUMENTS
|
|
|
36
36
|
node "$HOME/.devflow/scripts/resolve-settings.cjs" "{root}" 2>/dev/null; echo "exit=$?"
|
|
37
37
|
```
|
|
38
38
|
|
|
39
|
-
Accept the output only when it is exactly two lines: `exit=0` last and, before it, one line of the form `TRACKER=<github|jira|linear> TRACKER_SOURCE=<project|personal|machine|default> TRACKER_WARN=<none|mismatch|invalid> SITE=<none|https://<host>> KEY=<none|<key>> REVIEW_PUBLICATION=<off|auto|full> COMPLIANCE=<off|generic|<id>[,<id>…]> MEMORY=<on|off>
|
|
39
|
+
Accept the output only when it is exactly two lines: `exit=0` last and, before it, one line of the form `TRACKER=<github|jira|linear> TRACKER_SOURCE=<project|personal|machine|default> TRACKER_WARN=<none|mismatch|invalid> SITE=<none|https://<host>> KEY=<none|<key>> REVIEW_PUBLICATION=<off|auto|full> COMPLIANCE=<off|generic|<id>[,<id>…]> MEMORY=<on|off> CURATION=<on|off> KNOWLEDGE=<on|off> GATE_LEVEL=<full|standard|lean>` — these fields, in this order, nothing else, where `<host>` is a lowercase dotted host name alone, `<key>` is 2–10 of `A-Z`, `0-9` and `_` starting with a letter, and each `<id>` is one of `gdpr`, `hipaa`, `pci-dss`, `soc2`, `iso-27001`, `sox`. **Anything else** (a non-zero exit, no line, extra text, or a missing, reordered or unlisted field or value) ⇒ use `TRACKER=github TRACKER_SOURCE=default TRACKER_WARN=invalid SITE=none KEY=none REVIEW_PUBLICATION=off COMPLIANCE=generic MEMORY=on CURATION=on KNOWLEDGE=off GATE_LEVEL=full` instead.
|
|
40
40
|
|
|
41
41
|
The accepted line is the only source of these values.
|
|
42
42
|
|
|
@@ -83,7 +83,7 @@ When a ticket requires multiple sequential Code agent phases, each Code agent ap
|
|
|
83
83
|
node "$HOME/.devflow/scripts/resolve-settings.cjs" "{root}" 2>/dev/null; echo "exit=$?"
|
|
84
84
|
```
|
|
85
85
|
|
|
86
|
-
Accept the output only when it is exactly two lines: `exit=0` last and, before it, one line of the form `TRACKER=<github|jira|linear> TRACKER_SOURCE=<project|personal|machine|default> TRACKER_WARN=<none|mismatch|invalid> SITE=<none|https://<host>> KEY=<none|<key>> REVIEW_PUBLICATION=<off|auto|full> COMPLIANCE=<off|generic|<id>[,<id>…]> MEMORY=<on|off>
|
|
86
|
+
Accept the output only when it is exactly two lines: `exit=0` last and, before it, one line of the form `TRACKER=<github|jira|linear> TRACKER_SOURCE=<project|personal|machine|default> TRACKER_WARN=<none|mismatch|invalid> SITE=<none|https://<host>> KEY=<none|<key>> REVIEW_PUBLICATION=<off|auto|full> COMPLIANCE=<off|generic|<id>[,<id>…]> MEMORY=<on|off> CURATION=<on|off> KNOWLEDGE=<on|off> GATE_LEVEL=<full|standard|lean>` — these fields, in this order, nothing else, where `<host>` is a lowercase dotted host name alone, `<key>` is 2–10 of `A-Z`, `0-9` and `_` starting with a letter, and each `<id>` is one of `gdpr`, `hipaa`, `pci-dss`, `soc2`, `iso-27001`, `sox`. **Anything else** (a non-zero exit, no line, extra text, or a missing, reordered or unlisted field or value) ⇒ use `TRACKER=github TRACKER_SOURCE=default TRACKER_WARN=invalid SITE=none KEY=none REVIEW_PUBLICATION=off COMPLIANCE=generic MEMORY=on CURATION=on KNOWLEDGE=off GATE_LEVEL=full` instead.
|
|
87
87
|
|
|
88
88
|
The accepted line is the only source of these values.
|
|
89
89
|
|
|
@@ -278,7 +278,7 @@ TASK_DESCRIPTION: ${TICKET}
|
|
|
278
278
|
ISSUE_REQUIRED: ${ISSUE_REQUIRED}
|
|
279
279
|
APPLY_CONVENTIONS: ${APPLY_CONVENTIONS}
|
|
280
280
|
${ISSUE_INPUT !== "(none)" ? "ISSUE_INPUT: " + ISSUE_INPUT : ""}
|
|
281
|
-
Return: {"branch": "<the - **Branch name**: value under your ### Branch, or (none)>", "issueId": "<the - **Issue ID**: value under your ### Handoff Values, or (none)>", "prLinkLine": "<the - **PR link line**: value, or (none)>"}`, { agentType: "Git" })
|
|
281
|
+
Return: {"branch": "<the - **Branch name**: value under your ### Branch, or (none)>", "issueId": "<the - **Issue ID**: value under your ### Handoff Values, or (none)>", "prLinkLine": "<the - **PR link line**: value, or (none)>", "baseSha": "<the 40 or 64 hex git rev-parse HEAD prints before step 4>"}`, { agentType: "Git" })
|
|
282
282
|
);
|
|
283
283
|
|
|
284
284
|
// The ticket's own Handoff Values, read from setup-task's Output — never derived from ISSUE_INPUT.
|
|
@@ -288,6 +288,7 @@ const ISSUE_NUMBER = ISSUE_ID_SHAPE.test(String(setup?.issueId ?? "")) ? setup.i
|
|
|
288
288
|
const ISSUE_PR_LINK = setup?.prLinkLine || "(none)"; // "(none)" ⇒ the wave PR carries no closing reference for this ticket
|
|
289
289
|
// The branch setup-task created, as it reported it: every later phase and the merge use it. The engine never names one.
|
|
290
290
|
const BRANCH = typeof setup?.branch === "string" && setup.branch.trim() !== "" && setup.branch.trim() !== "(none)" ? setup.branch : "(none)";
|
|
291
|
+
const BASE_SHA = /^(?:[0-9a-f]{40}|[0-9a-f]{64})$/.test(String(setup?.baseSha ?? "")) ? setup.baseSha : "(none)"; // the commit the ticket branch was forked from
|
|
291
292
|
|
|
292
293
|
// Ticket-link stop, before implement. The workflow cannot ask, so it never records an exception: it stops.
|
|
293
294
|
if (ISSUE_REQUIRED === "true" && ISSUE_NUMBER === "(none)") {
|
|
@@ -299,6 +300,11 @@ if (BRANCH === "(none)") {
|
|
|
299
300
|
return { ticket: TICKET, branch: BRANCH, verdict: "ESCALATED", issueId: ISSUE_NUMBER, issuePrLink: ISSUE_PR_LINK, escalations: [{ type: "branch-missing", description: "setup-task reported no branch name — check its Output, then re-run" }] };
|
|
300
301
|
}
|
|
301
302
|
|
|
303
|
+
// Base stop: every review range starts at the commit the ticket branch was forked from.
|
|
304
|
+
if (BASE_SHA === "(none)") {
|
|
305
|
+
return { ticket: TICKET, branch: BRANCH, verdict: "ESCALATED", issueId: ISSUE_NUMBER, issuePrLink: ISSUE_PR_LINK, escalations: [{ type: "base-missing", description: "setup-task reported no base commit — check its Output, then re-run" }] };
|
|
306
|
+
}
|
|
307
|
+
|
|
302
308
|
// Phase 2: Implement
|
|
303
309
|
await phase("implement", () =>
|
|
304
310
|
agent(`OPERATION: implement
|
|
@@ -412,10 +418,9 @@ Self-verify your fix compiles and the scenarios pass, following your Running com
|
|
|
412
418
|
|
|
413
419
|
// Phase 5: Review → verify → fix (single pass)
|
|
414
420
|
const reviewResult = await phase("review", async () => {
|
|
415
|
-
// Review scope: the entire branch diff from the
|
|
416
|
-
// Review agents diff the branch against its merge-base with the default branch.
|
|
421
|
+
// Review scope: the entire branch diff, from the commit the ticket branch was forked from to HEAD.
|
|
417
422
|
// The pass runs exactly ONCE.
|
|
418
|
-
const reviewScope = `Review the full branch diff on branch ${BRANCH}
|
|
423
|
+
const reviewScope = `Review the full branch diff on branch ${BRANCH}.\nDIFF_RANGE: ${BASE_SHA}...HEAD\n`;
|
|
419
424
|
|
|
420
425
|
// Review agent focus list (order = index mapping for dead-reviewer detection)
|
|
421
426
|
const reviewFocuses = ["security", "architecture", "performance", "complexity", "consistency", "regression", "testing", "reliability"];
|
|
@@ -459,13 +464,12 @@ Focus discipline: ${focus}. Return: {"focus": "${focus}", "reviewed": true, "fil
|
|
|
459
464
|
return { survivingFindings: [], fixedFindings: [], coverageGaps };
|
|
460
465
|
}
|
|
461
466
|
|
|
462
|
-
// Adversarial
|
|
463
|
-
// Panel asks perspective-diverse questions over the WHOLE finding set (not one agent per finding).
|
|
464
|
-
// A finding survives if >50% of panel agents CONFIRM it.
|
|
467
|
+
// Adversarial panel over the WHOLE finding set (not one agent per finding): >50% CONFIRMED survives
|
|
465
468
|
const VERIFY_PANEL = 3;
|
|
466
469
|
const panels = await parallel(
|
|
467
470
|
Array.from({ length: VERIFY_PANEL }, (_, lens) => () =>
|
|
468
471
|
agent(`Adversarially verify all ${allFindings.length} findings on branch ${BRANCH}.
|
|
472
|
+
DIFF_RANGE: ${BASE_SHA}...HEAD
|
|
469
473
|
Lens ${lens + 1} of ${VERIFY_PANEL}:
|
|
470
474
|
${["Does each finding actually reproduce in the current code? Hunt for findings that describe patterns not present in the diff.",
|
|
471
475
|
"Is each finding a real issue or a false positive in context? Consider intent, surrounding code, and project conventions.",
|
|
@@ -483,16 +487,13 @@ ${JSON.stringify(allFindings.map((f, i) => ({ index: i, description: f.descripti
|
|
|
483
487
|
panels.filter(p => (p.verdicts || []).find(v => v.index === i)?.verdict === "CONFIRMED").length > VERIFY_PANEL / 2
|
|
484
488
|
);
|
|
485
489
|
|
|
486
|
-
// No confirmed findings
|
|
490
|
+
// No confirmed findings: coverageGaps carry forward and block PASS downstream
|
|
487
491
|
if (confirmedFindings.length === 0) {
|
|
488
492
|
return { survivingFindings: [], fixedFindings: [], coverageGaps };
|
|
489
493
|
}
|
|
490
494
|
|
|
491
|
-
//
|
|
492
|
-
//
|
|
493
|
-
// concurrent same-file edits cause index contention and lost fixes).
|
|
494
|
-
// Sub-batches for DISTINCT files run in parallel (different code areas — safe per concurrency doctrine).
|
|
495
|
-
// A finding with no file field gets its own singleton group (unknown scope — never mix with known files).
|
|
495
|
+
// Sub-batches (max 5 findings): same file in sequence, distinct files in parallel.
|
|
496
|
+
// A finding with no file is a singleton group.
|
|
496
497
|
const MAX_BATCH = 5; // max 5 findings per sub-batch
|
|
497
498
|
const fileGroups = {};
|
|
498
499
|
for (let fi = 0; fi < confirmedFindings.length; fi++) {
|
|
@@ -502,9 +503,7 @@ ${JSON.stringify(allFindings.map((f, i) => ({ index: i, description: f.descripti
|
|
|
502
503
|
fileGroups[key].push(f);
|
|
503
504
|
}
|
|
504
505
|
|
|
505
|
-
// One entry per
|
|
506
|
-
// Distinct-file groups are paced in chunks of FIX_CHUNK — same pacing bar as the Review spawn
|
|
507
|
-
// path — to avoid launching all Code agents at once on a large branch (reliability: explicit bound).
|
|
506
|
+
// One entry per file; FIX_CHUNK chunks bound concurrent Code agents
|
|
508
507
|
const FIX_CHUNK = 5;
|
|
509
508
|
// issue-fix SCOPE per finding: CRITICAL or HIGH takes the Careful protocol (failing regression test first); anything else is Standard.
|
|
510
509
|
const CAREFUL_SEVERITIES = new Set(["critical", "high"]);
|
|
@@ -785,7 +784,7 @@ The review pass runs exactly ONCE per ticket. One full-branch review → one adv
|
|
|
785
784
|
|
|
786
785
|
**Step 1 — Spawn Review agents in parallel (one agent() per focus)**
|
|
787
786
|
|
|
788
|
-
**Review scope:** the entire branch diff
|
|
787
|
+
**Review scope:** the entire branch diff, `DIFF_RANGE: {base commit}...HEAD`; the base commit is the 40 or 64 hex commit that the ticket branch was forked from, as the setup step reported it; a ticket with none stops `base-missing`.
|
|
789
788
|
|
|
790
789
|
Core Review agents (always, 8 total): security, architecture, performance, complexity, consistency, regression, testing, reliability
|
|
791
790
|
|
|
@@ -868,7 +867,7 @@ Each ticket engine run returns a structured result. The Synthesize agent or the
|
|
|
868
867
|
},
|
|
869
868
|
"escalations": [
|
|
870
869
|
{
|
|
871
|
-
"type": "merge-conflict | gate2-fail | validation-exhausted | harden-blocked | ambiguous-resolution | review-coverage-incomplete | dependency-blocked | engine-crash | ticket-link-missing | branch-missing",
|
|
870
|
+
"type": "merge-conflict | gate2-fail | validation-exhausted | harden-blocked | ambiguous-resolution | review-coverage-incomplete | dependency-blocked | engine-crash | ticket-link-missing | branch-missing | base-missing",
|
|
872
871
|
"description": "string"
|
|
873
872
|
}
|
|
874
873
|
],
|
|
@@ -1010,7 +1009,7 @@ const results = {}; // ticketId → its row of the workflow's return
|
|
|
1010
1009
|
const rowOf = (ticketId, r, merged, treeEqual = null) => ({ ticket: ticketId, ran: true, verdict: r?.verdict || r?.overallVerdict || null, merged, treeEqual, issuePrLink: r?.issuePrLink || "(none)", evaluateVerdict: r?.gate2?.evaluateVerdict, testVerdict: r?.gate2?.testVerdict, surviving: r?.survivingFindings?.length, coverageComplete: r?.reviewCoverage?.complete });
|
|
1011
1010
|
const MAX_ROUNDS = Math.max(10, remainingTickets.length * 2 + 5); // heuristic; always finite
|
|
1012
1011
|
const MERGE_SHA = /^[0-9a-f]{40}$/; // a SHA as git prints it; with the checked branch, the only Git-reported values that reach a merge, Validate or undo prompt
|
|
1013
|
-
const BRANCH_NAME = /^(?![-#]|(?:@|(?:FETCH_|ORIG_|MERGE_)?HEAD)$)(?!.*\.\.)[A-Za-z0-9._/+@,#-]{1,200}$/; //
|
|
1012
|
+
const BRANCH_NAME = /^(?![-#]|(?:@|(?:FETCH_|ORIG_|MERGE_)?HEAD)$)(?!.*\.\.)[A-Za-z0-9._/+@,#-]{1,200}$/; // STRICT_NAME_RE's deliberate variant, less its origin/ refusal; the name enters git lines
|
|
1014
1013
|
// One ticket's merge, post-merge Validate and undo (D-WAVE-MERGE-VALIDATE: Git validates nothing).
|
|
1015
1014
|
const mergeValidateUndo = async (ticketId, engineResult) => {
|
|
1016
1015
|
if (typeof engineResult.branch !== "string" || !BRANCH_NAME.test(engineResult.branch)) return { kept: false, reason: "ticket branch name refused: not a plain git ref name", halted: null, treeEqual: null };
|
|
@@ -1179,12 +1178,14 @@ Do NOT ask questions mid-workflow — that is impossible (F4). The workflow only
|
|
|
1179
1178
|
|
|
1180
1179
|
7. **Wave PR evidence** — only when step 6 reported the wave PR, after it; it never blocks, and every outcome below goes into the run summary. Take `{n}` from step 6's `- **PR**: #{n}` line when `{n}` matches `^[1-9][0-9]{0,9}$` as a whole; no such line ⇒ record `TRACEABILITY: DEGRADED (wave PR number not captured)` and skip this step. `PR_TEST_PLAN_BLOCK` `(none)` ⇒ record `Wave evidence: skipped (no wave test plan)` and skip it.
|
|
1181
1180
|
|
|
1181
|
+
**Changed files.** Take `{base_ref}` from step 6's `- **Base ref**:` line; only when it is 40 or 64 lowercase hex, run `git -C "{integration worktree root}" diff --name-only --diff-filter=d {base_ref}...HEAD; echo "exit=$?"`. Unless it ran and printed `exit=0`, record `TRACEABILITY: DEGRADED (wave base unusable)` and skip this step.
|
|
1182
|
+
|
|
1182
1183
|
**(a) Test the wave.** Spawn one Test agent on the integration worktree with the wave test plan — the TP lines of the `## Test Plan` section step 3(b) wrote to `{integration worktree root}/.devflow/docs/evidence-wave-{slug}.md`:
|
|
1183
1184
|
|
|
1184
1185
|
```
|
|
1185
1186
|
Agent(subagent_type="Test"):
|
|
1186
1187
|
"ORIGINAL_REQUEST: the merged tickets of wave/{slug}, as the wave test plan names them
|
|
1187
|
-
FILES_CHANGED: {the
|
|
1188
|
+
FILES_CHANGED: {the file list that diff printed}
|
|
1188
1189
|
TEST_PLAN: {the TP lines of the wave evidence file's ## Test Plan section}
|
|
1189
1190
|
WORKTREE_PATH: {integration worktree root}
|
|
1190
1191
|
Cover every TEST_PLAN line on the integration branch as it stands. Report PASS or FAIL with evidence."
|
|
@@ -36,7 +36,7 @@ $ARGUMENTS
|
|
|
36
36
|
node "$HOME/.devflow/scripts/resolve-settings.cjs" "{root}" 2>/dev/null; echo "exit=$?"
|
|
37
37
|
```
|
|
38
38
|
|
|
39
|
-
Accept the output only when it is exactly two lines: `exit=0` last and, before it, one line of the form `TRACKER=<github|jira|linear> TRACKER_SOURCE=<project|personal|machine|default> TRACKER_WARN=<none|mismatch|invalid> SITE=<none|https://<host>> KEY=<none|<key>> REVIEW_PUBLICATION=<off|auto|full> COMPLIANCE=<off|generic|<id>[,<id>…]> MEMORY=<on|off>
|
|
39
|
+
Accept the output only when it is exactly two lines: `exit=0` last and, before it, one line of the form `TRACKER=<github|jira|linear> TRACKER_SOURCE=<project|personal|machine|default> TRACKER_WARN=<none|mismatch|invalid> SITE=<none|https://<host>> KEY=<none|<key>> REVIEW_PUBLICATION=<off|auto|full> COMPLIANCE=<off|generic|<id>[,<id>…]> MEMORY=<on|off> CURATION=<on|off> KNOWLEDGE=<on|off> GATE_LEVEL=<full|standard|lean>` — these fields, in this order, nothing else, where `<host>` is a lowercase dotted host name alone, `<key>` is 2–10 of `A-Z`, `0-9` and `_` starting with a letter, and each `<id>` is one of `gdpr`, `hipaa`, `pci-dss`, `soc2`, `iso-27001`, `sox`. **Anything else** (a non-zero exit, no line, extra text, or a missing, reordered or unlisted field or value) ⇒ use `TRACKER=github TRACKER_SOURCE=default TRACKER_WARN=invalid SITE=none KEY=none REVIEW_PUBLICATION=off COMPLIANCE=generic MEMORY=on CURATION=on KNOWLEDGE=off GATE_LEVEL=full` instead.
|
|
40
40
|
|
|
41
41
|
The accepted line is the only source of these values.
|
|
42
42
|
|