@pareto4/pp-core 1.13.0 → 1.18.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/plugin.json +3 -3
- package/README.md +31 -12
- package/agents/pp-code-fixer.md +0 -11
- package/agents/pp-code-reviewer.md +1 -77
- package/agents/pp-debug-session-manager.md +9 -6
- package/agents/pp-executor.md +12 -29
- package/agents/pp-plan-checker.md +4 -4
- package/agents/pp-planner.md +34 -20
- package/agents/pp-vault-reviewer.md +100 -23
- package/agents/pp-verifier.md +1 -3
- package/bin/install.js +10 -3
- package/commands/pp-execute-phase.md +1 -3
- package/commands/pp-ns-manage.md +1 -1
- package/commands/pp-ns-review.md +1 -1
- package/commands/pp-plan-phase.md +1 -2
- package/commands/pp-vault-promote.md +7 -8
- package/commands/pp-vault-review.md +6 -5
- package/commands/pp-verify-work.md +1 -2
- package/gemini-extension.json +1 -1
- package/hooks/dist/pp-check-update.js +0 -0
- package/hooks/dist/pp-cursor-session-start.js +1 -1
- package/hooks/dist/pp-statusline.js +1 -1
- package/hooks/dist/pp-update-banner.js +0 -0
- package/hooks/pp-check-update.js +0 -0
- package/hooks/pp-cursor-session-start.js +1 -1
- package/hooks/pp-statusline.js +1 -1
- package/hooks/pp-update-banner.js +0 -0
- package/package.json +10 -18
- package/pareto-skills/_shared/create-project-board.sh +0 -0
- package/pareto-skills/pp-project-setup/SKILL.md +1 -1
- package/pp-core/bin/check-latest-version.cjs +0 -0
- package/pp-core/bin/detect-build-commands.sh +2 -2
- package/pp-core/bin/lib/capability-activation.cjs +83 -9
- package/pp-core/bin/lib/capability-registry.cjs +201 -229
- package/pp-core/bin/lib/capability-state.cjs +93 -1
- package/pp-core/bin/lib/capability-writer.cjs +3 -3
- package/pp-core/bin/lib/check-command-router.cjs +1906 -1514
- package/pp-core/bin/lib/clusters.cjs +3 -0
- package/pp-core/bin/lib/command-aliases.cjs +0 -35
- package/pp-core/bin/lib/commands.cjs +9 -4
- package/pp-core/bin/lib/compose-bindings.cjs +251 -88
- package/pp-core/bin/lib/config-loader.cjs +7 -103
- package/pp-core/bin/lib/config-schema.cjs +1 -1
- package/pp-core/bin/lib/config.cjs +151 -62
- package/pp-core/bin/lib/decisions.cjs +4 -4
- package/pp-core/bin/lib/discovery-vault-check.cjs +246 -0
- package/pp-core/bin/lib/frontmatter.cjs +1 -38
- package/pp-core/bin/lib/git-base-branch.cjs +11 -12
- package/pp-core/bin/lib/git-provider.cjs +9 -10
- package/pp-core/bin/lib/init-command-router.cjs +5 -8
- package/pp-core/bin/lib/init-contract.cjs +620 -738
- package/pp-core/bin/lib/init-interactive.cjs +62 -4
- package/pp-core/bin/lib/init.cjs +24 -51
- package/pp-core/bin/lib/install-profiles.cjs +1 -1
- package/pp-core/bin/lib/io.cjs +4 -2
- package/pp-core/bin/lib/loop-resolver.cjs +165 -129
- package/pp-core/bin/lib/org-profile.cjs +402 -161
- package/pp-core/bin/lib/package-identity.cjs +3 -3
- package/pp-core/bin/lib/phase-command-router.cjs +1 -29
- package/pp-core/bin/lib/phase-scope.cjs +1 -1
- package/pp-core/bin/lib/phase.cjs +11 -253
- package/pp-core/bin/lib/platform-bindings.cjs +40 -19
- package/pp-core/bin/lib/profile-output.cjs +1 -1
- package/pp-core/bin/lib/shell-command-projection.cjs +104 -1
- package/pp-core/bin/lib/state.cjs +11 -85
- package/pp-core/bin/lib/template.cjs +1 -1
- package/pp-core/bin/lib/vault-command-router.cjs +1682 -477
- package/pp-core/bin/lib/vault-coordinates.cjs +16 -7
- package/pp-core/bin/lib/vault-index.cjs +656 -0
- package/pp-core/bin/lib/vault-seal.cjs +1851 -0
- package/pp-core/bin/lib/vault-standards-promote.cjs +577 -0
- package/pp-core/bin/lib/vault-standards-review.cjs +293 -0
- package/pp-core/bin/lib/vault-standards.cjs +1504 -0
- package/pp-core/bin/lib/vault-trace.cjs +155 -2778
- package/pp-core/bin/lib/vault-update.cjs +10 -59
- package/pp-core/bin/lib/vault.cjs +2570 -950
- package/pp-core/bin/lib/verify.cjs +0 -11
- package/pp-core/bin/portable-timeout.sh +1 -1
- package/pp-core/bin/pp-tools.cjs +157 -54
- package/pp-core/bin/shared/config-defaults.manifest.json +0 -7
- package/pp-core/bin/shared/config-schema.manifest.json +0 -3
- package/pp-core/bin/shared/model-catalog.json +2 -2
- package/pp-core/bin/verify-reapply-patches.cjs +0 -0
- package/pp-core/org-profile.json +26 -0
- package/pp-core/references/autonomous-best-effort.md +8 -7
- package/pp-core/references/loop-hook-dispatch.md +0 -25
- package/pp-core/references/planner-gap-closure.md +0 -1
- package/pp-core/references/planner-tdd.md +0 -1
- package/pp-core/references/planner-vault-standards.md +311 -0
- package/pp-core/references/planning-config.md +0 -8
- package/pp-core/references/tdd.md +0 -1
- package/pp-core/templates/README.md +1 -0
- package/pp-core/templates/VAULT-REVIEW.md +56 -0
- package/pp-core/templates/phase-prompt.md +2 -6
- package/pp-core/workflows/_runtime-launcher.snippet.sh +0 -0
- package/pp-core/workflows/add-tests.md +55 -4
- package/pp-core/workflows/audit-fix.md +63 -2
- package/pp-core/workflows/audit-milestone.md +1 -1
- package/pp-core/workflows/autonomous.md +85 -11
- package/pp-core/workflows/check-todos.md +13 -2
- package/pp-core/workflows/code-review-fix.md +59 -3
- package/pp-core/workflows/code-review.md +10 -57
- package/pp-core/workflows/complete-milestone.md +1 -1
- package/pp-core/workflows/debug.md +54 -4
- package/pp-core/workflows/discovery-sprint/prefill.md +19 -7
- package/pp-core/workflows/discovery-sprint/prototype.md +46 -49
- package/pp-core/workflows/discovery-sprint/session-13-gates.md +2 -0
- package/pp-core/workflows/discovery-sprint/sessions/01-kick-off.md +1 -3
- package/pp-core/workflows/discovery-sprint/sessions/02-as-is.md +1 -3
- package/pp-core/workflows/discovery-sprint/sessions/03-to-be.md +1 -3
- package/pp-core/workflows/discovery-sprint/sessions/04-ux-design.md +20 -24
- package/pp-core/workflows/discovery-sprint/sessions/05-architecture.md +1 -3
- package/pp-core/workflows/discovery-sprint/sessions/06-security.md +1 -3
- package/pp-core/workflows/discovery-sprint/sessions/07-identity.md +1 -3
- package/pp-core/workflows/discovery-sprint/sessions/08-integration.md +1 -3
- package/pp-core/workflows/discovery-sprint/sessions/09-qa.md +1 -3
- package/pp-core/workflows/discovery-sprint/sessions/10-infrastructure.md +1 -6
- package/pp-core/workflows/discovery-sprint/sessions/11-roadmap.md +1 -3
- package/pp-core/workflows/discovery-sprint/sessions/12-delivery-model.md +1 -3
- package/pp-core/workflows/discovery-sprint/sessions/13-wrap-up.md +1 -3
- package/pp-core/workflows/discovery-sprint/templates/context-template.md +1 -1
- package/pp-core/workflows/discovery-sprint/vault-context.md +207 -0
- package/pp-core/workflows/discovery-sprint.md +7 -3
- package/pp-core/workflows/discovery-to-build/steps/architecture-deliverables.md +4 -4
- package/pp-core/workflows/discovery-to-build/templates/pp-handoff.md +43 -1
- package/pp-core/workflows/discovery-to-build.md +10 -2
- package/pp-core/workflows/discuss-phase.md +3 -10
- package/pp-core/workflows/execute-phase/steps/check-query-gate.md +327 -0
- package/pp-core/workflows/execute-phase/steps/client-context-gate.md +3 -2
- package/pp-core/workflows/execute-phase/steps/cross-ai-delegation.md +1 -1
- package/pp-core/workflows/execute-phase/steps/execute-pre-dispatch.md +78 -0
- package/pp-core/workflows/execute-phase/steps/per-plan-worktree-gate.md +94 -0
- package/pp-core/workflows/execute-phase/steps/post-merge-gate.md +6 -8
- package/pp-core/workflows/execute-phase/steps/vault-fetch.md +115 -14
- package/pp-core/workflows/execute-phase/steps/vault-load-gate.md +219 -20
- package/pp-core/workflows/execute-phase/steps/verify-post-gate.md +147 -0
- package/pp-core/workflows/execute-phase.md +152 -128
- package/pp-core/workflows/execute-plan.md +54 -6
- package/pp-core/workflows/fast.md +53 -4
- package/pp-core/workflows/help/modes/full.md +3 -3
- package/pp-core/workflows/init/steps/client-context-capture.md +101 -0
- package/pp-core/workflows/init/steps/gitlab-provisioning.md +130 -0
- package/pp-core/workflows/init/steps/project-md-deferral-narration.md +66 -0
- package/pp-core/workflows/init/steps/reachability-outcome.md +70 -0
- package/pp-core/workflows/init.md +232 -272
- package/pp-core/workflows/new-project.md +31 -23
- package/pp-core/workflows/plan-phase.md +98 -45
- package/pp-core/workflows/quick.md +117 -3
- package/pp-core/workflows/secure-phase.md +1 -1
- package/pp-core/workflows/ship.md +57 -28
- package/pp-core/workflows/undo.md +1 -1
- package/pp-core/workflows/update.md +3 -3
- package/pp-core/workflows/validate-phase.md +58 -3
- package/pp-core/workflows/vault-review.md +161 -23
- package/pp-core/workflows/vault-write-back.md +73 -110
- package/pp-core/workflows/verify-work.md +12 -14
- package/scripts/changeset/cli.cjs +6 -5
- package/scripts/changeset/lint.cjs +0 -0
- package/scripts/changeset/new.cjs +33 -50
- package/scripts/dev-env.cjs +25 -85
- package/scripts/gen-capability-registry.cjs +120 -13
- package/scripts/lib/allowlist-ratchet.cjs +1 -103
- package/scripts/lint-allow-test-rule-refs.allowlist.json +0 -2
- package/scripts/lint-docs-required.cjs +0 -0
- package/scripts/lint-pr-check-project-dir.cjs +1 -3
- package/scripts/lint-test-file-count.allowlist.json +3 -19
- package/scripts/lint-test-file-count.cjs +5 -6
- package/scripts/prompt-injection-scan.sh +19 -17
- package/scripts/release-channel.cjs +0 -0
- package/scripts/sync-manifest-versions.cjs +5 -4
- package/scripts/sync-rulesets.sh +1 -1
- package/scripts/update-size-baseline.cjs +30 -274
- package/scripts/verify-opengsd-sweep.cjs +3 -5
- package/scripts/workflow-size.cjs +9 -61
- package/pp-core/bin/lib/dispatch-plan.cjs +0 -483
- package/pp-core/bin/lib/install-run.cjs +0 -536
- package/pp-core/bin/lib/loop-gates.cjs +0 -213
- package/pp-core/bin/lib/phase-manifest.cjs +0 -527
- package/pp-core/bin/lib/phase-tier.cjs +0 -480
- package/pp-core/bin/lib/plan-graph.cjs +0 -368
- package/pp-core/bin/lib/practices-review-check.cjs +0 -938
- package/pp-core/bin/lib/vault-audit.cjs +0 -2070
- package/pp-core/bin/lib/vault-practices.cjs +0 -1990
- package/pp-core/bin/lib/vault-review.cjs +0 -2359
- package/pp-core/bin/lib/vault-write-back.cjs +0 -877
- package/pp-core/references/executor-vault-trace.md +0 -47
- package/pp-core/references/planner-plan-graph.md +0 -66
- package/pp-core/references/planner-vault-practices.md +0 -112
- package/pp-core/templates/practices/README.md +0 -251
- package/pp-core/templates/practices/error-handling.md +0 -18
- package/pp-core/templates/practices/minimal-comments.md +0 -14
- package/pp-core/templates/practices/naming-convention.md +0 -18
- package/pp-core/templates/practices/practice-template.md +0 -23
- package/pp-core/workflows/discovery-sprint/vault-fetch.md +0 -37
- package/pp-core/workflows/execute-phase/steps/checkpoint-handling.md +0 -45
- package/pp-core/workflows/execute-phase/steps/install-run.md +0 -29
- package/pp-core/workflows/execute-phase/steps/phase-close-rebaseline.md +0 -23
- package/pp-core/workflows/execute-phase/steps/serial-group-dispatch.md +0 -73
- package/pp-core/workflows/execute-phase/steps/vault-door-gate.md +0 -19
- package/pp-core/workflows/plan-phase/steps/phase-tier.md +0 -43
- package/scripts/lib/size-budget.cjs +0 -311
- package/scripts/lint-neutrality-names.cjs +0 -694
- package/scripts/lint-org-coordinates.allowlist.json +0 -35
- package/scripts/lint-org-coordinates.cjs +0 -426
|
@@ -89,16 +89,22 @@ Verify the work is ready to ship:
|
|
|
89
89
|
|
|
90
90
|
Resolve active `ship:pre` gate hooks from the capability registry — the registry evaluates each hook's `when` condition, so do **not** read `workflow.security_enforcement` directly:
|
|
91
91
|
|
|
92
|
+
Admission first (D-28, D-05): a config the gate cannot read renders no ship:pre vault gate at all, so this runs before the render; without bindings it is inert.
|
|
93
|
+
|
|
92
94
|
```bash
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
95
|
+
VAULT_ADMIT_PRESENT=$(pp_run query platform-bindings --pick present 2>/dev/null || echo true)
|
|
96
|
+
VAULT_ADMIT=inert
|
|
97
|
+
if [ "$VAULT_ADMIT_PRESENT" = true ]; then VAULT_ADMIT=$(pp_run vault admission 2>/dev/null || echo unrecognised); fi
|
|
98
|
+
case "$VAULT_ADMIT" in on) echo "VAULT_ADMIT=on" ;; off|inert) : ;; *) pp_run vault admission --explain; echo "PARETO_GATE_BLOCKED:vault.admission"; exit 1 ;; esac
|
|
97
99
|
```
|
|
98
100
|
|
|
99
|
-
|
|
101
|
+
```bash
|
|
102
|
+
SHIP_PRE_HOOKS_JSON=$(pp_run loop render-hooks ship:pre --raw)
|
|
103
|
+
printf '%s' "$SHIP_PRE_HOOKS_JSON" | node -e "let h=[];try{h=JSON.parse(require('fs').readFileSync(0,'utf-8')).activeHooks||[]}catch{}console.log('SHIP_PRE_HOOKS_JSON='+JSON.stringify({activeHooks:h}))"
|
|
104
|
+
SECURITY_FILE=$(ls "${PHASE_DIR}"/*-SECURITY.md 2>/dev/null | head -1)
|
|
105
|
+
```
|
|
100
106
|
|
|
101
|
-
Read the `activeHooks` array from `SHIP_PRE_HOOKS_JSON
|
|
107
|
+
Read the `activeHooks` array from the `SHIP_PRE_HOOKS_JSON=` line the fence printed, in-context (do NOT pipe it through a shell parser).
|
|
102
108
|
|
|
103
109
|
If an active entry exists with `kind == "gate"`, `capId == "security"`, and `blocking == true`, enforce its predicate (`SECURITY.md` frontmatter `threats_open == 0`) before shipping:
|
|
104
110
|
|
|
@@ -117,27 +123,50 @@ Verify the work is ready to ship:
|
|
|
117
123
|
|
|
118
124
|
**Generic `check.query` gate enforcement (capability-driven).**
|
|
119
125
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
126
|
+
> **Two behaviour changes landed here (GATE-02).** (1) Ship's gate enforcement now reads the
|
|
127
|
+
> boolean `block` field instead of `status == "block"`; every declared `check.query` producer in
|
|
128
|
+
> the repo was audited for that field and the audit table lives in the enforcer sub-file.
|
|
129
|
+
> (2) `onError: halt` now actually works at `ship:pre` — it was declared-but-unimplemented here
|
|
130
|
+
> before.
|
|
131
|
+
|
|
132
|
+
The `security` predicate branch above is handled *before* this generic loop, so the enforcer
|
|
133
|
+
never sees that entry.
|
|
134
|
+
|
|
135
|
+
For every remaining active entry in `activeHooks` where `kind == "gate"` and a `check.query` is
|
|
136
|
+
present (covers any capability-registered query gate, e.g. the `pareto-stack` platform-drift
|
|
137
|
+
gates), set `GATE_POINT=ship:pre`, `GATE_HOOKS_JSON=$SHIP_PRE_HOOKS_JSON`,
|
|
138
|
+
`GATE_POSITIONAL_ARG="${PHASE_DIR}"` and `GATE_UNPAIRED=strict`, then Read and follow
|
|
139
|
+
`pp-core/workflows/execute-phase/steps/check-query-gate.md` — the single generic `check.query`
|
|
140
|
+
gate enforcer (GATE-02, D-VH-7). It owns the two-step contract (did the command succeed? → then
|
|
141
|
+
read the boolean `block`), the halt, and the unconditional `message` passthrough. Do not restate
|
|
142
|
+
its loop here.
|
|
143
|
+
|
|
144
|
+
**The positional is `${PHASE_DIR}`, and emptying it again is an outage.** It was empty until
|
|
145
|
+
04-09. A gate declared `blocking: true` and handed no positional answers its `no-argument`
|
|
146
|
+
verdict with `block: true`, so an empty positional halts EVERY ship on EVERY vault-enabled
|
|
147
|
+
project, unconditionally and for every phase — the denial of service the gate exists to prevent,
|
|
148
|
+
shipped by the gate itself. `PHASE_DIR` is already parsed from `INIT` above and already used
|
|
149
|
+
twice before this loop, which is why the correction costs one token.
|
|
150
|
+
|
|
151
|
+
Set **no** `GATE_WS` here. A phase **directory** already carries the workstream partition — the
|
|
152
|
+
enforcer's own parameter table says so — so adding a workstream flag would not make this call
|
|
153
|
+
safer; it would add a fifth opportunity for the omitted-workstream defect this project has
|
|
154
|
+
already shipped four times. `GATE_UNPAIRED=strict` because ship is one of the two points at
|
|
155
|
+
which every plan must have an executed counterpart; mid-wave points stay tolerant.
|
|
156
|
+
|
|
157
|
+
**After the gate loop, certify the phase's end anchors.** The enforcer halts on a blocking
|
|
158
|
+
verdict, so this is reached only when it let the ship go on; nothing here assumes the phase is
|
|
159
|
+
clean from that. Run `pp_run vault anchor certify "${PHASE_DIR}" --raw` with the same
|
|
160
|
+
`${PHASE_DIR}` positional the gate loop used, print its one-line result, and continue regardless.
|
|
161
|
+
A ship run is a full-phase run by construction (see above), so there is no partial-run condition
|
|
162
|
+
here. The verb re-runs `check vault.trace "${PHASE_DIR}" --unpaired strict` itself and records
|
|
163
|
+
each SUMMARY's end anchor in the directory's `.vault-certificates.json` only when that check
|
|
164
|
+
answers clean with no override, so this step can never certify what the gate did not pass
|
|
165
|
+
(D-107, D-108). A skipped or failed step certifies nothing, which only widens the next phase's
|
|
166
|
+
SEAL-01 reach and never hides a commit (D-110). The verb prints nothing unless `vault admission`
|
|
167
|
+
answers `on`, so print nothing yourself then either. Every result (a certificate, `kept`, or a
|
|
168
|
+
refusal such as `not-clean` or `overridden`) is printed, never retried, and never halts the ship.
|
|
169
|
+
No bash fence.
|
|
141
170
|
</step>
|
|
142
171
|
|
|
143
172
|
<step name="push_branch">
|
|
@@ -452,7 +481,7 @@ pp_run query commit "docs(${padded_phase}): ship phase ${PHASE_NUMBER} — PR #$
|
|
|
452
481
|
> Capability-driven dispatch. Resolves active `ship:post` hooks via the capability registry; each hook's `when` is evaluated by the registry — no inline `config-get`. All `ship:post` hooks are post-ship and additive (`onError: skip`); a failure here never affects the already-created PR.
|
|
453
482
|
|
|
454
483
|
```bash
|
|
455
|
-
SHIP_POST_HOOKS_JSON=$(pp_run loop render-hooks ship:post --raw)
|
|
484
|
+
SHIP_POST_HOOKS_JSON=$(pp_run loop render-hooks ship:post --raw)
|
|
456
485
|
```
|
|
457
486
|
|
|
458
487
|
Read the `activeHooks` array directly from `SHIP_POST_HOOKS_JSON` in-context (do NOT pipe it through a shell parser).
|
|
@@ -75,7 +75,7 @@ Parse the user's selection into COMMITS list.
|
|
|
75
75
|
|
|
76
76
|
**MODE=phase:**
|
|
77
77
|
|
|
78
|
-
Read `.planning/.phase-manifest.json` if it exists
|
|
78
|
+
Read `.planning/.phase-manifest.json` if it exists.
|
|
79
79
|
|
|
80
80
|
If the file exists and `manifest.phases?.[TARGET_PHASE]?.commits` is a non-empty array:
|
|
81
81
|
- Use `manifest.phases[TARGET_PHASE].commits` entries as COMMITS (each entry is a commit hash)
|
|
@@ -192,8 +192,8 @@ Exit.
|
|
|
192
192
|
|
|
193
193
|
```bash
|
|
194
194
|
CHANGELOG_TMP="/tmp/pp-changelog-$$.md"
|
|
195
|
-
curl -fsSL "https://
|
|
196
|
-
|| wget -qO "$CHANGELOG_TMP" "https://
|
|
195
|
+
curl -fsSL "https://raw.githubusercontent.com/pareto000/pp-core/main/CHANGELOG.md" -o "$CHANGELOG_TMP" 2>/dev/null \
|
|
196
|
+
|| wget -qO "$CHANGELOG_TMP" "https://raw.githubusercontent.com/pareto000/pp-core/main/CHANGELOG.md" 2>/dev/null
|
|
197
197
|
|
|
198
198
|
GSD_CHANGESET_CLI="$GSD_DIR/scripts/changeset/cli.cjs"
|
|
199
199
|
if [ ! -f "$GSD_CHANGESET_CLI" ]; then
|
|
@@ -468,7 +468,7 @@ Format completion message (changelog was already shown in confirmation step):
|
|
|
468
468
|
|
|
469
469
|
⚠️ Restart your runtime to pick up the new commands.
|
|
470
470
|
|
|
471
|
-
[View full changelog](https://
|
|
471
|
+
[View full changelog](https://github.com/pareto000/pp-core/blob/main/CHANGELOG.md)
|
|
472
472
|
```
|
|
473
473
|
</step>
|
|
474
474
|
|
|
@@ -30,7 +30,7 @@ Parse: `phase_dir`, `phase_number`, `phase_name`, `phase_slug`, `padded_phase`.
|
|
|
30
30
|
|
|
31
31
|
```bash
|
|
32
32
|
AUDITOR_MODEL=$(pp_run query resolve-model pp-nyquist-auditor --raw)
|
|
33
|
-
VERIFY_POST_HOOKS_JSON=$(pp_run loop render-hooks verify:post --raw)
|
|
33
|
+
VERIFY_POST_HOOKS_JSON=$(pp_run loop render-hooks verify:post --raw)
|
|
34
34
|
```
|
|
35
35
|
|
|
36
36
|
Resolve active step hooks from `VERIFY_POST_HOOKS_JSON` where `kind == "step"` and `ref.skill == "validate-phase"`.
|
|
@@ -39,6 +39,36 @@ If no active validate-phase step hook exists: exit with "Nyquist validation is d
|
|
|
39
39
|
|
|
40
40
|
Display banner: `pp-core > VALIDATE PHASE {N}: {name}`
|
|
41
41
|
|
|
42
|
+
## 0.5 Vault admission and load gate
|
|
43
|
+
|
|
44
|
+
Vault admission and load gate (D-11, D-12, D-28): runs before the auditor writes or commits a test. A config the gate cannot
|
|
45
|
+
read halts here with the bindings present (D-05); without bindings, or with `vault.enabled` false,
|
|
46
|
+
nothing below prints or writes anything (D-13).
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
VAULT_ADMIT_PRESENT=$(pp_run query platform-bindings --pick present 2>/dev/null || echo true)
|
|
50
|
+
VAULT_ADMIT=inert
|
|
51
|
+
if [ "$VAULT_ADMIT_PRESENT" = true ]; then VAULT_ADMIT=$(pp_run vault admission 2>/dev/null || echo unrecognised); fi
|
|
52
|
+
case "$VAULT_ADMIT" in on) echo "VAULT_ADMIT=on" ;; off|inert) : ;; *) pp_run vault admission --explain; echo "PARETO_GATE_BLOCKED:vault.admission"; exit 1 ;; esac
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
**If the fence printed no `VAULT_ADMIT=on` line** (`off` and `inert` print nothing): skip the rest of this block silently. Otherwise run the load
|
|
56
|
+
gate on the `execute:pre` payload, filtered in the fence to the `vault`
|
|
57
|
+
capability (D-30):
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
VP_EXECUTE_PRE_HOOKS_JSON=$(pp_run loop render-hooks execute:pre --raw | node -e "const d=require('fs').readFileSync(0,'utf-8');try{const j=JSON.parse(d);j.activeHooks=(j.activeHooks||[]).filter((x)=>x&&x.capId==='vault');process.stdout.write(JSON.stringify(j));}catch{process.stdout.write('');}")
|
|
61
|
+
printf '%s' "$VP_EXECUTE_PRE_HOOKS_JSON" | node -e "let h=[];try{h=JSON.parse(require('fs').readFileSync(0,'utf-8')).activeHooks||[]}catch{}console.log('VP_EXECUTE_PRE_HOOKS_JSON='+JSON.stringify({activeHooks:h}))"
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Set `VAULT_FETCH_HOOKS_JSON=$VP_EXECUTE_PRE_HOOKS_JSON`, then Read and execute
|
|
65
|
+
`pp-core/workflows/execute-phase/steps/vault-fetch.md` (hook mode). Then, in the
|
|
66
|
+
`VP_EXECUTE_PRE_HOOKS_JSON=` line that fence printed, find active entries where `kind == "gate"` and `check.query ==
|
|
67
|
+
"vault.status"`; if none, skip silently. Otherwise set `GATE_POINT=execute:pre` and
|
|
68
|
+
`GATE_HOOKS_JSON=$VP_EXECUTE_PRE_HOOKS_JSON`, leave `GATE_POSITIONAL_ARG`, `GATE_WS` and
|
|
69
|
+
`GATE_STAGE` empty, then Read and follow `pp-core/workflows/execute-phase/steps/check-query-gate.md`;
|
|
70
|
+
it owns the halt.
|
|
71
|
+
|
|
42
72
|
## 1. Detect Input State
|
|
43
73
|
|
|
44
74
|
```bash
|
|
@@ -97,9 +127,17 @@ Call AskUserQuestion with gap table and options:
|
|
|
97
127
|
2. "Skip — mark manual-only" → add to Manual-Only, Step 6
|
|
98
128
|
3. "Cancel" → exit
|
|
99
129
|
|
|
100
|
-
|
|
130
|
+
### Door START anchor (before the auditor spawn)
|
|
101
131
|
|
|
102
|
-
|
|
132
|
+
Then record the door's START anchor, before the `pp-nyquist-auditor` spawn (D-31):
|
|
133
|
+
|
|
134
|
+
```bash
|
|
135
|
+
pp_run vault door-record --begin --door validate-phase --raw
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
It records HEAD in `.planning/.vault-door-starts.json`, where the record step reads it back: a shell
|
|
139
|
+
variable would not survive into that later step, and the agent never types a sha. It prints nothing
|
|
140
|
+
and writes nothing unless `vault admission` answers `on`.
|
|
103
141
|
|
|
104
142
|
## 5. Spawn pp-nyquist-auditor
|
|
105
143
|
|
|
@@ -155,6 +193,23 @@ git commit -m "test(phase-${PHASE}): add Nyquist validation tests"
|
|
|
155
193
|
pp_run query commit "docs(phase-${PHASE}): add/update validation strategy"
|
|
156
194
|
```
|
|
157
195
|
|
|
196
|
+
Vault door record (D-12), only when Step 5 ran: after the door's last source commit, set `DOOR_DIR="${PHASE_DIR}"`,
|
|
197
|
+
`DOOR_PADDED="${PADDED_PHASE}"` and `DOOR_PHASE="${PHASE}"`, then run:
|
|
198
|
+
|
|
199
|
+
```bash
|
|
200
|
+
DOOR_RUN=$(date -u +%Y%m%dT%H%M%SZ)
|
|
201
|
+
pp_run vault door-record --door validate-phase --artifact "${DOOR_DIR}/${DOOR_PADDED}-door-${DOOR_RUN}-ADD-TESTS.md" --phase "$DOOR_PHASE" --raw
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
The verb writes a `## Vault Door Record` (mode, vault ref and sha, governing phase, the start `--begin`
|
|
205
|
+
recorded and the end commit; the agent never types a sha) into a fresh per-run artifact, because it refuses a second record
|
|
206
|
+
in one file (D-57) and a rewritten report would drop the earlier run's coverage (D-79). It prints
|
|
207
|
+
nothing and writes nothing unless `vault admission` answers `on`. When it wrote the file and
|
|
208
|
+
`commit_docs` is true, commit the `artifact` path it printed: `pp_run query commit "docs(phase-${PHASE}): vault door record for validate-phase" --files "<that artifact>"`.
|
|
209
|
+
|
|
210
|
+
(A per-run `-VALIDATION.md` name would be read as the phase's validation strategy by the `*-VALIDATION.md`
|
|
211
|
+
globs, so validate-phase's record uses the `-ADD-TESTS.md` suffix: what it records is the tests it added.)
|
|
212
|
+
|
|
158
213
|
## 8. Results + Routing
|
|
159
214
|
|
|
160
215
|
**Compliant:**
|
|
@@ -1,65 +1,203 @@
|
|
|
1
1
|
<purpose>
|
|
2
|
-
Retroactive
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
Retroactive review of a completed phase against the client vault's standards documents. Works on
|
|
3
|
+
any phase whose plans carry a `<vault_standards>` block. Produces `{padded}-VAULT-REVIEW.md` with one
|
|
4
|
+
verdict per standards document that governed the phase, and counts by verdict. This workflow
|
|
5
|
+
reports; it gates nothing.
|
|
5
6
|
</purpose>
|
|
6
7
|
|
|
7
8
|
<available_agent_types>
|
|
8
9
|
Valid pp-core subagent types (use exact names — do not fall back to 'general-purpose'):
|
|
9
|
-
- pp-vault-reviewer —
|
|
10
|
+
- pp-vault-reviewer — Judges whether the phase's changes conform to each governing standards document
|
|
10
11
|
</available_agent_types>
|
|
11
12
|
|
|
12
13
|
<process>
|
|
13
14
|
|
|
14
|
-
##
|
|
15
|
+
## 0. Initialize
|
|
15
16
|
|
|
16
17
|
```bash
|
|
17
18
|
_PP_SHIM_NAME="pp-tools.cjs"; _pp_root() { ( for _v in $(env | sed -n 's/^\(GIT_[A-Za-z0-9_]*\)=.*/\1/p'); do unset "$_v"; done; _c=$(git rev-parse --git-common-dir 2>/dev/null); if [ "${_c##*/}" = .git ] && cd "$_c/.." 2>/dev/null; then pwd -P; else git rev-parse --show-toplevel 2>/dev/null || pwd; fi ); }; pp_run() { case "$PP_TOOLS" in *.cjs) node "$PP_TOOLS" "$@";; *) "$PP_TOOLS" "$@";; esac; }; _PP_RUNTIME_ROOT="${RUNTIME_DIR:-$(_pp_root)}"; PP_TOOLS="${_PP_RUNTIME_ROOT}/pp-core/bin/${_PP_SHIM_NAME}"; if [ -f "$PP_TOOLS" ]; then :; elif [ -f "${_PP_RUNTIME_ROOT}/.claude/pp-core/bin/${_PP_SHIM_NAME}" ]; then PP_TOOLS="${_PP_RUNTIME_ROOT}/.claude/pp-core/bin/${_PP_SHIM_NAME}"; elif [ -f "${_PP_RUNTIME_ROOT}/.codex/pp-core/bin/${_PP_SHIM_NAME}" ]; then PP_TOOLS="${_PP_RUNTIME_ROOT}/.codex/pp-core/bin/${_PP_SHIM_NAME}"; elif [ -f "$HOME/.claude/pp-core/bin/${_PP_SHIM_NAME}" ]; then PP_TOOLS="$HOME/.claude/pp-core/bin/${_PP_SHIM_NAME}"; elif [ -f "${HERMES_HOME:-$HOME/.hermes}/pp-core/bin/${_PP_SHIM_NAME}" ]; then PP_TOOLS="${HERMES_HOME:-$HOME/.hermes}/pp-core/bin/${_PP_SHIM_NAME}"; elif [ -f "${CURSOR_CONFIG_DIR:-$HOME/.cursor}/pp-core/bin/${_PP_SHIM_NAME}" ]; then PP_TOOLS="${CURSOR_CONFIG_DIR:-$HOME/.cursor}/pp-core/bin/${_PP_SHIM_NAME}"; elif [ -f "${CODEX_HOME:-$HOME/.codex}/pp-core/bin/${_PP_SHIM_NAME}" ]; then PP_TOOLS="${CODEX_HOME:-$HOME/.codex}/pp-core/bin/${_PP_SHIM_NAME}"; elif [ -f "${GEMINI_CONFIG_DIR:-$HOME/.gemini}/pp-core/bin/${_PP_SHIM_NAME}" ]; then PP_TOOLS="${GEMINI_CONFIG_DIR:-$HOME/.gemini}/pp-core/bin/${_PP_SHIM_NAME}"; elif [ -f "${COPILOT_CONFIG_DIR:-$HOME/.copilot}/pp-core/bin/${_PP_SHIM_NAME}" ]; then PP_TOOLS="${COPILOT_CONFIG_DIR:-$HOME/.copilot}/pp-core/bin/${_PP_SHIM_NAME}"; elif [ -f "${WINDSURF_CONFIG_DIR:-$HOME/.codeium/windsurf}/pp-core/bin/${_PP_SHIM_NAME}" ]; then PP_TOOLS="${WINDSURF_CONFIG_DIR:-$HOME/.codeium/windsurf}/pp-core/bin/${_PP_SHIM_NAME}"; elif [ -f "${AUGMENT_CONFIG_DIR:-$HOME/.augment}/pp-core/bin/${_PP_SHIM_NAME}" ]; then PP_TOOLS="${AUGMENT_CONFIG_DIR:-$HOME/.augment}/pp-core/bin/${_PP_SHIM_NAME}"; elif [ -f "${TRAE_CONFIG_DIR:-$HOME/.trae}/pp-core/bin/${_PP_SHIM_NAME}" ]; then PP_TOOLS="${TRAE_CONFIG_DIR:-$HOME/.trae}/pp-core/bin/${_PP_SHIM_NAME}"; elif [ -f "${QWEN_CONFIG_DIR:-$HOME/.qwen}/pp-core/bin/${_PP_SHIM_NAME}" ]; then PP_TOOLS="${QWEN_CONFIG_DIR:-$HOME/.qwen}/pp-core/bin/${_PP_SHIM_NAME}"; elif [ -f "${CODEBUDDY_CONFIG_DIR:-$HOME/.codebuddy}/pp-core/bin/${_PP_SHIM_NAME}" ]; then PP_TOOLS="${CODEBUDDY_CONFIG_DIR:-$HOME/.codebuddy}/pp-core/bin/${_PP_SHIM_NAME}"; elif [ -f "${CLINE_CONFIG_DIR:-$HOME/.cline}/pp-core/bin/${_PP_SHIM_NAME}" ]; then PP_TOOLS="${CLINE_CONFIG_DIR:-$HOME/.cline}/pp-core/bin/${_PP_SHIM_NAME}"; elif [ -f "${GROK_AGENTS_HOME:-$HOME/.agents}/pp-core/bin/${_PP_SHIM_NAME}" ]; then PP_TOOLS="${GROK_AGENTS_HOME:-$HOME/.agents}/pp-core/bin/${_PP_SHIM_NAME}"; elif [ -f "${ANTIGRAVITY_CONFIG_DIR:-$HOME/.gemini/antigravity}/pp-core/bin/${_PP_SHIM_NAME}" ]; then PP_TOOLS="${ANTIGRAVITY_CONFIG_DIR:-$HOME/.gemini/antigravity}/pp-core/bin/${_PP_SHIM_NAME}"; elif [ -f "${OPENCODE_CONFIG_DIR:-${XDG_CONFIG_HOME:-$HOME/.config}/opencode}/pp-core/bin/${_PP_SHIM_NAME}" ]; then PP_TOOLS="${OPENCODE_CONFIG_DIR:-${XDG_CONFIG_HOME:-$HOME/.config}/opencode}/pp-core/bin/${_PP_SHIM_NAME}"; elif [ -f "${KILO_CONFIG_DIR:-${XDG_CONFIG_HOME:-$HOME/.config}/kilo}/pp-core/bin/${_PP_SHIM_NAME}" ]; then PP_TOOLS="${KILO_CONFIG_DIR:-${XDG_CONFIG_HOME:-$HOME/.config}/kilo}/pp-core/bin/${_PP_SHIM_NAME}"; elif command -v pp-tools >/dev/null 2>&1; then PP_TOOLS="$(command -v pp-tools)"; else echo "ERROR: pp-tools.cjs not found at $PP_TOOLS and pp-tools is not on PATH. Run: npx -y @pareto4/pp-core@latest --claude --local" >&2; exit 1; fi; if [ -n "${CLAUDE_ENV_FILE:-}" ] && [ -n "${PP_TOOLS:-}" ]; then printf "export PATH='%s':\"\$PATH\"\n" "${PP_TOOLS%/*}" >> "$CLAUDE_ENV_FILE" 2>/dev/null || true; fi
|
|
18
19
|
INIT=$(pp_run query init.phase-op "${PHASE_ARG}")
|
|
19
20
|
if [[ "$INIT" == @file:* ]]; then INIT=$(cat "${INIT#@file:}"); fi
|
|
21
|
+
AGENT_SKILLS_VAULT_REVIEWER=$(pp_run query agent-skills pp-vault-reviewer)
|
|
20
22
|
```
|
|
21
23
|
|
|
22
|
-
Parse `phase_dir`, `phase_number`, `phase_name`, `padded_phase`, `
|
|
23
|
-
|
|
24
|
+
Parse: `phase_dir`, `phase_number`, `phase_name`, `padded_phase`, `commit_docs`.
|
|
25
|
+
|
|
26
|
+
### 0a. Derive first, and stop when there is nothing to review
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
REVIEW_PAYLOAD=$(pp_run check vault-review "${PHASE_DIR}" --raw)
|
|
30
|
+
REVIEW_STATUS=$(printf '%s' "${REVIEW_PAYLOAD}" | node -e "let s='';process.stdin.on('data',d=>{s+=d}).on('end',()=>{try{console.log(JSON.parse(s).status||'')}catch{console.log('unparseable')}})")
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
| `REVIEW_STATUS` | What happens |
|
|
34
|
+
|---|---|
|
|
35
|
+
| `inert` | The vault is off for this project. Print the payload's `statement` and stop. Nothing is written. |
|
|
36
|
+
| `no-argument`, `usage`, `unresolved` | Print the `statement` and stop: the CLI could not use the phase argument. Re-run with the phase directory. |
|
|
37
|
+
| `no-records` | Print the `statement` and stop: no plan in this phase was governed by a standards document. |
|
|
38
|
+
| `ok` | Continue. |
|
|
39
|
+
|
|
40
|
+
This workflow never reads `vault.enabled` itself; the CLI is the one place that decides whether the
|
|
41
|
+
vault applies.
|
|
42
|
+
|
|
43
|
+
Then display the banner:
|
|
44
|
+
|
|
45
|
+
```
|
|
46
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
47
|
+
pp-core ► VAULT STANDARDS REVIEW — PHASE {N}: {name}
|
|
48
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## 1. Detect Input State
|
|
24
52
|
|
|
25
53
|
```bash
|
|
26
|
-
|
|
54
|
+
SUMMARY_FILES=$(ls "${PHASE_DIR}"/*-SUMMARY.md 2>/dev/null)
|
|
55
|
+
VAULT_REVIEW_FILE=$(ls "${PHASE_DIR}"/*-VAULT-REVIEW.md 2>/dev/null | head -1)
|
|
27
56
|
```
|
|
28
57
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
-
|
|
32
|
-
|
|
33
|
-
- `
|
|
58
|
+
- **State A** (`VAULT_REVIEW_FILE` non-empty): a review already exists. Re-review, and append a dated
|
|
59
|
+
block to the artifact's Audit Trail rather than discarding the previous one.
|
|
60
|
+
- **State B** (`SUMMARY_FILES` non-empty): the phase is completed. Run the review.
|
|
61
|
+
- **State C** (`SUMMARY_FILES` empty): exit cleanly with "Phase {N} not executed. Run
|
|
62
|
+
`/pp:execute-phase {N}` first."
|
|
34
63
|
|
|
35
|
-
|
|
64
|
+
**Text mode (`workflow.text_mode: true` in config or `--text` flag):** Set `TEXT_MODE=true` if `--text` is present in `$ARGUMENTS` OR `text_mode` from init JSON is `true`. When TEXT_MODE is active, replace every `AskUserQuestion` call with a plain-text numbered list and ask the user to type their choice number. This is required for non-Claude runtimes (OpenAI Codex, Gemini CLI, etc.) where `AskUserQuestion` is not available.
|
|
65
|
+
|
|
66
|
+
**In State A**, use AskUserQuestion:
|
|
67
|
+
- header: "Existing Vault Review"
|
|
68
|
+
- question: "VAULT-REVIEW.md already exists for Phase {N}."
|
|
69
|
+
- options:
|
|
70
|
+
- "Re-review — run a fresh review and append to the audit trail"
|
|
71
|
+
- "View — display the current review and exit"
|
|
72
|
+
|
|
73
|
+
If "View": display the file, exit. If "Re-review": continue.
|
|
74
|
+
|
|
75
|
+
## 2. What the payload gives the reviewer
|
|
76
|
+
|
|
77
|
+
The payload is the CLI's derivation and is passed to the agent verbatim; this workflow does not
|
|
78
|
+
reinterpret it.
|
|
79
|
+
|
|
80
|
+
- `documents[]`: every standards document that governed a plan in this phase, with `cachePath` (the
|
|
81
|
+
cached copy to read; `null` when it is not cached) and `governed[]` (each plan it governed, the
|
|
82
|
+
planner's `reason`, and the executor's `consulted` status).
|
|
83
|
+
- `plans[]`: each plan's record files, its commit `range`, and the source `files` changed in that
|
|
84
|
+
range (`filesTruncated` when the list was capped).
|
|
85
|
+
- `gaps[]`: facts the CLI could not establish. Every gap goes into the artifact's `## Not Derived`
|
|
86
|
+
section; a gap is never silently dropped and never turned into a verdict.
|
|
87
|
+
|
|
88
|
+
## 3. Spawn pp-vault-reviewer
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
REVIEWER_MODEL=$(pp_run query resolve-model pp-vault-reviewer --raw)
|
|
92
|
+
```
|
|
36
93
|
|
|
37
94
|
```
|
|
38
95
|
◆ Spawning vault reviewer... (runs in a subagent — no output until it returns, ~1–5 min; expected, not a freeze)
|
|
39
96
|
```
|
|
40
97
|
|
|
98
|
+
Build the prompt:
|
|
99
|
+
|
|
100
|
+
```
|
|
101
|
+
<objective>
|
|
102
|
+
Review Phase {N}: {phase_name} against the client vault's standards documents. Give exactly one
|
|
103
|
+
verdict per document in the payload's documents[]: PASS, FAIL, N-A or INCONCLUSIVE, each non-PASS
|
|
104
|
+
verdict with a stated reason, and evidence as file:line references into the phase's changed files.
|
|
105
|
+
Write exactly one file: {phase_dir}/{padded_phase}-VAULT-REVIEW.md
|
|
106
|
+
</objective>
|
|
107
|
+
|
|
108
|
+
<review_payload>
|
|
109
|
+
{REVIEW_PAYLOAD verbatim}
|
|
110
|
+
</review_payload>
|
|
111
|
+
|
|
112
|
+
<required_reading>
|
|
113
|
+
- {summary_paths} (Execution summaries)
|
|
114
|
+
- {plan_paths} (Execution plans)
|
|
115
|
+
- {context_path} (User decisions, if it exists)
|
|
116
|
+
</required_reading>
|
|
117
|
+
|
|
118
|
+
${AGENT_SKILLS_VAULT_REVIEWER}
|
|
119
|
+
|
|
120
|
+
<config>
|
|
121
|
+
phase_dir: {phase_dir}
|
|
122
|
+
padded_phase: {padded_phase}
|
|
123
|
+
</config>
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
Omit null file paths.
|
|
127
|
+
|
|
41
128
|
```
|
|
42
129
|
Agent(
|
|
130
|
+
prompt=vault_review_prompt,
|
|
43
131
|
subagent_type="pp-vault-reviewer",
|
|
44
|
-
model="{
|
|
45
|
-
description="Vault
|
|
46
|
-
prompt="Fill the TODO rows of {phase_dir}/{padded_phase}-VAULT-REVIEW.md (Phase {phase_number}: {phase_name})."
|
|
132
|
+
model="{REVIEWER_MODEL}",
|
|
133
|
+
description="Vault standards review Phase {N}"
|
|
47
134
|
)
|
|
48
135
|
```
|
|
49
136
|
|
|
50
|
-
|
|
137
|
+
> **ORCHESTRATOR RULE — CODEX RUNTIME**: After calling Agent() above, stop working on this task immediately. Do not read more files, edit code, or run tests related to this task while the subagent is active. Wait for the subagent to return its result. This prevents duplicate work, conflicting edits, and wasted context. Only resume when the subagent result is available.
|
|
138
|
+
|
|
139
|
+
## 4. Handle Return
|
|
140
|
+
|
|
141
|
+
The agent returns `## REVIEWED` or `## ESCALATE`. On `REVIEWED`, check what it wrote:
|
|
51
142
|
|
|
52
143
|
```bash
|
|
53
|
-
pp_run vault
|
|
144
|
+
pp_run check vault-review "${PHASE_DIR}" --validate "${PHASE_DIR}/${PADDED_PHASE}-VAULT-REVIEW.md" --raw
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
`valid: true` means every governing document has exactly one verdict row, each verdict is one of the
|
|
148
|
+
four, every non-PASS verdict states its reason, and the counts line agrees with the table. Otherwise
|
|
149
|
+
list each entry of `problems[]` to the operator as a repair item. A problem is repaired in the
|
|
150
|
+
artifact, never by deleting the row that produced it. Exit 0 either way.
|
|
151
|
+
|
|
152
|
+
`ESCALATE` means no artifact could be written. Report what the agent said and stop; still exit 0.
|
|
153
|
+
|
|
154
|
+
Display the summary:
|
|
155
|
+
|
|
156
|
+
```
|
|
157
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
158
|
+
pp-core ► VAULT STANDARDS REVIEW COMPLETE
|
|
159
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
160
|
+
|
|
161
|
+
**Phase {N}: {Name}**
|
|
162
|
+
|
|
163
|
+
{the artifact's counts line}
|
|
164
|
+
|
|
165
|
+
Gaps reported: {none. / the payload's gaps}
|
|
166
|
+
|
|
167
|
+
Full review: {path to VAULT-REVIEW.md}
|
|
168
|
+
|
|
169
|
+
This review reports and does not gate. No verdict above changes a phase status,
|
|
170
|
+
a gap or any gate.
|
|
171
|
+
|
|
172
|
+
───────────────────────────────────────────────────────────────
|
|
173
|
+
|
|
174
|
+
## ▶ Next
|
|
175
|
+
|
|
176
|
+
`/clear` then one of:
|
|
177
|
+
|
|
178
|
+
- `/pp:verify-work {N}` — UAT testing
|
|
179
|
+
- `/pp:plan-phase {N+1}` — plan next phase
|
|
180
|
+
|
|
181
|
+
───────────────────────────────────────────────────────────────
|
|
54
182
|
```
|
|
55
183
|
|
|
56
|
-
|
|
57
|
-
|
|
184
|
+
The routing is offered on every path; a review with FAIL rows routes exactly like one without. No
|
|
185
|
+
step reads a verdict into a halt, an exit code or a block, and nothing here writes `ROADMAP.md`,
|
|
186
|
+
`STATE.md`, `VERIFICATION.md` or a `SUMMARY.md`. The one file this command produces is the artifact.
|
|
58
187
|
|
|
59
|
-
|
|
188
|
+
## 5. Commit (if configured)
|
|
60
189
|
|
|
61
190
|
```bash
|
|
62
|
-
pp_run query commit "docs(${PADDED_PHASE}): vault
|
|
191
|
+
pp_run query commit "docs(${PADDED_PHASE}): vault standards review" --files "${PHASE_DIR}/${PADDED_PHASE}-VAULT-REVIEW.md"
|
|
63
192
|
```
|
|
64
193
|
|
|
65
194
|
</process>
|
|
195
|
+
|
|
196
|
+
<success_criteria>
|
|
197
|
+
- [ ] Step 0a ran first and stopped on every status other than `ok`
|
|
198
|
+
- [ ] Input state detected (A/B/C); State C exits cleanly
|
|
199
|
+
- [ ] Agent spawned with the CLI payload verbatim
|
|
200
|
+
- [ ] `{padded}-VAULT-REVIEW.md` written in the phase directory and validated with `check vault-review --validate`
|
|
201
|
+
- [ ] Every payload gap appears under Not Derived
|
|
202
|
+
- [ ] Routing offered unconditionally; no verdict reached any halt, block or status
|
|
203
|
+
</success_criteria>
|