@pareto4/pp-core 1.13.0 → 1.17.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/plugin.json +3 -3
- package/README.md +26 -9
- package/agents/pp-code-reviewer.md +2 -1
- package/agents/pp-debug-session-manager.md +9 -6
- package/agents/pp-executor.md +10 -13
- package/agents/pp-plan-checker.md +4 -4
- package/agents/pp-planner.md +23 -9
- package/agents/pp-vault-reviewer.md +244 -21
- package/agents/pp-verifier.md +7 -3
- package/bin/install.js +10 -3
- package/commands/pp-execute-phase.md +1 -3
- package/commands/pp-ns-review.md +1 -1
- package/commands/pp-plan-phase.md +1 -2
- package/commands/pp-vault-review.md +5 -3
- package/commands/pp-verify-work.md +1 -2
- package/gemini-extension.json +1 -1
- package/hooks/dist/pp-check-update.js +0 -0
- package/hooks/dist/pp-cursor-session-start.js +1 -1
- package/hooks/dist/pp-statusline.js +1 -1
- package/hooks/dist/pp-update-banner.js +0 -0
- package/hooks/pp-check-update.js +0 -0
- package/hooks/pp-cursor-session-start.js +1 -1
- package/hooks/pp-statusline.js +1 -1
- package/hooks/pp-update-banner.js +0 -0
- package/package.json +14 -19
- package/pareto-skills/_shared/create-project-board.sh +0 -0
- package/pareto-skills/pp-project-setup/SKILL.md +1 -1
- package/pp-core/bin/check-latest-version.cjs +0 -0
- package/pp-core/bin/detect-build-commands.sh +2 -2
- package/pp-core/bin/lib/capability-activation.cjs +83 -9
- package/pp-core/bin/lib/capability-registry.cjs +396 -82
- package/pp-core/bin/lib/capability-state.cjs +160 -4
- package/pp-core/bin/lib/capability-writer.cjs +19 -5
- package/pp-core/bin/lib/check-command-router.cjs +3334 -946
- package/pp-core/bin/lib/clusters.cjs +3 -0
- package/pp-core/bin/lib/command-aliases.cjs +0 -35
- package/pp-core/bin/lib/commands.cjs +9 -4
- package/pp-core/bin/lib/compose-bindings.cjs +251 -88
- package/pp-core/bin/lib/config-loader.cjs +7 -103
- package/pp-core/bin/lib/config-schema.cjs +1 -1
- package/pp-core/bin/lib/config.cjs +154 -62
- package/pp-core/bin/lib/decisions.cjs +4 -4
- package/pp-core/bin/lib/discovery-vault-check.cjs +246 -0
- package/pp-core/bin/lib/frontmatter.cjs +1 -38
- package/pp-core/bin/lib/git-base-branch.cjs +13 -11
- package/pp-core/bin/lib/git-provider.cjs +4 -4
- package/pp-core/bin/lib/init-command-router.cjs +5 -8
- package/pp-core/bin/lib/init-contract.cjs +648 -738
- package/pp-core/bin/lib/init-interactive.cjs +76 -4
- package/pp-core/bin/lib/init.cjs +24 -51
- package/pp-core/bin/lib/install-profiles.cjs +1 -1
- package/pp-core/bin/lib/io.cjs +8 -0
- package/pp-core/bin/lib/loop-resolver.cjs +189 -129
- package/pp-core/bin/lib/org-profile.cjs +469 -152
- package/pp-core/bin/lib/package-identity.cjs +3 -3
- package/pp-core/bin/lib/phase-command-router.cjs +1 -29
- package/pp-core/bin/lib/phase-scope.cjs +1 -1
- package/pp-core/bin/lib/phase.cjs +11 -253
- package/pp-core/bin/lib/platform-bindings.cjs +40 -19
- package/pp-core/bin/lib/practices-review-check.cjs +15 -9
- package/pp-core/bin/lib/profile-output.cjs +1 -1
- package/pp-core/bin/lib/shell-command-projection.cjs +104 -1
- package/pp-core/bin/lib/state.cjs +11 -85
- package/pp-core/bin/lib/template.cjs +1 -1
- package/pp-core/bin/lib/vault-audit.cjs +650 -126
- package/pp-core/bin/lib/vault-command-router.cjs +2604 -367
- package/pp-core/bin/lib/vault-coordinates.cjs +13 -4
- package/pp-core/bin/lib/vault-index.cjs +699 -0
- package/pp-core/bin/lib/vault-mode.cjs +235 -0
- package/pp-core/bin/lib/vault-practices.cjs +139 -72
- package/pp-core/bin/lib/vault-review.cjs +194 -451
- package/pp-core/bin/lib/vault-seal.cjs +1936 -0
- package/pp-core/bin/lib/vault-standards.cjs +1505 -0
- package/pp-core/bin/lib/vault-trace.cjs +607 -254
- package/pp-core/bin/lib/vault-update.cjs +9 -33
- package/pp-core/bin/lib/vault-write-back.cjs +70 -42
- package/pp-core/bin/lib/vault.cjs +2734 -920
- package/pp-core/bin/lib/verify.cjs +0 -11
- package/pp-core/bin/portable-timeout.sh +1 -1
- package/pp-core/bin/pp-tools.cjs +184 -54
- package/pp-core/bin/shared/config-defaults.manifest.json +0 -7
- package/pp-core/bin/shared/config-schema.manifest.json +0 -3
- package/pp-core/bin/shared/model-catalog.json +2 -2
- package/pp-core/bin/verify-reapply-patches.cjs +0 -0
- package/pp-core/org-profile.json +26 -0
- package/pp-core/references/autonomous-best-effort.md +8 -7
- package/pp-core/references/loop-hook-dispatch.md +0 -25
- package/pp-core/references/planner-gap-closure.md +0 -1
- package/pp-core/references/planner-tdd.md +0 -1
- package/pp-core/references/planner-vault-practices.md +17 -34
- package/pp-core/references/planner-vault-standards.md +320 -0
- package/pp-core/references/planning-config.md +0 -8
- package/pp-core/references/practice-arithmetic-contract.md +121 -0
- package/pp-core/references/tdd.md +0 -1
- package/pp-core/references/verifier-practice-verdicts.md +263 -0
- package/pp-core/templates/README.md +1 -0
- package/pp-core/templates/VAULT-REVIEW.md +202 -0
- package/pp-core/templates/phase-prompt.md +2 -6
- package/pp-core/templates/practices/README.md +20 -23
- package/pp-core/workflows/_runtime-launcher.snippet.sh +0 -0
- package/pp-core/workflows/add-tests.md +55 -4
- package/pp-core/workflows/audit-fix.md +63 -2
- package/pp-core/workflows/audit-milestone.md +1 -1
- package/pp-core/workflows/autonomous.md +85 -11
- package/pp-core/workflows/check-todos.md +13 -2
- package/pp-core/workflows/code-review-fix.md +59 -3
- package/pp-core/workflows/code-review.md +10 -1
- package/pp-core/workflows/complete-milestone.md +1 -1
- package/pp-core/workflows/debug.md +54 -4
- package/pp-core/workflows/discovery-sprint/prefill.md +19 -7
- package/pp-core/workflows/discovery-sprint/prototype.md +46 -49
- package/pp-core/workflows/discovery-sprint/session-13-gates.md +2 -0
- package/pp-core/workflows/discovery-sprint/sessions/01-kick-off.md +1 -3
- package/pp-core/workflows/discovery-sprint/sessions/02-as-is.md +1 -3
- package/pp-core/workflows/discovery-sprint/sessions/03-to-be.md +1 -3
- package/pp-core/workflows/discovery-sprint/sessions/04-ux-design.md +20 -24
- package/pp-core/workflows/discovery-sprint/sessions/05-architecture.md +1 -3
- package/pp-core/workflows/discovery-sprint/sessions/06-security.md +1 -3
- package/pp-core/workflows/discovery-sprint/sessions/07-identity.md +1 -3
- package/pp-core/workflows/discovery-sprint/sessions/08-integration.md +1 -3
- package/pp-core/workflows/discovery-sprint/sessions/09-qa.md +1 -3
- package/pp-core/workflows/discovery-sprint/sessions/10-infrastructure.md +1 -6
- package/pp-core/workflows/discovery-sprint/sessions/11-roadmap.md +1 -3
- package/pp-core/workflows/discovery-sprint/sessions/12-delivery-model.md +1 -3
- package/pp-core/workflows/discovery-sprint/sessions/13-wrap-up.md +1 -3
- package/pp-core/workflows/discovery-sprint/templates/context-template.md +1 -1
- package/pp-core/workflows/discovery-sprint/vault-context.md +213 -0
- package/pp-core/workflows/discovery-sprint.md +7 -3
- package/pp-core/workflows/discovery-to-build/steps/architecture-deliverables.md +4 -4
- package/pp-core/workflows/discovery-to-build/templates/pp-handoff.md +43 -1
- package/pp-core/workflows/discovery-to-build.md +10 -2
- package/pp-core/workflows/discuss-phase.md +3 -10
- package/pp-core/workflows/execute-phase/steps/check-query-gate.md +329 -0
- package/pp-core/workflows/execute-phase/steps/client-context-gate.md +3 -2
- package/pp-core/workflows/execute-phase/steps/cross-ai-delegation.md +1 -1
- package/pp-core/workflows/execute-phase/steps/execute-pre-dispatch.md +98 -0
- package/pp-core/workflows/execute-phase/steps/per-plan-worktree-gate.md +94 -0
- package/pp-core/workflows/execute-phase/steps/post-merge-gate.md +6 -8
- package/pp-core/workflows/execute-phase/steps/vault-fetch.md +115 -14
- package/pp-core/workflows/execute-phase/steps/vault-load-gate.md +322 -20
- package/pp-core/workflows/execute-phase/steps/verifier-practice-payload.md +165 -0
- package/pp-core/workflows/execute-phase/steps/verify-post-gate.md +163 -0
- package/pp-core/workflows/execute-phase.md +155 -128
- package/pp-core/workflows/execute-plan.md +56 -6
- package/pp-core/workflows/fast.md +53 -4
- package/pp-core/workflows/help/modes/full.md +3 -3
- package/pp-core/workflows/init/steps/client-context-capture.md +101 -0
- package/pp-core/workflows/init/steps/gitlab-provisioning.md +130 -0
- package/pp-core/workflows/init/steps/project-md-deferral-narration.md +66 -0
- package/pp-core/workflows/init/steps/reachability-outcome.md +70 -0
- package/pp-core/workflows/init.md +232 -272
- package/pp-core/workflows/new-project.md +31 -23
- package/pp-core/workflows/plan-phase.md +98 -45
- package/pp-core/workflows/quick.md +117 -3
- package/pp-core/workflows/secure-phase.md +1 -1
- package/pp-core/workflows/ship.md +57 -28
- package/pp-core/workflows/undo.md +1 -1
- package/pp-core/workflows/update.md +3 -3
- package/pp-core/workflows/validate-phase.md +58 -3
- package/pp-core/workflows/vault-review.md +282 -22
- package/pp-core/workflows/verify-work.md +12 -14
- package/scripts/changeset/cli.cjs +6 -5
- package/scripts/changeset/lint.cjs +0 -0
- package/scripts/changeset/new.cjs +33 -50
- package/scripts/dev-env.cjs +25 -85
- package/scripts/gen-capability-registry.cjs +199 -11
- package/scripts/gen-practice-arithmetic-contract.cjs +412 -0
- package/scripts/lib/allowlist-ratchet.cjs +1 -103
- package/scripts/lint-allow-test-rule-refs.allowlist.json +0 -2
- package/scripts/lint-docs-required.cjs +0 -0
- package/scripts/lint-pr-check-project-dir.cjs +1 -3
- package/scripts/lint-test-file-count.allowlist.json +12 -10
- package/scripts/practice-arithmetic-contract.allow.json +35 -0
- package/scripts/prompt-injection-scan.sh +22 -17
- package/scripts/record-vault-mode-golden.cjs +89 -0
- package/scripts/release-channel.cjs +0 -0
- package/scripts/sync-manifest-versions.cjs +5 -4
- package/scripts/sync-rulesets.sh +1 -1
- package/scripts/update-size-baseline.cjs +30 -274
- package/scripts/vault-calibrate.cjs +996 -0
- package/scripts/verify-opengsd-sweep.cjs +3 -5
- package/scripts/workflow-size.cjs +9 -61
- package/pp-core/bin/lib/dispatch-plan.cjs +0 -483
- package/pp-core/bin/lib/install-run.cjs +0 -536
- package/pp-core/bin/lib/loop-gates.cjs +0 -213
- package/pp-core/bin/lib/phase-manifest.cjs +0 -527
- package/pp-core/bin/lib/phase-tier.cjs +0 -480
- package/pp-core/bin/lib/plan-graph.cjs +0 -368
- package/pp-core/references/executor-vault-trace.md +0 -47
- package/pp-core/references/planner-plan-graph.md +0 -66
- package/pp-core/workflows/discovery-sprint/vault-fetch.md +0 -37
- package/pp-core/workflows/execute-phase/steps/checkpoint-handling.md +0 -45
- package/pp-core/workflows/execute-phase/steps/install-run.md +0 -29
- package/pp-core/workflows/execute-phase/steps/phase-close-rebaseline.md +0 -23
- package/pp-core/workflows/execute-phase/steps/serial-group-dispatch.md +0 -73
- package/pp-core/workflows/execute-phase/steps/vault-door-gate.md +0 -19
- package/pp-core/workflows/plan-phase/steps/phase-tier.md +0 -43
- package/scripts/lib/size-budget.cjs +0 -311
- package/scripts/lint-neutrality-names.cjs +0 -694
- package/scripts/lint-org-coordinates.allowlist.json +0 -35
- package/scripts/lint-org-coordinates.cjs +0 -426
|
@@ -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
|
package/pp-core/bin/pp-tools.cjs
CHANGED
|
@@ -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
|
-
//
|
|
733
|
-
//
|
|
734
|
-
//
|
|
735
|
-
//
|
|
736
|
-
|
|
737
|
-
|
|
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,68 @@ function createReadlinePrompter({ input = process.stdin, output = process.stdout
|
|
|
751
748
|
};
|
|
752
749
|
}
|
|
753
750
|
|
|
751
|
+
/**
|
|
752
|
+
* The vault mode a mode-filtered hook is judged against (Phase 15 D-02). Built
|
|
753
|
+
* here, at the CLI entry, so the pure resolvers (`loop-resolver`,
|
|
754
|
+
* `capability-state`) never import the vault adapter. It asks
|
|
755
|
+
* `vaultModeVerdict`, the single mode owner that honours the org-profile
|
|
756
|
+
* ladder, and answers the mode only for an active gate with a cleanly
|
|
757
|
+
* resolved mode. Anything else, including a throw, is `null`: the undefined
|
|
758
|
+
* mode, fail-closed per D-28. `vault.cjs` is required lazily so commands that
|
|
759
|
+
* never render hooks do not load it.
|
|
760
|
+
*/
|
|
761
|
+
function makeVaultModeResolver(cwd) {
|
|
762
|
+
return () => {
|
|
763
|
+
try {
|
|
764
|
+
const v = require('./lib/vault.cjs').vaultModeVerdict(cwd);
|
|
765
|
+
return v.active && v.ok ? v.mode : null;
|
|
766
|
+
} catch {
|
|
767
|
+
return null;
|
|
768
|
+
}
|
|
769
|
+
};
|
|
770
|
+
}
|
|
771
|
+
|
|
772
|
+
/**
|
|
773
|
+
* Does this project hold engine-written vault records? (Phase 16 D-19.) The
|
|
774
|
+
* predicate a seal gate (`onRecordedArtifacts: true`) is rendered under, built
|
|
775
|
+
* here at the CLI entry for the same reason as `makeVaultModeResolver`: the
|
|
776
|
+
* pure resolver never imports vault code. It asks the seal leaf's
|
|
777
|
+
* `hasRecordedVaultArtifacts`, which is bindings-first (D-42) and answers true
|
|
778
|
+
* when it cannot prove absence (D-44). A throw is `false`, the inert answer.
|
|
779
|
+
* Injected ONLY into `loop render-hooks`: `capability state` / `set` report
|
|
780
|
+
* activation, not render, so they never take it. Required lazily so commands
|
|
781
|
+
* that never render hooks do not load the leaf; the resolver memoises it per
|
|
782
|
+
* render and asks it only for an enabled, config-inactive seal gate.
|
|
783
|
+
*/
|
|
784
|
+
function makeRecordedArtifactsResolver(cwd) {
|
|
785
|
+
return () => {
|
|
786
|
+
try {
|
|
787
|
+
return require('./lib/vault-seal.cjs').hasRecordedVaultArtifacts(cwd) === true;
|
|
788
|
+
} catch {
|
|
789
|
+
return false;
|
|
790
|
+
}
|
|
791
|
+
};
|
|
792
|
+
}
|
|
793
|
+
|
|
794
|
+
/**
|
|
795
|
+
* Quick 261015-ect (QD-13): the `.platform-bindings.json` measurement
|
|
796
|
+
* `loop render-hooks` injects, built here at the CLI entry for the same reason
|
|
797
|
+
* as `makeVaultModeResolver`: the resolver imports no vault code (D-02). The
|
|
798
|
+
* reader is EXISTENCE, admission's own step 1 (`hasPlatformBindings`), so a
|
|
799
|
+
* malformed file counts as present and the fence's `vault admission` decides
|
|
800
|
+
* (D-47 b). A throw answers `null`, "could not measure", which the resolver
|
|
801
|
+
* renders through.
|
|
802
|
+
*/
|
|
803
|
+
function makePlatformBindingsPresentResolver(cwd) {
|
|
804
|
+
return () => {
|
|
805
|
+
try {
|
|
806
|
+
return require('./lib/vault.cjs').hasPlatformBindings(cwd) === true;
|
|
807
|
+
} catch {
|
|
808
|
+
return null;
|
|
809
|
+
}
|
|
810
|
+
};
|
|
811
|
+
}
|
|
812
|
+
|
|
754
813
|
async function runCommand(command, args, cwd, raw, defaultValue, originalCommand, workstreamContext = null) {
|
|
755
814
|
switch (command) {
|
|
756
815
|
case 'agent': {
|
|
@@ -784,6 +843,14 @@ async function runCommand(command, args, cwd, raw, defaultValue, originalCommand
|
|
|
784
843
|
break;
|
|
785
844
|
}
|
|
786
845
|
|
|
846
|
+
case 'platform-latest-tag': {
|
|
847
|
+
// quick 261003-my0: the init.md / new-project.md preflights read
|
|
848
|
+
// `--pick latest` from here instead of composing the platform URL in
|
|
849
|
+
// shell — one owner (compose-bindings resolveLatestPlatformTag).
|
|
850
|
+
composeBindings.cmdPlatformLatestTag(cwd, args.slice(1), raw);
|
|
851
|
+
break;
|
|
852
|
+
}
|
|
853
|
+
|
|
787
854
|
case 'validate-bindings': {
|
|
788
855
|
platformBindings.cmdValidateBindings(cwd, args.slice(1), raw);
|
|
789
856
|
break;
|
|
@@ -820,7 +887,6 @@ async function runCommand(command, args, cwd, raw, defaultValue, originalCommand
|
|
|
820
887
|
case 'init-contract': {
|
|
821
888
|
// init-contract [--questions] [--verify] [--session-next]
|
|
822
889
|
// [--session-answer <stepId>=<value>] [--session-reset] [--offline]
|
|
823
|
-
// [--arm-vault]
|
|
824
890
|
// --questions (also the no-flag default, D-05): read-only, always
|
|
825
891
|
// exits 0, prints the canonical /pp-init question set as data.
|
|
826
892
|
// --verify: runs the end-state invariant check (Phase 34-07 gap
|
|
@@ -835,6 +901,20 @@ async function runCommand(command, args, cwd, raw, defaultValue, originalCommand
|
|
|
835
901
|
// BEFORE the unrecognized-flag scan below since the payload itself
|
|
836
902
|
// is not a flag. --offline forwards to every composeBindings call
|
|
837
903
|
// the session makes (parity with compose-bindings --offline).
|
|
904
|
+
// --record-probe <passed|failed>=<note> / --defer-probe <reason>
|
|
905
|
+
// (Phase 7, plan 07-01 — D-07-03, OD-2): the WRITE side of /pp-init
|
|
906
|
+
// Step 2.6's reachability proof. Both take their payload as the NEXT
|
|
907
|
+
// argv token for the same reason --session-answer does — the payload
|
|
908
|
+
// is operator prose and would otherwise be read as a flag — and both
|
|
909
|
+
// are extracted BEFORE the unrecognized-flag scan below. The record is
|
|
910
|
+
// written by recordProbeOutcome/recordProbeDeferral in
|
|
911
|
+
// src/init-contract.cts; --verify reads it back from plan 07-07 on
|
|
912
|
+
// (D-07-04), which is what stops a committed deferral from passing
|
|
913
|
+
// silently forever.
|
|
914
|
+
// --arm-vault (quick 261003-kmd): non-interactive — composes the
|
|
915
|
+
// client-vault binding from the resolved org profile and arms the three
|
|
916
|
+
// vault keys where absent; /pp-new-project calls it. Inert (exit 0,
|
|
917
|
+
// armed:false) when no profile resolves; ok:false means run /pp-init.
|
|
838
918
|
const icArgs = args.slice(1);
|
|
839
919
|
let sessionAnswerRaw;
|
|
840
920
|
const saIdx = icArgs.indexOf('--session-answer');
|
|
@@ -849,12 +929,38 @@ async function runCommand(command, args, cwd, raw, defaultValue, originalCommand
|
|
|
849
929
|
}
|
|
850
930
|
icArgs.splice(saIdx, 2);
|
|
851
931
|
}
|
|
932
|
+
let recordProbeRaw;
|
|
933
|
+
const rpIdx = icArgs.indexOf('--record-probe');
|
|
934
|
+
if (rpIdx !== -1) {
|
|
935
|
+
recordProbeRaw = icArgs[rpIdx + 1];
|
|
936
|
+
if (!recordProbeRaw || recordProbeRaw.startsWith('--')) {
|
|
937
|
+
error(
|
|
938
|
+
'Missing value for --record-probe. Usage: --record-probe <passed|failed>=<note>',
|
|
939
|
+
ERROR_REASON.SDK_MISSING_ARG,
|
|
940
|
+
);
|
|
941
|
+
break;
|
|
942
|
+
}
|
|
943
|
+
icArgs.splice(rpIdx, 2);
|
|
944
|
+
}
|
|
945
|
+
let deferProbeRaw;
|
|
946
|
+
const dpIdx = icArgs.indexOf('--defer-probe');
|
|
947
|
+
if (dpIdx !== -1) {
|
|
948
|
+
deferProbeRaw = icArgs[dpIdx + 1];
|
|
949
|
+
if (!deferProbeRaw || deferProbeRaw.startsWith('--')) {
|
|
950
|
+
error(
|
|
951
|
+
'Missing value for --defer-probe. Usage: --defer-probe "<reason>"',
|
|
952
|
+
ERROR_REASON.SDK_MISSING_ARG,
|
|
953
|
+
);
|
|
954
|
+
break;
|
|
955
|
+
}
|
|
956
|
+
icArgs.splice(dpIdx, 2);
|
|
957
|
+
}
|
|
852
958
|
const unrecognizedIcFlag = icArgs.find(
|
|
853
959
|
(a) => a.startsWith('--') && !initContract.INIT_CONTRACT_FLAGS.includes(a),
|
|
854
960
|
);
|
|
855
961
|
if (unrecognizedIcFlag !== undefined) {
|
|
856
962
|
error(
|
|
857
|
-
`Unrecognized flag "${unrecognizedIcFlag}" for init-contract. Supported: --questions, --verify, --session-next, --session-answer, --session-reset, --offline, --arm-vault.`,
|
|
963
|
+
`Unrecognized flag "${unrecognizedIcFlag}" for init-contract. Supported: --questions, --verify, --session-next, --session-answer, --session-reset, --offline, --record-probe, --defer-probe, --arm-vault.`,
|
|
858
964
|
ERROR_REASON.SDK_FAIL_FAST,
|
|
859
965
|
);
|
|
860
966
|
break;
|
|
@@ -873,7 +979,6 @@ async function runCommand(command, args, cwd, raw, defaultValue, originalCommand
|
|
|
873
979
|
} else if (a === '--offline') {
|
|
874
980
|
icOptions.offline = true;
|
|
875
981
|
} else if (a === '--arm-vault') {
|
|
876
|
-
// Pack 6 D-09: set vault.enabled true only where absent.
|
|
877
982
|
icOptions.armVault = true;
|
|
878
983
|
}
|
|
879
984
|
}
|
|
@@ -891,6 +996,25 @@ async function runCommand(command, args, cwd, raw, defaultValue, originalCommand
|
|
|
891
996
|
value: sessionAnswerRaw.slice(eqIdx + 1),
|
|
892
997
|
};
|
|
893
998
|
}
|
|
999
|
+
if (recordProbeRaw !== undefined) {
|
|
1000
|
+
// Split at the FIRST "=" only: the status is a closed vocabulary with
|
|
1001
|
+
// no "=" in it, and the note is free prose that may well contain one.
|
|
1002
|
+
const rpEq = recordProbeRaw.indexOf('=');
|
|
1003
|
+
if (rpEq === -1) {
|
|
1004
|
+
error(
|
|
1005
|
+
`Invalid --record-probe value "${recordProbeRaw}" — expected <passed|failed>=<note>.`,
|
|
1006
|
+
ERROR_REASON.USAGE,
|
|
1007
|
+
);
|
|
1008
|
+
break;
|
|
1009
|
+
}
|
|
1010
|
+
icOptions.recordProbe = {
|
|
1011
|
+
status: recordProbeRaw.slice(0, rpEq),
|
|
1012
|
+
note: recordProbeRaw.slice(rpEq + 1),
|
|
1013
|
+
};
|
|
1014
|
+
}
|
|
1015
|
+
if (deferProbeRaw !== undefined) {
|
|
1016
|
+
icOptions.deferProbe = deferProbeRaw;
|
|
1017
|
+
}
|
|
894
1018
|
initContract.cmdInitContract(cwd, icOptions, raw);
|
|
895
1019
|
break;
|
|
896
1020
|
}
|
|
@@ -1547,7 +1671,7 @@ async function runCommand(command, args, cwd, raw, defaultValue, originalCommand
|
|
|
1547
1671
|
}
|
|
1548
1672
|
|
|
1549
1673
|
case 'loop': {
|
|
1550
|
-
// loop render-hooks <point> [--config-dir <dir>] [--active-cap <capId>] [--into <role>]
|
|
1674
|
+
// loop render-hooks <point> [--config-dir <dir>] [--active-cap <capId>] [--into <role>]
|
|
1551
1675
|
const loopSubcommand = args[1];
|
|
1552
1676
|
if (loopSubcommand === 'render-hooks') {
|
|
1553
1677
|
let loopConfigDir = null;
|
|
@@ -1579,50 +1703,33 @@ async function runCommand(command, args, cwd, raw, defaultValue, originalCommand
|
|
|
1579
1703
|
}
|
|
1580
1704
|
loopActiveCap = value;
|
|
1581
1705
|
}
|
|
1582
|
-
// --
|
|
1583
|
-
//
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1706
|
+
// --into <role>: print the fragment text of active contributions into <role>
|
|
1707
|
+
// (Phase 15 D-12/D-30; execute-phase interpolates it into the spawn prompt)
|
|
1708
|
+
let loopInto = undefined;
|
|
1709
|
+
const intoEqArg = args.find(arg => arg.startsWith('--into='));
|
|
1710
|
+
const intoIdx = args.indexOf('--into');
|
|
1711
|
+
if (intoEqArg) {
|
|
1712
|
+
const value = intoEqArg.slice('--into='.length).trim();
|
|
1713
|
+
if (!value) error('Missing value for --into (e.g. --into executor)', ERROR_REASON ? ERROR_REASON.USAGE : undefined);
|
|
1714
|
+
loopInto = value;
|
|
1715
|
+
} else if (intoIdx !== -1) {
|
|
1716
|
+
const value = args[intoIdx + 1];
|
|
1590
1717
|
if (!value || value.startsWith('--')) {
|
|
1591
|
-
error(
|
|
1718
|
+
error('Missing value for --into (e.g. --into executor)', ERROR_REASON ? ERROR_REASON.USAGE : undefined);
|
|
1592
1719
|
}
|
|
1593
|
-
|
|
1594
|
-
}
|
|
1720
|
+
loopInto = value;
|
|
1721
|
+
}
|
|
1595
1722
|
loopResolver.cmdLoopRenderHooks(cwd, args[2], raw, {
|
|
1596
1723
|
configDir: loopConfigDir ? path.resolve(loopConfigDir) : undefined,
|
|
1597
1724
|
activeCap: loopActiveCap,
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
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'),
|
|
1725
|
+
into: loopInto,
|
|
1726
|
+
resolveVaultMode: makeVaultModeResolver(cwd),
|
|
1727
|
+
resolveRecordedArtifacts: makeRecordedArtifactsResolver(cwd),
|
|
1728
|
+
resolvePlatformBindingsPresent: makePlatformBindingsPresentResolver(cwd),
|
|
1622
1729
|
});
|
|
1623
1730
|
} else {
|
|
1624
1731
|
error(
|
|
1625
|
-
`Unknown loop subcommand: ${loopSubcommand}. Available: render-hooks
|
|
1732
|
+
`Unknown loop subcommand: ${loopSubcommand}. Available: render-hooks`,
|
|
1626
1733
|
ERROR_REASON ? ERROR_REASON.SDK_UNKNOWN_COMMAND : undefined,
|
|
1627
1734
|
);
|
|
1628
1735
|
}
|
|
@@ -1649,7 +1756,9 @@ async function runCommand(command, args, cwd, raw, defaultValue, originalCommand
|
|
|
1649
1756
|
configDir = configDirVal;
|
|
1650
1757
|
}
|
|
1651
1758
|
const resolvedConfigDir = configDir ? path.resolve(configDir) : null;
|
|
1652
|
-
capabilityState.cmdCapabilityState(cwd, resolvedConfigDir, raw, {
|
|
1759
|
+
capabilityState.cmdCapabilityState(cwd, resolvedConfigDir, raw, {
|
|
1760
|
+
resolveVaultMode: makeVaultModeResolver(cwd),
|
|
1761
|
+
});
|
|
1653
1762
|
} else if (capSubcommand === 'set') {
|
|
1654
1763
|
// capability set <id> [--on|--off|--enable|--disable] [--gate <key>=<bool>]... [--config-dir <dir>] [--runtime <r>] [--scope <s>]
|
|
1655
1764
|
const capId = args[2];
|
|
@@ -1723,7 +1832,14 @@ async function runCommand(command, args, cwd, raw, defaultValue, originalCommand
|
|
|
1723
1832
|
cwd,
|
|
1724
1833
|
resolvedSetConfigDir,
|
|
1725
1834
|
capId,
|
|
1726
|
-
{
|
|
1835
|
+
{
|
|
1836
|
+
enabled: setEnabled,
|
|
1837
|
+
gates: Object.keys(setGates).length > 0 ? setGates : undefined,
|
|
1838
|
+
runtime: setRuntime,
|
|
1839
|
+
scope: setScope,
|
|
1840
|
+
// 15-REVIEW WR-07: the same mode `capability state` and render-hooks use.
|
|
1841
|
+
resolveVaultMode: makeVaultModeResolver(cwd),
|
|
1842
|
+
},
|
|
1727
1843
|
raw,
|
|
1728
1844
|
);
|
|
1729
1845
|
} else {
|
|
@@ -2410,6 +2526,13 @@ async function runCommand(command, args, cwd, raw, defaultValue, originalCommand
|
|
|
2410
2526
|
// Lists every functional element of the prototype under
|
|
2411
2527
|
// .planning/discovery/prototype/ so each is decided once in _sweep.md;
|
|
2412
2528
|
// --check fails (discovery_element_sweep_failed) while one is undecided.
|
|
2529
|
+
//
|
|
2530
|
+
// discovery vault-check <session>
|
|
2531
|
+
//
|
|
2532
|
+
// Checks the `## Vault Context` record of .planning/discovery/session-NN.md:
|
|
2533
|
+
// the index the selection used, one well-formed line per selected vault
|
|
2534
|
+
// document, and that each was cited [vault: <path>] in the notes or marked
|
|
2535
|
+
// not used with a reason. Any gap fails (discovery_vault_check_failed).
|
|
2413
2536
|
|
|
2414
2537
|
case 'discovery': {
|
|
2415
2538
|
const subcommand = args[1];
|
|
@@ -2455,13 +2578,20 @@ async function runCommand(command, args, cwd, raw, defaultValue, originalCommand
|
|
|
2455
2578
|
} catch (rebaselineCheckErr) {
|
|
2456
2579
|
error(`discovery rebaseline-check: ${rebaselineCheckErr && rebaselineCheckErr.message ? rebaselineCheckErr.message : String(rebaselineCheckErr)}`, ERROR_REASON.UNKNOWN);
|
|
2457
2580
|
}
|
|
2581
|
+
} else if (subcommand === 'vault-check') {
|
|
2582
|
+
const vaultCheck = require('./lib/discovery-vault-check.cjs');
|
|
2583
|
+
try {
|
|
2584
|
+
vaultCheck.cmdDiscoveryVaultCheck(cwd, args, raw);
|
|
2585
|
+
} catch (vaultCheckErr) {
|
|
2586
|
+
error(`discovery vault-check: ${vaultCheckErr && vaultCheckErr.message ? vaultCheckErr.message : String(vaultCheckErr)}`, ERROR_REASON.UNKNOWN);
|
|
2587
|
+
}
|
|
2458
2588
|
} else {
|
|
2459
2589
|
// WIRING, NOT HELP TEXT: tests/discovery-artifacts.test.cjs derives each
|
|
2460
2590
|
// subcommand spelling by regexing `<namespace>_<subcommand>_failed` out of
|
|
2461
2591
|
// the engine's exported exit identity, splits this string on commas and
|
|
2462
2592
|
// asserts membership. A spelling missing here is a command the engine
|
|
2463
2593
|
// 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);
|
|
2594
|
+
error('Unknown discovery subcommand. Available: rollup, input-check, research-check, screen-check, element-sweep, rebaseline-check, vault-check', ERROR_REASON.SDK_UNKNOWN_COMMAND);
|
|
2465
2595
|
}
|
|
2466
2596
|
break;
|
|
2467
2597
|
}
|
|
@@ -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-
|
|
159
|
-
"pp-
|
|
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
|
|
5
|
-
caller's launcher — it
|
|
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
|
|
25
|
-
|
|
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
|
|
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,
|
|
305
|
+
| codebase-drift-gate, per-plan-worktree-gate, execute-pre-dispatch, verify-post-gate, verifier-practice-payload | 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)
|