@eir-labs/coltrane 0.4.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 (279) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +85 -0
  3. package/agents/anticipation-mapper.json +34 -0
  4. package/agents/claim-amender.json +34 -0
  5. package/agents/claim-architect.json +34 -0
  6. package/agents/claim-rewriter.json +32 -0
  7. package/agents/delivery-finalizer.json +40 -0
  8. package/agents/diamond-cutter.json +33 -0
  9. package/agents/disclosure-analyst.json +26 -0
  10. package/agents/domain-explorer.json +37 -0
  11. package/agents/e2e-runner.json +34 -0
  12. package/agents/e2e-suite-judge.json +26 -0
  13. package/agents/event-clusterer.json +29 -0
  14. package/agents/novelty-searcher.json +40 -0
  15. package/agents/patent-browser-scout.json +49 -0
  16. package/agents/patent-examiner.json +36 -0
  17. package/agents/phase_agents/claim-rewriter.md +44 -0
  18. package/agents/phase_agents/delivery-finalizer.md +30 -0
  19. package/agents/phase_agents/diamond-cutter.md +47 -0
  20. package/agents/phase_agents/domain-explorer.md +27 -0
  21. package/agents/phase_agents/novelty-searcher.md +50 -0
  22. package/agents/phase_agents/problem-definer.md +32 -0
  23. package/agents/phase_agents/solution-developer.md +26 -0
  24. package/agents/phase_agents/verdict-judger.md +70 -0
  25. package/agents/players/audience-modeler.md +40 -0
  26. package/agents/players/chain-audit-keeper.md +41 -0
  27. package/agents/players/illumination-reviewer.md +42 -0
  28. package/agents/players/methodology-cadence-keeper.md +42 -0
  29. package/agents/players/substrate-edge-keeper.md +45 -0
  30. package/agents/prior-art-scout.json +45 -0
  31. package/agents/problem-definer.json +35 -0
  32. package/agents/seeds/steve_seed_a.json +12 -0
  33. package/agents/seeds/steve_seed_b.json +12 -0
  34. package/agents/seeds/steve_seed_c.json +12 -0
  35. package/agents/seeds/steve_seed_d.json +12 -0
  36. package/agents/sensor.json +22 -0
  37. package/agents/solution-developer.json +35 -0
  38. package/agents/source-walker.json +38 -0
  39. package/agents/spec-drafter.json +31 -0
  40. package/agents/sub_thread_soft_judge.json +26 -0
  41. package/agents/sub_thread_trace_sensor.json +22 -0
  42. package/agents/summarizer.json +25 -0
  43. package/agents/synthesis-writer.json +29 -0
  44. package/agents/triage-judge.json +39 -0
  45. package/agents/user_flow_judge.json +26 -0
  46. package/agents/user_flow_sensor.json +22 -0
  47. package/agents/verdict-judger.json +39 -0
  48. package/core_types/artifact.json +17 -0
  49. package/core_types/interpretation.json +16 -0
  50. package/core_types/judgment.json +16 -0
  51. package/core_types/plan.json +16 -0
  52. package/core_types/signal.json +16 -0
  53. package/core_types/verdict.json +27 -0
  54. package/dist/src/access_grant.d.ts +46 -0
  55. package/dist/src/access_grant.js +76 -0
  56. package/dist/src/access_grant.js.map +1 -0
  57. package/dist/src/acoustics.d.ts +9 -0
  58. package/dist/src/acoustics.js +65 -0
  59. package/dist/src/acoustics.js.map +1 -0
  60. package/dist/src/agent_profile.d.ts +36 -0
  61. package/dist/src/agent_profile.js +57 -0
  62. package/dist/src/agent_profile.js.map +1 -0
  63. package/dist/src/bifrost_invoker.d.ts +33 -0
  64. package/dist/src/bifrost_invoker.js +85 -0
  65. package/dist/src/bifrost_invoker.js.map +1 -0
  66. package/dist/src/canonical_core_types.d.ts +2 -0
  67. package/dist/src/canonical_core_types.js +111 -0
  68. package/dist/src/canonical_core_types.js.map +1 -0
  69. package/dist/src/canonical_form.d.ts +55 -0
  70. package/dist/src/canonical_form.js +93 -0
  71. package/dist/src/canonical_form.js.map +1 -0
  72. package/dist/src/charter.d.ts +37 -0
  73. package/dist/src/charter.js +86 -0
  74. package/dist/src/charter.js.map +1 -0
  75. package/dist/src/circle_of_fifths.d.ts +27 -0
  76. package/dist/src/circle_of_fifths.js +78 -0
  77. package/dist/src/circle_of_fifths.js.map +1 -0
  78. package/dist/src/claude_invoker.d.ts +102 -0
  79. package/dist/src/claude_invoker.js +760 -0
  80. package/dist/src/claude_invoker.js.map +1 -0
  81. package/dist/src/coltrane_profile.d.ts +87 -0
  82. package/dist/src/coltrane_profile.js +132 -0
  83. package/dist/src/coltrane_profile.js.map +1 -0
  84. package/dist/src/composition.d.ts +57 -0
  85. package/dist/src/composition.js +447 -0
  86. package/dist/src/composition.js.map +1 -0
  87. package/dist/src/core_types.d.ts +6 -0
  88. package/dist/src/core_types.js +25 -0
  89. package/dist/src/core_types.js.map +1 -0
  90. package/dist/src/document_factory.d.ts +89 -0
  91. package/dist/src/document_factory.js +176 -0
  92. package/dist/src/document_factory.js.map +1 -0
  93. package/dist/src/genome_schema.d.ts +512 -0
  94. package/dist/src/genome_schema.js +168 -0
  95. package/dist/src/genome_schema.js.map +1 -0
  96. package/dist/src/genome_writer.d.ts +67 -0
  97. package/dist/src/genome_writer.js +179 -0
  98. package/dist/src/genome_writer.js.map +1 -0
  99. package/dist/src/gig_song.d.ts +29 -0
  100. package/dist/src/gig_song.js +56 -0
  101. package/dist/src/gig_song.js.map +1 -0
  102. package/dist/src/gig_tracker.d.ts +54 -0
  103. package/dist/src/gig_tracker.js +109 -0
  104. package/dist/src/gig_tracker.js.map +1 -0
  105. package/dist/src/harmonic_validation.d.ts +11 -0
  106. package/dist/src/harmonic_validation.js +35 -0
  107. package/dist/src/harmonic_validation.js.map +1 -0
  108. package/dist/src/hooks.d.ts +27 -0
  109. package/dist/src/hooks.js +2 -0
  110. package/dist/src/hooks.js.map +1 -0
  111. package/dist/src/index.d.ts +36 -0
  112. package/dist/src/index.js +37 -0
  113. package/dist/src/index.js.map +1 -0
  114. package/dist/src/jsong.d.ts +47 -0
  115. package/dist/src/jsong.js +130 -0
  116. package/dist/src/jsong.js.map +1 -0
  117. package/dist/src/judges/user_flow_judge.d.ts +89 -0
  118. package/dist/src/judges/user_flow_judge.js +200 -0
  119. package/dist/src/judges/user_flow_judge.js.map +1 -0
  120. package/dist/src/learner.d.ts +37 -0
  121. package/dist/src/learner.js +30 -0
  122. package/dist/src/learner.js.map +1 -0
  123. package/dist/src/ledger.d.ts +225 -0
  124. package/dist/src/ledger.js +306 -0
  125. package/dist/src/ledger.js.map +1 -0
  126. package/dist/src/loader.d.ts +87 -0
  127. package/dist/src/loader.js +504 -0
  128. package/dist/src/loader.js.map +1 -0
  129. package/dist/src/mcp.d.ts +23 -0
  130. package/dist/src/mcp.js +125 -0
  131. package/dist/src/mcp.js.map +1 -0
  132. package/dist/src/modulation_path.d.ts +42 -0
  133. package/dist/src/modulation_path.js +60 -0
  134. package/dist/src/modulation_path.js.map +1 -0
  135. package/dist/src/output_validation.d.ts +19 -0
  136. package/dist/src/output_validation.js +51 -0
  137. package/dist/src/output_validation.js.map +1 -0
  138. package/dist/src/outputs.d.ts +125 -0
  139. package/dist/src/outputs.js +452 -0
  140. package/dist/src/outputs.js.map +1 -0
  141. package/dist/src/overtones.d.ts +42 -0
  142. package/dist/src/overtones.js +98 -0
  143. package/dist/src/overtones.js.map +1 -0
  144. package/dist/src/player_to_claude_code.d.ts +17 -0
  145. package/dist/src/player_to_claude_code.js +141 -0
  146. package/dist/src/player_to_claude_code.js.map +1 -0
  147. package/dist/src/playwright_cage.d.ts +28 -0
  148. package/dist/src/playwright_cage.js +47 -0
  149. package/dist/src/playwright_cage.js.map +1 -0
  150. package/dist/src/polyphony.d.ts +46 -0
  151. package/dist/src/polyphony.js +91 -0
  152. package/dist/src/polyphony.js.map +1 -0
  153. package/dist/src/portfolio.d.ts +52 -0
  154. package/dist/src/portfolio.js +186 -0
  155. package/dist/src/portfolio.js.map +1 -0
  156. package/dist/src/pricing.d.ts +23 -0
  157. package/dist/src/pricing.js +16 -0
  158. package/dist/src/pricing.js.map +1 -0
  159. package/dist/src/registry.d.ts +46 -0
  160. package/dist/src/registry.js +199 -0
  161. package/dist/src/registry.js.map +1 -0
  162. package/dist/src/runtime.d.ts +304 -0
  163. package/dist/src/runtime.js +1099 -0
  164. package/dist/src/runtime.js.map +1 -0
  165. package/dist/src/server.d.ts +88 -0
  166. package/dist/src/server.js +1692 -0
  167. package/dist/src/server.js.map +1 -0
  168. package/dist/src/server_entry.d.ts +2 -0
  169. package/dist/src/server_entry.js +40 -0
  170. package/dist/src/server_entry.js.map +1 -0
  171. package/dist/src/server_relay.d.ts +82 -0
  172. package/dist/src/server_relay.js +341 -0
  173. package/dist/src/server_relay.js.map +1 -0
  174. package/dist/src/simulate.d.ts +60 -0
  175. package/dist/src/simulate.js +72 -0
  176. package/dist/src/simulate.js.map +1 -0
  177. package/dist/src/skill_runner.mjs +34 -0
  178. package/dist/src/skill_subprocess.d.ts +65 -0
  179. package/dist/src/skill_subprocess.js +132 -0
  180. package/dist/src/skill_subprocess.js.map +1 -0
  181. package/dist/src/skills.d.ts +85 -0
  182. package/dist/src/skills.js +258 -0
  183. package/dist/src/skills.js.map +1 -0
  184. package/dist/src/subthread_recorder.d.ts +68 -0
  185. package/dist/src/subthread_recorder.js +166 -0
  186. package/dist/src/subthread_recorder.js.map +1 -0
  187. package/dist/src/tensor_read.d.ts +38 -0
  188. package/dist/src/tensor_read.js +60 -0
  189. package/dist/src/tensor_read.js.map +1 -0
  190. package/dist/src/test_honest_broker.d.ts +34 -0
  191. package/dist/src/test_honest_broker.js +155 -0
  192. package/dist/src/test_honest_broker.js.map +1 -0
  193. package/dist/src/test_topology.d.ts +22 -0
  194. package/dist/src/test_topology.js +137 -0
  195. package/dist/src/test_topology.js.map +1 -0
  196. package/dist/src/tones.d.ts +20 -0
  197. package/dist/src/tones.js +81 -0
  198. package/dist/src/tones.js.map +1 -0
  199. package/dist/src/tool_providers.d.ts +45 -0
  200. package/dist/src/tool_providers.js +104 -0
  201. package/dist/src/tool_providers.js.map +1 -0
  202. package/dist/src/type_versioning.d.ts +23 -0
  203. package/dist/src/type_versioning.js +31 -0
  204. package/dist/src/type_versioning.js.map +1 -0
  205. package/dist/src/version.d.ts +28 -0
  206. package/dist/src/version.js +86 -0
  207. package/dist/src/version.js.map +1 -0
  208. package/domain_types/claim-draft.json +34 -0
  209. package/domain_types/coverage-report.json +31 -0
  210. package/domain_types/draft-agent-profile.json +31 -0
  211. package/domain_types/draft-domain-type.json +28 -0
  212. package/domain_types/draft-standard.json +46 -0
  213. package/domain_types/e2e-observation.json +32 -0
  214. package/domain_types/e2e-report.json +30 -0
  215. package/domain_types/e2e-target.json +26 -0
  216. package/domain_types/e2e-verdict.json +26 -0
  217. package/domain_types/examine-round-record.json +40 -0
  218. package/domain_types/examiner-rejection.json +28 -0
  219. package/domain_types/failure-modes.json +31 -0
  220. package/domain_types/invention-analysis.json +34 -0
  221. package/domain_types/invention-spec.json +34 -0
  222. package/domain_types/novelty-analysis.json +28 -0
  223. package/domain_types/novelty-verdict.json +35 -0
  224. package/domain_types/parsed-conversation-trace.json +38 -0
  225. package/domain_types/pattern-extraction.json +62 -0
  226. package/domain_types/prior-art-hit.json +50 -0
  227. package/domain_types/project-charter.json +71 -0
  228. package/domain_types/provisional-draft.json +34 -0
  229. package/domain_types/raw-note.json +19 -0
  230. package/domain_types/repo-survey.json +28 -0
  231. package/domain_types/seeding-verdict.json +70 -0
  232. package/domain_types/soft-verdict.json +55 -0
  233. package/domain_types/summary.json +19 -0
  234. package/domain_types/triage-verdict.json +59 -0
  235. package/domain_types/user-flow-transcript.json +43 -0
  236. package/domain_types/user-flow-verdict.json +60 -0
  237. package/domain_types/verdict-record.json +39 -0
  238. package/package.json +82 -0
  239. package/skills/citation-verify/fixtures/basic.json +14 -0
  240. package/skills/citation-verify/meta.json +10 -0
  241. package/skills/citation-verify/skill.mjs +26 -0
  242. package/skills/claim-element-decompose/fixtures/basic.json +11 -0
  243. package/skills/claim-element-decompose/meta.json +10 -0
  244. package/skills/claim-element-decompose/skill.mjs +14 -0
  245. package/skills/diamond-cutting-discipline/fixtures/basic.json +13 -0
  246. package/skills/diamond-cutting-discipline/meta.json +19 -0
  247. package/skills/diamond-cutting-discipline/skill.md +46 -0
  248. package/skills/element-mapping-matrix/fixtures/basic.json +13 -0
  249. package/skills/element-mapping-matrix/meta.json +10 -0
  250. package/skills/element-mapping-matrix/skill.mjs +20 -0
  251. package/skills/number-adder/fixtures/basic.json +9 -0
  252. package/skills/number-adder/meta.json +10 -0
  253. package/skills/number-adder/skill.mjs +12 -0
  254. package/skills/patent-fetch/fixtures/parse.json +18 -0
  255. package/skills/patent-fetch/meta.json +11 -0
  256. package/skills/patent-fetch/skill.mjs +34 -0
  257. package/skills/query-expand/fixtures/basic.json +14 -0
  258. package/skills/query-expand/meta.json +10 -0
  259. package/skills/query-expand/skill.mjs +29 -0
  260. package/skills/run-vitest-band/fixtures/basic.json +9 -0
  261. package/skills/run-vitest-band/meta.json +18 -0
  262. package/skills/run-vitest-band/skill.mjs +22 -0
  263. package/skills/statutory-checklist/fixtures/basic.json +16 -0
  264. package/skills/statutory-checklist/meta.json +10 -0
  265. package/skills/statutory-checklist/skill.mjs +25 -0
  266. package/skills/summarize-tight/fixtures/basic.json +13 -0
  267. package/skills/summarize-tight/meta.json +20 -0
  268. package/skills/summarize-tight/skill.md +1 -0
  269. package/skills/verdict-gate/fixtures/basic.json +9 -0
  270. package/skills/verdict-gate/meta.json +10 -0
  271. package/skills/verdict-gate/skill.mjs +82 -0
  272. package/standards/e2e-suite-v0.json +44 -0
  273. package/standards/patent-triage-v0.json +98 -0
  274. package/standards/patent-triage-v1.json +84 -0
  275. package/standards/seed-from-local-repos-v0.json +115 -0
  276. package/standards/sub_thread_invocation.json +50 -0
  277. package/standards/summarize.json +40 -0
  278. package/standards/synthesis-walk-v0.json +108 -0
  279. package/standards/user_flow_correctness.json +57 -0
@@ -0,0 +1,16 @@
1
+ export const DEPTH_MULTIPLIER = { skim: 0.5, quick: 0.75, standard: 1.0, deep: 2.0 };
2
+ export const MODEL_MULTIPLIER = { economy: 0.5, standard: 1.0, premium: 2.0 };
3
+ // The admissible depth values, derived from the multiplier table so the two cannot drift.
4
+ // #237 — `depth` was advertised on gig_dispatch and silently discarded; a dispatch-time depth
5
+ // now has to BE one of these or the call fails loudly, because "silently ran at full depth"
6
+ // is exactly the failure the parameter existed to prevent.
7
+ export const DEPTHS = Object.keys(DEPTH_MULTIPLIER);
8
+ export function isDepth(v) {
9
+ return typeof v === "string" && DEPTHS.includes(v);
10
+ }
11
+ export function computeCredits(input) {
12
+ return (input.base_cost * DEPTH_MULTIPLIER[input.depth] * MODEL_MULTIPLIER[input.model_tier] +
13
+ input.agents * 0.5 +
14
+ input.external_tool_calls * 0.1);
15
+ }
16
+ //# sourceMappingURL=pricing.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pricing.js","sourceRoot":"","sources":["../../src/pricing.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,gBAAgB,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAW,CAAC;AAC9F,MAAM,CAAC,MAAM,gBAAgB,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAW,CAAC;AAKvF,0FAA0F;AAC1F,8FAA8F;AAC9F,4FAA4F;AAC5F,2DAA2D;AAC3D,MAAM,CAAC,MAAM,MAAM,GAAqB,MAAM,CAAC,IAAI,CAAC,gBAAgB,CAAY,CAAC;AACjF,MAAM,UAAU,OAAO,CAAC,CAAU;IAChC,OAAO,OAAO,CAAC,KAAK,QAAQ,IAAK,MAA4B,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;AAC5E,CAAC;AAUD,MAAM,UAAU,cAAc,CAAC,KAAkB;IAC/C,OAAO,CACL,KAAK,CAAC,SAAS,GAAG,gBAAgB,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,gBAAgB,CAAC,KAAK,CAAC,UAAU,CAAC;QACpF,KAAK,CAAC,MAAM,GAAG,GAAG;QAClB,KAAK,CAAC,mBAAmB,GAAG,GAAG,CAChC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,46 @@
1
+ import { type DomainTypeOutput } from "./genome_schema.js";
2
+ import type { LoadedGenome } from "./loader.js";
3
+ export declare const RESOLVE_WEIGHTS: {
4
+ readonly field_coverage: 0.4;
5
+ readonly usage_gravity: 0.15;
6
+ readonly downstream_satisfaction: 0.2;
7
+ readonly domain_affinity: 0.15;
8
+ readonly recency: 0.1;
9
+ };
10
+ export type DomainType = Pick<DomainTypeOutput, "slug" | "extends" | "domain" | "schema" | "required_fields">;
11
+ export interface ResolveQuery {
12
+ extends: string;
13
+ domain: string;
14
+ required_fields: string[];
15
+ }
16
+ export interface ResolveResult {
17
+ score: number;
18
+ action: "use" | "extend" | "create";
19
+ candidates: DomainType[];
20
+ }
21
+ export interface OutputToValidate {
22
+ core_type: string;
23
+ domain_type: string;
24
+ input_refs?: string[];
25
+ data: Record<string, unknown>;
26
+ }
27
+ export interface RegistryValidationResult {
28
+ valid: boolean;
29
+ errors: string[];
30
+ }
31
+ export interface Registry {
32
+ registerType(def: DomainType): {
33
+ registered: true;
34
+ version: number;
35
+ };
36
+ resolveType(query: ResolveQuery): ResolveResult;
37
+ validate(output: OutputToValidate): RegistryValidationResult;
38
+ listTypes(): DomainType[];
39
+ replaceTypes(defs: readonly DomainType[]): {
40
+ added: string[];
41
+ modified: string[];
42
+ removed: string[];
43
+ };
44
+ }
45
+ export declare function createRegistry(initial?: DomainType[]): Registry;
46
+ export declare function loadRegistry(genome: LoadedGenome): Registry;
@@ -0,0 +1,199 @@
1
+ import Ajv from "ajv";
2
+ import { CORE_TYPES } from "./core_types.js";
3
+ import { CANONICAL_CORE_TYPES } from "./canonical_core_types.js";
4
+ // Base-type property inheritance (docs/genome-extension.md). A domain type extending
5
+ // a core type inherits the core's schema PROPERTIES — the base fields are "around at
6
+ // runtime" because the core is always loaded — so a subtype instance may carry them.
7
+ // The subtype OVERLOADS (same-named field wins) and EXTENDS (adds new fields). The 6
8
+ // cores are immutable, so we read their properties straight from the canonical set.
9
+ const CORE_SCHEMA_PROPS = Object.fromEntries(CANONICAL_CORE_TYPES.map((c) => [
10
+ c.slug,
11
+ (c.schema.properties ?? {}),
12
+ ]));
13
+ export const RESOLVE_WEIGHTS = {
14
+ field_coverage: 0.4,
15
+ usage_gravity: 0.15,
16
+ downstream_satisfaction: 0.2,
17
+ domain_affinity: 0.15,
18
+ recency: 0.1,
19
+ };
20
+ function isCoreType(slug) {
21
+ return CORE_TYPES.includes(slug);
22
+ }
23
+ export function createRegistry(initial = []) {
24
+ const ajv = new Ajv({ allErrors: true, strict: false });
25
+ const types = new Map();
26
+ for (const def of initial)
27
+ types.set(def.slug, def);
28
+ function score(query) {
29
+ const candidates = [...types.values()].filter((t) => t.extends === query.extends);
30
+ if (candidates.length === 0)
31
+ return { score: 0, action: "create", candidates: [] };
32
+ let best = 0;
33
+ for (const c of candidates) {
34
+ const covered = query.required_fields.filter((f) => c.required_fields.includes(f)).length;
35
+ const coverage = query.required_fields.length === 0 ? 1 : covered / query.required_fields.length;
36
+ const affinity = c.domain === query.domain ? 1 : 0;
37
+ // usage_gravity, downstream_satisfaction, recency default to 1 until usage stats exist
38
+ const s = 100 *
39
+ (RESOLVE_WEIGHTS.field_coverage * coverage +
40
+ RESOLVE_WEIGHTS.usage_gravity * 1 +
41
+ RESOLVE_WEIGHTS.downstream_satisfaction * 1 +
42
+ RESOLVE_WEIGHTS.domain_affinity * affinity +
43
+ RESOLVE_WEIGHTS.recency * 1);
44
+ if (s > best)
45
+ best = s;
46
+ }
47
+ const action = best >= 80 ? "use" : best >= 50 ? "extend" : "create";
48
+ return { score: best, action, candidates };
49
+ }
50
+ return {
51
+ registerType(def) {
52
+ if (!isCoreType(def.extends)) {
53
+ throw new Error(`extends must be a core type, got "${def.extends}"`);
54
+ }
55
+ const resolved = score({ extends: def.extends, domain: def.domain, required_fields: def.required_fields });
56
+ if (resolved.score >= 80) {
57
+ throw new Error(`reuse enforcement: an existing type scores ${resolved.score} (>=80)`);
58
+ }
59
+ types.set(def.slug, def);
60
+ return { registered: true, version: 1 };
61
+ },
62
+ resolveType(query) {
63
+ return score(query);
64
+ },
65
+ replaceTypes(defs) {
66
+ const before = new Map(types);
67
+ const added = [];
68
+ const modified = [];
69
+ const removed = [];
70
+ types.clear();
71
+ for (const def of defs) {
72
+ if (!isCoreType(def.extends))
73
+ continue; // soft-skip; mirrors loader's stance
74
+ types.set(def.slug, def);
75
+ const prior = before.get(def.slug);
76
+ if (!prior)
77
+ added.push(def.slug);
78
+ else if (JSON.stringify(prior) !== JSON.stringify(def))
79
+ modified.push(def.slug);
80
+ }
81
+ for (const slug of before.keys()) {
82
+ if (!types.has(slug))
83
+ removed.push(slug);
84
+ }
85
+ return { added, modified, removed };
86
+ },
87
+ validate(output) {
88
+ // Rob #133 — domain_type is OPTIONAL. Empty / missing means the output
89
+ // is freeform vs. its core type (Interpretation, Plan, Artifact, …) but
90
+ // doesn't conform to any registered domain schema. Examples that need
91
+ // this: a discover-phase domain-model document, an analytical plan that
92
+ // doesn't fit a typed plan-shape yet. The core_type discipline still
93
+ // holds; only the domain-schema strictness is bypassed.
94
+ if (!output.domain_type)
95
+ return { valid: true, errors: [] };
96
+ // A bare CORE type as the domain_type is a freeform output of that core (e.g. a
97
+ // skill-backed chair that produces a plain Signal, no domain subtype). The core_type
98
+ // discipline still holds; there's just no domain schema to enforce — same as above.
99
+ // "Still holds" is now a fact rather than a claim: outputs.write runs validateOutput
100
+ // on every seal, so a bare core meets the same substance floor as its subtypes (#227).
101
+ if (isCoreType(output.domain_type))
102
+ return { valid: true, errors: [] };
103
+ const dt = types.get(output.domain_type);
104
+ if (!dt)
105
+ return { valid: false, errors: [`unknown domain_type "${output.domain_type}"`] };
106
+ // Inherit the base core type's properties, then let the subtype overload + extend.
107
+ //
108
+ // MAINTAINER RULING (#227) — "There's no subtype thing. It's all the way top to
109
+ // bottom." This REPLACES the stance that used to be documented here: that a core's
110
+ // base fields are "available, not forced" on a subtype, so `required` stays the
111
+ // subtype's own and existing instances that carry no base field still validate.
112
+ //
113
+ // That stance is wrong. Every core carries ONE substance floor — the declared field
114
+ // that makes its output answerable to someone else (Signal.source, Interpretation.claims,
115
+ // Plan.steps, Judgment.criteria, Artifact.validation_criteria, Verdict.checks) — and
116
+ // that floor is FORCED on every sealed output of that core, bare core or domain
117
+ // subtype alike. See src/output_validation.ts for the table and the per-core reasoning.
118
+ //
119
+ // The forcing lives at the seal boundary (outputs.write → validateOutput), not here,
120
+ // for a reason: it must hold on the paths this function deliberately does not reach —
121
+ // an absent domain_type (line 140), a bare core type as the domain_type (line 144),
122
+ // and a subtype that overloads an inherited floor away (#230). Enforcing it here as
123
+ // well would leave those three holes open. What this function still owns is the
124
+ // subtype's OWN declared contract; `required` below stays the subtype's own because
125
+ // the core's floor is already enforced unconditionally one layer out — not because
126
+ // base fields are optional.
127
+ const baseProps = CORE_SCHEMA_PROPS[dt.extends] ?? {};
128
+ const ownProps = dt.schema.properties ?? {};
129
+ // #200 — honor the type's declared additionalProperties. Closed-by-default
130
+ // stays the discipline (undeclared → false), but a type that opts into open
131
+ // extension with `additionalProperties: true` accepts agent-added contextual
132
+ // fields at seal instead of aborting the terminal chair.
133
+ const additionalProperties = dt.schema.additionalProperties ?? false;
134
+ // #229 — a type's required fields may be declared in EITHER place, and both are
135
+ // honored. Two authoring conventions exist in the genome and nothing reconciles
136
+ // them: most types populate `required_fields` and leave `schema.required` empty;
137
+ // the hand-authored seeding/bootstrap types do the reverse. Reading only
138
+ // `required_fields` (as this did) silently discarded the declaration of every type
139
+ // in the second group, so `{}` sealed as a well-formed instance of a type declaring
140
+ // 3-6 required fields.
141
+ //
142
+ // UNION, not precedence. `type_extend` (src/server.ts:609) resolves the same
143
+ // ambiguity as `schema.required ?? required_fields`, but precedence is the wrong
144
+ // rule at seal time: it makes one declaration silently void the other. No type in
145
+ // the genome populates both today, so the two rules are indistinguishable on
146
+ // current data — which is exactly why the safer rule should be the one that gets
147
+ // frozen in. Everything an author wrote down is enforced.
148
+ const declaredRequired = [
149
+ ...new Set([
150
+ ...((dt.schema.required) ?? []),
151
+ ...dt.required_fields,
152
+ ]),
153
+ ];
154
+ const schema = {
155
+ type: "object",
156
+ properties: { ...baseProps, ...ownProps },
157
+ required: declaredRequired,
158
+ additionalProperties,
159
+ };
160
+ const validateFn = ajv.compile(schema);
161
+ const ok = validateFn(output.data);
162
+ // Preserve instancePath + keyword in the error projection so operators see
163
+ // the failing field path, not just a type-class message. For property-level
164
+ // failures Ajv puts the field in `params.missingProperty` (required) or
165
+ // in `instancePath` (type mismatch) or `params.additionalProperty` (extras).
166
+ return {
167
+ valid: ok === true,
168
+ errors: (validateFn.errors ?? []).map((e) => {
169
+ const path = e.instancePath ?? "";
170
+ const keyword = e.keyword ?? "";
171
+ const message = e.message ?? "invalid";
172
+ const params = e.params ?? {};
173
+ const missing = typeof params["missingProperty"] === "string"
174
+ ? ` '${params["missingProperty"]}'`
175
+ : "";
176
+ const additional = typeof params["additionalProperty"] === "string"
177
+ ? ` '${params["additionalProperty"]}'`
178
+ : "";
179
+ const fieldHint = path ? ` at ${path}` : "";
180
+ return `${keyword}${fieldHint}: ${message}${missing}${additional}`.trim();
181
+ }),
182
+ };
183
+ },
184
+ listTypes() {
185
+ return [...types.values()];
186
+ },
187
+ };
188
+ }
189
+ export function loadRegistry(genome) {
190
+ const defs = [...genome.domain_types.values()].map((d) => ({
191
+ slug: d.slug,
192
+ extends: d.extends,
193
+ domain: d.domain,
194
+ schema: d.schema,
195
+ required_fields: [...d.required_fields],
196
+ }));
197
+ return createRegistry(defs);
198
+ }
199
+ //# sourceMappingURL=registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/registry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,304 @@
1
+ import type { Standard, Agent, Chair } from "./composition.js";
2
+ import type { OutputStore, OutputRecord } from "./outputs.js";
3
+ import { type Ledger, type GigUsage } from "./ledger.js";
4
+ import type { Depth } from "./pricing.js";
5
+ import type { SkillRecord, EvalRecord } from "./loader.js";
6
+ export interface AgentInvocationContext {
7
+ agent: Agent;
8
+ phase: string;
9
+ inputs: readonly OutputRecord[];
10
+ gig_input: Record<string, unknown>;
11
+ output_types?: readonly string[];
12
+ skills?: readonly SkillRecord[];
13
+ missing_skills?: readonly string[];
14
+ onEvent?: (ev: AgentStreamEvent) => void;
15
+ signal?: AbortSignal | undefined;
16
+ depth?: Depth | undefined;
17
+ }
18
+ export interface AgentStreamEvent {
19
+ type: string;
20
+ tool?: string | undefined;
21
+ text?: string | undefined;
22
+ raw?: unknown;
23
+ }
24
+ export type GigProgressEvent = {
25
+ type: "phase_start";
26
+ phase: string;
27
+ roles: string[];
28
+ } | {
29
+ type: "chair_start";
30
+ phase: string;
31
+ role: string;
32
+ producer: string;
33
+ } | {
34
+ type: "chair_complete";
35
+ phase: string;
36
+ role: string;
37
+ producer: string;
38
+ /** types actually SEALED */
39
+ output_types: string[];
40
+ duration_ms: number;
41
+ /** #243 — types the chair's output_contract PROMISED. Equal to output_types when the
42
+ * chair delivered everything; the difference is what `missing_output_types` names. */
43
+ promised_output_types?: string[];
44
+ /** #243 — promised but not sealed. Legal (conditional outputs) but never silent. */
45
+ missing_output_types?: string[];
46
+ /** #240 — `*_sha` fields the engine could not tie to any consumed input or the gig
47
+ * payload. Sealed as "" rather than guessed; listed here so the gap is visible. */
48
+ unresolved_sha_fields?: string[];
49
+ } | {
50
+ type: "chair_failed";
51
+ phase: string;
52
+ role: string;
53
+ error: string;
54
+ } | {
55
+ type: "skills_unresolved";
56
+ phase: string;
57
+ role: string;
58
+ agent: string;
59
+ missing: string[];
60
+ } | {
61
+ type: "agent_event";
62
+ phase: string;
63
+ role: string;
64
+ event: AgentStreamEvent;
65
+ } | {
66
+ type: "gig_complete";
67
+ outputs: number;
68
+ } | {
69
+ type: "gig_failed";
70
+ error: string;
71
+ } | {
72
+ type: "gig_aborted";
73
+ reason: string;
74
+ };
75
+ export type AgentInvoker = (ctx: AgentInvocationContext) => Record<string, unknown> | Promise<Record<string, unknown>>;
76
+ export interface ChairSelectionView {
77
+ phase: string;
78
+ ready: readonly Chair[];
79
+ produced: readonly OutputRecord[];
80
+ budget: Readonly<BudgetState> | null;
81
+ standard: Standard;
82
+ }
83
+ export type ChairSelector = (view: ChairSelectionView) => readonly Chair[] | Promise<readonly Chair[]>;
84
+ export interface RunDeps {
85
+ outputs: OutputStore;
86
+ ledger: Ledger;
87
+ invoke: AgentInvoker;
88
+ model_version?: string | undefined;
89
+ skills?: ReadonlyMap<string, SkillRecord> | undefined;
90
+ skill_dirs?: ReadonlyMap<string, string> | undefined;
91
+ evals?: ReadonlyMap<string, EvalRecord> | undefined;
92
+ /**
93
+ * Optional cost-budget input. When omitted (default), no budget enforcement
94
+ * runs — preserving v0 back-compat. When present, the runtime tracks
95
+ * per-gig BudgetState matching budget-state.json schema: balance =
96
+ * opening - spent + credit.
97
+ *
98
+ * The cycle is RESERVE → SETTLE (#232). At chair-prep the runtime computes
99
+ * cost-of-append (base + k*size(input)) and compares it against
100
+ * `balance - reserved`; short → BudgetExhausted. Passing chairs RESERVE the
101
+ * cost. `spent` moves only when a chair's invocation SUCCEEDS, which is what
102
+ * the contract always claimed and what the code did not do: prep runs
103
+ * eagerly for the whole ready batch, so a batch member tripping the gate
104
+ * used to leave every earlier member of that batch charged for work no
105
+ * invoker ever started.
106
+ *
107
+ * The final BudgetState is returned in GigResult.budget_state, and is also
108
+ * attached to a BudgetExhausted / mid-gig error so a FAILED gig can still
109
+ * report what it cost.
110
+ */
111
+ budget?: BudgetInput | undefined;
112
+ onProgress?: ((ev: GigProgressEvent) => void) | undefined;
113
+ gig_id?: string | undefined;
114
+ selectChairs?: ChairSelector | undefined;
115
+ /**
116
+ * #249/#250 — the cancellation seam. Abort it and the run stops at its next checkpoint
117
+ * (between phases and between dispatch batches) and rejects with `GigAborted`. The same
118
+ * signal is threaded into every AgentInvocationContext, so an invoker that wires it to its
119
+ * subprocess also stops the in-flight chair. Absent = an uncancellable run (the v0 shape).
120
+ *
121
+ * Known bound: a SKILL-backed chair runs `spawnSync` (src/skill_subprocess.ts), which
122
+ * blocks the event loop, so an abort delivered while one is executing is not even RECEIVED
123
+ * until it returns. Skill chairs are therefore a hard uncancellable window of up to their
124
+ * declared `meta.timeout_ms` (default 120s). Deliberate for now — see #253.
125
+ */
126
+ signal?: AbortSignal | undefined;
127
+ /**
128
+ * #237 — the depth this gig was dispatched at, threaded to every invocation so it reaches
129
+ * the thing that actually spends. Absent = each agent's own `depth_profile` stands.
130
+ */
131
+ depth?: Depth | undefined;
132
+ }
133
+ /**
134
+ * Per-gig cost-budget input. Honors budget-state.json schema (PR #56). Only
135
+ * `opening` is required for v0 enforcement; the rest are recomputed.
136
+ *
137
+ * COST FORMULA (v0, tunable):
138
+ * cost = base_cost + k * size_bytes(input)
139
+ * defaults: base_cost = 1, k = 0.1
140
+ *
141
+ * Where size_bytes(input) = JSON.stringify(canonical context).length.
142
+ *
143
+ * WHAT THIS IS AND IS NOT (#233). `opening`/`spent`/`balance` are SYNTHETIC APPEND UNITS —
144
+ * see `BudgetState.unit`. They are not dollars and were never converted to dollars; an
145
+ * `opening: 1000` that reads like a dollar figure to an operator is a coincidence of scale.
146
+ * The real, settled figure is `BudgetState.settled_usd`, reconciled from the model's own
147
+ * `result` events at each batch boundary. Two honest limits on the synthetic gate:
148
+ *
149
+ * 1. It is a proxy for prompt size, not a price. It has no model tier, no output side, no
150
+ * skills/charter/schema bytes — only the agent slug, phase, consumed input CONTENT and
151
+ * the gig payload. It is a rate limiter on context growth, nothing more.
152
+ * 2. A USD figure cannot gate a chair before that chair runs, because `prepareChair` runs
153
+ * for the WHOLE ready batch before any invocation — a chair cannot see its batch
154
+ * siblings' settled cost. So reconciliation happens at BATCH BOUNDARIES, and any dollar
155
+ * bound built on it would be a cap plus one batch of slack, never a hard stop. No such
156
+ * bound is wired: there is no per-chair dollar estimator, and inventing one would be
157
+ * guessing. `settled_usd` reports; it does not enforce.
158
+ */
159
+ export interface BudgetInput {
160
+ opening: number;
161
+ /** base cost per agent invocation, in append units. Default 1. */
162
+ base_cost?: number;
163
+ /** per-byte multiplier on consumed-input size, in append units. Default 0.1. */
164
+ k?: number;
165
+ }
166
+ /**
167
+ * Per-gig budget snapshot. Mirrors fields of domain_types/budget-state.json
168
+ * (PR #56) that are runtime-tractable in v0. balance = opening - spent + credit.
169
+ *
170
+ * The `agent_state` mirrors the budget-state.json enum:
171
+ * active — currently spending, balance > cost-of-next-append
172
+ * yielding — below cost-of-next-append, paused (used when partial)
173
+ * depleted — balance <= 0 OR < cost-of-next-append, hard stop
174
+ * awaiting_grade — work shipped, external grader contacted (v0 unused)
175
+ * settled — cycle closed, closing populated (v0 set on success)
176
+ */
177
+ export interface BudgetState {
178
+ opening: number;
179
+ /** Cost of chairs that ACTUALLY RAN AND SUCCEEDED. Reserved-but-unsettled cost is not here. */
180
+ spent: number;
181
+ credit: number;
182
+ balance: number;
183
+ agent_state: "active" | "yielding" | "depleted" | "awaiting_grade" | "settled";
184
+ /** Slug of the agent whose invocation tripped depletion. null when solvent. */
185
+ depleted_agent: string | null;
186
+ /** Wall-clock when balance first crossed below cost-of-next-append. null while solvent. */
187
+ depleted_at: string | null;
188
+ base_cost: number;
189
+ k: number;
190
+ /**
191
+ * #233 — the denomination of opening/spent/balance/base_cost/k, stated rather than assumed.
192
+ * These are a synthetic proxy for consumed context bytes. They are NOT dollars, and nothing
193
+ * converts between the two. Read `settled_usd` for money.
194
+ */
195
+ unit: "append-units";
196
+ /**
197
+ * #233 — REAL settled model spend for this gig so far, in USD, reconciled from the invokers'
198
+ * own `result` events at each dispatch-batch boundary. This is the number `src/ledger.ts`
199
+ * calls settled spend; the budget gate above never used it, even though it was live and
200
+ * in-scope. Reporting only — see the BudgetInput docstring for why it cannot gate.
201
+ * 0 when no invoker reported cost (stubbed invokers, skill-only gigs).
202
+ */
203
+ settled_usd: number;
204
+ }
205
+ export interface GigResult {
206
+ gig_id: string;
207
+ standard_slug: string;
208
+ genome_hash: string;
209
+ run_fingerprint: string;
210
+ outputs: readonly OutputRecord[];
211
+ eval_scores: Record<string, number>;
212
+ /**
213
+ * #246 — declared eval_slugs that resolved to NO eval definition. They still appear in
214
+ * `eval_scores` at 0.0 (back-compat: callers key off presence), but a 0.0 that means
215
+ * "no such eval" is not the same claim as a 0.0 that means "the contract did not hold",
216
+ * and the two used to be indistinguishable — including inside `run_fingerprint`.
217
+ * Present only when non-empty.
218
+ */
219
+ unresolved_evals?: readonly string[];
220
+ /**
221
+ * #243 — chairs that sealed FEWER types than their output_contract promised. The runtime
222
+ * treats output_contract as a selector, not a floor, because a keyed output can legitimately
223
+ * be conditional. For a chair with a downstream consumer the shortfall surfaces as an
224
+ * input_contract failure; for a TERMINAL chair nothing consumes it and the promise used to
225
+ * evaporate into `status: "complete"`. Recording it is not enforcement — see the note at the
226
+ * seal loop. Present only when non-empty.
227
+ */
228
+ unfulfilled_outputs?: ReadonlyArray<{
229
+ role: string;
230
+ phase: string;
231
+ missing: readonly string[];
232
+ }>;
233
+ status: "complete";
234
+ /** Final budget snapshot. Present only when a budget was supplied. */
235
+ budget_state?: BudgetState;
236
+ /** Settled model spend (#195). Present when ≥1 real model invocation ran this gig. */
237
+ usage?: GigUsage;
238
+ }
239
+ /**
240
+ * #236 — settled spend used to be discarded on every failed gig: `usage` was written only on
241
+ * the success path, and the async dispatcher's `.catch` set status/error and nothing else. A
242
+ * gig that burned $6 across four chairs and died on the fifth reported zero dollars, everywhere
243
+ * — and failed gigs are exactly the ones whose cost an operator most needs. runGig now attaches
244
+ * the partial accounting to whatever it throws; these read it back safely.
245
+ */
246
+ export declare function partialGigUsage(e: unknown): GigUsage | undefined;
247
+ export declare function partialBudgetState(e: unknown): BudgetState | undefined;
248
+ export declare class RuntimeError extends Error {
249
+ }
250
+ /**
251
+ * Raised when a gig is cancelled through `RunDeps.signal` (#249). Distinct from RuntimeError
252
+ * so a caller can tell "an operator stopped this" from "this crashed" — #251's point that a
253
+ * killed gig surfacing as `failed` with a kill-shaped error is indistinguishable from a
254
+ * genuine crash.
255
+ *
256
+ * Carries the spend accrued BEFORE the cancellation. Today abort does nothing, so the gig
257
+ * completes and its cost IS recorded; a fix that kills children without capturing accrued
258
+ * usage would improve cost control while regressing accounting. The dispatcher folds this
259
+ * onto the run state so `gig_monitor` still answers "what did this cost me".
260
+ */
261
+ export declare class GigAborted extends Error {
262
+ readonly gig_id: string;
263
+ readonly reason: string;
264
+ readonly usage: GigUsage | undefined;
265
+ readonly outputs: readonly OutputRecord[];
266
+ constructor(gig_id: string, reason: string, usage: GigUsage | undefined, outputs: readonly OutputRecord[]);
267
+ }
268
+ /** The human-readable cause behind an AbortSignal, whatever shape the aborter used. */
269
+ export declare function abortReasonText(signal: AbortSignal): string;
270
+ /**
271
+ * Raised when a gig's budget cannot cover the next agent's cost-of-append.
272
+ * Carries the agent_slug, the available balance, and the required cost so
273
+ * the caller can render the exact reason. The in-memory BudgetState is
274
+ * also attached for downstream telemetry.
275
+ */
276
+ export declare class BudgetExhausted extends Error {
277
+ readonly agent_slug: string;
278
+ readonly balance: number;
279
+ readonly cost: number;
280
+ readonly state: BudgetState;
281
+ constructor(agent_slug: string, balance: number, cost: number, state: BudgetState);
282
+ }
283
+ /**
284
+ * Cost-of-append for an agent invocation, in synthetic append units (see BudgetState.unit).
285
+ * Deterministic function of the input context size — same input → same cost. Keeps cost
286
+ * calculation inside the runtime (not the invoker) so budget enforcement cannot be spoofed by
287
+ * a misbehaving invoker.
288
+ *
289
+ * #233 — this used to serialize `input_ids`: the UUIDs of the upstream outputs a chair
290
+ * consumes, not their data. An upstream output contributed exactly 36 bytes whether it was a
291
+ * one-line signal or a 40-page draft, so the proxy was not even monotonic in the thing that
292
+ * drives real cost. It now measures the CONTENT the invoker actually receives.
293
+ *
294
+ * Still excluded, honestly: resolved skills, the agent charter, type schemas, model tier,
295
+ * max_tool_calls, and the entire output side. This is a rate limiter on consumed context, not
296
+ * a price. Money is `BudgetState.settled_usd`.
297
+ */
298
+ export declare function computeAppendCost(ctx: {
299
+ agent: Agent;
300
+ phase: string;
301
+ inputs: readonly OutputRecord[];
302
+ gig_input: Record<string, unknown>;
303
+ }, base_cost: number, k: number): number;
304
+ export declare function runGig(standard: Standard, gigInput: Record<string, unknown>, deps: RunDeps): Promise<GigResult>;