@pareto4/pp-core 1.11.1 → 1.12.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.
Files changed (255) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/README.md +31 -0
  3. package/agents/pp-code-fixer.md +1 -1
  4. package/agents/pp-debug-session-manager.md +1 -1
  5. package/agents/pp-debugger.md +1 -1
  6. package/agents/pp-executor.md +20 -10
  7. package/agents/pp-intel-updater.md +1 -1
  8. package/agents/pp-phase-researcher.md +1 -1
  9. package/agents/pp-plan-checker.md +5 -5
  10. package/agents/pp-planner.md +10 -24
  11. package/agents/pp-project-researcher.md +1 -1
  12. package/agents/pp-research-synthesizer.md +1 -1
  13. package/agents/pp-ui-researcher.md +1 -1
  14. package/agents/pp-verifier.md +8 -4
  15. package/bin/install.js +429 -82
  16. package/commands/pp-autonomous.md +8 -6
  17. package/commands/pp-discovery-to-build.md +1 -1
  18. package/commands/pp-discovery.md +3 -2
  19. package/commands/pp-discuss-phase.md +2 -2
  20. package/commands/pp-execute-phase.md +3 -1
  21. package/commands/pp-graphify.md +5 -5
  22. package/commands/pp-import.md +1 -1
  23. package/commands/pp-map-codebase.md +1 -1
  24. package/commands/pp-ns-project.md +2 -3
  25. package/commands/pp-ns-workflow.md +1 -1
  26. package/commands/pp-plan-phase.md +2 -1
  27. package/commands/pp-verify-work.md +2 -1
  28. package/gemini-extension.json +1 -1
  29. package/hooks/dist/pp-cursor-session-start.js +2 -2
  30. package/hooks/dist/pp-session-state.sh +1 -1
  31. package/hooks/dist/pp-statusline.js +21 -2
  32. package/hooks/pp-cursor-session-start.js +2 -2
  33. package/hooks/pp-session-state.sh +1 -1
  34. package/hooks/pp-statusline.js +21 -2
  35. package/package.json +18 -5
  36. package/pareto-skills/pp-project-setup/SKILL.md +5 -63
  37. package/pp-core/bin/detect-build-commands.sh +182 -0
  38. package/pp-core/bin/lib/capability-registry.cjs +65 -7
  39. package/pp-core/bin/lib/check-command-router.cjs +79 -38
  40. package/pp-core/bin/lib/clusters.cjs +2 -3
  41. package/pp-core/bin/lib/command-aliases.cjs +36 -0
  42. package/pp-core/bin/lib/command-arg-projection.cjs +99 -1
  43. package/pp-core/bin/lib/commands.cjs +21 -6
  44. package/pp-core/bin/lib/compose-bindings.cjs +70 -6
  45. package/pp-core/bin/lib/config-schema.cjs +16 -0
  46. package/pp-core/bin/lib/config.cjs +142 -27
  47. package/pp-core/bin/lib/core-utils.cjs +43 -7
  48. package/pp-core/bin/lib/discovery-input-check.cjs +218 -0
  49. package/pp-core/bin/lib/discovery-rebaseline.cjs +1372 -0
  50. package/pp-core/bin/lib/discovery-research-track.cjs +979 -0
  51. package/pp-core/bin/lib/discovery-rollup.cjs +476 -0
  52. package/pp-core/bin/lib/discovery-screens.cjs +1995 -0
  53. package/pp-core/bin/lib/discovery-sweep.cjs +390 -0
  54. package/pp-core/bin/lib/discovery-table.cjs +98 -0
  55. package/pp-core/bin/lib/dispatch-plan.cjs +472 -0
  56. package/pp-core/bin/lib/frontmatter.cjs +17 -2
  57. package/pp-core/bin/lib/init-command-router.cjs +8 -5
  58. package/pp-core/bin/lib/init-contract.cjs +93 -4
  59. package/pp-core/bin/lib/init.cjs +124 -134
  60. package/pp-core/bin/lib/install-profiles.cjs +5 -0
  61. package/pp-core/bin/lib/install-run.cjs +536 -0
  62. package/pp-core/bin/lib/io.cjs +15 -0
  63. package/pp-core/bin/lib/loop-resolver.cjs +24 -0
  64. package/pp-core/bin/lib/milestone.cjs +345 -48
  65. package/pp-core/bin/lib/phase-command-router.cjs +23 -1
  66. package/pp-core/bin/lib/phase-locator.cjs +15 -6
  67. package/pp-core/bin/lib/phase-scope.cjs +91 -0
  68. package/pp-core/bin/lib/phase-tier.cjs +467 -0
  69. package/pp-core/bin/lib/phase.cjs +247 -21
  70. package/pp-core/bin/lib/phases-command-router.cjs +2 -0
  71. package/pp-core/bin/lib/plan-graph.cjs +368 -0
  72. package/pp-core/bin/lib/planning-workspace.cjs +53 -0
  73. package/pp-core/bin/lib/platform-bindings.cjs +32 -2
  74. package/pp-core/bin/lib/profile-output.cjs +11 -3
  75. package/pp-core/bin/lib/prohibition-enforcement.cjs +112 -0
  76. package/pp-core/bin/lib/roadmap-parser.cjs +366 -99
  77. package/pp-core/bin/lib/roadmap.cjs +141 -39
  78. package/pp-core/bin/lib/runtime-hooks-surface.cjs +1 -1
  79. package/pp-core/bin/lib/shell-command-projection.cjs +24 -0
  80. package/pp-core/bin/lib/state-command-router.cjs +82 -13
  81. package/pp-core/bin/lib/state-document.cjs +124 -7
  82. package/pp-core/bin/lib/state.cjs +784 -257
  83. package/pp-core/bin/lib/template.cjs +22 -6
  84. package/pp-core/bin/lib/vault-command-router.cjs +57 -6
  85. package/pp-core/bin/lib/vault-practices.cjs +6 -36
  86. package/pp-core/bin/lib/vault-write-back.cjs +20 -4
  87. package/pp-core/bin/lib/vault.cjs +555 -23
  88. package/pp-core/bin/lib/verify.cjs +53 -31
  89. package/pp-core/bin/lib/workstream.cjs +1 -1
  90. package/pp-core/bin/lib/worktree-safety.cjs +26 -15
  91. package/pp-core/bin/portable-timeout.sh +89 -0
  92. package/pp-core/bin/pp-tools.cjs +149 -9
  93. package/pp-core/bin/shared/config-defaults.manifest.json +7 -0
  94. package/pp-core/bin/shared/config-schema.manifest.json +3 -0
  95. package/pp-core/references/autonomous-best-effort.md +461 -0
  96. package/pp-core/references/autonomous-lifecycle.md +146 -0
  97. package/pp-core/references/autonomous-smart-discuss.md +16 -12
  98. package/pp-core/references/checkpoints.md +1 -1
  99. package/pp-core/references/discovery-id-conventions.md +202 -0
  100. package/pp-core/references/discovery-rebaseline.md +254 -0
  101. package/pp-core/references/discovery-research-track.md +283 -0
  102. package/pp-core/references/discovery-traceability.md +400 -0
  103. package/pp-core/references/loop-hook-dispatch.md +7 -0
  104. package/pp-core/references/mandatory-initial-read.md +1 -1
  105. package/pp-core/references/planner-gap-closure.md +1 -0
  106. package/pp-core/references/planner-human-verify-mode.md +1 -1
  107. package/pp-core/references/planner-load-graph-context.md +1 -1
  108. package/pp-core/references/planner-plan-graph.md +66 -0
  109. package/pp-core/references/planner-tdd.md +1 -0
  110. package/pp-core/references/planning-config.md +8 -0
  111. package/pp-core/references/sketch-tooling.md +4 -0
  112. package/pp-core/references/tdd.md +1 -0
  113. package/pp-core/templates/claude-md.md +1 -1
  114. package/pp-core/templates/phase-prompt.md +6 -2
  115. package/pp-core/templates/prototype-review/review.js +303 -0
  116. package/pp-core/templates/state.md +6 -0
  117. package/pp-core/workflows/_runtime-launcher.snippet.sh +1 -1
  118. package/pp-core/workflows/add-backlog.md +1 -1
  119. package/pp-core/workflows/add-phase.md +1 -1
  120. package/pp-core/workflows/add-tests.md +1 -1
  121. package/pp-core/workflows/add-todo.md +1 -1
  122. package/pp-core/workflows/ai-integration-phase.md +2 -2
  123. package/pp-core/workflows/audit-fix.md +12 -16
  124. package/pp-core/workflows/audit-milestone.md +1 -1
  125. package/pp-core/workflows/audit-uat.md +1 -1
  126. package/pp-core/workflows/autonomous.md +68 -306
  127. package/pp-core/workflows/check-todos.md +1 -1
  128. package/pp-core/workflows/cleanup.md +1 -1
  129. package/pp-core/workflows/code-review-fix.md +1 -1
  130. package/pp-core/workflows/code-review.md +19 -7
  131. package/pp-core/workflows/complete-milestone.md +41 -60
  132. package/pp-core/workflows/debug.md +1 -1
  133. package/pp-core/workflows/diagnose-issues.md +1 -1
  134. package/pp-core/workflows/discovery-sprint/gap-analysis.md +140 -0
  135. package/pp-core/workflows/discovery-sprint/input-package.md +140 -0
  136. package/pp-core/workflows/discovery-sprint/prefill.md +92 -0
  137. package/pp-core/workflows/discovery-sprint/prototype.md +257 -0
  138. package/pp-core/workflows/discovery-sprint/rebaseline.md +276 -0
  139. package/pp-core/workflows/discovery-sprint/session-13-gates.md +24 -0
  140. package/pp-core/workflows/discovery-sprint/sessions/01-kick-off.md +92 -0
  141. package/pp-core/workflows/discovery-sprint/sessions/02-as-is.md +98 -0
  142. package/pp-core/workflows/discovery-sprint/sessions/03-to-be.md +215 -0
  143. package/pp-core/workflows/discovery-sprint/sessions/04-ux-design.md +146 -0
  144. package/pp-core/workflows/discovery-sprint/sessions/05-architecture.md +98 -0
  145. package/pp-core/workflows/discovery-sprint/sessions/06-security.md +107 -0
  146. package/pp-core/workflows/discovery-sprint/sessions/07-identity.md +98 -0
  147. package/pp-core/workflows/discovery-sprint/sessions/08-integration.md +85 -0
  148. package/pp-core/workflows/discovery-sprint/sessions/09-qa.md +109 -0
  149. package/pp-core/workflows/discovery-sprint/sessions/10-infrastructure.md +119 -0
  150. package/pp-core/workflows/discovery-sprint/sessions/11-roadmap.md +92 -0
  151. package/pp-core/workflows/discovery-sprint/sessions/12-delivery-model.md +98 -0
  152. package/pp-core/workflows/discovery-sprint/sessions/13-wrap-up.md +205 -0
  153. package/pp-core/workflows/discovery-sprint/templates/context-template.md +266 -0
  154. package/pp-core/workflows/discovery-sprint.md +79 -1714
  155. package/pp-core/workflows/discovery-to-build/steps/architecture-deliverables.md +5 -5
  156. package/pp-core/workflows/discovery-to-build/steps/screen-inventory-gate.md +70 -0
  157. package/pp-core/workflows/discovery-to-build/templates/discovery-references.md +54 -0
  158. package/pp-core/workflows/discovery-to-build/templates/pp-handoff.md +184 -0
  159. package/pp-core/workflows/discovery-to-build.md +21 -238
  160. package/pp-core/workflows/discuss-phase/modes/advisor.md +1 -1
  161. package/pp-core/workflows/discuss-phase/modes/auto.md +1 -1
  162. package/pp-core/workflows/discuss-phase/modes/chain.md +1 -1
  163. package/pp-core/workflows/discuss-phase-assumptions.md +1 -1
  164. package/pp-core/workflows/discuss-phase.md +9 -2
  165. package/pp-core/workflows/do.md +4 -4
  166. package/pp-core/workflows/docs-update.md +1 -1
  167. package/pp-core/workflows/edit-phase.md +1 -1
  168. package/pp-core/workflows/eval-review.md +1 -1
  169. package/pp-core/workflows/execute-phase/steps/checkpoint-handling.md +45 -0
  170. package/pp-core/workflows/execute-phase/steps/client-context-gate.md +1 -1
  171. package/pp-core/workflows/execute-phase/steps/codebase-drift-gate.md +1 -1
  172. package/pp-core/workflows/execute-phase/steps/cross-ai-delegation.md +90 -0
  173. package/pp-core/workflows/execute-phase/steps/install-run.md +29 -0
  174. package/pp-core/workflows/execute-phase/steps/phase-close-rebaseline.md +23 -0
  175. package/pp-core/workflows/execute-phase/steps/post-merge-gate.md +76 -77
  176. package/pp-core/workflows/execute-phase/steps/serial-group-dispatch.md +72 -0
  177. package/pp-core/workflows/execute-phase/steps/vault-fetch.md +5 -5
  178. package/pp-core/workflows/execute-phase/steps/vault-load-gate.md +19 -112
  179. package/pp-core/workflows/execute-phase.md +102 -216
  180. package/pp-core/workflows/execute-plan.md +6 -2
  181. package/pp-core/workflows/explore.md +1 -1
  182. package/pp-core/workflows/extract-learnings.md +1 -1
  183. package/pp-core/workflows/forensics.md +4 -4
  184. package/pp-core/workflows/graduation.md +1 -1
  185. package/pp-core/workflows/health.md +1 -1
  186. package/pp-core/workflows/help/modes/brief.md +1 -0
  187. package/pp-core/workflows/help/modes/default.md +2 -1
  188. package/pp-core/workflows/help/modes/full.md +12 -5
  189. package/pp-core/workflows/import.md +1 -1
  190. package/pp-core/workflows/ingest-docs.md +1 -1
  191. package/pp-core/workflows/init.md +18 -2
  192. package/pp-core/workflows/insert-phase.md +1 -1
  193. package/pp-core/workflows/list-workspaces.md +1 -1
  194. package/pp-core/workflows/manager.md +3 -3
  195. package/pp-core/workflows/map-codebase.md +2 -2
  196. package/pp-core/workflows/milestone-summary.md +4 -4
  197. package/pp-core/workflows/mvp-phase.md +1 -1
  198. package/pp-core/workflows/new-milestone.md +7 -8
  199. package/pp-core/workflows/new-project.md +6 -1
  200. package/pp-core/workflows/new-workspace.md +1 -1
  201. package/pp-core/workflows/next.md +2 -2
  202. package/pp-core/workflows/note.md +2 -2
  203. package/pp-core/workflows/pause-work.md +1 -1
  204. package/pp-core/workflows/plan-milestone-gaps.md +1 -1
  205. package/pp-core/workflows/plan-phase/steps/chunked-planning.md +111 -0
  206. package/pp-core/workflows/plan-phase/steps/phase-tier.md +34 -0
  207. package/pp-core/workflows/plan-phase.md +43 -167
  208. package/pp-core/workflows/plan-review-convergence.md +2 -2
  209. package/pp-core/workflows/plant-seed.md +1 -1
  210. package/pp-core/workflows/pr-branch.md +1 -1
  211. package/pp-core/workflows/profile-user.md +1 -1
  212. package/pp-core/workflows/progress.md +3 -3
  213. package/pp-core/workflows/quick.md +3 -1
  214. package/pp-core/workflows/remove-phase.md +1 -1
  215. package/pp-core/workflows/remove-workspace.md +1 -1
  216. package/pp-core/workflows/resume-project.md +6 -12
  217. package/pp-core/workflows/review.md +1 -1
  218. package/pp-core/workflows/scan.md +1 -1
  219. package/pp-core/workflows/secure-phase.md +1 -1
  220. package/pp-core/workflows/settings-advanced.md +1 -1
  221. package/pp-core/workflows/settings-integrations.md +1 -1
  222. package/pp-core/workflows/settings.md +1 -1
  223. package/pp-core/workflows/ship.md +25 -8
  224. package/pp-core/workflows/sketch-wrap-up.md +1 -1
  225. package/pp-core/workflows/sketch.md +2 -1
  226. package/pp-core/workflows/spec-phase.md +1 -1
  227. package/pp-core/workflows/spike-wrap-up.md +1 -1
  228. package/pp-core/workflows/spike.md +1 -1
  229. package/pp-core/workflows/stats.md +2 -2
  230. package/pp-core/workflows/thread.md +1 -1
  231. package/pp-core/workflows/transition.md +5 -9
  232. package/pp-core/workflows/ui-phase.md +23 -2
  233. package/pp-core/workflows/ui-review.md +1 -1
  234. package/pp-core/workflows/ultraplan-phase.md +2 -2
  235. package/pp-core/workflows/validate-phase.md +1 -1
  236. package/pp-core/workflows/vault-write-back.md +1 -1
  237. package/pp-core/workflows/verify-phase.md +29 -26
  238. package/pp-core/workflows/verify-work.md +14 -10
  239. package/scripts/base64-scan.sh +7 -41
  240. package/scripts/changeset/cli.cjs +25 -5
  241. package/scripts/dev-env.cjs +462 -0
  242. package/scripts/lib/allowlist-ratchet.cjs +103 -1
  243. package/scripts/lib/size-budget.cjs +311 -0
  244. package/scripts/lint-neutrality-names.cjs +694 -0
  245. package/scripts/lint-org-coordinates.allowlist.json +35 -0
  246. package/scripts/lint-org-coordinates.cjs +426 -0
  247. package/scripts/lint-skill-deps.cjs +48 -9
  248. package/scripts/lint-test-file-count.cjs +17 -2
  249. package/scripts/prompt-injection-scan.sh +41 -20
  250. package/scripts/sync-manifest-versions.cjs +41 -7
  251. package/scripts/sync-runtime-launcher.cjs +106 -1
  252. package/scripts/update-size-baseline.cjs +274 -30
  253. package/scripts/workflow-size.cjs +61 -9
  254. package/commands/pp-build-handoff.md +0 -46
  255. package/pp-core/workflows/execute-phase/steps/per-plan-worktree-gate.md +0 -94
@@ -21,12 +21,12 @@ const { toPosixPath, generateSlugInternal } = coreUtilsMod;
21
21
  const phaseIdMod = require("./phase-id.cjs");
22
22
  const { normalizePhaseName } = phaseIdMod;
23
23
  // eslint-disable-next-line @typescript-eslint/no-require-imports
24
- const phaseLocatorMod = require("./phase-locator.cjs");
25
- const { findPhaseInternal } = phaseLocatorMod;
24
+ const phaseScopeMod = require("./phase-scope.cjs");
25
+ const { resolvePhaseForWrite } = phaseScopeMod;
26
26
  const shell_command_projection_cjs_1 = require("./shell-command-projection.cjs");
27
27
  // eslint-disable-next-line @typescript-eslint/no-require-imports
28
28
  const planningWorkspace = require("./planning-workspace.cjs");
29
- const { planningDir } = planningWorkspace;
29
+ const { planningDir, resolveProjectFile } = planningWorkspace;
30
30
  // eslint-disable-next-line @typescript-eslint/no-require-imports
31
31
  const frontmatter = require("./frontmatter.cjs");
32
32
  const { reconstructFrontmatter } = frontmatter;
@@ -79,8 +79,23 @@ function cmdTemplateFill(cwd, templateType, options, raw) {
79
79
  if (!options.phase) {
80
80
  error('--phase required');
81
81
  }
82
- const phaseInfo = findPhaseInternal(cwd, options.phase);
83
- if (!phaseInfo || !phaseInfo.found) {
82
+ // D-02 (todo "template-fill-writes-into-an-archived-
83
+ // phase-directory"): a writer never resolves into a closed milestone's archive. The
84
+ // phase-scope owner hands back a live match only; an archive this phase still names
85
+ // (current milestone, or no longer on the ROADMAP) is refused naming the archive, and a
86
+ // prior milestone's archive whose number the current ROADMAP reuses takes the not-found
87
+ // line below, as the init verbs already answer.
88
+ const verdict = resolvePhaseForWrite(cwd, options.phase);
89
+ if (!verdict.ok && verdict.reason === 'archived') {
90
+ output({ error: 'Phase archived', phase: options.phase, archived: verdict.version, directory: verdict.directory }, raw, undefined);
91
+ return;
92
+ }
93
+ if (!verdict.ok) {
94
+ output({ error: 'Phase not found', phase: options.phase }, raw, undefined);
95
+ return;
96
+ }
97
+ const phaseInfo = verdict.match;
98
+ if (!phaseInfo.found) {
84
99
  output({ error: 'Phase not found', phase: options.phase }, raw, undefined);
85
100
  return;
86
101
  }
@@ -156,7 +171,8 @@ function cmdTemplateFill(cwd, templateType, options, raw) {
156
171
  ...fields,
157
172
  };
158
173
  const planBase = planningDir(cwd);
159
- const projectRef = toPosixPath(node_path_1.default.relative(cwd, node_path_1.default.join(planBase, 'PROJECT.md')));
174
+ // D1 (261007-jkl): the context reference names the PROJECT.md that answers for this cwd.
175
+ const projectRef = toPosixPath(node_path_1.default.relative(cwd, resolveProjectFile(cwd).path));
160
176
  const roadmapRef = toPosixPath(node_path_1.default.relative(cwd, node_path_1.default.join(planBase, 'ROADMAP.md')));
161
177
  const stateRef = toPosixPath(node_path_1.default.relative(cwd, node_path_1.default.join(planBase, 'STATE.md')));
162
178
  body = [
@@ -33,6 +33,20 @@ const shell_command_projection_cjs_1 = require("./shell-command-projection.cjs")
33
33
  const { ERROR_REASON } = io;
34
34
  // Default CoreModule implementation. _core seam overrides this for test injection.
35
35
  const _defaultCore = { output: io.output };
36
+ /**
37
+ * Pack 6 D-01: the vault router's subcommand table. `readsVerdict` marks every
38
+ * subcommand that reports the vault load verdict — each one must spread the
39
+ * owner's `VAULT_VERDICT_FIELDS` verbatim (tests/vault-status-check.test.cjs
40
+ * enumerates this table and compares every reader against the owner).
41
+ */
42
+ const VAULT_SUBCOMMANDS = Object.freeze([
43
+ { name: 'fetch', readsVerdict: false },
44
+ { name: 'status', readsVerdict: true },
45
+ { name: 'summary', readsVerdict: false },
46
+ { name: 'practices', readsVerdict: false },
47
+ { name: 'org-profile', readsVerdict: false },
48
+ { name: 'probe', readsVerdict: false },
49
+ ]);
36
50
  /**
37
51
  * Render a short plain-text `vault org-profile` report from its structured
38
52
  * shape — one line naming the pointer, one naming the resolution, a
@@ -93,7 +107,24 @@ function routeVaultCommand({ args, cwd, raw, error, _vault, _core, _practices, _
93
107
  c.output(vault.vaultFetch(cwd), raw);
94
108
  }
95
109
  else if (subcommand === 'status') {
96
- c.output(vault.vaultStatus(cwd), raw);
110
+ // Pack 6 D-01: the manifest read is unchanged; the verdict fields come
111
+ // from the one owner, never from a second derivation here.
112
+ const status = vault.vaultStatus(cwd);
113
+ const verdict = vault.computeVaultVerdict && vault.verdictFields ? vault.verdictFields(vault.computeVaultVerdict(cwd)) : {};
114
+ c.output({ ...status, ...verdict }, raw);
115
+ }
116
+ else if (subcommand === 'probe') {
117
+ // Pack 6 D-09: one reachability line, empty when the vault is disabled (D-06).
118
+ const result = vault.vaultProbe ? vault.vaultProbe(cwd) : { line: '', enabled: false };
119
+ if (!result.enabled) {
120
+ c.output(result, true, '');
121
+ }
122
+ else if (raw) {
123
+ c.output(result, true, JSON.stringify(result));
124
+ }
125
+ else {
126
+ c.output(result, true, `${result.line}\n`);
127
+ }
97
128
  }
98
129
  else if (subcommand === 'summary') {
99
130
  c.output(vault.vaultSummary(cwd), raw);
@@ -257,6 +288,21 @@ function routeVaultCommand({ args, cwd, raw, error, _vault, _core, _practices, _
257
288
  overridden.push({ key, profile: profileValue, effective: effectiveValue });
258
289
  }
259
290
  }
291
+ // Pack 6 D-07: the drift comparison above ran on RAW values (two repos
292
+ // differing only by a credential still report drift); what is EMITTED is
293
+ // display-safe — the shared-repo coordinate through the owner, prose
294
+ // through the prose redactor.
295
+ const shownRepo = (key, v) => key === coordinates.SHARED_REPO_CONFIG_KEY && typeof v === 'string' && vault.redactCloneTarget
296
+ ? vault.redactCloneTarget(v)
297
+ : v;
298
+ const shownText = (t) => (vault.redactRemoteText ? vault.redactRemoteText(t) : t);
299
+ const shownContributes = {};
300
+ for (const key of Object.keys(resolution.contributes)) {
301
+ shownContributes[key] = shownRepo(key, resolution.contributes[key]) ?? '';
302
+ }
303
+ const shownEffective = {};
304
+ for (const key of Object.keys(effective))
305
+ shownEffective[key] = shownRepo(key, effective[key]);
260
306
  const report = {
261
307
  pointer: { key: orgProfile.ORG_PROFILE_CONFIG_KEY, value: resolution.configured },
262
308
  profile: {
@@ -266,12 +312,16 @@ function routeVaultCommand({ args, cwd, raw, error, _vault, _core, _practices, _
266
312
  source: resolution.source,
267
313
  dataPath: resolution.dataPath,
268
314
  },
269
- contributes: resolution.contributes,
270
- effective,
271
- overridden,
315
+ contributes: shownContributes,
316
+ effective: shownEffective,
317
+ overridden: overridden.map((o) => ({
318
+ key: o.key,
319
+ profile: shownRepo(o.key, o.profile) ?? '',
320
+ effective: shownRepo(o.key, o.effective),
321
+ })),
272
322
  ignored: resolution.ignored,
273
323
  rejected: resolution.rejected,
274
- warnings: resolution.warnings,
324
+ warnings: resolution.warnings.map(shownText),
275
325
  };
276
326
  // Never call error() for a project with no profile, and never exit
277
327
  // non-zero for a resolution failure — this is a diagnostic, not an
@@ -285,9 +335,10 @@ function routeVaultCommand({ args, cwd, raw, error, _vault, _core, _practices, _
285
335
  }
286
336
  }
287
337
  else {
288
- error('Unknown vault subcommand. Available: fetch, status, summary, practices, org-profile', ERROR_REASON.SDK_UNKNOWN_COMMAND);
338
+ error(`Unknown vault subcommand. Available: ${VAULT_SUBCOMMANDS.map((x) => x.name).join(', ')}`, ERROR_REASON.SDK_UNKNOWN_COMMAND);
289
339
  }
290
340
  }
291
341
  module.exports = {
292
342
  routeVaultCommand,
343
+ VAULT_SUBCOMMANDS,
293
344
  };
@@ -642,42 +642,12 @@ function discoverPracticeFiles(cwd) {
642
642
  }
643
643
  }
644
644
  // ─── Matching + report (PRAC-02 / PRAC-03 / COMM-01) ───────────────────────────
645
- // External-content fence markers (D-15 / T-24-05) — copied verbatim from
646
- // `vaultSummary`'s untrusted-reference preamble in src/vault.cts so every
647
- // consumer of a global practice's excerpt inherits the same fencing
648
- // discipline from day one, rather than retrofitting it in a later phase.
649
- const EXTERNAL_CONTENT_FENCE_START = '<!-- vault:external-content-start -->';
650
- const EXTERNAL_CONTENT_FENCE_END = '<!-- vault:external-content-end -->';
651
- // Zero-width space (U+200B) — invisible when rendered, but breaks an exact
652
- // string match against the literal fence marker (CR-01 / T-24-05). Used by
653
- // `defangFenceMarkers` to neutralize a spoofed marker planted inside untrusted
654
- // body text without visibly mangling the text for a human/agent reader.
655
- const ZERO_WIDTH_SPACE = '\u200B';
656
- /**
657
- * Neutralize any occurrence of the external-content fence marker strings
658
- * inside untrusted body text BEFORE it is wrapped between the real markers
659
- * (CR-01 / T-24-05 fence-spoof escape). Without this, a practice body
660
- * containing the literal end-fence marker (`<!-- vault:external-content-end
661
- * -->`) could make a downstream consumer that naively splits on the exact
662
- * marker treat the injected text as being OUTSIDE the untrusted-content
663
- * fence — the classic "premature fence close" prompt-injection escape.
664
- *
665
- * Replaces each literal marker occurrence with a defanged variant (a
666
- * zero-width space inserted immediately after the opening `<!--`) that is
667
- * visually indistinguishable but no longer matches the real marker string —
668
- * so only the two GENUINE markers `boundedFencedExcerpt` appends afterward
669
- * remain real fence boundaries.
670
- */
671
- function defangFenceMarkers(body) {
672
- let result = body;
673
- for (const marker of [EXTERNAL_CONTENT_FENCE_START, EXTERNAL_CONTENT_FENCE_END]) {
674
- if (result.includes(marker)) {
675
- const defanged = `${marker.slice(0, 4)}${ZERO_WIDTH_SPACE}${marker.slice(4)}`;
676
- result = result.split(marker).join(defanged);
677
- }
678
- }
679
- return result;
680
- }
645
+ // External-content fence (D-15 / T-24-05). Pack 6 D-08: the fence has ONE
646
+ // owner, src/vault.cts — the marker strings and `defangFenceMarkers` are
647
+ // imported from it rather than copied, so every path that hands vault text to
648
+ // an agent defangs every marker spelling (case, whitespace, HTML entities,
649
+ // compatibility forms, zero-width characters), not only the literal marker.
650
+ const { EXTERNAL_CONTENT_FENCE_START, EXTERNAL_CONTENT_FENCE_END, defangFenceMarkers } = vaultMod;
681
651
  /**
682
652
  * Read a BOUNDED prefix of a practice file's markdown BODY (frontmatter
683
653
  * stripped) and wrap it in the `vault:external-content` fence + untrusted-
@@ -440,7 +440,7 @@ function previewPromotion({ cwd, filePath, _exec, _vault, _practices }) {
440
440
  cloneDir,
441
441
  ], { timeout: 120_000 });
442
442
  if (cl.exitCode !== 0) {
443
- const cause = boundedToken((cl.stderr || '').split(/\r?\n/)[0] || 'unknown error');
443
+ const cause = shownCause(cl.stderr);
444
444
  return refusal(PROMOTE_GUARD.TRANSPORT, ERROR_REASON.VAULT_PROMOTE_TRANSPORT_FAILED, `This practice was not pushed: git could not reach the vault (${cause}). Check your access to the vault and run the promotion again.`);
445
445
  }
446
446
  // 3. Capture the baseline BEFORE writing — an id already present in the
@@ -558,7 +558,7 @@ function previewPromotion({ cwd, filePath, _exec, _vault, _practices }) {
558
558
  const expect = buildExpectToken(pre.raw, baseline);
559
559
  return {
560
560
  status: 'preview',
561
- repo: pre.repo,
561
+ repo: shownRepo(pre.repo),
562
562
  ref: pre.ref,
563
563
  destination: pre.destination,
564
564
  mode,
@@ -577,9 +577,25 @@ function previewPromotion({ cwd, filePath, _exec, _vault, _practices }) {
577
577
  }
578
578
  }
579
579
  // ─── Confirm (write half of the write path) ──────────────────────────────────────
580
+ /**
581
+ * Pack 6 D-07: the display-safe forms used in every verdict and refusal this
582
+ * module EMITS — the one owner in src/vault.cts, lazily required (the
583
+ * module's `_vault` seam stays the fetch seam; redaction is never mocked).
584
+ * Comparisons, the expect token and every git invocation keep the RAW values.
585
+ */
586
+ function shownRepo(repo) {
587
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
588
+ const v = require('./vault.cjs');
589
+ return v.redactCloneTarget(repo) ?? repo;
590
+ }
591
+ function shownCause(stderr) {
592
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
593
+ const v = require('./vault.cjs');
594
+ return boundedToken(v.redactRemoteText((stderr || '').split(/\r?\n/)[0] || 'unknown error'));
595
+ }
580
596
  /** Build a TRANSPORT refusal from a failed git invocation's stderr (first line only). */
581
597
  function transportRefusal(res) {
582
- const cause = boundedToken((res.stderr || '').split(/\r?\n/)[0] || 'unknown error');
598
+ const cause = shownCause(res.stderr);
583
599
  return refusal(PROMOTE_GUARD.TRANSPORT, ERROR_REASON.VAULT_PROMOTE_TRANSPORT_FAILED, `This practice was not pushed: git could not reach the vault (${cause}). Check your access to the vault and run the promotion again.`);
584
600
  }
585
601
  /**
@@ -739,7 +755,7 @@ function confirmPromotion({ cwd, filePath, expect, _exec, _vault, _practices })
739
755
  }
740
756
  return {
741
757
  status: 'pushed',
742
- repo: pre.repo,
758
+ repo: shownRepo(pre.repo),
743
759
  ref: pre.ref,
744
760
  destination: pre.destination,
745
761
  mode,