@pareto4/pp-core 1.17.1 → 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 +1 -1
- package/README.md +5 -3
- package/agents/pp-code-fixer.md +0 -11
- package/agents/pp-code-reviewer.md +1 -78
- package/agents/pp-executor.md +9 -23
- package/agents/pp-planner.md +11 -11
- package/agents/pp-vault-reviewer.md +43 -189
- package/agents/pp-verifier.md +0 -6
- package/commands/pp-ns-manage.md +1 -1
- package/commands/pp-ns-review.md +1 -1
- package/commands/pp-vault-promote.md +7 -8
- package/commands/pp-vault-review.md +6 -7
- package/gemini-extension.json +1 -1
- package/package.json +3 -6
- package/pp-core/bin/lib/capability-registry.cjs +13 -355
- package/pp-core/bin/lib/capability-state.cjs +15 -79
- package/pp-core/bin/lib/capability-writer.cjs +2 -16
- package/pp-core/bin/lib/check-command-router.cjs +277 -2273
- package/pp-core/bin/lib/clusters.cjs +2 -2
- package/pp-core/bin/lib/compose-bindings.cjs +2 -2
- package/pp-core/bin/lib/config.cjs +3 -6
- package/pp-core/bin/lib/git-base-branch.cjs +10 -13
- package/pp-core/bin/lib/git-provider.cjs +5 -6
- package/pp-core/bin/lib/init-contract.cjs +7 -35
- package/pp-core/bin/lib/init-interactive.cjs +6 -20
- package/pp-core/bin/lib/io.cjs +2 -8
- package/pp-core/bin/lib/loop-resolver.cjs +8 -32
- package/pp-core/bin/lib/org-profile.cjs +16 -92
- package/pp-core/bin/lib/vault-command-router.cjs +174 -1206
- package/pp-core/bin/lib/vault-coordinates.cjs +3 -3
- package/pp-core/bin/lib/vault-index.cjs +27 -70
- package/pp-core/bin/lib/vault-seal.cjs +37 -122
- 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 +15 -16
- package/pp-core/bin/lib/vault-trace.cjs +40 -3016
- package/pp-core/bin/lib/vault-update.cjs +1 -26
- package/pp-core/bin/lib/vault.cjs +120 -314
- package/pp-core/bin/pp-tools.cjs +5 -32
- package/pp-core/references/autonomous-best-effort.md +1 -1
- package/pp-core/references/planner-vault-standards.md +16 -25
- package/pp-core/templates/README.md +1 -1
- package/pp-core/templates/VAULT-REVIEW.md +24 -170
- package/pp-core/workflows/add-tests.md +3 -3
- package/pp-core/workflows/audit-fix.md +3 -3
- package/pp-core/workflows/code-review-fix.md +3 -3
- package/pp-core/workflows/code-review.md +1 -57
- package/pp-core/workflows/debug.md +2 -2
- package/pp-core/workflows/discovery-sprint/prototype.md +2 -2
- package/pp-core/workflows/discovery-sprint/vault-context.md +4 -10
- package/pp-core/workflows/execute-phase/steps/check-query-gate.md +11 -13
- package/pp-core/workflows/execute-phase/steps/execute-pre-dispatch.md +5 -25
- package/pp-core/workflows/execute-phase/steps/vault-fetch.md +6 -6
- package/pp-core/workflows/execute-phase/steps/vault-load-gate.md +6 -109
- package/pp-core/workflows/execute-phase/steps/verify-post-gate.md +1 -17
- package/pp-core/workflows/execute-phase.md +2 -5
- package/pp-core/workflows/execute-plan.md +6 -8
- package/pp-core/workflows/help/modes/full.md +1 -1
- package/pp-core/workflows/quick.md +8 -8
- package/pp-core/workflows/validate-phase.md +3 -3
- package/pp-core/workflows/vault-review.md +64 -186
- package/pp-core/workflows/vault-write-back.md +73 -110
- package/pp-core/workflows/verify-work.md +1 -1
- package/scripts/gen-capability-registry.cjs +12 -93
- package/scripts/lint-test-file-count.allowlist.json +1 -19
- package/scripts/lint-test-file-count.cjs +5 -6
- package/scripts/prompt-injection-scan.sh +0 -3
- package/pp-core/bin/lib/practices-review-check.cjs +0 -944
- package/pp-core/bin/lib/vault-audit.cjs +0 -2594
- package/pp-core/bin/lib/vault-mode.cjs +0 -235
- package/pp-core/bin/lib/vault-practices.cjs +0 -2057
- package/pp-core/bin/lib/vault-review.cjs +0 -2102
- package/pp-core/bin/lib/vault-write-back.cjs +0 -905
- package/pp-core/references/planner-vault-practices.md +0 -95
- package/pp-core/references/practice-arithmetic-contract.md +0 -121
- package/pp-core/references/verifier-practice-verdicts.md +0 -263
- package/pp-core/templates/practices/README.md +0 -248
- 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/execute-phase/steps/verifier-practice-payload.md +0 -165
- package/scripts/gen-practice-arithmetic-contract.cjs +0 -412
- package/scripts/practice-arithmetic-contract.allow.json +0 -35
- package/scripts/record-vault-mode-golden.cjs +0 -89
- package/scripts/vault-calibrate.cjs +0 -996
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
<purpose>
|
|
2
|
-
Take one local
|
|
3
|
-
vault
|
|
4
|
-
irreversible outward action: it shows the operator the complete preview, asks once
|
|
5
|
-
to proceed, and only on explicit approval re-invokes the same guarded CLI
|
|
6
|
-
mode. It never authors, edits
|
|
7
|
-
|
|
8
|
-
workflow only calls.
|
|
2
|
+
Take one local standards document from preview to a confirmed, pushed promotion into the client
|
|
3
|
+
vault, together with its INDEX.md entry, and nothing more. This workflow is the single human gate
|
|
4
|
+
in front of an irreversible outward action: it shows the operator the complete preview, asks once
|
|
5
|
+
whether to proceed, and only on explicit approval re-invokes the same guarded CLI verb in confirmed
|
|
6
|
+
mode. It never authors, edits or reformats the document, and it performs no git operation of its
|
|
7
|
+
own; every outward action happens inside `pp_run vault standards promote`.
|
|
9
8
|
</purpose>
|
|
10
9
|
|
|
11
10
|
<required_reading>
|
|
@@ -15,79 +14,64 @@ Read all files referenced by the invoking prompt's execution_context before star
|
|
|
15
14
|
<process>
|
|
16
15
|
|
|
17
16
|
<step name="text_mode">
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
workflow
|
|
22
|
-
operator to type their choice number. This is required because non-Claude runtimes have no
|
|
23
|
-
interactive question tool, and the confirmation in Step 4 is the entire point of this
|
|
24
|
-
workflow — it must degrade to plain text, never disappear.
|
|
25
|
-
</step>
|
|
26
|
-
|
|
27
|
-
<step name="resolve_launcher">
|
|
28
|
-
Resolve the `pp_run` launcher shim before any other step, so every call below goes through
|
|
29
|
-
the repo-local or installed `pp-tools` binary rather than assuming a global install:
|
|
30
|
-
|
|
31
|
-
```bash
|
|
32
|
-
```
|
|
17
|
+
Set `TEXT_MODE=true` if `--text` is present in `$ARGUMENTS`. When `TEXT_MODE` is active, replace
|
|
18
|
+
every `AskUserQuestion` call in this workflow, including the gate below, with a plain-text numbered
|
|
19
|
+
list, and ask the operator to type their choice number. The confirmation is the point of this
|
|
20
|
+
workflow: it must degrade to plain text, never disappear.
|
|
33
21
|
</step>
|
|
34
22
|
|
|
35
23
|
<step name="resolve_input">
|
|
36
|
-
Take
|
|
37
|
-
none was given, ask the operator for one with a plain prompt:
|
|
24
|
+
Take from `$ARGUMENTS`:
|
|
38
25
|
|
|
39
|
-
|
|
40
|
-
Path to the local
|
|
41
|
-
|
|
26
|
+
- the document path: the first token that is not a flag (required; ask for it with a plain prompt
|
|
27
|
+
when it is missing: `Path to the local standards document to promote (e.g. docs/standards/api-errors.md):`);
|
|
28
|
+
- `--path <vault-path>`: where the document goes in the vault (optional; defaults to
|
|
29
|
+
`standards/<file name>`);
|
|
30
|
+
- `--entry "<what it is>; used when <…>"`: the document's INDEX.md entry text (required when the
|
|
31
|
+
vault's INDEX.md does not list the document yet; replaces the existing line when given for a
|
|
32
|
+
listed document);
|
|
33
|
+
- `--section <title>`: the INDEX.md `##` section a new entry goes under (optional).
|
|
34
|
+
|
|
35
|
+
When the document is new to the vault and no `--entry` was given, ask the operator for one plain
|
|
36
|
+
sentence of the form `<what the document is>; used when <when a plan should follow it>`. Never
|
|
37
|
+
invent it.
|
|
42
38
|
|
|
43
|
-
Do not compose,
|
|
44
|
-
|
|
45
|
-
that path are exactly the bytes that will be previewed and, if approved, pushed.
|
|
39
|
+
Do not compose, rewrite or reformat the document at this or any later step. Whatever bytes are on
|
|
40
|
+
disk at that path are exactly the bytes that will be previewed and, if approved, pushed.
|
|
46
41
|
|
|
47
42
|
```bash
|
|
48
|
-
|
|
43
|
+
DOC_FILE="<the resolved path>"
|
|
44
|
+
PROMOTE_ARGS=() # add --path, --entry and --section with their values, as given
|
|
49
45
|
```
|
|
50
46
|
</step>
|
|
51
47
|
|
|
52
48
|
<step name="preview">
|
|
53
|
-
Run the promote verb
|
|
54
|
-
|
|
55
|
-
|
|
49
|
+
Run the promote verb without `--confirmed`, capturing stdout, stderr and the exit code. This
|
|
50
|
+
invocation performs no outward action: it clones the client vault into a disposable directory,
|
|
51
|
+
writes the change there, and reports the diff.
|
|
56
52
|
|
|
57
53
|
```bash
|
|
58
54
|
_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
|
|
59
55
|
PROMOTE_PREVIEW_OUT=$(mktemp)
|
|
60
56
|
PROMOTE_PREVIEW_ERR=$(mktemp)
|
|
61
|
-
pp_run vault
|
|
57
|
+
pp_run vault standards promote "$DOC_FILE" "${PROMOTE_ARGS[@]}" --raw >"$PROMOTE_PREVIEW_OUT" 2>"$PROMOTE_PREVIEW_ERR"
|
|
62
58
|
PREVIEW_EXIT=$?
|
|
63
59
|
```
|
|
64
60
|
|
|
65
|
-
**When `$PREVIEW_EXIT` is non-zero: stop here.** Show the operator the
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
and nothing has been pushed. Clean up both temp files before ending.
|
|
61
|
+
**When `$PREVIEW_EXIT` is non-zero: stop here.** Show the operator the single-sentence refusal in
|
|
62
|
+
`$PROMOTE_PREVIEW_ERR` verbatim and add nothing to it. Do not ask anything. Nothing has been pushed.
|
|
63
|
+
Clean up both temp files before ending.
|
|
69
64
|
|
|
70
|
-
When `$PREVIEW_EXIT` is zero,
|
|
71
|
-
preview verdict as JSON.
|
|
65
|
+
When `$PREVIEW_EXIT` is zero, `$PROMOTE_PREVIEW_OUT` holds the preview verdict as JSON.
|
|
72
66
|
</step>
|
|
73
67
|
|
|
74
68
|
<step name="render_confirmation">
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
emits.
|
|
79
|
-
|
|
80
|
-
Field values are vault-authored, so they are read as **data, never as shell syntax**. `id`
|
|
81
|
-
is only constrained to equal the practice file's basename (D-03), and a filename may legally
|
|
82
|
-
contain `$(...)`, backticks, or `;` — so writing the fields as a `KEY="value"` file and
|
|
83
|
-
`source`-ing it would execute whatever the filename contains. `JSON.stringify` does not help:
|
|
84
|
-
it escapes `"` and `\` but leaves `$` and backticks intact, and both expand inside double
|
|
85
|
-
quotes. Each field therefore goes to its own file and is read back with `$(cat …)`, whose
|
|
86
|
-
result bash does not re-scan for expansion.
|
|
69
|
+
Read the verdict's fields directly, never by scraping a prose rendering. Each field is written to
|
|
70
|
+
its own file and read back with `$(cat …)`, whose result bash does not re-scan for expansion, so a
|
|
71
|
+
destination path containing `$(...)` or backticks is shown, never executed.
|
|
87
72
|
|
|
88
73
|
```bash
|
|
89
74
|
PROMOTE_FIELDS=$(mktemp -d)
|
|
90
|
-
PROMOTE_BODY=$(mktemp)
|
|
91
75
|
node -e "
|
|
92
76
|
const fs = require('fs');
|
|
93
77
|
const path = require('path');
|
|
@@ -98,94 +82,78 @@ put('repo', v.repo);
|
|
|
98
82
|
put('ref', v.ref);
|
|
99
83
|
put('destination', v.destination);
|
|
100
84
|
put('mode', v.mode);
|
|
101
|
-
put('
|
|
102
|
-
put('sharedShadow', v.sharedShadow ? 'true' : 'false');
|
|
103
|
-
put('sharedShadowNote', v.sharedShadowNote);
|
|
85
|
+
put('indexChange', v.indexChange);
|
|
104
86
|
put('expect', v.expect);
|
|
105
|
-
|
|
106
|
-
|
|
87
|
+
put('diff', v.diff);
|
|
88
|
+
put('notes', (v.notes || []).join('\n'));
|
|
89
|
+
" "$PROMOTE_PREVIEW_OUT" "$PROMOTE_FIELDS"
|
|
107
90
|
PROMOTE_REPO=$(cat "$PROMOTE_FIELDS/repo")
|
|
108
91
|
PROMOTE_REF=$(cat "$PROMOTE_FIELDS/ref")
|
|
109
92
|
PROMOTE_DEST=$(cat "$PROMOTE_FIELDS/destination")
|
|
110
93
|
PROMOTE_MODE=$(cat "$PROMOTE_FIELDS/mode")
|
|
111
|
-
|
|
112
|
-
PROMOTE_SHARED=$(cat "$PROMOTE_FIELDS/sharedShadow")
|
|
113
|
-
PROMOTE_SHARED_NOTE=$(cat "$PROMOTE_FIELDS/sharedShadowNote")
|
|
94
|
+
PROMOTE_INDEX=$(cat "$PROMOTE_FIELDS/indexChange")
|
|
114
95
|
PROMOTE_EXPECT=$(cat "$PROMOTE_FIELDS/expect")
|
|
115
96
|
```
|
|
116
97
|
|
|
117
|
-
Show the operator, in this
|
|
118
|
-
never truncated, summarized, or collapsed to "the first N lines":
|
|
98
|
+
Show the operator, in this order, never truncated or summarised:
|
|
119
99
|
|
|
120
100
|
1. The target vault repository (`$PROMOTE_REPO`) and ref (`$PROMOTE_REF`).
|
|
121
|
-
2. The destination path
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
5.
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
6. The complete contents of `$PROMOTE_BODY` — the full diff when `$PROMOTE_MODE` is
|
|
131
|
-
`update`, or the full new-file content when it is `create`. Show every byte; the operator
|
|
132
|
-
is about to approve exactly these bytes, so nothing here may be shortened.
|
|
101
|
+
2. The destination path in the vault (`$PROMOTE_DEST`), and whether this **creates** a new
|
|
102
|
+
standards document or **updates** an existing one (`$PROMOTE_MODE`).
|
|
103
|
+
3. What happens to INDEX.md (`$PROMOTE_INDEX`): `added` (a new line), `replaced` (its line gets the
|
|
104
|
+
new entry text) or `unchanged`.
|
|
105
|
+
4. One line stating that the secret scan inside the promote verb found nothing; a document that
|
|
106
|
+
failed it would have been refused before any preview existed.
|
|
107
|
+
5. Any notes in `$PROMOTE_FIELDS/notes`.
|
|
108
|
+
6. The complete contents of `$PROMOTE_FIELDS/diff`: the document and the INDEX.md change, every
|
|
109
|
+
byte. The operator is about to approve exactly these bytes.
|
|
133
110
|
</step>
|
|
134
111
|
|
|
135
112
|
<step name="gate">
|
|
136
|
-
Ask
|
|
137
|
-
active) whether to push this to the client vault. Offer exactly two outcomes — there is no
|
|
138
|
-
default, no timeout, and no auto-advance, because this is an irreversible outward action and
|
|
139
|
-
this confirmation is the whole review step:
|
|
113
|
+
Ask once whether to push. Exactly two outcomes, no default, no timeout, no auto-advance:
|
|
140
114
|
|
|
141
115
|
```text
|
|
142
116
|
AskUserQuestion([
|
|
143
117
|
{
|
|
144
118
|
header: "Push to client vault",
|
|
145
|
-
question: "Push this
|
|
119
|
+
question: "Push this standards document to the client vault now?",
|
|
146
120
|
multiSelect: false,
|
|
147
121
|
options: [
|
|
148
|
-
{ label: "Push it", description: "Push exactly the diff
|
|
122
|
+
{ label: "Push it", description: "Push exactly the diff shown above" },
|
|
149
123
|
{ label: "Stop", description: "Do not push anything — the vault stays unchanged" }
|
|
150
124
|
]
|
|
151
125
|
}
|
|
152
126
|
])
|
|
153
127
|
```
|
|
154
128
|
|
|
155
|
-
**When the operator chooses to stop:**
|
|
156
|
-
|
|
129
|
+
**When the operator chooses to stop:** say in one sentence that nothing was pushed and the client
|
|
130
|
+
vault is unchanged, clean up the temp paths, and end.
|
|
157
131
|
|
|
158
|
-
**When the operator chooses to push:** continue
|
|
132
|
+
**When the operator chooses to push:** continue.
|
|
159
133
|
</step>
|
|
160
134
|
|
|
161
135
|
<step name="push">
|
|
162
|
-
Only inside this approved branch, run the
|
|
163
|
-
|
|
164
|
-
workflow never runs an outward git operation itself — the only thing it does here is invoke
|
|
165
|
-
this verb a second time; every push, every commit, and every other outward action happens
|
|
166
|
-
inside the verb, not in this shell block.
|
|
136
|
+
Only inside this approved branch, run the verb again with the same arguments, `--confirmed`, and the
|
|
137
|
+
expect token carried verbatim from the preview.
|
|
167
138
|
|
|
168
139
|
```bash
|
|
169
140
|
PROMOTE_PUSH_OUT=$(mktemp)
|
|
170
141
|
PROMOTE_PUSH_ERR=$(mktemp)
|
|
171
|
-
pp_run vault
|
|
142
|
+
pp_run vault standards promote "$DOC_FILE" "${PROMOTE_ARGS[@]}" --confirmed --expect "$PROMOTE_EXPECT" --raw >"$PROMOTE_PUSH_OUT" 2>"$PROMOTE_PUSH_ERR"
|
|
172
143
|
PUSH_EXIT=$?
|
|
173
144
|
```
|
|
174
145
|
|
|
175
|
-
**When `$PUSH_EXIT` is non-zero:** show the
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
The remedy is simply to run this workflow again from the top — the new preview will diff
|
|
180
|
-
against their current version. Clean up all temp files before ending.
|
|
181
|
-
|
|
182
|
-
When `$PUSH_EXIT` is zero, continue to Step 6 with `$PROMOTE_PUSH_OUT` holding the push
|
|
183
|
-
verdict as JSON.
|
|
146
|
+
**When `$PUSH_EXIT` is non-zero:** show the verb's single-sentence refusal from `$PROMOTE_PUSH_ERR`
|
|
147
|
+
verbatim and end; a refusal guarantees nothing was pushed. A concurrent-edit refusal is ordinary:
|
|
148
|
+
someone changed the document or INDEX.md in the vault since the preview. The remedy is to run this
|
|
149
|
+
workflow again from the top. Clean up all temp paths before ending.
|
|
184
150
|
</step>
|
|
185
151
|
|
|
186
152
|
<step name="report">
|
|
187
|
-
|
|
188
|
-
|
|
153
|
+
Read the push verdict's fields the same way, then show the operator the repository, the destination,
|
|
154
|
+
the new commit, what happened to INDEX.md, and whether the local vault cache was refreshed. When the
|
|
155
|
+
refresh did not succeed, say so plainly: the next vault fetch picks the change up; the push itself
|
|
156
|
+
succeeded.
|
|
189
157
|
|
|
190
158
|
```bash
|
|
191
159
|
node -e "
|
|
@@ -195,19 +163,14 @@ process.stdout.write(
|
|
|
195
163
|
'repo=' + (v.repo ?? '') + '\n' +
|
|
196
164
|
'destination=' + (v.destination ?? '') + '\n' +
|
|
197
165
|
'commit=' + (v.commit ?? '') + '\n' +
|
|
166
|
+
'indexChange=' + (v.indexChange ?? '') + '\n' +
|
|
198
167
|
'cacheRefreshed=' + String(!!v.cacheRefreshed) + '\n'
|
|
199
168
|
);
|
|
200
169
|
" "$PROMOTE_PUSH_OUT"
|
|
201
170
|
```
|
|
202
171
|
|
|
203
|
-
|
|
204
|
-
and
|
|
205
|
-
not succeed, say so plainly and note that the next vault fetch will pick up the change — this
|
|
206
|
-
is a cosmetic staleness in the local cache only, not a sign the push failed.
|
|
207
|
-
|
|
208
|
-
Clean up every temp path created in this workflow (`$PROMOTE_PREVIEW_OUT`,
|
|
209
|
-
`$PROMOTE_PREVIEW_ERR`, `$PROMOTE_BODY`, `$PROMOTE_PUSH_OUT`, `$PROMOTE_PUSH_ERR`, and the
|
|
210
|
-
`$PROMOTE_FIELDS` **directory**, which needs `rm -rf`) before ending.
|
|
172
|
+
Clean up every temp path created in this workflow (`$PROMOTE_PREVIEW_OUT`, `$PROMOTE_PREVIEW_ERR`,
|
|
173
|
+
`$PROMOTE_PUSH_OUT`, `$PROMOTE_PUSH_ERR`, and the `$PROMOTE_FIELDS` directory with `rm -rf`).
|
|
211
174
|
</step>
|
|
212
175
|
|
|
213
176
|
</process>
|
|
@@ -463,7 +463,7 @@ printf '%s' "$VERIFY_POST_HOOKS_JSON" | node -e "let h=[];try{h=JSON.parse(requi
|
|
|
463
463
|
SECURITY_FILE=$(ls "${PHASE_DIR}"/*-SECURITY.md 2>/dev/null | head -1)
|
|
464
464
|
```
|
|
465
465
|
|
|
466
|
-
**Vault
|
|
466
|
+
**Vault gates.** Read `pp-core/workflows/execute-phase/steps/verify-post-gate.md` — it
|
|
467
467
|
dispatches this point's blocking gates to the generic enforcer, which owns the halt. Rendering the
|
|
468
468
|
payload above is not enforcing it, and the branch below marks the phase complete.
|
|
469
469
|
|
|
@@ -1247,8 +1247,7 @@ function validateGate(gate, prefix) {
|
|
|
1247
1247
|
* - contribution.into ∈ step's agentRoles, OR contribution.into names an agent
|
|
1248
1248
|
* already registered by some capability's own `agents` array (a non-pipeline
|
|
1249
1249
|
* consumer of the same loop point, e.g. code-review.md reading execute:post
|
|
1250
|
-
* alongside execute-phase.md
|
|
1251
|
-
* execute:post -> pp-code-reviewer contribution)
|
|
1250
|
+
* alongside execute-phase.md)
|
|
1252
1251
|
* - when references a config key in cap.config
|
|
1253
1252
|
*
|
|
1254
1253
|
* NOTE: step.consumes satisfiability is NOT checked here — it requires the full
|
|
@@ -1331,78 +1330,9 @@ function validateAgainstContract(cap, capId, knownAgentIds) {
|
|
|
1331
1330
|
return errors;
|
|
1332
1331
|
}
|
|
1333
1332
|
|
|
1334
|
-
/**
|
|
1335
|
-
* Phase 15 D-02: validate the per-hook `vaultMode` filter field.
|
|
1336
|
-
*
|
|
1337
|
-
* The pure loop resolver evaluates `vaultMode` against an injected mode value
|
|
1338
|
-
* and never emits it, so an unknown or misplaced value must be refused HERE,
|
|
1339
|
-
* at generation, never interpreted at runtime. Three rules, each reported on
|
|
1340
|
-
* its own:
|
|
1341
|
-
* (a) the field is allowed on contributions and gates only (a step is
|
|
1342
|
-
* refused);
|
|
1343
|
-
* (b) the value must be a string in the vault capability's declared
|
|
1344
|
-
* `config["vault.mode"].values`. That enum declaration is the ONE owner of
|
|
1345
|
-
* the closed set; it is read here, never restated. With no vault
|
|
1346
|
-
* capability, or no such values array, there is no closed set and every
|
|
1347
|
-
* `vaultMode` is refused (fail closed);
|
|
1348
|
-
* (c) the declaring capability must be `vault` or list `vault` in `requires`,
|
|
1349
|
-
* so a filtered hook can only exist where the vault gate's closure holds.
|
|
1350
|
-
*
|
|
1351
|
-
* Presence is own-property presence, so a JSON `null` is refused under (b).
|
|
1352
|
-
*
|
|
1353
|
-
* @param {Map<string, object>} capMap
|
|
1354
|
-
* @returns {string[]} error strings; empty = all pass
|
|
1355
|
-
*/
|
|
1356
|
-
function validateVaultModeField(capMap) {
|
|
1357
|
-
const errors = [];
|
|
1358
|
-
const vaultCap = capMap.get('vault');
|
|
1359
|
-
const modeDecl = vaultCap && vaultCap.config && typeof vaultCap.config === 'object'
|
|
1360
|
-
? vaultCap.config['vault.mode']
|
|
1361
|
-
: undefined;
|
|
1362
|
-
const allowed = modeDecl && Array.isArray(modeDecl.values)
|
|
1363
|
-
? modeDecl.values.filter((v) => typeof v === 'string')
|
|
1364
|
-
: null;
|
|
1365
|
-
const KINDS = [['steps', 'step'], ['contributions', 'contribution'], ['gates', 'gate']];
|
|
1366
|
-
for (const [capId, cap] of capMap) {
|
|
1367
|
-
if (!cap || typeof cap !== 'object') continue;
|
|
1368
|
-
const prefix = 'capability "' + capId + '"';
|
|
1369
|
-
const requiresVault = Array.isArray(cap.requires) && cap.requires.includes('vault');
|
|
1370
|
-
for (const [arrKey, kind] of KINDS) {
|
|
1371
|
-
const arr = Array.isArray(cap[arrKey]) ? cap[arrKey] : [];
|
|
1372
|
-
for (const hook of arr) {
|
|
1373
|
-
if (!hook || typeof hook !== 'object') continue;
|
|
1374
|
-
if (!Object.prototype.hasOwnProperty.call(hook, 'vaultMode')) continue;
|
|
1375
|
-
const where = prefix + ' ' + kind + ' at point "' + String(hook.point) + '"';
|
|
1376
|
-
const value = hook.vaultMode;
|
|
1377
|
-
if (kind === 'step') {
|
|
1378
|
-
errors.push(where + ': vaultMode is allowed on contributions and gates only');
|
|
1379
|
-
}
|
|
1380
|
-
if (allowed === null) {
|
|
1381
|
-
errors.push(
|
|
1382
|
-
where + ': vaultMode ' + JSON.stringify(value) + ' cannot be checked: the vault capability ' +
|
|
1383
|
-
'declares no "vault.mode" values, which own the closed set',
|
|
1384
|
-
);
|
|
1385
|
-
} else if (typeof value !== 'string' || !allowed.includes(value)) {
|
|
1386
|
-
errors.push(
|
|
1387
|
-
where + ': vaultMode ' + JSON.stringify(value) + ' is not one of [' + allowed.join(', ') +
|
|
1388
|
-
'] (the closed set owned by the vault capability\'s "vault.mode" values)',
|
|
1389
|
-
);
|
|
1390
|
-
}
|
|
1391
|
-
if (capId !== 'vault' && !requiresVault) {
|
|
1392
|
-
errors.push(
|
|
1393
|
-
where + ': vaultMode is allowed only on the "vault" capability or a capability that ' +
|
|
1394
|
-
'lists "vault" in requires',
|
|
1395
|
-
);
|
|
1396
|
-
}
|
|
1397
|
-
}
|
|
1398
|
-
}
|
|
1399
|
-
}
|
|
1400
|
-
return errors;
|
|
1401
|
-
}
|
|
1402
|
-
|
|
1403
1333
|
/**
|
|
1404
1334
|
* Quick 261015-ect (QD-13): the vault-family rule for `requiresPlatformBindings`,
|
|
1405
|
-
*
|
|
1335
|
+
* A capability that is `vault` or
|
|
1406
1336
|
* lists `vault` in `requires` MUST declare the field, so a vault-family
|
|
1407
1337
|
* capability added later cannot render hooks on a project the vault does not
|
|
1408
1338
|
* govern by forgetting it. A capability outside the family may declare it too.
|
|
@@ -1441,18 +1371,15 @@ const SEAL_FIELD_NAME = 'onRecordedArtifacts';
|
|
|
1441
1371
|
* A gate carrying the field renders for an enabled, config-inactive capability
|
|
1442
1372
|
* over recorded vault artifacts, bypassing the capability's active check and
|
|
1443
1373
|
* its `when` (D-18). That is a widening of render behaviour, so the field is
|
|
1444
|
-
* closed HERE, at generation, to exactly the shape the
|
|
1445
|
-
*
|
|
1374
|
+
* closed HERE, at generation, to exactly the shape the shipped seal gate has.
|
|
1375
|
+
* Five rules, each reported on its own:
|
|
1446
1376
|
* (a) gates only (a step or contribution carrying it is refused);
|
|
1447
1377
|
* (b) the value is literal `true` (`"true"`, `1`, `null`, `false` refused);
|
|
1448
|
-
* (c) the declaring capability
|
|
1449
|
-
*
|
|
1450
|
-
*
|
|
1451
|
-
*
|
|
1452
|
-
* (
|
|
1453
|
-
* the predicate, research C-1);
|
|
1454
|
-
* (e) the gate is `blocking: true`;
|
|
1455
|
-
* (f) the point is `ship:pre` (D-21: the requirement's block point; a seal at
|
|
1378
|
+
* (c) the declaring capability is `vault` or lists `vault` in `requires`.
|
|
1379
|
+
* A seal gate never dispatches twice: the resolver drops it whenever its
|
|
1380
|
+
* capability is active, so it renders only with the vault switched off;
|
|
1381
|
+
* (d) the gate is `blocking: true`;
|
|
1382
|
+
* (e) the point is `ship:pre` (D-21: the requirement's block point; a seal at
|
|
1456
1383
|
* verify:post would halt execute-phase on a switch set on purpose).
|
|
1457
1384
|
*
|
|
1458
1385
|
* Presence is own-property presence.
|
|
@@ -1481,15 +1408,12 @@ function validateSealField(capMap) {
|
|
|
1481
1408
|
if (value !== true) {
|
|
1482
1409
|
errors.push(where + ': ' + SEAL_FIELD_NAME + ' must be literal true (got ' + JSON.stringify(value) + ')');
|
|
1483
1410
|
}
|
|
1484
|
-
if (capId
|
|
1411
|
+
if (capId !== 'vault' && !requiresVault) {
|
|
1485
1412
|
errors.push(
|
|
1486
|
-
where + ': ' + SEAL_FIELD_NAME + ' is allowed only on
|
|
1487
|
-
'
|
|
1413
|
+
where + ': ' + SEAL_FIELD_NAME + ' is allowed only on the "vault" capability or a capability that ' +
|
|
1414
|
+
'lists "vault" in requires',
|
|
1488
1415
|
);
|
|
1489
1416
|
}
|
|
1490
|
-
if (!Object.prototype.hasOwnProperty.call(hook, 'vaultMode')) {
|
|
1491
|
-
errors.push(where + ': a gate carrying ' + SEAL_FIELD_NAME + ' must also carry vaultMode');
|
|
1492
|
-
}
|
|
1493
1417
|
if (hook.blocking !== true) {
|
|
1494
1418
|
errors.push(where + ': a gate carrying ' + SEAL_FIELD_NAME + ' must be blocking: true');
|
|
1495
1419
|
}
|
|
@@ -1662,10 +1586,6 @@ const TIER_RANK = { core: 0, standard: 1, full: 2 };
|
|
|
1662
1586
|
function validateCrossCapability(capMap, centralKeys) {
|
|
1663
1587
|
const errors = [];
|
|
1664
1588
|
|
|
1665
|
-
// Phase 15 D-02: the per-hook vaultMode filter field (needs capMap to read the
|
|
1666
|
-
// vault capability's closed value set and every capability's `requires`).
|
|
1667
|
-
errors.push(...validateVaultModeField(capMap));
|
|
1668
|
-
|
|
1669
1589
|
// Phase 16 D-19: the per-hook seal field (needs capMap for every capability's
|
|
1670
1590
|
// `requires`).
|
|
1671
1591
|
errors.push(...validateSealField(capMap));
|
|
@@ -2841,7 +2761,6 @@ module.exports = {
|
|
|
2841
2761
|
validateAgainstContract,
|
|
2842
2762
|
validateConsumesGlobal,
|
|
2843
2763
|
validateCrossCapability,
|
|
2844
|
-
validateVaultModeField,
|
|
2845
2764
|
validateSealField,
|
|
2846
2765
|
validatePlatformBindingsField,
|
|
2847
2766
|
SEAL_FIELD_NAME,
|
|
@@ -114,14 +114,6 @@
|
|
|
114
114
|
],
|
|
115
115
|
"issue": "180"
|
|
116
116
|
},
|
|
117
|
-
"vault-review": {
|
|
118
|
-
"files": [
|
|
119
|
-
"vault-review.integration.test.cjs",
|
|
120
|
-
"vault-review.security.test.cjs",
|
|
121
|
-
"vault-review.test.cjs"
|
|
122
|
-
],
|
|
123
|
-
"issue": "71924 — Vault Assurance phase 06 (06-03/06-04), three distinct concerns for pp-core/bin/lib/vault-review.cjs: vault-review.test (06-03 unit tests over every pure derivation — the verdict vocabularies, both derived-N-A arms, the counts arithmetic, the range resolver and the clean-render refusal predicate), vault-review.integration.test (06-04 SEAM tests — the deterministic validator of the agent-written artifact, plus the `check vault-review` arm driven through the real pp-core/bin/pp-tools.cjs, where the exit-0/no-block-key contract of D-06-01 and VERIFY-03 is proved at the boundary a gate enforcer actually reads, with RED control 2 proving that guard non-vacuous), and vault-review.security.test (06-04 ADVERSARIAL tests — a spoofed external-content fence-end marker, directive-shaped text and a forged tool-call block planted in real practice BODIES, proving 05-REVIEW's open Critical CR-02 is not repeated on this surface, plus the CR-03 class: no absolute filesystem path in any emitted byte). The split mirrors the `vault` cluster's own reasoning: the unit lane, the CLI seam and the security marker are independently load-bearing verification gates, and the `.security.test.cjs` marker is what makes the adversarial lane identifiable to a reader and to scripts/run-tests.cjs. Consolidating would blur three different questions into one file."
|
|
124
|
-
},
|
|
125
117
|
"verify": {
|
|
126
118
|
"files": [
|
|
127
119
|
"bug-2969-verify-reapply-patches.test.cjs",
|
|
@@ -189,22 +181,12 @@
|
|
|
189
181
|
"files": [
|
|
190
182
|
"feat-71924-vault-required-gate.test.cjs",
|
|
191
183
|
"vault-doors.integration.test.cjs",
|
|
192
|
-
"vault-practices.property.test.cjs",
|
|
193
184
|
"vault-read-path.test.cjs",
|
|
194
185
|
"vault-security.test.cjs",
|
|
195
186
|
"vault-status-check.test.cjs",
|
|
196
187
|
"vault.test.cjs"
|
|
197
188
|
],
|
|
198
|
-
"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).
|
|
199
|
-
},
|
|
200
|
-
"vault-practices": {
|
|
201
|
-
"files": [
|
|
202
|
-
"vault-practices-examples.test.cjs",
|
|
203
|
-
"vault-practices-matcher.test.cjs",
|
|
204
|
-
"vault-practices.slow.test.cjs",
|
|
205
|
-
"vault-practices.test.cjs"
|
|
206
|
-
],
|
|
207
|
-
"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. Vault Assurance phase 05 (#71924) added vault-practices.slow.test.cjs — the >5 s six-axis worst-case matcher corpus for the same production module (pp-core/bin/lib/vault-practices.cjs), split out per the .slow suffix convention so the default suite stays fast; attributed here once the count lint learned to strip the .slow suffix."
|
|
189
|
+
"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). Vault Assurance phase 02 (#71924) added feat-71924-vault-required-gate.test.cjs as the phase's ONE consolidated source-grep feature file — it owns the source-text assertions for GATE-02, GATE-03, GATE-06, GATE-08, GATE-09 and GATE-10 together, deliberately in a single file so the phase's six requirements do not each spawn a sibling; later plans in the phase extend it rather than adding files. Vault Assurance phase 16 plan 10 added vault-doors.integration.test.cjs as the phase's ONE door fence-proof owner (DOOR-01..05, D-09): every door's shipped fence (execute-plan, quick, fast, debug, the secondary doors) composed by tests/helpers/gate-fence-composer.cjs and run in bash and zsh, one describe per door plan, so 16-12..16-15 extend it rather than each adding a sibling. The hyphen-prefix matcher attributes it here because no vault-doors module exists; it tests workflow fences, not vault.cjs."
|
|
208
190
|
}
|
|
209
191
|
}
|
|
210
192
|
}
|
|
@@ -80,12 +80,11 @@ function prodPrefix(filename) {
|
|
|
80
80
|
// stamps. Five forms are stripped: `.integration`, `.slow`, `.security`,
|
|
81
81
|
// `.install` and the bare `.test`.
|
|
82
82
|
//
|
|
83
|
-
// `.property` is DELIBERATELY NOT stripped
|
|
84
|
-
//
|
|
85
|
-
//
|
|
86
|
-
//
|
|
87
|
-
//
|
|
88
|
-
// statement. Changing it is a deliberate allowlist migration, not a tidy-up.
|
|
83
|
+
// `.property` is DELIBERATELY NOT stripped: a `<name>.property.test.cjs` keeps
|
|
84
|
+
// the suffix in its prefix, so the hyphen-prefix matcher clusters it under the
|
|
85
|
+
// shortest matching module rather than under `<name>`. Stripping it would
|
|
86
|
+
// re-cluster every property test the allowlist has already counted. Changing
|
|
87
|
+
// it is a deliberate allowlist migration, not a tidy-up.
|
|
89
88
|
function testEffectivePrefix(testName) {
|
|
90
89
|
const bare = testName
|
|
91
90
|
.replace(/\.(integration|slow|security|install)\.test\.(ts|cjs)$/, '')
|
|
@@ -95,9 +95,6 @@ ALLOWLIST=(
|
|
|
95
95
|
'tests/fixtures/adversarial/security/::a directory of adversarial corpus files whose entire purpose is to BE injection payloads for the suites above; measured 20 pattern hits across its 7 tracked files at HEAD on 2026-09-19'
|
|
96
96
|
'tests/discovery-vault-context.test.cjs::the DISCO-03/SC4 suite plants a real role-manipulation line (the PLANTED constant) into a fixture vault document and asserts the shipped scanner FINDS it, which is the non-vacuity partner for the assertion that the subflow itself scans clean; the payload has to be a literal for that half to mean anything, so the file matches the vocabulary it exists to prove is caught'
|
|
97
97
|
'tests/vault-status-check.test.cjs::sanitisation seeds for the vault status message carry a real instruction and a real control character on purpose, each paired with a non-vacuity assertion that the RENDERED message does not carry it intact; measured 5 pattern hits at HEAD on 2026-09-19'
|
|
98
|
-
'tests/vault-practices-matcher.test.cjs::the CR-01 fence-spoof suite plants a real instruction-override line and a forged end-fence marker inside practice bodies on purpose, each paired with an assertion that the RENDERED practices block keeps the planted text inside the fence and leaves exactly one genuine closer, so the payload must be a literal for the defang proof to mean anything; measured 3 pattern hits at HEAD b4dd6b3 on 2026-10-04'
|
|
99
|
-
'tests/vault-review.security.test.cjs::the CR-02 suite 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 b4dd6b3 on 2026-10-04'
|
|
100
|
-
'tests/practices-review-check-property.test.cjs::a false positive rather than a payload, since the fence-parsing invariance property builds a never-closed fence whose second-opener line is ordinary English about whether the client line becomes a cut point, and one role-pattern regex matches that plain wording; the fixture text stays as written; measured 1 pattern hit at HEAD b4dd6b3 on 2026-10-04'
|
|
101
98
|
'tests/vault-index.integration.test.cjs::the fence-spoof suite seeds a vault document heading and an INDEX description that carry a forged end-fence marker followed by an instruction-override phrase, and asserts the rendered SUMMARY keeps exactly one live end marker with the planted line defanged inside the fence, so the phrase must be a literal for the defang proof to mean anything; measured 4 pattern hits at HEAD 5ddb0b3 on 2026-10-12'
|
|
102
99
|
'tests/vault-seal.integration.test.cjs::the uncovered-commit suite builds a commit whose subject is an instruction-override phrase padded past the cap, modelling a hostile commit message, and asserts the subject leaving the seal leaf is controls-collapsed and bounded to SEAL_SUBJECT_CAP before it can reach a record; measured 1 pattern hit at HEAD 5ddb0b3 on 2026-10-12'
|
|
103
100
|
'tests/vault-standards.integration.test.cjs::the D-14 suites plant instruction-override lines in a standards document and in its INDEX description, each tagged with a random token, and assert that neither the token nor the phrase appears in any output of vault standards block or consulted, so the phrase must be a literal for the absence proof to mean anything; measured 6 pattern hits at HEAD 5ddb0b3 on 2026-10-12'
|