@pareto4/pp-core 1.12.0 → 1.13.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 +1 -1
- package/agents/pp-code-reviewer.md +1 -1
- package/agents/pp-executor.md +2 -13
- package/agents/pp-planner.md +1 -1
- package/agents/pp-vault-reviewer.md +51 -0
- package/commands/pp-ns-review.md +2 -1
- package/commands/pp-vault-review.md +33 -0
- package/gemini-extension.json +1 -1
- package/package.json +1 -1
- package/pp-core/bin/lib/capability-activation.cjs +19 -9
- package/pp-core/bin/lib/capability-registry.cjs +200 -10
- package/pp-core/bin/lib/check-command-router.cjs +1242 -37
- package/pp-core/bin/lib/clusters.cjs +1 -0
- package/pp-core/bin/lib/command-aliases.cjs +7 -0
- package/pp-core/bin/lib/compose-bindings.cjs +41 -27
- package/pp-core/bin/lib/config-loader.cjs +151 -8
- package/pp-core/bin/lib/decisions.cjs +104 -27
- package/pp-core/bin/lib/dispatch-plan.cjs +12 -1
- package/pp-core/bin/lib/frontmatter.cjs +37 -0
- package/pp-core/bin/lib/git-base-branch.cjs +136 -10
- package/pp-core/bin/lib/init-contract.cjs +180 -66
- package/pp-core/bin/lib/init-interactive.cjs +4 -20
- package/pp-core/bin/lib/loop-gates.cjs +213 -0
- package/pp-core/bin/lib/loop-resolver.cjs +111 -35
- package/pp-core/bin/lib/org-profile.cjs +218 -44
- package/pp-core/bin/lib/phase-command-router.cjs +7 -1
- package/pp-core/bin/lib/phase-manifest.cjs +527 -0
- package/pp-core/bin/lib/phase-tier.cjs +15 -2
- package/pp-core/bin/lib/phase.cjs +51 -1
- package/pp-core/bin/lib/vault-audit.cjs +2070 -0
- package/pp-core/bin/lib/vault-command-router.cjs +460 -1
- package/pp-core/bin/lib/vault-practices.cjs +1142 -104
- package/pp-core/bin/lib/vault-review.cjs +2359 -0
- package/pp-core/bin/lib/vault-trace.cjs +2831 -0
- package/pp-core/bin/lib/vault-update.cjs +266 -0
- package/pp-core/bin/lib/vault-write-back.cjs +19 -0
- package/pp-core/bin/lib/vault.cjs +313 -11
- package/pp-core/bin/pp-tools.cjs +30 -13
- package/pp-core/bin/shared/model-catalog.json +2 -1
- package/pp-core/references/executor-vault-trace.md +47 -0
- package/pp-core/references/loop-hook-dispatch.md +20 -2
- package/pp-core/references/planner-vault-practices.md +46 -1
- package/pp-core/references/planning-config.md +1 -1
- package/pp-core/templates/practices/README.md +140 -11
- package/pp-core/templates/project-charter.md +226 -0
- package/pp-core/workflows/add-tests.md +4 -0
- package/pp-core/workflows/audit-fix.md +2 -0
- package/pp-core/workflows/audit-milestone.md +1 -1
- package/pp-core/workflows/autonomous.md +3 -3
- package/pp-core/workflows/check-todos.md +1 -1
- package/pp-core/workflows/code-review-fix.md +3 -1
- package/pp-core/workflows/code-review.md +1 -1
- package/pp-core/workflows/debug.md +4 -0
- package/pp-core/workflows/discovery-sprint/prefill.md +9 -0
- package/pp-core/workflows/discovery-sprint/prototype.md +2 -1
- package/pp-core/workflows/discovery-sprint/vault-fetch.md +37 -0
- package/pp-core/workflows/discovery-sprint.md +1 -1
- package/pp-core/workflows/discovery-to-build.md +1 -1
- package/pp-core/workflows/discuss-phase.md +2 -2
- package/pp-core/workflows/execute-phase/steps/serial-group-dispatch.md +1 -0
- package/pp-core/workflows/execute-phase/steps/vault-door-gate.md +19 -0
- package/pp-core/workflows/execute-phase/steps/vault-fetch.md +1 -1
- package/pp-core/workflows/execute-phase/steps/vault-load-gate.md +10 -8
- package/pp-core/workflows/execute-phase.md +29 -12
- package/pp-core/workflows/execute-plan.md +4 -0
- package/pp-core/workflows/fast.md +4 -0
- package/pp-core/workflows/help/modes/full.md +3 -2
- package/pp-core/workflows/init.md +2 -2
- package/pp-core/workflows/new-project.md +1 -1
- package/pp-core/workflows/plan-phase/steps/phase-tier.md +9 -0
- package/pp-core/workflows/plan-phase.md +13 -10
- package/pp-core/workflows/quick.md +5 -1
- package/pp-core/workflows/secure-phase.md +1 -1
- package/pp-core/workflows/ship.md +7 -3
- package/pp-core/workflows/undo.md +1 -1
- package/pp-core/workflows/validate-phase.md +5 -1
- package/pp-core/workflows/vault-review.md +65 -0
- package/pp-core/workflows/verify-work.md +6 -3
- package/scripts/gen-capability-registry.cjs +11 -0
- package/scripts/lint-test-file-count.allowlist.json +10 -1
- package/scripts/prompt-injection-scan.sh +2 -0
|
@@ -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) || exit 1
|
|
34
34
|
```
|
|
35
35
|
|
|
36
36
|
Resolve active step hooks from `VERIFY_POST_HOOKS_JSON` where `kind == "step"` and `ref.skill == "validate-phase"`.
|
|
@@ -97,6 +97,10 @@ Call AskUserQuestion with gap table and options:
|
|
|
97
97
|
2. "Skip — mark manual-only" → add to Manual-Only, Step 6
|
|
98
98
|
3. "Cancel" → exit
|
|
99
99
|
|
|
100
|
+
## 4b. Vault door gate
|
|
101
|
+
|
|
102
|
+
Before the auditor writes tests, Read and execute `pp-core/workflows/execute-phase/steps/vault-door-gate.md`; a stop ends validation with no test written.
|
|
103
|
+
|
|
100
104
|
## 5. Spawn pp-nyquist-auditor
|
|
101
105
|
|
|
102
106
|
Print: `◆ Spawning nyquist auditor... (runs in a subagent — no output until it returns, ~1–5 min; expected, not a freeze)`
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
<purpose>
|
|
2
|
+
Retroactive client-vault practice review of a built phase: one agent-judged verdict (PASS / FAIL /
|
|
3
|
+
N-A / INCONCLUSIVE) per practice the vault audit cannot check, in `{padded}-VAULT-REVIEW.md`. It
|
|
4
|
+
reports and never gates: no verdict changes a status, a score, a route or a ship.
|
|
5
|
+
</purpose>
|
|
6
|
+
|
|
7
|
+
<available_agent_types>
|
|
8
|
+
Valid pp-core subagent types (use exact names — do not fall back to 'general-purpose'):
|
|
9
|
+
- pp-vault-reviewer — judges the practices the CLI could not settle
|
|
10
|
+
</available_agent_types>
|
|
11
|
+
|
|
12
|
+
<process>
|
|
13
|
+
|
|
14
|
+
## 1. Scaffold
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
_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
|
+
INIT=$(pp_run query init.phase-op "${PHASE_ARG}")
|
|
19
|
+
if [[ "$INIT" == @file:* ]]; then INIT=$(cat "${INIT#@file:}"); fi
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Parse `phase_dir`, `phase_number`, `phase_name`, `padded_phase`, `text_mode`. A phase with no
|
|
23
|
+
`*-SUMMARY.md` is not built: say "Phase {N} not executed — run /pp-execute-phase {N} first." and stop.
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
SCAFFOLD=$(pp_run vault review scaffold "${PHASE_DIR}" ${FORCE:+--force} --raw)
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Branch on its `status`:
|
|
30
|
+
- `inert`, `usage`, `no-argument`, `unresolved` — print its `statement` and stop; nothing is written.
|
|
31
|
+
- `exists` — ask "Re-review" (set `FORCE=1`, scaffold again) or "View" (show the file, stop), with
|
|
32
|
+
AskUserQuestion, or as a numbered list when `--text` is in `$ARGUMENTS` or `text_mode` is true.
|
|
33
|
+
- `written` — continue. With `toJudge` 0 there is nothing to judge: go to step 3.
|
|
34
|
+
|
|
35
|
+
## 2. Judge
|
|
36
|
+
|
|
37
|
+
```
|
|
38
|
+
◆ Spawning vault reviewer... (runs in a subagent — no output until it returns, ~1–5 min; expected, not a freeze)
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
```
|
|
42
|
+
Agent(
|
|
43
|
+
subagent_type="pp-vault-reviewer",
|
|
44
|
+
model="{pp_run query resolve-model pp-vault-reviewer --raw}",
|
|
45
|
+
description="Vault practice review Phase {phase_number}",
|
|
46
|
+
prompt="Fill the TODO rows of {phase_dir}/{padded_phase}-VAULT-REVIEW.md (Phase {phase_number}: {phase_name})."
|
|
47
|
+
)
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## 3. Finalize
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
pp_run vault review finalize "${PHASE_DIR}"
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Print its output. If it lists repair items, send them to the reviewer once ("Fix these repair items
|
|
57
|
+
in {file}: …") and finalize again. Never clear an item by editing a computed line or a derived row.
|
|
58
|
+
|
|
59
|
+
Route the same way whatever the verdicts: `/pp-verify-work {N}` or `/pp-plan-phase {N+1}`. Commit:
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
pp_run query commit "docs(${PADDED_PHASE}): vault practice review" --files "${PHASE_DIR}/${PADDED_PHASE}-VAULT-REVIEW.md"
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
</process>
|
|
@@ -41,7 +41,7 @@ _PP_SHIM_NAME="pp-tools.cjs"; _pp_root() { ( for _v in $(env | sed -n 's/^\(GIT_
|
|
|
41
41
|
GSD_WS=""
|
|
42
42
|
echo "$ARGUMENTS" | grep -qE -- '--ws[[:space:]]+[^[:space:]]+' && GSD_WS=$(echo "$ARGUMENTS" | grep -oE -- '--ws[[:space:]]+[^[:space:]]+')
|
|
43
43
|
PHASE_ARG=$(echo "$ARGUMENTS" | sed -E 's/--ws[[:space:]]+[^[:space:]]+//g' | xargs)
|
|
44
|
-
TIER_FLAG=$(
|
|
44
|
+
TIER_FLAG=$(printf '%s\n' "$ARGUMENTS" | grep -oE -- '--tier[[:space:]=]+(light|standard|heavy)' | head -1 | sed -E 's/^--tier[[:space:]=]+/--tier=/')
|
|
45
45
|
PHASE_ARG=$(echo "$PHASE_ARG" | sed -E 's/--tier[[:space:]]+[a-z]+//g' | xargs)
|
|
46
46
|
|
|
47
47
|
INIT=$(pp_run query init.verify-work "${PHASE_ARG}" ${GSD_WS} ${TIER_FLAG})
|
|
@@ -113,7 +113,7 @@ Continue to `create_uat_file`.
|
|
|
113
113
|
Before UAT, check UI capability activation and whether Playwright/Puppeteer MCP tools are available.
|
|
114
114
|
|
|
115
115
|
```bash
|
|
116
|
-
PLAN_HOOKS_JSON=$(pp_run loop render-hooks plan:pre --raw --phase "${phase_number}" ${TIER_FLAG})
|
|
116
|
+
PLAN_HOOKS_JSON=$(pp_run loop render-hooks plan:pre --raw --phase "${phase_number}" ${TIER_FLAG}) || exit 1
|
|
117
117
|
UI_SPEC_FILE=$(ls "${PHASE_DIR}"/*-UI-SPEC.md 2>/dev/null | head -1)
|
|
118
118
|
```
|
|
119
119
|
|
|
@@ -460,10 +460,13 @@ Present summary:
|
|
|
460
460
|
**If issues == 0:**
|
|
461
461
|
|
|
462
462
|
```bash
|
|
463
|
-
VERIFY_POST_HOOKS_JSON=$(pp_run loop render-hooks verify:post --raw --phase "${phase_number}" ${GSD_WS} ${TIER_FLAG})
|
|
463
|
+
VERIFY_POST_HOOKS_JSON=$(pp_run loop render-hooks verify:post --raw --phase "${phase_number}" ${GSD_WS} ${TIER_FLAG}) || exit 1
|
|
464
|
+
VERIFY_POST_GATES_JSON=$(pp_run loop run-gates verify:post --phase "${phase_number}" ${GSD_WS} ${TIER_FLAG}) || exit 1
|
|
464
465
|
SECURITY_FILE=$(ls "${PHASE_DIR}"/*-SECURITY.md 2>/dev/null | head -1)
|
|
465
466
|
```
|
|
466
467
|
|
|
468
|
+
`loop run-gates` runs every active `verify:post` gate and owns the halt: exit 1 (a `⛔` line) means a blocking gate blocked — stop, relay it, do not mark the phase complete. `⚠` lines are advisories: relay and continue.
|
|
469
|
+
|
|
467
470
|
Resolve active step hooks from `VERIFY_POST_HOOKS_JSON` where `kind == "step"` and `ref.skill == "secure-phase"`.
|
|
468
471
|
|
|
469
472
|
If an active secure-phase step hook exists AND `SECURITY_FILE` is empty, dispatch the registry-provided skill stem:
|
|
@@ -1204,6 +1204,17 @@ function validateGate(gate, prefix) {
|
|
|
1204
1204
|
if (count !== 1) {
|
|
1205
1205
|
errors.push(prefix + '.check must have exactly one of: query, predicate, agentVerdict');
|
|
1206
1206
|
}
|
|
1207
|
+
// check.args: literal tokens `loop run-gates` appends after the phase — query gates only,
|
|
1208
|
+
// at most 8, each a flag or a plain word (the runner refuses anything else at run time too).
|
|
1209
|
+
if (Object.prototype.hasOwnProperty.call(gate.check, 'args')) {
|
|
1210
|
+
const a = gate.check.args;
|
|
1211
|
+
if (!hasQuery) {
|
|
1212
|
+
errors.push(prefix + '.check.args is only valid beside check.query');
|
|
1213
|
+
} else if (!Array.isArray(a) || a.length > 8
|
|
1214
|
+
|| !a.every((t) => typeof t === 'string' && /^(?:--[a-z][a-z0-9-]*|[a-z0-9][a-z0-9._-]*)$/i.test(t))) {
|
|
1215
|
+
errors.push(prefix + '.check.args must be an array of at most 8 flags (--name) or plain words');
|
|
1216
|
+
}
|
|
1217
|
+
}
|
|
1207
1218
|
// agentVerdict forces blocking: false (advisory only)
|
|
1208
1219
|
if (hasAgentVerdict && gate.blocking === true) {
|
|
1209
1220
|
errors.push(
|
|
@@ -187,13 +187,22 @@
|
|
|
187
187
|
],
|
|
188
188
|
"issue": "v1.7.0 Client Vault Load — four distinct concerns: vault.test (fetch/status/summary unit), vault-security (VSEC-02/03 write-guard + secret/fence), vault-read-path (VGATE-03 SUMMARY pointer), vault-status-check (VGATE-02 gate-query handler). Phase 24-02 added vault-practices.property.test.cjs (fast-check fuzz of the practices glob-fallback compiler + a practices-frontmatter round-trip, PRAC-02) — it is grouped under this bucket rather than \"vault-practices\" because the test-file-count lint's hyphen-prefix matcher treats \"vault-practices.property\" (period before \"property\") as starting with \"vault-\" before it can match the more specific \"vault-practices-\" prefix; the module it actually tests is pp-core/bin/lib/vault-practices.cjs, not vault.cjs."
|
|
189
189
|
},
|
|
190
|
+
"vault-review": {
|
|
191
|
+
"files": [
|
|
192
|
+
"vault-review.integration.test.cjs",
|
|
193
|
+
"vault-review.security.test.cjs",
|
|
194
|
+
"vault-review.test.cjs"
|
|
195
|
+
],
|
|
196
|
+
"issue": "Agent practice review (vault assurance R5) — three distinct concerns for pp-core/bin/lib/vault-review.cjs: vault-review.test (the pure derivations — vocabularies, both derived-N-A arms, the counts, the range, the clean-render refusal, the scaffold renderer and the line stamper — plus the require-graph barrier), vault-review.integration.test (the seams: the artifact validator and the check vault-review / vault review scaffold|finalize arms driven through the real pp-tools.cjs, where the exit-0 / no-block-key contract is proved), and vault-review.security.test (adversarial practice bodies: a spoofed fence marker, directive-shaped text, a client table inside the fence, an option-shaped base branch). The .security marker is what identifies the adversarial lane to scripts/run-tests.cjs; consolidating would blur three different questions into one file."
|
|
197
|
+
},
|
|
190
198
|
"vault-practices": {
|
|
191
199
|
"files": [
|
|
192
200
|
"vault-practices-examples.test.cjs",
|
|
193
201
|
"vault-practices-matcher.test.cjs",
|
|
202
|
+
"vault-practices.slow.test.cjs",
|
|
194
203
|
"vault-practices.test.cjs"
|
|
195
204
|
],
|
|
196
|
-
"issue": "Phase 24 (24-01/24-02/24-04) — three distinct concerns for pp-core/bin/lib/vault-practices.cjs: vault-practices.test (24-01 parser/validation/discovery unit tests), vault-practices-matcher.test (24-02 glob matcher + two-bucket result + report unit tests), vault-practices-examples.test (24-04 shipped-example drift guard + minimal-comments global-bucket smoke case, PRAC-03 Success Criterion 3). All three test the same production module and are each independently load-bearing; consolidating would blur distinct plan-level verification gates."
|
|
205
|
+
"issue": "Phase 24 (24-01/24-02/24-04) — three distinct concerns for pp-core/bin/lib/vault-practices.cjs: vault-practices.test (24-01 parser/validation/discovery unit tests), vault-practices-matcher.test (24-02 glob matcher + two-bucket result + report unit tests), vault-practices-examples.test (24-04 shipped-example drift guard + minimal-comments global-bucket smoke case, PRAC-03 Success Criterion 3). All three test the same production module and are each independently load-bearing; consolidating would blur distinct plan-level verification gates. The practice-file contract extensions added vault-practices.slow.test.cjs — the >5 s worst-case matcher corpus behind the matching cost bound, split out per the .slow suffix convention so the default suite stays fast."
|
|
197
206
|
}
|
|
198
207
|
}
|
|
199
208
|
}
|
|
@@ -89,6 +89,8 @@ ALLOWLIST=(
|
|
|
89
89
|
'tests/security.test.cjs::the adversarial suite for the library sanitisers, whose fixtures are real override and role-manipulation strings asserted to be neutralised; measured 54 pattern hits at HEAD on 2026-10-11'
|
|
90
90
|
'tests/prompt-injection-scan.security.test.cjs::drives scanForInjection in the compiled security library with crafted payloads, and carries a second allowlist of its own for that separate scanner; measured 11 pattern hits at HEAD on 2026-10-11'
|
|
91
91
|
'tests/vault-security.test.cjs::the vault fencing suite plants an instruction-override heading in a fixture vault file and asserts SUMMARY.md fences and defangs it rather than passing it to the agent as instructions; measured 1 pattern hit at HEAD on 2026-10-11'
|
|
92
|
+
'tests/vault-practices-matcher.test.cjs::the vault practices matcher suite plants an instruction-override line inside a fixture practice body and a spoofed fence end, and asserts the matcher keeps both inside the untrusted fenced region, so the fixtures must carry a real injection phrase'
|
|
93
|
+
'tests/vault-review.security.test.cjs::the adversarial suite of the agent practice review seeds a practice body with directive-shaped text aimed at the practice judge (the DIRECTIVE_TEXT constant) and asserts the rendered review entry carries it only between the fence markers, after the reference-data preamble, so the judge reads it as data; the text must be a literal for that assertion to mean anything; measured 1 pattern hit at HEAD on 2026-10-12'
|
|
92
94
|
'tests/verify.test.cjs::the verification suite plants an instruction-override line in a phase artifact and asserts it is rejected, so the line is present as a negative fixture; measured 1 pattern hit at HEAD on 2026-10-11'
|
|
93
95
|
'pp-core/bin/lib/security.cjs::gitignored build output compiled from src/security.cts per .gitignore line 117, so it is unreachable in diff mode and matters only to a local dir-mode run; it carries the library injection patterns inline; measured 8 pattern hits at HEAD on 2026-10-11'
|
|
94
96
|
'tests/read-injection-scanner.security.test.cjs::exercises the read-time injection scanner hook with the payloads a hostile file would carry, each asserted to be blocked rather than obeyed; measured 14 pattern hits at HEAD on 2026-10-11'
|