@workflow-cannon/workspace-kit 0.7.0 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (74) hide show
  1. package/README.md +5 -4
  2. package/dist/cli/run-command.d.ts +11 -0
  3. package/dist/cli/run-command.js +138 -0
  4. package/dist/cli.js +18 -135
  5. package/dist/contracts/index.d.ts +1 -1
  6. package/dist/contracts/module-contract.d.ts +13 -0
  7. package/dist/core/config-cli.js +4 -4
  8. package/dist/core/config-metadata.js +199 -5
  9. package/dist/core/index.d.ts +6 -0
  10. package/dist/core/index.js +6 -0
  11. package/dist/core/instruction-template-mapper.d.ts +9 -0
  12. package/dist/core/instruction-template-mapper.js +35 -0
  13. package/dist/core/lineage-contract.d.ts +1 -1
  14. package/dist/core/lineage-contract.js +1 -1
  15. package/dist/core/policy.d.ts +13 -2
  16. package/dist/core/policy.js +42 -25
  17. package/dist/core/response-template-contract.d.ts +15 -0
  18. package/dist/core/response-template-contract.js +10 -0
  19. package/dist/core/response-template-registry.d.ts +4 -0
  20. package/dist/core/response-template-registry.js +44 -0
  21. package/dist/core/response-template-shaping.d.ts +6 -0
  22. package/dist/core/response-template-shaping.js +128 -0
  23. package/dist/core/session-policy.d.ts +18 -0
  24. package/dist/core/session-policy.js +57 -0
  25. package/dist/core/transcript-completion-hook.d.ts +7 -0
  26. package/dist/core/transcript-completion-hook.js +128 -0
  27. package/dist/core/workspace-kit-config.d.ts +2 -1
  28. package/dist/core/workspace-kit-config.js +19 -23
  29. package/dist/modules/approvals/index.js +2 -2
  30. package/dist/modules/documentation/runtime.js +413 -20
  31. package/dist/modules/improvement/generate-recommendations-runtime.d.ts +7 -0
  32. package/dist/modules/improvement/generate-recommendations-runtime.js +37 -4
  33. package/dist/modules/improvement/improvement-state.d.ts +10 -1
  34. package/dist/modules/improvement/improvement-state.js +36 -7
  35. package/dist/modules/improvement/index.js +70 -23
  36. package/dist/modules/improvement/ingest.js +2 -1
  37. package/dist/modules/improvement/transcript-redaction.d.ts +4 -0
  38. package/dist/modules/improvement/transcript-redaction.js +10 -0
  39. package/dist/modules/improvement/transcript-sync-runtime.d.ts +42 -1
  40. package/dist/modules/improvement/transcript-sync-runtime.js +215 -9
  41. package/dist/modules/index.d.ts +1 -1
  42. package/dist/modules/index.js +1 -1
  43. package/dist/modules/task-engine/index.d.ts +0 -2
  44. package/dist/modules/task-engine/index.js +4 -78
  45. package/package.json +6 -2
  46. package/src/modules/documentation/README.md +39 -0
  47. package/src/modules/documentation/RULES.md +70 -0
  48. package/src/modules/documentation/config.md +14 -0
  49. package/src/modules/documentation/index.ts +120 -0
  50. package/src/modules/documentation/instructions/document-project.md +44 -0
  51. package/src/modules/documentation/instructions/documentation-maintainer.md +81 -0
  52. package/src/modules/documentation/instructions/generate-document.md +44 -0
  53. package/src/modules/documentation/runtime.ts +870 -0
  54. package/src/modules/documentation/schemas/documentation-schema.md +54 -0
  55. package/src/modules/documentation/state.md +8 -0
  56. package/src/modules/documentation/templates/AGENTS.md +84 -0
  57. package/src/modules/documentation/templates/ARCHITECTURE.md +71 -0
  58. package/src/modules/documentation/templates/PRINCIPLES.md +122 -0
  59. package/src/modules/documentation/templates/RELEASING.md +96 -0
  60. package/src/modules/documentation/templates/ROADMAP.md +131 -0
  61. package/src/modules/documentation/templates/SECURITY.md +53 -0
  62. package/src/modules/documentation/templates/SUPPORT.md +40 -0
  63. package/src/modules/documentation/templates/TERMS.md +61 -0
  64. package/src/modules/documentation/templates/runbooks/consumer-cadence.md +55 -0
  65. package/src/modules/documentation/templates/runbooks/parity-validation-flow.md +68 -0
  66. package/src/modules/documentation/templates/runbooks/release-channels.md +30 -0
  67. package/src/modules/documentation/templates/workbooks/phase2-config-policy-workbook.md +42 -0
  68. package/src/modules/documentation/templates/workbooks/task-engine-workbook.md +42 -0
  69. package/src/modules/documentation/templates/workbooks/transcript-automation-baseline.md +68 -0
  70. package/src/modules/documentation/types.ts +51 -0
  71. package/dist/modules/task-engine/generator.d.ts +0 -3
  72. package/dist/modules/task-engine/generator.js +0 -118
  73. package/dist/modules/task-engine/importer.d.ts +0 -8
  74. package/dist/modules/task-engine/importer.js +0 -163
package/README.md CHANGED
@@ -62,7 +62,7 @@ This keeps automation adaptive without sacrificing safety, governance, or develo
62
62
  ## Current Status
63
63
 
64
64
  - **Phase 0** and **Phase 1** (task engine, `v0.3.0`) are complete.
65
- - **Phase 2** (layered config, policy gates, cutover docs, `v0.4.0`) is complete in-repo; see `docs/maintainers/TASKS.md` and `docs/maintainers/ROADMAP.md`.
65
+ - **Phase 2** (layered config, policy gates, cutover docs, `v0.4.0`) is complete in-repo; see `.workspace-kit/tasks/state.json` and `docs/maintainers/ROADMAP.md`.
66
66
  - **Phase 2b** (policy + config UX, `v0.4.1`) and **Phase 3** (enhancement loop MVP, `v0.5.0`) are complete in-repo: evidence-driven **improvement** tasks, **`approvals`** (`review-item`), heuristic confidence, and append-only lineage.
67
67
  - **Phase 4** (`v0.6.0`) is complete in-repo: compatibility matrix/gates, diagnostics/SLO baseline evidence, release-channel mapping, and planning-doc consistency checks.
68
68
 
@@ -87,7 +87,7 @@ npm install @workflow-cannon/workspace-kit
87
87
  - `README.md` - project entry point
88
88
  - `.ai/PRINCIPLES.md` - project goals and decision principles (canonical AI)
89
89
  - `docs/maintainers/ROADMAP.md` - roadmap and decision log
90
- - `docs/maintainers/TASKS.md` - execution tracking
90
+ - `.workspace-kit/tasks/state.json` - execution tracking
91
91
  - `docs/maintainers/ARCHITECTURE.md` - architecture direction
92
92
  - `docs/maintainers/DECISIONS.md` - focused design/decision notes
93
93
  - `docs/maintainers/RELEASING.md` - release checklist and validation expectations
@@ -100,12 +100,13 @@ npm install @workflow-cannon/workspace-kit
100
100
 
101
101
  - Project goals and decision principles: `.ai/PRINCIPLES.md`
102
102
  - Strategy and long-range direction: `docs/maintainers/ROADMAP.md`
103
- - Active execution tasks: `docs/maintainers/TASKS.md`
103
+ - Active execution tasks: `.workspace-kit/tasks/state.json`
104
104
  - Glossary and agent-guidance terms: `docs/maintainers/TERMS.md`
105
105
  - Architecture direction: `docs/maintainers/ARCHITECTURE.md`
106
106
  - Project decisions: `docs/maintainers/DECISIONS.md`
107
- - Contribution guidelines: `docs/maintainers/CONTRIBUTING.md`
107
+ - Governance policy surface: `docs/maintainers/GOVERNANCE.md`
108
108
  - Release process and gates: `docs/maintainers/RELEASING.md`
109
+ - Canonical changelog: `docs/maintainers/CHANGELOG.md` (`CHANGELOG.md` at repo root is pointer-only)
109
110
  - Canonical AI module build guidance: `.ai/module-build.md`
110
111
  - Human module build guide: `docs/maintainers/module-build-guide.md`
111
112
  - Security, support, and governance: `docs/maintainers/SECURITY.md`, `docs/maintainers/SUPPORT.md`, `docs/maintainers/GOVERNANCE.md`
@@ -0,0 +1,11 @@
1
+ export type RunCommandIo = {
2
+ writeLine: (message: string) => void;
3
+ writeError: (message: string) => void;
4
+ };
5
+ export type RunCommandExitCodes = {
6
+ success: number;
7
+ validationFailure: number;
8
+ usageError: number;
9
+ internalError: number;
10
+ };
11
+ export declare function handleRunCommand(cwd: string, args: string[], io: RunCommandIo, codes: RunCommandExitCodes): Promise<number>;
@@ -0,0 +1,138 @@
1
+ import { ModuleRegistry } from "../core/module-registry.js";
2
+ import { ModuleCommandRouter } from "../core/module-command-router.js";
3
+ import { appendPolicyTrace, isSensitiveModuleCommandForEffective, parsePolicyApproval, resolveActorWithFallback, resolvePolicyOperationIdForCommand } from "../core/policy.js";
4
+ import { getSessionGrant, recordSessionGrant, resolveSessionId } from "../core/session-policy.js";
5
+ import { applyResponseTemplateApplication } from "../core/response-template-shaping.js";
6
+ import { resolveWorkspaceConfigWithLayers } from "../core/workspace-kit-config.js";
7
+ import { documentationModule } from "../modules/documentation/index.js";
8
+ import { taskEngineModule } from "../modules/task-engine/index.js";
9
+ import { approvalsModule } from "../modules/approvals/index.js";
10
+ import { planningModule } from "../modules/planning/index.js";
11
+ import { improvementModule } from "../modules/improvement/index.js";
12
+ import { workspaceConfigModule } from "../modules/workspace-config/index.js";
13
+ export async function handleRunCommand(cwd, args, io, codes) {
14
+ const { writeLine, writeError } = io;
15
+ const allModules = [
16
+ workspaceConfigModule,
17
+ documentationModule,
18
+ taskEngineModule,
19
+ approvalsModule,
20
+ planningModule,
21
+ improvementModule
22
+ ];
23
+ const registry = new ModuleRegistry(allModules);
24
+ const router = new ModuleCommandRouter(registry);
25
+ const subcommand = args[1];
26
+ if (!subcommand) {
27
+ const commands = router.listCommands();
28
+ writeLine("Available module commands:");
29
+ for (const cmd of commands) {
30
+ const desc = cmd.description ? ` — ${cmd.description}` : "";
31
+ writeLine(` ${cmd.name} (${cmd.moduleId})${desc}`);
32
+ }
33
+ writeLine("");
34
+ writeLine("Usage: workspace-kit run <command> [json-args]");
35
+ return codes.success;
36
+ }
37
+ let commandArgs = {};
38
+ if (args[2]) {
39
+ try {
40
+ const parsed = JSON.parse(args[2]);
41
+ if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
42
+ commandArgs = parsed;
43
+ }
44
+ else {
45
+ writeError("Command args must be a JSON object.");
46
+ return codes.usageError;
47
+ }
48
+ }
49
+ catch {
50
+ writeError(`Invalid JSON args: ${args[2]}`);
51
+ return codes.usageError;
52
+ }
53
+ }
54
+ const invocationConfig = typeof commandArgs.config === "object" &&
55
+ commandArgs.config !== null &&
56
+ !Array.isArray(commandArgs.config)
57
+ ? commandArgs.config
58
+ : {};
59
+ let effective;
60
+ try {
61
+ const resolved = await resolveWorkspaceConfigWithLayers({
62
+ workspacePath: cwd,
63
+ registry,
64
+ invocationConfig
65
+ });
66
+ effective = resolved.effective;
67
+ }
68
+ catch (err) {
69
+ const message = err instanceof Error ? err.message : String(err);
70
+ writeError(`Config resolution failed: ${message}`);
71
+ return codes.validationFailure;
72
+ }
73
+ const actor = await resolveActorWithFallback(cwd, commandArgs, process.env);
74
+ const sensitive = isSensitiveModuleCommandForEffective(subcommand, commandArgs, effective);
75
+ const sessionId = resolveSessionId(process.env);
76
+ const policyOp = resolvePolicyOperationIdForCommand(subcommand, effective);
77
+ const explicitPolicyApproval = parsePolicyApproval(commandArgs);
78
+ let resolvedSensitiveApproval = explicitPolicyApproval;
79
+ if (sensitive) {
80
+ if (!resolvedSensitiveApproval && policyOp) {
81
+ const grant = await getSessionGrant(cwd, policyOp, sessionId);
82
+ if (grant) {
83
+ resolvedSensitiveApproval = { confirmed: true, rationale: grant.rationale };
84
+ }
85
+ }
86
+ if (!resolvedSensitiveApproval) {
87
+ if (policyOp) {
88
+ await appendPolicyTrace(cwd, {
89
+ timestamp: new Date().toISOString(),
90
+ operationId: policyOp,
91
+ command: `run ${subcommand}`,
92
+ actor,
93
+ allowed: false,
94
+ message: "missing policyApproval in JSON args"
95
+ });
96
+ }
97
+ writeLine(JSON.stringify({
98
+ ok: false,
99
+ code: "policy-denied",
100
+ message: 'Sensitive command requires policyApproval in JSON args (or an existing session grant for this operation): {"policyApproval":{"confirmed":true,"rationale":"why","scope":"session"}}'
101
+ }, null, 2));
102
+ return codes.validationFailure;
103
+ }
104
+ }
105
+ const ctx = {
106
+ runtimeVersion: "0.1",
107
+ workspacePath: cwd,
108
+ effectiveConfig: effective,
109
+ resolvedActor: actor,
110
+ moduleRegistry: registry
111
+ };
112
+ try {
113
+ const rawResult = await router.execute(subcommand, commandArgs, ctx);
114
+ if (sensitive && resolvedSensitiveApproval && policyOp) {
115
+ await appendPolicyTrace(cwd, {
116
+ timestamp: new Date().toISOString(),
117
+ operationId: policyOp,
118
+ command: `run ${subcommand}`,
119
+ actor,
120
+ allowed: true,
121
+ rationale: resolvedSensitiveApproval.rationale,
122
+ commandOk: rawResult.ok,
123
+ message: rawResult.message
124
+ });
125
+ if (explicitPolicyApproval?.scope === "session" && rawResult.ok) {
126
+ await recordSessionGrant(cwd, policyOp, sessionId, explicitPolicyApproval.rationale);
127
+ }
128
+ }
129
+ const result = applyResponseTemplateApplication(subcommand, commandArgs, rawResult, effective);
130
+ writeLine(JSON.stringify(result, null, 2));
131
+ return result.ok ? codes.success : codes.validationFailure;
132
+ }
133
+ catch (error) {
134
+ const message = error instanceof Error ? error.message : String(error);
135
+ writeError(`Module command failed: ${message}`);
136
+ return codes.internalError;
137
+ }
138
+ }
package/dist/cli.js CHANGED
@@ -2,21 +2,14 @@
2
2
  import fs from "node:fs/promises";
3
3
  import path from "node:path";
4
4
  import { pathToFileURL } from "node:url";
5
- import { ModuleRegistry } from "./core/module-registry.js";
6
- import { ModuleCommandRouter } from "./core/module-command-router.js";
7
- import { appendPolicyTrace, isSensitiveModuleCommandForEffective, parsePolicyApproval, parsePolicyApprovalFromEnv, resolveActor, resolvePolicyOperationIdForCommand } from "./core/policy.js";
5
+ import { appendPolicyTrace, parsePolicyApprovalFromEnv, resolveActorWithFallback } from "./core/policy.js";
8
6
  import { runWorkspaceConfigCli } from "./core/config-cli.js";
9
- import { resolveWorkspaceConfigWithLayers } from "./core/workspace-kit-config.js";
10
- import { documentationModule } from "./modules/documentation/index.js";
11
- import { taskEngineModule } from "./modules/task-engine/index.js";
12
- import { approvalsModule } from "./modules/approvals/index.js";
13
- import { planningModule } from "./modules/planning/index.js";
14
- import { improvementModule } from "./modules/improvement/index.js";
15
- import { workspaceConfigModule } from "./modules/workspace-config/index.js";
7
+ import { handleRunCommand } from "./cli/run-command.js";
16
8
  const EXIT_SUCCESS = 0;
17
9
  const EXIT_VALIDATION_FAILURE = 1;
18
10
  const EXIT_USAGE_ERROR = 2;
19
11
  const EXIT_INTERNAL_ERROR = 3;
12
+ const CANONICAL_KIT_NAME = "@workflow-cannon/workspace-kit";
20
13
  export const defaultWorkspaceKitPaths = {
21
14
  profile: "workspace-kit.profile.json",
22
15
  profileSchema: "schemas/workspace-kit-profile.schema.json",
@@ -106,7 +99,7 @@ async function requireCliPolicyApproval(cwd, operationId, commandLabel, writeErr
106
99
  timestamp: new Date().toISOString(),
107
100
  operationId,
108
101
  command: commandLabel,
109
- actor: resolveActor(cwd, {}, process.env),
102
+ actor: await resolveActorWithFallback(cwd, {}, process.env),
110
103
  allowed: false,
111
104
  message: "missing WORKSPACE_KIT_POLICY_APPROVAL"
112
105
  });
@@ -119,7 +112,7 @@ async function recordCliPolicySuccess(cwd, operationId, commandLabel, rationale,
119
112
  timestamp: new Date().toISOString(),
120
113
  operationId,
121
114
  command: commandLabel,
122
- actor: resolveActor(cwd, {}, process.env),
115
+ actor: await resolveActorWithFallback(cwd, {}, process.env),
123
116
  allowed: true,
124
117
  rationale,
125
118
  commandOk
@@ -273,7 +266,8 @@ async function resolvePackageVersion(cwd) {
273
266
  const version = parsed.version;
274
267
  const name = parsed.name;
275
268
  if (typeof version === "string" && version.length > 0 && typeof name === "string") {
276
- if (name === "quicktask-workspace-kit" ||
269
+ if (name === CANONICAL_KIT_NAME ||
270
+ name === "quicktask-workspace-kit" ||
277
271
  candidatePath.endsWith("packages/workspace-kit/package.json")) {
278
272
  return version;
279
273
  }
@@ -418,11 +412,7 @@ export async function runCli(args, options = {}) {
418
412
  const mergedManifest = {
419
413
  schemaVersion: 1,
420
414
  kit: {
421
- name: typeof existingManifest.kit === "object" &&
422
- existingManifest.kit &&
423
- typeof existingManifest.kit.name === "string"
424
- ? existingManifest.kit.name
425
- : "quicktask-workspace-kit",
415
+ name: CANONICAL_KIT_NAME,
426
416
  version: typeof existingManifest.kit === "object" &&
427
417
  existingManifest.kit &&
428
418
  typeof existingManifest.kit.version === "string"
@@ -552,12 +542,14 @@ export async function runCli(args, options = {}) {
552
542
  if (!manifestKitName || !manifestKitVersion) {
553
543
  driftFindings.push(`${defaultWorkspaceKitPaths.manifest}: kit.name and kit.version are required`);
554
544
  }
555
- else if (manifestKitName === "quicktask-workspace-kit" && packageVersion) {
545
+ else if ((manifestKitName === CANONICAL_KIT_NAME || manifestKitName === "quicktask-workspace-kit") &&
546
+ packageVersion) {
556
547
  if (manifestKitVersion !== packageVersion) {
557
548
  driftFindings.push(`${defaultWorkspaceKitPaths.manifest}: kit.version (${manifestKitVersion}) does not match package version (${packageVersion})`);
558
549
  }
559
550
  }
560
- else if (manifestKitName !== "quicktask-workspace-kit") {
551
+ else if (manifestKitName !== CANONICAL_KIT_NAME &&
552
+ manifestKitName !== "quicktask-workspace-kit") {
561
553
  warnings.push(`${defaultWorkspaceKitPaths.manifest}: kit.name is '${manifestKitName}', skipping package-version drift comparison`);
562
554
  }
563
555
  }
@@ -579,121 +571,12 @@ export async function runCli(args, options = {}) {
579
571
  return EXIT_SUCCESS;
580
572
  }
581
573
  if (command === "run") {
582
- const allModules = [
583
- workspaceConfigModule,
584
- documentationModule,
585
- taskEngineModule,
586
- approvalsModule,
587
- planningModule,
588
- improvementModule
589
- ];
590
- const registry = new ModuleRegistry(allModules);
591
- const router = new ModuleCommandRouter(registry);
592
- const subcommand = args[1];
593
- if (!subcommand) {
594
- const commands = router.listCommands();
595
- writeLine("Available module commands:");
596
- for (const cmd of commands) {
597
- const desc = cmd.description ? ` — ${cmd.description}` : "";
598
- writeLine(` ${cmd.name} (${cmd.moduleId})${desc}`);
599
- }
600
- writeLine("");
601
- writeLine("Usage: workspace-kit run <command> [json-args]");
602
- return EXIT_SUCCESS;
603
- }
604
- let commandArgs = {};
605
- if (args[2]) {
606
- try {
607
- const parsed = JSON.parse(args[2]);
608
- if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
609
- commandArgs = parsed;
610
- }
611
- else {
612
- writeError("Command args must be a JSON object.");
613
- return EXIT_USAGE_ERROR;
614
- }
615
- }
616
- catch {
617
- writeError(`Invalid JSON args: ${args[2]}`);
618
- return EXIT_USAGE_ERROR;
619
- }
620
- }
621
- const invocationConfig = typeof commandArgs.config === "object" &&
622
- commandArgs.config !== null &&
623
- !Array.isArray(commandArgs.config)
624
- ? commandArgs.config
625
- : {};
626
- let effective;
627
- try {
628
- const resolved = await resolveWorkspaceConfigWithLayers({
629
- workspacePath: cwd,
630
- registry,
631
- invocationConfig
632
- });
633
- effective = resolved.effective;
634
- }
635
- catch (err) {
636
- const message = err instanceof Error ? err.message : String(err);
637
- writeError(`Config resolution failed: ${message}`);
638
- return EXIT_VALIDATION_FAILURE;
639
- }
640
- const actor = resolveActor(cwd, commandArgs, process.env);
641
- const sensitive = isSensitiveModuleCommandForEffective(subcommand, commandArgs, effective);
642
- if (sensitive) {
643
- const approval = parsePolicyApproval(commandArgs);
644
- if (!approval) {
645
- const op = resolvePolicyOperationIdForCommand(subcommand, effective);
646
- if (op) {
647
- await appendPolicyTrace(cwd, {
648
- timestamp: new Date().toISOString(),
649
- operationId: op,
650
- command: `run ${subcommand}`,
651
- actor,
652
- allowed: false,
653
- message: "missing policyApproval in JSON args"
654
- });
655
- }
656
- writeLine(JSON.stringify({
657
- ok: false,
658
- code: "policy-denied",
659
- message: 'Sensitive command requires policyApproval in JSON args: {"policyApproval":{"confirmed":true,"rationale":"user approved in chat"}}'
660
- }, null, 2));
661
- return EXIT_VALIDATION_FAILURE;
662
- }
663
- }
664
- const ctx = {
665
- runtimeVersion: "0.1",
666
- workspacePath: cwd,
667
- effectiveConfig: effective,
668
- resolvedActor: actor,
669
- moduleRegistry: registry
670
- };
671
- try {
672
- const result = await router.execute(subcommand, commandArgs, ctx);
673
- if (sensitive) {
674
- const approval = parsePolicyApproval(commandArgs);
675
- const op = resolvePolicyOperationIdForCommand(subcommand, effective);
676
- if (approval && op) {
677
- await appendPolicyTrace(cwd, {
678
- timestamp: new Date().toISOString(),
679
- operationId: op,
680
- command: `run ${subcommand}`,
681
- actor,
682
- allowed: true,
683
- rationale: approval.rationale,
684
- commandOk: result.ok,
685
- message: result.message
686
- });
687
- }
688
- }
689
- writeLine(JSON.stringify(result, null, 2));
690
- return result.ok ? EXIT_SUCCESS : EXIT_VALIDATION_FAILURE;
691
- }
692
- catch (error) {
693
- const message = error instanceof Error ? error.message : String(error);
694
- writeError(`Module command failed: ${message}`);
695
- return EXIT_INTERNAL_ERROR;
696
- }
574
+ return handleRunCommand(cwd, args, { writeLine, writeError }, {
575
+ success: EXIT_SUCCESS,
576
+ validationFailure: EXIT_VALIDATION_FAILURE,
577
+ usageError: EXIT_USAGE_ERROR,
578
+ internalError: EXIT_INTERNAL_ERROR
579
+ });
697
580
  }
698
581
  if (command !== "doctor") {
699
582
  writeError(`Unknown command '${command}'. Supported commands: init, doctor, check, upgrade, drift-check, run, config.`);
@@ -1 +1 @@
1
- export type { ConfigRegistryView, ModuleCommand, ModuleCommandResult, ModuleCapability, ModuleDocumentContract, ModuleEvent, ModuleInstructionContract, ModuleInstructionEntry, ModuleLifecycleContext, ModuleRegistration, WorkflowModule } from "./module-contract.js";
1
+ export type { ConfigRegistryView, ResponseTemplateApplicationMeta, ModuleCommand, ModuleCommandResult, ModuleCapability, ModuleDocumentContract, ModuleEvent, ModuleInstructionContract, ModuleInstructionEntry, ModuleLifecycleContext, ModuleRegistration, WorkflowModule } from "./module-contract.js";
@@ -30,11 +30,24 @@ export type ModuleCommand = {
30
30
  name: string;
31
31
  args?: Record<string, unknown>;
32
32
  };
33
+ /** Structured response-template application record (Phase 6b); mirrored in core for shaping. */
34
+ export type ResponseTemplateApplicationMeta = {
35
+ requestedTemplateId: string | null;
36
+ appliedTemplateId: string | null;
37
+ enforcementMode: "advisory" | "strict";
38
+ warnings: string[];
39
+ telemetry?: {
40
+ resolveNs: number;
41
+ warningCount: number;
42
+ };
43
+ };
33
44
  export type ModuleCommandResult = {
34
45
  ok: boolean;
35
46
  code: string;
36
47
  message?: string;
37
48
  data?: Record<string, unknown>;
49
+ /** Advisory response-template shaping metadata; always present for `workspace-kit run` JSON output when enabled. */
50
+ responseTemplate?: ResponseTemplateApplicationMeta;
38
51
  };
39
52
  /** Subset of module registry used for config layer ordering (avoids core↔contracts cycles). */
40
53
  export type ConfigRegistryView = {
@@ -3,7 +3,7 @@ import { createInterface } from "node:readline/promises";
3
3
  import { stdin as processStdin, stdout as processStdout } from "node:process";
4
4
  import path from "node:path";
5
5
  import { ModuleRegistry } from "./module-registry.js";
6
- import { appendPolicyTrace, parsePolicyApprovalFromEnv, resolveActor } from "./policy.js";
6
+ import { appendPolicyTrace, parsePolicyApprovalFromEnv, resolveActorWithFallback } from "./policy.js";
7
7
  import { appendConfigMutation, summarizeForEvidence } from "./config-mutations.js";
8
8
  import { assertWritableKey, getConfigKeyMetadata, listConfigMetadata, validatePersistedConfigDocument, validateValueForMetadata } from "./config-metadata.js";
9
9
  import { explainConfigPath, getAtPath, getProjectConfigPath, getUserConfigFilePath, resolveWorkspaceConfigWithLayers, stableStringifyConfig } from "./workspace-kit-config.js";
@@ -114,7 +114,7 @@ async function requireConfigApproval(cwd, commandLabel, writeError) {
114
114
  timestamp: new Date().toISOString(),
115
115
  operationId: "cli.config-mutate",
116
116
  command: commandLabel,
117
- actor: resolveActor(cwd, {}, process.env),
117
+ actor: await resolveActorWithFallback(cwd, {}, process.env),
118
118
  allowed: false,
119
119
  message: "missing WORKSPACE_KIT_POLICY_APPROVAL"
120
120
  });
@@ -303,7 +303,7 @@ export async function runWorkspaceConfigCli(cwd, argv, io) {
303
303
  const prevVal = getAtPath(before, key);
304
304
  const next = setDeep(before, key, parsed);
305
305
  validatePersistedConfigDocument(next, scope === "project" ? ".workspace-kit/config.json" : "user config");
306
- const actor = resolveActor(cwd, {}, process.env);
306
+ const actor = await resolveActorWithFallback(cwd, {}, process.env);
307
307
  try {
308
308
  await writeConfigFileAtomic(fp, next);
309
309
  await appendConfigMutation(cwd, {
@@ -380,7 +380,7 @@ export async function runWorkspaceConfigCli(cwd, argv, io) {
380
380
  const prevVal = getAtPath(before, key);
381
381
  const next = unsetDeep(before, key);
382
382
  validatePersistedConfigDocument(next, scope === "project" ? ".workspace-kit/config.json" : "user config");
383
- const actor = resolveActor(cwd, {}, process.env);
383
+ const actor = await resolveActorWithFallback(cwd, {}, process.env);
384
384
  try {
385
385
  if (Object.keys(next).length === 0) {
386
386
  await fs.rm(fp, { force: true });