@ai-dossier/sched 0.2.0 → 0.3.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 (58) hide show
  1. package/README.md +85 -17
  2. package/dist/dispatch.d.ts +128 -0
  3. package/dist/dispatch.d.ts.map +1 -0
  4. package/dist/dispatch.js +300 -0
  5. package/dist/dispatch.js.map +1 -0
  6. package/dist/engine.d.ts +111 -0
  7. package/dist/engine.d.ts.map +1 -0
  8. package/dist/engine.js +936 -0
  9. package/dist/engine.js.map +1 -0
  10. package/dist/enqueue.d.ts +38 -0
  11. package/dist/enqueue.d.ts.map +1 -0
  12. package/dist/enqueue.js +222 -0
  13. package/dist/enqueue.js.map +1 -0
  14. package/dist/groundtruth.d.ts +135 -0
  15. package/dist/groundtruth.d.ts.map +1 -0
  16. package/dist/groundtruth.js +259 -0
  17. package/dist/groundtruth.js.map +1 -0
  18. package/dist/index.d.ts +14 -0
  19. package/dist/index.d.ts.map +1 -0
  20. package/dist/index.js +101 -0
  21. package/dist/index.js.map +1 -0
  22. package/dist/journal.d.ts +32 -0
  23. package/dist/journal.d.ts.map +1 -0
  24. package/dist/journal.js +113 -0
  25. package/dist/journal.js.map +1 -0
  26. package/dist/persist.d.ts +54 -0
  27. package/dist/persist.d.ts.map +1 -0
  28. package/dist/persist.js +348 -0
  29. package/dist/persist.js.map +1 -0
  30. package/dist/project.d.ts +41 -0
  31. package/dist/project.d.ts.map +1 -0
  32. package/dist/project.js +124 -0
  33. package/dist/project.js.map +1 -0
  34. package/dist/readiness.d.ts +43 -0
  35. package/dist/readiness.d.ts.map +1 -0
  36. package/dist/readiness.js +102 -0
  37. package/dist/readiness.js.map +1 -0
  38. package/dist/scheduler.d.ts +78 -0
  39. package/dist/scheduler.d.ts.map +1 -0
  40. package/dist/scheduler.js +191 -0
  41. package/dist/scheduler.js.map +1 -0
  42. package/dist/state.d.ts +40 -0
  43. package/dist/state.d.ts.map +1 -0
  44. package/dist/state.js +391 -0
  45. package/dist/state.js.map +1 -0
  46. package/dist/status.d.ts +44 -0
  47. package/dist/status.d.ts.map +1 -0
  48. package/dist/status.js +82 -0
  49. package/dist/status.js.map +1 -0
  50. package/dist/teardown.d.ts +57 -0
  51. package/dist/teardown.d.ts.map +1 -0
  52. package/dist/teardown.js +242 -0
  53. package/dist/teardown.js.map +1 -0
  54. package/dist/types.d.ts +253 -0
  55. package/dist/types.d.ts.map +1 -0
  56. package/dist/types.js +91 -0
  57. package/dist/types.js.map +1 -0
  58. package/package.json +1 -1
@@ -0,0 +1,259 @@
1
+ "use strict";
2
+ /**
3
+ * Ground truth for completion verification (#464, AC2 — "an agent exiting is
4
+ * never proof of completion"). The engine never trusts the spawned agent's own
5
+ * exit; it reconciles the claimed state against the durable sources — the
6
+ * issue's runstate milestone trail (`ai-dossier runstate last`), GitHub
7
+ * itself (`gh issue view`), and `git ls-remote` for the "new pushed commit"
8
+ * stall signal. #468 adds the parked-PR state (`gh pr view`) and the setup
9
+ * milestone's teardown keys (`gh issue view --json comments`).
10
+ *
11
+ * Everything is injectable (the `ExecFn` pattern from project.ts): tests —
12
+ * and any consumer — supply fake ground truth and no subprocess runs.
13
+ */
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.groundTruthExec = void 0;
16
+ exports.parseMilestoneJson = parseMilestoneJson;
17
+ exports.createExecGroundTruth = createExecGroundTruth;
18
+ exports.parsePrViewJson = parsePrViewJson;
19
+ exports.parseSetupInfo = parseSetupInfo;
20
+ exports.prOfMilestone = prOfMilestone;
21
+ exports.isParkedMilestone = isParkedMilestone;
22
+ exports.isVerifiedComplete = isVerifiedComplete;
23
+ const project_1 = require("./project");
24
+ /** Subprocess timeout: a hung gh/git call must not stall a tick. */
25
+ const GROUND_TRUTH_TIMEOUT_MS = 30_000;
26
+ /**
27
+ * Default exec for ground-truth calls: like project.ts's `defaultExec` (never
28
+ * throws) but with a hard timeout so a hung `gh`/`git` cannot stall a tick
29
+ * indefinitely (ground truth is polled outside the state lock), and a failure
30
+ * observer that warns on stderr — a broken ground-truth environment (gh auth
31
+ * expired, `ai-dossier` missing from a cron PATH) is never silent.
32
+ */
33
+ exports.groundTruthExec = (0, project_1.createExecFn)(GROUND_TRUTH_TIMEOUT_MS, {
34
+ onError: (file, args, err) => process.stderr.write(`⚠ sched ground truth: '${file} ${args.join(' ')}' failed: ${err.message}\n`),
35
+ });
36
+ /** Parse the stdout of `ai-dossier runstate last --issue N --json`. */
37
+ function parseMilestoneJson(stdout) {
38
+ if (stdout === null || stdout.trim() === '' || stdout.trim() === 'null')
39
+ return null;
40
+ try {
41
+ const parsed = JSON.parse(stdout);
42
+ if (parsed === null || typeof parsed !== 'object')
43
+ return null;
44
+ const obj = parsed;
45
+ if (typeof obj.phase !== 'string' ||
46
+ typeof obj.status !== 'string' ||
47
+ typeof obj.at !== 'string') {
48
+ return null;
49
+ }
50
+ const keys = {};
51
+ for (const [key, value] of Object.entries(obj)) {
52
+ if (typeof value === 'string')
53
+ keys[key] = value;
54
+ }
55
+ return {
56
+ phase: obj.phase,
57
+ status: obj.status,
58
+ run: typeof obj.run === 'string' ? obj.run : '',
59
+ at: obj.at,
60
+ keys,
61
+ };
62
+ }
63
+ catch {
64
+ return null;
65
+ }
66
+ }
67
+ /**
68
+ * Ground truth backed by subprocess calls:
69
+ * - `ai-dossier runstate last --issue N --json` — the milestone trail
70
+ * - `gh issue view N --json state --jq .state` — issue closed
71
+ * - `git ls-remote origin <branch>` — branch head
72
+ * - `gh pr view <n> --json state,mergedAt,mergeable,labels` — parked-PR state (#468)
73
+ * - `gh issue view N --json comments` — the setup milestone's teardown keys (#468)
74
+ *
75
+ * `repoDir` is the cwd for git; gh resolves the repo from cwd by default.
76
+ * Every failure degrades safely: a failed milestone/PR poll reports UNREACHABLE
77
+ * (undefined — decision 2, option A), a failed closed-poll reports false, a
78
+ * failed head-poll null. Ground truth being unreachable pauses the engine's
79
+ * stall/verify/watch decisions; it never crashes a tick.
80
+ */
81
+ function createExecGroundTruth(exec = exports.groundTruthExec, opts = {}) {
82
+ const runstateBin = opts.runstateBin ?? 'ai-dossier';
83
+ return {
84
+ latestMilestone(issue) {
85
+ const out = exec(runstateBin, ['runstate', 'last', '--issue', String(issue), '--json'], opts.repoDir);
86
+ if (out === null)
87
+ return undefined; // subprocess failed — unreachable, NOT known-absent
88
+ return parseMilestoneJson(out); // 'null' output → null (verifiably no milestone)
89
+ },
90
+ issueClosed(issue) {
91
+ return (exec('gh', ['issue', 'view', String(issue), '--json', 'state', '--jq', '.state']) ===
92
+ 'CLOSED');
93
+ },
94
+ branchHead(branch) {
95
+ // The branch string originates from milestone output written by the
96
+ // spawned agent — validate it as a ref name and end git's option
97
+ // parsing with `--` so a crafted "branch" (e.g. `--upload-pack=…`)
98
+ // can never become a git option (CWE-88). A rejected ref degrades to
99
+ // null head: the pushed-commit progress signal just doesn't fire.
100
+ if (!/^[A-Za-z0-9][A-Za-z0-9._/-]*$/.test(branch))
101
+ return null;
102
+ const out = exec('git', ['ls-remote', 'origin', '--', branch], opts.repoDir);
103
+ if (out === null || out === '')
104
+ return null;
105
+ const sha = out.split('\t')[0]?.trim();
106
+ return sha && /^[0-9a-f]{40}$/i.test(sha) ? sha : null;
107
+ },
108
+ prState(pr) {
109
+ const out = exec('gh', ['pr', 'view', String(pr), '--json', 'state,mergedAt,mergeable,labels'], opts.repoDir);
110
+ if (out === null)
111
+ return undefined; // poll failed — unreachable
112
+ return parsePrViewJson(out) ?? undefined;
113
+ },
114
+ setupInfo(issue) {
115
+ const out = exec('gh', ['issue', 'view', String(issue), '--json', 'comments'], opts.repoDir);
116
+ if (out === null)
117
+ return undefined; // poll failed — unreachable
118
+ return parseSetupInfo(out);
119
+ },
120
+ };
121
+ }
122
+ /** Parse the stdout of `gh pr view --json state,mergedAt,mergeable,labels`. */
123
+ function parsePrViewJson(stdout) {
124
+ if (stdout === null || stdout.trim() === '')
125
+ return null;
126
+ try {
127
+ const parsed = JSON.parse(stdout);
128
+ if (parsed === null || typeof parsed !== 'object')
129
+ return null;
130
+ const obj = parsed;
131
+ if (typeof obj.state !== 'string')
132
+ return null;
133
+ const state = obj.state.toUpperCase();
134
+ if (state !== 'OPEN' && state !== 'MERGED' && state !== 'CLOSED')
135
+ return null;
136
+ const mergedAt = typeof obj.mergedAt === 'string' && obj.mergedAt !== '' ? obj.mergedAt : null;
137
+ const mergeableRaw = typeof obj.mergeable === 'string' ? obj.mergeable.toUpperCase() : null;
138
+ const mergeable = mergeableRaw === 'MERGEABLE' || mergeableRaw === 'CONFLICTING' || mergeableRaw === 'UNKNOWN'
139
+ ? mergeableRaw
140
+ : null;
141
+ const blocked = Array.isArray(obj.labels)
142
+ ? obj.labels.some((l) => l !== null &&
143
+ typeof l === 'object' &&
144
+ l.name === 'auto-merge-blocked')
145
+ : false;
146
+ return { state, mergedAt, mergeable, blocked };
147
+ }
148
+ catch {
149
+ return null;
150
+ }
151
+ }
152
+ /**
153
+ * Parse the stdout of `gh issue view --json comments` and recover the teardown
154
+ * inputs from the run's `setup done` milestone comment (#468). Milestone
155
+ * comments carry a `<!-- runstate:v1 -->` marker followed by `key=value`
156
+ * lines; the setup milestone is the one whose header starts `phase=setup`.
157
+ * Comments from non-collaborators (authorAssociation outside
158
+ * OWNER/MEMBER/COLLABORATOR) are skipped — teardown inputs feed destructive
159
+ * scripts, so a random commenter cannot supply them. Returns null when no
160
+ * usable setup milestone exists (verifiably).
161
+ */
162
+ function parseSetupInfo(commentsJson) {
163
+ if (commentsJson === null || commentsJson.trim() === '')
164
+ return null;
165
+ let comments;
166
+ try {
167
+ comments = JSON.parse(commentsJson);
168
+ }
169
+ catch {
170
+ return null;
171
+ }
172
+ if (!Array.isArray(comments))
173
+ return null;
174
+ const TRUSTED_ASSOCIATIONS = new Set(['OWNER', 'MEMBER', 'COLLABORATOR']);
175
+ // Newest setup milestone wins (a re-run can re-post setup).
176
+ for (const raw of [...comments].reverse()) {
177
+ if (raw === null || typeof raw !== 'object')
178
+ continue;
179
+ const comment = raw;
180
+ if (typeof comment.body !== 'string' || !comment.body.includes('<!-- runstate:v1 -->')) {
181
+ continue;
182
+ }
183
+ if (comment.authorAssociation !== undefined &&
184
+ !TRUSTED_ASSOCIATIONS.has(String(comment.authorAssociation))) {
185
+ continue; // untrusted author — never a teardown source
186
+ }
187
+ const keys = parseMilestoneKeys(comment.body);
188
+ if (keys.phase !== 'setup' || keys.status !== 'done')
189
+ continue;
190
+ const worktree = keys.worktree ?? null;
191
+ if (worktree === null || worktree.length === 0)
192
+ continue;
193
+ return {
194
+ worktree,
195
+ poolClaimed: keys.pool_claimed === 'true',
196
+ branch: keys.branch ?? null,
197
+ };
198
+ }
199
+ return null;
200
+ }
201
+ /**
202
+ * `key=value` tokens of a runstate milestone comment body — the same pair
203
+ * grammar `cli/src/runstate.ts` owns (the tolerant reader): the `phase=`
204
+ * header line carries several space-separated pairs, other lines carry one
205
+ * pair each split at the FIRST `=`. First occurrence of a key wins.
206
+ */
207
+ function parseMilestoneKeys(body) {
208
+ const keys = {};
209
+ const put = (token) => {
210
+ const eq = token.indexOf('=');
211
+ if (eq <= 0)
212
+ return;
213
+ const key = token.slice(0, eq);
214
+ if (keys[key] === undefined)
215
+ keys[key] = token.slice(eq + 1);
216
+ };
217
+ for (const line of body.split('\n')) {
218
+ const trimmed = line.trim();
219
+ if (trimmed.startsWith('phase=')) {
220
+ for (const token of trimmed.split(/\s+/))
221
+ put(token);
222
+ }
223
+ else {
224
+ put(trimmed);
225
+ }
226
+ }
227
+ return keys;
228
+ }
229
+ /** The `pr=` key of a milestone as a positive integer, or null when absent/malformed. */
230
+ function prOfMilestone(milestone) {
231
+ if (milestone === null)
232
+ return null;
233
+ const pr = Number.parseInt(milestone.keys.pr ?? '', 10);
234
+ return Number.isInteger(pr) && pr > 0 ? pr : null;
235
+ }
236
+ /**
237
+ * The detached-ship park signal (#468): the latest milestone is the ship
238
+ * phase's `awaiting-merge` record carrying a `pr=` key. Such an exit is a
239
+ * VERIFIED park, not an unverified exit — the watcher takes over from here.
240
+ */
241
+ function isParkedMilestone(milestone) {
242
+ if (milestone === null)
243
+ return false;
244
+ if (milestone.phase !== 'ship' || milestone.status !== 'awaiting-merge')
245
+ return false;
246
+ return prOfMilestone(milestone) !== null;
247
+ }
248
+ /**
249
+ * Completion rule (AC2): a unit's work is verified complete when the issue's
250
+ * latest milestone is the final `report done` — the full-cycle trail's last
251
+ * phase — or when GitHub itself says the issue is closed (a merged PR
252
+ * auto-closes it, which is ground truth no milestone can contradict).
253
+ */
254
+ function isVerifiedComplete(milestone, issueClosed) {
255
+ if (issueClosed)
256
+ return true;
257
+ return milestone !== null && milestone.phase === 'report' && milestone.status === 'done';
258
+ }
259
+ //# sourceMappingURL=groundtruth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"groundtruth.js","sourceRoot":"","sources":["../src/groundtruth.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ export { buildAgentCommand, buildPrompt, buildReportPrompt, createSpawnDeps, DEFAULT_DISPATCH_COMMAND, DEFAULT_PROMPT_TEMPLATE, DEFAULT_REPORT_PROMPT_TEMPLATE, DEFAULT_TIER_MODELS, escalateTier, OPENCODE_DISPATCH_COMMAND, type ResolvedDispatch, reportTierFor, resolveDispatch, type SpawnDeps, unitLogName, } from './dispatch';
2
+ export { type EngineDeps, runLoop, type TickResult, tick } from './engine';
3
+ export { assertNoDependencyCycle, EnqueueError, type EnqueueInput, enqueueEntries, parseManifest, } from './enqueue';
4
+ export { createExecGroundTruth, type GroundTruth, type GroundTruthMilestone, groundTruthExec, isParkedMilestone, isVerifiedComplete, type PrTruth, parseMilestoneJson, parsePrViewJson, parseSetupInfo, prOfMilestone, type SetupInfo, } from './groundtruth';
5
+ export { issueOfUnit, JOURNAL_FILE, Journal, readJsonl, unitEvent } from './journal';
6
+ export { CorruptStateError, LockTimeoutError, SchedStore, writeAtomic } from './persist';
7
+ export { createExecFn, defaultExec, type ExecFn, resolveProjectSlug, sanitizeSlug, schedStateDir, } from './project';
8
+ export { DISPATCHABLE_ISSUE_STATUSES } from './readiness';
9
+ export { type Assignment, abandonBatch, abandonIssue, assignToIdleSlot, batchBlockers, computeAssignments, type DependencyBlocker, dependencyBlockers, freeCapacity, type RunnableUnit, runnableUnits, setPaused, } from './scheduler';
10
+ export { createEmptyState, findBatch, findEntry, TRANSITIONS, transitionBatch, transitionIssue, transitionSlot, validateState, } from './state';
11
+ export { type BlockedItem, buildStatusReport, type ParkedItem, type StatusReport } from './status';
12
+ export { isSafeWorktree, runTeardown, TEARDOWN_TIMEOUT_MS, type TeardownResult } from './teardown';
13
+ export { type BatchEntry, type BatchStatus, type CleanupStatus, CONFIG_SCHEMA_VERSION, type CycleMode, DEFAULT_MAX_SLOTS, DEFAULT_PR_POLL_INTERVAL_MS, DEFAULT_RECONCILE_INTERVAL_MS, DEFAULT_STALL_TIMEOUT_MS, type DispatchConfig, ESCALATION_CAP, IllegalTransitionError, type IssueStatus, type JournalEvent, type JournalEventName, LEGACY_CONFIG_SCHEMA_VERSIONS, LEGACY_SCHEMA_VERSIONS, LIVE_SLOT_STATUSES, MAX_MAX_SLOTS, MERGED_BATCH_STATUSES, MIN_MAX_SLOTS, type ModelTier, type QueueEntry, SATISFIED_ISSUE_STATUSES, SCHEMA_VERSION, type SchedConfig, type SchedConfigFile, SchedNotFoundError, type SchedState, type SlotEntry, type SlotStatus, TERMINAL_BATCH_STATUSES, TERMINAL_ISSUE_STATUSES, TIER_LADDER, TIER_ORDER, } from './types';
14
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iBAAiB,EACjB,WAAW,EACX,iBAAiB,EACjB,eAAe,EACf,wBAAwB,EACxB,uBAAuB,EACvB,8BAA8B,EAC9B,mBAAmB,EACnB,YAAY,EACZ,yBAAyB,EACzB,KAAK,gBAAgB,EACrB,aAAa,EACb,eAAe,EACf,KAAK,SAAS,EACd,WAAW,GACZ,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,KAAK,UAAU,EAAE,OAAO,EAAE,KAAK,UAAU,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAC3E,OAAO,EACL,uBAAuB,EACvB,YAAY,EACZ,KAAK,YAAY,EACjB,cAAc,EACd,aAAa,GACd,MAAM,WAAW,CAAC;AACnB,OAAO,EACL,qBAAqB,EACrB,KAAK,WAAW,EAChB,KAAK,oBAAoB,EACzB,eAAe,EACf,iBAAiB,EACjB,kBAAkB,EAClB,KAAK,OAAO,EACZ,kBAAkB,EAClB,eAAe,EACf,cAAc,EACd,aAAa,EACb,KAAK,SAAS,GACf,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAErF,OAAO,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACzF,OAAO,EACL,YAAY,EACZ,WAAW,EACX,KAAK,MAAM,EACX,kBAAkB,EAClB,YAAY,EACZ,aAAa,GACd,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,2BAA2B,EAAE,MAAM,aAAa,CAAC;AAC1D,OAAO,EACL,KAAK,UAAU,EACf,YAAY,EACZ,YAAY,EACZ,gBAAgB,EAChB,aAAa,EACb,kBAAkB,EAClB,KAAK,iBAAiB,EACtB,kBAAkB,EAClB,YAAY,EACZ,KAAK,YAAY,EACjB,aAAa,EACb,SAAS,GACV,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,gBAAgB,EAChB,SAAS,EACT,SAAS,EACT,WAAW,EACX,eAAe,EACf,eAAe,EACf,cAAc,EACd,aAAa,GACd,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,KAAK,WAAW,EAAE,iBAAiB,EAAE,KAAK,UAAU,EAAE,KAAK,YAAY,EAAE,MAAM,UAAU,CAAC;AACnG,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,mBAAmB,EAAE,KAAK,cAAc,EAAE,MAAM,YAAY,CAAC;AACnG,OAAO,EACL,KAAK,UAAU,EACf,KAAK,WAAW,EAChB,KAAK,aAAa,EAClB,qBAAqB,EACrB,KAAK,SAAS,EACd,iBAAiB,EACjB,2BAA2B,EAC3B,6BAA6B,EAC7B,wBAAwB,EACxB,KAAK,cAAc,EACnB,cAAc,EACd,sBAAsB,EACtB,KAAK,WAAW,EAChB,KAAK,YAAY,EACjB,KAAK,gBAAgB,EACrB,6BAA6B,EAC7B,sBAAsB,EACtB,kBAAkB,EAClB,aAAa,EACb,qBAAqB,EACrB,aAAa,EACb,KAAK,SAAS,EACd,KAAK,UAAU,EACf,wBAAwB,EACxB,cAAc,EACd,KAAK,WAAW,EAChB,KAAK,eAAe,EACpB,kBAAkB,EAClB,KAAK,UAAU,EACf,KAAK,SAAS,EACd,KAAK,UAAU,EACf,uBAAuB,EACvB,uBAAuB,EACvB,WAAW,EACX,UAAU,GACX,MAAM,SAAS,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,101 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.runnableUnits = exports.freeCapacity = exports.dependencyBlockers = exports.computeAssignments = exports.batchBlockers = exports.assignToIdleSlot = exports.abandonIssue = exports.abandonBatch = exports.DISPATCHABLE_ISSUE_STATUSES = exports.schedStateDir = exports.sanitizeSlug = exports.resolveProjectSlug = exports.defaultExec = exports.createExecFn = exports.writeAtomic = exports.SchedStore = exports.LockTimeoutError = exports.CorruptStateError = exports.unitEvent = exports.readJsonl = exports.Journal = exports.JOURNAL_FILE = exports.issueOfUnit = exports.prOfMilestone = exports.parseSetupInfo = exports.parsePrViewJson = exports.parseMilestoneJson = exports.isVerifiedComplete = exports.isParkedMilestone = exports.groundTruthExec = exports.createExecGroundTruth = exports.parseManifest = exports.enqueueEntries = exports.EnqueueError = exports.assertNoDependencyCycle = exports.tick = exports.runLoop = exports.unitLogName = exports.resolveDispatch = exports.reportTierFor = exports.OPENCODE_DISPATCH_COMMAND = exports.escalateTier = exports.DEFAULT_TIER_MODELS = exports.DEFAULT_REPORT_PROMPT_TEMPLATE = exports.DEFAULT_PROMPT_TEMPLATE = exports.DEFAULT_DISPATCH_COMMAND = exports.createSpawnDeps = exports.buildReportPrompt = exports.buildPrompt = exports.buildAgentCommand = void 0;
4
+ exports.TIER_ORDER = exports.TIER_LADDER = exports.TERMINAL_ISSUE_STATUSES = exports.TERMINAL_BATCH_STATUSES = exports.SchedNotFoundError = exports.SCHEMA_VERSION = exports.SATISFIED_ISSUE_STATUSES = exports.MIN_MAX_SLOTS = exports.MERGED_BATCH_STATUSES = exports.MAX_MAX_SLOTS = exports.LIVE_SLOT_STATUSES = exports.LEGACY_SCHEMA_VERSIONS = exports.LEGACY_CONFIG_SCHEMA_VERSIONS = exports.IllegalTransitionError = exports.ESCALATION_CAP = exports.DEFAULT_STALL_TIMEOUT_MS = exports.DEFAULT_RECONCILE_INTERVAL_MS = exports.DEFAULT_PR_POLL_INTERVAL_MS = exports.DEFAULT_MAX_SLOTS = exports.CONFIG_SCHEMA_VERSION = exports.TEARDOWN_TIMEOUT_MS = exports.runTeardown = exports.isSafeWorktree = exports.buildStatusReport = exports.validateState = exports.transitionSlot = exports.transitionIssue = exports.transitionBatch = exports.TRANSITIONS = exports.findEntry = exports.findBatch = exports.createEmptyState = exports.setPaused = void 0;
5
+ var dispatch_1 = require("./dispatch");
6
+ Object.defineProperty(exports, "buildAgentCommand", { enumerable: true, get: function () { return dispatch_1.buildAgentCommand; } });
7
+ Object.defineProperty(exports, "buildPrompt", { enumerable: true, get: function () { return dispatch_1.buildPrompt; } });
8
+ Object.defineProperty(exports, "buildReportPrompt", { enumerable: true, get: function () { return dispatch_1.buildReportPrompt; } });
9
+ Object.defineProperty(exports, "createSpawnDeps", { enumerable: true, get: function () { return dispatch_1.createSpawnDeps; } });
10
+ Object.defineProperty(exports, "DEFAULT_DISPATCH_COMMAND", { enumerable: true, get: function () { return dispatch_1.DEFAULT_DISPATCH_COMMAND; } });
11
+ Object.defineProperty(exports, "DEFAULT_PROMPT_TEMPLATE", { enumerable: true, get: function () { return dispatch_1.DEFAULT_PROMPT_TEMPLATE; } });
12
+ Object.defineProperty(exports, "DEFAULT_REPORT_PROMPT_TEMPLATE", { enumerable: true, get: function () { return dispatch_1.DEFAULT_REPORT_PROMPT_TEMPLATE; } });
13
+ Object.defineProperty(exports, "DEFAULT_TIER_MODELS", { enumerable: true, get: function () { return dispatch_1.DEFAULT_TIER_MODELS; } });
14
+ Object.defineProperty(exports, "escalateTier", { enumerable: true, get: function () { return dispatch_1.escalateTier; } });
15
+ Object.defineProperty(exports, "OPENCODE_DISPATCH_COMMAND", { enumerable: true, get: function () { return dispatch_1.OPENCODE_DISPATCH_COMMAND; } });
16
+ Object.defineProperty(exports, "reportTierFor", { enumerable: true, get: function () { return dispatch_1.reportTierFor; } });
17
+ Object.defineProperty(exports, "resolveDispatch", { enumerable: true, get: function () { return dispatch_1.resolveDispatch; } });
18
+ Object.defineProperty(exports, "unitLogName", { enumerable: true, get: function () { return dispatch_1.unitLogName; } });
19
+ var engine_1 = require("./engine");
20
+ Object.defineProperty(exports, "runLoop", { enumerable: true, get: function () { return engine_1.runLoop; } });
21
+ Object.defineProperty(exports, "tick", { enumerable: true, get: function () { return engine_1.tick; } });
22
+ var enqueue_1 = require("./enqueue");
23
+ Object.defineProperty(exports, "assertNoDependencyCycle", { enumerable: true, get: function () { return enqueue_1.assertNoDependencyCycle; } });
24
+ Object.defineProperty(exports, "EnqueueError", { enumerable: true, get: function () { return enqueue_1.EnqueueError; } });
25
+ Object.defineProperty(exports, "enqueueEntries", { enumerable: true, get: function () { return enqueue_1.enqueueEntries; } });
26
+ Object.defineProperty(exports, "parseManifest", { enumerable: true, get: function () { return enqueue_1.parseManifest; } });
27
+ var groundtruth_1 = require("./groundtruth");
28
+ Object.defineProperty(exports, "createExecGroundTruth", { enumerable: true, get: function () { return groundtruth_1.createExecGroundTruth; } });
29
+ Object.defineProperty(exports, "groundTruthExec", { enumerable: true, get: function () { return groundtruth_1.groundTruthExec; } });
30
+ Object.defineProperty(exports, "isParkedMilestone", { enumerable: true, get: function () { return groundtruth_1.isParkedMilestone; } });
31
+ Object.defineProperty(exports, "isVerifiedComplete", { enumerable: true, get: function () { return groundtruth_1.isVerifiedComplete; } });
32
+ Object.defineProperty(exports, "parseMilestoneJson", { enumerable: true, get: function () { return groundtruth_1.parseMilestoneJson; } });
33
+ Object.defineProperty(exports, "parsePrViewJson", { enumerable: true, get: function () { return groundtruth_1.parsePrViewJson; } });
34
+ Object.defineProperty(exports, "parseSetupInfo", { enumerable: true, get: function () { return groundtruth_1.parseSetupInfo; } });
35
+ Object.defineProperty(exports, "prOfMilestone", { enumerable: true, get: function () { return groundtruth_1.prOfMilestone; } });
36
+ var journal_1 = require("./journal");
37
+ Object.defineProperty(exports, "issueOfUnit", { enumerable: true, get: function () { return journal_1.issueOfUnit; } });
38
+ Object.defineProperty(exports, "JOURNAL_FILE", { enumerable: true, get: function () { return journal_1.JOURNAL_FILE; } });
39
+ Object.defineProperty(exports, "Journal", { enumerable: true, get: function () { return journal_1.Journal; } });
40
+ Object.defineProperty(exports, "readJsonl", { enumerable: true, get: function () { return journal_1.readJsonl; } });
41
+ Object.defineProperty(exports, "unitEvent", { enumerable: true, get: function () { return journal_1.unitEvent; } });
42
+ var persist_1 = require("./persist");
43
+ Object.defineProperty(exports, "CorruptStateError", { enumerable: true, get: function () { return persist_1.CorruptStateError; } });
44
+ Object.defineProperty(exports, "LockTimeoutError", { enumerable: true, get: function () { return persist_1.LockTimeoutError; } });
45
+ Object.defineProperty(exports, "SchedStore", { enumerable: true, get: function () { return persist_1.SchedStore; } });
46
+ Object.defineProperty(exports, "writeAtomic", { enumerable: true, get: function () { return persist_1.writeAtomic; } });
47
+ var project_1 = require("./project");
48
+ Object.defineProperty(exports, "createExecFn", { enumerable: true, get: function () { return project_1.createExecFn; } });
49
+ Object.defineProperty(exports, "defaultExec", { enumerable: true, get: function () { return project_1.defaultExec; } });
50
+ Object.defineProperty(exports, "resolveProjectSlug", { enumerable: true, get: function () { return project_1.resolveProjectSlug; } });
51
+ Object.defineProperty(exports, "sanitizeSlug", { enumerable: true, get: function () { return project_1.sanitizeSlug; } });
52
+ Object.defineProperty(exports, "schedStateDir", { enumerable: true, get: function () { return project_1.schedStateDir; } });
53
+ var readiness_1 = require("./readiness");
54
+ Object.defineProperty(exports, "DISPATCHABLE_ISSUE_STATUSES", { enumerable: true, get: function () { return readiness_1.DISPATCHABLE_ISSUE_STATUSES; } });
55
+ var scheduler_1 = require("./scheduler");
56
+ Object.defineProperty(exports, "abandonBatch", { enumerable: true, get: function () { return scheduler_1.abandonBatch; } });
57
+ Object.defineProperty(exports, "abandonIssue", { enumerable: true, get: function () { return scheduler_1.abandonIssue; } });
58
+ Object.defineProperty(exports, "assignToIdleSlot", { enumerable: true, get: function () { return scheduler_1.assignToIdleSlot; } });
59
+ Object.defineProperty(exports, "batchBlockers", { enumerable: true, get: function () { return scheduler_1.batchBlockers; } });
60
+ Object.defineProperty(exports, "computeAssignments", { enumerable: true, get: function () { return scheduler_1.computeAssignments; } });
61
+ Object.defineProperty(exports, "dependencyBlockers", { enumerable: true, get: function () { return scheduler_1.dependencyBlockers; } });
62
+ Object.defineProperty(exports, "freeCapacity", { enumerable: true, get: function () { return scheduler_1.freeCapacity; } });
63
+ Object.defineProperty(exports, "runnableUnits", { enumerable: true, get: function () { return scheduler_1.runnableUnits; } });
64
+ Object.defineProperty(exports, "setPaused", { enumerable: true, get: function () { return scheduler_1.setPaused; } });
65
+ var state_1 = require("./state");
66
+ Object.defineProperty(exports, "createEmptyState", { enumerable: true, get: function () { return state_1.createEmptyState; } });
67
+ Object.defineProperty(exports, "findBatch", { enumerable: true, get: function () { return state_1.findBatch; } });
68
+ Object.defineProperty(exports, "findEntry", { enumerable: true, get: function () { return state_1.findEntry; } });
69
+ Object.defineProperty(exports, "TRANSITIONS", { enumerable: true, get: function () { return state_1.TRANSITIONS; } });
70
+ Object.defineProperty(exports, "transitionBatch", { enumerable: true, get: function () { return state_1.transitionBatch; } });
71
+ Object.defineProperty(exports, "transitionIssue", { enumerable: true, get: function () { return state_1.transitionIssue; } });
72
+ Object.defineProperty(exports, "transitionSlot", { enumerable: true, get: function () { return state_1.transitionSlot; } });
73
+ Object.defineProperty(exports, "validateState", { enumerable: true, get: function () { return state_1.validateState; } });
74
+ var status_1 = require("./status");
75
+ Object.defineProperty(exports, "buildStatusReport", { enumerable: true, get: function () { return status_1.buildStatusReport; } });
76
+ var teardown_1 = require("./teardown");
77
+ Object.defineProperty(exports, "isSafeWorktree", { enumerable: true, get: function () { return teardown_1.isSafeWorktree; } });
78
+ Object.defineProperty(exports, "runTeardown", { enumerable: true, get: function () { return teardown_1.runTeardown; } });
79
+ Object.defineProperty(exports, "TEARDOWN_TIMEOUT_MS", { enumerable: true, get: function () { return teardown_1.TEARDOWN_TIMEOUT_MS; } });
80
+ var types_1 = require("./types");
81
+ Object.defineProperty(exports, "CONFIG_SCHEMA_VERSION", { enumerable: true, get: function () { return types_1.CONFIG_SCHEMA_VERSION; } });
82
+ Object.defineProperty(exports, "DEFAULT_MAX_SLOTS", { enumerable: true, get: function () { return types_1.DEFAULT_MAX_SLOTS; } });
83
+ Object.defineProperty(exports, "DEFAULT_PR_POLL_INTERVAL_MS", { enumerable: true, get: function () { return types_1.DEFAULT_PR_POLL_INTERVAL_MS; } });
84
+ Object.defineProperty(exports, "DEFAULT_RECONCILE_INTERVAL_MS", { enumerable: true, get: function () { return types_1.DEFAULT_RECONCILE_INTERVAL_MS; } });
85
+ Object.defineProperty(exports, "DEFAULT_STALL_TIMEOUT_MS", { enumerable: true, get: function () { return types_1.DEFAULT_STALL_TIMEOUT_MS; } });
86
+ Object.defineProperty(exports, "ESCALATION_CAP", { enumerable: true, get: function () { return types_1.ESCALATION_CAP; } });
87
+ Object.defineProperty(exports, "IllegalTransitionError", { enumerable: true, get: function () { return types_1.IllegalTransitionError; } });
88
+ Object.defineProperty(exports, "LEGACY_CONFIG_SCHEMA_VERSIONS", { enumerable: true, get: function () { return types_1.LEGACY_CONFIG_SCHEMA_VERSIONS; } });
89
+ Object.defineProperty(exports, "LEGACY_SCHEMA_VERSIONS", { enumerable: true, get: function () { return types_1.LEGACY_SCHEMA_VERSIONS; } });
90
+ Object.defineProperty(exports, "LIVE_SLOT_STATUSES", { enumerable: true, get: function () { return types_1.LIVE_SLOT_STATUSES; } });
91
+ Object.defineProperty(exports, "MAX_MAX_SLOTS", { enumerable: true, get: function () { return types_1.MAX_MAX_SLOTS; } });
92
+ Object.defineProperty(exports, "MERGED_BATCH_STATUSES", { enumerable: true, get: function () { return types_1.MERGED_BATCH_STATUSES; } });
93
+ Object.defineProperty(exports, "MIN_MAX_SLOTS", { enumerable: true, get: function () { return types_1.MIN_MAX_SLOTS; } });
94
+ Object.defineProperty(exports, "SATISFIED_ISSUE_STATUSES", { enumerable: true, get: function () { return types_1.SATISFIED_ISSUE_STATUSES; } });
95
+ Object.defineProperty(exports, "SCHEMA_VERSION", { enumerable: true, get: function () { return types_1.SCHEMA_VERSION; } });
96
+ Object.defineProperty(exports, "SchedNotFoundError", { enumerable: true, get: function () { return types_1.SchedNotFoundError; } });
97
+ Object.defineProperty(exports, "TERMINAL_BATCH_STATUSES", { enumerable: true, get: function () { return types_1.TERMINAL_BATCH_STATUSES; } });
98
+ Object.defineProperty(exports, "TERMINAL_ISSUE_STATUSES", { enumerable: true, get: function () { return types_1.TERMINAL_ISSUE_STATUSES; } });
99
+ Object.defineProperty(exports, "TIER_LADDER", { enumerable: true, get: function () { return types_1.TIER_LADDER; } });
100
+ Object.defineProperty(exports, "TIER_ORDER", { enumerable: true, get: function () { return types_1.TIER_ORDER; } });
101
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Append-only event journal (#464, AC6 — "all events journaled"; RFC-0001 §D.4
3
+ * "Audit"). Every engine decision lands here as one JSONL line in
4
+ * `<sched-dir>/events.jsonl`. The journal must never crash a tick: write
5
+ * failures are swallowed after a one-line stderr warning — state.json remains
6
+ * the operational truth, the journal is the operator's flight recorder.
7
+ */
8
+ import type { JournalEvent, JournalEventName } from './types';
9
+ /** The journal file name — the single source (persist.ts's journalPath uses it). */
10
+ export declare const JOURNAL_FILE = "events.jsonl";
11
+ export declare class Journal {
12
+ readonly filePath: string;
13
+ constructor(dir: string);
14
+ /** Append one event, stamping `ts` from the caller's clock. Never throws. */
15
+ append(event: Omit<JournalEvent, 'ts'>, now?: Date): void;
16
+ /** Read every event, oldest first; malformed lines are skipped. */
17
+ read(): JournalEvent[];
18
+ }
19
+ /**
20
+ * Read a JSONL file oldest-first, skipping malformed lines; `[]` when the
21
+ * file is absent or unreadable. Shared by the journal and the CLI's run log
22
+ * so the read-loop exists once.
23
+ */
24
+ export declare function readJsonl<T>(file: string): T[];
25
+ /** `issue:464` → 464; null for batch or malformed unit ids. */
26
+ export declare function issueOfUnit(unit: string | null): number | null;
27
+ /** Convenience: build the journaled event for a unit without repeating ids. */
28
+ export declare function unitEvent(event: JournalEventName, unit: string, extra?: Omit<JournalEvent, 'ts' | 'event' | 'unit'>): Omit<JournalEvent, 'ts' | 'event' | 'unit'> & {
29
+ event: JournalEventName;
30
+ unit: string;
31
+ };
32
+ //# sourceMappingURL=journal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"journal.d.ts","sourceRoot":"","sources":["../src/journal.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,OAAO,KAAK,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAE9D,oFAAoF;AACpF,eAAO,MAAM,YAAY,iBAAiB,CAAC;AAE3C,qBAAa,OAAO;IAClB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;gBAEd,GAAG,EAAE,MAAM;IAIvB,6EAA6E;IAC7E,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,EAAE,GAAG,GAAE,IAAiB,GAAG,IAAI;IAerE,mEAAmE;IACnE,IAAI,IAAI,YAAY,EAAE;CAGvB;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,GAAG,CAAC,EAAE,CAgB9C;AAED,+DAA+D;AAC/D,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,GAAG,IAAI,CAI9D;AAED,+EAA+E;AAC/E,wBAAgB,SAAS,CACvB,KAAK,EAAE,gBAAgB,EACvB,IAAI,EAAE,MAAM,EACZ,KAAK,GAAE,IAAI,CAAC,YAAY,EAAE,IAAI,GAAG,OAAO,GAAG,MAAM,CAAM,GACtD,IAAI,CAAC,YAAY,EAAE,IAAI,GAAG,OAAO,GAAG,MAAM,CAAC,GAAG;IAAE,KAAK,EAAE,gBAAgB,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAGzF"}
@@ -0,0 +1,113 @@
1
+ "use strict";
2
+ /**
3
+ * Append-only event journal (#464, AC6 — "all events journaled"; RFC-0001 §D.4
4
+ * "Audit"). Every engine decision lands here as one JSONL line in
5
+ * `<sched-dir>/events.jsonl`. The journal must never crash a tick: write
6
+ * failures are swallowed after a one-line stderr warning — state.json remains
7
+ * the operational truth, the journal is the operator's flight recorder.
8
+ */
9
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ var desc = Object.getOwnPropertyDescriptor(m, k);
12
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
13
+ desc = { enumerable: true, get: function() { return m[k]; } };
14
+ }
15
+ Object.defineProperty(o, k2, desc);
16
+ }) : (function(o, m, k, k2) {
17
+ if (k2 === undefined) k2 = k;
18
+ o[k2] = m[k];
19
+ }));
20
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
21
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
22
+ }) : function(o, v) {
23
+ o["default"] = v;
24
+ });
25
+ var __importStar = (this && this.__importStar) || (function () {
26
+ var ownKeys = function(o) {
27
+ ownKeys = Object.getOwnPropertyNames || function (o) {
28
+ var ar = [];
29
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
30
+ return ar;
31
+ };
32
+ return ownKeys(o);
33
+ };
34
+ return function (mod) {
35
+ if (mod && mod.__esModule) return mod;
36
+ var result = {};
37
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
38
+ __setModuleDefault(result, mod);
39
+ return result;
40
+ };
41
+ })();
42
+ Object.defineProperty(exports, "__esModule", { value: true });
43
+ exports.Journal = exports.JOURNAL_FILE = void 0;
44
+ exports.readJsonl = readJsonl;
45
+ exports.issueOfUnit = issueOfUnit;
46
+ exports.unitEvent = unitEvent;
47
+ const fs = __importStar(require("node:fs"));
48
+ const path = __importStar(require("node:path"));
49
+ /** The journal file name — the single source (persist.ts's journalPath uses it). */
50
+ exports.JOURNAL_FILE = 'events.jsonl';
51
+ class Journal {
52
+ filePath;
53
+ constructor(dir) {
54
+ this.filePath = path.join(dir, exports.JOURNAL_FILE);
55
+ }
56
+ /** Append one event, stamping `ts` from the caller's clock. Never throws. */
57
+ append(event, now = new Date()) {
58
+ const line = { ts: now.toISOString(), ...event };
59
+ try {
60
+ fs.mkdirSync(path.dirname(this.filePath), { recursive: true, mode: 0o700 });
61
+ fs.appendFileSync(this.filePath, `${JSON.stringify(line)}\n`, {
62
+ encoding: 'utf8',
63
+ mode: 0o600,
64
+ });
65
+ }
66
+ catch (err) {
67
+ process.stderr.write(`⚠ sched: could not append journal event ${event.event}: ${err.message}\n`);
68
+ }
69
+ }
70
+ /** Read every event, oldest first; malformed lines are skipped. */
71
+ read() {
72
+ return readJsonl(this.filePath);
73
+ }
74
+ }
75
+ exports.Journal = Journal;
76
+ /**
77
+ * Read a JSONL file oldest-first, skipping malformed lines; `[]` when the
78
+ * file is absent or unreadable. Shared by the journal and the CLI's run log
79
+ * so the read-loop exists once.
80
+ */
81
+ function readJsonl(file) {
82
+ try {
83
+ if (!fs.existsSync(file))
84
+ return [];
85
+ const lines = fs.readFileSync(file, 'utf8').split('\n').filter(Boolean);
86
+ const out = [];
87
+ for (const line of lines) {
88
+ try {
89
+ out.push(JSON.parse(line));
90
+ }
91
+ catch {
92
+ // Skip malformed lines — append-only best-effort files.
93
+ }
94
+ }
95
+ return out;
96
+ }
97
+ catch {
98
+ return [];
99
+ }
100
+ }
101
+ /** `issue:464` → 464; null for batch or malformed unit ids. */
102
+ function issueOfUnit(unit) {
103
+ if (unit === null || !unit.startsWith('issue:'))
104
+ return null;
105
+ const n = Number.parseInt(unit.slice('issue:'.length), 10);
106
+ return Number.isInteger(n) && n > 0 ? n : null;
107
+ }
108
+ /** Convenience: build the journaled event for a unit without repeating ids. */
109
+ function unitEvent(event, unit, extra = {}) {
110
+ const issue = issueOfUnit(unit);
111
+ return { event, unit, ...(issue !== null ? { issue } : {}), ...extra };
112
+ }
113
+ //# sourceMappingURL=journal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"journal.js","sourceRoot":"","sources":["../src/journal.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,54 @@
1
+ /**
2
+ * Crash-safe persistence for the scheduler core.
3
+ *
4
+ * `state.json` is written atomically: contents land in `state.json.tmp` in the
5
+ * SAME directory (rename is atomic only within a filesystem), get fsynced, and
6
+ * are renamed over `state.json`. A process killed between writes therefore
7
+ * leaves either the previous complete state or the new one — never a partial
8
+ * file (AC2). A stray `.tmp` is ignored by `load()` and overwritten by the
9
+ * next write.
10
+ *
11
+ * Cross-process mutations are serialized by a directory mutex (`.sched-lock`),
12
+ * the same acquire/release protocol as `packages/worktree-pool/src/pool-actions.ts`
13
+ * (acquireLock/releaseLock there) — the two copies must be kept in lockstep.
14
+ */
15
+ import { type SchedConfig, type SchedState } from './types';
16
+ /** Thrown when the cross-process lock cannot be acquired in time. */
17
+ export declare class LockTimeoutError extends Error {
18
+ readonly lockPath: string;
19
+ constructor(lockPath: string, heldByPid: number | null);
20
+ }
21
+ export declare class CorruptStateError extends Error {
22
+ readonly filePath: string;
23
+ constructor(filePath: string, cause: unknown);
24
+ }
25
+ /** Write `contents` to `filePath` atomically (tmp + fsync + rename, same directory). */
26
+ export declare function writeAtomic(filePath: string, contents: string): void;
27
+ /**
28
+ * Filesystem-backed store for one project's scheduler state
29
+ * (`~/.dossier/sched/<project>/`). The constructor only records the directory;
30
+ * all I/O happens per call so a long-lived instance always sees fresh disk
31
+ * state under the lock.
32
+ */
33
+ export declare class SchedStore {
34
+ readonly dir: string;
35
+ constructor(dir: string);
36
+ get statePath(): string;
37
+ get configPath(): string;
38
+ get journalPath(): string;
39
+ /** Directory for per-unit agent output logs (`runs/<unit>.log`). */
40
+ get runsDir(): string;
41
+ load(): SchedState;
42
+ save(state: SchedState): void;
43
+ /**
44
+ * Load → mutate → save under the cross-process lock. The mutator must be
45
+ * pure (state in, state out) — same contract as pool's `withLock`.
46
+ */
47
+ withLock<T>(fn: (state: SchedState) => {
48
+ state: SchedState;
49
+ result: T;
50
+ }): T;
51
+ loadConfig(): SchedConfig;
52
+ saveConfig(config: SchedConfig): void;
53
+ }
54
+ //# sourceMappingURL=persist.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"persist.d.ts","sourceRoot":"","sources":["../src/persist.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAMH,OAAO,EAQL,KAAK,WAAW,EAEhB,KAAK,UAAU,EAChB,MAAM,SAAS,CAAC;AASjB,qEAAqE;AACrE,qBAAa,gBAAiB,SAAQ,KAAK;IACzC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;gBAEd,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI;CASvD;AAED,qBAAa,iBAAkB,SAAQ,KAAK;IAC1C,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;gBAEd,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO;CAS7C;AAED,wFAAwF;AACxF,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAwBpE;AA8DD;;;;;GAKG;AACH,qBAAa,UAAU;IACrB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;gBAET,GAAG,EAAE,MAAM;IAIvB,IAAI,SAAS,IAAI,MAAM,CAEtB;IAED,IAAI,UAAU,IAAI,MAAM,CAEvB;IAED,IAAI,WAAW,IAAI,MAAM,CAExB;IAED,oEAAoE;IACpE,IAAI,OAAO,IAAI,MAAM,CAEpB;IAED,IAAI,IAAI,UAAU;IAyBlB,IAAI,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI;IAI7B;;;OAGG;IACH,QAAQ,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK;QAAE,KAAK,EAAE,UAAU,CAAC;QAAC,MAAM,EAAE,CAAC,CAAA;KAAE,GAAG,CAAC;IAY3E,UAAU,IAAI,WAAW;IAqDzB,UAAU,CAAC,MAAM,EAAE,WAAW,GAAG,IAAI;CAiBtC"}