@voybio/ace-swarm 0.2.0 → 0.2.1

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 (64) hide show
  1. package/README.md +15 -15
  2. package/assets/agent-state/EVIDENCE_LOG.md +1 -1
  3. package/assets/agent-state/STATUS.md +2 -2
  4. package/dist/ace-autonomy.js +38 -1
  5. package/dist/ace-context.js +8 -0
  6. package/dist/ace-server-instructions.js +55 -19
  7. package/dist/ace-state-resolver.d.ts +18 -0
  8. package/dist/ace-state-resolver.js +106 -0
  9. package/dist/cli.js +67 -0
  10. package/dist/handoff-registry.js +11 -7
  11. package/dist/helpers.js +74 -8
  12. package/dist/job-scheduler.js +94 -44
  13. package/dist/run-ledger.js +3 -4
  14. package/dist/server.d.ts +1 -1
  15. package/dist/server.js +1 -1
  16. package/dist/shared.d.ts +1 -1
  17. package/dist/status-events.js +12 -14
  18. package/dist/store/bootstrap-store.js +20 -9
  19. package/dist/store/materializers/context-snapshot-materializer.d.ts +10 -0
  20. package/dist/store/materializers/context-snapshot-materializer.js +51 -0
  21. package/dist/store/materializers/host-file-materializer.d.ts +6 -0
  22. package/dist/store/materializers/host-file-materializer.js +13 -0
  23. package/dist/store/materializers/projection-manager.d.ts +14 -0
  24. package/dist/store/materializers/projection-manager.js +73 -0
  25. package/dist/store/materializers/scheduler-projection-materializer.d.ts +16 -0
  26. package/dist/store/materializers/scheduler-projection-materializer.js +48 -0
  27. package/dist/store/repositories/context-snapshot-repository.d.ts +46 -0
  28. package/dist/store/repositories/context-snapshot-repository.js +105 -0
  29. package/dist/store/repositories/local-model-runtime-repository.d.ts +98 -0
  30. package/dist/store/repositories/local-model-runtime-repository.js +165 -0
  31. package/dist/store/repositories/scheduler-repository.d.ts +21 -39
  32. package/dist/store/repositories/scheduler-repository.js +123 -93
  33. package/dist/store/repositories/todo-repository.d.ts +4 -0
  34. package/dist/store/repositories/todo-repository.js +50 -0
  35. package/dist/store/state-reader.d.ts +8 -1
  36. package/dist/store/state-reader.js +12 -1
  37. package/dist/store/store-artifacts.js +31 -5
  38. package/dist/store/store-authority-audit.d.ts +30 -0
  39. package/dist/store/store-authority-audit.js +448 -0
  40. package/dist/store/types.d.ts +2 -0
  41. package/dist/store/types.js +1 -0
  42. package/dist/todo-state.js +179 -11
  43. package/dist/tools-files.js +2 -1
  44. package/dist/tools-framework.js +60 -0
  45. package/dist/tools-memory.js +69 -34
  46. package/dist/tools-todo.js +1 -1
  47. package/dist/tui/agent-worker.d.ts +1 -1
  48. package/dist/tui/agent-worker.js +5 -3
  49. package/dist/tui/chat.d.ts +19 -0
  50. package/dist/tui/chat.js +275 -9
  51. package/dist/tui/commands.d.ts +2 -0
  52. package/dist/tui/commands.js +62 -0
  53. package/dist/tui/dashboard.d.ts +5 -0
  54. package/dist/tui/dashboard.js +38 -2
  55. package/dist/tui/index.d.ts +5 -0
  56. package/dist/tui/index.js +146 -2
  57. package/dist/tui/input.js +5 -0
  58. package/dist/tui/layout.d.ts +24 -0
  59. package/dist/tui/layout.js +76 -2
  60. package/dist/tui/local-model-contract.d.ts +50 -0
  61. package/dist/tui/local-model-contract.js +272 -0
  62. package/dist/vericify-bridge.js +3 -4
  63. package/dist/vericify-context.js +18 -6
  64. package/package.json +1 -1
@@ -3,48 +3,30 @@
3
3
  * Replaces: job-queue.json, job-locks.json, scheduler-lease.json
4
4
  */
5
5
  import { AcePackedStore } from "../ace-packed-store.js";
6
- export interface Job {
7
- id: string;
8
- role: string;
9
- task: string;
10
- priority: "high" | "medium" | "low";
11
- status: "queued" | "running" | "done" | "failed" | "cancelled";
12
- depends_on?: string[];
13
- created_at: number;
14
- started_at?: number;
15
- completed_at?: number;
16
- result?: unknown;
17
- metadata?: Record<string, unknown>;
18
- }
19
- export interface ResourceLock {
20
- resource: string;
21
- holder: string;
22
- acquired_at: number;
23
- expires_at?: number;
24
- }
25
- export interface SchedulerLease {
26
- holder: string;
27
- acquired_at: number;
28
- expires_at: number;
29
- run_id?: string;
30
- }
6
+ import type { JobLockRecord, JobLockTableFile, JobQueueFile, JobRecord, SchedulerLeaseFile } from "../../job-scheduler.js";
31
7
  export declare class SchedulerRepository {
32
8
  private store;
33
9
  constructor(store: AcePackedStore);
34
- enqueue(job: Omit<Job, "created_at" | "status">): Promise<Job>;
10
+ readQueue(): Promise<JobQueueFile>;
11
+ readLockTable(): Promise<JobLockTableFile>;
12
+ readLease(): Promise<SchedulerLeaseFile | undefined>;
13
+ writeQueue(queue: JobQueueFile): Promise<JobQueueFile>;
14
+ writeLockTable(table: JobLockTableFile): Promise<JobLockTableFile>;
15
+ writeLease(lease: SchedulerLeaseFile | undefined): Promise<SchedulerLeaseFile | undefined>;
16
+ replaceState(input: {
17
+ queue: JobQueueFile;
18
+ locks: JobLockTableFile;
19
+ lease?: SchedulerLeaseFile;
20
+ }): Promise<{
21
+ queue: JobQueueFile;
22
+ locks: JobLockTableFile;
23
+ lease?: SchedulerLeaseFile;
24
+ }>;
35
25
  listJobs(filter?: {
36
- status?: Job["status"];
37
- role?: string;
38
- }): Promise<Job[]>;
39
- updateJob(id: string, patch: Partial<Job>): Promise<Job>;
40
- completeJob(id: string, result?: unknown): Promise<Job>;
41
- failJob(id: string, reason?: string): Promise<Job>;
42
- dispatchReady(): Promise<Job[]>;
43
- acquireLock(resource: string, holder: string, ttlMs?: number): Promise<ResourceLock>;
44
- releaseLock(resource: string, holder: string): Promise<boolean>;
45
- getLocks(): Promise<ResourceLock[]>;
46
- acquireLease(holder: string, ttlMs?: number, runId?: string): Promise<SchedulerLease>;
47
- releaseLease(holder: string): Promise<boolean>;
48
- getLease(): Promise<SchedulerLease | undefined>;
26
+ status?: JobRecord["status"];
27
+ }): Promise<JobRecord[]>;
28
+ listLocks(filter?: {
29
+ status?: JobLockRecord["status"];
30
+ }): Promise<JobLockRecord[]>;
49
31
  }
50
32
  //# sourceMappingURL=scheduler-repository.d.ts.map
@@ -6,118 +6,148 @@ import { ContentSource, EntityKind } from "../types.js";
6
6
  const QUEUE_KEY = "state/scheduler/queue";
7
7
  const LOCKS_KEY = "state/scheduler/locks";
8
8
  const LEASE_KEY = "state/scheduler/lease";
9
+ function nowIso() {
10
+ return new Date().toISOString();
11
+ }
12
+ function defaultQueueFile() {
13
+ return {
14
+ version: 1,
15
+ updated_at: nowIso(),
16
+ jobs: [],
17
+ };
18
+ }
19
+ function defaultLockTableFile() {
20
+ return {
21
+ version: 1,
22
+ updated_at: nowIso(),
23
+ locks: [],
24
+ };
25
+ }
26
+ function normalizeQueue(queue) {
27
+ if (!queue || queue.version !== 1 || !Array.isArray(queue.jobs)) {
28
+ return defaultQueueFile();
29
+ }
30
+ return {
31
+ version: 1,
32
+ updated_at: typeof queue.updated_at === "string" ? queue.updated_at : nowIso(),
33
+ jobs: Array.isArray(queue.jobs) ? queue.jobs : [],
34
+ };
35
+ }
36
+ function normalizeLockTable(table) {
37
+ if (!table || table.version !== 1 || !Array.isArray(table.locks)) {
38
+ return defaultLockTableFile();
39
+ }
40
+ return {
41
+ version: 1,
42
+ updated_at: typeof table.updated_at === "string" ? table.updated_at : nowIso(),
43
+ locks: Array.isArray(table.locks) ? table.locks : [],
44
+ };
45
+ }
46
+ function normalizeLease(lease) {
47
+ if (!lease || lease.version !== 1)
48
+ return undefined;
49
+ return lease;
50
+ }
9
51
  export class SchedulerRepository {
10
52
  store;
11
53
  constructor(store) {
12
54
  this.store = store;
13
55
  }
14
- // ── Jobs ──────────────────────────────────────────────────────────────────
15
- async enqueue(job) {
16
- const record = { ...job, status: "queued", created_at: Date.now() };
17
- const queue = await this.store.getJSON(QUEUE_KEY) ?? [];
18
- queue.push(record);
19
- await this.store.setJSON(QUEUE_KEY, queue);
56
+ async readQueue() {
57
+ return normalizeQueue(await this.store.getJSON(QUEUE_KEY));
58
+ }
59
+ async readLockTable() {
60
+ return normalizeLockTable(await this.store.getJSON(LOCKS_KEY));
61
+ }
62
+ async readLease() {
63
+ const stored = await this.store.getJSON(LEASE_KEY);
64
+ return normalizeLease(stored);
65
+ }
66
+ async writeQueue(queue) {
67
+ const record = {
68
+ ...normalizeQueue(queue),
69
+ updated_at: nowIso(),
70
+ };
71
+ await this.store.setJSON(QUEUE_KEY, record);
20
72
  await this.store.appendEntry({
21
73
  kind: EntityKind.SchedulerTick,
22
74
  content_source: ContentSource.Runtime,
23
75
  key: QUEUE_KEY,
24
- payload: { op: "enqueue", job_id: job.id },
76
+ payload: {
77
+ op: "queue_write",
78
+ job_count: record.jobs.length,
79
+ },
25
80
  });
26
81
  return record;
27
82
  }
28
- async listJobs(filter) {
29
- const queue = await this.store.getJSON(QUEUE_KEY) ?? [];
30
- return queue.filter((j) => {
31
- if (filter?.status && j.status !== filter.status)
32
- return false;
33
- if (filter?.role && j.role !== filter.role)
34
- return false;
35
- return true;
83
+ async writeLockTable(table) {
84
+ const record = {
85
+ ...normalizeLockTable(table),
86
+ updated_at: nowIso(),
87
+ };
88
+ await this.store.setJSON(LOCKS_KEY, record);
89
+ await this.store.appendEntry({
90
+ kind: EntityKind.SchedulerTick,
91
+ content_source: ContentSource.Runtime,
92
+ key: LOCKS_KEY,
93
+ payload: {
94
+ op: "lock_table_write",
95
+ lock_count: record.locks.length,
96
+ },
36
97
  });
98
+ return record;
37
99
  }
38
- async updateJob(id, patch) {
39
- const queue = await this.store.getJSON(QUEUE_KEY) ?? [];
40
- const idx = queue.findIndex((j) => j.id === id);
41
- if (idx === -1)
42
- throw new Error(`SchedulerRepository: job not found: ${id}`);
43
- queue[idx] = { ...queue[idx], ...patch };
44
- await this.store.setJSON(QUEUE_KEY, queue);
45
- return queue[idx];
100
+ async writeLease(lease) {
101
+ if (!lease) {
102
+ await this.store.setJSON(LEASE_KEY, null);
103
+ await this.store.appendEntry({
104
+ kind: EntityKind.SchedulerTick,
105
+ content_source: ContentSource.Runtime,
106
+ key: LEASE_KEY,
107
+ payload: {
108
+ op: "lease_clear",
109
+ },
110
+ });
111
+ return undefined;
112
+ }
113
+ const record = {
114
+ ...lease,
115
+ version: 1,
116
+ };
117
+ await this.store.setJSON(LEASE_KEY, record);
118
+ await this.store.appendEntry({
119
+ kind: EntityKind.SchedulerTick,
120
+ content_source: ContentSource.Runtime,
121
+ key: LEASE_KEY,
122
+ payload: {
123
+ op: "lease_write",
124
+ owner: record.owner,
125
+ lease_id: record.lease_id,
126
+ },
127
+ });
128
+ return record;
46
129
  }
47
- async completeJob(id, result) {
48
- return this.updateJob(id, { status: "done", completed_at: Date.now(), result });
130
+ async replaceState(input) {
131
+ const queue = await this.writeQueue(input.queue);
132
+ const locks = await this.writeLockTable(input.locks);
133
+ const lease = await this.writeLease(input.lease);
134
+ return { queue, locks, lease };
49
135
  }
50
- async failJob(id, reason) {
51
- return this.updateJob(id, {
52
- status: "failed",
53
- completed_at: Date.now(),
54
- metadata: { failure_reason: reason },
136
+ async listJobs(filter) {
137
+ const queue = await this.readQueue();
138
+ return queue.jobs.filter((job) => {
139
+ if (filter?.status && job.status !== filter.status)
140
+ return false;
141
+ return true;
55
142
  });
56
143
  }
57
- async dispatchReady() {
58
- const queue = await this.listJobs({ status: "queued" });
59
- const done = new Set((await this.listJobs({ status: "done" })).map((j) => j.id));
60
- return queue.filter((j) => {
61
- if (!j.depends_on?.length)
62
- return true;
63
- return j.depends_on.every((dep) => done.has(dep));
144
+ async listLocks(filter) {
145
+ const table = await this.readLockTable();
146
+ return table.locks.filter((lock) => {
147
+ if (filter?.status && lock.status !== filter.status)
148
+ return false;
149
+ return true;
64
150
  });
65
151
  }
66
- // ── Resource locks ────────────────────────────────────────────────────────
67
- async acquireLock(resource, holder, ttlMs) {
68
- const locks = await this.store.getJSON(LOCKS_KEY) ?? [];
69
- const existing = locks.find((l) => l.resource === resource);
70
- const now = Date.now();
71
- if (existing) {
72
- if (!existing.expires_at || existing.expires_at > now) {
73
- throw new Error(`SchedulerRepository: resource locked by ${existing.holder}: ${resource}`);
74
- }
75
- // Expired lock — remove it
76
- const next = locks.filter((l) => l.resource !== resource);
77
- next.push({ resource, holder, acquired_at: now, expires_at: ttlMs ? now + ttlMs : undefined });
78
- await this.store.setJSON(LOCKS_KEY, next);
79
- return next.find((l) => l.resource === resource);
80
- }
81
- locks.push({ resource, holder, acquired_at: now, expires_at: ttlMs ? now + ttlMs : undefined });
82
- await this.store.setJSON(LOCKS_KEY, locks);
83
- return locks.find((l) => l.resource === resource);
84
- }
85
- async releaseLock(resource, holder) {
86
- const locks = await this.store.getJSON(LOCKS_KEY) ?? [];
87
- const next = locks.filter((l) => !(l.resource === resource && l.holder === holder));
88
- if (next.length === locks.length)
89
- return false;
90
- await this.store.setJSON(LOCKS_KEY, next);
91
- return true;
92
- }
93
- async getLocks() {
94
- return (await this.store.getJSON(LOCKS_KEY)) ?? [];
95
- }
96
- // ── Scheduler lease ───────────────────────────────────────────────────────
97
- async acquireLease(holder, ttlMs = 60_000, runId) {
98
- const existing = await this.getLease();
99
- const now = Date.now();
100
- if (existing && existing.expires_at > now) {
101
- throw new Error(`SchedulerRepository: lease held by ${existing.holder}`);
102
- }
103
- const lease = {
104
- holder,
105
- acquired_at: now,
106
- expires_at: now + ttlMs,
107
- run_id: runId,
108
- };
109
- await this.store.setJSON(LEASE_KEY, lease);
110
- return lease;
111
- }
112
- async releaseLease(holder) {
113
- const lease = await this.getLease();
114
- if (!lease || lease.holder !== holder)
115
- return false;
116
- await this.store.delete(LEASE_KEY);
117
- return true;
118
- }
119
- async getLease() {
120
- return this.store.getJSON(LEASE_KEY);
121
- }
122
152
  }
123
153
  //# sourceMappingURL=scheduler-repository.js.map
@@ -14,6 +14,7 @@ export interface TodoNode {
14
14
  updated_at: number;
15
15
  notes?: string;
16
16
  }
17
+ type TodoUpsertInput = Omit<TodoNode, "created_at" | "updated_at"> & Partial<Pick<TodoNode, "created_at">>;
17
18
  export declare class TodoRepository {
18
19
  private store;
19
20
  constructor(store: AcePackedStore);
@@ -26,6 +27,9 @@ export declare class TodoRepository {
26
27
  assigned_to?: string;
27
28
  }): Promise<TodoNode[]>;
28
29
  getAll(): Promise<TodoNode[]>;
30
+ remove(id: string): Promise<boolean>;
31
+ replaceAll(todos: TodoUpsertInput[]): Promise<TodoNode[]>;
29
32
  private _updateIndex;
30
33
  }
34
+ export {};
31
35
  //# sourceMappingURL=todo-repository.d.ts.map
@@ -61,6 +61,56 @@ export class TodoRepository {
61
61
  async getAll() {
62
62
  return this.list();
63
63
  }
64
+ async remove(id) {
65
+ const existing = await this.get(id);
66
+ if (!existing)
67
+ return false;
68
+ await this.store.delete(this.key(id));
69
+ await this.store.appendEntry({
70
+ kind: EntityKind.Todo,
71
+ content_source: ContentSource.Runtime,
72
+ key: this.key(id),
73
+ payload: { op: "remove", id },
74
+ });
75
+ await this._updateIndex(existing, "remove");
76
+ return true;
77
+ }
78
+ async replaceAll(todos) {
79
+ const existing = new Map((await this.getAll()).map((todo) => [todo.id, todo]));
80
+ const nextRecords = [];
81
+ const nextIds = [];
82
+ for (const todo of todos) {
83
+ const now = Date.now();
84
+ const prior = existing.get(todo.id);
85
+ const record = {
86
+ ...prior,
87
+ ...todo,
88
+ created_at: todo.created_at ?? prior?.created_at ?? now,
89
+ updated_at: now,
90
+ };
91
+ await this.store.setJSON(this.key(todo.id), record);
92
+ await this.store.appendEntry({
93
+ kind: EntityKind.Todo,
94
+ content_source: ContentSource.Runtime,
95
+ key: this.key(todo.id),
96
+ payload: record,
97
+ });
98
+ nextIds.push(todo.id);
99
+ nextRecords.push(record);
100
+ existing.delete(todo.id);
101
+ }
102
+ for (const staleId of existing.keys()) {
103
+ await this.store.delete(this.key(staleId));
104
+ await this.store.appendEntry({
105
+ kind: EntityKind.Todo,
106
+ content_source: ContentSource.Runtime,
107
+ key: this.key(staleId),
108
+ payload: { op: "remove", id: staleId },
109
+ });
110
+ }
111
+ await this.store.setJSON(TODO_INDEX_KEY, nextIds);
112
+ return nextRecords;
113
+ }
64
114
  async _updateIndex(todo, op) {
65
115
  const index = await this.store.getJSON(TODO_INDEX_KEY) ?? [];
66
116
  if (op === "add" && !index.includes(todo.id)) {
@@ -14,14 +14,18 @@ import { SessionRepository } from "./repositories/session-repository.js";
14
14
  import { TrackerRepository } from "./repositories/tracker-repository.js";
15
15
  import { DiscoveryRepository } from "./repositories/discovery-repository.js";
16
16
  import { VericifyRepository } from "./repositories/vericify-repository.js";
17
+ import { LocalModelRuntimeRepository } from "./repositories/local-model-runtime-repository.js";
17
18
  export interface DashboardSnapshot {
18
19
  handoffs: Awaited<ReturnType<HandoffRepository["list"]>>;
19
20
  todos: Awaited<ReturnType<TodoRepository["getAll"]>>;
20
21
  ledger: Awaited<ReturnType<LedgerRepository["recent"]>>;
21
22
  jobs: Awaited<ReturnType<SchedulerRepository["listJobs"]>>;
23
+ schedulerLocks: Awaited<ReturnType<SchedulerRepository["listLocks"]>>;
24
+ schedulerLease: Awaited<ReturnType<SchedulerRepository["readLease"]>>;
22
25
  sessions: Awaited<ReturnType<SessionRepository["list"]>>;
23
26
  events: Awaited<ReturnType<TrackerRepository["list"]>>;
24
27
  providers: Awaited<ReturnType<DiscoveryRepository["listAll"]>>;
28
+ runtimeStatuses: Awaited<ReturnType<LocalModelRuntimeRepository["listRuntimeStatuses"]>>;
25
29
  posts: Awaited<ReturnType<VericifyRepository["list"]>>;
26
30
  snapped_at: number;
27
31
  }
@@ -34,10 +38,13 @@ export declare class StoreStateReader {
34
38
  handoffs(): Promise<import("./repositories/handoff-repository.js").HandoffRecord[]>;
35
39
  todos(): Promise<import("./repositories/todo-repository.js").TodoNode[]>;
36
40
  ledger(): Promise<import("./repositories/ledger-repository.js").LedgerEvent[]>;
37
- schedulerState(): Promise<import("./repositories/scheduler-repository.js").Job[]>;
41
+ schedulerState(): Promise<import("../job-scheduler.js").JobRecord[]>;
42
+ schedulerLocks(): Promise<import("../job-scheduler.js").JobLockRecord[]>;
43
+ schedulerLease(): Promise<import("../job-scheduler.js").SchedulerLeaseFile | undefined>;
38
44
  sessions(): Promise<import("./repositories/session-repository.js").SessionRecord[]>;
39
45
  statusEvents(): Promise<import("./repositories/tracker-repository.js").StatusEvent[]>;
40
46
  providerDiscovery(): Promise<import("./repositories/discovery-repository.js").DiscoveryResult[]>;
47
+ runtimeStatuses(): Promise<import("./repositories/local-model-runtime-repository.js").AceRuntimeStatusPacket[]>;
41
48
  vericifyPosts(): Promise<import("./repositories/vericify-repository.js").VericifyPost[]>;
42
49
  domainDocs(_domain: string): Promise<never[]>;
43
50
  }
@@ -15,6 +15,7 @@ import { SessionRepository } from "./repositories/session-repository.js";
15
15
  import { TrackerRepository } from "./repositories/tracker-repository.js";
16
16
  import { DiscoveryRepository } from "./repositories/discovery-repository.js";
17
17
  import { VericifyRepository } from "./repositories/vericify-repository.js";
18
+ import { LocalModelRuntimeRepository } from "./repositories/local-model-runtime-repository.js";
18
19
  export class StoreStateReader {
19
20
  store = null;
20
21
  get repos() {
@@ -28,6 +29,7 @@ export class StoreStateReader {
28
29
  sessions: new SessionRepository(this.store),
29
30
  tracker: new TrackerRepository(this.store),
30
31
  discovery: new DiscoveryRepository(this.store),
32
+ localModelRuntime: new LocalModelRuntimeRepository(this.store),
31
33
  vericify: new VericifyRepository(this.store),
32
34
  };
33
35
  }
@@ -43,14 +45,17 @@ export class StoreStateReader {
43
45
  }
44
46
  async snapshot() {
45
47
  const r = this.repos;
46
- const [handoffs, todos, ledger, jobs, sessions, events, providers, posts] = await Promise.all([
48
+ const [handoffs, todos, ledger, jobs, schedulerLocks, schedulerLease, sessions, events, providers, runtimeStatuses, posts] = await Promise.all([
47
49
  r.handoffs.list(),
48
50
  r.todos.getAll(),
49
51
  r.ledger.recent(20),
50
52
  r.scheduler.listJobs(),
53
+ r.scheduler.listLocks(),
54
+ r.scheduler.readLease(),
51
55
  r.sessions.list(),
52
56
  r.tracker.list({ limit: 50 }),
53
57
  r.discovery.listAll(),
58
+ r.localModelRuntime.listRuntimeStatuses(),
54
59
  r.vericify.list(),
55
60
  ]);
56
61
  return {
@@ -58,9 +63,12 @@ export class StoreStateReader {
58
63
  todos,
59
64
  ledger,
60
65
  jobs,
66
+ schedulerLocks,
67
+ schedulerLease,
61
68
  sessions,
62
69
  events,
63
70
  providers,
71
+ runtimeStatuses,
64
72
  posts,
65
73
  snapped_at: Date.now(),
66
74
  };
@@ -69,9 +77,12 @@ export class StoreStateReader {
69
77
  async todos() { return this.repos.todos.getAll(); }
70
78
  async ledger() { return this.repos.ledger.list(); }
71
79
  async schedulerState() { return this.repos.scheduler.listJobs(); }
80
+ async schedulerLocks() { return this.repos.scheduler.listLocks(); }
81
+ async schedulerLease() { return this.repos.scheduler.readLease(); }
72
82
  async sessions() { return this.repos.sessions.list(); }
73
83
  async statusEvents() { return this.repos.tracker.list(); }
74
84
  async providerDiscovery() { return this.repos.discovery.listAll(); }
85
+ async runtimeStatuses() { return this.repos.localModelRuntime.listRuntimeStatuses(); }
75
86
  async vericifyPosts() { return this.repos.vericify.list(); }
76
87
  async domainDocs(_domain) { return []; } // Phase 6 wiring
77
88
  }
@@ -13,21 +13,47 @@ const H_EVT_BASE = 60;
13
13
  const TEXT = new TextEncoder();
14
14
  const DECODE = new TextDecoder();
15
15
  export const OPERATIONAL_ARTIFACT_REL_PATHS = new Set([
16
+ // ── Core mutable state — agent-written, must stay inside ace-state.ace ──────
17
+ "agent-state/TASK.md",
18
+ "agent-state/STATUS.md",
19
+ "agent-state/SCOPE.md",
20
+ "agent-state/DECISIONS.md",
21
+ "agent-state/RISKS.md",
22
+ "agent-state/QUALITY_GATES.md",
23
+ "agent-state/HANDOFF.json",
24
+ "agent-state/EVIDENCE_LOG.md",
25
+ "agent-state/PROVENANCE_LOG.md",
26
+ "agent-state/TEAL_CONFIG.md",
27
+ "agent-state/INTERFACE_REGISTRY.md",
28
+ // ── Tool-generated state — written by internal tools, not agents directly ───
29
+ "agent-state/ARTIFACT_MANIFEST.json",
30
+ "agent-state/AST_GREP_COMMANDS.md",
16
31
  "agent-state/AST_GREP_INDEX.json",
17
32
  "agent-state/AST_GREP_INDEX.md",
18
- "agent-state/EVIDENCE_LOG.md",
33
+ "agent-state/SKILL_CATALOG.md",
34
+ "agent-state/PUBLIC_SURFACE_REPORT.md",
35
+ // ── Append-only event logs ────────────────────────────────────────────────
19
36
  "agent-state/STATUS_EVENTS.ndjson",
20
37
  "agent-state/STATUS_EVENTS-archive.ndjson",
38
+ "agent-state/run-ledger.json",
39
+ "agent-state/run-ledger-archive.ndjson",
40
+ // ── Registries and indexes ────────────────────────────────────────────────
21
41
  "agent-state/handoff-registry.json",
22
42
  "agent-state/index-fingerprints.json",
23
43
  "agent-state/index.json",
24
- "agent-state/run-ledger.json",
25
- "agent-state/run-ledger-archive.ndjson",
44
+ "agent-state/kanban.html",
45
+ "agent-state/kanban.json",
46
+ "agent-state/tracker-snapshot.json",
47
+ "agent-state/todo-state.json",
48
+ // ── Runtime config and sessions ───────────────────────────────────────────
26
49
  "agent-state/runtime-executor-sessions.json",
27
50
  "agent-state/runtime-tool-specs.json",
28
51
  "agent-state/runtime-workspaces.json",
29
- "agent-state/todo-state.json",
30
- "agent-state/tracker-snapshot.json",
52
+ // ── Scheduler hot-path — also projected to disk for fast reads ────────────
53
+ "agent-state/job-locks.json",
54
+ "agent-state/job-queue.json",
55
+ "agent-state/scheduler-lease.json",
56
+ // ── Vericify sidecar ─────────────────────────────────────────────────────
31
57
  "agent-state/vericify/ace-bridge.json",
32
58
  "agent-state/vericify/process-posts.json",
33
59
  ]);
@@ -0,0 +1,30 @@
1
+ export declare const STORE_AUTHORITY_AUDIT_REPORT_REL_PATH = "agent-state/STORE_AUTHORITY_AUDIT.md";
2
+ export type StoreAuthorityClassification = "canonical knowledge artifact" | "canonical runtime state" | "projection only";
3
+ export interface StoreAuthoritySafeWriteSite {
4
+ call: "safeWrite" | "safeWriteWorkspaceFile" | "safeWriteReport";
5
+ classification: StoreAuthorityClassification;
6
+ file: string;
7
+ line: number;
8
+ column: number;
9
+ target_expression: string;
10
+ target_path?: string;
11
+ fallback_keys: string[];
12
+ bypasses_acepack: boolean;
13
+ regenerable_from_store: boolean;
14
+ note: string;
15
+ }
16
+ export interface StoreAuthorityAuditResult {
17
+ bypassing_sites: StoreAuthoritySafeWriteSite[];
18
+ classifications: Record<StoreAuthorityClassification, StoreAuthoritySafeWriteSite[]>;
19
+ generated_at: string;
20
+ non_regenerable_projections: StoreAuthoritySafeWriteSite[];
21
+ report_path: string;
22
+ runtime_files_without_store_fallback_keys: StoreAuthoritySafeWriteSite[];
23
+ safe_write_sites: StoreAuthoritySafeWriteSite[];
24
+ source_root: string;
25
+ total_safe_write_sites: number;
26
+ }
27
+ export declare function auditStoreAuthority(): StoreAuthorityAuditResult;
28
+ export declare function renderStoreAuthorityAuditReport(result: StoreAuthorityAuditResult): string;
29
+ export declare function writeStoreAuthorityAuditReport(result: StoreAuthorityAuditResult, targetPath?: string): string;
30
+ //# sourceMappingURL=store-authority-audit.d.ts.map