@eir-labs/coltrane 0.6.2 → 0.7.3

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 (106) hide show
  1. package/README.md +23 -0
  2. package/agents/bill.json +59 -0
  3. package/agents/deploy-agent.json +68 -0
  4. package/agents/deploy-scout.json +40 -0
  5. package/agents/john.json +42 -0
  6. package/agents/lineage-scout-external.json +25 -0
  7. package/agents/lineage-scout-internal.json +32 -0
  8. package/agents/lineage-scribe.json +21 -0
  9. package/agents/lineage-weaver.json +23 -0
  10. package/agents/miles.json +44 -0
  11. package/charts/software-delivery-v1.json +9 -0
  12. package/charts/software-delivery-v2.json +39 -0
  13. package/dist/src/canonical_form.d.ts +23 -0
  14. package/dist/src/canonical_form.js +53 -0
  15. package/dist/src/canonical_form.js.map +1 -1
  16. package/dist/src/chart.d.ts +254 -0
  17. package/dist/src/chart.js +897 -0
  18. package/dist/src/chart.js.map +1 -0
  19. package/dist/src/cli.d.ts +19 -4
  20. package/dist/src/cli.js +132 -9
  21. package/dist/src/cli.js.map +1 -1
  22. package/dist/src/composition.d.ts +24 -0
  23. package/dist/src/composition.js +50 -5
  24. package/dist/src/composition.js.map +1 -1
  25. package/dist/src/genome_schema.d.ts +1203 -166
  26. package/dist/src/genome_schema.js +344 -34
  27. package/dist/src/genome_schema.js.map +1 -1
  28. package/dist/src/genome_store.d.ts +53 -3
  29. package/dist/src/genome_store.js +316 -139
  30. package/dist/src/genome_store.js.map +1 -1
  31. package/dist/src/gig_tracker.d.ts +11 -1
  32. package/dist/src/gig_tracker.js +5 -0
  33. package/dist/src/gig_tracker.js.map +1 -1
  34. package/dist/src/index.d.ts +1 -0
  35. package/dist/src/index.js +1 -0
  36. package/dist/src/index.js.map +1 -1
  37. package/dist/src/ledger.d.ts +22 -0
  38. package/dist/src/ledger.js +4 -0
  39. package/dist/src/ledger.js.map +1 -1
  40. package/dist/src/loader.d.ts +9 -1
  41. package/dist/src/loader.js +105 -5
  42. package/dist/src/loader.js.map +1 -1
  43. package/dist/src/mcp.js +54 -4
  44. package/dist/src/mcp.js.map +1 -1
  45. package/dist/src/output_mirror.d.ts +1 -1
  46. package/dist/src/outputs.d.ts +75 -1
  47. package/dist/src/outputs.js +142 -28
  48. package/dist/src/outputs.js.map +1 -1
  49. package/dist/src/reuse.d.ts +71 -0
  50. package/dist/src/reuse.js +0 -0
  51. package/dist/src/reuse.js.map +1 -1
  52. package/dist/src/runtime.d.ts +91 -2
  53. package/dist/src/runtime.js +236 -18
  54. package/dist/src/runtime.js.map +1 -1
  55. package/dist/src/server.d.ts +16 -0
  56. package/dist/src/server.js +600 -64
  57. package/dist/src/server.js.map +1 -1
  58. package/dist/src/version.d.ts +1 -1
  59. package/dist/src/version.js +1 -1
  60. package/dist/src/worker.d.ts +228 -0
  61. package/dist/src/worker.js +737 -0
  62. package/dist/src/worker.js.map +1 -0
  63. package/domain_types/alignment-plan.json +16 -0
  64. package/domain_types/branch-state.json +21 -0
  65. package/domain_types/change-context.json +39 -0
  66. package/domain_types/change-decision.json +36 -0
  67. package/domain_types/change-plan.json +47 -0
  68. package/domain_types/change-request.json +24 -0
  69. package/domain_types/change-set.json +46 -0
  70. package/domain_types/change-verdict.json +26 -0
  71. package/domain_types/deploy-verdict.json +23 -0
  72. package/domain_types/design-brief.json +37 -0
  73. package/domain_types/design-concept.json +36 -0
  74. package/domain_types/design-definition.json +37 -0
  75. package/domain_types/design-question.json +23 -0
  76. package/domain_types/design-verdict.json +27 -0
  77. package/domain_types/internal-inventory.json +26 -0
  78. package/domain_types/lineage-hit.json +19 -0
  79. package/domain_types/lineage-map.json +32 -0
  80. package/domain_types/lineage-question.json +17 -0
  81. package/domain_types/lineage-record.json +19 -0
  82. package/domain_types/lineage-verdict.json +16 -0
  83. package/domain_types/preview-deployment.json +32 -0
  84. package/institutions/quartet.json +344 -0
  85. package/package.json +4 -1
  86. package/skills/vercel-api/fixtures/error.json +10 -0
  87. package/skills/vercel-api/fixtures/ready.json +10 -0
  88. package/skills/vercel-api/fixtures/unsettled.json +10 -0
  89. package/skills/vercel-api/meta.json +10 -0
  90. package/skills/vercel-api/skill.mjs +63 -0
  91. package/standards/lineage-pass-v1.json +96 -0
  92. package/standards/preview-deploy-v1.json +89 -0
  93. package/standards/product-design-v1.json +122 -0
  94. package/standards/promote-v1.json +41 -0
  95. package/standards/software-change-v1.json +147 -0
  96. package/venues/ci-deploy-room-v1.json +28 -0
  97. package/venues/empty-room-v1.json +19 -0
  98. package/dist/src/conduct_daemon.d.ts +0 -59
  99. package/dist/src/conduct_daemon.js +0 -178
  100. package/dist/src/conduct_daemon.js.map +0 -1
  101. package/dist/src/play_worker.d.ts +0 -24
  102. package/dist/src/play_worker.js +0 -49
  103. package/dist/src/play_worker.js.map +0 -1
  104. package/dist/src/supabase_genome.d.ts +0 -28
  105. package/dist/src/supabase_genome.js +0 -49
  106. package/dist/src/supabase_genome.js.map +0 -1
@@ -0,0 +1,228 @@
1
+ import { type AgentInvoker } from "./runtime.js";
2
+ import { type Registry } from "./registry.js";
3
+ import { type OutputStore } from "./outputs.js";
4
+ import { type GigCheckpoint, type RunIdentity } from "./reuse.js";
5
+ import type { Standard } from "./composition.js";
6
+ import type { LoadedGenome } from "./loader.js";
7
+ /** Where the org store is, and who is working. */
8
+ export interface WorkerContext {
9
+ baseUrl: string;
10
+ anonKey: string;
11
+ /** The seated agent's ctk_ capability token — claim/genome/fail all speak through it. */
12
+ agentToken: string;
13
+ /** Lease label recorded on the claimed row (defaults to worker:<acting_for> store-side). */
14
+ worker?: string;
15
+ }
16
+ /** The claim RPC's payload: everything the worker needs to run the row it now leases. */
17
+ export interface ClaimedGig {
18
+ gig_id: string;
19
+ standard_slug: string;
20
+ standard_version: number | null;
21
+ mode: string;
22
+ input: Record<string, unknown>;
23
+ acting_for: string;
24
+ /**
25
+ * The human seat's verdicts, keyed by chair role — present on a RE-claim of a gig that
26
+ * parked. The approve RPC writes them onto the row's manifest and re-queues it; the claim
27
+ * hands them back here, and each entry carries the verdict AND who gave it, because the
28
+ * approval seals under the approving principal's name rather than the worker's.
29
+ */
30
+ approvals?: Record<string, {
31
+ verdict: Record<string, unknown>;
32
+ approved_by?: string;
33
+ }> | null;
34
+ }
35
+ /**
36
+ * The worker's durable state root: `checkpoints/` for the resume records, `outputs/` + `refs/`
37
+ * for the sealed rows those records name — the sibling layout `createCheckpointStore` documents.
38
+ *
39
+ * BOTH halves have to outlive the process. A worker is a short-lived consumer: it claims one
40
+ * row and exits, and the approved re-claim is a DIFFERENT process. A checkpoint whose outputs
41
+ * the next process cannot read refuses the resume it exists to permit, so the run would be
42
+ * paid for twice — which is the whole cost this store exists to avoid.
43
+ */
44
+ export declare function workerStateRoot(): string;
45
+ /** Default worker-state TTL, in days. A checkpoint older than this is presumed abandoned. */
46
+ export declare const DEFAULT_WORKER_STATE_TTL_DAYS = 7;
47
+ /** Resolve the reaper TTL from `COLTRANE_WORKER_STATE_TTL_DAYS`, falling back to the default. */
48
+ export declare function workerStateTtlDays(): number;
49
+ export interface ReapOptions {
50
+ /** Age threshold in days. State whose mtime is older than this is eligible. Defaults to `workerStateTtlDays()`. */
51
+ ttlDays?: number;
52
+ /** "Now", in epoch ms, for the age comparison. Defaults to `Date.now()` at call time (never module load). */
53
+ now?: number;
54
+ }
55
+ export interface ReapResult {
56
+ /** gig ids whose checkpoint (+ siblings) were removed for being older than the TTL. */
57
+ checkpoints_removed: string[];
58
+ /** gig ids whose orphan output/refs rows (no live checkpoint) were removed for age. */
59
+ orphans_removed: string[];
60
+ /** How many checkpoint files were inspected and KEPT (fresh, or load-bearing). */
61
+ kept: number;
62
+ /** Non-fatal per-file errors, so a partial sweep is visible without throwing. */
63
+ errors: string[];
64
+ }
65
+ /**
66
+ * Bound the worker state root's growth. The runtime deletes a checkpoint on SUCCESS, but a
67
+ * FAILED / awaiting-approval / abandoned gig leaves its `checkpoints/<gig>.json` (plus the
68
+ * `outputs/<gig>.jsonl` + `refs/<gig>.jsonl` it names) behind forever — an unbounded disk
69
+ * leak. This drops what is old enough to be presumed abandoned.
70
+ *
71
+ * WHAT IT TOUCHES:
72
+ * - A `checkpoints/<gig>.json` whose MTIME is older than the TTL, together with that gig's
73
+ * sibling `outputs/<gig>.jsonl` and `refs/<gig>.jsonl` — they are dead weight once the
74
+ * checkpoint that named them is gone.
75
+ * - An ORPHAN `outputs/<gig>.jsonl` / `refs/<gig>.jsonl` (no checkpoint file for that gig at
76
+ * all — e.g. a completed gig whose checkpoint was already dropped on success) older than the
77
+ * TTL. This is the other half of the leak: success removes the checkpoint but leaves the rows.
78
+ *
79
+ * WHAT IT NEVER TOUCHES:
80
+ * - Any gig whose checkpoint is FRESHER than the TTL. A parked / awaiting-approval gig's
81
+ * checkpoint is LOAD-BEARING for the approved resume, and the TTL is the "reasonable window"
82
+ * that protects it — the reaper cannot see the org store's row status locally, so mtime is
83
+ * the proxy: recent state is kept. A fresh checkpoint's outputs are never swept even if the
84
+ * outputs file itself looks old (a restore-only resume re-touches the checkpoint but appends
85
+ * no new rows), because the sweep is driven from checkpoint age, not output age.
86
+ *
87
+ * Best-effort by construction: every filesystem op is caught and recorded in `errors`; the
88
+ * function never throws, so a reap failure can never fail the claim it runs ahead of.
89
+ */
90
+ export declare function reapWorkerState(root: string, opts?: ReapOptions): ReapResult;
91
+ export type WorkOnceResult = {
92
+ claimed: false;
93
+ } | {
94
+ claimed: true;
95
+ gig_id: string;
96
+ /** `awaiting_approval` is its own outcome: a run that reached a human chair is neither
97
+ * finished nor broken, and calling it either would be a lie the operator acts on. */
98
+ status: "complete" | "failed" | "awaiting_approval";
99
+ outputs_count?: number;
100
+ error?: string;
101
+ /** Present iff awaiting_approval: the human chair the run parked at. */
102
+ awaiting?: {
103
+ phase: string;
104
+ role: string;
105
+ };
106
+ };
107
+ export interface WorkOnceDeps {
108
+ /** Build the chair invoker against the STORE registry (types the org's outputs seal to). */
109
+ makeInvoke(registry: Registry, genome: LoadedGenome): AgentInvoker;
110
+ /** Progress line sink (CLI wires stderr); silent by default. */
111
+ log?(line: string): void;
112
+ }
113
+ /** Atomically claim the oldest runnable gig (queued, or running with an expired lease) the
114
+ * seated agent's chair contract authorizes. Null means the queue holds nothing for us. */
115
+ export declare function claimNextGig(ctx: WorkerContext): Promise<ClaimedGig | null>;
116
+ /**
117
+ * Release the lease on a PARKED gig: the row goes `awaiting_approval` and its lease clears, so
118
+ * an approval can re-queue it immediately instead of waiting the lease out. Deliberately NOT
119
+ * `gig_fail` — a run waiting on a person is not a failed run, and recording it as one both lies
120
+ * to the operator and takes the row out of the approve→requeue path.
121
+ *
122
+ * False means the store did not record the release — including a store that has not deployed
123
+ * the RPC yet. The run's own drained header already carries `awaiting_approval`, so an absent
124
+ * release is a missing convenience, not a lost fact, and must not fail the claim.
125
+ */
126
+ export declare function parkGig(ctx: WorkerContext, gig_id: string): Promise<boolean>;
127
+ /** Record a failed run on the claimed row. True iff the store recorded it (row was running). */
128
+ export declare function failGig(ctx: WorkerContext, gig_id: string, error: string): Promise<boolean>;
129
+ /**
130
+ * One sealed row as `coltrane_mcp_gig_outputs` hands it back — the sink's view of an output.
131
+ *
132
+ * NARROWER than an `OutputRecord`, and the gap is the whole difficulty: the sink returns no
133
+ * `core_type`, no `domain`, no `primitive`, no `domain_type_version` and no `from_role`. Every
134
+ * one of the first four is folded into `content_sha`, so they are RE-DERIVED from the loaded
135
+ * genome the way the seal boundary derives them, and the re-derivation is then proved against
136
+ * the sha the sink recorded. A row that no longer hashes to its claimed sha is refused.
137
+ */
138
+ export interface DrainedOutput {
139
+ id: string;
140
+ domain_type: string;
141
+ agent_slug: string;
142
+ phase?: string | null;
143
+ content_sha: string;
144
+ input_shas?: readonly (string | null)[] | null;
145
+ created_at: string;
146
+ data: Record<string, unknown>;
147
+ }
148
+ /** A reconstruction either produced a checkpoint or refused, and a refusal always says why. */
149
+ export type DrainResumeState = {
150
+ ok: true;
151
+ checkpoint: GigCheckpoint;
152
+ } | {
153
+ ok: false;
154
+ reason: string;
155
+ };
156
+ /** The sink's sealed rows for one gig. `[]` covers "no drain to read" as well as "nothing drained". */
157
+ export declare function fetchDrainedOutputs(ctx: WorkerContext, gig_id: string): Promise<{
158
+ rows: DrainedOutput[];
159
+ error?: string;
160
+ }>;
161
+ /**
162
+ * The `genome_hash` the sink recorded on this gig's drained HEADER.
163
+ *
164
+ * This is the only identity a drained gig carries, and reading it is what keeps the
165
+ * reconstruction from being a splice. `genomeHash` folds the standard's whole phase graph and
166
+ * every bound agent's type surface — chair `depends_on`, `input_contract`, an added or removed
167
+ * phase — none of which reaches an individual row's `content_sha`. Without this check a
168
+ * pipeline could be re-wired between the park and the approval and the restored outputs would
169
+ * be consumed by chairs that never produced them, with nothing in the manifest recording it.
170
+ *
171
+ * STATED GAP: the header carries no `producers_sha`, so a rewritten agent `method` (or a
172
+ * rewritten skill under a stable version) is invisible to this path — the very hole
173
+ * `RunIdentity.producers_sha` exists to close for a LOCAL checkpoint. A drain-reconstructed
174
+ * resume is therefore a weaker gate than a local one by exactly that much, and the strongest
175
+ * available check is the one applied: the sink's structural hash plus a per-row re-seal.
176
+ */
177
+ export declare function fetchDrainedGenomeHash(ctx: WorkerContext, gig_id: string): Promise<{
178
+ genome_hash?: string;
179
+ error?: string;
180
+ }>;
181
+ /**
182
+ * Turn the sink's sealed rows into a resume checkpoint — or refuse, with a reason.
183
+ *
184
+ * ALL-OR-NOTHING, in two passes. Pass one derives and verifies every row while nothing is
185
+ * durable; pass two writes. A gig whose second row fails must not leave its first one in the
186
+ * local store seeding a half-resume, which is the same invariant #243 gave a single chair, one
187
+ * scope up.
188
+ *
189
+ * ROLE MAPPING. The sink does not record `from_role`, so each row is mapped to a chair by
190
+ * `phase` + the chair's SEAT: `agent_slug` for an agent chair, the skill slug for a skill-backed
191
+ * one, and name-agnostically for a human chair (its record seals under the approving principal,
192
+ * whom the genome cannot know). The row's `domain_type` narrows further — a chair that does not
193
+ * seal that type is not a candidate. Zero candidates or MORE THAN ONE both refuse: a guess about
194
+ * which chair produced a sealed output is a guess about the provenance chain.
195
+ *
196
+ * SHA VERIFICATION. Every row is re-sealed under the derived core/primitive/domain and the sha
197
+ * compared to the one the sink recorded. A mismatch refuses the WHOLE reconstruction — a sink
198
+ * row that no longer hashes to its claimed sha must never silently seed a resume, and one such
199
+ * row is evidence about the sink, not about that row alone.
200
+ */
201
+ export declare function resumeStateFromDrain(args: {
202
+ gig_id: string;
203
+ standard: Standard;
204
+ identity: RunIdentity;
205
+ rows: readonly DrainedOutput[];
206
+ outputs: OutputStore;
207
+ }): DrainResumeState;
208
+ /**
209
+ * Map the claim's per-role approval entries onto runGig's two arguments.
210
+ *
211
+ * The store keys each verdict by ROLE (a standard may hold more than one human chair) while
212
+ * runGig takes a single `approved_by` for the run. So the name is read from the entry for the
213
+ * chair this claim will actually reach — the first human chair the checkpoint does not already
214
+ * hold — and falls back to the first entry when that is not discernible. Attribution on a seal
215
+ * is not decoration: the approval output carries it as its `agent_slug`.
216
+ */
217
+ export declare function approvalWiring(approvals: ClaimedGig["approvals"], standard: Standard, completedRoles?: readonly string[]): {
218
+ approvals?: Record<string, Record<string, unknown>>;
219
+ approved_by?: string;
220
+ };
221
+ /** One unit of work: claim → load the org genome (as the agent) → run under the claimed
222
+ * gig's id → results drain via the org drain key (engine drain layer, env-configured), or
223
+ * the failure is recorded. Never throws for a run failure — a thrown claim/store error
224
+ * means the worker itself could not speak to the store.
225
+ *
226
+ * A run that reaches an unapproved human chair PARKS: the row is released (parkGig) and the
227
+ * outcome is `awaiting_approval` — its own status, because it is neither finished nor broken. */
228
+ export declare function workOnce(ctx: WorkerContext, deps: WorkOnceDeps): Promise<WorkOnceResult>;