@pareto4/pp-core 1.13.0 → 1.18.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (204) hide show
  1. package/.claude-plugin/plugin.json +3 -3
  2. package/README.md +31 -12
  3. package/agents/pp-code-fixer.md +0 -11
  4. package/agents/pp-code-reviewer.md +1 -77
  5. package/agents/pp-debug-session-manager.md +9 -6
  6. package/agents/pp-executor.md +12 -29
  7. package/agents/pp-plan-checker.md +4 -4
  8. package/agents/pp-planner.md +34 -20
  9. package/agents/pp-vault-reviewer.md +100 -23
  10. package/agents/pp-verifier.md +1 -3
  11. package/bin/install.js +10 -3
  12. package/commands/pp-execute-phase.md +1 -3
  13. package/commands/pp-ns-manage.md +1 -1
  14. package/commands/pp-ns-review.md +1 -1
  15. package/commands/pp-plan-phase.md +1 -2
  16. package/commands/pp-vault-promote.md +7 -8
  17. package/commands/pp-vault-review.md +6 -5
  18. package/commands/pp-verify-work.md +1 -2
  19. package/gemini-extension.json +1 -1
  20. package/hooks/dist/pp-check-update.js +0 -0
  21. package/hooks/dist/pp-cursor-session-start.js +1 -1
  22. package/hooks/dist/pp-statusline.js +1 -1
  23. package/hooks/dist/pp-update-banner.js +0 -0
  24. package/hooks/pp-check-update.js +0 -0
  25. package/hooks/pp-cursor-session-start.js +1 -1
  26. package/hooks/pp-statusline.js +1 -1
  27. package/hooks/pp-update-banner.js +0 -0
  28. package/package.json +10 -18
  29. package/pareto-skills/_shared/create-project-board.sh +0 -0
  30. package/pareto-skills/pp-project-setup/SKILL.md +1 -1
  31. package/pp-core/bin/check-latest-version.cjs +0 -0
  32. package/pp-core/bin/detect-build-commands.sh +2 -2
  33. package/pp-core/bin/lib/capability-activation.cjs +83 -9
  34. package/pp-core/bin/lib/capability-registry.cjs +201 -229
  35. package/pp-core/bin/lib/capability-state.cjs +93 -1
  36. package/pp-core/bin/lib/capability-writer.cjs +3 -3
  37. package/pp-core/bin/lib/check-command-router.cjs +1906 -1514
  38. package/pp-core/bin/lib/clusters.cjs +3 -0
  39. package/pp-core/bin/lib/command-aliases.cjs +0 -35
  40. package/pp-core/bin/lib/commands.cjs +9 -4
  41. package/pp-core/bin/lib/compose-bindings.cjs +251 -88
  42. package/pp-core/bin/lib/config-loader.cjs +7 -103
  43. package/pp-core/bin/lib/config-schema.cjs +1 -1
  44. package/pp-core/bin/lib/config.cjs +151 -62
  45. package/pp-core/bin/lib/decisions.cjs +4 -4
  46. package/pp-core/bin/lib/discovery-vault-check.cjs +246 -0
  47. package/pp-core/bin/lib/frontmatter.cjs +1 -38
  48. package/pp-core/bin/lib/git-base-branch.cjs +11 -12
  49. package/pp-core/bin/lib/git-provider.cjs +9 -10
  50. package/pp-core/bin/lib/init-command-router.cjs +5 -8
  51. package/pp-core/bin/lib/init-contract.cjs +620 -738
  52. package/pp-core/bin/lib/init-interactive.cjs +62 -4
  53. package/pp-core/bin/lib/init.cjs +24 -51
  54. package/pp-core/bin/lib/install-profiles.cjs +1 -1
  55. package/pp-core/bin/lib/io.cjs +4 -2
  56. package/pp-core/bin/lib/loop-resolver.cjs +165 -129
  57. package/pp-core/bin/lib/org-profile.cjs +402 -161
  58. package/pp-core/bin/lib/package-identity.cjs +3 -3
  59. package/pp-core/bin/lib/phase-command-router.cjs +1 -29
  60. package/pp-core/bin/lib/phase-scope.cjs +1 -1
  61. package/pp-core/bin/lib/phase.cjs +11 -253
  62. package/pp-core/bin/lib/platform-bindings.cjs +40 -19
  63. package/pp-core/bin/lib/profile-output.cjs +1 -1
  64. package/pp-core/bin/lib/shell-command-projection.cjs +104 -1
  65. package/pp-core/bin/lib/state.cjs +11 -85
  66. package/pp-core/bin/lib/template.cjs +1 -1
  67. package/pp-core/bin/lib/vault-command-router.cjs +1682 -477
  68. package/pp-core/bin/lib/vault-coordinates.cjs +16 -7
  69. package/pp-core/bin/lib/vault-index.cjs +656 -0
  70. package/pp-core/bin/lib/vault-seal.cjs +1851 -0
  71. package/pp-core/bin/lib/vault-standards-promote.cjs +577 -0
  72. package/pp-core/bin/lib/vault-standards-review.cjs +293 -0
  73. package/pp-core/bin/lib/vault-standards.cjs +1504 -0
  74. package/pp-core/bin/lib/vault-trace.cjs +155 -2778
  75. package/pp-core/bin/lib/vault-update.cjs +10 -59
  76. package/pp-core/bin/lib/vault.cjs +2570 -950
  77. package/pp-core/bin/lib/verify.cjs +0 -11
  78. package/pp-core/bin/portable-timeout.sh +1 -1
  79. package/pp-core/bin/pp-tools.cjs +157 -54
  80. package/pp-core/bin/shared/config-defaults.manifest.json +0 -7
  81. package/pp-core/bin/shared/config-schema.manifest.json +0 -3
  82. package/pp-core/bin/shared/model-catalog.json +2 -2
  83. package/pp-core/bin/verify-reapply-patches.cjs +0 -0
  84. package/pp-core/org-profile.json +26 -0
  85. package/pp-core/references/autonomous-best-effort.md +8 -7
  86. package/pp-core/references/loop-hook-dispatch.md +0 -25
  87. package/pp-core/references/planner-gap-closure.md +0 -1
  88. package/pp-core/references/planner-tdd.md +0 -1
  89. package/pp-core/references/planner-vault-standards.md +311 -0
  90. package/pp-core/references/planning-config.md +0 -8
  91. package/pp-core/references/tdd.md +0 -1
  92. package/pp-core/templates/README.md +1 -0
  93. package/pp-core/templates/VAULT-REVIEW.md +56 -0
  94. package/pp-core/templates/phase-prompt.md +2 -6
  95. package/pp-core/workflows/_runtime-launcher.snippet.sh +0 -0
  96. package/pp-core/workflows/add-tests.md +55 -4
  97. package/pp-core/workflows/audit-fix.md +63 -2
  98. package/pp-core/workflows/audit-milestone.md +1 -1
  99. package/pp-core/workflows/autonomous.md +85 -11
  100. package/pp-core/workflows/check-todos.md +13 -2
  101. package/pp-core/workflows/code-review-fix.md +59 -3
  102. package/pp-core/workflows/code-review.md +10 -57
  103. package/pp-core/workflows/complete-milestone.md +1 -1
  104. package/pp-core/workflows/debug.md +54 -4
  105. package/pp-core/workflows/discovery-sprint/prefill.md +19 -7
  106. package/pp-core/workflows/discovery-sprint/prototype.md +46 -49
  107. package/pp-core/workflows/discovery-sprint/session-13-gates.md +2 -0
  108. package/pp-core/workflows/discovery-sprint/sessions/01-kick-off.md +1 -3
  109. package/pp-core/workflows/discovery-sprint/sessions/02-as-is.md +1 -3
  110. package/pp-core/workflows/discovery-sprint/sessions/03-to-be.md +1 -3
  111. package/pp-core/workflows/discovery-sprint/sessions/04-ux-design.md +20 -24
  112. package/pp-core/workflows/discovery-sprint/sessions/05-architecture.md +1 -3
  113. package/pp-core/workflows/discovery-sprint/sessions/06-security.md +1 -3
  114. package/pp-core/workflows/discovery-sprint/sessions/07-identity.md +1 -3
  115. package/pp-core/workflows/discovery-sprint/sessions/08-integration.md +1 -3
  116. package/pp-core/workflows/discovery-sprint/sessions/09-qa.md +1 -3
  117. package/pp-core/workflows/discovery-sprint/sessions/10-infrastructure.md +1 -6
  118. package/pp-core/workflows/discovery-sprint/sessions/11-roadmap.md +1 -3
  119. package/pp-core/workflows/discovery-sprint/sessions/12-delivery-model.md +1 -3
  120. package/pp-core/workflows/discovery-sprint/sessions/13-wrap-up.md +1 -3
  121. package/pp-core/workflows/discovery-sprint/templates/context-template.md +1 -1
  122. package/pp-core/workflows/discovery-sprint/vault-context.md +207 -0
  123. package/pp-core/workflows/discovery-sprint.md +7 -3
  124. package/pp-core/workflows/discovery-to-build/steps/architecture-deliverables.md +4 -4
  125. package/pp-core/workflows/discovery-to-build/templates/pp-handoff.md +43 -1
  126. package/pp-core/workflows/discovery-to-build.md +10 -2
  127. package/pp-core/workflows/discuss-phase.md +3 -10
  128. package/pp-core/workflows/execute-phase/steps/check-query-gate.md +327 -0
  129. package/pp-core/workflows/execute-phase/steps/client-context-gate.md +3 -2
  130. package/pp-core/workflows/execute-phase/steps/cross-ai-delegation.md +1 -1
  131. package/pp-core/workflows/execute-phase/steps/execute-pre-dispatch.md +78 -0
  132. package/pp-core/workflows/execute-phase/steps/per-plan-worktree-gate.md +94 -0
  133. package/pp-core/workflows/execute-phase/steps/post-merge-gate.md +6 -8
  134. package/pp-core/workflows/execute-phase/steps/vault-fetch.md +115 -14
  135. package/pp-core/workflows/execute-phase/steps/vault-load-gate.md +219 -20
  136. package/pp-core/workflows/execute-phase/steps/verify-post-gate.md +147 -0
  137. package/pp-core/workflows/execute-phase.md +152 -128
  138. package/pp-core/workflows/execute-plan.md +54 -6
  139. package/pp-core/workflows/fast.md +53 -4
  140. package/pp-core/workflows/help/modes/full.md +3 -3
  141. package/pp-core/workflows/init/steps/client-context-capture.md +101 -0
  142. package/pp-core/workflows/init/steps/gitlab-provisioning.md +130 -0
  143. package/pp-core/workflows/init/steps/project-md-deferral-narration.md +66 -0
  144. package/pp-core/workflows/init/steps/reachability-outcome.md +70 -0
  145. package/pp-core/workflows/init.md +232 -272
  146. package/pp-core/workflows/new-project.md +31 -23
  147. package/pp-core/workflows/plan-phase.md +98 -45
  148. package/pp-core/workflows/quick.md +117 -3
  149. package/pp-core/workflows/secure-phase.md +1 -1
  150. package/pp-core/workflows/ship.md +57 -28
  151. package/pp-core/workflows/undo.md +1 -1
  152. package/pp-core/workflows/update.md +3 -3
  153. package/pp-core/workflows/validate-phase.md +58 -3
  154. package/pp-core/workflows/vault-review.md +161 -23
  155. package/pp-core/workflows/vault-write-back.md +73 -110
  156. package/pp-core/workflows/verify-work.md +12 -14
  157. package/scripts/changeset/cli.cjs +6 -5
  158. package/scripts/changeset/lint.cjs +0 -0
  159. package/scripts/changeset/new.cjs +33 -50
  160. package/scripts/dev-env.cjs +25 -85
  161. package/scripts/gen-capability-registry.cjs +120 -13
  162. package/scripts/lib/allowlist-ratchet.cjs +1 -103
  163. package/scripts/lint-allow-test-rule-refs.allowlist.json +0 -2
  164. package/scripts/lint-docs-required.cjs +0 -0
  165. package/scripts/lint-pr-check-project-dir.cjs +1 -3
  166. package/scripts/lint-test-file-count.allowlist.json +3 -19
  167. package/scripts/lint-test-file-count.cjs +5 -6
  168. package/scripts/prompt-injection-scan.sh +19 -17
  169. package/scripts/release-channel.cjs +0 -0
  170. package/scripts/sync-manifest-versions.cjs +5 -4
  171. package/scripts/sync-rulesets.sh +1 -1
  172. package/scripts/update-size-baseline.cjs +30 -274
  173. package/scripts/verify-opengsd-sweep.cjs +3 -5
  174. package/scripts/workflow-size.cjs +9 -61
  175. package/pp-core/bin/lib/dispatch-plan.cjs +0 -483
  176. package/pp-core/bin/lib/install-run.cjs +0 -536
  177. package/pp-core/bin/lib/loop-gates.cjs +0 -213
  178. package/pp-core/bin/lib/phase-manifest.cjs +0 -527
  179. package/pp-core/bin/lib/phase-tier.cjs +0 -480
  180. package/pp-core/bin/lib/plan-graph.cjs +0 -368
  181. package/pp-core/bin/lib/practices-review-check.cjs +0 -938
  182. package/pp-core/bin/lib/vault-audit.cjs +0 -2070
  183. package/pp-core/bin/lib/vault-practices.cjs +0 -1990
  184. package/pp-core/bin/lib/vault-review.cjs +0 -2359
  185. package/pp-core/bin/lib/vault-write-back.cjs +0 -877
  186. package/pp-core/references/executor-vault-trace.md +0 -47
  187. package/pp-core/references/planner-plan-graph.md +0 -66
  188. package/pp-core/references/planner-vault-practices.md +0 -112
  189. package/pp-core/templates/practices/README.md +0 -251
  190. package/pp-core/templates/practices/error-handling.md +0 -18
  191. package/pp-core/templates/practices/minimal-comments.md +0 -14
  192. package/pp-core/templates/practices/naming-convention.md +0 -18
  193. package/pp-core/templates/practices/practice-template.md +0 -23
  194. package/pp-core/workflows/discovery-sprint/vault-fetch.md +0 -37
  195. package/pp-core/workflows/execute-phase/steps/checkpoint-handling.md +0 -45
  196. package/pp-core/workflows/execute-phase/steps/install-run.md +0 -29
  197. package/pp-core/workflows/execute-phase/steps/phase-close-rebaseline.md +0 -23
  198. package/pp-core/workflows/execute-phase/steps/serial-group-dispatch.md +0 -73
  199. package/pp-core/workflows/execute-phase/steps/vault-door-gate.md +0 -19
  200. package/pp-core/workflows/plan-phase/steps/phase-tier.md +0 -43
  201. package/scripts/lib/size-budget.cjs +0 -311
  202. package/scripts/lint-neutrality-names.cjs +0 -694
  203. package/scripts/lint-org-coordinates.allowlist.json +0 -35
  204. package/scripts/lint-org-coordinates.cjs +0 -426
@@ -52,7 +52,6 @@ const { getDeclaredMilestoneInfo, stripShippedMilestones, extractCurrentMileston
52
52
  // eslint-disable-next-line @typescript-eslint/no-require-imports
53
53
  const worktreeSafetyMod = require("./worktree-safety.cjs");
54
54
  const { inspectWorktreeHealth } = worktreeSafetyMod;
55
- const plan_graph_cjs_1 = require("./plan-graph.cjs");
56
55
  const { planningDir, milestonePathsFor, resolveProjectFile } = planningWorkspace;
57
56
  const { extractFrontmatter, parseMustHavesBlock } = frontmatterMod;
58
57
  const { writeStateMd } = stateMod;
@@ -541,16 +540,6 @@ function cmdVerifyPlanStructure(cwd, filePath, raw) {
541
540
  if (fm[field] === undefined)
542
541
  errors.push(`Missing required frontmatter field: ${field}`);
543
542
  }
544
- // `title:` is required on every plan not yet executed. A plan that already has a
545
- // SUMMARY predates the rule (or ran without it): its missing title only warns.
546
- const titleProblem = (0, plan_graph_cjs_1.planTitleProblem)(fm['title']);
547
- if (titleProblem) {
548
- const summaryPath = fullPath.replace(/PLAN\.md$/, 'SUMMARY.md');
549
- if (summaryPath !== fullPath && node_fs_1.default.existsSync(summaryPath))
550
- warnings.push(`${titleProblem} (executed plan: warning only)`);
551
- else
552
- errors.push(titleProblem);
553
- }
554
543
  const taskPattern = /<task[^>]*>([\s\S]*?)<\/task>/g;
555
544
  const tasks = [];
556
545
  let taskMatch;
@@ -22,7 +22,7 @@
22
22
  #
23
23
  # MEASURED exit-code matrix (macOS 26.5, bash 3.2.57, no timeout and no
24
24
  # gtimeout on PATH, perl at /usr/bin/perl; re-measured 2026-09-19 and pinned by
25
- # tests/gate-shell-owners.test.cjs):
25
+ # tests/feat-73988-gate-shell-owners.test.cjs):
26
26
  #
27
27
  # run_with_timeout 1 sleep 5 -> 142 (perl) / 124 (GNU)
28
28
  # run_with_timeout 5 bash -c '<missing command>' -> 127 under every backend
@@ -178,7 +178,6 @@
178
178
  *
179
179
  * Loop Extension Point Queries (ADR-857 phase 3c):
180
180
  * loop render-hooks <point> Resolve + render active Capability hooks at a loop point
181
- * loop run-gates <point> Run the active gates at a loop point (exit 1 on a halt)
182
181
  * Returns JSON envelope { point, activeHooks, rendered }
183
182
  * Valid points: discuss:pre/post, plan:pre/post,
184
183
  * execute:pre/wave:pre/wave:post/post, verify:pre/post, ship:pre/post
@@ -530,7 +529,7 @@ async function main() {
530
529
  'current-timestamp, detect-custom-files, discovery, docs-init, drift-guard, effort, extract-messages, find-phase, ' +
531
530
  'from-gsd2, frontmatter, gap-analysis, generate-claude-md, generate-claude-profile, ' +
532
531
  'generate-client-context, generate-dev-preferences, generate-slug, graphify, history-digest, init, init-contract, intel, ' +
533
- 'capability, classify-confidence, git, learnings, list-todos, loop, milestone, package-legitimacy, phase, phase-plan-index, phases, platform-bindings, profile-questionnaire, ' +
532
+ 'capability, classify-confidence, git, learnings, list-todos, loop, milestone, package-legitimacy, phase, phase-plan-index, phases, platform-bindings, platform-latest-tag, profile-questionnaire, ' +
534
533
  'profile-sample, progress, prompt-budget, requirements, research-plan, research-store, resolve-granularity, resolve-model, roadmap, scaffold, state, ' +
535
534
  'task, template, user-story, validate, validate-bindings, verify, verify-path-exists, verify-summary, workstream, worktree\n\n' +
536
535
  'Global flags:\n' +
@@ -728,15 +727,13 @@ function createReadlinePrompter({ input = process.stdin, output = process.stdout
728
727
  .join(' / ');
729
728
  rendered += `\n Options: ${optionsRendered}`;
730
729
  }
731
- if (question.optionalAnswer) {
732
- // A detected org profile is a hint inside the prompt text, so no
733
- // option-less question carries a default and Enter always skips an
734
- // optional question. The question text may already carry the hint
735
- // (both org profile prompts do), so it is added only when absent (I-1).
736
- const skipHint = 'press Enter to skip';
737
- if (!String(question.prompt).toLowerCase().includes(skipHint.toLowerCase())) {
738
- rendered += `\n (${skipHint})`;
739
- }
730
+ if (question.optionalAnswer && !/press Enter to skip/i.test(question.prompt)) {
731
+ // UAT-13-F2: a detected org profile is a HINT inside the prompt text
732
+ // itself, so Enter always skips an optional question. The question
733
+ // text may already carry the skip hint (the org profile prompts do),
734
+ // so it is added only for an optional question whose text lacks it
735
+ // (I-1).
736
+ rendered += '\n (press Enter to skip)';
740
737
  }
741
738
  return new Promise((resolve) => {
742
739
  rl.question(`${rendered}\n> `, (answer) => resolve(answer));
@@ -751,6 +748,46 @@ function createReadlinePrompter({ input = process.stdin, output = process.stdout
751
748
  };
752
749
  }
753
750
 
751
+ /**
752
+ * Does this project hold engine-written vault records? (Phase 16 D-19.) The
753
+ * predicate a seal gate (`onRecordedArtifacts: true`) is rendered under, built
754
+ * here at the CLI entry so the pure resolver never imports vault code. It asks the seal leaf's
755
+ * `hasRecordedVaultArtifacts`, which is bindings-first (D-42) and answers true
756
+ * when it cannot prove absence (D-44). A throw is `false`, the inert answer.
757
+ * Injected ONLY into `loop render-hooks`: `capability state` / `set` report
758
+ * activation, not render, so they never take it. Required lazily so commands
759
+ * that never render hooks do not load the leaf; the resolver memoises it per
760
+ * render and asks it only for an enabled, config-inactive seal gate.
761
+ */
762
+ function makeRecordedArtifactsResolver(cwd) {
763
+ return () => {
764
+ try {
765
+ return require('./lib/vault-seal.cjs').hasRecordedVaultArtifacts(cwd) === true;
766
+ } catch {
767
+ return false;
768
+ }
769
+ };
770
+ }
771
+
772
+ /**
773
+ * Quick 261015-ect (QD-13): the `.platform-bindings.json` measurement
774
+ * `loop render-hooks` injects, built here at the CLI entry so the resolver
775
+ * imports no vault code (D-02). The
776
+ * reader is EXISTENCE, admission's own step 1 (`hasPlatformBindings`), so a
777
+ * malformed file counts as present and the fence's `vault admission` decides
778
+ * (D-47 b). A throw answers `null`, "could not measure", which the resolver
779
+ * renders through.
780
+ */
781
+ function makePlatformBindingsPresentResolver(cwd) {
782
+ return () => {
783
+ try {
784
+ return require('./lib/vault.cjs').hasPlatformBindings(cwd) === true;
785
+ } catch {
786
+ return null;
787
+ }
788
+ };
789
+ }
790
+
754
791
  async function runCommand(command, args, cwd, raw, defaultValue, originalCommand, workstreamContext = null) {
755
792
  switch (command) {
756
793
  case 'agent': {
@@ -784,6 +821,14 @@ async function runCommand(command, args, cwd, raw, defaultValue, originalCommand
784
821
  break;
785
822
  }
786
823
 
824
+ case 'platform-latest-tag': {
825
+ // quick 261003-my0: the init.md / new-project.md preflights read
826
+ // `--pick latest` from here instead of composing the platform URL in
827
+ // shell — one owner (compose-bindings resolveLatestPlatformTag).
828
+ composeBindings.cmdPlatformLatestTag(cwd, args.slice(1), raw);
829
+ break;
830
+ }
831
+
787
832
  case 'validate-bindings': {
788
833
  platformBindings.cmdValidateBindings(cwd, args.slice(1), raw);
789
834
  break;
@@ -820,7 +865,6 @@ async function runCommand(command, args, cwd, raw, defaultValue, originalCommand
820
865
  case 'init-contract': {
821
866
  // init-contract [--questions] [--verify] [--session-next]
822
867
  // [--session-answer <stepId>=<value>] [--session-reset] [--offline]
823
- // [--arm-vault]
824
868
  // --questions (also the no-flag default, D-05): read-only, always
825
869
  // exits 0, prints the canonical /pp-init question set as data.
826
870
  // --verify: runs the end-state invariant check (Phase 34-07 gap
@@ -835,6 +879,20 @@ async function runCommand(command, args, cwd, raw, defaultValue, originalCommand
835
879
  // BEFORE the unrecognized-flag scan below since the payload itself
836
880
  // is not a flag. --offline forwards to every composeBindings call
837
881
  // the session makes (parity with compose-bindings --offline).
882
+ // --record-probe <passed|failed>=<note> / --defer-probe <reason>
883
+ // (Phase 7, plan 07-01 — D-07-03, OD-2): the WRITE side of /pp-init
884
+ // Step 2.6's reachability proof. Both take their payload as the NEXT
885
+ // argv token for the same reason --session-answer does — the payload
886
+ // is operator prose and would otherwise be read as a flag — and both
887
+ // are extracted BEFORE the unrecognized-flag scan below. The record is
888
+ // written by recordProbeOutcome/recordProbeDeferral in
889
+ // src/init-contract.cts; --verify reads it back from plan 07-07 on
890
+ // (D-07-04), which is what stops a committed deferral from passing
891
+ // silently forever.
892
+ // --arm-vault (quick 261003-kmd): non-interactive — composes the
893
+ // client-vault binding from the resolved org profile and arms the two
894
+ // vault keys where absent; /pp-new-project calls it. Inert (exit 0,
895
+ // armed:false) when no profile resolves; ok:false means run /pp-init.
838
896
  const icArgs = args.slice(1);
839
897
  let sessionAnswerRaw;
840
898
  const saIdx = icArgs.indexOf('--session-answer');
@@ -849,12 +907,38 @@ async function runCommand(command, args, cwd, raw, defaultValue, originalCommand
849
907
  }
850
908
  icArgs.splice(saIdx, 2);
851
909
  }
910
+ let recordProbeRaw;
911
+ const rpIdx = icArgs.indexOf('--record-probe');
912
+ if (rpIdx !== -1) {
913
+ recordProbeRaw = icArgs[rpIdx + 1];
914
+ if (!recordProbeRaw || recordProbeRaw.startsWith('--')) {
915
+ error(
916
+ 'Missing value for --record-probe. Usage: --record-probe <passed|failed>=<note>',
917
+ ERROR_REASON.SDK_MISSING_ARG,
918
+ );
919
+ break;
920
+ }
921
+ icArgs.splice(rpIdx, 2);
922
+ }
923
+ let deferProbeRaw;
924
+ const dpIdx = icArgs.indexOf('--defer-probe');
925
+ if (dpIdx !== -1) {
926
+ deferProbeRaw = icArgs[dpIdx + 1];
927
+ if (!deferProbeRaw || deferProbeRaw.startsWith('--')) {
928
+ error(
929
+ 'Missing value for --defer-probe. Usage: --defer-probe "<reason>"',
930
+ ERROR_REASON.SDK_MISSING_ARG,
931
+ );
932
+ break;
933
+ }
934
+ icArgs.splice(dpIdx, 2);
935
+ }
852
936
  const unrecognizedIcFlag = icArgs.find(
853
937
  (a) => a.startsWith('--') && !initContract.INIT_CONTRACT_FLAGS.includes(a),
854
938
  );
855
939
  if (unrecognizedIcFlag !== undefined) {
856
940
  error(
857
- `Unrecognized flag "${unrecognizedIcFlag}" for init-contract. Supported: --questions, --verify, --session-next, --session-answer, --session-reset, --offline, --arm-vault.`,
941
+ `Unrecognized flag "${unrecognizedIcFlag}" for init-contract. Supported: --questions, --verify, --session-next, --session-answer, --session-reset, --offline, --record-probe, --defer-probe, --arm-vault.`,
858
942
  ERROR_REASON.SDK_FAIL_FAST,
859
943
  );
860
944
  break;
@@ -873,7 +957,6 @@ async function runCommand(command, args, cwd, raw, defaultValue, originalCommand
873
957
  } else if (a === '--offline') {
874
958
  icOptions.offline = true;
875
959
  } else if (a === '--arm-vault') {
876
- // Pack 6 D-09: set vault.enabled true only where absent.
877
960
  icOptions.armVault = true;
878
961
  }
879
962
  }
@@ -891,6 +974,25 @@ async function runCommand(command, args, cwd, raw, defaultValue, originalCommand
891
974
  value: sessionAnswerRaw.slice(eqIdx + 1),
892
975
  };
893
976
  }
977
+ if (recordProbeRaw !== undefined) {
978
+ // Split at the FIRST "=" only: the status is a closed vocabulary with
979
+ // no "=" in it, and the note is free prose that may well contain one.
980
+ const rpEq = recordProbeRaw.indexOf('=');
981
+ if (rpEq === -1) {
982
+ error(
983
+ `Invalid --record-probe value "${recordProbeRaw}" — expected <passed|failed>=<note>.`,
984
+ ERROR_REASON.USAGE,
985
+ );
986
+ break;
987
+ }
988
+ icOptions.recordProbe = {
989
+ status: recordProbeRaw.slice(0, rpEq),
990
+ note: recordProbeRaw.slice(rpEq + 1),
991
+ };
992
+ }
993
+ if (deferProbeRaw !== undefined) {
994
+ icOptions.deferProbe = deferProbeRaw;
995
+ }
894
996
  initContract.cmdInitContract(cwd, icOptions, raw);
895
997
  break;
896
998
  }
@@ -1547,7 +1649,7 @@ async function runCommand(command, args, cwd, raw, defaultValue, originalCommand
1547
1649
  }
1548
1650
 
1549
1651
  case 'loop': {
1550
- // loop render-hooks <point> [--config-dir <dir>] [--active-cap <capId>] [--into <role>] [--phase <N>] [--tier <t>]
1652
+ // loop render-hooks <point> [--config-dir <dir>] [--active-cap <capId>] [--into <role>]
1551
1653
  const loopSubcommand = args[1];
1552
1654
  if (loopSubcommand === 'render-hooks') {
1553
1655
  let loopConfigDir = null;
@@ -1579,50 +1681,32 @@ async function runCommand(command, args, cwd, raw, defaultValue, originalCommand
1579
1681
  }
1580
1682
  loopActiveCap = value;
1581
1683
  }
1582
- // --phase <N> / --tier <light|standard|heavy>: resolve the phase's
1583
- // ceremony tier and read the gate booleans from it (pack 9).
1584
- const loopValue = (flag) => {
1585
- const eq = args.find(arg => arg.startsWith(`--${flag}=`));
1586
- if (eq) return eq.slice(flag.length + 3).trim();
1587
- const idx = args.indexOf(`--${flag}`);
1588
- if (idx === -1) return undefined;
1589
- const value = args[idx + 1];
1684
+ // --into <role>: print the fragment text of active contributions into <role>
1685
+ // (Phase 15 D-12/D-30; execute-phase interpolates it into the spawn prompt)
1686
+ let loopInto = undefined;
1687
+ const intoEqArg = args.find(arg => arg.startsWith('--into='));
1688
+ const intoIdx = args.indexOf('--into');
1689
+ if (intoEqArg) {
1690
+ const value = intoEqArg.slice('--into='.length).trim();
1691
+ if (!value) error('Missing value for --into (e.g. --into executor)', ERROR_REASON ? ERROR_REASON.USAGE : undefined);
1692
+ loopInto = value;
1693
+ } else if (intoIdx !== -1) {
1694
+ const value = args[intoIdx + 1];
1590
1695
  if (!value || value.startsWith('--')) {
1591
- error(`Missing value for --${flag}`, ERROR_REASON ? ERROR_REASON.USAGE : undefined);
1696
+ error('Missing value for --into (e.g. --into executor)', ERROR_REASON ? ERROR_REASON.USAGE : undefined);
1592
1697
  }
1593
- return value;
1594
- };
1698
+ loopInto = value;
1699
+ }
1595
1700
  loopResolver.cmdLoopRenderHooks(cwd, args[2], raw, {
1596
1701
  configDir: loopConfigDir ? path.resolve(loopConfigDir) : undefined,
1597
1702
  activeCap: loopActiveCap,
1598
- phase: loopValue('phase'),
1599
- tier: loopValue('tier'),
1600
- // --into <role>: print the fragment text of active contributions into <role>
1601
- into: loopValue('into'),
1602
- });
1603
- } else if (loopSubcommand === 'run-gates') {
1604
- // loop run-gates <point> [--phase <N>] [--tier <t>] [--query <q>]: run the point's
1605
- // active gates (only those whose check.query is <q>, when given) under the
1606
- // two-step gate contract; exit 1 on a halt.
1607
- const gateValue = (flag) => {
1608
- const eq = args.find(arg => arg.startsWith(`--${flag}=`));
1609
- if (eq) return eq.slice(flag.length + 3).trim();
1610
- const idx = args.indexOf(`--${flag}`);
1611
- if (idx === -1) return undefined;
1612
- const value = args[idx + 1];
1613
- if (!value || value.startsWith('--')) {
1614
- error(`Missing value for --${flag}`, ERROR_REASON ? ERROR_REASON.USAGE : undefined);
1615
- }
1616
- return value;
1617
- };
1618
- require('./lib/loop-gates.cjs').cmdLoopRunGates(cwd, args[2], raw, {
1619
- phase: gateValue('phase'),
1620
- tier: gateValue('tier'),
1621
- query: gateValue('query'),
1703
+ into: loopInto,
1704
+ resolveRecordedArtifacts: makeRecordedArtifactsResolver(cwd),
1705
+ resolvePlatformBindingsPresent: makePlatformBindingsPresentResolver(cwd),
1622
1706
  });
1623
1707
  } else {
1624
1708
  error(
1625
- `Unknown loop subcommand: ${loopSubcommand}. Available: render-hooks, run-gates`,
1709
+ `Unknown loop subcommand: ${loopSubcommand}. Available: render-hooks`,
1626
1710
  ERROR_REASON ? ERROR_REASON.SDK_UNKNOWN_COMMAND : undefined,
1627
1711
  );
1628
1712
  }
@@ -1649,7 +1733,7 @@ async function runCommand(command, args, cwd, raw, defaultValue, originalCommand
1649
1733
  configDir = configDirVal;
1650
1734
  }
1651
1735
  const resolvedConfigDir = configDir ? path.resolve(configDir) : null;
1652
- capabilityState.cmdCapabilityState(cwd, resolvedConfigDir, raw, {});
1736
+ capabilityState.cmdCapabilityState(cwd, resolvedConfigDir, raw);
1653
1737
  } else if (capSubcommand === 'set') {
1654
1738
  // capability set <id> [--on|--off|--enable|--disable] [--gate <key>=<bool>]... [--config-dir <dir>] [--runtime <r>] [--scope <s>]
1655
1739
  const capId = args[2];
@@ -1723,7 +1807,12 @@ async function runCommand(command, args, cwd, raw, defaultValue, originalCommand
1723
1807
  cwd,
1724
1808
  resolvedSetConfigDir,
1725
1809
  capId,
1726
- { enabled: setEnabled, gates: Object.keys(setGates).length > 0 ? setGates : undefined, runtime: setRuntime, scope: setScope },
1810
+ {
1811
+ enabled: setEnabled,
1812
+ gates: Object.keys(setGates).length > 0 ? setGates : undefined,
1813
+ runtime: setRuntime,
1814
+ scope: setScope,
1815
+ },
1727
1816
  raw,
1728
1817
  );
1729
1818
  } else {
@@ -2410,6 +2499,13 @@ async function runCommand(command, args, cwd, raw, defaultValue, originalCommand
2410
2499
  // Lists every functional element of the prototype under
2411
2500
  // .planning/discovery/prototype/ so each is decided once in _sweep.md;
2412
2501
  // --check fails (discovery_element_sweep_failed) while one is undecided.
2502
+ //
2503
+ // discovery vault-check <session>
2504
+ //
2505
+ // Checks the `## Vault Context` record of .planning/discovery/session-NN.md:
2506
+ // the index the selection used, one well-formed line per selected vault
2507
+ // document, and that each was cited [vault: <path>] in the notes or marked
2508
+ // not used with a reason. Any gap fails (discovery_vault_check_failed).
2413
2509
 
2414
2510
  case 'discovery': {
2415
2511
  const subcommand = args[1];
@@ -2455,13 +2551,20 @@ async function runCommand(command, args, cwd, raw, defaultValue, originalCommand
2455
2551
  } catch (rebaselineCheckErr) {
2456
2552
  error(`discovery rebaseline-check: ${rebaselineCheckErr && rebaselineCheckErr.message ? rebaselineCheckErr.message : String(rebaselineCheckErr)}`, ERROR_REASON.UNKNOWN);
2457
2553
  }
2554
+ } else if (subcommand === 'vault-check') {
2555
+ const vaultCheck = require('./lib/discovery-vault-check.cjs');
2556
+ try {
2557
+ vaultCheck.cmdDiscoveryVaultCheck(cwd, args, raw);
2558
+ } catch (vaultCheckErr) {
2559
+ error(`discovery vault-check: ${vaultCheckErr && vaultCheckErr.message ? vaultCheckErr.message : String(vaultCheckErr)}`, ERROR_REASON.UNKNOWN);
2560
+ }
2458
2561
  } else {
2459
2562
  // WIRING, NOT HELP TEXT: tests/discovery-artifacts.test.cjs derives each
2460
2563
  // subcommand spelling by regexing `<namespace>_<subcommand>_failed` out of
2461
2564
  // the engine's exported exit identity, splits this string on commas and
2462
2565
  // asserts membership. A spelling missing here is a command the engine
2463
2566
  // claims to be and the router does not dispatch.
2464
- error('Unknown discovery subcommand. Available: rollup, input-check, research-check, screen-check, element-sweep, rebaseline-check', ERROR_REASON.SDK_UNKNOWN_COMMAND);
2567
+ error('Unknown discovery subcommand. Available: rollup, input-check, research-check, screen-check, element-sweep, rebaseline-check, vault-check', ERROR_REASON.SDK_UNKNOWN_COMMAND);
2465
2568
  }
2466
2569
  break;
2467
2570
  }
@@ -93,12 +93,5 @@
93
93
  "plan_review": {
94
94
  "source_grounding": true,
95
95
  "source_grounding_authority": "grep"
96
- },
97
- "size_budget": {
98
- "per_file_bytes": 1024,
99
- "per_commit_bytes": 4096
100
- },
101
- "phase": {
102
- "tier": "standard"
103
96
  }
104
97
  }
@@ -31,9 +31,6 @@
31
31
  "workflow.plan_bounce",
32
32
  "workflow.plan_bounce_script",
33
33
  "workflow.plan_bounce_passes",
34
- "size_budget.per_file_bytes",
35
- "size_budget.per_commit_bytes",
36
- "phase.tier",
37
34
  "workflow.plan_chunked",
38
35
  "workflow.plan_review_convergence",
39
36
  "code_quality.fallow.enabled",
@@ -155,7 +155,7 @@
155
155
  "pp-intel-updater": { "golden": "opus", "balanced": "sonnet", "budget": "haiku", "phaseType": "research", "routingTier": "light" },
156
156
  "pp-mempalace-curator": { "golden": "sonnet", "balanced": "sonnet", "budget": "haiku", "phaseType": "research", "routingTier": "light" },
157
157
  "pp-security-auditor": { "golden": "opus", "balanced": "sonnet", "budget": "sonnet", "phaseType": "verification", "routingTier": "heavy" },
158
- "pp-user-profiler": { "golden": "opus", "balanced": "sonnet", "budget": "sonnet", "phaseType": "research", "routingTier": "heavy" },
159
- "pp-vault-reviewer": { "golden": "opus", "balanced": "sonnet", "budget": "sonnet", "phaseType": "verification", "routingTier": "heavy" }
158
+ "pp-vault-reviewer": { "golden": "opus", "balanced": "sonnet", "budget": "sonnet", "phaseType": "verification", "routingTier": "heavy" },
159
+ "pp-user-profiler": { "golden": "opus", "balanced": "sonnet", "budget": "sonnet", "phaseType": "research", "routingTier": "heavy" }
160
160
  }
161
161
  }
File without changes
@@ -0,0 +1,26 @@
1
+ {
2
+ "vault": {
3
+ "provider": "github",
4
+ "fallback_repo": ""
5
+ },
6
+ "platform": {
7
+ "host": "github.com"
8
+ },
9
+ "bindings": {
10
+ "platform": {
11
+ "repo": "pareto000/Pareto-Platform"
12
+ },
13
+ "client": {
14
+ "vaultRepo": "pareto000/Pareto-Vault",
15
+ "vaultHost": "github.com"
16
+ },
17
+ "provisioning": {
18
+ "group": "pareto000"
19
+ }
20
+ },
21
+ "init": {
22
+ "provider": "github",
23
+ "visibility": "private",
24
+ "derive_slugs": true
25
+ }
26
+ }
@@ -1,8 +1,9 @@
1
1
  # Autonomous — Best-Effort Rules
2
2
 
3
3
  This file is Read at the start of EVERY phase (`autonomous.md` §3, first line) and again at §6, so
4
- context compaction cannot erode the rules below. It contains bare `pp_run` calls and relies on the
5
- caller's launcher — it carries no preamble of its own.
4
+ context compaction cannot erode the rules below. It contains bare `pp_run` calls and, like
5
+ `pp-core/workflows/execute-phase/steps/check-query-gate.md`, relies on the caller's launcher — it
6
+ carries no preamble of its own.
6
7
 
7
8
  Mode model:
8
9
 
@@ -21,8 +22,8 @@ auto-advance into a second execute-phase.
21
22
 
22
23
  These stop the run in every mode. Best-effort never answers them.
23
24
 
24
- - Blocking capability `check.query` gates (`blocking: true` and `block: true`) — the host workflow
25
- HALTs, which ends the run like an `exit 1`; unchanged.
25
+ - Blocking `check.query` gates (vault `plan:pre`, security) — the enforcer prints its token and runs
26
+ `exit 1`; unchanged.
26
27
  - `human-action` checkpoints (auth/credentials) in execute-phase.
27
28
  - Any checkpoint with `gate="blocking-human"` — package legitimacy (`agents/pp-executor.md`,
28
29
  `agents/pp-planner.md`: never auto-approvable). Presented to the user under `UNATTENDED` and
@@ -297,13 +298,13 @@ calls (`pp-ui-phase`, `pp-code-review`, `pp-ui-review`) and the agents on the pa
297
298
  | execute-phase checkpoint_handling (`human-action`, `gate="blocking-human"`) | hard stop — U-E1 |
298
299
  | execute-phase/steps/cross-ai-delegation.md failure | converted — U-E8 |
299
300
  | execute-phase/steps/vault-load-gate.md, client-context-gate.md `confirmed` | hard stop (governance) |
300
- | execute-phase / plan-phase blocking capability `check.query` gates (`blocking: true`, `block: true`) | hard stop (HALT) |
301
+ | execute-phase/steps/check-query-gate.md, vault-fetch.md halt | hard stop (`exit 1`) |
301
302
  | execute-phase/steps/worktree-recovery-policy.md exit 42; execute-phase partial-execution recovery | hard stop (fail closed) |
302
303
  | execute-phase `state_exists` false; `--interactive` per-plan menu | unreachable — autonomous requires STATE.md and never passes `--interactive` to execute-phase |
303
304
  | post-merge-gate | build-failure "Fix now / Continue" (step 5.8) — this is the U-E2 site: fix once, then continue and record |
304
- | codebase-drift-gate, serial-group-dispatch, vault-fetch | no prompt (non-blocking) |
305
+ | codebase-drift-gate, per-plan-worktree-gate, execute-pre-dispatch, verify-post-gate | no prompt (non-blocking or gate-enforcer only) |
305
306
  | `pp-code-review --fix --auto` (3c.5) | no prompt |
306
- | **`pp-ui-phase`** (§3a.5): step 9 max-revision choice, and its `pp-ui-researcher` design questions | **remaining stop** — ui-phase has no non-interactive flag; filed as deferred |
307
+ | **`pp-ui-phase`** (§3a.5-ii): step 9 max-revision choice, and its `pp-ui-researcher` design questions | **remaining stop** — ui-phase has no non-interactive flag; filed as deferred |
307
308
  | **`pp-ui-review`** (§3d.5): "UI-REVIEW.md already exists" | **remaining stop** (only on a re-run) — no non-interactive flag; filed as deferred |
308
309
  | agents: `pp-planner` / `pp-phase-researcher` / `pp-executor` / `pp-verifier` returns | routed through the host sites above; `pp-executor`'s own auto-approve under `workflow.auto_advance` is filed as deferred (not reached — autonomous sets neither auto flag) |
309
310
 
@@ -5,14 +5,6 @@ in any host-loop workflow. This document is point-agnostic — it applies to eve
5
5
  extension point (discuss:pre, discuss:post, plan:pre, plan:post, execute:pre, execute:wave:pre,
6
6
  execute:wave:post, execute:post, verify:pre, verify:post, ship:pre, ship:post).
7
7
 
8
- Phase workflows pass `--phase <N> [--tier light|standard|heavy]`: the phase's ceremony tier
9
- (`pp_run query phase.tier <N>`) then decides the nine gate booleans (`workflow.research`,
10
- `workflow.pattern_mapper`, `workflow.plan_check`, `workflow.verifier`, `workflow.nyquist_validation`,
11
- `workflow.code_review`, `workflow.post_planning_gaps`, `workflow.security_enforcement`,
12
- `workflow.vault_review`) that hook
13
- `when` keys read, and the envelope carries `phase_tier`. Without `--phase` the project's own
14
- booleans are read.
15
-
16
8
  ## Envelope shape
17
9
 
18
10
  ```json
@@ -30,22 +22,12 @@ booleans are read.
30
22
  `activeHooks` is an array of enabled hook entries for the named point. It is empty (or absent)
31
23
  when no capability has registered an active hook at this point — treat that as a no-op.
32
24
 
33
- ## Refusal
34
-
35
- `render-hooks` refuses — exit 1, empty stdout, one stderr line naming each config file and its
36
- parse error — when a project config file exists but cannot be read (not JSON, or not a JSON
37
- object). A missing config is not refused. Every host writes `X=$(pp_run loop render-hooks …) || exit 1`,
38
- so a refusal stops the workflow: relay the stderr line and stop. Never read a refusal as "no hooks".
39
-
40
25
  ## Dispatch rules by `kind`
41
26
 
42
27
  ### `contribution`
43
28
 
44
29
  Inject `fragment.inline` verbatim into the context for the role named in `into`
45
30
  (e.g. `orchestrator`, `planner`). Do not paraphrase — the text is the product.
46
- `pp_run loop render-hooks <point> --into <role>` prints just those fragments, blank-line separated.
47
- An `execute:pre` contribution `into: executor` reaches every executor through `phase.dispatch-plan`:
48
- each spawn's `contributions[]` carries it, and the spawn prompt injects each `fragment` verbatim.
49
31
 
50
32
  ### `step`
51
33
 
@@ -73,13 +55,6 @@ Evaluate `check` (one of `query`, `predicate`, or `agentVerdict`). Then honor `b
73
55
  Honor `onError` if the check itself errors: `skip` means treat as non-blocking and continue;
74
56
  `fail` means surface the error and stop.
75
57
 
76
- `pp_run loop run-gates <point> --phase <N> [--query <q>]` applies this contract in code for every
77
- active `check.query` gate at the point (only those whose query is `<q>` with `--query`), appending
78
- the gate's declared `check.args` after the phase: exit 1 with a `⛔` line on a halt, `⚠` lines for
79
- advisories and skipped command errors, an `ℹ` line for a passing blocking gate's note, the verdict
80
- JSON on stdout. It runs every `verify:post` gate, and the `vault.trace` gate at `plan:post`,
81
- `execute:post` and `ship:pre` (`--query vault.trace`); the hosts' own gate loops skip that query.
82
-
83
58
  ## Empty / absent `activeHooks`
84
59
 
85
60
  If `activeHooks` is absent, null, or an empty array, skip silently and continue to the next
@@ -52,7 +52,6 @@ grep -l "status: diagnosed" "$phase_dir"/*-UAT.md 2>/dev/null
52
52
  ---
53
53
  phase: XX-name
54
54
  plan: NN # Sequential after existing
55
- title: "..." # REQUIRED one line
56
55
  type: execute
57
56
  wave: N # Computed from depends_on (see assign_waves)
58
57
  depends_on: [...] # Other plans this depends on (gap or existing)
@@ -18,7 +18,6 @@ TDD candidates identified in task_breakdown get dedicated plans (type: tdd). One
18
18
  ---
19
19
  phase: XX-name
20
20
  plan: NN
21
- title: "..."
22
21
  type: tdd
23
22
  ---
24
23