@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
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
/**
|
|
3
|
-
* src/vault-update.cts — `pp-tools vault update [<tag>] [--yes]
|
|
3
|
+
* src/vault-update.cts — `pp-tools vault update [<tag>] [--yes]` (PBI 74316).
|
|
4
4
|
*
|
|
5
|
-
* Moves a project to another version of its client vault. The
|
|
5
|
+
* FORK-ONLY. Moves a project to another version of its client vault. The
|
|
6
6
|
* vault version is a PROJECT property: `client.vaultRef` in the committed
|
|
7
7
|
* `.platform-bindings.json` is the one place it lives, so no pp-core release
|
|
8
8
|
* can move it — changing it is a deliberate act, and this is its command.
|
|
@@ -20,15 +20,6 @@
|
|
|
20
20
|
* vault version a project picks implies a minimum pp-core, never the reverse).
|
|
21
21
|
* It never commits: the command it prints is the operator's to run.
|
|
22
22
|
*
|
|
23
|
-
* With no `<tag>` it proposes the newest stable `vX.Y.Z` tag of the configured
|
|
24
|
-
* vault repository, listed with `git ls-remote` at the same clone target the
|
|
25
|
-
* fetch uses (`resolveClientCoordinates` + `composeCloneTarget`). Nothing here
|
|
26
|
-
* reads an org profile for a version: the vault version is the project's.
|
|
27
|
-
*
|
|
28
|
-
* Every repository coordinate it prints goes through `redactCloneTarget`, and
|
|
29
|
-
* every value it echoes from the bindings file or the command line is
|
|
30
|
-
* bounded to one short line.
|
|
31
|
-
*
|
|
32
23
|
* ADR-457 build-at-publish: this TypeScript file is the SOURCE OF TRUTH. It
|
|
33
24
|
* compiles to the git-ignored `pp-core/bin/lib/vault-update.cjs`.
|
|
34
25
|
*/
|
|
@@ -48,8 +39,8 @@ const compose_bindings_cjs_1 = require("./compose-bindings.cjs");
|
|
|
48
39
|
const git_provider_cjs_1 = require("./git-provider.cjs");
|
|
49
40
|
const vault_coordinates_cjs_1 = require("./vault-coordinates.cjs");
|
|
50
41
|
const platform_bindings_cjs_1 = require("./platform-bindings.cjs");
|
|
51
|
-
//
|
|
52
|
-
// this module; the lazy `require` in runFetch exists for the `_fetch` seam default.
|
|
42
|
+
// VAULT-EGRESS-1 (quick 261005-8py): the one coordinate redactor. Cycle-free — src/vault.cts imports
|
|
43
|
+
// nothing from this module; the lazy `require` in runFetch exists for the `_fetch` seam default.
|
|
53
44
|
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
54
45
|
const vaultModule = require("./vault.cjs");
|
|
55
46
|
const { redactCloneTarget } = vaultModule;
|
|
@@ -66,11 +57,6 @@ function isObject(v) {
|
|
|
66
57
|
function usableString(v) {
|
|
67
58
|
return typeof v === 'string' && v.trim() !== '' ? v.trim() : null;
|
|
68
59
|
}
|
|
69
|
-
/** A value from the bindings file or the command line, made safe to print: one line, at most 80 characters. */
|
|
70
|
-
function shown(v) {
|
|
71
|
-
const flat = v.replace(/[\u0000-\u001F\u007F]+/g, ' ').trim();
|
|
72
|
-
return flat.length > 80 ? `${flat.slice(0, 80)}…` : flat;
|
|
73
|
-
}
|
|
74
60
|
function resolveRoot(cwd) {
|
|
75
61
|
try {
|
|
76
62
|
return (0, project_root_cjs_1.findProjectRoot)(cwd) || cwd;
|
|
@@ -103,7 +89,6 @@ function runFetch(root, opts) {
|
|
|
103
89
|
return {
|
|
104
90
|
source: typeof manifest.source === 'string' ? manifest.source : 'unknown',
|
|
105
91
|
ref: typeof manifest.ref === 'string' ? manifest.ref : null,
|
|
106
|
-
tier: typeof manifest.tier === 'string' ? manifest.tier : null,
|
|
107
92
|
warnings,
|
|
108
93
|
};
|
|
109
94
|
}
|
|
@@ -173,8 +158,7 @@ function vaultUpdate(cwd, opts = {}) {
|
|
|
173
158
|
let tags;
|
|
174
159
|
try {
|
|
175
160
|
const provider = (0, git_provider_cjs_1.resolveProvider)(root).provider;
|
|
176
|
-
|
|
177
|
-
const host = (0, vault_coordinates_cjs_1.resolveClientCoordinates)(root, provider).host;
|
|
161
|
+
const host = usableString(client.vaultHost) ?? (0, vault_coordinates_cjs_1.resolvePlatformHost)(root).host ?? (0, vault_coordinates_cjs_1.defaultHostForProvider)(provider);
|
|
178
162
|
const target = (0, git_provider_cjs_1.composeCloneTarget)(provider, repo, host);
|
|
179
163
|
tags = (0, compose_bindings_cjs_1.listStableTagsAt)(target.url, { _lsRemote: opts._lsRemote });
|
|
180
164
|
}
|
|
@@ -190,10 +174,10 @@ function vaultUpdate(cwd, opts = {}) {
|
|
|
190
174
|
const requested = usableString(opts.target);
|
|
191
175
|
const to = requested ? matchRequestedTag(requested, tags) : tags[0];
|
|
192
176
|
if (!to) {
|
|
193
|
-
return fail('unknown_tag', `The vault repo has no tag "${
|
|
177
|
+
return fail('unknown_tag', `The vault repo has no tag "${requested}". Available (newest first): ${result.available.join(', ')}.`);
|
|
194
178
|
}
|
|
195
179
|
result.to = to;
|
|
196
|
-
const fromLabel = result.from
|
|
180
|
+
const fromLabel = result.from ?? 'main (unpinned)';
|
|
197
181
|
if (result.from === to) {
|
|
198
182
|
return { ...result, ok: true, message: `The project is already on vault ${to}.` };
|
|
199
183
|
}
|
|
@@ -227,7 +211,7 @@ function vaultUpdate(cwd, opts = {}) {
|
|
|
227
211
|
applied.fetch = runFetch(root, opts);
|
|
228
212
|
}
|
|
229
213
|
catch {
|
|
230
|
-
applied.fetch = { source: 'error', ref: null,
|
|
214
|
+
applied.fetch = { source: 'error', ref: null, warnings: ['The vault could not be fetched at the new version — run "pp-tools vault fetch" to retry.'] };
|
|
231
215
|
}
|
|
232
216
|
try {
|
|
233
217
|
applied.newerSchemaPractices = findNewerSchemaPractices(root, opts);
|
|
@@ -244,15 +228,7 @@ function renderVaultUpdate(r) {
|
|
|
244
228
|
lines.push(`Newest available: ${r.latest}.`);
|
|
245
229
|
}
|
|
246
230
|
if (r.fetch) {
|
|
247
|
-
|
|
248
|
-
// A fallback-tier fetch is not the client vault at the new version, and
|
|
249
|
-
// must not read as if it were.
|
|
250
|
-
lines.push(`The client vault at ${r.to ?? 'the new version'} was NOT loaded: the fetch fell back to the ${r.fetch.tier} tier` +
|
|
251
|
-
`${r.fetch.ref ? ` at ${r.fetch.ref}` : ''}. Check access to the client vault, then run "pp-tools vault fetch".`);
|
|
252
|
-
}
|
|
253
|
-
else {
|
|
254
|
-
lines.push(`Fetched the vault: ${r.fetch.source}${r.fetch.ref ? ` at ${r.fetch.ref}` : ''}.`);
|
|
255
|
-
}
|
|
231
|
+
lines.push(`Fetched the vault: ${r.fetch.source}${r.fetch.ref ? ` at ${r.fetch.ref}` : ''}.`);
|
|
256
232
|
for (const w of r.fetch.warnings)
|
|
257
233
|
lines.push(w);
|
|
258
234
|
}
|
|
@@ -103,6 +103,8 @@ const PROMOTE_GUARD = Object.freeze({
|
|
|
103
103
|
WRITE_TARGET: 'write_target',
|
|
104
104
|
CONCURRENT_EDIT: 'concurrent_edit',
|
|
105
105
|
TRANSPORT: 'transport',
|
|
106
|
+
// 13-07 (D-14): standards mode — write-back has no practice layer to write to.
|
|
107
|
+
MODE: 'mode',
|
|
106
108
|
});
|
|
107
109
|
// ─── Secret-content scanner (WRB-03 / D-13 / D-14) ──────────────────────────────
|
|
108
110
|
//
|
|
@@ -200,7 +202,7 @@ function boundedToken(v, max = 80) {
|
|
|
200
202
|
}
|
|
201
203
|
// ─── Preflight guard chain ───────────────────────────────────────────────────────
|
|
202
204
|
/**
|
|
203
|
-
* Run the promote preflight guard chain: activation, input, format
|
|
205
|
+
* Run the promote preflight guard chain: activation, mode (13-07), input, format
|
|
204
206
|
* validation (D-03), secret scan (D-13/D-14), target resolution, and the
|
|
205
207
|
* write-target guard (D-05) — strictly in that order, refusing at the
|
|
206
208
|
* first failing stage and never continuing past it. Makes no network
|
|
@@ -211,16 +213,37 @@ function promotePreflight({ cwd, filePath, _vault, _practices }) {
|
|
|
211
213
|
const vault = _vault ?? require('./vault.cjs');
|
|
212
214
|
// eslint-disable-next-line @typescript-eslint/no-require-imports, @typescript-eslint/no-unsafe-assignment
|
|
213
215
|
const practices = _practices ?? require('./vault-practices.cjs');
|
|
214
|
-
// 1. Activation —
|
|
215
|
-
//
|
|
216
|
-
//
|
|
217
|
-
//
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
216
|
+
// 1. Activation — the vault-practices capability must be on. Runs before
|
|
217
|
+
// any filesystem access; rides the two existing default-false config keys
|
|
218
|
+
// (no new config key, no capability surface widening). Phase 15 D-24/D-25:
|
|
219
|
+
// asked of the ONE practices-switch reader, `isPracticesGateActive`, which
|
|
220
|
+
// resolves both keys exactly as the vault-practices gates' `when` does. The
|
|
221
|
+
// `cfgGet` pair it replaces read only the root config, so a workstream-scoped
|
|
222
|
+
// switch refused here while the gates rendered (15-RESEARCH C-1). Read from
|
|
223
|
+
// the REAL vault leaf, not the `_vault` seam, like the mode guard below: a
|
|
224
|
+
// mocked config read must not be able to switch promotion on.
|
|
225
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
226
|
+
const switchOwner = require('./vault.cjs');
|
|
227
|
+
if (!switchOwner.isPracticesGateActive(cwd)) {
|
|
221
228
|
return refusal(PROMOTE_GUARD.ACTIVATION, ERROR_REASON.VAULT_PROMOTE_DISABLED, 'This practice was not promoted: vault write-back is switched off for this project. ' +
|
|
222
229
|
'Set both vault.enabled and vault.practices_enabled to true in .planning/config.json and run the promotion again.');
|
|
223
230
|
}
|
|
231
|
+
// 1b. Mode (13-07, D-14, PARK-03) — in standards mode the vault carries
|
|
232
|
+
// standards documents maintained through its INDEX.md, not practice files,
|
|
233
|
+
// so there is nothing a promotion could write. Refused here, after the
|
|
234
|
+
// activation guard and BEFORE the input guard reads `filePath` or any clone
|
|
235
|
+
// runs, so the preview and `--confirmed` share it (both call this chain
|
|
236
|
+
// first). Read from the REAL vault leaf, not the `_vault` seam: a governance
|
|
237
|
+
// decision must not be switchable by a test mock (the 13-06 precedent). The
|
|
238
|
+
// envelope carries NO mode key — a promote verdict already uses that key for
|
|
239
|
+
// create/update — so the mode is named in the message only.
|
|
240
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
241
|
+
const modeOwner = require('./vault.cjs');
|
|
242
|
+
if (modeOwner.isStandardsModeActive(cwd)) {
|
|
243
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
244
|
+
const { notApplicablePromoteMessage } = require('./vault-mode.cjs');
|
|
245
|
+
return refusal(PROMOTE_GUARD.MODE, ERROR_REASON.VAULT_PROMOTE_NOT_APPLICABLE, notApplicablePromoteMessage());
|
|
246
|
+
}
|
|
224
247
|
// 2. Input — a path to an already-authored practice file (D-02); this
|
|
225
248
|
// module never composes, rewrites, reformats, or extracts a practice.
|
|
226
249
|
if (typeof filePath !== 'string' ||
|
|
@@ -242,21 +265,40 @@ function promotePreflight({ cwd, filePath, _vault, _practices }) {
|
|
|
242
265
|
const cause = parsed.warning.replace(/^.*?\s+skipped:\s*/, '');
|
|
243
266
|
return refusal(PROMOTE_GUARD.VALIDATION, ERROR_REASON.VAULT_PROMOTE_INVALID_PRACTICE, `This practice was not promoted: ${cause} Fix the practice file and run the promotion again.`);
|
|
244
267
|
}
|
|
245
|
-
// 3b. Degraded-parse refusal
|
|
246
|
-
//
|
|
247
|
-
//
|
|
248
|
-
//
|
|
249
|
-
//
|
|
250
|
-
//
|
|
251
|
-
//
|
|
268
|
+
// 3b. Degraded-parse refusal (CHECK-02e, 05-01).
|
|
269
|
+
//
|
|
270
|
+
// WRITE-SIDE STRICTNESS IS DELIBERATE, and the asymmetry with the read side
|
|
271
|
+
// is the point. On the READ side a practice the engine does not fully
|
|
272
|
+
// understand is retained: it came from the vault, it already governs work,
|
|
273
|
+
// and dropping it would silently un-govern that work (ADR-71924 §5). On the
|
|
274
|
+
// WRITE side the same practice is refused, because promoting it pushes the
|
|
275
|
+
// defect INTO the fleet-wide vault that every developer machine and CI runner
|
|
276
|
+
// fetches — one unreviewed key becomes everyone's degraded warning. The read
|
|
277
|
+
// side tolerates what the write side refuses.
|
|
278
|
+
//
|
|
279
|
+
// Both consumers of DOCUMENTED_FRONTMATTER_KEYS therefore moved in the one
|
|
280
|
+
// change that widened it (T-4-49): had only the reader moved, an unknown key
|
|
281
|
+
// would have quietly become promotable.
|
|
252
282
|
if (parsed.degradedWarnings !== undefined && parsed.degradedWarnings.length > 0) {
|
|
253
283
|
const cause = parsed.degradedWarnings[0].replace(/^.*?\s+degraded:\s*/, '');
|
|
254
284
|
return refusal(PROMOTE_GUARD.VALIDATION, ERROR_REASON.VAULT_PROMOTE_INVALID_PRACTICE, `This practice was not promoted: ${cause} Fix the practice file and run the promotion again.`);
|
|
255
285
|
}
|
|
256
|
-
// 3c. Invalid-check-block refusal
|
|
257
|
-
//
|
|
258
|
-
// `
|
|
259
|
-
//
|
|
286
|
+
// 3c. Invalid-check-block refusal (CR-05 / G-3, 05-11).
|
|
287
|
+
//
|
|
288
|
+
// An invalid `check:` block is refused on the write side for the same reason
|
|
289
|
+
// 3b refuses a degraded parse, and the consequence here is worse. The reader
|
|
290
|
+
// reports this defect on a THIRD channel — `practice.checkInvalid` — which is
|
|
291
|
+
// neither `!parsed.ok` nor `degradedWarnings`, so both rungs above miss it;
|
|
292
|
+
// and the folding of `checkInvalid` into `degraded[]` happens inside
|
|
293
|
+
// `discoverPracticeFiles`, which this path never calls.
|
|
294
|
+
//
|
|
295
|
+
// Once such a practice is in the fleet vault the defect is not a warning for
|
|
296
|
+
// the next reader: `verdictForPractice`'s FIRST rung maps `checkInvalid` to a
|
|
297
|
+
// fail-closed FAIL(check_invalid), so it becomes `block: true` at ship:pre and
|
|
298
|
+
// verify:post on every machine that fetches the vault. One typo would stop the
|
|
299
|
+
// whole fleet's builds. The refusal covers ANY invalid block regardless of
|
|
300
|
+
// which assertion kind it declared (D-05-05), because `checkInvalid` is the
|
|
301
|
+
// single fail-closed signal for both.
|
|
260
302
|
if (typeof parsed.practice.checkInvalid === 'string' && parsed.practice.checkInvalid.length > 0) {
|
|
261
303
|
return refusal(PROMOTE_GUARD.VALIDATION, ERROR_REASON.VAULT_PROMOTE_INVALID_PRACTICE, `This practice was not promoted: ${parsed.practice.checkInvalid} ` +
|
|
262
304
|
'Fix the practice file and run the promotion again.');
|
|
@@ -421,7 +463,9 @@ function buildExpectToken(localRaw, remoteBaseline) {
|
|
|
421
463
|
// reading) — duplicating the fix a second time is exactly how that class of
|
|
422
464
|
// bug recurs.
|
|
423
465
|
function previewPromotion({ cwd, filePath, _exec, _vault, _practices }) {
|
|
424
|
-
const gitExec = _exec ?? shell_command_projection_cjs_1.
|
|
466
|
+
const gitExec = _exec ?? shell_command_projection_cjs_1.execGitLocal;
|
|
467
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports, @typescript-eslint/no-unsafe-assignment
|
|
468
|
+
const vault = _vault ?? require('./vault.cjs');
|
|
425
469
|
// 1. Run the full preflight guard chain; refuse unchanged with no clone.
|
|
426
470
|
const pre = promotePreflight({ cwd, filePath, _vault, _practices });
|
|
427
471
|
if (pre.status !== 'ok')
|
|
@@ -459,7 +503,7 @@ function previewPromotion({ cwd, filePath, _exec, _vault, _practices }) {
|
|
|
459
503
|
cloneDir,
|
|
460
504
|
], { timeout: 120_000 });
|
|
461
505
|
if (cl.exitCode !== 0) {
|
|
462
|
-
const cause =
|
|
506
|
+
const cause = boundedToken((cl.stderr || '').split(/\r?\n/)[0] || 'unknown error');
|
|
463
507
|
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.`);
|
|
464
508
|
}
|
|
465
509
|
// 3. Capture the baseline BEFORE writing — an id already present in the
|
|
@@ -571,13 +615,13 @@ function previewPromotion({ cwd, filePath, _exec, _vault, _practices }) {
|
|
|
571
615
|
// sentence (plan 03); this note additionally explains why, in the
|
|
572
616
|
// read-only preview an operator reads before confirming.
|
|
573
617
|
if (pre.sharedSuppressed && pre.sharedSuppressedKind === 'provider-default-unavailable') {
|
|
574
|
-
notes.push(`No shared vault is configured for the ${pre.provider} provider — the built-in Pareto shared default applies only to the
|
|
618
|
+
notes.push(`No shared vault is configured for the ${pre.provider} provider — the built-in Pareto shared default applies only to the github provider. Set vault.fallback_repo to enable the shared tier.`);
|
|
575
619
|
}
|
|
576
620
|
// 7 & 8. Pin both sides in the opaque expect token, then return.
|
|
577
621
|
const expect = buildExpectToken(pre.raw, baseline);
|
|
578
622
|
return {
|
|
579
623
|
status: 'preview',
|
|
580
|
-
repo:
|
|
624
|
+
repo: vault.redactCloneTarget(pre.repo),
|
|
581
625
|
ref: pre.ref,
|
|
582
626
|
destination: pre.destination,
|
|
583
627
|
mode,
|
|
@@ -596,25 +640,9 @@ function previewPromotion({ cwd, filePath, _exec, _vault, _practices }) {
|
|
|
596
640
|
}
|
|
597
641
|
}
|
|
598
642
|
// ─── Confirm (write half of the write path) ──────────────────────────────────────
|
|
599
|
-
/**
|
|
600
|
-
* Pack 6 D-07: the display-safe forms used in every verdict and refusal this
|
|
601
|
-
* module EMITS — the one owner in src/vault.cts, lazily required (the
|
|
602
|
-
* module's `_vault` seam stays the fetch seam; redaction is never mocked).
|
|
603
|
-
* Comparisons, the expect token and every git invocation keep the RAW values.
|
|
604
|
-
*/
|
|
605
|
-
function shownRepo(repo) {
|
|
606
|
-
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
607
|
-
const v = require('./vault.cjs');
|
|
608
|
-
return v.redactCloneTarget(repo) ?? repo;
|
|
609
|
-
}
|
|
610
|
-
function shownCause(stderr) {
|
|
611
|
-
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
612
|
-
const v = require('./vault.cjs');
|
|
613
|
-
return boundedToken(v.redactRemoteText((stderr || '').split(/\r?\n/)[0] || 'unknown error'));
|
|
614
|
-
}
|
|
615
643
|
/** Build a TRANSPORT refusal from a failed git invocation's stderr (first line only). */
|
|
616
644
|
function transportRefusal(res) {
|
|
617
|
-
const cause =
|
|
645
|
+
const cause = boundedToken((res.stderr || '').split(/\r?\n/)[0] || 'unknown error');
|
|
618
646
|
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.`);
|
|
619
647
|
}
|
|
620
648
|
/**
|
|
@@ -636,7 +664,7 @@ function transportRefusal(res) {
|
|
|
636
664
|
* for free, so no separate `git show`/`cat-file` call is needed.
|
|
637
665
|
*/
|
|
638
666
|
function confirmPromotion({ cwd, filePath, expect, _exec, _vault, _practices }) {
|
|
639
|
-
const gitExec = _exec ?? shell_command_projection_cjs_1.
|
|
667
|
+
const gitExec = _exec ?? shell_command_projection_cjs_1.execGitLocal;
|
|
640
668
|
// 1. Full preflight re-run — never trust the preview. Re-derives repo,
|
|
641
669
|
// ref, host, and destination from scratch; never accepts a caller-
|
|
642
670
|
// supplied id/destination/repo/ref.
|
|
@@ -774,7 +802,7 @@ function confirmPromotion({ cwd, filePath, expect, _exec, _vault, _practices })
|
|
|
774
802
|
}
|
|
775
803
|
return {
|
|
776
804
|
status: 'pushed',
|
|
777
|
-
repo:
|
|
805
|
+
repo: vault.redactCloneTarget(pre.repo),
|
|
778
806
|
ref: pre.ref,
|
|
779
807
|
destination: pre.destination,
|
|
780
808
|
mode,
|