@deftai/directive 0.119.8 → 0.119.10
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/dist/cli-router/route-argv.js +6 -0
- package/dist/dispatch.d.ts +2 -2
- package/dist/dispatch.js +22 -0
- package/dist/policy.d.ts +1 -1
- package/dist/policy.js +69 -15
- package/dist/preflight-gh.d.ts +1 -0
- package/dist/preflight-gh.js +16 -74
- package/dist/scope-record-intent-constraint.d.ts +1 -0
- package/dist/scope-record-intent-constraint.js +28 -4
- package/dist/scope-record-observable-scope.d.ts +1 -0
- package/dist/scope-record-observable-scope.js +28 -4
- package/dist/session-start.d.ts +2 -0
- package/dist/session-start.js +17 -0
- package/dist/verify-ac.js +103 -1
- package/dist/verify-class-checks.d.ts +11 -0
- package/dist/verify-class-checks.js +71 -0
- package/dist/verify-completed-write-guard.js +12 -0
- package/dist/verify-operator-scope-limit.d.ts +17 -0
- package/dist/verify-operator-scope-limit.js +285 -0
- package/dist/verify-review-monitor.d.ts +5 -0
- package/dist/verify-review-monitor.js +93 -2
- package/dist/verify-scope-provenance.js +5 -1
- package/dist/verify-session-ritual.js +5 -3
- package/dist/windows-bin-ps1.d.ts +39 -0
- package/dist/windows-bin-ps1.js +224 -0
- package/package.json +7 -5
- package/scripts/remove-windows-ps1-shims.mjs +26 -0
|
@@ -29,6 +29,7 @@ export const SCOPE_LIFECYCLE_VERBS = new Set([
|
|
|
29
29
|
"block",
|
|
30
30
|
"unblock",
|
|
31
31
|
"stamp-evidence",
|
|
32
|
+
"bind-clause",
|
|
32
33
|
]);
|
|
33
34
|
/** pr:* task names that do not hyphenate 1:1 to handler stems. */
|
|
34
35
|
export const PR_VERB_MAP = {
|
|
@@ -82,6 +83,8 @@ export const SUBCOMMAND_ROUTES = {
|
|
|
82
83
|
"policy:enable-directive": ["policy", "enable-directive"],
|
|
83
84
|
"policy:enforce-branches": ["policy", "enforce-branches"],
|
|
84
85
|
"policy:allow-direct-commits": ["policy", "allow-direct-commits"],
|
|
86
|
+
"policy:allow-destructive-gh-verbs": ["policy", "allow-destructive-gh-verbs"],
|
|
87
|
+
"policy:enforce-destructive-gh-verbs": ["policy", "enforce-destructive-gh-verbs"],
|
|
85
88
|
"policy:allow-bot-merge": ["policy", "allow-bot-merge"],
|
|
86
89
|
"policy:enable-value-feedback": ["policy", "enable-value-feedback"],
|
|
87
90
|
"policy:disable-host-hooks": ["policy", "disable-host-hooks"],
|
|
@@ -207,6 +210,9 @@ function routeNamespaceVerb(ns, verb, rest) {
|
|
|
207
210
|
if (ns === "scm" && verb === "issue:design-critique-chip") {
|
|
208
211
|
return { kind: "dispatch", argv: ["scm", "issue", "design-critique-chip", ...rest] };
|
|
209
212
|
}
|
|
213
|
+
if (ns === "scm" && verb === "issue:design-critique-stale-ready") {
|
|
214
|
+
return { kind: "dispatch", argv: ["scm", "issue", "design-critique-stale-ready", ...rest] };
|
|
215
|
+
}
|
|
210
216
|
if (ns === "scm" && verb === "issue:work-claim") {
|
|
211
217
|
return { kind: "dispatch", argv: ["scm", "issue", "work-claim", ...rest] };
|
|
212
218
|
}
|
package/dist/dispatch.d.ts
CHANGED
|
@@ -10,9 +10,9 @@ export interface DispatchIo {
|
|
|
10
10
|
writeErr: (text: string) => void;
|
|
11
11
|
}
|
|
12
12
|
/** CLI modules in packages/cli/src (excluding parity harnesses and bin/index). */
|
|
13
|
-
export declare const CLI_MODULE_VERBS: readonly ["agents-refresh", "cache", "check", "capacity-backfill", "capacity-show", "codebase-default-extractor", "codebase-map", "codebase-map-fresh", "codebase-projection-registry", "codebase-provider", "doctor", "install-upgrade", "install-uninstall", "migrate-preflight", "migrate-xbrief", "migrate-category-b", "framework-check-updates", "hook-dispatch", "umbrella-current-shape", "changelog-check", "change-init", "commit-lint", "coverage-hotspots", "policy", "authz", "escalation-cli", "pr-closing-keywords", "pr-merge-readiness", "pr-monitor", "pr-protected-issues", "pr-wait-mergeable", "pr-watch", "pr-finish-loop", "directive-finish-loop", "preflight-cache", "preflight-gh", "probe-session", "release", "release-e2e", "release-publish", "release-rollback", "release-wait-npm", "scope-lifecycle", "scope-record-approved-scope", "scope-record-observable-scope", "scope-record-intent-constraint", "scm-sync-default", "lifecycle-event", "lifecycle-stats", "session-start", "session-ready", "occupancy-steal", "occupancy-release", "occupancy-heartbeat", "occupancy-grant", "plan-sequence", "slice", "subagent-monitor", "toolchain-check", "triage-actions", "triage-bootstrap", "triage-bulk", "triage-classify", "triage-strip-withdrawn", "triage-evaluate", "triage-help", "triage-queue", "triage-reconcile", "triage-refresh", "triage-scope", "triage-scope-drift", "triage-smoketest", "triage-subscribe", "triage-summary", "triage-welcome", "ts-check-lane", "vbrief-activate", "vbrief-build", "vbrief-preflight", "vbrief-reconcile", "vbrief-validate", "vbrief-validation", "xbrief-create", "xbrief-verify", "verify-branch", "verify-encoding", "verify-forward-coverage", "verify-test-boundary", "verify-scope-provenance", "verify-consumer-check-contract", "verify-hooks-installed", "verify-investigation", "verify-judgment-gates", "verify-no-task-runtime", "validate-links", "validate-strategy-output", "verify-biome-config", "verify-bridge-drift", "verify-capacity", "verify-contained-writes", "verify-telemetry-coverage", "verify-content-manifest", "verify-deposit-closure", "verify-consumer-hard-stops", "verify-closing-keywords", "verify-skill-external-fetch-gate", "verify-semantic-single-source", "verify-contract-drift", "verify-cursor-tier1", "verify-openclaw-tier1", "verify-go-freeze", "verify-scm-boundary", "verify-session-ritual", "verify-plan-sequence", "verify-stubs", "verify-xbrief-drift", "verify-spec-prd-fresh", "rule-ownership-lint", "verify-story-ready", "verify-review-monitor", "verify-l4-owner", "verify-subagent-alive", "verify-subagent-steer", "review-monitor-register", "review-monitor-release", "verify-tools", "verify-wip-cap", "verify-orphan-active", "verify-pr-closeout-attestable", "verify-lifecycle-visible", "verify-completed-tracked", "verify-completed-write-guard", "verify-literal-ac", "verify-ac", "verify-agents-md-budget", "verify-agents-md-advisory", "verify-eval-health-relocation", "verify-eval-triggers-relocation", "verify-evaluator-surface", "verify-observable-scope", "verify-intent-constraint", "verify-consumer-test-lane", "eval-health", "eval-run", "eval-report", "eval-triggers"];
|
|
13
|
+
export declare const CLI_MODULE_VERBS: readonly ["agents-refresh", "cache", "check", "capacity-backfill", "capacity-show", "codebase-default-extractor", "codebase-map", "codebase-map-fresh", "codebase-projection-registry", "codebase-provider", "doctor", "install-upgrade", "install-uninstall", "migrate-preflight", "migrate-xbrief", "migrate-category-b", "framework-check-updates", "hook-dispatch", "umbrella-current-shape", "changelog-check", "change-init", "commit-lint", "coverage-hotspots", "policy", "authz", "escalation-cli", "pr-closing-keywords", "pr-merge-readiness", "pr-monitor", "pr-protected-issues", "pr-wait-mergeable", "pr-watch", "pr-finish-loop", "directive-finish-loop", "preflight-cache", "preflight-gh", "probe-session", "release", "release-e2e", "release-publish", "release-rollback", "release-wait-npm", "scope-lifecycle", "scope-record-approved-scope", "scope-record-observable-scope", "scope-record-intent-constraint", "scm-sync-default", "lifecycle-event", "lifecycle-stats", "session-start", "session-ready", "occupancy-steal", "occupancy-release", "occupancy-heartbeat", "occupancy-grant", "plan-sequence", "slice", "subagent-monitor", "toolchain-check", "triage-actions", "triage-bootstrap", "triage-bulk", "triage-classify", "triage-strip-withdrawn", "triage-evaluate", "triage-help", "triage-queue", "triage-reconcile", "triage-refresh", "triage-scope", "triage-scope-drift", "triage-smoketest", "triage-subscribe", "triage-summary", "triage-welcome", "ts-check-lane", "vbrief-activate", "vbrief-build", "vbrief-preflight", "vbrief-reconcile", "vbrief-validate", "vbrief-validation", "xbrief-create", "xbrief-verify", "xbrief-adopt-stored-plan-id", "verify-branch", "verify-encoding", "verify-forward-coverage", "verify-test-boundary", "verify-class-checks", "verify-scope-provenance", "verify-consumer-check-contract", "verify-hooks-installed", "verify-investigation", "verify-judgment-gates", "verify-no-task-runtime", "validate-links", "validate-strategy-output", "verify-biome-config", "verify-bridge-drift", "verify-capacity", "verify-contained-writes", "verify-telemetry-coverage", "verify-content-manifest", "verify-deposit-closure", "verify-consumer-hard-stops", "verify-closing-keywords", "verify-skill-external-fetch-gate", "verify-semantic-single-source", "verify-contract-drift", "verify-cursor-tier1", "verify-openclaw-tier1", "verify-go-freeze", "verify-scm-boundary", "verify-session-ritual", "verify-plan-sequence", "verify-stubs", "verify-xbrief-drift", "verify-spec-prd-fresh", "rule-ownership-lint", "verify-story-ready", "verify-review-monitor", "verify-l4-owner", "verify-subagent-alive", "verify-subagent-steer", "review-monitor-register", "review-monitor-release", "verify-tools", "verify-wip-cap", "verify-orphan-active", "verify-pr-closeout-attestable", "verify-lifecycle-visible", "verify-completed-tracked", "verify-completed-write-guard", "verify-literal-ac", "verify-ac", "verify-agents-md-budget", "verify-agents-md-advisory", "verify-eval-health-relocation", "verify-eval-triggers-relocation", "verify-evaluator-surface", "verify-observable-scope", "verify-operator-scope-limit", "verify-intent-constraint", "verify-consumer-test-lane", "eval-health", "eval-run", "eval-report", "eval-triggers"];
|
|
14
14
|
/** Core-only CLI entrypoints without a packages/cli wrapper. */
|
|
15
|
-
export declare const CORE_MODULE_VERBS: readonly ["scm", "scm-readiness", "github-auth-modes", "github-body", "issue-emit", "issue-ingest", "issue-sync-from-xbrief", "reconcile-issues", "swarm-launch", "swarm-complete-cohort", "swarm-finalize-cohort", "swarm-pre-dispatch", "swarm-readiness", "swarm-routing-verify", "swarm-routing-set", "swarm-verify-review-clean", "swarm-worktrees", "framework-commands", "pack-render", "packs-slice", "prd-render", "export-spec", "project-render", "project-write-narratives", "roadmap-render", "rule-map", "spec-render", "spec-validate", "code-structure-validate", "pack-migrate-skills", "pack-migrate-rules", "pack-migrate-strategies", "pack-migrate-patterns", "pack-migrate-swarm-spec", "policy-set", "setup-ghx", "scope-undo", "scope-demote", "scope-decompose", "changelog-resolve-unreleased", "architecture-preflight-sor", "feedback-file", "value-readback", "product-signal", "freshness-report", "decision-write", "decision-list", "docs-impact"];
|
|
15
|
+
export declare const CORE_MODULE_VERBS: readonly ["scm", "scm-readiness", "github-auth-modes", "github-body", "issue-emit", "issue-ingest", "issue-sync-from-xbrief", "reconcile-issues", "swarm-launch", "swarm-complete-cohort", "swarm-finalize-cohort", "swarm-finalize-owed", "swarm-pre-dispatch", "swarm-readiness", "swarm-routing-verify", "swarm-routing-set", "swarm-verify-review-clean", "swarm-worktrees", "framework-commands", "pack-render", "packs-slice", "prd-render", "export-spec", "project-render", "project-write-narratives", "roadmap-render", "rule-map", "spec-render", "spec-validate", "code-structure-validate", "pack-migrate-skills", "pack-migrate-rules", "pack-migrate-strategies", "pack-migrate-patterns", "pack-migrate-swarm-spec", "policy-set", "setup-ghx", "scope-undo", "scope-demote", "scope-decompose", "changelog-resolve-unreleased", "architecture-preflight-sor", "feedback-file", "value-readback", "product-signal", "freshness-report", "decision-write", "decision-list", "docs-impact"];
|
|
16
16
|
/** Colon aliases for triage-actions (mirrors cli-router SUBCOMMAND_ROUTES). */
|
|
17
17
|
export declare const TRIAGE_ACTION_ALIAS_SUBCOMMANDS: Readonly<Record<string, string>>;
|
|
18
18
|
/** Colon aliases for policy subcommands (mirrors cli-router SUBCOMMAND_ROUTES). */
|
package/dist/dispatch.js
CHANGED
|
@@ -111,10 +111,12 @@ export const CLI_MODULE_VERBS = [
|
|
|
111
111
|
"vbrief-validation",
|
|
112
112
|
"xbrief-create",
|
|
113
113
|
"xbrief-verify",
|
|
114
|
+
"xbrief-adopt-stored-plan-id",
|
|
114
115
|
"verify-branch",
|
|
115
116
|
"verify-encoding",
|
|
116
117
|
"verify-forward-coverage",
|
|
117
118
|
"verify-test-boundary",
|
|
119
|
+
"verify-class-checks",
|
|
118
120
|
"verify-scope-provenance",
|
|
119
121
|
"verify-consumer-check-contract",
|
|
120
122
|
"verify-hooks-installed",
|
|
@@ -167,6 +169,7 @@ export const CLI_MODULE_VERBS = [
|
|
|
167
169
|
"verify-eval-triggers-relocation",
|
|
168
170
|
"verify-evaluator-surface",
|
|
169
171
|
"verify-observable-scope",
|
|
172
|
+
"verify-operator-scope-limit",
|
|
170
173
|
"verify-intent-constraint",
|
|
171
174
|
"verify-consumer-test-lane",
|
|
172
175
|
"eval-health",
|
|
@@ -187,6 +190,7 @@ export const CORE_MODULE_VERBS = [
|
|
|
187
190
|
"swarm-launch",
|
|
188
191
|
"swarm-complete-cohort",
|
|
189
192
|
"swarm-finalize-cohort",
|
|
193
|
+
"swarm-finalize-owed",
|
|
190
194
|
"swarm-pre-dispatch",
|
|
191
195
|
"swarm-readiness",
|
|
192
196
|
"swarm-routing-verify",
|
|
@@ -242,6 +246,8 @@ export const POLICY_ACTION_ALIAS_SUBCOMMANDS = {
|
|
|
242
246
|
"policy:show": "show",
|
|
243
247
|
"policy:enforce-branches": "enforce-branches",
|
|
244
248
|
"policy:allow-direct-commits": "allow-direct-commits",
|
|
249
|
+
"policy:allow-destructive-gh-verbs": "allow-destructive-gh-verbs",
|
|
250
|
+
"policy:enforce-destructive-gh-verbs": "enforce-destructive-gh-verbs",
|
|
245
251
|
"policy:allow-bot-merge": "allow-bot-merge",
|
|
246
252
|
"policy:enable-value-feedback": "enable-value-feedback",
|
|
247
253
|
"policy:disable-host-hooks": "disable-host-hooks",
|
|
@@ -299,6 +305,7 @@ export const VERB_ALIASES = {
|
|
|
299
305
|
"verify:encoding": "verify-encoding",
|
|
300
306
|
"verify:forward-coverage": "verify-forward-coverage",
|
|
301
307
|
"verify:test-boundary": "verify-test-boundary",
|
|
308
|
+
"verify:class-checks": "verify-class-checks",
|
|
302
309
|
"verify:scope-provenance": "verify-scope-provenance",
|
|
303
310
|
"scope:record-approved-scope": "scope-record-approved-scope",
|
|
304
311
|
"scope:record-observable-scope": "scope-record-observable-scope",
|
|
@@ -323,6 +330,7 @@ export const VERB_ALIASES = {
|
|
|
323
330
|
"verify:eval-triggers-relocation": "verify-eval-triggers-relocation",
|
|
324
331
|
"verify:evaluator-surface": "verify-evaluator-surface",
|
|
325
332
|
"verify:observable-scope": "verify-observable-scope",
|
|
333
|
+
"verify:operator-scope-limit": "verify-operator-scope-limit",
|
|
326
334
|
"verify:intent-constraint": "verify-intent-constraint",
|
|
327
335
|
"verify:consumer-test-lane": "verify-consumer-test-lane",
|
|
328
336
|
"verify:hooks-installed": "verify-hooks-installed",
|
|
@@ -337,6 +345,7 @@ export const VERB_ALIASES = {
|
|
|
337
345
|
"xbrief:preflight": "vbrief-preflight",
|
|
338
346
|
"xbrief:create": "xbrief-create",
|
|
339
347
|
"xbrief:verify": "xbrief-verify",
|
|
348
|
+
"xbrief:adopt-stored-plan-id": "xbrief-adopt-stored-plan-id",
|
|
340
349
|
"vbrief:activate": "vbrief-activate",
|
|
341
350
|
"verify:story-ready": "verify-story-ready",
|
|
342
351
|
"verify:review-monitor": "verify-review-monitor",
|
|
@@ -478,6 +487,7 @@ const WRAPPER_CLI_STEMS = new Set([
|
|
|
478
487
|
"vbrief-validation",
|
|
479
488
|
"xbrief-create",
|
|
480
489
|
"xbrief-verify",
|
|
490
|
+
"xbrief-adopt-stored-plan-id",
|
|
481
491
|
]);
|
|
482
492
|
function emitCliResult(result, io) {
|
|
483
493
|
if (result.stdout)
|
|
@@ -553,6 +563,10 @@ async function loadWrapperCliHandler(stem, io) {
|
|
|
553
563
|
const { runXbriefVerifyCli } = await import("@deftai/directive-core/xbrief");
|
|
554
564
|
return (argv) => emitCliResult(runXbriefVerifyCli(argv), io);
|
|
555
565
|
}
|
|
566
|
+
case "xbrief-adopt-stored-plan-id": {
|
|
567
|
+
const { runAdoptStoredPlanIdCli } = await import("@deftai/directive-core/xbrief");
|
|
568
|
+
return (argv) => emitCliResult(runAdoptStoredPlanIdCli(argv), io);
|
|
569
|
+
}
|
|
556
570
|
default:
|
|
557
571
|
throw new Error(`no wrapper handler for ${stem}`);
|
|
558
572
|
}
|
|
@@ -2444,6 +2458,10 @@ async function loadCoreModuleHandler(verb, io) {
|
|
|
2444
2458
|
const { finalizeCohortMain } = await import("@deftai/directive-core/dist/swarm/finalize-cohort-cli.js");
|
|
2445
2459
|
return finalizeCohortMain;
|
|
2446
2460
|
}
|
|
2461
|
+
case "swarm-finalize-owed": {
|
|
2462
|
+
const { finalizeOwedMain } = await import("@deftai/directive-core/dist/swarm/finalize-owed-cli.js");
|
|
2463
|
+
return finalizeOwedMain;
|
|
2464
|
+
}
|
|
2447
2465
|
case "swarm-pre-dispatch": {
|
|
2448
2466
|
const { preDispatchMain } = await import("@deftai/directive-core/dist/swarm/pre-dispatch-cli.js");
|
|
2449
2467
|
return preDispatchMain;
|
|
@@ -2771,6 +2789,10 @@ const CURATED_HELP_GROUPS = [
|
|
|
2771
2789
|
name: "xbrief:verify",
|
|
2772
2790
|
summary: "Verify a dense xBRIEF artifact at --out (requires --format); not scope:*",
|
|
2773
2791
|
},
|
|
2792
|
+
{
|
|
2793
|
+
name: "xbrief:adopt-stored-plan-id",
|
|
2794
|
+
summary: "Set plan.id from the stored plan-id binding; refuse if another artifact has it",
|
|
2795
|
+
},
|
|
2774
2796
|
],
|
|
2775
2797
|
},
|
|
2776
2798
|
{
|
package/dist/policy.d.ts
CHANGED
|
@@ -8,7 +8,7 @@ interface ShowArgs {
|
|
|
8
8
|
error?: string;
|
|
9
9
|
}
|
|
10
10
|
interface SetArgs {
|
|
11
|
-
cmd: "show" | "enforce-branches" | "allow-direct-commits" | "allow-bot-merge" | "enable-value-feedback" | "clear-value-feedback" | "set-ceremony-dial" | "disable-host-hooks" | "disable-directive" | "enable-directive" | "resolve";
|
|
11
|
+
cmd: "show" | "enforce-branches" | "allow-direct-commits" | "allow-destructive-gh-verbs" | "enforce-destructive-gh-verbs" | "allow-bot-merge" | "enable-value-feedback" | "clear-value-feedback" | "set-ceremony-dial" | "disable-host-hooks" | "disable-directive" | "enable-directive" | "resolve";
|
|
12
12
|
confirm: boolean;
|
|
13
13
|
actor: string;
|
|
14
14
|
note: string;
|
package/dist/policy.js
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
import { existsSync } from "node:fs";
|
|
7
7
|
import { resolve as pathResolve, relative } from "node:path";
|
|
8
8
|
import { fileURLToPath } from "node:url";
|
|
9
|
-
import { ALLOW_BOT_MERGE_CAPABILITY_COST, CEREMONY_DEPTHS, clearValueFeedback, createNoDeftDirectiveFlag, describeShadowedPlanExtension, detectNoDeftDirective, detectShadowedPlanExtensions, disableHostHooks, disclosureLine, enableValueFeedback, FIELD_VALUE_FEEDBACK, FIELD_VALUE_FEEDBACK_CLI_ALIAS, formatValueFeedbackStatusLine, humanMergeDisclosureLine, inspectAllPolicies, inspectOnePolicy, loadProjectDefinition, NO_DEFT_DIRECTIVE_DISABLED_MESSAGE, NO_DEFT_DIRECTIVE_FLAG_NAME, NO_DEFT_DIRECTIVE_INCONSISTENT_MESSAGE, POLICY_AUDIT_NOOP_STDOUT, parseHookHost, policyColonInvocation, projectDefinitionPath, pythonListRepr, pythonStringRepr, registeredPolicyNames, removeNoDeftDirectiveFlag, renderJson, renderText, resolveHumanMergePolicy, resolvePolicy, resolveValueFeedback, setCeremonyDial, setPolicy, setRequireHumanMerge, } from "@deftai/directive-core/policy";
|
|
9
|
+
import { ALLOW_BOT_MERGE_CAPABILITY_COST, ALLOW_DESTRUCTIVE_GH_VERBS_CAPABILITY_COST, CEREMONY_DEPTHS, clearValueFeedback, createNoDeftDirectiveFlag, describeShadowedPlanExtension, detectNoDeftDirective, detectShadowedPlanExtensions, disableHostHooks, disclosureLine, enableValueFeedback, FIELD_VALUE_FEEDBACK, FIELD_VALUE_FEEDBACK_CLI_ALIAS, formatValueFeedbackStatusLine, humanMergeDisclosureLine, inspectAllPolicies, inspectOnePolicy, loadProjectDefinition, NO_DEFT_DIRECTIVE_DISABLED_MESSAGE, NO_DEFT_DIRECTIVE_FLAG_NAME, NO_DEFT_DIRECTIVE_INCONSISTENT_MESSAGE, POLICY_AUDIT_NOOP_STDOUT, parseHookHost, policyColonInvocation, projectDefinitionPath, pythonListRepr, pythonStringRepr, registeredPolicyNames, removeNoDeftDirectiveFlag, renderJson, renderText, resolveHumanMergePolicy, resolvePolicy, resolveValueFeedback, setAllowDestructiveGhVerbs, setCeremonyDial, setPolicy, setRequireHumanMerge, } from "@deftai/directive-core/policy";
|
|
10
10
|
const CAPABILITY_COST_DISCLOSURE = "\u26a0 Capability-cost disclosure -- enabling direct commits to the default " +
|
|
11
11
|
"branch turns OFF the deft branch-protection policy.\n" +
|
|
12
12
|
" \u2022 Pre-commit + pre-push hooks will no longer block default-branch " +
|
|
@@ -114,7 +114,7 @@ export function parseShowArgs(argv) {
|
|
|
114
114
|
/** Parse argv for the policy CLI (show + set subcommands). */
|
|
115
115
|
export function parseArgs(argv) {
|
|
116
116
|
if (argv.length === 0) {
|
|
117
|
-
const usage = "usage: policy [show|enforce-branches|allow-direct-commits|allow-bot-merge|enable-value-feedback|clear-value-feedback|set-ceremony-dial|disable-host-hooks|disable-directive|enable-directive|resolve] ...";
|
|
117
|
+
const usage = "usage: policy [show|enforce-branches|allow-direct-commits|allow-destructive-gh-verbs|enforce-destructive-gh-verbs|allow-bot-merge|enable-value-feedback|clear-value-feedback|set-ceremony-dial|disable-host-hooks|disable-directive|enable-directive|resolve] ...";
|
|
118
118
|
return makeSetError(usage);
|
|
119
119
|
}
|
|
120
120
|
const cmd = argv[0];
|
|
@@ -148,6 +148,8 @@ export function parseArgs(argv) {
|
|
|
148
148
|
}
|
|
149
149
|
if (cmd === "enforce-branches" ||
|
|
150
150
|
cmd === "allow-direct-commits" ||
|
|
151
|
+
cmd === "allow-destructive-gh-verbs" ||
|
|
152
|
+
cmd === "enforce-destructive-gh-verbs" ||
|
|
151
153
|
cmd === "allow-bot-merge" ||
|
|
152
154
|
cmd === "enable-value-feedback" ||
|
|
153
155
|
cmd === "clear-value-feedback" ||
|
|
@@ -160,19 +162,23 @@ export function parseArgs(argv) {
|
|
|
160
162
|
? policyColonInvocation("enforce-branches")
|
|
161
163
|
: cmd === "allow-direct-commits"
|
|
162
164
|
? policyColonInvocation("allow-direct-commits")
|
|
163
|
-
: cmd === "allow-
|
|
164
|
-
? policyColonInvocation("allow-
|
|
165
|
-
: cmd === "
|
|
166
|
-
? policyColonInvocation("
|
|
167
|
-
: cmd === "
|
|
168
|
-
? policyColonInvocation("
|
|
169
|
-
: cmd === "
|
|
170
|
-
? policyColonInvocation("
|
|
171
|
-
: cmd === "
|
|
172
|
-
? policyColonInvocation("
|
|
173
|
-
: cmd === "
|
|
174
|
-
? policyColonInvocation("
|
|
175
|
-
:
|
|
165
|
+
: cmd === "allow-destructive-gh-verbs"
|
|
166
|
+
? policyColonInvocation("allow-destructive-gh-verbs")
|
|
167
|
+
: cmd === "enforce-destructive-gh-verbs"
|
|
168
|
+
? policyColonInvocation("enforce-destructive-gh-verbs")
|
|
169
|
+
: cmd === "allow-bot-merge"
|
|
170
|
+
? policyColonInvocation("allow-bot-merge")
|
|
171
|
+
: cmd === "enable-value-feedback"
|
|
172
|
+
? policyColonInvocation("enable-value-feedback")
|
|
173
|
+
: cmd === "clear-value-feedback"
|
|
174
|
+
? policyColonInvocation("clear-value-feedback")
|
|
175
|
+
: cmd === "set-ceremony-dial"
|
|
176
|
+
? policyColonInvocation("set-ceremony-dial")
|
|
177
|
+
: cmd === "disable-host-hooks"
|
|
178
|
+
? policyColonInvocation("disable-host-hooks")
|
|
179
|
+
: cmd === "disable-directive"
|
|
180
|
+
? policyColonInvocation("disable-directive")
|
|
181
|
+
: policyColonInvocation("enable-directive");
|
|
176
182
|
let note = "";
|
|
177
183
|
let projectRoot = ".";
|
|
178
184
|
let host;
|
|
@@ -476,6 +482,51 @@ function runEnableDirective(args) {
|
|
|
476
482
|
process.stdout.write("Directive opt-out cleared. Run `directive init` or `directive update` to ensure install.\n");
|
|
477
483
|
return 0;
|
|
478
484
|
}
|
|
485
|
+
/** Allow or re-enforce the #1019 destructive-gh-verb gate. */
|
|
486
|
+
function runDestructiveGhVerbs(args) {
|
|
487
|
+
const projectRoot = pathResolve(args.projectRoot);
|
|
488
|
+
const allow = args.cmd === "allow-destructive-gh-verbs";
|
|
489
|
+
if (allow && !args.confirm) {
|
|
490
|
+
process.stdout.write(`${ALLOW_DESTRUCTIVE_GH_VERBS_CAPABILITY_COST}\n\n`);
|
|
491
|
+
process.stdout.write(`Re-run with --confirm to apply: ${policyColonInvocation("allow-destructive-gh-verbs", " -- --confirm")}\n`);
|
|
492
|
+
return 1;
|
|
493
|
+
}
|
|
494
|
+
try {
|
|
495
|
+
const result = setAllowDestructiveGhVerbs(projectRoot, {
|
|
496
|
+
allowDestructiveGhVerbs: allow,
|
|
497
|
+
actor: args.actor,
|
|
498
|
+
note: args.note,
|
|
499
|
+
});
|
|
500
|
+
if (!result.ok) {
|
|
501
|
+
process.stderr.write(`\u274c ${result.message}\n`);
|
|
502
|
+
if (result.message.includes("PROJECT-DEFINITION not found")) {
|
|
503
|
+
const pdRel = relative(projectRoot, projectDefinitionPath(projectRoot));
|
|
504
|
+
process.stderr.write(` Recovery: run \`task setup\` to generate ${pdRel}.\n`);
|
|
505
|
+
}
|
|
506
|
+
return 2;
|
|
507
|
+
}
|
|
508
|
+
process.stdout.write(`\u2713 plan.policy.allowDestructiveGhVerbs=${allow ? "true" : "false"} ` +
|
|
509
|
+
`(#1019 gate ${allow ? "OFF" : "ON"}).\n`);
|
|
510
|
+
if (result.changed) {
|
|
511
|
+
process.stdout.write(` audit: meta/policy-changes.log :: ${result.auditEntry}\n`);
|
|
512
|
+
}
|
|
513
|
+
else {
|
|
514
|
+
process.stdout.write(`${POLICY_AUDIT_NOOP_STDOUT}\n`);
|
|
515
|
+
}
|
|
516
|
+
return 0;
|
|
517
|
+
}
|
|
518
|
+
catch (err) {
|
|
519
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
520
|
+
if (message.includes("PROJECT-DEFINITION not found")) {
|
|
521
|
+
process.stderr.write(`\u274c ${message}\n`);
|
|
522
|
+
const pdRel = relative(projectRoot, projectDefinitionPath(projectRoot));
|
|
523
|
+
process.stderr.write(` Recovery: run \`task setup\` to generate ${pdRel}.\n`);
|
|
524
|
+
return 2;
|
|
525
|
+
}
|
|
526
|
+
process.stderr.write(`\u274c Config error: ${message}\n`);
|
|
527
|
+
return 2;
|
|
528
|
+
}
|
|
529
|
+
}
|
|
479
530
|
/** Allow agent/bot merge by writing requireHumanMerge=false (#1193). */
|
|
480
531
|
function runAllowBotMerge(args) {
|
|
481
532
|
const projectRoot = pathResolve(args.projectRoot);
|
|
@@ -539,6 +590,9 @@ export function run(argv) {
|
|
|
539
590
|
if (args.cmd === "enforce-branches" || args.cmd === "allow-direct-commits") {
|
|
540
591
|
return runSet(args);
|
|
541
592
|
}
|
|
593
|
+
if (args.cmd === "allow-destructive-gh-verbs" || args.cmd === "enforce-destructive-gh-verbs") {
|
|
594
|
+
return runDestructiveGhVerbs(args);
|
|
595
|
+
}
|
|
542
596
|
if (args.cmd === "allow-bot-merge") {
|
|
543
597
|
return runAllowBotMerge(args);
|
|
544
598
|
}
|
package/dist/preflight-gh.d.ts
CHANGED
package/dist/preflight-gh.js
CHANGED
|
@@ -7,11 +7,13 @@
|
|
|
7
7
|
* deft-ts preflight-gh --command "<gh ...>"
|
|
8
8
|
* deft-ts preflight-gh --pre-push-stdin (reads from stdin)
|
|
9
9
|
*
|
|
10
|
-
* Thin shim -- delegates
|
|
10
|
+
* Thin shim -- delegates through @deftai/directive-core/preflight
|
|
11
|
+
* (re-exports the preflight-gh API; vitest already aliases that subpath).
|
|
12
|
+
* --project-root is consulted by evaluatePrePush / evaluateCommand (#4384).
|
|
11
13
|
*/
|
|
12
14
|
import { createInterface } from "node:readline";
|
|
13
15
|
import { fileURLToPath } from "node:url";
|
|
14
|
-
import { DEFAULT_BRANCHES,
|
|
16
|
+
import { DEFAULT_BRANCHES, evaluateCommand, evaluatePrePush, parsePrePushStdin, runSelfTest, } from "@deftai/directive-core/preflight";
|
|
15
17
|
export function parseArgs(argv) {
|
|
16
18
|
const parsed = { defaultBranches: new Set(DEFAULT_BRANCHES) };
|
|
17
19
|
for (let i = 0; i < argv.length; i++) {
|
|
@@ -44,7 +46,11 @@ export function parseArgs(argv) {
|
|
|
44
46
|
i++;
|
|
45
47
|
}
|
|
46
48
|
else if (arg === "--project-root") {
|
|
47
|
-
|
|
49
|
+
const next = argv[i + 1];
|
|
50
|
+
if (next === undefined) {
|
|
51
|
+
return { ...parsed, error: "argument --project-root: expected one argument" };
|
|
52
|
+
}
|
|
53
|
+
parsed.projectRoot = next;
|
|
48
54
|
i++;
|
|
49
55
|
}
|
|
50
56
|
else {
|
|
@@ -73,7 +79,9 @@ export function run(argv) {
|
|
|
73
79
|
return code;
|
|
74
80
|
}
|
|
75
81
|
if (args.mode === "command" && args.command !== undefined) {
|
|
76
|
-
const [code, msg] = evaluateCommand(args.command, branches
|
|
82
|
+
const [code, msg] = evaluateCommand(args.command, branches, {
|
|
83
|
+
projectRoot: args.projectRoot,
|
|
84
|
+
});
|
|
77
85
|
if (code === 0) {
|
|
78
86
|
if (!quiet)
|
|
79
87
|
process.stdout.write(`${msg}\n`);
|
|
@@ -84,85 +92,19 @@ export function run(argv) {
|
|
|
84
92
|
return code;
|
|
85
93
|
}
|
|
86
94
|
if (args.mode === "pre-push-stdin") {
|
|
87
|
-
return runPrePushStdin(branches, quiet);
|
|
95
|
+
return runPrePushStdin(branches, quiet, args.projectRoot);
|
|
88
96
|
}
|
|
89
97
|
process.stderr.write("preflight-gh: one of --self-test / --command / --pre-push-stdin required\n");
|
|
90
98
|
return 2;
|
|
91
99
|
}
|
|
92
|
-
function
|
|
93
|
-
return text
|
|
94
|
-
.split("\n")
|
|
95
|
-
.map((l) => l.trim())
|
|
96
|
-
.filter((l) => l.length > 0)
|
|
97
|
-
.flatMap((l) => {
|
|
98
|
-
const parts = l.split(/\s+/);
|
|
99
|
-
if (parts.length !== 4)
|
|
100
|
-
return [];
|
|
101
|
-
return [
|
|
102
|
-
{
|
|
103
|
-
localRef: parts[0] ?? "",
|
|
104
|
-
localOid: parts[1] ?? "",
|
|
105
|
-
remoteRef: parts[2] ?? "",
|
|
106
|
-
remoteOid: parts[3] ?? "",
|
|
107
|
-
},
|
|
108
|
-
];
|
|
109
|
-
});
|
|
110
|
-
}
|
|
111
|
-
const ZERO_OID_RE = /^0+$/;
|
|
112
|
-
function evaluatePrePush(refs, branches) {
|
|
113
|
-
if (refs.length === 0) {
|
|
114
|
-
return [0, "✓ deft destructive-gh-verb gate (pre-push): no refs in stdin -- nothing to gate."];
|
|
115
|
-
}
|
|
116
|
-
const branchesLower = new Set([...branches].map((b) => b.toLowerCase()));
|
|
117
|
-
const blocked = [];
|
|
118
|
-
for (const { localRef, localOid, remoteRef, remoteOid } of refs) {
|
|
119
|
-
const branch = remoteRef.replace(/^refs\/heads\//, "");
|
|
120
|
-
if (!branchesLower.has(branch.toLowerCase()))
|
|
121
|
-
continue;
|
|
122
|
-
if (ZERO_OID_RE.test(remoteOid)) {
|
|
123
|
-
blocked.push(`create ${branch} (local=${localRef})`);
|
|
124
|
-
}
|
|
125
|
-
else if (ZERO_OID_RE.test(localOid)) {
|
|
126
|
-
blocked.push(`delete ${branch}`);
|
|
127
|
-
}
|
|
128
|
-
else {
|
|
129
|
-
blocked.push(`update ${branch} (local=${localRef})`);
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
if (blocked.length === 0) {
|
|
133
|
-
return [
|
|
134
|
-
0,
|
|
135
|
-
"✓ deft destructive-gh-verb gate (pre-push): no pushes to default branches detected -- proceeding.",
|
|
136
|
-
];
|
|
137
|
-
}
|
|
138
|
-
const bypass = (process.env[ENV_BYPASS] ?? "").trim().toLowerCase();
|
|
139
|
-
if (["1", "true", "yes", "on"].includes(bypass)) {
|
|
140
|
-
return [
|
|
141
|
-
0,
|
|
142
|
-
`⚠ deft destructive-gh-verb gate (pre-push): default-branch push detected (${blocked.join("; ")}) but ${ENV_BYPASS}=1 is set -- policy bypassed for this invocation.`,
|
|
143
|
-
];
|
|
144
|
-
}
|
|
145
|
-
return [
|
|
146
|
-
1,
|
|
147
|
-
[
|
|
148
|
-
"❌ deft destructive-gh-verb gate (pre-push): refusing to push directly to the default branch.",
|
|
149
|
-
` Detail: ${blocked.join("; ")}`,
|
|
150
|
-
"",
|
|
151
|
-
" How to proceed:",
|
|
152
|
-
" • push to a feature branch and open a PR",
|
|
153
|
-
` • or set the env-var bypass for this shell: ${ENV_BYPASS}=1`,
|
|
154
|
-
" See scm/github.md (## Destructive gh verbs (#1019)).",
|
|
155
|
-
].join("\n"),
|
|
156
|
-
];
|
|
157
|
-
}
|
|
158
|
-
function runPrePushStdin(branches, quiet) {
|
|
100
|
+
function runPrePushStdin(branches, quiet, projectRoot) {
|
|
159
101
|
return new Promise((resolve) => {
|
|
160
102
|
const lines = [];
|
|
161
103
|
const rl = createInterface({ input: process.stdin });
|
|
162
104
|
rl.on("line", (l) => lines.push(l));
|
|
163
105
|
rl.on("close", () => {
|
|
164
|
-
const refs =
|
|
165
|
-
const [code, msg] = evaluatePrePush(refs, branches);
|
|
106
|
+
const refs = parsePrePushStdin(lines.join("\n"));
|
|
107
|
+
const [code, msg] = evaluatePrePush(refs, { branches, projectRoot });
|
|
166
108
|
if (code === 0) {
|
|
167
109
|
if (!quiet)
|
|
168
110
|
process.stdout.write(`${msg}\n`);
|
|
@@ -11,12 +11,18 @@ import { buildIntentConstraintRecord, extractIntentConstraintFromPlan, parseInte
|
|
|
11
11
|
import { isDirectEntrypoint } from "./entrypoint.js";
|
|
12
12
|
import { refuseMintWhileUatActive, refuseNonInteractiveMint, resolveHumanPresenceMintSeams, } from "./human-presence-mint.js";
|
|
13
13
|
import { isPathInsideRoot } from "./scope-record-approved-scope.js";
|
|
14
|
+
const DEFAULT_MINTED_VIA = "scope:record-intent-constraint";
|
|
15
|
+
const ALLOWED_MINTED_VIA = new Set([DEFAULT_MINTED_VIA, "in-harness-ask"]);
|
|
14
16
|
function usage() {
|
|
15
17
|
return ("usage: scope:record-intent-constraint -- <xbrief-path> --actor <name> --confirm " +
|
|
16
|
-
"[--kind operator] [--
|
|
18
|
+
"[--kind operator] [--minted-via in-harness-ask|scope:record-intent-constraint] " +
|
|
19
|
+
"[--project-root <dir>] [--quiet]\n" +
|
|
17
20
|
' Writes .deft/intent-constraint/<plan-id>.json from plan["x-directive/intentConstraint"].\n' +
|
|
18
|
-
"
|
|
19
|
-
"
|
|
21
|
+
" Attended mid-build (#5010): ask in parent chat; on yes the human runs this verb on a real TTY " +
|
|
22
|
+
"with --minted-via=in-harness-ask (attestation is not an agent-shell bypass). Commit the record on " +
|
|
23
|
+
"the delivery-branch merge base, then rebase the implementation branch — same-PR working-tree-only " +
|
|
24
|
+
"records are not authoritative. Unattended/C1: rewrite or park. --actor is display only. Mint still " +
|
|
25
|
+
"requires a real TTY, controlling terminal, --confirm, and typed phrase mint (#3110). Agent/CI shells refuse.");
|
|
20
26
|
}
|
|
21
27
|
function extractPlanId(payload) {
|
|
22
28
|
if (payload === null || typeof payload !== "object" || Array.isArray(payload))
|
|
@@ -33,6 +39,7 @@ export function parseArgs(argv) {
|
|
|
33
39
|
xbriefPath: "",
|
|
34
40
|
actor: "",
|
|
35
41
|
kind: "operator",
|
|
42
|
+
mintedVia: DEFAULT_MINTED_VIA,
|
|
36
43
|
quiet: false,
|
|
37
44
|
confirm: false,
|
|
38
45
|
};
|
|
@@ -77,6 +84,16 @@ export function parseArgs(argv) {
|
|
|
77
84
|
else if (arg?.startsWith("--kind=")) {
|
|
78
85
|
parsed.kind = arg.slice("--kind=".length);
|
|
79
86
|
}
|
|
87
|
+
else if (arg === "--minted-via") {
|
|
88
|
+
const value = argv[i + 1];
|
|
89
|
+
if (value === undefined)
|
|
90
|
+
return { ...parsed, error: "argument --minted-via: expected one argument" };
|
|
91
|
+
parsed.mintedVia = value;
|
|
92
|
+
i += 1;
|
|
93
|
+
}
|
|
94
|
+
else if (arg?.startsWith("--minted-via=")) {
|
|
95
|
+
parsed.mintedVia = arg.slice("--minted-via=".length);
|
|
96
|
+
}
|
|
80
97
|
else if (arg?.startsWith("-")) {
|
|
81
98
|
return { ...parsed, error: `unrecognized argument: ${arg}` };
|
|
82
99
|
}
|
|
@@ -98,6 +115,13 @@ export function parseArgs(argv) {
|
|
|
98
115
|
error: `argument --actor is required (human operator identity)\n${usage()}`,
|
|
99
116
|
};
|
|
100
117
|
}
|
|
118
|
+
if (!ALLOWED_MINTED_VIA.has(parsed.mintedVia.trim())) {
|
|
119
|
+
return {
|
|
120
|
+
...parsed,
|
|
121
|
+
error: `argument --minted-via must be one of: ${[...ALLOWED_MINTED_VIA].join(", ")}\n${usage()}`,
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
parsed.mintedVia = parsed.mintedVia.trim();
|
|
101
125
|
return parsed;
|
|
102
126
|
}
|
|
103
127
|
export function run(argv, seams = {}) {
|
|
@@ -159,7 +183,7 @@ export function run(argv, seams = {}) {
|
|
|
159
183
|
kind: args.kind,
|
|
160
184
|
actor: args.actor,
|
|
161
185
|
mintedAt: new Date().toISOString().replace(/\.\d{3}Z$/, "Z"),
|
|
162
|
-
mintedVia:
|
|
186
|
+
mintedVia: args.mintedVia,
|
|
163
187
|
},
|
|
164
188
|
});
|
|
165
189
|
if ("error" in rec) {
|
|
@@ -11,12 +11,18 @@ import { buildObservableScopeRecord, extractObservableChangeFromPlan, parseObser
|
|
|
11
11
|
import { isDirectEntrypoint } from "./entrypoint.js";
|
|
12
12
|
import { refuseMintWhileUatActive, refuseNonInteractiveMint, resolveHumanPresenceMintSeams, } from "./human-presence-mint.js";
|
|
13
13
|
import { isPathInsideRoot } from "./scope-record-approved-scope.js";
|
|
14
|
+
const DEFAULT_MINTED_VIA = "scope:record-observable-scope";
|
|
15
|
+
const ALLOWED_MINTED_VIA = new Set([DEFAULT_MINTED_VIA, "in-harness-ask"]);
|
|
14
16
|
function usage() {
|
|
15
17
|
return ("usage: scope:record-observable-scope -- <xbrief-path> --actor <name> --confirm " +
|
|
16
|
-
"[--kind operator] [--
|
|
18
|
+
"[--kind operator] [--minted-via in-harness-ask|scope:record-observable-scope] " +
|
|
19
|
+
"[--project-root <dir>] [--quiet]\n" +
|
|
17
20
|
' Writes .deft/observable-scope/<plan-id>.json from plan["x-directive/observableChange"].\n' +
|
|
18
|
-
"
|
|
19
|
-
"
|
|
21
|
+
" Attended mid-build (#5010): ask in parent chat; on yes the human runs this verb on a real TTY " +
|
|
22
|
+
"with --minted-via=in-harness-ask (attestation is not an agent-shell bypass). Commit the record on " +
|
|
23
|
+
"the delivery-branch merge base, then rebase the implementation branch — same-PR working-tree-only " +
|
|
24
|
+
"records are not authoritative. Unattended/C1: rewrite or park. --actor is display only. Mint still " +
|
|
25
|
+
"requires a real TTY, controlling terminal, --confirm, and typed phrase mint (#3110). Agent/CI shells refuse.");
|
|
20
26
|
}
|
|
21
27
|
function extractPlanId(payload) {
|
|
22
28
|
if (payload === null || typeof payload !== "object" || Array.isArray(payload))
|
|
@@ -33,6 +39,7 @@ export function parseArgs(argv) {
|
|
|
33
39
|
xbriefPath: "",
|
|
34
40
|
actor: "",
|
|
35
41
|
kind: "operator",
|
|
42
|
+
mintedVia: DEFAULT_MINTED_VIA,
|
|
36
43
|
quiet: false,
|
|
37
44
|
confirm: false,
|
|
38
45
|
};
|
|
@@ -77,6 +84,16 @@ export function parseArgs(argv) {
|
|
|
77
84
|
else if (arg?.startsWith("--kind=")) {
|
|
78
85
|
parsed.kind = arg.slice("--kind=".length);
|
|
79
86
|
}
|
|
87
|
+
else if (arg === "--minted-via") {
|
|
88
|
+
const value = argv[i + 1];
|
|
89
|
+
if (value === undefined)
|
|
90
|
+
return { ...parsed, error: "argument --minted-via: expected one argument" };
|
|
91
|
+
parsed.mintedVia = value;
|
|
92
|
+
i += 1;
|
|
93
|
+
}
|
|
94
|
+
else if (arg?.startsWith("--minted-via=")) {
|
|
95
|
+
parsed.mintedVia = arg.slice("--minted-via=".length);
|
|
96
|
+
}
|
|
80
97
|
else if (arg?.startsWith("-")) {
|
|
81
98
|
return { ...parsed, error: `unrecognized argument: ${arg}` };
|
|
82
99
|
}
|
|
@@ -98,6 +115,13 @@ export function parseArgs(argv) {
|
|
|
98
115
|
error: `argument --actor is required (human operator identity)\n${usage()}`,
|
|
99
116
|
};
|
|
100
117
|
}
|
|
118
|
+
if (!ALLOWED_MINTED_VIA.has(parsed.mintedVia.trim())) {
|
|
119
|
+
return {
|
|
120
|
+
...parsed,
|
|
121
|
+
error: `argument --minted-via must be one of: ${[...ALLOWED_MINTED_VIA].join(", ")}\n${usage()}`,
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
parsed.mintedVia = parsed.mintedVia.trim();
|
|
101
125
|
return parsed;
|
|
102
126
|
}
|
|
103
127
|
export function run(argv, seams = {}) {
|
|
@@ -161,7 +185,7 @@ export function run(argv, seams = {}) {
|
|
|
161
185
|
kind: args.kind,
|
|
162
186
|
actor: args.actor,
|
|
163
187
|
mintedAt: new Date().toISOString().replace(/\.\d{3}Z$/, "Z"),
|
|
164
|
-
mintedVia:
|
|
188
|
+
mintedVia: args.mintedVia,
|
|
165
189
|
},
|
|
166
190
|
});
|
|
167
191
|
if ("error" in rec) {
|
package/dist/session-start.d.ts
CHANGED
|
@@ -4,6 +4,8 @@ import { type PrimaryClaimException, type SessionCeremonyTier, type SessionPostu
|
|
|
4
4
|
export interface ParsedSessionStartArgs {
|
|
5
5
|
projectRoot: string;
|
|
6
6
|
deferValues: string[];
|
|
7
|
+
/** #4919: defer finalize-owed session gate with a recorded reason. */
|
|
8
|
+
deferOwedReason: string | null;
|
|
7
9
|
emitJson: boolean;
|
|
8
10
|
noHistory: boolean;
|
|
9
11
|
readOnly: boolean;
|
package/dist/session-start.js
CHANGED
|
@@ -30,6 +30,7 @@ export function parseArgs(argv) {
|
|
|
30
30
|
const parsed = {
|
|
31
31
|
projectRoot: ".",
|
|
32
32
|
deferValues: [],
|
|
33
|
+
deferOwedReason: null,
|
|
33
34
|
emitJson: false,
|
|
34
35
|
noHistory: false,
|
|
35
36
|
readOnly: false,
|
|
@@ -124,6 +125,21 @@ export function parseArgs(argv) {
|
|
|
124
125
|
}
|
|
125
126
|
parsed.deferValues.push(value);
|
|
126
127
|
}
|
|
128
|
+
else if (arg === "--defer-owed") {
|
|
129
|
+
const value = argv[i + 1];
|
|
130
|
+
if (value === undefined || value.startsWith("--")) {
|
|
131
|
+
return { ...parsed, error: "argument --defer-owed: expected one argument" };
|
|
132
|
+
}
|
|
133
|
+
parsed.deferOwedReason = value;
|
|
134
|
+
i += 1;
|
|
135
|
+
}
|
|
136
|
+
else if (arg?.startsWith("--defer-owed=")) {
|
|
137
|
+
const value = arg.slice("--defer-owed=".length);
|
|
138
|
+
if (value.length === 0 || value.startsWith("--")) {
|
|
139
|
+
return { ...parsed, error: "argument --defer-owed: expected one argument" };
|
|
140
|
+
}
|
|
141
|
+
parsed.deferOwedReason = value;
|
|
142
|
+
}
|
|
127
143
|
else if (arg === "--task-size" || arg === "--ceremony-task-size") {
|
|
128
144
|
const value = argv[i + 1];
|
|
129
145
|
if (value === undefined) {
|
|
@@ -487,6 +503,7 @@ export function run(argv) {
|
|
|
487
503
|
occupant: args.occupant ?? undefined,
|
|
488
504
|
primaryClaimException: args.primaryClaimException ?? undefined,
|
|
489
505
|
sessionId: args.sessionId ?? undefined,
|
|
506
|
+
deferOwedReason: args.deferOwedReason,
|
|
490
507
|
...(args.ceremonyDepthOverride !== null
|
|
491
508
|
? {
|
|
492
509
|
ceremonyDial: selectCeremonyDepth({
|