ushman-ledger 1.2.0 → 1.2.2

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 (63) hide show
  1. package/ARCHITECTURE.md +79 -0
  2. package/README.md +144 -5
  3. package/TROUBLESHOOTING.md +170 -0
  4. package/dist/blobs.d.ts +3 -0
  5. package/dist/blobs.d.ts.map +1 -1
  6. package/dist/blobs.js +41 -15
  7. package/dist/builders.d.ts +1 -2
  8. package/dist/builders.d.ts.map +1 -1
  9. package/dist/cli.d.ts.map +1 -1
  10. package/dist/cli.js +231 -70
  11. package/dist/coverage.d.ts.map +1 -1
  12. package/dist/coverage.js +3 -2
  13. package/dist/doctor.d.ts +17 -4
  14. package/dist/doctor.d.ts.map +1 -1
  15. package/dist/doctor.js +225 -58
  16. package/dist/handle.d.ts +27 -7
  17. package/dist/handle.d.ts.map +1 -1
  18. package/dist/handle.js +96 -20
  19. package/dist/helpers.d.ts +1 -0
  20. package/dist/helpers.d.ts.map +1 -1
  21. package/dist/helpers.js +23 -0
  22. package/dist/index.d.ts +6 -3
  23. package/dist/index.d.ts.map +1 -1
  24. package/dist/index.js +4 -1
  25. package/dist/list.d.ts +3 -2
  26. package/dist/list.d.ts.map +1 -1
  27. package/dist/list.js +24 -12
  28. package/dist/note.d.ts +7 -0
  29. package/dist/note.d.ts.map +1 -1
  30. package/dist/note.js +6 -0
  31. package/dist/patch-resolver.d.ts +12 -0
  32. package/dist/patch-resolver.d.ts.map +1 -1
  33. package/dist/patch-resolver.js +205 -53
  34. package/dist/read-index.d.ts.map +1 -1
  35. package/dist/read-index.js +6 -5
  36. package/dist/record.d.ts.map +1 -1
  37. package/dist/record.js +3 -3
  38. package/dist/render/migration-log.d.ts +8 -1
  39. package/dist/render/migration-log.d.ts.map +1 -1
  40. package/dist/render/migration-log.js +40 -33
  41. package/dist/render/retro.d.ts.map +1 -1
  42. package/dist/render/retro.js +1 -7
  43. package/dist/render/workspace-narrative.d.ts +7 -1
  44. package/dist/render/workspace-narrative.d.ts.map +1 -1
  45. package/dist/render/workspace-narrative.js +114 -46
  46. package/dist/runtime-config.d.ts +12 -0
  47. package/dist/runtime-config.d.ts.map +1 -0
  48. package/dist/runtime-config.js +83 -0
  49. package/dist/schema/entry-read.d.ts.map +1 -1
  50. package/dist/schema/entry-read.js +1 -1
  51. package/dist/schema/entry-write.d.ts.map +1 -1
  52. package/dist/schema/entry-write.js +1 -1
  53. package/dist/schema/entry.d.ts.map +1 -1
  54. package/dist/storage/filesystem.d.ts +8 -0
  55. package/dist/storage/filesystem.d.ts.map +1 -1
  56. package/dist/storage/filesystem.js +110 -5
  57. package/dist/text-lines.d.ts +8 -0
  58. package/dist/text-lines.d.ts.map +1 -0
  59. package/dist/text-lines.js +20 -0
  60. package/dist/version.d.ts +1 -1
  61. package/dist/version.d.ts.map +1 -1
  62. package/dist/version.js +2 -1
  63. package/package.json +5 -3
@@ -1 +1 @@
1
- {"version":3,"file":"read-index.d.ts","sourceRoot":"","sources":["../src/read-index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,CAAC,MAAM,SAAS,CAAC;AAG7B,OAAO,EAAgB,KAAK,WAAW,EAAE,KAAK,UAAU,EAAE,KAAK,WAAW,EAAoB,MAAM,mBAAmB,CAAC;AACxH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAO3D,QAAA,MAAM,oBAAoB;;;;aAIxB,CAAC;AAEH,QAAA,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;sDAiB1B,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,WAAW,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAC1E,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,WAAW,CAAC,OAAO,oBAAoB,CAAC,CAAC;AACxE,MAAM,MAAM,qBAAqB,GAAG,SAAS,CAAC,MAAM,EAAE;IAAE,KAAK,EAAE,WAAW,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AA0HhG,eAAO,MAAM,0BAA0B,GAAU,eAAe,MAAM,EAAE,UAAU,cAAc;;;;;;;;;;;EAuB/F,CAAC;AAYF,eAAO,MAAM,kBAAkB,GAAI,OAAO,eAAe,EAAE,UAAU,cAAc,YAG1C,CAAC;AAE1C,eAAO,MAAM,aAAa,GAAU,eAAe,MAAM,KAAG,OAAO,CAAC,eAAe,GAAG,IAAI,CAWzF,CAAC;AAEF,eAAO,MAAM,aAAa,GAAU,eAAe,MAAM,EAAE,WAAW,eAAe,kBAGpF,CAAC;AAEF,eAAO,MAAM,wBAAwB,GAAU,eAAe,MAAM,EAAE,UAAU,cAAc;;;;;;;;;;;EAiB7F,CAAC;AAEF,eAAO,MAAM,sBAAsB,GAAI,iCAIpC;IACC,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC;IAC5B,QAAQ,CAAC,SAAS,EAAE,eAAe,CAAC;IACpC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC7B;;;;;;;;;;;CAYA,CAAC;AAEF,eAAO,MAAM,sBAAsB,GAAI,uCAIpC;IACC,QAAQ,CAAC,MAAM,EAAE;QACb,QAAQ,CAAC,IAAI,CAAC,EAAE,UAAU,CAAC;QAC3B,QAAQ,CAAC,KAAK,CAAC,EAAE,WAAW,CAAC;QAC7B,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;KAC3B,CAAC;IACF,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAC;IAClC,QAAQ,CAAC,cAAc,EAAE,cAAc,CAAC;CAC3C,YAeA,CAAC"}
1
+ {"version":3,"file":"read-index.d.ts","sourceRoot":"","sources":["../src/read-index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,CAAC,MAAM,SAAS,CAAC;AAI7B,OAAO,EAAgB,KAAK,WAAW,EAAE,KAAK,UAAU,EAAE,KAAK,WAAW,EAAoB,MAAM,mBAAmB,CAAC;AACxH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAK3D,QAAA,MAAM,oBAAoB;;;;aAIxB,CAAC;AAEH,QAAA,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;sDAc1B,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,WAAW,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAC1E,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,WAAW,CAAC,OAAO,oBAAoB,CAAC,CAAC;AACxE,MAAM,MAAM,qBAAqB,GAAG,SAAS,CAAC,MAAM,EAAE;IAAE,KAAK,EAAE,WAAW,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AA4HhG,eAAO,MAAM,0BAA0B,GAAU,eAAe,MAAM,EAAE,UAAU,cAAc;;;;;;;;;;;EAyB/F,CAAC;AAYF,eAAO,MAAM,kBAAkB,GAAI,OAAO,eAAe,EAAE,UAAU,cAAc,YAG1C,CAAC;AAE1C,eAAO,MAAM,aAAa,GAAU,eAAe,MAAM,KAAG,OAAO,CAAC,eAAe,GAAG,IAAI,CAWzF,CAAC;AAEF,eAAO,MAAM,aAAa,GAAU,eAAe,MAAM,EAAE,WAAW,eAAe,kBAGpF,CAAC;AAEF,eAAO,MAAM,wBAAwB,GAAU,eAAe,MAAM,EAAE,UAAU,cAAc;;;;;;;;;;;EAiB7F,CAAC;AAEF,eAAO,MAAM,sBAAsB,GAAI,iCAIpC;IACC,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC;IAC5B,QAAQ,CAAC,SAAS,EAAE,eAAe,CAAC;IACpC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC7B;;;;;;;;;;;CAYA,CAAC;AAEF,eAAO,MAAM,sBAAsB,GAAI,uCAIpC;IACC,QAAQ,CAAC,MAAM,EAAE;QACb,QAAQ,CAAC,IAAI,CAAC,EAAE,UAAU,CAAC;QAC3B,QAAQ,CAAC,KAAK,CAAC,EAAE,WAAW,CAAC;QAC7B,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;KAC3B,CAAC;IACF,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAC;IAClC,QAAQ,CAAC,cAAc,EAAE,cAAc,CAAC;CAC3C,YAeA,CAAC"}
@@ -2,11 +2,10 @@ import { readFile } from 'node:fs/promises';
2
2
  import * as v from 'valibot';
3
3
  import { mapWithConcurrencyLimit } from "./async.js";
4
4
  import { stableStringify } from "./json.js";
5
+ import { getLedgerRuntimeConfig } from "./runtime-config.js";
5
6
  import { LEDGER_KINDS, parseLedgerEntry } from "./schema/entry.js";
6
7
  import { readPhaseEntryText, resolveLedgerPaths, writeAtomicTextFile } from "./storage/filesystem.js";
7
8
  const READ_INDEX_SCHEMA_VERSION = 'ushman-ledger-read-index/v1';
8
- const ENTRY_READ_BATCH_SIZE = 32;
9
- const ENTRY_READ_CONCURRENCY = 16;
10
9
  const ReadIndexEntrySchema = v.object({
11
10
  id: v.pipe(v.string(), v.minLength(1)),
12
11
  kind: v.picklist(LEDGER_KINDS),
@@ -83,7 +82,7 @@ const readIndexedEntry = async ({ entryId, phase, workspaceRoot, }) => {
83
82
  const text = await readPhaseEntryText(workspaceRoot, phase, `${entryId}.json`);
84
83
  return parseLedgerEntry(JSON.parse(text));
85
84
  };
86
- const readIndexedEntryBatch = async ({ entryLocations, workspaceRoot, }) => mapWithConcurrencyLimit(entryLocations, ENTRY_READ_CONCURRENCY, async ([entryId, location]) => readIndexedEntry({
85
+ const readIndexedEntryBatch = async ({ entryReadConcurrency, entryLocations, workspaceRoot, }) => mapWithConcurrencyLimit(entryLocations, entryReadConcurrency, async ([entryId, location]) => readIndexedEntry({
87
86
  entryId,
88
87
  phase: location.phase,
89
88
  workspaceRoot,
@@ -97,12 +96,14 @@ const collectCoveredFiles = (entry, coveredFiles) => {
97
96
  }
98
97
  };
99
98
  export const buildReadIndexFromManifest = async (workspaceRoot, manifest) => {
99
+ const { readIndexRebuildBatchSize, readIndexRebuildConcurrency } = getLedgerRuntimeConfig();
100
100
  const orderedEntryLocations = getManifestSequenceLocations(manifest);
101
101
  const entries = [];
102
102
  const coveredFiles = new Set();
103
- for (let index = 0; index < orderedEntryLocations.length; index += ENTRY_READ_BATCH_SIZE) {
104
- const batch = orderedEntryLocations.slice(index, index + ENTRY_READ_BATCH_SIZE);
103
+ for (let index = 0; index < orderedEntryLocations.length; index += readIndexRebuildBatchSize) {
104
+ const batch = orderedEntryLocations.slice(index, index + readIndexRebuildBatchSize);
105
105
  const resolvedEntries = await readIndexedEntryBatch({
106
+ entryReadConcurrency: readIndexRebuildConcurrency,
106
107
  entryLocations: batch,
107
108
  workspaceRoot,
108
109
  });
@@ -1 +1 @@
1
- {"version":3,"file":"record.d.ts","sourceRoot":"","sources":["../src/record.ts"],"names":[],"mappings":"AASA,OAAO,EACH,KAAK,WAAW,EAKnB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAU3D,KAAK,qBAAqB,GAAG;IACzB,QAAQ,CAAC,eAAe,CAAC,EAAE,CAAC,OAAO,EAAE;QAAE,KAAK,EAAE,WAAW,CAAA;KAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9E,QAAQ,CAAC,iBAAiB,CAAC,EAAE,CAAC,OAAO,EAAE;QAAE,KAAK,EAAE,WAAW,CAAA;KAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAChF,QAAQ,CAAC,uBAAuB,CAAC,EAAE,CAAC,OAAO,EAAE;QAAE,KAAK,EAAE,WAAW,CAAC;QAAC,iBAAiB,EAAE,MAAM,CAAA;KAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACjH,QAAQ,CAAC,kBAAkB,CAAC,EAAE,CAAC,OAAO,EAAE;QAAE,KAAK,EAAE,WAAW,CAAA;KAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACpF,CAAC;AAOF,eAAO,MAAM,wBAAwB,GAAI,eAAe,MAAM,EAAE,OAAO,qBAAqB,GAAG,IAAI,SAOlG,CAAC;AA0EF,eAAO,MAAM,YAAY,GACrB,eAAe,MAAM,EACrB,OAAO,OAAO,KACf,OAAO,CAAC;IAAE,KAAK,EAAE,WAAW,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,CAsF5C,CAAC;AAEF,eAAO,MAAM,aAAa,GACtB,eAAe,MAAM,EACrB,UAAU,cAAc,EACxB,SAAS,MAAM,KAChB,OAAO,CAAC,WAAW,CAMrB,CAAC"}
1
+ {"version":3,"file":"record.d.ts","sourceRoot":"","sources":["../src/record.ts"],"names":[],"mappings":"AASA,OAAO,EACH,KAAK,WAAW,EAMnB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAU3D,KAAK,qBAAqB,GAAG;IACzB,QAAQ,CAAC,eAAe,CAAC,EAAE,CAAC,OAAO,EAAE;QAAE,KAAK,EAAE,WAAW,CAAA;KAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9E,QAAQ,CAAC,iBAAiB,CAAC,EAAE,CAAC,OAAO,EAAE;QAAE,KAAK,EAAE,WAAW,CAAA;KAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAChF,QAAQ,CAAC,uBAAuB,CAAC,EAAE,CAAC,OAAO,EAAE;QAAE,KAAK,EAAE,WAAW,CAAC;QAAC,iBAAiB,EAAE,MAAM,CAAA;KAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACjH,QAAQ,CAAC,kBAAkB,CAAC,EAAE,CAAC,OAAO,EAAE;QAAE,KAAK,EAAE,WAAW,CAAA;KAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACpF,CAAC;AAOF,eAAO,MAAM,wBAAwB,GAAI,eAAe,MAAM,EAAE,OAAO,qBAAqB,GAAG,IAAI,SAOlG,CAAC;AA0EF,eAAO,MAAM,YAAY,GACrB,eAAe,MAAM,EACrB,OAAO,OAAO,KACf,OAAO,CAAC;IAAE,KAAK,EAAE,WAAW,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,CAsF5C,CAAC;AAEF,eAAO,MAAM,aAAa,GACtB,eAAe,MAAM,EACrB,UAAU,cAAc,EACxB,SAAS,MAAM,KAChB,OAAO,CAAC,WAAW,CASrB,CAAC"}
package/dist/record.js CHANGED
@@ -2,12 +2,12 @@ import { readFile } from 'node:fs/promises';
2
2
  import path from 'node:path';
3
3
  import * as v from 'valibot';
4
4
  import { sha256Hex, stableStringify } from "./json.js";
5
+ import { getNextManifestSequence } from "./manifest-update.js";
5
6
  import { updateManifestForEntry } from "./manifest-update.js";
6
- import { LedgerSchemaVersion } from "./schema/entry.js";
7
7
  import { resolvePatchRecord } from "./patch-resolver.js";
8
8
  import { appendEntryToReadIndex, saveReadIndex } from "./read-index.js";
9
9
  import { reconcileLedgerStateUnderLock, removePendingCommit, writePendingCommit } from "./recovery.js";
10
- import { LedgerEntrySchema, parseLedgerEntry, parseLedgerRecord, } from "./schema/entry.js";
10
+ import { LedgerEntrySchema, LedgerSchemaVersion, parseLedgerEntry, parseLedgerRecord, } from "./schema/entry.js";
11
11
  import { ensureLedgerDirectories, readManifest, resolveLedgerPaths, saveManifest, writeEntryFile, } from "./storage/filesystem.js";
12
12
  import { acquireLock } from "./storage/lock.js";
13
13
  const appendRecordTestHooks = new Map();
@@ -106,7 +106,7 @@ export const appendRecord = async (workspaceRoot, input) => {
106
106
  id: existingId,
107
107
  };
108
108
  }
109
- const nextSequence = manifest.lastSequence + 1;
109
+ const nextSequence = getNextManifestSequence(manifest.lastSequence);
110
110
  const { idempotencyKey: _idempotencyKey, ...recordWithoutIdempotencyKey } = normalizedRecord;
111
111
  const entryWithoutId = {
112
112
  ...recordWithoutIdempotencyKey,
@@ -1,3 +1,10 @@
1
1
  import type { LedgerEntry } from '../schema/entry.ts';
2
- export declare const renderMigrationLogMarkdown: (entries: AsyncIterable<LedgerEntry>) => Promise<string>;
2
+ export declare const writeMigrationLogMarkdown: ({ entries, write, }: {
3
+ readonly entries: AsyncIterable<LedgerEntry>;
4
+ readonly write: (chunk: string) => Promise<void> | void;
5
+ }) => Promise<void>;
6
+ export declare const renderMigrationLogMarkdown: ({ entries, write, }: {
7
+ readonly entries: AsyncIterable<LedgerEntry>;
8
+ readonly write?: (chunk: string) => Promise<void> | void;
9
+ }) => Promise<string>;
3
10
  //# sourceMappingURL=migration-log.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"migration-log.d.ts","sourceRoot":"","sources":["../../src/render/migration-log.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAuC,WAAW,EAAE,MAAM,oBAAoB,CAAC;AA2C3F,eAAO,MAAM,0BAA0B,GAAU,SAAS,aAAa,CAAC,WAAW,CAAC,KAAG,OAAO,CAAC,MAAM,CAwCpG,CAAC"}
1
+ {"version":3,"file":"migration-log.d.ts","sourceRoot":"","sources":["../../src/render/migration-log.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAuC,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAmE3F,eAAO,MAAM,yBAAyB,GAAU,qBAG7C;IACC,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC,WAAW,CAAC,CAAC;IAC7C,QAAQ,CAAC,KAAK,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;CAC3D,kBAaA,CAAC;AAEF,eAAO,MAAM,0BAA0B,GAAU,qBAG9C;IACC,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC,WAAW,CAAC,CAAC;IAC7C,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;CAC5D,KAAG,OAAO,CAAC,MAAM,CASjB,CAAC"}
@@ -32,41 +32,48 @@ const renderSmokeLine = (entry) => {
32
32
  return '**Smoke result**: Not recorded.';
33
33
  };
34
34
  const isChangeLogEntry = (entry) => entry.kind === 'change-log';
35
- export const renderMigrationLogMarkdown = async (entries) => {
36
- const changeLogEntries = [];
35
+ const renderChangeLogSection = (entry) => [
36
+ `## ${entry.ts} - ${entry.summary}`,
37
+ '',
38
+ `**Type**: ${entry.subkind}`,
39
+ '',
40
+ '**Files changed**:',
41
+ renderFilesChanged(entry.filesChanged),
42
+ '',
43
+ renderOptionalLine('Hypothesis', entry.hypothesis),
44
+ '',
45
+ '**Commands run**:',
46
+ toCodeBlock(entry.commandsRun),
47
+ '',
48
+ renderSmokeLine(entry),
49
+ '',
50
+ renderOptionalLine('Parity status', entry.parityStatus),
51
+ '',
52
+ renderOptionalLine('Rollback plan', entry.rollbackPlan),
53
+ '',
54
+ '---',
55
+ '',
56
+ ].join('\n');
57
+ export const writeMigrationLogMarkdown = async ({ entries, write, }) => {
58
+ await write('# Ushman Ledger Migration Log\n\n');
59
+ let hasEntries = false;
37
60
  for await (const entry of entries) {
38
- if (isChangeLogEntry(entry)) {
39
- changeLogEntries.push(entry);
61
+ if (!isChangeLogEntry(entry)) {
62
+ continue;
40
63
  }
64
+ hasEntries = true;
65
+ await write(renderChangeLogSection(entry));
41
66
  }
42
- changeLogEntries.reverse();
43
- if (changeLogEntries.length === 0) {
44
- return ['# Ushman Ledger Migration Log', '', 'No change-log entries recorded.'].join('\n');
67
+ if (!hasEntries) {
68
+ await write('No change-log entries recorded.');
45
69
  }
46
- return [
47
- '# Ushman Ledger Migration Log',
48
- '',
49
- ...changeLogEntries.flatMap((entry) => [
50
- `## ${entry.ts} - ${entry.summary}`,
51
- '',
52
- `**Type**: ${entry.subkind}`,
53
- '',
54
- '**Files changed**:',
55
- renderFilesChanged(entry.filesChanged),
56
- '',
57
- renderOptionalLine('Hypothesis', entry.hypothesis),
58
- '',
59
- '**Commands run**:',
60
- toCodeBlock(entry.commandsRun),
61
- '',
62
- renderSmokeLine(entry),
63
- '',
64
- renderOptionalLine('Parity status', entry.parityStatus),
65
- '',
66
- renderOptionalLine('Rollback plan', entry.rollbackPlan),
67
- '',
68
- '---',
69
- '',
70
- ]),
71
- ].join('\n');
70
+ };
71
+ export const renderMigrationLogMarkdown = async ({ entries, write, }) => {
72
+ const chunks = [];
73
+ const resolvedWriter = write ??
74
+ ((chunk) => {
75
+ chunks.push(chunk);
76
+ });
77
+ await writeMigrationLogMarkdown({ entries, write: resolvedWriter });
78
+ return chunks.join('');
72
79
  };
@@ -1 +1 @@
1
- {"version":3,"file":"retro.d.ts","sourceRoot":"","sources":["../../src/render/retro.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAgItD,eAAO,MAAM,mBAAmB,GAAU,wBAGvC;IACC,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC,WAAW,CAAC,CAAC;IAC7C,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;CAC9B,KAAG,OAAO,CAAC,MAAM,CAgDjB,CAAC"}
1
+ {"version":3,"file":"retro.d.ts","sourceRoot":"","sources":["../../src/render/retro.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AA4HtD,eAAO,MAAM,mBAAmB,GAAU,wBAGvC;IACC,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC,WAAW,CAAC,CAAC;IAC7C,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;CAC9B,KAAG,OAAO,CAAC,MAAM,CAgDjB,CAAC"}
@@ -21,13 +21,7 @@ const isRetroNote = (entry) => entry.kind === 'note' && entry.subkind === 'retro
21
21
  const isOperatorNote = (entry) => entry.kind === 'note' && entry.subkind === 'operator';
22
22
  const isDedicatedNarrativeEntry = (entry) => entry.kind === 'change-log' ||
23
23
  (entry.kind === 'note' &&
24
- [
25
- 'cleanup-wave',
26
- 'verified-flow',
27
- 'open-issue',
28
- 'decomposition-wave',
29
- 'semantic-cleanup-summary',
30
- ].includes(entry.subkind));
24
+ ['cleanup-wave', 'verified-flow', 'open-issue', 'decomposition-wave', 'semantic-cleanup-summary'].includes(entry.subkind));
31
25
  const resolveRenderedAt = (entryCount, lastEntryTimestamp, manifest) => {
32
26
  if (entryCount > 0) {
33
27
  return lastEntryTimestamp ?? 'n/a';
@@ -1,6 +1,12 @@
1
1
  import type { LedgerEntry } from '../schema/entry.ts';
2
- export declare const renderWorkspaceNarrativeMarkdown: ({ entries, workspaceName, }: {
2
+ export declare const writeWorkspaceNarrativeMarkdown: ({ entries, workspaceName, write, }: {
3
3
  readonly entries: AsyncIterable<LedgerEntry>;
4
4
  readonly workspaceName: string;
5
+ readonly write: (chunk: string) => Promise<void> | void;
6
+ }) => Promise<void>;
7
+ export declare const renderWorkspaceNarrativeMarkdown: ({ entries, workspaceName, write, }: {
8
+ readonly entries: AsyncIterable<LedgerEntry>;
9
+ readonly workspaceName: string;
10
+ readonly write?: (chunk: string) => Promise<void> | void;
5
11
  }) => Promise<string>;
6
12
  //# sourceMappingURL=workspace-narrative.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"workspace-narrative.d.ts","sourceRoot":"","sources":["../../src/render/workspace-narrative.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAa,MAAM,oBAAoB,CAAC;AAsCjE,eAAO,MAAM,gCAAgC,GAAU,6BAGpD;IACC,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC,WAAW,CAAC,CAAC;IAC7C,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;CAClC,KAAG,OAAO,CAAC,MAAM,CA+CjB,CAAC"}
1
+ {"version":3,"file":"workspace-narrative.d.ts","sourceRoot":"","sources":["../../src/render/workspace-narrative.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAa,MAAM,oBAAoB,CAAC;AAuIjE,eAAO,MAAM,+BAA+B,GAAU,oCAInD;IACC,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC,WAAW,CAAC,CAAC;IAC7C,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,KAAK,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;CAC3D,kBA+BA,CAAC;AAEF,eAAO,MAAM,gCAAgC,GAAU,oCAIpD;IACC,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC,WAAW,CAAC,CAAC;IAC7C,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;CAC5D,KAAG,OAAO,CAAC,MAAM,CAajB,CAAC"}
@@ -14,56 +14,124 @@ const NARRATIVE_SUBKINDS = [
14
14
  'semantic-cleanup-summary',
15
15
  ];
16
16
  const isNarrativeNote = (entry) => entry.kind === 'note' && NARRATIVE_SUBKINDS.some((subkind) => subkind === entry.subkind);
17
- const byNewestFirst = (left, right) => right.ts.localeCompare(left.ts);
18
- const renderBulletSection = (entries) => entries.length === 0
19
- ? '- None recorded.'
20
- : entries.map((entry) => `- ${entry.ts} — ${entry.summary}`).join('\n');
21
- const renderLatestSummary = (entries) => {
22
- const [latest] = entries;
23
- if (!latest) {
24
- return 'No entries recorded.';
25
- }
26
- return [`### ${latest.ts} — ${latest.summary}`, '', latest.body || 'No narrative body recorded.'].join('\n');
27
- };
28
- export const renderWorkspaceNarrativeMarkdown = async ({ entries, workspaceName, }) => {
29
- const entriesBySubkind = new Map(NARRATIVE_SUBKINDS.map((subkind) => [subkind, []]));
17
+ const renderSummaryBullet = (entry) => `- ${entry.ts} — ${entry.summary}`;
18
+ const collectNarrativeSections = async (entries) => {
19
+ let latestSummary = null;
20
+ const cleanupWaveEntries = [];
21
+ const decompositionWaveEntries = [];
22
+ const openIssueEntries = [];
23
+ const summaryArchiveEntries = [];
24
+ const verifiedFlowEntries = [];
30
25
  for await (const entry of entries) {
31
26
  if (!isNarrativeNote(entry)) {
32
27
  continue;
33
28
  }
34
- entriesBySubkind.get(entry.subkind)?.push(entry);
29
+ switch (entry.subkind) {
30
+ case 'cleanup-wave':
31
+ cleanupWaveEntries.push(entry);
32
+ break;
33
+ case 'decomposition-wave':
34
+ decompositionWaveEntries.push(entry);
35
+ break;
36
+ case 'open-issue':
37
+ openIssueEntries.push(entry);
38
+ break;
39
+ case 'semantic-cleanup-summary':
40
+ if (!latestSummary) {
41
+ latestSummary = entry;
42
+ break;
43
+ }
44
+ summaryArchiveEntries.push(entry);
45
+ break;
46
+ case 'verified-flow':
47
+ verifiedFlowEntries.push(entry);
48
+ break;
49
+ }
50
+ }
51
+ return {
52
+ cleanupWaveEntries,
53
+ decompositionWaveEntries,
54
+ latestSummary,
55
+ openIssueEntries,
56
+ summaryArchiveEntries,
57
+ verifiedFlowEntries,
58
+ };
59
+ };
60
+ const writeBulletSection = async ({ entries, title, write, }) => {
61
+ await write(`${title}\n\n`);
62
+ if (entries.length === 0) {
63
+ await write('- None recorded.\n');
64
+ await write('\n');
65
+ return;
66
+ }
67
+ for (const entry of entries) {
68
+ await write(`${renderSummaryBullet(entry)}\n`);
35
69
  }
36
- for (const noteEntries of entriesBySubkind.values()) {
37
- noteEntries.sort(byNewestFirst);
70
+ await write('\n');
71
+ };
72
+ const writeLatestSummarySection = async ({ latestSummary, write, }) => {
73
+ await write(`${SECTION_TITLES.semanticCleanupSummary}\n\n`);
74
+ if (latestSummary) {
75
+ await write(`### ${latestSummary.ts} — ${latestSummary.summary}\n\n`);
76
+ await write(`${latestSummary.body || 'No narrative body recorded.'}\n\n`);
77
+ return;
78
+ }
79
+ await write('No entries recorded.\n\n');
80
+ };
81
+ const writeSummaryArchiveSection = async ({ entries, write, }) => {
82
+ await write(`${SECTION_TITLES.semanticCleanupSummaryArchive}\n\n`);
83
+ if (entries.length === 0) {
84
+ await write('- None recorded.\n');
85
+ await write('\n');
86
+ return;
38
87
  }
39
- const semanticCleanupSummaries = entriesBySubkind.get('semantic-cleanup-summary') ?? [];
40
- const [, ...archivedSummaries] = semanticCleanupSummaries;
41
- return [
42
- `# Workspace narrative — ${workspaceName}`,
43
- '',
44
- SECTION_TITLES.semanticCleanupSummary,
45
- '',
46
- renderLatestSummary(semanticCleanupSummaries),
47
- '',
48
- SECTION_TITLES.cleanupWave,
49
- '',
50
- renderBulletSection(entriesBySubkind.get('cleanup-wave') ?? []),
51
- '',
52
- SECTION_TITLES.verifiedFlow,
53
- '',
54
- renderBulletSection(entriesBySubkind.get('verified-flow') ?? []),
55
- '',
56
- SECTION_TITLES.openIssue,
57
- '',
58
- renderBulletSection(entriesBySubkind.get('open-issue') ?? []),
59
- '',
60
- SECTION_TITLES.decompositionWave,
61
- '',
62
- renderBulletSection(entriesBySubkind.get('decomposition-wave') ?? []),
63
- '',
64
- SECTION_TITLES.semanticCleanupSummaryArchive,
65
- '',
66
- renderBulletSection(archivedSummaries),
67
- '',
68
- ].join('\n');
88
+ for (const entry of entries) {
89
+ await write(`${renderSummaryBullet(entry)}\n`);
90
+ }
91
+ await write('\n');
92
+ };
93
+ export const writeWorkspaceNarrativeMarkdown = async ({ entries, workspaceName, write, }) => {
94
+ const sections = await collectNarrativeSections(entries);
95
+ await write(`# Workspace narrative — ${workspaceName}\n\n`);
96
+ await writeLatestSummarySection({
97
+ latestSummary: sections.latestSummary,
98
+ write,
99
+ });
100
+ await writeBulletSection({
101
+ entries: sections.cleanupWaveEntries,
102
+ title: SECTION_TITLES.cleanupWave,
103
+ write,
104
+ });
105
+ await writeBulletSection({
106
+ entries: sections.verifiedFlowEntries,
107
+ title: SECTION_TITLES.verifiedFlow,
108
+ write,
109
+ });
110
+ await writeBulletSection({
111
+ entries: sections.openIssueEntries,
112
+ title: SECTION_TITLES.openIssue,
113
+ write,
114
+ });
115
+ await writeBulletSection({
116
+ entries: sections.decompositionWaveEntries,
117
+ title: SECTION_TITLES.decompositionWave,
118
+ write,
119
+ });
120
+ await writeSummaryArchiveSection({
121
+ entries: sections.summaryArchiveEntries,
122
+ write,
123
+ });
124
+ };
125
+ export const renderWorkspaceNarrativeMarkdown = async ({ entries, workspaceName, write, }) => {
126
+ const chunks = [];
127
+ const resolvedWriter = write ??
128
+ ((chunk) => {
129
+ chunks.push(chunk);
130
+ });
131
+ await writeWorkspaceNarrativeMarkdown({
132
+ entries,
133
+ workspaceName,
134
+ write: resolvedWriter,
135
+ });
136
+ return chunks.join('');
69
137
  };
@@ -0,0 +1,12 @@
1
+ export type LedgerRuntimeConfig = {
2
+ readonly blobHashConcurrency: number;
3
+ readonly coverageFileStatConcurrency: number;
4
+ readonly maxPatchBytes: number;
5
+ readonly readIndexRebuildBatchSize: number;
6
+ readonly readIndexRebuildConcurrency: number;
7
+ readonly scanBatchSize: number;
8
+ readonly scanConcurrency: number;
9
+ };
10
+ export declare const validateLedgerRuntimeConfig: (env?: NodeJS.ProcessEnv) => void;
11
+ export declare const getLedgerRuntimeConfig: (env?: NodeJS.ProcessEnv) => LedgerRuntimeConfig;
12
+ //# sourceMappingURL=runtime-config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime-config.d.ts","sourceRoot":"","sources":["../src/runtime-config.ts"],"names":[],"mappings":"AAgCA,MAAM,MAAM,mBAAmB,GAAG;IAC9B,QAAQ,CAAC,mBAAmB,EAAE,MAAM,CAAC;IACrC,QAAQ,CAAC,2BAA2B,EAAE,MAAM,CAAC;IAC7C,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,yBAAyB,EAAE,MAAM,CAAC;IAC3C,QAAQ,CAAC,2BAA2B,EAAE,MAAM,CAAC;IAC7C,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;CACpC,CAAC;AAuDF,eAAO,MAAM,2BAA2B,GAAI,MAAK,MAAM,CAAC,UAAwB,SAE/E,CAAC;AAEF,eAAO,MAAM,sBAAsB,GAAI,MAAK,MAAM,CAAC,UAAwB,KAAG,mBAgB7E,CAAC"}
@@ -0,0 +1,83 @@
1
+ const DEFAULT_SCAN_BATCH_SIZE = 32;
2
+ const DEFAULT_SCAN_CONCURRENCY = 16;
3
+ const DEFAULT_MAX_PATCH_BYTES = 10 * 1024 * 1024;
4
+ const RUNTIME_CONFIG_ENV_VARS = [
5
+ 'USHMAN_LEDGER_BLOB_HASH_CONCURRENCY',
6
+ 'USHMAN_LEDGER_COVERAGE_FILE_STAT_CONCURRENCY',
7
+ 'USHMAN_LEDGER_MAX_PATCH_BYTES',
8
+ 'USHMAN_LEDGER_READ_INDEX_REBUILD_BATCH_SIZE',
9
+ 'USHMAN_LEDGER_READ_INDEX_REBUILD_CONCURRENCY',
10
+ 'USHMAN_LEDGER_SCAN_BATCH_SIZE',
11
+ 'USHMAN_LEDGER_SCAN_CONCURRENCY',
12
+ ];
13
+ const parsePositiveIntegerEnv = ({ defaultValue, env, envVar, }) => {
14
+ const rawValue = env[envVar];
15
+ if (!rawValue) {
16
+ return defaultValue;
17
+ }
18
+ if (!/^[1-9]\d*$/u.test(rawValue)) {
19
+ throw new Error(`Invalid ${envVar} value: ${rawValue}. Expected a positive integer.`);
20
+ }
21
+ return Number.parseInt(rawValue, 10);
22
+ };
23
+ let processEnvRuntimeConfigCache;
24
+ const getRuntimeConfigSignature = (env) => RUNTIME_CONFIG_ENV_VARS.map((envVar) => `${envVar}=${env[envVar] ?? ''}`).join('\u0000');
25
+ const buildLedgerRuntimeConfig = (env) => {
26
+ const scanBatchSize = parsePositiveIntegerEnv({
27
+ defaultValue: DEFAULT_SCAN_BATCH_SIZE,
28
+ env,
29
+ envVar: 'USHMAN_LEDGER_SCAN_BATCH_SIZE',
30
+ });
31
+ const scanConcurrency = parsePositiveIntegerEnv({
32
+ defaultValue: DEFAULT_SCAN_CONCURRENCY,
33
+ env,
34
+ envVar: 'USHMAN_LEDGER_SCAN_CONCURRENCY',
35
+ });
36
+ return {
37
+ blobHashConcurrency: parsePositiveIntegerEnv({
38
+ defaultValue: scanConcurrency,
39
+ env,
40
+ envVar: 'USHMAN_LEDGER_BLOB_HASH_CONCURRENCY',
41
+ }),
42
+ coverageFileStatConcurrency: parsePositiveIntegerEnv({
43
+ defaultValue: scanConcurrency,
44
+ env,
45
+ envVar: 'USHMAN_LEDGER_COVERAGE_FILE_STAT_CONCURRENCY',
46
+ }),
47
+ maxPatchBytes: parsePositiveIntegerEnv({
48
+ defaultValue: DEFAULT_MAX_PATCH_BYTES,
49
+ env,
50
+ envVar: 'USHMAN_LEDGER_MAX_PATCH_BYTES',
51
+ }),
52
+ readIndexRebuildBatchSize: parsePositiveIntegerEnv({
53
+ defaultValue: scanBatchSize,
54
+ env,
55
+ envVar: 'USHMAN_LEDGER_READ_INDEX_REBUILD_BATCH_SIZE',
56
+ }),
57
+ readIndexRebuildConcurrency: parsePositiveIntegerEnv({
58
+ defaultValue: scanConcurrency,
59
+ env,
60
+ envVar: 'USHMAN_LEDGER_READ_INDEX_REBUILD_CONCURRENCY',
61
+ }),
62
+ scanBatchSize,
63
+ scanConcurrency,
64
+ };
65
+ };
66
+ export const validateLedgerRuntimeConfig = (env = process.env) => {
67
+ void getLedgerRuntimeConfig(env);
68
+ };
69
+ export const getLedgerRuntimeConfig = (env = process.env) => {
70
+ if (env !== process.env) {
71
+ return buildLedgerRuntimeConfig(env);
72
+ }
73
+ const signature = getRuntimeConfigSignature(env);
74
+ if (processEnvRuntimeConfigCache?.signature === signature) {
75
+ return processEnvRuntimeConfigCache.config;
76
+ }
77
+ const config = buildLedgerRuntimeConfig(env);
78
+ processEnvRuntimeConfigCache = {
79
+ config,
80
+ signature,
81
+ };
82
+ return config;
83
+ };
@@ -1 +1 @@
1
- {"version":3,"file":"entry-read.d.ts","sourceRoot":"","sources":["../../src/schema/entry-read.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,SAAS,CAAC;AAc7B,eAAO,MAAM,yBAAyB;;;;;;;;;;;;;;;;;;;;;;;;;;;;aAMpC,CAAC;AAQH,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;aAOhC,CAAC;AAEH,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;aAMnC,CAAC;AAEH,eAAO,MAAM,2BAA2B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;aAItC,CAAC;AAEH,eAAO,MAAM,0BAA0B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;aAOrC,CAAC;AAEH,eAAO,MAAM,uBAAuB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;aAOlC,CAAC;AAEH,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;aAK1B,CAAC;AAEH,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;yDAUjC,CAAC;AAEF,eAAO,MAAM,gCAAgC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;aAI3C,CAAC;AAEH,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;aAY/B,CAAC;AAEH,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;0BAW5B,CAAC;AAEH,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,WAAW,CAAC,OAAO,oBAAoB,CAAC,CAAC;AACxE,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,WAAW,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAClE,MAAM,MAAM,SAAS,GAAG,OAAO,CAAC,WAAW,EAAE;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC"}
1
+ {"version":3,"file":"entry-read.d.ts","sourceRoot":"","sources":["../../src/schema/entry-read.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,SAAS,CAAC;AAc7B,eAAO,MAAM,yBAAyB;;;;;;;;;;;;;;;;;;;;;;;;;;;;aAMpC,CAAC;AAQH,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;aAOhC,CAAC;AAEH,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;aAMnC,CAAC;AAEH,eAAO,MAAM,2BAA2B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;aAItC,CAAC;AAEH,eAAO,MAAM,0BAA0B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;aAOrC,CAAC;AAEH,eAAO,MAAM,uBAAuB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;aAOlC,CAAC;AAEH,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;aAK1B,CAAC;AAEH,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;yDAOjC,CAAC;AAEF,eAAO,MAAM,gCAAgC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;aAI3C,CAAC;AAEH,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;aAY/B,CAAC;AAEH,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;0BAW5B,CAAC;AAEH,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,WAAW,CAAC,OAAO,oBAAoB,CAAC,CAAC;AACxE,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,WAAW,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAClE,MAAM,MAAM,SAAS,GAAG,OAAO,CAAC,WAAW,EAAE;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC"}
@@ -1,6 +1,6 @@
1
1
  import * as v from 'valibot';
2
- import { NoteSubkindSchema } from "./note.js";
3
2
  import { AgentPatchDiffSchema, ChangeLogFileChangeSchema, ChangeLogParityStatusSchema, ChangeLogSmokeResultSchema, ChangeLogSubkindSchema, ledgerEntryBaseEntries, NonEmptyTrimmedStringSchema, OperatorDecisionPayloadSchema, StripDecisionRevertedPayloadSchema, } from "./entry-core.js";
3
+ import { NoteSubkindSchema } from "./note.js";
4
4
  export const ToolInvocationEntrySchema = v.object({
5
5
  ...ledgerEntryBaseEntries,
6
6
  args: v.optional(v.array(v.string())),
@@ -1 +1 @@
1
- {"version":3,"file":"entry-write.d.ts","sourceRoot":"","sources":["../../src/schema/entry-write.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,SAAS,CAAC;AAoC7B,eAAO,MAAM,0BAA0B;;;;;;;;;;;;;;;;;;;;;;;;;aAMrC,CAAC;AAUH,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8HAUlC,CAAC;AAEF,eAAO,MAAM,yBAAyB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8HASrC,CAAC;AAEF,eAAO,MAAM,4BAA4B;;;;;;;;;;;;;;;;;;;;;;;;;;;aAIvC,CAAC;AAEH,eAAO,MAAM,2BAA2B;;;;;;;;;;;;;;;;;;;;;;;;;;aAOtC,CAAC;AAEH,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;;;;;;;;;;;;;aAOnC,CAAC;AAEH,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;aAK3B,CAAC;AAEH,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;yDAUlC,CAAC;AAEF,eAAO,MAAM,iCAAiC;;;;;;;;;;;;;;;;;;;;;;;;;;;aAI5C,CAAC;AAEH,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;qDAkBjC,CAAC;AAEF,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kEAW7B,CAAC;AAEH,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,WAAW,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAC1E,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,WAAW,CAAC,OAAO,kBAAkB,CAAC,CAAC"}
1
+ {"version":3,"file":"entry-write.d.ts","sourceRoot":"","sources":["../../src/schema/entry-write.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,SAAS,CAAC;AAoC7B,eAAO,MAAM,0BAA0B;;;;;;;;;;;;;;;;;;;;;;;;;aAMrC,CAAC;AAUH,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8HAUlC,CAAC;AAEF,eAAO,MAAM,yBAAyB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8HASrC,CAAC;AAEF,eAAO,MAAM,4BAA4B;;;;;;;;;;;;;;;;;;;;;;;;;;;aAIvC,CAAC;AAEH,eAAO,MAAM,2BAA2B;;;;;;;;;;;;;;;;;;;;;;;;;;aAOtC,CAAC;AAEH,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;;;;;;;;;;;;;aAOnC,CAAC;AAEH,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;aAK3B,CAAC;AAEH,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;yDAOlC,CAAC;AAEF,eAAO,MAAM,iCAAiC;;;;;;;;;;;;;;;;;;;;;;;;;;;aAI5C,CAAC;AAEH,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;qDAkBjC,CAAC;AAEF,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kEAW7B,CAAC;AAEH,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,WAAW,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAC1E,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,WAAW,CAAC,OAAO,kBAAkB,CAAC,CAAC"}
@@ -1,6 +1,6 @@
1
1
  import * as v from 'valibot';
2
- import { NoteSubkindSchema } from "./note.js";
3
2
  import { AgentPatchDiffSchema, ChangeLogFileChangeSchema, ChangeLogParityStatusSchema, ChangeLogSmokeResultSchema, ChangeLogSubkindSchema, NonEmptyTrimmedStringSchema, OperatorDecisionPayloadSchema, recordEntryBaseEntries, StripDecisionRevertedPayloadSchema, } from "./entry-core.js";
3
+ import { NoteSubkindSchema } from "./note.js";
4
4
  const validatePatchRecord = (value) => {
5
5
  const provided = [value.diff, value.diffPath, value.diffText].filter((entry) => Boolean(entry));
6
6
  if (provided.length === 0) {
@@ -1 +1 @@
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
+ {"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,WACY,CAAC;AAE/D,eAAO,MAAM,iBAAiB,GAAI,OAAO,OAAO,KAAG,YACa,CAAC"}
@@ -5,6 +5,8 @@ export declare const LEDGER_ROOT_SEGMENTS: readonly [".lab", "ledger"];
5
5
  export declare const LEDGER_STALE_TEMP_MS = 60000;
6
6
  type AtomicWriteTestHook = {
7
7
  readonly beforeRename?: () => Promise<void>;
8
+ readonly beforeWrite?: () => Promise<void>;
9
+ readonly retainOnThrow?: boolean;
8
10
  };
9
11
  export type LedgerPaths = {
10
12
  readonly blobsDir: string;
@@ -22,10 +24,16 @@ export type LedgerPaths = {
22
24
  readonly root: string;
23
25
  readonly workspaceRoot: string;
24
26
  };
27
+ export type AtomicTextFileWriter = {
28
+ readonly abort: () => Promise<void>;
29
+ readonly close: () => Promise<void>;
30
+ readonly write: (chunk: string) => Promise<void>;
31
+ };
25
32
  export declare const resolveLedgerPaths: (workspaceRoot: string) => LedgerPaths;
26
33
  export declare const ensureLedgerDirectories: (workspaceRoot: string) => Promise<LedgerPaths>;
27
34
  export declare const setAtomicWriteTestHook: (filePath: string, hook: AtomicWriteTestHook | null) => void;
28
35
  export declare const writeAtomicTextFile: (filePath: string, text: string) => Promise<void>;
36
+ export declare const createAtomicTextFileWriter: (filePath: string) => Promise<AtomicTextFileWriter>;
29
37
  export declare const writeAtomicJsonFile: (filePath: string, value: unknown) => Promise<void>;
30
38
  export declare const readManifest: (workspaceRoot: string) => Promise<LedgerManifest>;
31
39
  export declare const saveManifest: (workspaceRoot: string, manifest: LedgerManifest) => Promise<void>;
@@ -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,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"}
1
+ {"version":3,"file":"filesystem.d.ts","sourceRoot":"","sources":["../../src/storage/filesystem.ts"],"names":[],"mappings":"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"}