@eir-labs/coltrane 0.10.0 → 0.12.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 (144) hide show
  1. package/agents/bandleader.json +54 -0
  2. package/agents/bill.json +4 -2
  3. package/agents/change-verifier.json +2 -1
  4. package/agents/code-implementer.json +7 -4
  5. package/agents/john.json +5 -3
  6. package/agents/lineage-scout-external.json +19 -6
  7. package/agents/lineage-scribe.json +20 -9
  8. package/agents/lineage-weaver.json +26 -11
  9. package/agents/miles.json +2 -1
  10. package/agents/players/bandleader.md +70 -0
  11. package/agents/pr-publisher.json +4 -2
  12. package/agents/red-spec-drafter.json +12 -6
  13. package/agents/room-prober.json +29 -0
  14. package/agents/source-walker.json +1 -1
  15. package/charts/room-probe-chart-v1.json +14 -0
  16. package/charts/worker-contract-docker-v2.json +135 -0
  17. package/charts/worker-contract-v3.json +206 -0
  18. package/dist/src/boundary_check.d.ts +18 -0
  19. package/dist/src/boundary_check.js +70 -0
  20. package/dist/src/boundary_check.js.map +1 -0
  21. package/dist/src/boundary_scan.d.ts +62 -0
  22. package/dist/src/boundary_scan.js +93 -0
  23. package/dist/src/boundary_scan.js.map +1 -0
  24. package/dist/src/chart.js +34 -1
  25. package/dist/src/chart.js.map +1 -1
  26. package/dist/src/claude_invoker.d.ts +2 -13
  27. package/dist/src/claude_invoker.js +242 -18
  28. package/dist/src/claude_invoker.js.map +1 -1
  29. package/dist/src/cli.d.ts +1 -1
  30. package/dist/src/cli.js +115 -27
  31. package/dist/src/cli.js.map +1 -1
  32. package/dist/src/drain_preflight.d.ts +33 -0
  33. package/dist/src/drain_preflight.js +97 -0
  34. package/dist/src/drain_preflight.js.map +1 -0
  35. package/dist/src/genome_schema.d.ts +390 -9
  36. package/dist/src/genome_schema.js +163 -8
  37. package/dist/src/genome_schema.js.map +1 -1
  38. package/dist/src/genome_store.js +9 -0
  39. package/dist/src/genome_store.js.map +1 -1
  40. package/dist/src/genome_writer.d.ts +1 -1
  41. package/dist/src/genome_writer.js +10 -2
  42. package/dist/src/genome_writer.js.map +1 -1
  43. package/dist/src/gig_conformance.d.ts +66 -0
  44. package/dist/src/gig_conformance.js +153 -0
  45. package/dist/src/gig_conformance.js.map +1 -0
  46. package/dist/src/gig_tracker.js +8 -0
  47. package/dist/src/gig_tracker.js.map +1 -1
  48. package/dist/src/grounding.d.ts +44 -0
  49. package/dist/src/grounding.js +127 -0
  50. package/dist/src/grounding.js.map +1 -0
  51. package/dist/src/index.d.ts +3 -0
  52. package/dist/src/index.js +9 -0
  53. package/dist/src/index.js.map +1 -1
  54. package/dist/src/institution_loader.d.ts +29 -5
  55. package/dist/src/institution_loader.js +67 -6
  56. package/dist/src/institution_loader.js.map +1 -1
  57. package/dist/src/lineage_adoption.d.ts +82 -0
  58. package/dist/src/lineage_adoption.js +82 -0
  59. package/dist/src/lineage_adoption.js.map +1 -0
  60. package/dist/src/lineage_persist.d.ts +34 -0
  61. package/dist/src/lineage_persist.js +60 -0
  62. package/dist/src/lineage_persist.js.map +1 -0
  63. package/dist/src/loader.d.ts +13 -0
  64. package/dist/src/loader.js +43 -2
  65. package/dist/src/loader.js.map +1 -1
  66. package/dist/src/local_queue.d.ts +105 -0
  67. package/dist/src/local_queue.js +380 -0
  68. package/dist/src/local_queue.js.map +1 -0
  69. package/dist/src/mcp.js +37 -4
  70. package/dist/src/mcp.js.map +1 -1
  71. package/dist/src/org_hire.d.ts +23 -0
  72. package/dist/src/org_hire.js +42 -0
  73. package/dist/src/org_hire.js.map +1 -0
  74. package/dist/src/outputs.d.ts +17 -0
  75. package/dist/src/outputs.js +86 -1
  76. package/dist/src/outputs.js.map +1 -1
  77. package/dist/src/player_to_claude_code.js +26 -2
  78. package/dist/src/player_to_claude_code.js.map +1 -1
  79. package/dist/src/registry.d.ts +3 -1
  80. package/dist/src/registry.js +43 -3
  81. package/dist/src/registry.js.map +1 -1
  82. package/dist/src/repo_index.d.ts +58 -0
  83. package/dist/src/repo_index.js +232 -0
  84. package/dist/src/repo_index.js.map +1 -0
  85. package/dist/src/residency.d.ts +149 -0
  86. package/dist/src/residency.js +283 -0
  87. package/dist/src/residency.js.map +1 -0
  88. package/dist/src/reuse.d.ts +44 -4
  89. package/dist/src/reuse.js +0 -0
  90. package/dist/src/reuse.js.map +1 -1
  91. package/dist/src/runtime.d.ts +82 -0
  92. package/dist/src/runtime.js +254 -25
  93. package/dist/src/runtime.js.map +1 -1
  94. package/dist/src/server.d.ts +37 -0
  95. package/dist/src/server.js +422 -11
  96. package/dist/src/server.js.map +1 -1
  97. package/dist/src/server_relay.d.ts +40 -2
  98. package/dist/src/server_relay.js +186 -19
  99. package/dist/src/server_relay.js.map +1 -1
  100. package/dist/src/tool_providers.d.ts +27 -0
  101. package/dist/src/tool_providers.js +48 -0
  102. package/dist/src/tool_providers.js.map +1 -1
  103. package/dist/src/venue_credential.d.ts +41 -0
  104. package/dist/src/venue_credential.js +57 -0
  105. package/dist/src/venue_credential.js.map +1 -0
  106. package/dist/src/venue_realize.d.ts +23 -0
  107. package/dist/src/venue_realize.js +43 -3
  108. package/dist/src/venue_realize.js.map +1 -1
  109. package/dist/src/venue_realizer.d.ts +224 -0
  110. package/dist/src/venue_realizer.js +889 -0
  111. package/dist/src/venue_realizer.js.map +1 -0
  112. package/dist/src/version.d.ts +1 -1
  113. package/dist/src/version.js +1 -1
  114. package/dist/src/worker.d.ts +57 -0
  115. package/dist/src/worker.js +155 -24
  116. package/dist/src/worker.js.map +1 -1
  117. package/dist/src/worker_env.d.ts +79 -0
  118. package/dist/src/worker_env.js +322 -0
  119. package/dist/src/worker_env.js.map +1 -0
  120. package/dist/src/workspace.d.ts +12 -1
  121. package/dist/src/workspace.js +10 -3
  122. package/dist/src/workspace.js.map +1 -1
  123. package/domain_types/change-context.json +59 -13
  124. package/domain_types/lineage-adoption-target.json +22 -0
  125. package/domain_types/lineage-map.json +7 -2
  126. package/domain_types/lineage-record.json +55 -5
  127. package/domain_types/prior-art-hit.json +16 -1
  128. package/domain_types/red-spec.json +5 -3
  129. package/domain_types/woodshed-record.json +149 -0
  130. package/evals/gist-present.json +7 -0
  131. package/institutions/coltrane.json +178 -6
  132. package/package.json +6 -3
  133. package/skills/non-vacuity-probe/fixtures/fixture-001.json +17 -0
  134. package/skills/non-vacuity-probe/meta.json +12 -0
  135. package/skills/non-vacuity-probe/skill.md +27 -0
  136. package/skills/non-vacuity-probe/skill.mjs +81 -0
  137. package/standards/lineage-adopt-v0.json +37 -0
  138. package/standards/room-probe-v1.json +28 -0
  139. package/standards/software-change-pr-v1.json +15 -15
  140. package/standards/software-change-red-first-v0.json +183 -0
  141. package/standards/spec-review-and-sequence-v0.json +112 -0
  142. package/standards/studio-session-v0.json +101 -0
  143. package/tours/coltrane.json +72 -0
  144. package/venues/engine-room-v1.json +32 -0
@@ -0,0 +1,153 @@
1
+ import { outputSatisfiesType } from "./runtime.js";
2
+ /**
3
+ * Classify a sealed gig run against its construction. PURE — same inputs, same result; no store,
4
+ * no invoker, no network.
5
+ *
6
+ * @param standard the composed standard (the chart) this run performed
7
+ * @param produced the settled sealed output set (produced[] as runGig finalizes it — derived,
8
+ * reused-and-re-sealed, resume-restored and every amend round included)
9
+ * @param skipped the SkippedChair rows (resume + reuse), so a contract satisfied only by a prior
10
+ * gig's reused output is not read as missing
11
+ * @param status the run's terminal status. `"complete"` runs FIT+TIMING; `"awaiting_approval"`
12
+ * short-circuits to INCOMPLETE; anything else is FAILED
13
+ * @param gigId this gig's id — the boundary that tells an in-gig derived record from a seeded or
14
+ * reused-by-reference cross-gig record (whose source gig owns its own timing)
15
+ */
16
+ export function checkGigConformance(standard, produced, skipped, status, gigId) {
17
+ // ── Status routing FIRST — before any FIT/TIMING analysis ──────────────────────────────────
18
+ // A parked gig legitimately lacks its human chair's output; a failed gig lacks outputs by
19
+ // definition. Neither is a nonconformance, and running FIT over either would manufacture one.
20
+ if (status === "awaiting_approval") {
21
+ return { verdict: "INCOMPLETE", awaiting_status: status };
22
+ }
23
+ if (status !== "complete") {
24
+ return { verdict: "FAILED", description: `gig ended in status "${status}" — a run that did not complete lacks outputs by definition; conformance describes that, it does not condemn it` };
25
+ }
26
+ const chairs = standard.phases.flatMap((p) => [...p.chairs]);
27
+ const chairByRole = new Map(chairs.map((c) => [c.role, c]));
28
+ // Records THIS chair actually sealed, keyed by producing role. Reuse re-seals into this gig and
29
+ // resume restores into it, so both already appear here under their chair's role.
30
+ const recordsByRole = new Map();
31
+ for (const r of produced) {
32
+ if (r.from_role === undefined)
33
+ continue; // legacy hand-rolled write with no chair attribution
34
+ const list = recordsByRole.get(r.from_role);
35
+ if (list)
36
+ list.push(r);
37
+ else
38
+ recordsByRole.set(r.from_role, [r]);
39
+ }
40
+ // Reuse SkippedChairs, keyed by role: a declared type satisfied ONLY by a prior gig's reused
41
+ // output (the "referenced, not re-sealed" shape) is conformant, not missing. Resume rows also
42
+ // appear in produced[] under their role, so this is the reuse-by-reference safety net.
43
+ const reuseTypesByRole = new Map();
44
+ for (const sk of skipped) {
45
+ if (sk.reason !== "reuse")
46
+ continue;
47
+ const set = reuseTypesByRole.get(sk.role) ?? new Set();
48
+ for (const t of sk.output_types)
49
+ set.add(t);
50
+ reuseTypesByRole.set(sk.role, set);
51
+ }
52
+ // ── FIT ────────────────────────────────────────────────────────────────────────────────────
53
+ const fit_violations = [];
54
+ const fit_surplus = [];
55
+ for (const c of chairs) {
56
+ const optional = new Set(c.optional_outputs ?? []);
57
+ const sealed = recordsByRole.get(c.role) ?? [];
58
+ const reused = reuseTypesByRole.get(c.role);
59
+ for (const declared of c.output_contract) {
60
+ // Cardinality is not the question — "at least one" record of the declared type, subtype-aware.
61
+ const satisfiedByRecord = sealed.some((r) => outputSatisfiesType(r, declared));
62
+ // A reuse SkippedChair names its covered types as plain strings (no record to run the
63
+ // polymorphic predicate over), so an exact-name match is the honest check there.
64
+ const satisfiedByReuse = reused?.has(declared) === true;
65
+ if (satisfiedByRecord || satisfiedByReuse)
66
+ continue;
67
+ // A genome-declared optional (#243) that sealed nothing is a conditional output, not a gap —
68
+ // that shortfall is `GigResult.unfulfilled_outputs`' concern, a different question from FIT.
69
+ if (optional.has(declared))
70
+ continue;
71
+ fit_violations.push({ chair_slug: c.role, declared_type: declared });
72
+ }
73
+ }
74
+ // Surplus: a record sealed under a type its chair never declared. Scanned over records the chair
75
+ // actually sealed (attributable via from_role) — a foreign record with no matching chair is not
76
+ // this standard's to grade.
77
+ for (const c of chairs) {
78
+ const contract = c.output_contract;
79
+ for (const r of recordsByRole.get(c.role) ?? []) {
80
+ const matchesSomeDeclared = contract.some((declared) => outputSatisfiesType(r, declared));
81
+ if (!matchesSomeDeclared) {
82
+ fit_surplus.push({ chair_slug: c.role, sealed_type: r.domain_type });
83
+ }
84
+ }
85
+ }
86
+ // ── TIMING ───────────────────────────────────────────────────────────────────────────────────
87
+ // Reverse-dependency index: for each chair, the chairs that declared depends_on IT. The
88
+ // examine-amend loop feeds a verify chair's verdict back into the maker it judged, and the verify
89
+ // chair `depends_on` the maker — so a maker consuming that verdict is respecting a DECLARED edge,
90
+ // read in reverse for feedback. Authorizing both directions of a declared edge is what keeps the
91
+ // check from crying wolf on every amend round.
92
+ const reverseDeps = new Map();
93
+ for (const c of chairs) {
94
+ for (const dep of c.depends_on) {
95
+ const set = reverseDeps.get(dep) ?? new Set();
96
+ set.add(c.role);
97
+ reverseDeps.set(dep, set);
98
+ }
99
+ }
100
+ // sha → the in-gig chair that sealed a record with that content_sha. Attribution for a flagged
101
+ // sha, and the resolvability test: a sha NOT in this map belongs to a seed / reused-by-reference
102
+ // / store-miss record and is unresolvable here — the check stays silent rather than guess.
103
+ const shaToRole = new Map();
104
+ for (const r of produced) {
105
+ if (r.gig_id !== gigId)
106
+ continue; // only in-gig sealed records attribute a chair here
107
+ if (r.from_role === undefined)
108
+ continue;
109
+ if (!shaToRole.has(r.content_sha))
110
+ shaToRole.set(r.content_sha, r.from_role);
111
+ }
112
+ const timing_violations = [];
113
+ for (const r of produced) {
114
+ // A reused/seeded record's provenance was validated by its SOURCE gig at that gig's close —
115
+ // its shas resolve into that gig, not this one. Skip on either signal: a foreign gig_id, or the
116
+ // reused_from annotation the reuse re-seal stamps.
117
+ if (r.gig_id !== gigId)
118
+ continue;
119
+ if (r.reused_from)
120
+ continue;
121
+ if (r.from_role === undefined)
122
+ continue;
123
+ const producer = chairByRole.get(r.from_role);
124
+ if (!producer)
125
+ continue; // record from a role not in this standard — not ours to time
126
+ // Authorized producers of this record's inputs: the declared upstream (depends_on), the reverse
127
+ // feedback edge (chairs that depend_on this producer — the examine-amend case), and the producer
128
+ // itself (iterative self-consumption).
129
+ const authorized = new Set([producer.role, ...producer.depends_on]);
130
+ for (const rev of reverseDeps.get(producer.role) ?? [])
131
+ authorized.add(rev);
132
+ for (const sha of r.input_shas) {
133
+ if (sha === "")
134
+ continue; // engine stamped "" for an input it could not resolve — a store-miss, not a breach
135
+ const source = shaToRole.get(sha);
136
+ if (source === undefined)
137
+ continue; // resolves to no in-gig record — a seed / cross-gig input, unresolvable here
138
+ if (authorized.has(source))
139
+ continue; // respects a declared edge (forward, reverse, or self)
140
+ timing_violations.push({
141
+ record_id: r.id,
142
+ sealing_chair_slug: r.from_role,
143
+ unauthorized_sha: sha,
144
+ unauthorized_source_chair_slug: source,
145
+ });
146
+ }
147
+ }
148
+ if (fit_violations.length === 0 && fit_surplus.length === 0 && timing_violations.length === 0) {
149
+ return { verdict: "CLEAN" };
150
+ }
151
+ return { verdict: "VIOLATED", fit_violations, fit_surplus, timing_violations };
152
+ }
153
+ //# sourceMappingURL=gig_conformance.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gig_conformance.js","sourceRoot":"","sources":["../../src/gig_conformance.ts"],"names":[],"mappings":"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"}
@@ -117,6 +117,14 @@ export function gigEventLogLine(gig_id, ev) {
117
117
  case "phase_start": return JSON.stringify({ ...base, ev: "phase_start", phase: ev.phase, chairs: ev.roles });
118
118
  case "chair_start": return JSON.stringify({ ...base, ev: "chair_start", phase: ev.phase, role: ev.role, producer: ev.producer });
119
119
  case "chair_complete": return JSON.stringify({ ...base, ev: "chair_complete", role: ev.role, sealed: ev.output_types, ms: ev.duration_ms });
120
+ // Logged whichever way it went. An adoption is a governance act and a refusal is the
121
+ // reason one did not happen; a line that only appeared on success would make silence
122
+ // ambiguous, which is the defect this channel exists to close.
123
+ case "lineage_adoption": return JSON.stringify({ ...base, ev: "lineage_adoption", role: ev.role,
124
+ adopt: ev.adopt, ...(ev.record_ref ? { record_ref: ev.record_ref } : {}),
125
+ ...(ev.institution_slug ? { institution: ev.institution_slug } : {}),
126
+ ...(ev.approved_by ? { approved_by: ev.approved_by } : {}),
127
+ ...(ev.refusals ? { refusals: ev.refusals } : {}) });
120
128
  case "chair_failed": return JSON.stringify({ ...base, ev: "chair_failed", role: ev.role, error: ev.error });
121
129
  // #241 — a dangling (non-required) skill binding. Surfaced live because an unskilled run
122
130
  // is otherwise indistinguishable from a skilled one: same genome_hash, run_fingerprint,
@@ -1 +1 @@
1
- {"version":3,"file":"gig_tracker.js","sourceRoot":"","sources":["../../src/gig_tracker.ts"],"names":[],"mappings":"AAAA,kFAAkF;AAClF,EAAE;AACF,0FAA0F;AAC1F,4FAA4F;AAC5F,4FAA4F;AAC5F,0FAA0F;AA8E1F,MAAM,UAAU,SAAS,CAAC,MAAc,EAAE,aAAqB,EAAE,YAAoB,EAAE,GAAW;IAChG,OAAO;QACL,MAAM,EAAE,aAAa,EAAE,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,GAAG;QACzD,YAAY,EAAE,WAAW,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,aAAa,EAAE,CAAC;KAC5D,CAAC;AACJ,CAAC;AAED,4FAA4F;AAC5F,wEAAwE;AACxE,MAAM,UAAU,gBAAgB,CAAC,KAAkB,EAAE,EAAoB;IACvE,QAAQ,EAAE,CAAC,IAAI,EAAE,CAAC;QAChB,KAAK,aAAa;YAChB,KAAK,CAAC,aAAa,GAAG,EAAE,CAAC,KAAK,CAAC;YAC/B,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,QAAQ,CAAC,EAAE,CAAC,KAAK,CAAC;gBAAE,KAAK,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC;YAC5E,KAAK,MAAM,IAAI,IAAI,EAAE,CAAC,KAAK,EAAE,CAAC;gBAC5B,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC;oBAAE,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC;YAC7G,CAAC;YACD,MAAM;QACR,KAAK,aAAa;YAChB,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,EAAE,CAAC,QAAQ,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC;YACrH,MAAM;QACR,KAAK,aAAa,CAAC,CAAC,CAAC;YACnB,MAAM,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC;YAChC,IAAI,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,UAAU,IAAI,EAAE,CAAC,KAAK,CAAC,IAAI;gBAAE,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YACzF,MAAM;QACR,CAAC;QACD,KAAK,gBAAgB,CAAC,CAAC,CAAC;YACtB,MAAM,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC,CAAC;YACnI,CAAC,CAAC,MAAM,GAAG,UAAU,CAAC;YACtB,CAAC,CAAC,QAAQ,GAAG,EAAE,CAAC,QAAQ,CAAC;YACzB,CAAC,CAAC,YAAY,GAAG,EAAE,CAAC,YAAY,CAAC;YACjC,CAAC,CAAC,WAAW,GAAG,EAAE,CAAC,WAAW,CAAC;YAC/B,KAAK,CAAC,aAAa,IAAI,EAAE,CAAC,YAAY,CAAC,MAAM,CAAC;YAC9C,MAAM;QACR,CAAC;QACD,KAAK,cAAc,CAAC,CAAC,CAAC;YACpB,MAAM,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC,CAAC;YACnI,CAAC,CAAC,MAAM,GAAG,QAAQ,CAAC;YACpB,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC,KAAK,CAAC;YACnB,MAAM;QACR,CAAC;QACD,KAAK,aAAa;YAChB,KAAK,CAAC,YAAY,GAAG,EAAE,MAAM,EAAE,EAAE,CAAC,WAAW,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE,CAAC,OAAO,EAAE,CAAC;YACtF,KAAK,CAAC,aAAa,IAAI,EAAE,CAAC,OAAO,CAAC;YAClC,MAAM;QACR,KAAK,eAAe,CAAC,CAAC,CAAC;YACrB,+EAA+E;YAC/E,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG;gBACtB,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,EAAE;gBACjE,YAAY,EAAE,EAAE,CAAC,YAAY,EAAE,cAAc,EAAE,EAAE,CAAC,MAAM,EAAE,aAAa,EAAE,EAAE,CAAC,aAAa;aAC1F,CAAC;YACF,CAAC,KAAK,CAAC,cAAc,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC;gBACjC,KAAK,EAAE,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,CAAC,MAAM;gBACjD,aAAa,EAAE,EAAE,CAAC,aAAa,EAAE,YAAY,EAAE,EAAE,CAAC,YAAY;aAC/D,CAAC,CAAC;YACH,MAAM;QACR,CAAC;QACD,KAAK,gBAAgB;YACnB,CAAC,KAAK,CAAC,cAAc,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC;gBACjC,KAAK,EAAE,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,CAAC,MAAM;gBACjD,GAAG,CAAC,EAAE,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aAC1D,CAAC,CAAC;YACH,MAAM;QACR,KAAK,cAAc;YACjB,KAAK,CAAC,aAAa,GAAG,EAAE,CAAC,OAAO,CAAC;YACjC,MAAM;QACR,KAAK,uBAAuB;YAC1B,KAAK,CAAC,MAAM,GAAG,mBAAmB,CAAC;YACnC,KAAK,CAAC,QAAQ,GAAG,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,CAAC;YACpD,MAAM;QACR,KAAK,YAAY;YACf,KAAK,CAAC,KAAK,GAAG,EAAE,CAAC,KAAK,CAAC;YACvB,MAAM;QACR,KAAK,aAAa;YAChB,wFAAwF;YACxF,uFAAuF;YACvF,KAAK,CAAC,MAAM,GAAG,SAAS,CAAC;YACzB,KAAK,CAAC,YAAY,GAAG,EAAE,CAAC,MAAM,CAAC;YAC/B,KAAK,CAAC,WAAW,KAAK,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;YAC/C,MAAM;IACV,CAAC;AACH,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAG,GAAG,CAAC;AAE7C,MAAM,UAAU,YAAY,CAAC,IAA8B,EAAE,GAAG,GAAG,yBAAyB;IAC1F,MAAM,OAAO,GAAG,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC;IACzE,IAAI,OAAO,CAAC,MAAM,IAAI,GAAG;QAAE,OAAO,CAAC,CAAC;IACpC,MAAM,EAAE,GAAG,CAAC,CAAc,EAAU,EAAE,CAAC,CAAC,CAAC,WAAW,IAAI,CAAC,CAAC,UAAU,CAAC;IACrE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACrE,MAAM,IAAI,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,OAAO,CAAC,MAAM,GAAG,GAAG,CAAC,CAAC;IACpD,KAAK,MAAM,CAAC,IAAI,IAAI;QAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;IAC5C,OAAO,IAAI,CAAC,MAAM,CAAC;AACrB,CAAC;AAED,yFAAyF;AACzF,MAAM,UAAU,eAAe,CAAC,MAAc,EAAE,EAAoB;IAClE,MAAM,IAAI,GAAG,EAAE,CAAC,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC;IAC1D,QAAQ,EAAE,CAAC,IAAI,EAAE,CAAC;QAChB,KAAK,aAAa,CAAC,CAAC,OAAO,IAAI,CAAC,SAAS,CAAC,EAAE,GAAG,IAAI,EAAE,EAAE,EAAE,aAAa,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,CAAC,KAAK,EAAE,CAAC,CAAC;QAC7G,KAAK,aAAa,CAAC,CAAC,OAAO,IAAI,CAAC,SAAS,CAAC,EAAE,GAAG,IAAI,EAAE,EAAE,EAAE,aAAa,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,QAAQ,EAAE,EAAE,CAAC,QAAQ,EAAE,CAAC,CAAC;QACjI,KAAK,gBAAgB,CAAC,CAAC,OAAO,IAAI,CAAC,SAAS,CAAC,EAAE,GAAG,IAAI,EAAE,EAAE,EAAE,gBAAgB,EAAE,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,CAAC,YAAY,EAAE,EAAE,EAAE,EAAE,CAAC,WAAW,EAAE,CAAC,CAAC;QAC5I,KAAK,cAAc,CAAC,CAAC,OAAO,IAAI,CAAC,SAAS,CAAC,EAAE,GAAG,IAAI,EAAE,EAAE,EAAE,cAAc,EAAE,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK,EAAE,CAAC,CAAC;QAC5G,yFAAyF;QACzF,wFAAwF;QACxF,yFAAyF;QACzF,KAAK,mBAAmB,CAAC,CAAC,OAAO,IAAI,CAAC,SAAS,CAAC,EAAE,GAAG,IAAI,EAAE,EAAE,EAAE,mBAAmB,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC;QAC5J,4FAA4F;QAC5F,uFAAuF;QACvF,KAAK,aAAa,CAAC,CAAC,OAAO,IAAI,CAAC,SAAS,CAAC,EAAE,GAAG,IAAI,EAAE,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,EAAE,CAAC,WAAW,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC;QACtI,KAAK,eAAe,CAAC,CAAC,OAAO,IAAI,CAAC,SAAS,CAAC,EAAE,GAAG,IAAI,EAAE,EAAE,EAAE,eAAe,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE,CAAC,MAAM,EAAE,QAAQ,EAAE,EAAE,CAAC,aAAa,EAAE,MAAM,EAAE,EAAE,CAAC,YAAY,EAAE,CAAC,CAAC;QACnL,KAAK,gBAAgB,CAAC,CAAC,OAAO,IAAI,CAAC,SAAS,CAAC,EAAE,GAAG,IAAI,EAAE,EAAE,EAAE,gBAAgB,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,CAAC,CAAC;QACtJ,0FAA0F;QAC1F,2FAA2F;QAC3F,sEAAsE;QACtE,KAAK,cAAc,CAAC,CAAC,OAAO,IAAI,CAAC,SAAS,CAAC,EAAE,GAAG,IAAI,EAAE,EAAE,EAAE,cAAc,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,WAAW,EAAE,EAAE,CAAC,WAAW,EAAE,cAAc,EAAE,EAAE,CAAC,cAAc,EAAE,CAAC,CAAC;QAC5K,KAAK,cAAc,CAAC,CAAC,OAAO,IAAI,CAAC,SAAS,CAAC,EAAE,GAAG,IAAI,EAAE,EAAE,EAAE,cAAc,EAAE,OAAO,EAAE,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC;QACjG,KAAK,uBAAuB,CAAC,CAAC,OAAO,IAAI,CAAC,SAAS,CAAC,EAAE,GAAG,IAAI,EAAE,EAAE,EAAE,uBAAuB,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC;QAC9H,KAAK,YAAY,CAAC,CAAC,OAAO,IAAI,CAAC,SAAS,CAAC,EAAE,GAAG,IAAI,EAAE,EAAE,EAAE,YAAY,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK,EAAE,CAAC,CAAC;QACzF,KAAK,aAAa,CAAC,CAAC,OAAO,IAAI,CAAC,SAAS,CAAC,EAAE,GAAG,IAAI,EAAE,EAAE,EAAE,aAAa,EAAE,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,CAAC,CAAC;QAC7F,KAAK,aAAa;YAChB,0DAA0D;YAC1D,OAAO,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,UAAU;gBACjC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,GAAG,IAAI,EAAE,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;gBACjF,CAAC,CAAC,IAAI,CAAC;IACb,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"gig_tracker.js","sourceRoot":"","sources":["../../src/gig_tracker.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,44 @@
1
+ import type { RepositoryIndex } from "./repo_index.js";
2
+ /** The judgment half a reader supplies — the noticing the compiler deliberately does not do. */
3
+ export type Judgment = {
4
+ claims: unknown[];
5
+ unknowns: string[];
6
+ frame: string;
7
+ confidence?: number;
8
+ };
9
+ /** A guard/acceptance result. `reason` is present only on refusal (exactOptionalPropertyTypes). */
10
+ export type GroundingResult = {
11
+ ok: boolean;
12
+ reason?: string;
13
+ };
14
+ /**
15
+ * Assemble a change-context from a compiled index (mechanical fields) plus a reader's judgment
16
+ * (the claims/unknowns/frame the compiler cannot produce). The result satisfies the shared
17
+ * change-context type: every required field is populated and no undeclared field is added.
18
+ */
19
+ export declare function assembleChangeContext(index: RepositoryIndex, judgment: Judgment): Record<string, unknown>;
20
+ /**
21
+ * Admit a change-context only when it carries a READING — at least one load-bearing claim (a
22
+ * locator with a line, asserting something the index cannot hold). Empty claims, or claims that
23
+ * merely restate the mechanical index (file-only locators), are refused: a judgment-free grounding
24
+ * does not pass, and a load-bearing claim is not laundered by derivable ones alongside it.
25
+ */
26
+ export declare function admitChangeContext(rec: Record<string, unknown>, index: RepositoryIndex): GroundingResult;
27
+ /**
28
+ * Refuse a change-context whose index revision has drifted from current source. Fail closed: a
29
+ * missing or mismatched revision does not pass — a stale index seeding a change is worse than a
30
+ * slow reader.
31
+ */
32
+ export declare function freshnessGate(rec: Record<string, unknown>, currentRevision: string): GroundingResult;
33
+ /**
34
+ * The golden-master surface: the MECHANICAL fields only. Judgment has no fixed oracle, so a
35
+ * snapshot must never pin `claims` / `unknowns` / `frame` to a "correct" value. Stripping them
36
+ * leaves exactly the fields a deterministic diff may hold to.
37
+ */
38
+ export declare function snapshotMechanical(rec: Record<string, unknown>): Record<string, unknown>;
39
+ /**
40
+ * The producer-agnostic acceptance. The consumer keys on the change-context TYPE — the presence of
41
+ * a reading (claims) and its mechanical companions — and NEVER on who produced it. `produced_by`
42
+ * is not read here, so the same record labelled by any producer is accepted identically.
43
+ */
44
+ export declare function consumerAcceptsGrounding(rec: Record<string, unknown>): GroundingResult;
@@ -0,0 +1,127 @@
1
+ // Grounding arrives as an INPUT — and judgment cannot be replaced by lookup.
2
+ //
3
+ // Two decoupled obligations, held apart on purpose (#424):
4
+ // (1) GROUNDING-AS-INPUT — a change-context is a first-class record any of four interchangeable
5
+ // producers (reader / compiler / prior standard / human) may seal, and the consuming
6
+ // standard keys on the TYPE, never on who produced it. `assembleChangeContext` is the
7
+ // compiler-plus-enricher producer: mechanical fields lifted from a compiled index, judgment
8
+ // supplied by a reader. `consumerAcceptsGrounding` is the producer-agnostic acceptance —
9
+ // it does not read `produced_by`. `freshnessGate` refuses a change-context whose index
10
+ // revision has drifted from current source (a stale index seeding a change is worse than a
11
+ // slow reader — fail closed).
12
+ // (2) DO-NOT-COMPILE-AWAY-THE-CLAIMS — the mechanical fields may be compiled, but a change-context
13
+ // is UNSATISFIABLE by a record whose claims are empty or merely restate the index. A reading
14
+ // is a claim that points at a specific line and asserts something the index cannot hold;
15
+ // `admitChangeContext` admits only a record that carries at least one. `snapshotMechanical`
16
+ // is the golden-master surface: it strips the judgment fields, because judgment has no fixed
17
+ // oracle — only the mechanical fields can be pinned.
18
+ //
19
+ // Everything here is pure: no I/O, no clock, no registry. The functions operate on plain records
20
+ // so the seam can be verified in isolation (consumer against a seeded change-context; each
21
+ // producer/guard against the shared type) without running a live agent.
22
+ /**
23
+ * A locator is LOAD-BEARING when it names a specific line (file:line) — evidence the mechanical
24
+ * index cannot itself hold. A file-only locator merely points at a file the index already lists,
25
+ * so it is derivable and does not, on its own, make a claim a reading. This is exactly the
26
+ * distinction the two spec fixtures exercise (`src/runtime.ts` vs `src/runtime.ts:2072`).
27
+ */
28
+ function isLoadBearing(claim) {
29
+ const locator = claim?.locator;
30
+ return typeof locator === "string" && /:\d+/.test(locator);
31
+ }
32
+ /**
33
+ * Assemble a change-context from a compiled index (mechanical fields) plus a reader's judgment
34
+ * (the claims/unknowns/frame the compiler cannot produce). The result satisfies the shared
35
+ * change-context type: every required field is populated and no undeclared field is added.
36
+ */
37
+ export function assembleChangeContext(index, judgment) {
38
+ const relevant_files = index.boundary.map((path) => ({
39
+ path,
40
+ why: "within the compiled boundary of the reading",
41
+ locator: path,
42
+ }));
43
+ const existing_tests = [...new Set(index.module_tests.map((m) => m.test))].sort();
44
+ const entry_points = index.entry_points.map((e) => `${e.module}#${e.symbol}`);
45
+ return {
46
+ id: `change-context@${index.source_revision}`,
47
+ input_refs: [`repo-index/${index.source_revision}`],
48
+ // Judgment half — supplied by the reader, opaque to the compiler.
49
+ frame: judgment.frame,
50
+ claims: judgment.claims,
51
+ unknowns: judgment.unknowns,
52
+ ...(judgment.confidence !== undefined ? { confidence: judgment.confidence } : {}),
53
+ // Mechanical half — lifted verbatim from the compiled index.
54
+ boundary: index.boundary,
55
+ entry_points,
56
+ relevant_files,
57
+ existing_tests,
58
+ conventions_observed: index.conventions_observed,
59
+ index_revision: index.source_revision,
60
+ };
61
+ }
62
+ /**
63
+ * Admit a change-context only when it carries a READING — at least one load-bearing claim (a
64
+ * locator with a line, asserting something the index cannot hold). Empty claims, or claims that
65
+ * merely restate the mechanical index (file-only locators), are refused: a judgment-free grounding
66
+ * does not pass, and a load-bearing claim is not laundered by derivable ones alongside it.
67
+ */
68
+ export function admitChangeContext(rec, index) {
69
+ void index; // the predicate keys on locator format alone (#424 tradeoff), not on index contents
70
+ const claims = rec["claims"];
71
+ if (!Array.isArray(claims) || claims.length === 0) {
72
+ return { ok: false, reason: "a change-context with no claims is a judgment-free grounding" };
73
+ }
74
+ if (!claims.some(isLoadBearing)) {
75
+ return {
76
+ ok: false,
77
+ reason: "every claim is derivable from the mechanical index — a lookup masquerading as a reading",
78
+ };
79
+ }
80
+ return { ok: true };
81
+ }
82
+ /**
83
+ * Refuse a change-context whose index revision has drifted from current source. Fail closed: a
84
+ * missing or mismatched revision does not pass — a stale index seeding a change is worse than a
85
+ * slow reader.
86
+ */
87
+ export function freshnessGate(rec, currentRevision) {
88
+ const rev = rec["index_revision"];
89
+ if (typeof rev !== "string" || rev.length === 0) {
90
+ return { ok: false, reason: "change-context carries no index_revision — cannot prove freshness" };
91
+ }
92
+ if (rev !== currentRevision) {
93
+ return { ok: false, reason: `stale index: change-context built at ${rev}, current source is ${currentRevision}` };
94
+ }
95
+ return { ok: true };
96
+ }
97
+ /**
98
+ * The golden-master surface: the MECHANICAL fields only. Judgment has no fixed oracle, so a
99
+ * snapshot must never pin `claims` / `unknowns` / `frame` to a "correct" value. Stripping them
100
+ * leaves exactly the fields a deterministic diff may hold to.
101
+ */
102
+ export function snapshotMechanical(rec) {
103
+ const { claims, unknowns, frame, ...mechanical } = rec;
104
+ void claims;
105
+ void unknowns;
106
+ void frame;
107
+ return mechanical;
108
+ }
109
+ /**
110
+ * The producer-agnostic acceptance. The consumer keys on the change-context TYPE — the presence of
111
+ * a reading (claims) and its mechanical companions — and NEVER on who produced it. `produced_by`
112
+ * is not read here, so the same record labelled by any producer is accepted identically.
113
+ */
114
+ export function consumerAcceptsGrounding(rec) {
115
+ const claims = rec["claims"];
116
+ if (!Array.isArray(claims) || claims.length === 0) {
117
+ return { ok: false, reason: "not a change-context: no claims" };
118
+ }
119
+ if (!Array.isArray(rec["relevant_files"])) {
120
+ return { ok: false, reason: "not a change-context: no relevant_files" };
121
+ }
122
+ if (!Array.isArray(rec["unknowns"])) {
123
+ return { ok: false, reason: "not a change-context: unknowns must be named, even if empty" };
124
+ }
125
+ return { ok: true };
126
+ }
127
+ //# sourceMappingURL=grounding.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"grounding.js","sourceRoot":"","sources":["../../src/grounding.ts"],"names":[],"mappings":"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"}
@@ -25,6 +25,7 @@ export * from "./reuse.js";
25
25
  export * from "./charter.js";
26
26
  export * from "./server.js";
27
27
  export * from "./runtime.js";
28
+ export * from "./gig_conformance.js";
28
29
  export * from "./chart.js";
29
30
  export * from "./claude_invoker.js";
30
31
  export * from "./bifrost_invoker.js";
@@ -39,3 +40,5 @@ export * from "./polyphony.js";
39
40
  export * from "./harmonic_validation.js";
40
41
  export * from "./acoustics.js";
41
42
  export * from "./document_factory.js";
43
+ export * from "./local_queue.js";
44
+ export * from "./residency.js";
package/dist/src/index.js CHANGED
@@ -25,6 +25,7 @@ export * from "./reuse.js";
25
25
  export * from "./charter.js";
26
26
  export * from "./server.js";
27
27
  export * from "./runtime.js";
28
+ export * from "./gig_conformance.js";
28
29
  export * from "./chart.js";
29
30
  export * from "./claude_invoker.js";
30
31
  export * from "./bifrost_invoker.js";
@@ -39,4 +40,12 @@ export * from "./polyphony.js";
39
40
  export * from "./harmonic_validation.js";
40
41
  export * from "./acoustics.js";
41
42
  export * from "./document_factory.js";
43
+ // The two engine-half modules a downstream consumer imports directly. Neither is wired into a
44
+ // surface yet — enqueueing locally and claiming locally are each their own contract — but both are
45
+ // PUBLIC surfaces, not internals: local_queue is the third queue backing (the file sibling of
46
+ // fileGenomeStore), and residency is the enforcement half of `coltrane reside`. Exporting them here
47
+ // is what tests/exported_symbols_are_reachable.test.ts asks for when a mechanism has no in-src
48
+ // caller: "wire it or export it." Wiring is a separate act; reachability is not.
49
+ export * from "./local_queue.js";
50
+ export * from "./residency.js";
42
51
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,iBAAiB,CAAC;AAChC,cAAc,sBAAsB,CAAC;AACrC,cAAc,kBAAkB,CAAC;AACjC,cAAc,qBAAqB,CAAC;AACpC,cAAc,sBAAsB,CAAC;AACrC,cAAc,UAAU,CAAC;AACzB,cAAc,cAAc,CAAC;AAC7B,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC;AACnC,cAAc,wBAAwB,CAAC;AACvC,cAAc,eAAe,CAAC;AAC9B,cAAc,uBAAuB,CAAC;AACtC,cAAc,cAAc,CAAC;AAC7B,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,2BAA2B,CAAC;AAC1C,cAAc,qBAAqB,CAAC;AACpC,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,oBAAoB,CAAC;AACnC,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,YAAY,CAAC;AAC3B,cAAc,qBAAqB,CAAC;AACpC,cAAc,sBAAsB,CAAC;AACrC,cAAc,uBAAuB,CAAC;AACtC,cAAc,sBAAsB,CAAC;AACrC,cAAc,kBAAkB,CAAC;AACjC,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC;AAC3B,cAAc,eAAe,CAAC;AAC9B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,0BAA0B,CAAC;AACzC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,uBAAuB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,iBAAiB,CAAC;AAChC,cAAc,sBAAsB,CAAC;AACrC,cAAc,kBAAkB,CAAC;AACjC,cAAc,qBAAqB,CAAC;AACpC,cAAc,sBAAsB,CAAC;AACrC,cAAc,UAAU,CAAC;AACzB,cAAc,cAAc,CAAC;AAC7B,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC;AACnC,cAAc,wBAAwB,CAAC;AACvC,cAAc,eAAe,CAAC;AAC9B,cAAc,uBAAuB,CAAC;AACtC,cAAc,cAAc,CAAC;AAC7B,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,2BAA2B,CAAC;AAC1C,cAAc,qBAAqB,CAAC;AACpC,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,oBAAoB,CAAC;AACnC,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,sBAAsB,CAAC;AACrC,cAAc,YAAY,CAAC;AAC3B,cAAc,qBAAqB,CAAC;AACpC,cAAc,sBAAsB,CAAC;AACrC,cAAc,uBAAuB,CAAC;AACtC,cAAc,sBAAsB,CAAC;AACrC,cAAc,kBAAkB,CAAC;AACjC,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC;AAC3B,cAAc,eAAe,CAAC;AAC9B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,0BAA0B,CAAC;AACzC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,uBAAuB,CAAC;AAEtC,8FAA8F;AAC9F,mGAAmG;AACnG,8FAA8F;AAC9F,oGAAoG;AACpG,+FAA+F;AAC/F,iFAAiF;AACjF,cAAc,kBAAkB,CAAC;AACjC,cAAc,gBAAgB,CAAC"}
@@ -1,5 +1,6 @@
1
1
  import type { LoadError } from "./loader.js";
2
2
  import type { InstitutionOutput, OrganizationOutput, AgentRecordOutput, InstitutionalChairOutput, ChairAssignmentOutput, ForebearOutput, LineageEdgeOutput, NorthstarOutput, TourOutput, ResourceOutput } from "./genome_schema.js";
3
+ import { type LineageRecordRefOutput } from "./genome_schema.js";
3
4
  /** The multi-section institution document as it lives on disk (shape per institutions/quartet.json).
4
5
  * Each present section is validated LOSS-FREE against its already-authored per-section schema in
5
6
  * src/genome_schema.ts; an absent optional section is treated as empty, not as an error. This IS
@@ -27,15 +28,16 @@ export interface LoadedInstitution {
27
28
  document: InstitutionDocumentSections;
28
29
  }
29
30
  /**
30
- * SEAM (RED — body throws). Read every institutions/*.json under `root`, validate each present
31
+ * Read every institutions/*.json under `root`, validate each present
31
32
  * section against its per-section schema, invoke checkInstitutionAdmissibility on the schema-valid
32
33
  * document, and return the admitted institutions keyed by slug PLUS one load_error of kind
33
34
  * "institution" per file that is malformed, schema-invalid, inadmissible, or a duplicate slug.
34
35
  *
35
- * TOTAL by contract: the GREEN body must never throw for an institution reason — a bad document is
36
- * a per-file load_error and drops out; the rest of the genome loads. Deliberately NOT wired into
37
- * loadGenome yet: wiring it (after the agent/standard/org maps exist) is the GREEN change these red
38
- * tests demand. Until then this throws, so the tree compiles and red is honest.
36
+ * TOTAL by contract: never throws for an institution reason — a bad document becomes a per-file
37
+ * load_error and drops out; the rest of the genome loads. WIRED: loadGenome calls this at
38
+ * src/loader.ts:577 and returns the map at :589, after the agent/standard/venue/chart maps exist.
39
+ * The laws are tests/institution_loader.test.ts INV5 pins that the map is populated after a real
40
+ * load, INV6 pins the ordering, INV1/INV7/INV14 pin the totality.
39
41
  */
40
42
  export declare function loadInstitutions(root: string): {
41
43
  institutions: Map<string, LoadedInstitution>;
@@ -61,3 +63,25 @@ export declare function loadTours(root: string, institutions: ReadonlyMap<string
61
63
  tours: Map<string, LoadedTour>;
62
64
  load_errors: LoadError[];
63
65
  };
66
+ /** The seat inherits the institution's lineage — the call site `institutionLineageGrounding`
67
+ * was written for and has been waiting on.
68
+ *
69
+ * Walk is `assignment.agent_slug -> chair_id -> chair.institution_slug -> institution.lineage[]`.
70
+ * The chair's own `institution_slug` is authoritative, not the document the assignment happens to
71
+ * be filed in: an assignment may seat a player from one institution into another's office, and
72
+ * the lineage a seat carries is the lineage of the office, never of the paperwork.
73
+ *
74
+ * ONLY APPROVED LINEAGE IS INHERITED. `LineageRecordRefSchema.approved_by` is nullable and
75
+ * defaulted to null precisely so this filter can exist — the schema states the rule outright:
76
+ * "an institution never grounds itself on an unapproved lineage." A record that reached the
77
+ * approve chair and was not sealed is therefore invisible here, which is what makes a parked
78
+ * lineage pass genuinely inert rather than quietly load-bearing.
79
+ *
80
+ * Deduplicated by `record_ref`: one agent seated in two offices of the same institution inherits
81
+ * the grounding once. Order is stable — institution slug, then declaration order — so a rendered
82
+ * grounding does not churn between loads.
83
+ *
84
+ * Returns refs, not dereferenced records. The store-backed dereference through
85
+ * `coltrane_institution_lineage` is the follow-up named on `LineageRecordRefSchema`; this closes
86
+ * the resolution half, which is the half that had no home at all. */
87
+ export declare function agentLineageGrounding(institutions: ReadonlyMap<string, LoadedInstitution>, agent_slug: string): readonly LineageRecordRefOutput[];
@@ -19,19 +19,20 @@
19
19
  import { existsSync, readFileSync, readdirSync, statSync } from "node:fs";
20
20
  import { extname, join } from "node:path";
21
21
  import { z } from "zod";
22
- import { InstitutionSchema, OrganizationSchema, AgentRecordSchema, OrgMemberSchema, InstitutionalChairSchema, ChairAssignmentSchema, ForebearSchema, LineageEdgeSchema, NorthstarSchema, TourSchema, ResourceSchema, } from "./genome_schema.js";
22
+ import { InstitutionSchema, OrganizationSchema, AgentRecordSchema, OrgMemberSchema, InstitutionalChairSchema, ChairAssignmentSchema, ForebearSchema, LineageEdgeSchema, NorthstarSchema, TourSchema, ResourceSchema, institutionLineageGrounding, } from "./genome_schema.js";
23
23
  import { checkInstitutionAdmissibility } from "./institution_enforcement.js";
24
24
  import { checkTourAdmissibility } from "./committed_work.js";
25
25
  /**
26
- * SEAM (RED — body throws). Read every institutions/*.json under `root`, validate each present
26
+ * Read every institutions/*.json under `root`, validate each present
27
27
  * section against its per-section schema, invoke checkInstitutionAdmissibility on the schema-valid
28
28
  * document, and return the admitted institutions keyed by slug PLUS one load_error of kind
29
29
  * "institution" per file that is malformed, schema-invalid, inadmissible, or a duplicate slug.
30
30
  *
31
- * TOTAL by contract: the GREEN body must never throw for an institution reason — a bad document is
32
- * a per-file load_error and drops out; the rest of the genome loads. Deliberately NOT wired into
33
- * loadGenome yet: wiring it (after the agent/standard/org maps exist) is the GREEN change these red
34
- * tests demand. Until then this throws, so the tree compiles and red is honest.
31
+ * TOTAL by contract: never throws for an institution reason — a bad document becomes a per-file
32
+ * load_error and drops out; the rest of the genome loads. WIRED: loadGenome calls this at
33
+ * src/loader.ts:577 and returns the map at :589, after the agent/standard/venue/chart maps exist.
34
+ * The laws are tests/institution_loader.test.ts INV5 pins that the map is populated after a real
35
+ * load, INV6 pins the ordering, INV1/INV7/INV14 pin the totality.
35
36
  */
36
37
  export function loadInstitutions(root) {
37
38
  const institutions = new Map();
@@ -236,4 +237,64 @@ export function loadTours(root, institutions) {
236
237
  }
237
238
  return { tours, load_errors };
238
239
  }
240
+ /** The seat inherits the institution's lineage — the call site `institutionLineageGrounding`
241
+ * was written for and has been waiting on.
242
+ *
243
+ * Walk is `assignment.agent_slug -> chair_id -> chair.institution_slug -> institution.lineage[]`.
244
+ * The chair's own `institution_slug` is authoritative, not the document the assignment happens to
245
+ * be filed in: an assignment may seat a player from one institution into another's office, and
246
+ * the lineage a seat carries is the lineage of the office, never of the paperwork.
247
+ *
248
+ * ONLY APPROVED LINEAGE IS INHERITED. `LineageRecordRefSchema.approved_by` is nullable and
249
+ * defaulted to null precisely so this filter can exist — the schema states the rule outright:
250
+ * "an institution never grounds itself on an unapproved lineage." A record that reached the
251
+ * approve chair and was not sealed is therefore invisible here, which is what makes a parked
252
+ * lineage pass genuinely inert rather than quietly load-bearing.
253
+ *
254
+ * Deduplicated by `record_ref`: one agent seated in two offices of the same institution inherits
255
+ * the grounding once. Order is stable — institution slug, then declaration order — so a rendered
256
+ * grounding does not churn between loads.
257
+ *
258
+ * Returns refs, not dereferenced records. The store-backed dereference through
259
+ * `coltrane_institution_lineage` is the follow-up named on `LineageRecordRefSchema`; this closes
260
+ * the resolution half, which is the half that had no home at all. */
261
+ export function agentLineageGrounding(institutions, agent_slug) {
262
+ const seen = new Set();
263
+ const out = [];
264
+ // Chair id -> the institution that holds the office. Built once across every loaded document,
265
+ // because the chair an assignment names need not live in the same document as the assignment.
266
+ const chair_home = new Map();
267
+ for (const inst of institutions.values()) {
268
+ for (const chair of inst.document.chairs ?? []) {
269
+ // InstitutionalChairSchema.id is optional. A chair with no id cannot be named by an
270
+ // assignment's chair_id, so it seats nobody and grounds nothing — skip rather than coerce.
271
+ if (chair.id)
272
+ chair_home.set(chair.id, chair.institution_slug);
273
+ }
274
+ }
275
+ const held = new Set();
276
+ for (const inst of institutions.values()) {
277
+ for (const a of inst.document.assignments ?? []) {
278
+ if (a.agent_slug !== agent_slug)
279
+ continue;
280
+ const home = chair_home.get(a.chair_id);
281
+ if (home)
282
+ held.add(home); // an assignment naming an unknown chair grounds nothing; it is not an error here
283
+ }
284
+ }
285
+ for (const slug of [...held].sort()) {
286
+ const inst = institutions.get(slug);
287
+ if (!inst)
288
+ continue;
289
+ for (const ref of institutionLineageGrounding(inst.document.institution)) {
290
+ if (ref.approved_by == null)
291
+ continue; // unapproved lineage is not inherited
292
+ if (seen.has(ref.record_ref))
293
+ continue;
294
+ seen.add(ref.record_ref);
295
+ out.push(ref);
296
+ }
297
+ }
298
+ return out;
299
+ }
239
300
  //# sourceMappingURL=institution_loader.js.map