@deftai/directive 0.98.1 → 0.99.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -83,6 +83,7 @@ export const SUBCOMMAND_ROUTES = {
83
83
  "policy:allow-direct-commits": ["policy", "allow-direct-commits"],
84
84
  "policy:allow-bot-merge": ["policy", "allow-bot-merge"],
85
85
  "policy:enable-value-feedback": ["policy", "enable-value-feedback"],
86
+ "policy:set-ceremony-dial": ["policy", "set-ceremony-dial"],
86
87
  "policy:coverage-check-resume-preset": ["policy", "coverage-check-resume-preset"],
87
88
  "policy:coverage-check-resume-dismiss": ["policy", "coverage-check-resume-dismiss"],
88
89
  "policy:coverage-check-resume-later": ["policy", "coverage-check-resume-later"],
@@ -12,7 +12,7 @@ export interface DispatchIo {
12
12
  /** CLI modules in packages/cli/src (excluding parity harnesses and bin/index). */
13
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", "scope-lifecycle", "scope-record-approved-scope", "lifecycle-event", "lifecycle-stats", "session-start", "session-ready", "plan-sequence", "slice", "subagent-monitor", "toolchain-check", "triage-actions", "triage-bootstrap", "triage-bulk", "triage-classify", "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-content-manifest", "verify-skill-external-fetch-gate", "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", "rule-ownership-lint", "verify-story-ready", "verify-review-monitor", "verify-l4-owner", "verify-subagent-alive", "review-monitor-register", "review-monitor-release", "verify-tools", "verify-wip-cap", "verify-orphan-active", "verify-agents-md-budget", "verify-agents-md-advisory", "verify-eval-health-relocation", "verify-eval-triggers-relocation", "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-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", "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"];
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", "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"];
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
@@ -159,6 +159,7 @@ export const CORE_MODULE_VERBS = [
159
159
  "swarm-launch",
160
160
  "swarm-complete-cohort",
161
161
  "swarm-finalize-cohort",
162
+ "swarm-pre-dispatch",
162
163
  "swarm-readiness",
163
164
  "swarm-routing-verify",
164
165
  "swarm-routing-set",
@@ -191,6 +192,8 @@ export const CORE_MODULE_VERBS = [
191
192
  "value-readback",
192
193
  "product-signal",
193
194
  "freshness-report",
195
+ "decision-write",
196
+ "decision-list",
194
197
  ];
195
198
  /** Colon aliases for triage-actions (mirrors cli-router SUBCOMMAND_ROUTES). */
196
199
  export const TRIAGE_ACTION_ALIAS_SUBCOMMANDS = {
@@ -211,6 +214,7 @@ export const POLICY_ACTION_ALIAS_SUBCOMMANDS = {
211
214
  "policy:allow-direct-commits": "allow-direct-commits",
212
215
  "policy:allow-bot-merge": "allow-bot-merge",
213
216
  "policy:enable-value-feedback": "enable-value-feedback",
217
+ "policy:set-ceremony-dial": "set-ceremony-dial",
214
218
  "policy:clear-value-feedback": "clear-value-feedback",
215
219
  "policy:coverage-check-resume-preset": "coverage-check-resume-preset",
216
220
  "policy:coverage-check-resume-dismiss": "coverage-check-resume-dismiss",
@@ -360,6 +364,8 @@ export const VERB_ALIASES = {
360
364
  "feedback:file": "feedback-file",
361
365
  "value:show": "value-readback",
362
366
  "triage:metrics": "value-readback",
367
+ "decision:write": "decision-write",
368
+ "decision:list": "decision-list",
363
369
  "eval:run": "eval-run",
364
370
  "eval:triggers": "eval-triggers",
365
371
  "eval:report": "eval-report",
@@ -2340,6 +2346,10 @@ async function loadCoreModuleHandler(verb, io) {
2340
2346
  const { finalizeCohortMain } = await import("@deftai/directive-core/dist/swarm/finalize-cohort-cli.js");
2341
2347
  return finalizeCohortMain;
2342
2348
  }
2349
+ case "swarm-pre-dispatch": {
2350
+ const { preDispatchMain } = await import("@deftai/directive-core/dist/swarm/pre-dispatch-cli.js");
2351
+ return preDispatchMain;
2352
+ }
2343
2353
  case "swarm-readiness": {
2344
2354
  const { readinessMain } = await import("@deftai/directive-core/dist/swarm/readiness-cli.js");
2345
2355
  return readinessMain;
@@ -2470,6 +2480,14 @@ async function loadCoreModuleHandler(verb, io) {
2470
2480
  const { mainEntry } = await import("@deftai/directive-core/dist/freshness/cli.js");
2471
2481
  return mainEntry;
2472
2482
  }
2483
+ case "decision-write": {
2484
+ const { writeMainEntry } = await import("@deftai/directive-core/dist/decision/index.js");
2485
+ return writeMainEntry;
2486
+ }
2487
+ case "decision-list": {
2488
+ const { listMainEntry } = await import("@deftai/directive-core/dist/decision/index.js");
2489
+ return listMainEntry;
2490
+ }
2473
2491
  default:
2474
2492
  throw new Error(`unknown core verb: ${verb}`);
2475
2493
  }
package/dist/policy.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env node
2
+ import { type CeremonyDepth } from "@deftai/directive-core/policy";
2
3
  interface ShowArgs {
3
4
  format: "text" | "json";
4
5
  changedOnly: boolean;
@@ -7,7 +8,7 @@ interface ShowArgs {
7
8
  error?: string;
8
9
  }
9
10
  interface SetArgs {
10
- cmd: "show" | "enforce-branches" | "allow-direct-commits" | "allow-bot-merge" | "enable-value-feedback" | "clear-value-feedback" | "coverage-check-resume-preset" | "coverage-check-resume-dismiss" | "coverage-check-resume-later" | "disable-directive" | "enable-directive" | "resolve";
11
+ cmd: "show" | "enforce-branches" | "allow-direct-commits" | "allow-bot-merge" | "enable-value-feedback" | "clear-value-feedback" | "set-ceremony-dial" | "coverage-check-resume-preset" | "coverage-check-resume-dismiss" | "coverage-check-resume-later" | "disable-directive" | "enable-directive" | "resolve";
11
12
  confirm: boolean;
12
13
  actor: string;
13
14
  note: string;
@@ -18,6 +19,10 @@ interface SetArgs {
18
19
  /** Strict | hatch-aware for coverage-check-resume-preset; reason for dismiss. */
19
20
  preset?: string;
20
21
  reason?: string;
22
+ /** #3214 ceremony dial override depth for set-ceremony-dial. */
23
+ ceremonyOverride?: CeremonyDepth | null;
24
+ /** #3214 ceremony dial enabled flag for set-ceremony-dial. */
25
+ ceremonyEnabled?: boolean;
21
26
  error?: string;
22
27
  }
23
28
  /** Parse policy:show flags (mirrors _policy_show_cli.py). */
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, applyHatchAwareCoverageCheckResumePreset, applyLaterCoverageCheckResumeSkip, applyStrictCoverageCheckResumePreset, clearValueFeedback, createNoDeftDirectiveFlag, describeShadowedPlanExtension, detectNoDeftDirective, detectShadowedPlanExtensions, disclosureLine, dismissCoverageCheckResume, 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, policyColonInvocation, projectDefinitionPath, pythonListRepr, pythonStringRepr, registeredPolicyNames, removeNoDeftDirectiveFlag, renderJson, renderText, resolveHumanMergePolicy, resolvePolicy, resolveValueFeedback, setPolicy, setRequireHumanMerge, } from "@deftai/directive-core/policy";
9
+ import { ALLOW_BOT_MERGE_CAPABILITY_COST, applyHatchAwareCoverageCheckResumePreset, applyLaterCoverageCheckResumeSkip, applyStrictCoverageCheckResumePreset, CEREMONY_DEPTHS, clearValueFeedback, createNoDeftDirectiveFlag, describeShadowedPlanExtension, detectNoDeftDirective, detectShadowedPlanExtensions, disclosureLine, dismissCoverageCheckResume, 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, policyColonInvocation, projectDefinitionPath, pythonListRepr, pythonStringRepr, registeredPolicyNames, removeNoDeftDirectiveFlag, renderJson, renderText, resolveHumanMergePolicy, resolvePolicy, resolveValueFeedback, 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|coverage-check-resume-preset|coverage-check-resume-dismiss|coverage-check-resume-later|disable-directive|enable-directive|resolve] ...";
117
+ const usage = "usage: policy [show|enforce-branches|allow-direct-commits|allow-bot-merge|enable-value-feedback|clear-value-feedback|set-ceremony-dial|coverage-check-resume-preset|coverage-check-resume-dismiss|coverage-check-resume-later|disable-directive|enable-directive|resolve] ...";
118
118
  return makeSetError(usage);
119
119
  }
120
120
  const cmd = argv[0];
@@ -151,6 +151,7 @@ export function parseArgs(argv) {
151
151
  cmd === "allow-bot-merge" ||
152
152
  cmd === "enable-value-feedback" ||
153
153
  cmd === "clear-value-feedback" ||
154
+ cmd === "set-ceremony-dial" ||
154
155
  cmd === "coverage-check-resume-preset" ||
155
156
  cmd === "coverage-check-resume-dismiss" ||
156
157
  cmd === "coverage-check-resume-later" ||
@@ -167,19 +168,23 @@ export function parseArgs(argv) {
167
168
  ? policyColonInvocation("enable-value-feedback")
168
169
  : cmd === "clear-value-feedback"
169
170
  ? policyColonInvocation("clear-value-feedback")
170
- : cmd === "coverage-check-resume-preset"
171
- ? policyColonInvocation("coverage-check-resume-preset")
172
- : cmd === "coverage-check-resume-dismiss"
173
- ? policyColonInvocation("coverage-check-resume-dismiss")
174
- : cmd === "coverage-check-resume-later"
175
- ? policyColonInvocation("coverage-check-resume-later")
176
- : cmd === "disable-directive"
177
- ? policyColonInvocation("disable-directive")
178
- : policyColonInvocation("enable-directive");
171
+ : cmd === "set-ceremony-dial"
172
+ ? policyColonInvocation("set-ceremony-dial")
173
+ : cmd === "coverage-check-resume-preset"
174
+ ? policyColonInvocation("coverage-check-resume-preset")
175
+ : cmd === "coverage-check-resume-dismiss"
176
+ ? policyColonInvocation("coverage-check-resume-dismiss")
177
+ : cmd === "coverage-check-resume-later"
178
+ ? policyColonInvocation("coverage-check-resume-later")
179
+ : cmd === "disable-directive"
180
+ ? policyColonInvocation("disable-directive")
181
+ : policyColonInvocation("enable-directive");
179
182
  let note = "";
180
183
  let projectRoot = ".";
181
184
  let preset = "";
182
185
  let reason = "";
186
+ let ceremonyOverride;
187
+ let ceremonyEnabled;
183
188
  for (let i = 1; i < argv.length; i += 1) {
184
189
  const arg = argv[i];
185
190
  if (arg === "--confirm") {
@@ -239,6 +244,50 @@ export function parseArgs(argv) {
239
244
  (arg === "strict" || arg === "hatch-aware")) {
240
245
  preset = arg;
241
246
  }
247
+ else if (cmd === "set-ceremony-dial" && (arg === "--override" || arg === "--depth")) {
248
+ const v = argv[i + 1];
249
+ if (v === undefined) {
250
+ return makeSetError(`argument ${arg}: expected one argument (minimal|rapid|standard|elevated|null)`);
251
+ }
252
+ if (v === "null" || v === "none" || v === "clear") {
253
+ ceremonyOverride = null;
254
+ }
255
+ else if (CEREMONY_DEPTHS.includes(v)) {
256
+ ceremonyOverride = v;
257
+ }
258
+ else {
259
+ return makeSetError(`argument ${arg}: expected minimal|rapid|standard|elevated|null, got ${JSON.stringify(v)}`);
260
+ }
261
+ i += 1;
262
+ }
263
+ else if (cmd === "set-ceremony-dial" &&
264
+ (arg?.startsWith("--override=") || arg?.startsWith("--depth="))) {
265
+ const v = arg.slice(arg.indexOf("=") + 1);
266
+ if (v === "null" || v === "none" || v === "clear") {
267
+ ceremonyOverride = null;
268
+ }
269
+ else if (CEREMONY_DEPTHS.includes(v)) {
270
+ ceremonyOverride = v;
271
+ }
272
+ else {
273
+ return makeSetError(`argument --override: expected minimal|rapid|standard|elevated|null, got ${JSON.stringify(v)}`);
274
+ }
275
+ }
276
+ else if (cmd === "set-ceremony-dial" && arg === "--enabled") {
277
+ const v = argv[i + 1];
278
+ if (v === undefined || (v !== "true" && v !== "false")) {
279
+ return makeSetError("argument --enabled: expected true|false");
280
+ }
281
+ ceremonyEnabled = v === "true";
282
+ i += 1;
283
+ }
284
+ else if (cmd === "set-ceremony-dial" && arg?.startsWith("--enabled=")) {
285
+ const v = arg.slice("--enabled=".length);
286
+ if (v !== "true" && v !== "false") {
287
+ return makeSetError("argument --enabled: expected true|false");
288
+ }
289
+ ceremonyEnabled = v === "true";
290
+ }
242
291
  else {
243
292
  return makeSetError(`unrecognized argument: ${arg}`);
244
293
  }
@@ -254,6 +303,8 @@ export function parseArgs(argv) {
254
303
  field: null,
255
304
  preset,
256
305
  reason,
306
+ ceremonyOverride,
307
+ ceremonyEnabled,
257
308
  };
258
309
  }
259
310
  return makeSetError(`unknown subcommand: ${cmd}`);
@@ -493,6 +544,9 @@ export function run(argv) {
493
544
  if (args.cmd === "clear-value-feedback") {
494
545
  return runClearValueFeedback(args);
495
546
  }
547
+ if (args.cmd === "set-ceremony-dial") {
548
+ return runSetCeremonyDial(args);
549
+ }
496
550
  if (args.cmd === "coverage-check-resume-preset") {
497
551
  return runCoverageCheckResumePreset(args);
498
552
  }
@@ -546,6 +600,24 @@ function runCoverageCheckResumeLater() {
546
600
  process.stdout.write(result.stdout);
547
601
  return result.exitCode;
548
602
  }
603
+ /** Persist plan.policy.ceremonyDial override/enabled (#3214). */
604
+ function runSetCeremonyDial(args) {
605
+ const root = pathResolve(args.projectRoot);
606
+ if (args.ceremonyOverride === undefined && args.ceremonyEnabled === undefined) {
607
+ process.stdout.write("usage: policy set-ceremony-dial -- --confirm [--override minimal|rapid|standard|elevated|null] [--enabled true|false] [--project-root PATH]\n" +
608
+ ` Inspect: ${policyColonInvocation("show", " --field=ceremonyDial")}\n`);
609
+ return 1;
610
+ }
611
+ const result = setCeremonyDial(root, {
612
+ confirm: args.confirm,
613
+ actor: args.actor,
614
+ note: args.note,
615
+ ...(args.ceremonyOverride !== undefined ? { override: args.ceremonyOverride } : {}),
616
+ ...(args.ceremonyEnabled !== undefined ? { enabled: args.ceremonyEnabled } : {}),
617
+ });
618
+ process.stdout.write(result.stdout);
619
+ return result.exitCode;
620
+ }
549
621
  if (process.argv[1] !== undefined && fileURLToPath(import.meta.url) === process.argv[1]) {
550
622
  process.exit(run(process.argv.slice(2)));
551
623
  }
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env node
2
+ import { type CeremonyDepth, type CeremonyDialInputs } from "@deftai/directive-core/policy";
2
3
  import { type SessionCeremonyTier } from "@deftai/directive-core/session";
3
4
  export interface ParsedSessionStartArgs {
4
5
  projectRoot: string;
@@ -10,6 +11,13 @@ export interface ParsedSessionStartArgs {
10
11
  withNetwork: boolean;
11
12
  /** #2992: cold (full) vs rearm (clock/HEAD refresh without fat path). */
12
13
  ceremonyTier: SessionCeremonyTier;
14
+ /** #3214: optional dial inputs for ritual-depth selection. */
15
+ ceremonyDialInputs: CeremonyDialInputs;
16
+ /**
17
+ * #3214: force depth for this session only (does not persist policy).
18
+ * Applied as resolve inputs via a one-shot config override in run().
19
+ */
20
+ ceremonyDepthOverride: CeremonyDepth | null;
13
21
  error?: string;
14
22
  }
15
23
  /** Parse session:start CLI args, mirroring scripts/session_start.py. */
@@ -1,7 +1,15 @@
1
1
  #!/usr/bin/env node
2
2
  import { resolve } from "node:path";
3
3
  import { fileURLToPath } from "node:url";
4
+ import { CEREMONY_DEPTHS, normalizeCeremonyModelTier, normalizeCeremonyProjectShape, normalizeCeremonyTaskSize, selectCeremonyDepth, } from "@deftai/directive-core/policy";
4
5
  import { COLD_CEREMONY_TIER, parseDeferrals, READ_ONLY_POSTURE, REARM_CEREMONY_TIER, ritualStatePath, runSessionStart, SESSION_CEREMONY_TIERS, } from "@deftai/directive-core/session";
6
+ function parseCeremonyDepth(raw) {
7
+ const value = raw.trim().toLowerCase();
8
+ if (CEREMONY_DEPTHS.includes(value)) {
9
+ return value;
10
+ }
11
+ return null;
12
+ }
5
13
  function parseCeremonyTier(raw) {
6
14
  const value = raw.trim().toLowerCase();
7
15
  if (SESSION_CEREMONY_TIERS.includes(value)) {
@@ -19,7 +27,10 @@ export function parseArgs(argv) {
19
27
  readOnly: false,
20
28
  withNetwork: false,
21
29
  ceremonyTier: COLD_CEREMONY_TIER,
30
+ ceremonyDialInputs: {},
31
+ ceremonyDepthOverride: null,
22
32
  };
33
+ const dialInputs = {};
23
34
  for (let i = 0; i < argv.length; i += 1) {
24
35
  const arg = argv[i];
25
36
  if (arg === "--json") {
@@ -86,10 +97,129 @@ export function parseArgs(argv) {
86
97
  else if (arg?.startsWith("--defer=")) {
87
98
  parsed.deferValues.push(arg.slice("--defer=".length));
88
99
  }
100
+ else if (arg === "--task-size" || arg === "--ceremony-task-size") {
101
+ const value = argv[i + 1];
102
+ if (value === undefined) {
103
+ return { ...parsed, error: `argument ${arg}: expected one argument (S|M|L|XL)` };
104
+ }
105
+ const size = normalizeCeremonyTaskSize(value);
106
+ if (size === null) {
107
+ return {
108
+ ...parsed,
109
+ error: `argument ${arg}: expected S|M|L|XL (or small|medium|large), got ${JSON.stringify(value)}`,
110
+ };
111
+ }
112
+ dialInputs.taskSize = size;
113
+ i += 1;
114
+ }
115
+ else if (arg?.startsWith("--task-size=") || arg?.startsWith("--ceremony-task-size=")) {
116
+ const value = arg.slice(arg.indexOf("=") + 1);
117
+ const size = normalizeCeremonyTaskSize(value);
118
+ if (size === null) {
119
+ return {
120
+ ...parsed,
121
+ error: `argument --task-size: expected S|M|L|XL, got ${JSON.stringify(value)}`,
122
+ };
123
+ }
124
+ dialInputs.taskSize = size;
125
+ }
126
+ else if (arg === "--model-tier" || arg === "--ceremony-model-tier") {
127
+ const value = argv[i + 1];
128
+ if (value === undefined) {
129
+ return {
130
+ ...parsed,
131
+ error: `argument ${arg}: expected one argument (frontier|mid|low)`,
132
+ };
133
+ }
134
+ const tier = normalizeCeremonyModelTier(value);
135
+ if (tier === null) {
136
+ return {
137
+ ...parsed,
138
+ error: `argument ${arg}: expected frontier|mid|low, got ${JSON.stringify(value)}`,
139
+ };
140
+ }
141
+ dialInputs.modelTier = tier;
142
+ i += 1;
143
+ }
144
+ else if (arg?.startsWith("--model-tier=") || arg?.startsWith("--ceremony-model-tier=")) {
145
+ const value = arg.slice(arg.indexOf("=") + 1);
146
+ const tier = normalizeCeremonyModelTier(value);
147
+ if (tier === null) {
148
+ return {
149
+ ...parsed,
150
+ error: `argument --model-tier: expected frontier|mid|low, got ${JSON.stringify(value)}`,
151
+ };
152
+ }
153
+ dialInputs.modelTier = tier;
154
+ }
155
+ else if (arg === "--project-shape" || arg === "--ceremony-project-shape") {
156
+ const value = argv[i + 1];
157
+ if (value === undefined) {
158
+ return {
159
+ ...parsed,
160
+ error: `argument ${arg}: expected one argument (project|non-project)`,
161
+ };
162
+ }
163
+ const shape = normalizeCeremonyProjectShape(value);
164
+ if (shape === null) {
165
+ return {
166
+ ...parsed,
167
+ error: `argument ${arg}: expected project|non-project, got ${JSON.stringify(value)}`,
168
+ };
169
+ }
170
+ dialInputs.projectShape = shape;
171
+ i += 1;
172
+ }
173
+ else if (arg?.startsWith("--project-shape=") ||
174
+ arg?.startsWith("--ceremony-project-shape=")) {
175
+ const value = arg.slice(arg.indexOf("=") + 1);
176
+ const shape = normalizeCeremonyProjectShape(value);
177
+ if (shape === null) {
178
+ return {
179
+ ...parsed,
180
+ error: `argument --project-shape: expected project|non-project, got ${JSON.stringify(value)}`,
181
+ };
182
+ }
183
+ dialInputs.projectShape = shape;
184
+ }
185
+ else if (arg === "--ceremony-depth") {
186
+ const value = argv[i + 1];
187
+ if (value === undefined) {
188
+ return {
189
+ ...parsed,
190
+ error: "argument --ceremony-depth: expected one argument (minimal|rapid|standard|elevated)",
191
+ };
192
+ }
193
+ const depth = parseCeremonyDepth(value);
194
+ if (depth === null) {
195
+ return {
196
+ ...parsed,
197
+ error: `argument --ceremony-depth: expected minimal|rapid|standard|elevated, got ${JSON.stringify(value)}`,
198
+ };
199
+ }
200
+ parsed.ceremonyDepthOverride = depth;
201
+ i += 1;
202
+ }
203
+ else if (arg?.startsWith("--ceremony-depth=")) {
204
+ const value = arg.slice("--ceremony-depth=".length);
205
+ const depth = parseCeremonyDepth(value);
206
+ if (depth === null) {
207
+ return {
208
+ ...parsed,
209
+ error: `argument --ceremony-depth: expected minimal|rapid|standard|elevated, got ${JSON.stringify(value)}`,
210
+ };
211
+ }
212
+ parsed.ceremonyDepthOverride = depth;
213
+ }
89
214
  else {
90
215
  return { ...parsed, error: `unrecognized argument: ${arg}` };
91
216
  }
92
217
  }
218
+ parsed.ceremonyDialInputs = {
219
+ taskSize: dialInputs.taskSize ?? null,
220
+ modelTier: dialInputs.modelTier ?? null,
221
+ projectShape: dialInputs.projectShape ?? null,
222
+ };
93
223
  return parsed;
94
224
  }
95
225
  /** Native session:start handler (#2032 — replaces framework-commands Python bridge). */
@@ -119,12 +249,22 @@ export function run(argv) {
119
249
  });
120
250
  let result;
121
251
  try {
252
+ // #3214: --ceremony-depth forces this session only (not persisted to policy).
122
253
  result = runSessionStart(projectRoot, {
123
254
  deferrals,
124
255
  writeHistory: !args.noHistory,
125
256
  posture: args.readOnly ? READ_ONLY_POSTURE : undefined,
126
257
  allowOptionalNetwork: args.withNetwork ? true : undefined,
127
258
  ceremonyTier: args.ceremonyTier,
259
+ ceremonyDialInputs: args.ceremonyDialInputs,
260
+ ...(args.ceremonyDepthOverride !== null
261
+ ? {
262
+ ceremonyDial: selectCeremonyDepth({
263
+ config: { enabled: true, override: args.ceremonyDepthOverride },
264
+ inputs: args.ceremonyDialInputs,
265
+ }),
266
+ }
267
+ : {}),
128
268
  });
129
269
  }
130
270
  finally {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@deftai/directive",
3
- "version": "0.98.1",
3
+ "version": "0.99.0",
4
4
  "description": "Directive CLI — npm install path for the Deft Directive framework.",
5
5
  "license": "MIT",
6
6
  "homepage": "https://deftai.github.io/directive/",
@@ -34,8 +34,8 @@
34
34
  "provenance": true
35
35
  },
36
36
  "dependencies": {
37
- "@deftai/directive-core": "^0.98.1",
38
- "@deftai/directive-content": "^0.98.1"
37
+ "@deftai/directive-core": "^0.99.0",
38
+ "@deftai/directive-content": "^0.99.0"
39
39
  },
40
40
  "scripts": {
41
41
  "build": "tsc -b"