ushman-ledger 1.1.0 → 1.2.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 (66) hide show
  1. package/AGENTS.md +11 -7
  2. package/CHANGELOG.md +6 -0
  3. package/README.md +22 -3
  4. package/dist/blobs.js +3 -3
  5. package/dist/builders.d.ts +43 -0
  6. package/dist/builders.d.ts.map +1 -1
  7. package/dist/builders.js +7 -2
  8. package/dist/cli.d.ts.map +1 -1
  9. package/dist/cli.js +222 -41
  10. package/dist/doctor.d.ts.map +1 -1
  11. package/dist/doctor.js +104 -4
  12. package/dist/handle.d.ts +3 -1
  13. package/dist/handle.d.ts.map +1 -1
  14. package/dist/handle.js +19 -1
  15. package/dist/helpers.d.ts +7 -0
  16. package/dist/helpers.d.ts.map +1 -0
  17. package/dist/helpers.js +38 -0
  18. package/dist/index.d.ts +3 -2
  19. package/dist/index.d.ts.map +1 -1
  20. package/dist/index.js +3 -2
  21. package/dist/list.d.ts +43 -1
  22. package/dist/list.d.ts.map +1 -1
  23. package/dist/note.d.ts +20 -0
  24. package/dist/note.d.ts.map +1 -1
  25. package/dist/note.js +5 -0
  26. package/dist/patch-resolver.d.ts +27 -0
  27. package/dist/patch-resolver.d.ts.map +1 -0
  28. package/dist/patch-resolver.js +184 -0
  29. package/dist/read-index.d.ts +7 -7
  30. package/dist/record.d.ts.map +1 -1
  31. package/dist/record.js +15 -39
  32. package/dist/render/migration-log.d.ts +3 -0
  33. package/dist/render/migration-log.d.ts.map +1 -0
  34. package/dist/render/migration-log.js +72 -0
  35. package/dist/render/retro.d.ts.map +1 -1
  36. package/dist/render/retro.js +40 -21
  37. package/dist/render/workspace-narrative.d.ts +6 -0
  38. package/dist/render/workspace-narrative.d.ts.map +1 -0
  39. package/dist/render/workspace-narrative.js +69 -0
  40. package/dist/schema/entry-core.d.ts +110 -0
  41. package/dist/schema/entry-core.d.ts.map +1 -0
  42. package/dist/schema/entry-core.js +143 -0
  43. package/dist/schema/entry-migrations.d.ts +3 -0
  44. package/dist/schema/entry-migrations.d.ts.map +1 -0
  45. package/dist/schema/entry-migrations.js +48 -0
  46. package/dist/schema/entry-read.d.ts +694 -0
  47. package/dist/schema/entry-read.d.ts.map +1 -0
  48. package/dist/schema/entry-read.js +92 -0
  49. package/dist/schema/entry-write.d.ts +865 -0
  50. package/dist/schema/entry-write.d.ts.map +1 -0
  51. package/dist/schema/entry-write.js +105 -0
  52. package/dist/schema/entry.d.ts +6 -1369
  53. package/dist/schema/entry.d.ts.map +1 -1
  54. package/dist/schema/entry.js +9 -286
  55. package/dist/schema/note.d.ts +1 -1
  56. package/dist/schema/note.d.ts.map +1 -1
  57. package/dist/schema/note.js +12 -1
  58. package/dist/storage/filesystem.d.ts +2 -0
  59. package/dist/storage/filesystem.d.ts.map +1 -1
  60. package/dist/storage/filesystem.js +2 -0
  61. package/dist/storage/lock-reclaimer.d.ts +2 -0
  62. package/dist/storage/lock-reclaimer.d.ts.map +1 -0
  63. package/dist/storage/lock-reclaimer.js +45 -0
  64. package/dist/version.d.ts +1 -1
  65. package/dist/version.js +1 -1
  66. package/package.json +2 -2
@@ -1 +1 @@
1
- {"version":3,"file":"entry.d.ts","sourceRoot":"","sources":["../../src/schema/entry.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"entry.d.ts","sourceRoot":"","sources":["../../src/schema/entry.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,WAAW,EAAqB,MAAM,iBAAiB,CAAC;AACtE,OAAO,EAAE,KAAK,YAAY,EAAsB,MAAM,kBAAkB,CAAC;AAEzE,cAAc,iBAAiB,CAAC;AAChC,cAAc,uBAAuB,CAAC;AACtC,cAAc,iBAAiB,CAAC;AAChC,cAAc,kBAAkB,CAAC;AAEjC,eAAO,MAAM,gBAAgB,GAAI,OAAO,OAAO,KAAG,WAAyE,CAAC;AAE5H,eAAO,MAAM,iBAAiB,GAAI,OAAO,OAAO,KAAG,YACa,CAAC"}
@@ -1,287 +1,10 @@
1
- import path from 'node:path';
2
1
  import * as v from 'valibot';
3
- import { NoteSubkindSchema } from "./note.js";
4
- export const LedgerSchemaVersion = 'ushman-ledger-entry/v1';
5
- export const LEDGER_PHASES = [
6
- 'capture',
7
- 'intake',
8
- 'seed',
9
- 'vendor-extract',
10
- 'cleanup',
11
- 'parity',
12
- 'characterize',
13
- 'equiv',
14
- 'analyze',
15
- 'recover',
16
- 'ship',
17
- 'migration',
18
- ];
19
- export const LEDGER_KINDS = [
20
- 'tool-invocation',
21
- 'agent-patch',
22
- 'operator-patch',
23
- 'operator-decision',
24
- 'validator-result',
25
- 'runtime-event',
26
- 'note',
27
- 'correction',
28
- 'strip-decision-reverted',
29
- ];
30
- export const OPERATOR_DECISION_ACTIONS = [
31
- 'bypass-doctor',
32
- 'skip-check',
33
- 'override-strip-decision',
34
- 'override-ship-state',
35
- 'manual-parity-assertion',
36
- 'ledger-hand-edit',
37
- 'escalation',
38
- ];
39
- const STRIP_DECISION_INVALIDATED_STAGES = [
40
- 'intake',
41
- 'seed',
42
- 'vendor-extract',
43
- 'cleanup',
44
- 'parity',
45
- 'characterize',
46
- ];
47
- const SHA256_HEX_PATTERN = /^[a-f0-9]{64}$/u;
48
- const WINDOWS_ABSOLUTE_PATH_PATTERN = /^[a-z]:[\\/]/iu;
49
- const normalizeWorkspaceRelativePath = (value) => value.replaceAll('\\', '/');
50
- const isNormalizedWorkspaceRelativePath = (value) => {
51
- const normalized = normalizeWorkspaceRelativePath(value);
52
- if (normalized.startsWith('/') || WINDOWS_ABSOLUTE_PATH_PATTERN.test(value)) {
53
- return false;
54
- }
55
- if (normalized.startsWith('./') ||
56
- normalized.endsWith('/') ||
57
- normalized.includes('//') ||
58
- normalized === '.' ||
59
- normalized === '..') {
60
- return false;
61
- }
62
- if (path.posix.normalize(normalized) !== normalized) {
63
- return false;
64
- }
65
- return !normalized.split('/').includes('..');
66
- };
67
- const WorkspaceRelativePathSchema = v.pipe(v.string(), v.minLength(1), v.check(isNormalizedWorkspaceRelativePath, 'Expected a normalized workspace-relative path.'));
68
- const SHA256HexSchema = v.pipe(v.string(), v.regex(SHA256_HEX_PATTERN, 'Expected a lowercase SHA-256 hex digest.'));
69
- export const LedgerPhaseSchema = v.picklist(LEDGER_PHASES);
70
- export const OperatorDecisionActionSchema = v.picklist(OPERATOR_DECISION_ACTIONS);
71
- const StripDecisionInvalidatedStageSchema = v.picklist(STRIP_DECISION_INVALIDATED_STAGES);
72
- export const EmitterSchema = v.object({
73
- tool: v.pipe(v.string(), v.minLength(1)),
74
- user: v.optional(v.pipe(v.string(), v.minLength(1))),
75
- version: v.pipe(v.string(), v.minLength(1)),
76
- });
77
- export const LedgerLinksSchema = v.objectWithRest({
78
- affectedFiles: v.optional(v.array(WorkspaceRelativePathSchema)),
79
- blobs: v.optional(v.array(v.string())),
80
- briefId: v.optional(v.string()),
81
- correctsLedgerId: v.optional(v.string()),
82
- gitRef: v.optional(v.string()),
83
- idempotencyKey: v.optional(v.string()),
84
- stripDecisionId: v.optional(v.string()),
85
- supersedesLedgerId: v.optional(v.string()),
86
- validatorVerdictId: v.optional(v.string()),
87
- }, v.unknown());
88
- const ledgerEntryBaseEntries = {
89
- details: v.optional(v.record(v.string(), v.unknown())),
90
- emitter: EmitterSchema,
91
- id: v.pipe(v.string(), v.minLength(1)),
92
- links: v.optional(LedgerLinksSchema, {}),
93
- phase: LedgerPhaseSchema,
94
- prevEntryId: v.nullable(v.pipe(v.string(), v.minLength(1))),
95
- schemaVersion: v.literal(LedgerSchemaVersion),
96
- summary: v.pipe(v.string(), v.minLength(1)),
97
- ts: v.pipe(v.string(), v.isoTimestamp()),
98
- };
99
- export const AgentPatchDiffSchema = v.object({
100
- addedLines: v.pipe(v.number(), v.integer(), v.minValue(0)),
101
- blobSha256: SHA256HexSchema,
102
- bytes: v.pipe(v.number(), v.integer(), v.minValue(0)),
103
- removedLines: v.pipe(v.number(), v.integer(), v.minValue(0)),
104
- });
105
- export const OperatorDecisionPayloadSchema = v.object({
106
- action: OperatorDecisionActionSchema,
107
- checkId: v.optional(v.pipe(v.string(), v.minLength(1))),
108
- rationale: v.pipe(v.string(), v.trim(), v.minLength(1, 'payload.rationale must not be empty')),
109
- });
110
- export const StripDecisionRevertedPayloadSchema = v.object({
111
- invalidatedStages: v.optional(v.array(StripDecisionInvalidatedStageSchema)),
112
- rationale: v.pipe(v.string(), v.trim(), v.minLength(1)),
113
- stripDecisionId: v.pipe(v.string(), v.minLength(1)),
114
- });
115
- export const ToolInvocationEntrySchema = v.object({
116
- ...ledgerEntryBaseEntries,
117
- args: v.optional(v.array(v.string())),
118
- cwd: v.optional(v.string()),
119
- exitCode: v.optional(v.pipe(v.number(), v.integer())),
120
- kind: v.literal('tool-invocation'),
121
- });
122
- const patchEntryEntries = {
123
- ...ledgerEntryBaseEntries,
124
- diff: AgentPatchDiffSchema,
125
- rationale: v.pipe(v.string(), v.minLength(1)),
126
- };
127
- export const AgentPatchEntrySchema = v.object({
128
- ...patchEntryEntries,
129
- agent: v.object({
130
- name: v.pipe(v.string(), v.minLength(1)),
131
- sessionId: v.optional(v.pipe(v.string(), v.minLength(1))),
132
- }),
133
- kind: v.literal('agent-patch'),
134
- });
135
- export const OperatorPatchEntrySchema = v.object({
136
- ...patchEntryEntries,
137
- kind: v.literal('operator-patch'),
138
- operator: v.object({
139
- name: v.pipe(v.string(), v.minLength(1)),
140
- }),
141
- });
142
- export const OperatorDecisionEntrySchema = v.object({
143
- ...ledgerEntryBaseEntries,
144
- kind: v.literal('operator-decision'),
145
- payload: OperatorDecisionPayloadSchema,
146
- });
147
- export const ValidatorResultEntrySchema = v.object({
148
- ...ledgerEntryBaseEntries,
149
- kind: v.literal('validator-result'),
150
- metrics: v.optional(v.record(v.string(), v.unknown())),
151
- resultPath: v.optional(v.string()),
152
- validator: v.picklist(['parity', 'equiv', 'characterize', 'verify', 'doctor']),
153
- verdict: v.picklist(['green', 'yellow', 'red']),
154
- });
155
- export const RuntimeEventEntrySchema = v.object({
156
- ...ledgerEntryBaseEntries,
157
- kind: v.literal('runtime-event'),
158
- level: v.picklist(['info', 'warn', 'error']),
159
- message: v.pipe(v.string(), v.minLength(1)),
160
- source: v.pipe(v.string(), v.minLength(1)),
161
- stripDecisionId: v.optional(v.string()),
162
- });
163
- export const NoteEntrySchema = v.object({
164
- ...ledgerEntryBaseEntries,
165
- body: v.string(),
166
- kind: v.literal('note'),
167
- subkind: NoteSubkindSchema,
168
- });
169
- export const CorrectionEntrySchema = v.pipe(v.object({
170
- ...ledgerEntryBaseEntries,
171
- kind: v.literal('correction'),
172
- rationale: v.pipe(v.string(), v.minLength(1)),
173
- }), v.check((value) => Boolean(value.links?.correctsLedgerId), 'correction entries require links.correctsLedgerId'));
174
- export const StripDecisionRevertedEntrySchema = v.object({
175
- ...ledgerEntryBaseEntries,
176
- kind: v.literal('strip-decision-reverted'),
177
- payload: StripDecisionRevertedPayloadSchema,
178
- });
179
- export const LedgerEntrySchema = v.variant('kind', [
180
- ToolInvocationEntrySchema,
181
- AgentPatchEntrySchema,
182
- OperatorPatchEntrySchema,
183
- OperatorDecisionEntrySchema,
184
- ValidatorResultEntrySchema,
185
- RuntimeEventEntrySchema,
186
- NoteEntrySchema,
187
- CorrectionEntrySchema,
188
- StripDecisionRevertedEntrySchema,
189
- ]);
190
- const recordEntryBaseEntries = {
191
- details: v.optional(v.record(v.string(), v.unknown())),
192
- emitter: EmitterSchema,
193
- idempotencyKey: v.optional(v.pipe(v.string(), v.minLength(1))),
194
- links: v.optional(LedgerLinksSchema),
195
- phase: LedgerPhaseSchema,
196
- summary: v.pipe(v.string(), v.minLength(1)),
197
- };
198
- export const ToolInvocationRecordSchema = v.object({
199
- ...recordEntryBaseEntries,
200
- args: v.optional(v.array(v.string())),
201
- cwd: v.optional(v.string()),
202
- exitCode: v.optional(v.pipe(v.number(), v.integer())),
203
- kind: v.literal('tool-invocation'),
204
- });
205
- const patchRecordEntries = {
206
- ...recordEntryBaseEntries,
207
- diff: v.optional(AgentPatchDiffSchema),
208
- diffPath: v.optional(v.pipe(v.string(), v.minLength(1))),
209
- diffText: v.optional(v.pipe(v.string(), v.minLength(1))),
210
- rationale: v.pipe(v.string(), v.minLength(1)),
211
- };
212
- const validatePatchRecord = (value) => {
213
- const provided = [value.diff, value.diffPath, value.diffText].filter((entry) => Boolean(entry));
214
- if (provided.length === 0) {
215
- return false;
216
- }
217
- if (value.diffPath && value.diffText) {
218
- return false;
219
- }
220
- return true;
221
- };
222
- const PATCH_RECORD_REFINEMENT_MESSAGE = 'patch records require exactly one source: diff, diffPath, or diffText (diffPath and diffText cannot be combined).';
223
- export const AgentPatchRecordSchema = v.pipe(v.object({
224
- ...patchRecordEntries,
225
- agent: v.object({
226
- name: v.pipe(v.string(), v.minLength(1)),
227
- sessionId: v.optional(v.pipe(v.string(), v.minLength(1))),
228
- }),
229
- kind: v.literal('agent-patch'),
230
- }), v.check(validatePatchRecord, PATCH_RECORD_REFINEMENT_MESSAGE));
231
- export const OperatorPatchRecordSchema = v.pipe(v.object({
232
- ...patchRecordEntries,
233
- kind: v.literal('operator-patch'),
234
- operator: v.object({
235
- name: v.pipe(v.string(), v.minLength(1)),
236
- }),
237
- }), v.check(validatePatchRecord, PATCH_RECORD_REFINEMENT_MESSAGE));
238
- export const OperatorDecisionRecordSchema = v.object({
239
- ...recordEntryBaseEntries,
240
- kind: v.literal('operator-decision'),
241
- payload: OperatorDecisionPayloadSchema,
242
- });
243
- export const ValidatorResultRecordSchema = v.object({
244
- ...recordEntryBaseEntries,
245
- kind: v.literal('validator-result'),
246
- metrics: v.optional(v.record(v.string(), v.unknown())),
247
- resultPath: v.optional(v.string()),
248
- validator: v.picklist(['parity', 'equiv', 'characterize', 'verify', 'doctor']),
249
- verdict: v.picklist(['green', 'yellow', 'red']),
250
- });
251
- export const RuntimeEventRecordSchema = v.object({
252
- ...recordEntryBaseEntries,
253
- kind: v.literal('runtime-event'),
254
- level: v.picklist(['info', 'warn', 'error']),
255
- message: v.pipe(v.string(), v.minLength(1)),
256
- source: v.pipe(v.string(), v.minLength(1)),
257
- stripDecisionId: v.optional(v.string()),
258
- });
259
- export const NoteRecordSchema = v.object({
260
- ...recordEntryBaseEntries,
261
- body: v.string(),
262
- kind: v.literal('note'),
263
- subkind: NoteSubkindSchema,
264
- });
265
- export const CorrectionRecordSchema = v.pipe(v.object({
266
- ...recordEntryBaseEntries,
267
- kind: v.literal('correction'),
268
- rationale: v.pipe(v.string(), v.minLength(1)),
269
- }), v.check((value) => Boolean(value.links?.correctsLedgerId), 'correction records require links.correctsLedgerId'));
270
- export const StripDecisionRevertedRecordSchema = v.object({
271
- ...recordEntryBaseEntries,
272
- kind: v.literal('strip-decision-reverted'),
273
- payload: StripDecisionRevertedPayloadSchema,
274
- });
275
- export const LedgerRecordSchema = v.variant('kind', [
276
- ToolInvocationRecordSchema,
277
- AgentPatchRecordSchema,
278
- OperatorPatchRecordSchema,
279
- OperatorDecisionRecordSchema,
280
- ValidatorResultRecordSchema,
281
- RuntimeEventRecordSchema,
282
- NoteRecordSchema,
283
- CorrectionRecordSchema,
284
- StripDecisionRevertedRecordSchema,
285
- ]);
286
- export const parseLedgerEntry = (input) => v.parse(LedgerEntrySchema, input);
287
- export const parseLedgerRecord = (input) => v.parse(LedgerRecordSchema, input);
2
+ import { migrateLedgerEntryInput, migrateLedgerRecordInput } from "./entry-migrations.js";
3
+ import { LedgerEntrySchema } from "./entry-read.js";
4
+ import { LedgerRecordSchema } from "./entry-write.js";
5
+ export * from "./entry-core.js";
6
+ export * from "./entry-migrations.js";
7
+ export * from "./entry-read.js";
8
+ export * from "./entry-write.js";
9
+ export const parseLedgerEntry = (input) => v.parse(LedgerEntrySchema, migrateLedgerEntryInput(input));
10
+ export const parseLedgerRecord = (input) => v.parse(LedgerRecordSchema, migrateLedgerRecordInput(input));
@@ -1,4 +1,4 @@
1
1
  import * as v from 'valibot';
2
- export declare const NoteSubkindSchema: v.PicklistSchema<["regression", "automation", "retro", "operator", "tooling-gap"], undefined>;
2
+ export declare const NoteSubkindSchema: v.PicklistSchema<["regression", "automation", "retro", "operator", "tooling-gap", "cleanup-wave", "verified-flow", "open-issue", "decomposition-wave", "semantic-cleanup-summary"], undefined>;
3
3
  export type NoteSubkind = v.InferOutput<typeof NoteSubkindSchema>;
4
4
  //# sourceMappingURL=note.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"note.d.ts","sourceRoot":"","sources":["../../src/schema/note.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,SAAS,CAAC;AAE7B,eAAO,MAAM,iBAAiB,+FAA+E,CAAC;AAE9G,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,WAAW,CAAC,OAAO,iBAAiB,CAAC,CAAC"}
1
+ {"version":3,"file":"note.d.ts","sourceRoot":"","sources":["../../src/schema/note.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,SAAS,CAAC;AAE7B,eAAO,MAAM,iBAAiB,gMAW5B,CAAC;AAEH,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,WAAW,CAAC,OAAO,iBAAiB,CAAC,CAAC"}
@@ -1,2 +1,13 @@
1
1
  import * as v from 'valibot';
2
- export const NoteSubkindSchema = v.picklist(['regression', 'automation', 'retro', 'operator', 'tooling-gap']);
2
+ export const NoteSubkindSchema = v.picklist([
3
+ 'regression',
4
+ 'automation',
5
+ 'retro',
6
+ 'operator',
7
+ 'tooling-gap',
8
+ 'cleanup-wave',
9
+ 'verified-flow',
10
+ 'open-issue',
11
+ 'decomposition-wave',
12
+ 'semantic-cleanup-summary',
13
+ ]);
@@ -16,7 +16,9 @@ export type LedgerPaths = {
16
16
  readonly phaseDir: (phase: LedgerPhase) => string;
17
17
  readonly readIndexFile: string;
18
18
  readonly renderFile: string;
19
+ readonly renderMigrationLogFile: string;
19
20
  readonly renderTimelineFile: string;
21
+ readonly renderWorkspaceNarrativeFile: string;
20
22
  readonly root: string;
21
23
  readonly workspaceRoot: string;
22
24
  };
@@ -1 +1 @@
1
- {"version":3,"file":"filesystem.d.ts","sourceRoot":"","sources":["../../src/storage/filesystem.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,aAAa,EAAE,KAAK,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACrE,OAAO,EAAE,KAAK,cAAc,EAAwB,MAAM,uBAAuB,CAAC;AAElF,OAAO,EAAE,aAAa,EAAE,CAAC;AACzB,eAAO,MAAM,oBAAoB,6BAA8B,CAAC;AAChE,eAAO,MAAM,oBAAoB,QAAS,CAAC;AAC3C,KAAK,mBAAmB,GAAG;IACvB,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC/C,CAAC;AAaF,MAAM,MAAM,WAAW,GAAG;IACtB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,MAAM,CAAC;IAClD,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC;IACnC,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAC;IACpC,QAAQ,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,MAAM,CAAC;IAClD,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAC;IACpC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;CAClC,CAAC;AAEF,eAAO,MAAM,kBAAkB,GAAI,eAAe,MAAM,KAAG,WAgB1D,CAAC;AAEF,eAAO,MAAM,uBAAuB,GAAU,eAAe,MAAM,KAAG,OAAO,CAAC,WAAW,CAYxF,CAAC;AAEF,eAAO,MAAM,sBAAsB,GAAI,UAAU,MAAM,EAAE,MAAM,mBAAmB,GAAG,IAAI,SAOxF,CAAC;AAoBF,eAAO,MAAM,mBAAmB,GAAU,UAAU,MAAM,EAAE,MAAM,MAAM,kBAiBvE,CAAC;AAEF,eAAO,MAAM,mBAAmB,GAAU,UAAU,MAAM,EAAE,OAAO,OAAO,kBAEzE,CAAC;AAoCF,eAAO,MAAM,YAAY,GAAU,eAAe,MAAM,KAAG,OAAO,CAAC,cAAc,CAmBhF,CAAC;AAEF,eAAO,MAAM,YAAY,GAAU,eAAe,MAAM,EAAE,UAAU,cAAc,kBASjF,CAAC;AAoFF,eAAO,MAAM,qBAAqB,GAAU,eAAe,MAAM,kBAIhE,CAAC;AAEF,eAAO,MAAM,uBAAuB,GAAU,eAAe,MAAM,EAAE,OAAO,WAAW,KAAG,OAAO,CAAC,MAAM,EAAE,CAOzG,CAAC;AAEF,eAAO,MAAM,kBAAkB,GAAU,eAAe,MAAM,EAAE,OAAO,WAAW,EAAE,UAAU,MAAM,oBAGnG,CAAC;AAEF,eAAO,MAAM,cAAc,GAAU,eAAe,MAAM,EAAE,OAAO,WAAW,EAAE,UAAU,MAAM,EAAE,OAAO,OAAO,oBAK/G,CAAC"}
1
+ {"version":3,"file":"filesystem.d.ts","sourceRoot":"","sources":["../../src/storage/filesystem.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,aAAa,EAAE,KAAK,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACrE,OAAO,EAAE,KAAK,cAAc,EAAwB,MAAM,uBAAuB,CAAC;AAElF,OAAO,EAAE,aAAa,EAAE,CAAC;AACzB,eAAO,MAAM,oBAAoB,6BAA8B,CAAC;AAChE,eAAO,MAAM,oBAAoB,QAAS,CAAC;AAC3C,KAAK,mBAAmB,GAAG;IACvB,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC/C,CAAC;AAaF,MAAM,MAAM,WAAW,GAAG;IACtB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,MAAM,CAAC;IAClD,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC;IACnC,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAC;IACpC,QAAQ,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,MAAM,CAAC;IAClD,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,sBAAsB,EAAE,MAAM,CAAC;IACxC,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAC;IACpC,QAAQ,CAAC,4BAA4B,EAAE,MAAM,CAAC;IAC9C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;CAClC,CAAC;AAEF,eAAO,MAAM,kBAAkB,GAAI,eAAe,MAAM,KAAG,WAkB1D,CAAC;AAEF,eAAO,MAAM,uBAAuB,GAAU,eAAe,MAAM,KAAG,OAAO,CAAC,WAAW,CAYxF,CAAC;AAEF,eAAO,MAAM,sBAAsB,GAAI,UAAU,MAAM,EAAE,MAAM,mBAAmB,GAAG,IAAI,SAOxF,CAAC;AAoBF,eAAO,MAAM,mBAAmB,GAAU,UAAU,MAAM,EAAE,MAAM,MAAM,kBAiBvE,CAAC;AAEF,eAAO,MAAM,mBAAmB,GAAU,UAAU,MAAM,EAAE,OAAO,OAAO,kBAEzE,CAAC;AAoCF,eAAO,MAAM,YAAY,GAAU,eAAe,MAAM,KAAG,OAAO,CAAC,cAAc,CAmBhF,CAAC;AAEF,eAAO,MAAM,YAAY,GAAU,eAAe,MAAM,EAAE,UAAU,cAAc,kBASjF,CAAC;AAoFF,eAAO,MAAM,qBAAqB,GAAU,eAAe,MAAM,kBAIhE,CAAC;AAEF,eAAO,MAAM,uBAAuB,GAAU,eAAe,MAAM,EAAE,OAAO,WAAW,KAAG,OAAO,CAAC,MAAM,EAAE,CAOzG,CAAC;AAEF,eAAO,MAAM,kBAAkB,GAAU,eAAe,MAAM,EAAE,OAAO,WAAW,EAAE,UAAU,MAAM,oBAGnG,CAAC;AAEF,eAAO,MAAM,cAAc,GAAU,eAAe,MAAM,EAAE,OAAO,WAAW,EAAE,UAAU,MAAM,EAAE,OAAO,OAAO,oBAK/G,CAAC"}
@@ -29,7 +29,9 @@ export const resolveLedgerPaths = (workspaceRoot) => {
29
29
  phaseDir: (phase) => path.join(root, phase),
30
30
  readIndexFile: path.join(root, 'read-index.json'),
31
31
  renderFile: path.join(root, 'render.md'),
32
+ renderMigrationLogFile: path.join(root, 'render.migration-log.md'),
32
33
  renderTimelineFile: path.join(root, 'render.timeline.html'),
34
+ renderWorkspaceNarrativeFile: path.join(root, 'render.workspace-narrative.md'),
33
35
  root,
34
36
  workspaceRoot,
35
37
  };
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=lock-reclaimer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lock-reclaimer.d.ts","sourceRoot":"","sources":["../../src/storage/lock-reclaimer.ts"],"names":[],"mappings":""}
@@ -0,0 +1,45 @@
1
+ import { mkdir, stat, writeFile } from 'node:fs/promises';
2
+ import path from 'node:path';
3
+ import { acquireLock } from "./lock.js";
4
+ const [, , lockPath, signalDir] = process.argv;
5
+ if (!lockPath || !signalDir) {
6
+ throw new Error('Expected lock path and signal directory.');
7
+ }
8
+ const waitForFile = async (filePath) => {
9
+ while (true) {
10
+ try {
11
+ await stat(filePath);
12
+ return;
13
+ }
14
+ catch (error) {
15
+ if (error.code !== 'ENOENT') {
16
+ throw error;
17
+ }
18
+ }
19
+ await new Promise((resolve) => setTimeout(resolve, 5));
20
+ }
21
+ };
22
+ const observedPath = path.join(signalDir, 'observed');
23
+ const continuePath = path.join(signalDir, 'continue');
24
+ const acquiredPath = path.join(signalDir, 'acquired');
25
+ const timedOutPath = path.join(signalDir, 'timed-out');
26
+ await mkdir(signalDir, { recursive: true });
27
+ try {
28
+ const lock = await acquireLock(lockPath, {
29
+ retryDelayMs: 10,
30
+ staleMs: 1_000,
31
+ testHooks: {
32
+ afterStaleObservation: async () => {
33
+ await writeFile(observedPath, '1', 'utf8');
34
+ await waitForFile(continuePath);
35
+ },
36
+ },
37
+ timeoutMs: 100,
38
+ });
39
+ await writeFile(acquiredPath, '1', 'utf8');
40
+ await lock.release();
41
+ }
42
+ catch (error) {
43
+ const message = error instanceof Error ? error.message : String(error);
44
+ await writeFile(timedOutPath, message, 'utf8');
45
+ }
package/dist/version.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- export declare const LEDGER_LIBRARY_VERSION = "1.0.0";
1
+ export declare const LEDGER_LIBRARY_VERSION = "1.1.0";
2
2
  //# sourceMappingURL=version.d.ts.map
package/dist/version.js CHANGED
@@ -1 +1 @@
1
- export const LEDGER_LIBRARY_VERSION = '1.0.0';
1
+ export const LEDGER_LIBRARY_VERSION = '1.1.0';
package/package.json CHANGED
@@ -18,7 +18,7 @@
18
18
  "devDependencies": {
19
19
  "@biomejs/biome": "^2.4.15",
20
20
  "@types/bun": "^1.3.14",
21
- "@types/node": "^25.8.0",
21
+ "@types/node": "^25.9.1",
22
22
  "typescript": "^6.0.3"
23
23
  },
24
24
  "engines": {
@@ -68,5 +68,5 @@
68
68
  },
69
69
  "type": "module",
70
70
  "types": "dist/index.d.ts",
71
- "version": "1.1.0"
71
+ "version": "1.2.0"
72
72
  }