@paths.design/caws-cli 11.1.6 → 11.1.8

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 (190) hide show
  1. package/README.md +1 -1
  2. package/dist/index.js +55 -58
  3. package/dist/init/hook-packs/manifest-claude-code.d.ts +1 -1
  4. package/dist/init/hook-packs/manifest-claude-code.d.ts.map +1 -1
  5. package/dist/init/hook-packs/manifest-claude-code.js +317 -6
  6. package/dist/init/hook-packs/manifest-claude-code.js.map +1 -1
  7. package/dist/init/hook-packs/types.js +1 -1
  8. package/dist/init/hook-packs/types.js.map +1 -1
  9. package/dist/shell/binding/resolve-binding.d.ts.map +1 -1
  10. package/dist/shell/binding/resolve-binding.js +105 -1
  11. package/dist/shell/binding/resolve-binding.js.map +1 -1
  12. package/dist/shell/binding/types.d.ts +47 -3
  13. package/dist/shell/binding/types.d.ts.map +1 -1
  14. package/dist/shell/command-metadata.d.ts +93 -0
  15. package/dist/shell/command-metadata.d.ts.map +1 -0
  16. package/dist/shell/command-metadata.js +687 -0
  17. package/dist/shell/command-metadata.js.map +1 -0
  18. package/dist/shell/commands/agents.d.ts +48 -0
  19. package/dist/shell/commands/agents.d.ts.map +1 -0
  20. package/dist/shell/commands/agents.js +577 -0
  21. package/dist/shell/commands/agents.js.map +1 -0
  22. package/dist/shell/commands/claim.d.ts +16 -0
  23. package/dist/shell/commands/claim.d.ts.map +1 -1
  24. package/dist/shell/commands/claim.js +88 -30
  25. package/dist/shell/commands/claim.js.map +1 -1
  26. package/dist/shell/commands/events.d.ts +106 -0
  27. package/dist/shell/commands/events.d.ts.map +1 -0
  28. package/dist/shell/commands/events.js +510 -0
  29. package/dist/shell/commands/events.js.map +1 -0
  30. package/dist/shell/commands/gates.d.ts +2 -2
  31. package/dist/shell/commands/gates.d.ts.map +1 -1
  32. package/dist/shell/commands/gates.js +106 -25
  33. package/dist/shell/commands/gates.js.map +1 -1
  34. package/dist/shell/commands/init.d.ts.map +1 -1
  35. package/dist/shell/commands/init.js +26 -0
  36. package/dist/shell/commands/init.js.map +1 -1
  37. package/dist/shell/commands/prepush.d.ts +26 -0
  38. package/dist/shell/commands/prepush.d.ts.map +1 -0
  39. package/dist/shell/commands/prepush.js +373 -0
  40. package/dist/shell/commands/prepush.js.map +1 -0
  41. package/dist/shell/commands/scope.d.ts.map +1 -1
  42. package/dist/shell/commands/scope.js +31 -1
  43. package/dist/shell/commands/scope.js.map +1 -1
  44. package/dist/shell/commands/specs.d.ts +44 -3
  45. package/dist/shell/commands/specs.d.ts.map +1 -1
  46. package/dist/shell/commands/specs.js +411 -15
  47. package/dist/shell/commands/specs.js.map +1 -1
  48. package/dist/shell/commands/status.d.ts +12 -0
  49. package/dist/shell/commands/status.d.ts.map +1 -1
  50. package/dist/shell/commands/status.js +236 -21
  51. package/dist/shell/commands/status.js.map +1 -1
  52. package/dist/shell/commands/worktree.d.ts +9 -0
  53. package/dist/shell/commands/worktree.d.ts.map +1 -1
  54. package/dist/shell/commands/worktree.js +353 -1
  55. package/dist/shell/commands/worktree.js.map +1 -1
  56. package/dist/shell/gates/disposition.d.ts.map +1 -1
  57. package/dist/shell/gates/disposition.js +43 -2
  58. package/dist/shell/gates/disposition.js.map +1 -1
  59. package/dist/shell/index.d.ts +14 -6
  60. package/dist/shell/index.d.ts.map +1 -1
  61. package/dist/shell/index.js +32 -1
  62. package/dist/shell/index.js.map +1 -1
  63. package/dist/shell/legacy-command-map.js +832 -0
  64. package/dist/shell/push-range/classify-range.d.ts +99 -0
  65. package/dist/shell/push-range/classify-range.d.ts.map +1 -0
  66. package/dist/shell/push-range/classify-range.js +155 -0
  67. package/dist/shell/push-range/classify-range.js.map +1 -0
  68. package/dist/shell/push-range/scope-match.d.ts +13 -0
  69. package/dist/shell/push-range/scope-match.d.ts.map +1 -0
  70. package/dist/shell/push-range/scope-match.js +53 -0
  71. package/dist/shell/push-range/scope-match.js.map +1 -0
  72. package/dist/shell/register.d.ts.map +1 -1
  73. package/dist/shell/register.js +350 -165
  74. package/dist/shell/register.js.map +1 -1
  75. package/dist/shell/registered-command-groups.js +48 -0
  76. package/dist/shell/render/status.d.ts +7 -1
  77. package/dist/shell/render/status.d.ts.map +1 -1
  78. package/dist/shell/render/status.js +72 -0
  79. package/dist/shell/render/status.js.map +1 -1
  80. package/dist/shell/rules.d.ts +19 -0
  81. package/dist/shell/rules.d.ts.map +1 -1
  82. package/dist/shell/rules.js +27 -0
  83. package/dist/shell/rules.js.map +1 -1
  84. package/dist/shell/session/resolve-session.d.ts +29 -1
  85. package/dist/shell/session/resolve-session.d.ts.map +1 -1
  86. package/dist/shell/session/resolve-session.js +817 -11
  87. package/dist/shell/session/resolve-session.js.map +1 -1
  88. package/dist/shell/session/types.d.ts +127 -1
  89. package/dist/shell/session/types.d.ts.map +1 -1
  90. package/dist/shell/session/types.js +10 -4
  91. package/dist/shell/session/types.js.map +1 -1
  92. package/dist/store/agents-store.d.ts.map +1 -1
  93. package/dist/store/agents-store.js +9 -0
  94. package/dist/store/agents-store.js.map +1 -1
  95. package/dist/store/apply-patch.d.ts.map +1 -1
  96. package/dist/store/apply-patch.js +15 -0
  97. package/dist/store/apply-patch.js.map +1 -1
  98. package/dist/store/doctor-snapshot.d.ts.map +1 -1
  99. package/dist/store/doctor-snapshot.js +169 -3
  100. package/dist/store/doctor-snapshot.js.map +1 -1
  101. package/dist/store/events-migration.d.ts +207 -0
  102. package/dist/store/events-migration.d.ts.map +1 -0
  103. package/dist/store/events-migration.js +358 -0
  104. package/dist/store/events-migration.js.map +1 -0
  105. package/dist/store/events-store.d.ts +47 -1
  106. package/dist/store/events-store.d.ts.map +1 -1
  107. package/dist/store/events-store.js +278 -0
  108. package/dist/store/events-store.js.map +1 -1
  109. package/dist/store/git-autocommit.d.ts +46 -0
  110. package/dist/store/git-autocommit.d.ts.map +1 -0
  111. package/dist/store/git-autocommit.js +198 -0
  112. package/dist/store/git-autocommit.js.map +1 -0
  113. package/dist/store/git-sparse-checkout.d.ts +25 -0
  114. package/dist/store/git-sparse-checkout.d.ts.map +1 -0
  115. package/dist/store/git-sparse-checkout.js +101 -0
  116. package/dist/store/git-sparse-checkout.js.map +1 -0
  117. package/dist/store/index.d.ts +6 -1
  118. package/dist/store/index.d.ts.map +1 -1
  119. package/dist/store/index.js +16 -1
  120. package/dist/store/index.js.map +1 -1
  121. package/dist/store/leases-store.d.ts +89 -0
  122. package/dist/store/leases-store.d.ts.map +1 -0
  123. package/dist/store/leases-store.js +427 -0
  124. package/dist/store/leases-store.js.map +1 -0
  125. package/dist/store/lifecycle-transaction.d.ts.map +1 -1
  126. package/dist/store/lifecycle-transaction.js +34 -1
  127. package/dist/store/lifecycle-transaction.js.map +1 -1
  128. package/dist/store/rules.d.ts +74 -1
  129. package/dist/store/rules.d.ts.map +1 -1
  130. package/dist/store/rules.js +76 -0
  131. package/dist/store/rules.js.map +1 -1
  132. package/dist/store/specs-migration.d.ts +128 -0
  133. package/dist/store/specs-migration.d.ts.map +1 -0
  134. package/dist/store/specs-migration.js +481 -0
  135. package/dist/store/specs-migration.js.map +1 -0
  136. package/dist/store/specs-store.d.ts.map +1 -1
  137. package/dist/store/specs-store.js +14 -2
  138. package/dist/store/specs-store.js.map +1 -1
  139. package/dist/store/specs-writer.d.ts +130 -3
  140. package/dist/store/specs-writer.d.ts.map +1 -1
  141. package/dist/store/specs-writer.js +941 -102
  142. package/dist/store/specs-writer.js.map +1 -1
  143. package/dist/store/types.d.ts +31 -1
  144. package/dist/store/types.d.ts.map +1 -1
  145. package/dist/store/waivers-store.d.ts.map +1 -1
  146. package/dist/store/waivers-store.js +8 -1
  147. package/dist/store/waivers-store.js.map +1 -1
  148. package/dist/store/worktrees-migration.d.ts +141 -0
  149. package/dist/store/worktrees-migration.d.ts.map +1 -0
  150. package/dist/store/worktrees-migration.js +356 -0
  151. package/dist/store/worktrees-migration.js.map +1 -0
  152. package/dist/store/worktrees-writer.d.ts +28 -0
  153. package/dist/store/worktrees-writer.d.ts.map +1 -1
  154. package/dist/store/worktrees-writer.js +147 -13
  155. package/dist/store/worktrees-writer.js.map +1 -1
  156. package/package.json +5 -2
  157. package/templates/hook-packs/claude-code/CLAUDE.md +11 -5
  158. package/templates/hook-packs/claude-code/agent-heartbeat.sh +131 -0
  159. package/templates/hook-packs/claude-code/agent-register.sh +62 -0
  160. package/templates/hook-packs/claude-code/agent-stop.sh +51 -0
  161. package/templates/hook-packs/claude-code/audit.sh +1 -1
  162. package/templates/hook-packs/claude-code/block-dangerous.sh +1 -1
  163. package/templates/hook-packs/claude-code/classify_command.py +1 -1
  164. package/templates/hook-packs/claude-code/cwd-guard.sh +30 -0
  165. package/templates/hook-packs/claude-code/dispatch/post_tool_use.sh +15 -4
  166. package/templates/hook-packs/claude-code/dispatch/pre_tool_use.sh +19 -2
  167. package/templates/hook-packs/claude-code/dispatch/session_start.sh +6 -2
  168. package/templates/hook-packs/claude-code/dispatch/stop.sh +7 -2
  169. package/templates/hook-packs/claude-code/duplicate-export-check.sh +156 -0
  170. package/templates/hook-packs/claude-code/god-object-check.sh +102 -0
  171. package/templates/hook-packs/claude-code/guard-strikes.sh +1 -1
  172. package/templates/hook-packs/claude-code/lib/parse-input.sh +115 -1
  173. package/templates/hook-packs/claude-code/lib/run-handlers.sh +1 -1
  174. package/templates/hook-packs/claude-code/loc-delta-check.sh +91 -0
  175. package/templates/hook-packs/claude-code/naming-check.sh +128 -0
  176. package/templates/hook-packs/claude-code/plan-transcript-finalize.sh +59 -0
  177. package/templates/hook-packs/claude-code/plan-transcript-snapshot.sh +86 -0
  178. package/templates/hook-packs/claude-code/protected-paths.sh +59 -0
  179. package/templates/hook-packs/claude-code/quiet-merge.sh +68 -0
  180. package/templates/hook-packs/claude-code/reset-danger-latch.sh +1 -1
  181. package/templates/hook-packs/claude-code/reset-strikes.sh +1 -1
  182. package/templates/hook-packs/claude-code/runtime-paths.sh +1 -1
  183. package/templates/hook-packs/claude-code/scan-secrets.sh +98 -0
  184. package/templates/hook-packs/claude-code/scope-guard.sh +47 -65
  185. package/templates/hook-packs/claude-code/session-caws-status.sh +7 -1
  186. package/templates/hook-packs/claude-code/session-log.sh +1 -1
  187. package/templates/hook-packs/claude-code/session_log_renderer.py +956 -0
  188. package/templates/hook-packs/claude-code/shortcut-language-check.sh +147 -0
  189. package/templates/hook-packs/claude-code/worktree-guard.sh +130 -4
  190. package/templates/hook-packs/claude-code/worktree-write-guard.sh +133 -18
@@ -0,0 +1,356 @@
1
+ "use strict";
2
+ // WORKTREE-REGISTRY-LEGACY-ENVELOPE-MIGRATION-001
3
+ //
4
+ // Pure-ish helper for converting v10.2 envelope-shaped
5
+ // .caws/worktrees.json into the v11 flat-map shape.
6
+ //
7
+ // Discipline:
8
+ // - The classifier (detectWorktreesRegistryShape) and planner
9
+ // (planMigration) are pure: they take fileContents + specs +
10
+ // a path-existence callback and return a plan. No fs reads,
11
+ // no process.env, no Date.now usage.
12
+ // - The shell command wraps the pure logic with real fs.existsSync
13
+ // and writeFileAtomic. The shell layer is responsible for IO.
14
+ // - writeFileAtomic semantics (verified at audit gate, commit
15
+ // a83927c): fsync + rename-on-same-filesystem atomicity. The
16
+ // migration relies on file-content atomicity (readers see
17
+ // either the old bytes or the new bytes; never partial), NOT
18
+ // on crash-safety past power loss or parent-directory
19
+ // durability.
20
+ // - loadSpecs semantics (verified at audit gate): read-only
21
+ // filesystem, returns specs + diagnostics. The migration
22
+ // consumes only `result.specs[]` for the destroyed-record
23
+ // policy check. A12 acceptance: when specs.length === 0 AND
24
+ // diagnostics contains READ_IO_FAILED, the migration refuses
25
+ // because the destroyed-record claim check cannot be verified.
26
+ // Benign loadSpecs diagnostics (non-yaml-skipped, duplicate-id)
27
+ // do NOT cause refusal.
28
+ //
29
+ // What this module does NOT do:
30
+ // - Read or write the filesystem (the shell command does that).
31
+ // - Append events (Decision 2: no new event in this slice).
32
+ // - Modify doctor's H1 rule (Decision 3: detection is explicit
33
+ // in this migration path; doctor stays unchanged).
34
+ // - Repair half-states (lives in PRUNE-REPAIR-WORKTREE-001 after
35
+ // authority closes).
36
+ Object.defineProperty(exports, "__esModule", { value: true });
37
+ exports.MIGRATION_RULES = void 0;
38
+ exports.detectWorktreesRegistryShape = detectWorktreesRegistryShape;
39
+ exports.classifyRecordsForMigration = classifyRecordsForMigration;
40
+ exports.isSpecLoadVerifiable = isSpecLoadVerifiable;
41
+ exports.planMigration = planMigration;
42
+ const caws_kernel_1 = require("@paths.design/caws-kernel");
43
+ // ---- Stable rule ids ------------------------------------------------------
44
+ //
45
+ // Co-located with the migration logic, following the pattern in
46
+ // doctor-snapshot.ts where diagnostic rule ids are defined inline rather
47
+ // than registered in STORE_RULES. This keeps the contract local to the
48
+ // migration surface and avoids touching the cross-cutting rules.ts file.
49
+ exports.MIGRATION_RULES = {
50
+ /** A10/A1: shape detection — file is in v10.2 envelope shape. */
51
+ LEGACY_ENVELOPE_DETECTED: 'store.worktrees_migration.legacy_envelope_detected',
52
+ /** A5: shape detection — ambiguous mix of envelope and flat-map structure. */
53
+ MIXED_SHAPE_REFUSED: 'store.worktrees_migration.mixed_shape_refused',
54
+ /** A4: at least one destroyed record blocks omission (spec claims it OR path present). */
55
+ DESTROYED_RECORD_BLOCKS_OMISSION: 'store.worktrees_migration.destroyed_record_blocks_omission',
56
+ /** A12: spec load failed in a way that makes the claim check unverifiable. */
57
+ SPEC_LOAD_FAILED_POLICY_UNVERIFIABLE: 'store.worktrees_migration.spec_load_failed_policy_unverifiable',
58
+ /** A6: file already in v11 flat-map shape; no-op. */
59
+ ALREADY_MIGRATED: 'store.worktrees_migration.already_migrated',
60
+ /** IO/parse error reading the file before classification. */
61
+ READ_FAILED: 'store.worktrees_migration.read_failed',
62
+ };
63
+ function migrationDiagnostic(rule, message, opts = {}) {
64
+ return {
65
+ rule,
66
+ authority: 'kernel/diagnostics',
67
+ severity: opts.severity ?? 'error',
68
+ message,
69
+ ...(opts.subject !== undefined ? { subject: opts.subject } : {}),
70
+ ...(opts.data !== undefined ? { data: opts.data } : {}),
71
+ ...(opts.narrowRepair !== undefined ? { narrowRepair: opts.narrowRepair } : {}),
72
+ };
73
+ }
74
+ /**
75
+ * Classify the raw .caws/worktrees.json bytes. Pure: no fs access.
76
+ *
77
+ * Recognized shapes:
78
+ * - `flat`: a JSON object with zero or more keys that are NOT
79
+ * `version` (number) AND NOT `worktrees` (object) — i.e., the
80
+ * v11 shape where each top-level key is a worktree name.
81
+ * - `legacy_envelope`: a JSON object whose keys are EXACTLY
82
+ * {version: number, worktrees: object}. No other top-level keys.
83
+ * - `mixed`: a JSON object that has BOTH legacy-envelope keys AND
84
+ * additional keys that look like flat-map records.
85
+ * - `empty`: a JSON object with zero keys (`{}`).
86
+ *
87
+ * A12-relevant note: the classifier does NOT need spec input. The
88
+ * spec-load policy check happens at the planner step.
89
+ */
90
+ function detectWorktreesRegistryShape(fileContents) {
91
+ let parsed;
92
+ try {
93
+ parsed = JSON.parse(fileContents);
94
+ }
95
+ catch (e) {
96
+ const msg = e.message ?? 'unknown JSON error';
97
+ return (0, caws_kernel_1.err)(migrationDiagnostic(exports.MIGRATION_RULES.READ_FAILED, `worktrees.json could not be parsed as JSON: ${msg}`));
98
+ }
99
+ if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) {
100
+ return (0, caws_kernel_1.err)(migrationDiagnostic(exports.MIGRATION_RULES.READ_FAILED, `worktrees.json is not a JSON object.`));
101
+ }
102
+ const obj = parsed;
103
+ const keys = Object.keys(obj);
104
+ if (keys.length === 0) {
105
+ return (0, caws_kernel_1.ok)({ kind: 'empty', reason: 'empty_object' });
106
+ }
107
+ const hasVersion = Object.prototype.hasOwnProperty.call(obj, 'version') &&
108
+ typeof obj.version === 'number';
109
+ const hasWorktreesObject = Object.prototype.hasOwnProperty.call(obj, 'worktrees') &&
110
+ typeof obj.worktrees === 'object' &&
111
+ obj.worktrees !== null &&
112
+ !Array.isArray(obj.worktrees);
113
+ if (hasVersion && hasWorktreesObject) {
114
+ const otherKeys = keys.filter((k) => k !== 'version' && k !== 'worktrees');
115
+ if (otherKeys.length > 0) {
116
+ // Mixed: envelope keys adjacent to non-envelope record keys.
117
+ return (0, caws_kernel_1.ok)({
118
+ kind: 'mixed',
119
+ reason: `legacy-envelope keys (version, worktrees) coexist with non-envelope top-level keys: ${otherKeys.join(', ')}`,
120
+ });
121
+ }
122
+ const nested = obj.worktrees;
123
+ return (0, caws_kernel_1.ok)({
124
+ kind: 'legacy_envelope',
125
+ version: obj.version,
126
+ nestedRecordCount: Object.keys(nested).length,
127
+ });
128
+ }
129
+ // No envelope. If `version` or `worktrees` appears alone (without the
130
+ // other), classify as mixed — that combination is not a recognized
131
+ // v10.2 shape and is not a clean flat map.
132
+ if (hasVersion && !hasWorktreesObject) {
133
+ return (0, caws_kernel_1.ok)({
134
+ kind: 'mixed',
135
+ reason: 'top-level "version" number is present but the legacy "worktrees" object is not',
136
+ });
137
+ }
138
+ if (!hasVersion && hasWorktreesObject) {
139
+ return (0, caws_kernel_1.ok)({
140
+ kind: 'mixed',
141
+ reason: 'top-level "worktrees" object is present but the legacy "version" number is not',
142
+ });
143
+ }
144
+ // Pure flat map (every top-level key is treated as a worktree name).
145
+ return (0, caws_kernel_1.ok)({ kind: 'flat', recordCount: keys.length });
146
+ }
147
+ /**
148
+ * Apply the destroyed-record policy to each nested record. Pure: takes
149
+ * the parsed envelope, the loaded specs (just id + worktree?), and a
150
+ * path-existence callback.
151
+ *
152
+ * Policy (invariant 3 of WORKTREE-REGISTRY-LEGACY-ENVELOPE-MIGRATION-001):
153
+ *
154
+ * A record with status: "destroyed" MAY be omitted IFF BOTH:
155
+ * (a) No loaded spec has its `worktree:` field set to the
156
+ * record's key.
157
+ * (b) The record's `path` is undefined/null/empty OR the
158
+ * path does not exist on disk.
159
+ *
160
+ * Otherwise, the migration refuses (whole-file refusal, not
161
+ * partial migration).
162
+ *
163
+ * Non-terminal records (status missing or != "destroyed") are
164
+ * always preserved verbatim.
165
+ */
166
+ function classifyRecordsForMigration(nestedRecords, specs, pathExistsCheck) {
167
+ const decisions = [];
168
+ // Build a name -> claiming spec id index. Multiple specs claiming
169
+ // the same name (a separate doctor concern; not our problem) — we
170
+ // take the first match for diagnostic naming.
171
+ const claims = new Map();
172
+ for (const spec of specs) {
173
+ if (typeof spec.worktree === 'string' && spec.worktree.length > 0) {
174
+ if (!claims.has(spec.worktree)) {
175
+ claims.set(spec.worktree, spec.id);
176
+ }
177
+ }
178
+ }
179
+ for (const [key, raw] of Object.entries(nestedRecords)) {
180
+ if (raw === null || typeof raw !== 'object' || Array.isArray(raw)) {
181
+ // Non-object nested value (defensive). Treat as non-terminal —
182
+ // preserve verbatim. The kernel's regular registry validation
183
+ // will surface it later if it's malformed.
184
+ decisions.push({
185
+ record: key,
186
+ omit: false,
187
+ reason: 'non_terminal',
188
+ detail: {},
189
+ });
190
+ continue;
191
+ }
192
+ const record = raw;
193
+ const status = typeof record.status === 'string' ? record.status : undefined;
194
+ if (status !== 'destroyed') {
195
+ decisions.push({
196
+ record: key,
197
+ omit: false,
198
+ reason: 'non_terminal',
199
+ ...(status !== undefined ? { status } : {}),
200
+ detail: {},
201
+ });
202
+ continue;
203
+ }
204
+ // Status is "destroyed". Check policy conditions (a) and (b).
205
+ const claimingSpec = claims.get(key);
206
+ if (claimingSpec !== undefined) {
207
+ decisions.push({
208
+ record: key,
209
+ status,
210
+ omit: false,
211
+ reason: 'spec_claims',
212
+ detail: { specId: claimingSpec },
213
+ });
214
+ continue;
215
+ }
216
+ const recordedPath = typeof record.path === 'string' && record.path.length > 0
217
+ ? record.path
218
+ : undefined;
219
+ if (recordedPath !== undefined && pathExistsCheck(recordedPath)) {
220
+ decisions.push({
221
+ record: key,
222
+ status,
223
+ omit: false,
224
+ reason: 'path_present',
225
+ detail: { path: recordedPath },
226
+ });
227
+ continue;
228
+ }
229
+ decisions.push({
230
+ record: key,
231
+ status,
232
+ omit: true,
233
+ reason: 'destroyed_safe_to_omit',
234
+ });
235
+ }
236
+ return decisions;
237
+ }
238
+ /**
239
+ * A12 gate: detect the precise spec-load failure mode that makes the
240
+ * destroyed-record policy unverifiable. Returns true iff
241
+ * specs.length === 0 AND diagnostics contains READ_IO_FAILED.
242
+ * Other diagnostics (SPECS_NON_YAML_SKIPPED, SPECS_DUPLICATE_ID,
243
+ * SPECS_SPEC_INVALID) MUST NOT cause refusal — those do not make
244
+ * the spec universe unknowable.
245
+ */
246
+ function isSpecLoadVerifiable(specs, diagnostics) {
247
+ if (specs.length > 0)
248
+ return true;
249
+ const hasReadIoFailed = diagnostics.some((d) => d.rule === 'store.read.io_failed');
250
+ return !hasReadIoFailed;
251
+ }
252
+ /**
253
+ * Compose shape detection + record classification into a single plan.
254
+ *
255
+ * Refusal precedence (locked):
256
+ * 1. read_failed (JSON parse / non-object): shape-level refusal.
257
+ * 2. mixed_shape: shape-level refusal.
258
+ * 3. already_flat / empty_object: no_op.
259
+ * 4. legacy_envelope + spec-load unverifiable (A12): refuse.
260
+ * 5. legacy_envelope + any destroyed record blocks omission: refuse.
261
+ * 6. legacy_envelope clean: apply.
262
+ *
263
+ * Note: spec-load verifiability is checked ONLY when the file is in
264
+ * legacy_envelope shape AND at least one destroyed record exists. A
265
+ * legacy envelope with zero destroyed records has no claim check to
266
+ * verify, so a spec-load failure does not block migration. Per the
267
+ * audit, this preserves the narrow refusal posture.
268
+ */
269
+ function planMigration(fileContents, specs, specLoadDiagnostics, pathExistsCheck) {
270
+ const shape = detectWorktreesRegistryShape(fileContents);
271
+ if (!(0, caws_kernel_1.isOk)(shape)) {
272
+ // err() guarantees at least one diagnostic; the [0] index is
273
+ // safe but TypeScript can't prove it under strict mode. Fall
274
+ // back to a synthesized read_failed diagnostic if the array is
275
+ // somehow empty.
276
+ const diagnostic = shape.errors[0] ??
277
+ migrationDiagnostic(exports.MIGRATION_RULES.READ_FAILED, 'worktrees.json detection failed without a specific diagnostic.');
278
+ return {
279
+ kind: 'refuse',
280
+ reason: 'read_failed',
281
+ diagnostic,
282
+ };
283
+ }
284
+ const shapeValue = shape.value;
285
+ if (shapeValue.kind === 'mixed') {
286
+ return {
287
+ kind: 'refuse',
288
+ reason: 'mixed_shape',
289
+ diagnostic: migrationDiagnostic(exports.MIGRATION_RULES.MIXED_SHAPE_REFUSED, `Refused to migrate: .caws/worktrees.json has a mixed shape (${shapeValue.reason}). Resolve manually.`, {
290
+ narrowRepair: 'Hand-edit .caws/worktrees.json to either the v10.2 envelope shape or the v11 flat-map shape, then re-run the migration.',
291
+ }),
292
+ };
293
+ }
294
+ if (shapeValue.kind === 'flat') {
295
+ return { kind: 'no_op', reason: 'already_flat', recordCount: shapeValue.recordCount };
296
+ }
297
+ if (shapeValue.kind === 'empty') {
298
+ return { kind: 'no_op', reason: 'empty_object' };
299
+ }
300
+ // shape is legacy_envelope. Parse the nested records.
301
+ // Safe to re-parse because shape detection already validated the
302
+ // top-level shape; this is to obtain the nested object reference.
303
+ const parsed = JSON.parse(fileContents);
304
+ const nested = parsed.worktrees;
305
+ const decisions = classifyRecordsForMigration(nested, specs, pathExistsCheck);
306
+ const hasDestroyedRecords = decisions.some((d) => d.status === 'destroyed');
307
+ // A12: spec-load verifiability check fires ONLY when at least one
308
+ // destroyed record exists (otherwise the claim check has no work).
309
+ if (hasDestroyedRecords && !isSpecLoadVerifiable(specs, specLoadDiagnostics)) {
310
+ return {
311
+ kind: 'refuse',
312
+ reason: 'spec_load_failed',
313
+ diagnostic: migrationDiagnostic(exports.MIGRATION_RULES.SPEC_LOAD_FAILED_POLICY_UNVERIFIABLE, 'Refused to migrate: cannot verify destroyed-record policy because spec loading failed (zero parsed specs and at least one READ_IO_FAILED diagnostic from .caws/specs/).', {
314
+ narrowRepair: 'Resolve the .caws/specs/ load failure (file permissions, directory corruption, etc.), then re-run the migration.',
315
+ }),
316
+ decisions,
317
+ };
318
+ }
319
+ const blocked = decisions.filter((d) => !d.omit && d.reason !== 'non_terminal');
320
+ if (blocked.length > 0) {
321
+ return {
322
+ kind: 'refuse',
323
+ reason: 'destroyed_blocked',
324
+ diagnostic: migrationDiagnostic(exports.MIGRATION_RULES.DESTROYED_RECORD_BLOCKS_OMISSION, `Refused to migrate: at least one destroyed record cannot be safely omitted. ${blocked.length} record(s) blocked.`, {
325
+ narrowRepair: 'Resolve the conflict manually: clear the worktree: field on the claiming spec if the worktree is genuinely destroyed, or remove the on-disk directory if it is leftover from a destroyed worktree. Then re-run the migration.',
326
+ data: {
327
+ blocked: blocked.map((d) => ({
328
+ record: d.record,
329
+ reason: d.reason,
330
+ detail: d.omit === false ? d.detail : undefined,
331
+ })),
332
+ },
333
+ }),
334
+ decisions,
335
+ };
336
+ }
337
+ // Build the flat map: preserve every record verbatim except those
338
+ // marked omit: true.
339
+ const flatMap = {};
340
+ for (const decision of decisions) {
341
+ if (decision.omit)
342
+ continue;
343
+ flatMap[decision.record] = nested[decision.record];
344
+ }
345
+ // Exact serialization: 2-space indent + trailing newline. Matches
346
+ // the apply-patch convention so loader round-trips are byte-stable.
347
+ const outputBytes = JSON.stringify(flatMap, null, 2) + '\n';
348
+ return {
349
+ kind: 'apply',
350
+ decisions,
351
+ outputBytes,
352
+ inputRecordCount: shapeValue.nestedRecordCount,
353
+ outputRecordCount: Object.keys(flatMap).length,
354
+ };
355
+ }
356
+ //# sourceMappingURL=worktrees-migration.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worktrees-migration.js","sourceRoot":"","sources":["../../src/store/worktrees-migration.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,6 @@
1
1
  import { type EventBody, type Result, type SessionIdentity, type Diagnostic } from '@paths.design/caws-kernel';
2
2
  import { loadSpecs } from './specs-store';
3
+ import type { SessionCandidates } from '../shell/session/types';
3
4
  export interface CreateWorktreeInput {
4
5
  readonly name: string;
5
6
  readonly specId: string;
@@ -22,7 +23,31 @@ export interface BindWorktreeInput {
22
23
  }
23
24
  export interface DestroyWorktreeInput {
24
25
  readonly name: string;
26
+ /**
27
+ * The session identity to record as the actor of the destroy event.
28
+ * Single identity by design — an event has exactly one author. This
29
+ * is the field minted-or-resolved by the caller's
30
+ * resolveSession({ allowMint: true }) call.
31
+ */
25
32
  readonly session: SessionIdentity;
33
+ /**
34
+ * The exhaustive set of session identities the invoking process can
35
+ * speak for, used for the ownership-comparison admission check.
36
+ *
37
+ * The split between `session` (actor) and `sessionCandidates`
38
+ * (comparison) addresses the destroy-side failure mode of
39
+ * CAWS-WORKTREE-DESTROY-SESSION-RESOLUTION-001: a single cwd-keyed
40
+ * `session` cannot distinguish "I am the registered owner via a
41
+ * sibling-cwd capsule" from "I am a genuinely-foreign session", so
42
+ * a destroy issued from canonical after a `claim --takeover` from
43
+ * inside the worktree would refuse its own owner. The comparison
44
+ * now admits the destroy iff ANY candidate matches `entry.owner`,
45
+ * which is the honest semantic — comparison is set membership, not
46
+ * cwd-keyed equality.
47
+ *
48
+ * Construct via the shell layer's `resolveSessionCandidates()`.
49
+ */
50
+ readonly sessionCandidates: SessionCandidates;
26
51
  readonly actor: EventBody['actor'];
27
52
  readonly now?: () => Date;
28
53
  /** Allow destruction even when the branch is not merged into base.
@@ -32,7 +57,10 @@ export interface DestroyWorktreeInput {
32
57
  }
33
58
  export interface MergeWorktreeInput {
34
59
  readonly name: string;
60
+ /** See DestroyWorktreeInput.session — same actor/event-author role. */
35
61
  readonly session: SessionIdentity;
62
+ /** See DestroyWorktreeInput.sessionCandidates — same comparison semantic. */
63
+ readonly sessionCandidates: SessionCandidates;
36
64
  readonly actor: EventBody['actor'];
37
65
  readonly now?: () => Date;
38
66
  /** When true, perform validation only; no git operations, no file
@@ -1 +1 @@
1
- {"version":3,"file":"worktrees-writer.d.ts","sourceRoot":"","sources":["../../src/store/worktrees-writer.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"worktrees-writer.d.ts","sourceRoot":"","sources":["../../src/store/worktrees-writer.ts"],"names":[],"mappings":"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"}