@eir-labs/coltrane 0.9.4 → 0.11.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 (141) 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 -1
  27. package/dist/src/claude_invoker.js +150 -17
  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 +61 -26
  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 +1 -0
  52. package/dist/src/index.js +1 -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/mcp.js +37 -4
  67. package/dist/src/mcp.js.map +1 -1
  68. package/dist/src/org_hire.d.ts +23 -0
  69. package/dist/src/org_hire.js +42 -0
  70. package/dist/src/org_hire.js.map +1 -0
  71. package/dist/src/output_mirror.js +98 -59
  72. package/dist/src/output_mirror.js.map +1 -1
  73. package/dist/src/outputs.d.ts +17 -0
  74. package/dist/src/outputs.js +86 -1
  75. package/dist/src/outputs.js.map +1 -1
  76. package/dist/src/player_to_claude_code.js +26 -2
  77. package/dist/src/player_to_claude_code.js.map +1 -1
  78. package/dist/src/registry.d.ts +3 -1
  79. package/dist/src/registry.js +43 -3
  80. package/dist/src/registry.js.map +1 -1
  81. package/dist/src/repo_index.d.ts +58 -0
  82. package/dist/src/repo_index.js +232 -0
  83. package/dist/src/repo_index.js.map +1 -0
  84. package/dist/src/reuse.d.ts +44 -4
  85. package/dist/src/reuse.js +0 -0
  86. package/dist/src/reuse.js.map +1 -1
  87. package/dist/src/runtime.d.ts +82 -0
  88. package/dist/src/runtime.js +254 -25
  89. package/dist/src/runtime.js.map +1 -1
  90. package/dist/src/server.d.ts +37 -0
  91. package/dist/src/server.js +422 -11
  92. package/dist/src/server.js.map +1 -1
  93. package/dist/src/server_relay.d.ts +40 -2
  94. package/dist/src/server_relay.js +186 -19
  95. package/dist/src/server_relay.js.map +1 -1
  96. package/dist/src/tool_providers.d.ts +27 -0
  97. package/dist/src/tool_providers.js +48 -0
  98. package/dist/src/tool_providers.js.map +1 -1
  99. package/dist/src/venue_credential.d.ts +41 -0
  100. package/dist/src/venue_credential.js +57 -0
  101. package/dist/src/venue_credential.js.map +1 -0
  102. package/dist/src/venue_realize.d.ts +23 -0
  103. package/dist/src/venue_realize.js +43 -3
  104. package/dist/src/venue_realize.js.map +1 -1
  105. package/dist/src/venue_realizer.d.ts +224 -0
  106. package/dist/src/venue_realizer.js +889 -0
  107. package/dist/src/venue_realizer.js.map +1 -0
  108. package/dist/src/version.d.ts +1 -1
  109. package/dist/src/version.js +1 -1
  110. package/dist/src/version.js.map +1 -1
  111. package/dist/src/worker.d.ts +37 -0
  112. package/dist/src/worker.js +127 -24
  113. package/dist/src/worker.js.map +1 -1
  114. package/dist/src/worker_env.d.ts +79 -0
  115. package/dist/src/worker_env.js +322 -0
  116. package/dist/src/worker_env.js.map +1 -0
  117. package/dist/src/workspace.d.ts +12 -1
  118. package/dist/src/workspace.js +10 -3
  119. package/dist/src/workspace.js.map +1 -1
  120. package/domain_types/change-context.json +59 -13
  121. package/domain_types/lineage-adoption-target.json +22 -0
  122. package/domain_types/lineage-map.json +7 -2
  123. package/domain_types/lineage-record.json +55 -5
  124. package/domain_types/prior-art-hit.json +16 -1
  125. package/domain_types/red-spec.json +5 -3
  126. package/domain_types/woodshed-record.json +149 -0
  127. package/evals/gist-present.json +7 -0
  128. package/institutions/coltrane.json +178 -6
  129. package/package.json +6 -3
  130. package/skills/non-vacuity-probe/fixtures/fixture-001.json +17 -0
  131. package/skills/non-vacuity-probe/meta.json +12 -0
  132. package/skills/non-vacuity-probe/skill.md +27 -0
  133. package/skills/non-vacuity-probe/skill.mjs +81 -0
  134. package/standards/lineage-adopt-v0.json +37 -0
  135. package/standards/room-probe-v1.json +28 -0
  136. package/standards/software-change-pr-v1.json +15 -15
  137. package/standards/software-change-red-first-v0.json +183 -0
  138. package/standards/spec-review-and-sequence-v0.json +112 -0
  139. package/standards/studio-session-v0.json +101 -0
  140. package/tours/coltrane.json +72 -0
  141. package/venues/engine-room-v1.json +32 -0
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "slug": "red-spec",
3
- "version": 1,
3
+ "version": 2,
4
4
  "extends": "Artifact",
5
5
  "domain": "spec-drafting",
6
6
  "status": "active",
@@ -21,7 +21,9 @@
21
21
  "type": "string"
22
22
  },
23
23
  "patch": {
24
- "type": "string"
24
+ "type": "string",
25
+ "description": "The unified diff itself, not a description of it. The spec-drafting review chair reads test bodies OUT OF THIS FIELD ('read each red test in the diffs'), so this is the evidence the gate adjudicates, not documentation of the change. Observed on gig 34ff466b: every patch sealed as a one-line summary ('full unified diff captured from git diff --cached ... content present verbatim in the working tree at this path') \u2014 true, and useless as evidence. The reviewer refused, correctly, marking NON-TAUTOLOGY and REDNESS 'NOT RUN'. The gate was not failed, it was STARVED, and the seal accepted that silently because the type asked only for a string.",
26
+ "pattern": "(^|\\n)[+-]"
25
27
  }
26
28
  },
27
29
  "required": [
@@ -59,7 +61,7 @@
59
61
  },
60
62
  "uncovered": {
61
63
  "type": "array",
62
- "description": "Contract invariants with no red test MUST be empty.",
64
+ "description": "Contract invariants with no red test \u2014 MUST be empty.",
63
65
  "items": {
64
66
  "type": "string"
65
67
  }
@@ -0,0 +1,149 @@
1
+ {
2
+ "slug": "woodshed-record",
3
+ "version": 1,
4
+ "extends": "Interpretation",
5
+ "domain": "learning",
6
+ "status": "active",
7
+ "schema": {
8
+ "type": "object",
9
+ "description": "The record of solitary practice — one worker, alone, producing nothing shippable, where the only output is that the worker got better. Carries NO acceptance criteria and NO pass field: a practice session with declared criteria is a gig wearing a woodshed costume. Jazz pedagogy states the separation directly — 'leave the woodshed behind and view practice activities as relatively exclusive of performance, trusting that practicing will demonstrate a meaningful effect as it organically evolves' — which is also an instruction NOT to gate practice on demonstrated transfer into later work. The stop-criterion has two halves and both are load-bearing: an objective floor that is necessary and never sufficient (a player drills a phrase through all twelve keys, at several tempos, across the range), and a felt judgment that closes it (the material is in the hands when it can be reached without conscious effort). A floor can be automated; a stop cannot. Above all this type carries FAULT ATTRIBUTION, because routing a correction to the wrong destination is the expensive failure: an engine defect written into a player's ledger becomes permanent superstition, carried at inference cost by a player it never belonged to.",
10
+ "properties": {
11
+ "question": {
12
+ "type": "string",
13
+ "description": "What was being worked out. A question, not a criterion — nobody knew the answer, which is why this was a woodshed and not a gig."
14
+ },
15
+ "iterations": {
16
+ "type": "array",
17
+ "description": "The attempts, in order, including and especially the wrong ones. A record that keeps only its final state has thrown away its entire product.",
18
+ "items": {
19
+ "type": "object",
20
+ "properties": {
21
+ "attempt": {
22
+ "type": "string"
23
+ },
24
+ "outcome": {
25
+ "type": "string",
26
+ "description": "What actually happened, measured rather than assumed."
27
+ },
28
+ "wrong_because": {
29
+ "type": "string",
30
+ "description": "Absent when the attempt held. Present is the normal case and is not a failure of the session."
31
+ },
32
+ "cost": {
33
+ "type": "string",
34
+ "description": "What the error actually cost — rounds, dollars, wall-clock, a wrong claim made to someone. An error whose cost is unrecorded cannot be prioritized against any other, and cost is the filter that makes improvement self-selecting."
35
+ }
36
+ },
37
+ "required": [
38
+ "attempt",
39
+ "outcome"
40
+ ]
41
+ }
42
+ },
43
+ "corrections": {
44
+ "type": "array",
45
+ "description": "The reductions. Many incidents collapse to few corrections, and the collapse IS the work — this is what survives compaction into a player's ledger. The incident list does not travel; the disposition does.",
46
+ "items": {
47
+ "type": "object",
48
+ "properties": {
49
+ "correction": {
50
+ "type": "string",
51
+ "description": "Stated as a disposition the next session can hold, not as a rule to remember."
52
+ },
53
+ "from_iterations": {
54
+ "type": "array",
55
+ "items": {
56
+ "type": "number"
57
+ }
58
+ },
59
+ "fault": {
60
+ "type": "string",
61
+ "enum": [
62
+ "player",
63
+ "engine",
64
+ "criterion",
65
+ "encode-this"
66
+ ],
67
+ "description": "THE LOAD-BEARING FIELD. player to that player's ledger; engine to an issue against the substrate; criterion to an amendment of the standard that asked for something unsatisfiable; encode-this to a minted skill, because the thing keeps being re-derived."
68
+ },
69
+ "attributed_to": {
70
+ "type": "string"
71
+ },
72
+ "routed": {
73
+ "type": "string",
74
+ "description": "Where it actually landed — a ledger entry, an issue number, a diff. Absent means the correction has not been delivered and the record is not finished."
75
+ }
76
+ },
77
+ "required": [
78
+ "correction",
79
+ "fault"
80
+ ]
81
+ }
82
+ },
83
+ "encode": {
84
+ "type": "array",
85
+ "description": "Techniques worth minting as skills because they were re-derived rather than recalled.",
86
+ "items": {
87
+ "type": "object",
88
+ "properties": {
89
+ "skill": {
90
+ "type": "string"
91
+ },
92
+ "why": {
93
+ "type": "string",
94
+ "description": "What its absence cost in this session."
95
+ },
96
+ "code_half": {
97
+ "type": "string",
98
+ "description": "The deterministic part, or an honest statement that there is none. A technique that can run without inference should."
99
+ }
100
+ },
101
+ "required": [
102
+ "skill",
103
+ "why"
104
+ ]
105
+ }
106
+ },
107
+ "sufficiency": {
108
+ "type": "array",
109
+ "description": "THE OBJECTIVE FLOOR — necessary, never sufficient. The checkable conditions actually met, each with how it was measured. A jazz player's floor is the phrase in all twelve keys at several tempos; a skill's floor is its fixtures passing. Clearing the floor does not end a session, and that asymmetry is the point.",
110
+ "items": {
111
+ "type": "object",
112
+ "properties": {
113
+ "condition": {
114
+ "type": "string"
115
+ },
116
+ "met": {
117
+ "type": "boolean"
118
+ },
119
+ "measured_by": {
120
+ "type": "string",
121
+ "description": "How it was established. An unmeasured condition is a claim."
122
+ }
123
+ },
124
+ "required": [
125
+ "condition",
126
+ "met"
127
+ ]
128
+ }
129
+ },
130
+ "heard_by": {
131
+ "type": "string",
132
+ "description": "Who judged the thing was in the hands. A NAME, never a rubric. The stop-criterion of practice is felt — reachable without conscious effort — and formalizing it would turn this into a gig. Absent means the session is still open."
133
+ },
134
+ "still_open": {
135
+ "type": "array",
136
+ "items": {
137
+ "type": "string"
138
+ },
139
+ "description": "What was not resolved. Required and may be empty, on the same argument as a verdict's inferred_not_run: an absent list is a claim that nothing was left open."
140
+ }
141
+ }
142
+ },
143
+ "required_fields": [
144
+ "question",
145
+ "iterations",
146
+ "corrections",
147
+ "still_open"
148
+ ]
149
+ }
@@ -0,0 +1,7 @@
1
+ {
2
+ "slug": "gist-present",
3
+ "domain": "demo",
4
+ "on_type": "summary",
5
+ "non_empty_fields": ["gist"],
6
+ "asserts": "the summary output has a non-empty gist field"
7
+ }
@@ -24,7 +24,7 @@
24
24
  "deontic": "permitted",
25
25
  "aim": "open a pull request proposing a change to the institution's main line",
26
26
  "conditions": "the change is committed on a non-main branch and its local verify passed",
27
- "or_else": "not applicable a permission, not an obligation",
27
+ "or_else": "not applicable \u2014 a permission, not an obligation",
28
28
  "check": {
29
29
  "predicate": "(=> (and (is-agent actor) (= action \"open-pr\") (not (= source \"main\"))) allow)",
30
30
  "inputs": {
@@ -55,7 +55,7 @@
55
55
  "deontic": "permitted",
56
56
  "aim": "stand deliberately red between the spec merge and the implementation merge on a change-set branch, off the protected line",
57
57
  "conditions": "while the target branch is a change-set branch and is not the protected main line",
58
- "or_else": "not applicable a permission, not an obligation",
58
+ "or_else": "not applicable \u2014 a permission, not an obligation",
59
59
  "check": {
60
60
  "predicate": "(=> (not (= target_branch \"main\")) allow)",
61
61
  "inputs": {
@@ -63,6 +63,54 @@
63
63
  }
64
64
  },
65
65
  "content_hash": "sha256:f465a9f3e76a5288dd993ef1b8228993feea04a47af8f3c99462cc4edcb238a5"
66
+ },
67
+ {
68
+ "attributes": "any seated agent performing a coltrane-shaped operation \u2014 composing a standard, writing a typed output, defining an agent, registering a type",
69
+ "deontic": "forbidden",
70
+ "aim": "perform a coltrane-shaped operation through a built-in file or search surface instead of the MCP surface",
71
+ "conditions": "whenever the operation has a coltrane tool that performs it; reading source and editing engine TypeScript are not coltrane-shaped and are unaffected",
72
+ "or_else": "the operation is not seen by the genome \u2014 the work does not enter the genome: no content_sha is sealed, no ledger entry is written, no hash updates, so the change is unrecorded however correct its bytes are. Where the seat holds no such grant the surface is absent and the bypass cannot arise; where it does, this is what follows.",
73
+ "check": {
74
+ "predicate": "(=> (and (is-agent actor) (= operation \"coltrane-shaped\") (not (= surface \"mcp\"))) deny)",
75
+ "inputs": {
76
+ "actor": "principal",
77
+ "operation": "operation-kind",
78
+ "surface": "tool-surface"
79
+ }
80
+ },
81
+ "content_hash": "sha256:b3f747e6039cdc1224a39fc0509e4b46f5c2b75c2e8feec2b3459b85a4cc762a"
82
+ },
83
+ {
84
+ "attributes": "any seated agent",
85
+ "deontic": "forbidden",
86
+ "aim": "write to core_types/ or domain_types/ directly instead of using type_register or type_extend",
87
+ "conditions": "at all times",
88
+ "or_else": "the type is not registered \u2014 the work does not enter the genome: no content_sha is sealed, no ledger entry is written, no hash updates, so the change is unrecorded however correct its bytes are. Where the seat holds no such grant the surface is absent and the bypass cannot arise; where it does, this is what follows.",
89
+ "check": {
90
+ "predicate": "(=> (and (is-agent actor) (= action \"direct-write\") (= target \"type-dir\")) deny)",
91
+ "inputs": {
92
+ "actor": "principal",
93
+ "action": "action-kind",
94
+ "target": "write-target"
95
+ }
96
+ },
97
+ "content_hash": "sha256:d1370d7b356ab529da71576f390d712a3896a85c89a2b9a8300cb729ab99f1ca"
98
+ },
99
+ {
100
+ "attributes": "any seated agent adding an agent definition to the genome",
101
+ "deontic": "forbidden",
102
+ "aim": "add an agent DEFINITION by dropping a file under agents/ instead of using agent_define",
103
+ "conditions": "for the genome agent-definition surface (agents/*.json). NOT the base-player surface: CLAUDE.md ships Claude Code subagents as markdown under agents/players/<name>.md, and those are files by design \u2014 a law that forbade them would forbid the shipped arrangement.",
104
+ "or_else": "the agent is not defined \u2014 the work does not enter the genome: no content_sha is sealed, no ledger entry is written, no hash updates, so the change is unrecorded however correct its bytes are. Where the seat holds no such grant the surface is absent and the bypass cannot arise; where it does, this is what follows.",
105
+ "check": {
106
+ "predicate": "(=> (and (is-agent actor) (= action \"file-drop\") (= target \"agent-definition\")) deny)",
107
+ "inputs": {
108
+ "actor": "principal",
109
+ "action": "action-kind",
110
+ "target": "write-target"
111
+ }
112
+ },
113
+ "content_hash": "sha256:cc778a9b25e6914cf9c8e70d63539dd7563f3be8c3c7b4f6a693de5bae5496f2"
66
114
  }
67
115
  ],
68
116
  "sovereign": true,
@@ -72,7 +120,7 @@
72
120
  {
73
121
  "slug": "eir-labs",
74
122
  "name": "Eir Labs",
75
- "charter": "The organization that develops Coltrane through Coltrane's own governed pipeline. Its charter is to carry every change to the engine and its genome through a reviewed pull request a human governor merges on green continuous integration never a direct write to the protected main line. It ships no capability it has not been granted and lands no change its checks have not passed.",
123
+ "charter": "The organization that develops Coltrane through Coltrane's own governed pipeline. Its charter is to carry every change to the engine and its genome through a reviewed pull request a human governor merges on green continuous integration \u2014 never a direct write to the protected main line. It ships no capability it has not been granted and lands no change its checks have not passed.",
76
124
  "parent_org": null
77
125
  }
78
126
  ],
@@ -86,6 +134,16 @@
86
134
  "status": "active",
87
135
  "named_from_forebear": null,
88
136
  "auth_user_id": null
137
+ },
138
+ {
139
+ "slug": "bandleader",
140
+ "name": "Bandleader",
141
+ "kind": "steve",
142
+ "is_institution": false,
143
+ "skill_slugs": [],
144
+ "status": "named",
145
+ "named_from_forebear": "blakey-art",
146
+ "auth_user_id": null
89
147
  }
90
148
  ],
91
149
  "org_members": [
@@ -132,7 +190,7 @@
132
190
  "role": "human-governor",
133
191
  "human": true,
134
192
  "function": "JUDGE",
135
- "mission": "Hold the merge authority for Coltrane's protected main line. This chair is held by a person, never a model agent: the governor reviews an open pull request and its continuous-integration result and merges it under their own name, or refuses it. Nothing lands on main without this office's yes. The office ships unassigned the adopting organization seats a person here as its first governance act.",
193
+ "mission": "Hold the merge authority for Coltrane's protected main line. This chair is held by a person, never a model agent: the governor reviews an open pull request and its continuous-integration result and merges it under their own name, or refuses it. Nothing lands on main without this office's yes. The office ships unassigned \u2014 the adopting organization seats a person here as its first governance act.",
136
194
  "required_skills": [],
137
195
  "caps": [],
138
196
  "obligations": [
@@ -161,6 +219,120 @@
161
219
  "witnessed_by": null
162
220
  }
163
221
  ],
164
- "forebears": [],
165
- "lineage_edges": []
222
+ "forebears": [
223
+ {
224
+ "slug": "crawford-ostrom-adico",
225
+ "institution_slug": "coltrane",
226
+ "name": "Crawford, S.E.S. & Ostrom, E. (1995), \"A Grammar of Institutions\"",
227
+ "domain": "institutional analysis",
228
+ "kind": "work",
229
+ "what_taken": "The ADICO grammar \u2014 Attribute, Deontic, aIm, Condition, Or-else \u2014 which InstitutionalLawSchema takes as the shape of a law. Cited with a DOI at src/genome_schema.ts:356, the tree's one explicit \"Descends from\" declaration."
230
+ },
231
+ {
232
+ "slug": "makinson-vandertorre-io-logic",
233
+ "institution_slug": "coltrane",
234
+ "name": "Makinson, D. & van der Torre, L. (2000), \"Input/Output Logics\"",
235
+ "domain": "deontic logic",
236
+ "kind": "work",
237
+ "what_taken": "The obligation as a norm-PAIR (condition, consequent) rather than a modal operator over a proposition \u2014 why a law here carries a predicate and an or_else instead of a truth value."
238
+ },
239
+ {
240
+ "slug": "xacml-3-decision-model",
241
+ "institution_slug": "coltrane",
242
+ "name": "OASIS eXtensible Access Control Markup Language (XACML) 3.0",
243
+ "domain": "access control",
244
+ "kind": "work",
245
+ "what_taken": "The multi-verdict decision algebra \u2014 permit / deny / not-applicable / indeterminate \u2014 that the admissibility result descends from, rather than a boolean. Named in the schema prose WITHOUT a locator: attestation, not archive."
246
+ },
247
+ {
248
+ "slug": "gasb-54-encumbrance",
249
+ "institution_slug": "coltrane",
250
+ "name": "GASB Statement No. 54, Fund Balance Reporting and Governmental Fund Type Definitions",
251
+ "domain": "governmental accounting",
252
+ "kind": "work",
253
+ "what_taken": "The encumbrance \u2014 a commitment recorded between an appropriation ceiling and an expenditure \u2014 which the committed-work objects (Tour / Booking / Resource) take as the binding middle place. Named in docs/specs/the-binding-middle-place.md WITHOUT a locator: attestation, not archive."
254
+ },
255
+ {
256
+ "slug": "blakey-art",
257
+ "institution_slug": "coltrane",
258
+ "name": "Art Blakey",
259
+ "domain": "modern jazz (drums, bandleading)",
260
+ "kind": "musician",
261
+ "what_taken": "Born 11 October 1919 in Pittsburgh, Pennsylvania; died 16 October 1990 in New York City (Scott DeVeaux/Gary Giddins record the dates; the American National Biography entry is titled \"Blakey, Art (1919-1990), jazz drummer and bandleader\", doi:10.1093/anb/9780198606697.article.1802592, retrieved 2026-08-20). What the BANDLEADER chair takes is the documented practice of running a band as an INSTITUTION THAT OUTLIVES ITS PLAYERS. From 1954 until his death Blakey led the Jazz Messengers through roughly two dozen lineups, seating young players, developing them, and releasing them onward \u2014 Horace Silver, Clifford Brown, Lee Morgan, Wayne Shorter, Freddie Hubbard, Keith Jarrett, Wynton Marsalis among them \u2014 while the band itself persisted as the durable thing. The disposition the chair takes is that of the seat rather than the incumbent: the leader calls the tune, counts it off, seats the players, judges the take, and stops the band when it is wrong, and does not play the horn. Grove Music Online's entry (Lewis Porter, 2003, doi:10.1093/gmo/9781561592630.article.j046400, retrieved 2026-08-20) records the Messengers as the defining vehicle of that practice. Nothing of the man's biography beyond this working disposition is claimed or carried."
262
+ }
263
+ ],
264
+ "lineage_edges": [
265
+ {
266
+ "institution_slug": "coltrane",
267
+ "edge_type": "descends-from",
268
+ "from_node": "law:coltrane",
269
+ "to_node": "forebear:crawford-ostrom-adico",
270
+ "kind": "attribution",
271
+ "source": {
272
+ "doi": "10.2307/2082975",
273
+ "evidence_grade": "attestation",
274
+ "locator": "src/genome_schema.ts:356",
275
+ "note": "cited in the genome source; the primary was not fetched in this run, so the grade is attestation and not archive"
276
+ }
277
+ },
278
+ {
279
+ "institution_slug": "coltrane",
280
+ "edge_type": "descends-from",
281
+ "from_node": "law:coltrane",
282
+ "to_node": "forebear:makinson-vandertorre-io-logic",
283
+ "kind": "attribution",
284
+ "source": {
285
+ "doi": "10.1023/A:1004748624537",
286
+ "evidence_grade": "attestation",
287
+ "locator": "src/genome_schema.ts (InstitutionalLawSchema)",
288
+ "note": "cited in the genome source; the primary was not fetched in this run, so the grade is attestation and not archive"
289
+ }
290
+ },
291
+ {
292
+ "institution_slug": "coltrane",
293
+ "edge_type": "descends-from",
294
+ "from_node": "type:admissibility-result",
295
+ "to_node": "forebear:xacml-3-decision-model",
296
+ "kind": "attribution",
297
+ "source": {
298
+ "evidence_grade": "attestation",
299
+ "locator": "src/genome_schema.ts (AdmissibilityResult)",
300
+ "note": "named in prose without a doi or url. Under system.coltrane.institutional-model the citation rule refuses a citation carrying neither \u2014 recorded here as an attestation so the gap is visible, never laundered upward to archive"
301
+ }
302
+ },
303
+ {
304
+ "institution_slug": "coltrane",
305
+ "edge_type": "descends-from",
306
+ "from_node": "type:tour",
307
+ "to_node": "forebear:gasb-54-encumbrance",
308
+ "kind": "attribution",
309
+ "source": {
310
+ "evidence_grade": "attestation",
311
+ "locator": "docs/specs/the-binding-middle-place.md",
312
+ "note": "named in prose without a doi or url. Under system.coltrane.institutional-model the citation rule refuses a citation carrying neither \u2014 recorded here as an attestation so the gap is visible, never laundered upward to archive"
313
+ }
314
+ },
315
+ {
316
+ "institution_slug": "coltrane",
317
+ "edge_type": "descends-from",
318
+ "from_node": "agent:bandleader",
319
+ "to_node": "forebear:blakey-art",
320
+ "kind": "attribution",
321
+ "source": {
322
+ "figure": "Art Blakey",
323
+ "lifespan": "11 October 1919 - 16 October 1990",
324
+ "recordings": [
325
+ "A Night at Birdland (Blue Note BLP 5037/5038, recorded 21 February 1954)",
326
+ "Moanin' (Blue Note BLP 4003, recorded 30 October 1958)"
327
+ ],
328
+ "reference_works": [
329
+ "American National Biography, \"Blakey, Art (1919-1990), jazz drummer and bandleader\", doi:10.1093/anb/9780198606697.article.1802592 (retrieved 2026-08-20)",
330
+ "Grove Music Online, Lewis Porter, \"Blakey, Art (jazz)\", doi:10.1093/gmo/9781561592630.article.j046400 (retrieved 2026-08-20)"
331
+ ],
332
+ "attributed_disposition": "running a band as an institution that outlives its players: seating them, developing them, releasing them onward across roughly two dozen Jazz Messengers lineups from 1954 to 1990, while the band itself persisted as the durable thing. The seat calls the tune, judges the take and stops the band; it does not play.",
333
+ "evidence_grade": "attestation",
334
+ "note": "The two reference-work DOIs were dereferenced through api.crossref.org on 2026-08-20 and returned matching author, year and title. The recording details are carried from the standard Blue Note discography and were NOT independently dereferenced, so this edge is graded attestation rather than archive."
335
+ }
336
+ }
337
+ ]
166
338
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@eir-labs/coltrane",
3
- "version": "0.9.4",
4
- "description": "A methodology engine a typed substrate for defining agents, composing multi-phase standards, dispatching gigs, and sealing every output to a content-addressed ledger. Ships as an MCP server.",
3
+ "version": "0.11.0",
4
+ "description": "A methodology engine \u2014 a typed substrate for defining agents, composing multi-phase standards, dispatching gigs, and sealing every output to a content-addressed ledger. Ships as an MCP server.",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",
7
7
  "author": "Eir",
@@ -63,6 +63,8 @@
63
63
  "domain_types",
64
64
  "core_types",
65
65
  "institutions",
66
+ "tours",
67
+ "evals",
66
68
  "README.md",
67
69
  "LICENSE"
68
70
  ],
@@ -76,12 +78,13 @@
76
78
  "test": "vitest run",
77
79
  "test:watch": "vitest",
78
80
  "typecheck": "tsc --noEmit",
79
- "verify": "tsc --noEmit && vitest run && npm run test:failure-modes && npm run test:honest-broker && npm run test:security && npm run e2e:offline",
81
+ "verify": "tsc --noEmit && vitest run && npm run test:failure-modes && npm run test:honest-broker && npm run test:security && npm run e2e:offline && npm run test:room",
80
82
  "e2e": "npm run build && vitest run --config tests/e2e/vitest.config.ts",
81
83
  "e2e:offline": "npm run build && vitest run --config tests/e2e/vitest.offline.config.ts",
82
84
  "test:failure-modes": "vitest run --config tests/failure_modes/vitest.config.ts",
83
85
  "test:honest-broker": "vitest run --config tests/honest_broker/vitest.config.ts",
84
86
  "test:security": "vitest run --config tests/security/vitest.config.ts",
87
+ "test:room": "vitest run --config tests/venue_live/vitest.config.ts",
85
88
  "lint:imports": "git ls-files 'src/**/*.ts' 'src/**/*.tsx' 'src/**/*.js' 'src/**/*.mjs' 'src/**/*.cjs' 'tests/**/*.ts' 'tests/**/*.tsx' 'tests/**/*.js' 'tests/**/*.mjs' 'tests/**/*.cjs' | bash scripts/check_imports.sh"
86
89
  },
87
90
  "dependencies": {
@@ -0,0 +1,17 @@
1
+ {
2
+ "id": "finds-the-known-hollow",
3
+ "description": "Non-vacuity of the probe ITSELF: run it against a file known to contain all-negative laws and it must find them. A probe that returns a clean verdict on a hollow suite is the defect it exists to detect, one level up.",
4
+ "input": {
5
+ "path": "tests/spec_venue_realization_substrate.test.ts"
6
+ },
7
+ "assertions": [
8
+ {
9
+ "path": "total_laws",
10
+ "op": "is_number"
11
+ },
12
+ {
13
+ "path": "hollow_count",
14
+ "op": "is_number"
15
+ }
16
+ ]
17
+ }
@@ -0,0 +1,12 @@
1
+ {
2
+ "slug": "non-vacuity-probe",
3
+ "version": 1,
4
+ "skill_type": "verification",
5
+ "input_type": "test-target",
6
+ "output_type": "test-verdict",
7
+ "determinism_ratio": 0.85,
8
+ "permission": {
9
+ "tier": 0
10
+ },
11
+ "description": "Ask whether a suite of laws can be fooled by an implementation that produces NOTHING. Earned, not theorised: a committed suite of 40 laws governing what a generated configuration must never contain was measured against a function returning an empty object, and 32 passed — including every one of the six laws its own specification called the sharpest. Every assertion was real; the thing they asserted about was absent. Two hollow-passable shapes, and this finds both: a law whose assertions are ALL negative, since an absence over an empty document is satisfied by producing nothing; and an assertion INSIDE a loop over a discovered collection with no non-empty guard, since an empty collection runs the body zero times and reports a pass having examined nothing. The second is the one that hides. The code half counts; the model half is consulted only for remedies and for borderline calls, which is why the iterables are always reported rather than only a classification."
12
+ }
@@ -0,0 +1,27 @@
1
+ # Non-vacuity probe
2
+
3
+ A green suite is evidence only if it could have gone red. Before trusting one, try to fool it.
4
+
5
+ ## The measurement that produced this
6
+
7
+ A committed suite of 40 laws pinned what a generated container configuration must never contain — no runtime socket, no host networking, no host PID namespace, no privileged flag, no added capabilities, no underived mount. Each was its own law with a real assertion. The suite was green.
8
+
9
+ Replacing the function that generates the configuration with one returning `{}` left **32 of the 40 still passing**, including all six escape laws.
10
+
11
+ Nothing was faked. Every assertion ran. They asserted absences over a document that did not exist.
12
+
13
+ ## The two shapes
14
+
15
+ **All-negative laws.** A law whose every assertion is `.not.*` is satisfied by producing nothing at all. The fix is a presence anchor in the same block: establish that the thing being examined exists, *then* ask what is missing from it. Anchor structurally — a rendered document has services and the room is one of them — not on an incidental string.
16
+
17
+ **Loop assertions with no guard.** The sharper one, because it hides. An assertion inside a `for` over a discovered collection never executes when the collection is empty, and the law reports a pass having examined nothing. Assert the collection is non-empty first.
18
+
19
+ ## Reading the output
20
+
21
+ `hollow_passable` is a classification and `iterables` is the evidence. Check the evidence. A loop over an inline array or a SCREAMING_CASE fixture is statically non-empty and safe; a loop over a `matchAll`, a `filter`, or a variable assigned from a call is not. The probe exempts the first two and reports what it iterated either way, so a borderline call is settled by looking rather than by trusting.
22
+
23
+ ## Use it on a suite you believe is correct
24
+
25
+ That is the point of it. This probe was itself wrong five times — it counted only in-block assertions and missed anchors reached through helpers; its guard window was too narrow to clear a sentence-length assertion message; it counted literal loops with a non-global regex. Each version was found by running it against laws that were already right and reading every hit.
26
+
27
+ A tool with a high false-positive rate is worse than no tool, because it teaches the reader to skip it — which is how the original vacuity survived a whole specification cycle.
@@ -0,0 +1,81 @@
1
+ import { readFileSync } from "node:fs";
2
+
3
+ const POSITIVE = /\.(toContain|toBe|toEqual|toMatch|toThrow|toBeTruthy|toBeDefined|toBeInstanceOf|toBeTypeOf|toBeGreaterThan|toBeGreaterThanOrEqual|toBeLessThan|toHaveLength|toHaveProperty)\b/;
4
+ const NEGATIVE = /\.not\./;
5
+ // The window must clear an assertion MESSAGE, which in a well-commented suite is a full sentence.
6
+ // A 60-char window missed a guard that was actually there — a false positive on an already-fixed
7
+ // law, which is the worst kind for a tool meant to be trusted.
8
+ const NONEMPTY = /\.length\b[\s\S]{0,400}?(toBeGreaterThan|toBeGreaterThanOrEqual)|not\.toHaveLength\(\s*0\s*\)|toHaveLength\(\s*[1-9]|\.length\s*[>!]==?\s*0/;
9
+ // A loop over an INLINE ARRAY or a SCREAMING_CASE fixture cannot run zero times, so it is not a
10
+ // vacuity risk. Only a DISCOVERED collection is. Both GLOBAL: a law may hold several statically
11
+ // safe loops, and a non-global match counts at most one.
12
+ const LITERAL_LOOP = /\bfor\s*\((?:const|let|var)\s+\w+\s+of\s*\[/g;
13
+ const FIXTURE_LOOP = /\bfor\s*\((?:const|let|var)\s+\w+\s+of\s+[A-Z][A-Z0-9_]*\b/g;
14
+
15
+ // A law may anchor through a HELPER rather than inline — `const doc = await rendered();` where
16
+ // `rendered()` asserts the document exists. Counting only in-block assertions marks every such law
17
+ // a false positive, and ten false positives train a reader to ignore the tool.
18
+ function anchoringHelpers(src) {
19
+ const names = new Set();
20
+ const re = /(?:const|function)\s+([A-Za-z_$][\w$]*)\s*(?:=|\()/g;
21
+ let m;
22
+ while ((m = re.exec(src))) {
23
+ const slice = src.slice(m.index, m.index + 1400);
24
+ const end = slice.search(/\n(?:const|function|describe|it)\b/);
25
+ const body = end > 0 ? slice.slice(0, end) : slice;
26
+ if (POSITIVE.test(body) && /expect\(/.test(body)) names.add(m[1]);
27
+ }
28
+ return names;
29
+ }
30
+
31
+ export default function run(input) {
32
+ const path = input && input.path ? String(input.path) : "";
33
+ let src = "";
34
+ try { src = readFileSync(path, "utf-8"); }
35
+ catch { return { laws: [], total_laws: 0, hollow_count: 0, error: `cannot read ${path}` }; }
36
+
37
+ const helpers = anchoringHelpers(src);
38
+ const helperCall = helpers.size ? new RegExp("\\b(" + [...helpers].join("|") + ")\\s*\\(") : null;
39
+
40
+ const laws = [];
41
+ let cur = null;
42
+ for (const line of src.split("\n")) {
43
+ const m = line.match(/\bit\(\s*["'`](.+?)["'`]/);
44
+ if (m) { if (cur) laws.push(finish(cur)); cur = { name: m[1], positive: 0, negative: 0, body: [] }; continue; }
45
+ if (!cur) continue;
46
+ cur.body.push(line);
47
+ if (helperCall && helperCall.test(line)) cur.positive++;
48
+ if (/expect\(/.test(line) || /\.(to[A-Z])/.test(line)) {
49
+ if (NEGATIVE.test(line)) cur.negative++;
50
+ else if (POSITIVE.test(line)) cur.positive++;
51
+ }
52
+ }
53
+ if (cur) laws.push(finish(cur));
54
+
55
+ const hollow = laws.filter((l) => l.hollow_passable);
56
+ return {
57
+ path,
58
+ laws,
59
+ total_laws: laws.length,
60
+ hollow_count: hollow.length,
61
+ verdict: hollow.length === 0
62
+ ? "no law in this file is satisfied by an implementation that produces nothing"
63
+ : `${hollow.length} of ${laws.length} laws pass against an implementation that produces nothing`,
64
+ };
65
+ }
66
+
67
+ function finish(l) {
68
+ const text = l.body.join("\n");
69
+ const loops = (text.match(/\bfor\s*\(|\.forEach\(/g) || []).length;
70
+ const safe = (text.match(LITERAL_LOOP) || []).length + (text.match(FIXTURE_LOOP) || []).length;
71
+ const loop = loops > safe;
72
+ const guard = NONEMPTY.test(text);
73
+ const iterables = (text.match(/\bfor\s*\((?:const|let|var)\s+\w+\s+of\s+([^)]{0,48})/g) || [])
74
+ .map((x) => x.replace(/^.*\bof\s+/, "").trim());
75
+ const reasons = [];
76
+ if (l.positive === 0 && l.negative > 0) reasons.push("all assertions are negative — an absence over nothing is satisfied");
77
+ if (loop && !guard) reasons.push("assertion inside a loop with no non-empty guard — an empty collection examines nothing");
78
+ // Always report what it iterates, so a reader settles a borderline call in one glance instead of
79
+ // trusting the classifier.
80
+ return { name: l.name, positive: l.positive, negative: l.negative, iterables, hollow_passable: reasons.length > 0, why: reasons.join("; ") || null };
81
+ }
@@ -0,0 +1,37 @@
1
+ {
2
+ "slug": "lineage-adopt-v0",
3
+ "domain": "lineage",
4
+ "status": "active",
5
+ "description": "A LINEAGE ADOPTION brings an already-composed lineage-record to a human seat and nowhere else. It runs no scout, draws no edge, and composes nothing: its single chair is the approval office, seeded directly with the record under review. It exists because the approve office was reachable only as the tail of lineage-pass-v1, which meant a record composed by any other route could never be promoted. lineage-reweave-v0 is exactly that route \u2014 it re-draws the synthesis over reused and deepened seeds and seals a lineage-record with no human chair anywhere in its phase graph, so the strongest record a lineage effort produces was structurally unadoptable. A composition standard should not have to carry an approval office to make its output signable, and an approval office should not have to re-run a synthesis to reach a record. This standard is that seam, held once.",
6
+ "agent_slugs": [],
7
+ "phases": [
8
+ {
9
+ "name": "approve",
10
+ "chairs": [
11
+ {
12
+ "role": "approve",
13
+ "agent_slug": "",
14
+ "human": true,
15
+ "depends_on": [],
16
+ "input_contract": [
17
+ "lineage-record",
18
+ "lineage-adoption-target"
19
+ ],
20
+ "output_contract": [
21
+ "lineage-verdict"
22
+ ],
23
+ "optional_outputs": [],
24
+ "required_skills": []
25
+ }
26
+ ],
27
+ "intent": "A human approval office, and the only seat in this standard. The incumbent reviews the seeded lineage-record and either seals a passing lineage-verdict \u2014 which is what promotes the record to first-class lineage attached to an institution \u2014 or refuses it. An ENTRY chair (depends_on []): the record is supplied by the dispatch payload rather than produced upstream, which is the whole point \u2014 a record composed anywhere, by a pass or by a reweave, can be brought here without re-running the work that made it. The chair is seeded with BOTH the record under review and the adoption target naming which institution it would ground \u2014 the attachment is a property of this act, not of the record or the verdict, so it arrives here and nowhere else. A run that reaches this office unapproved PARKS awaiting the seal; nothing is adopted on an absent yes, and a refusal is a decision that gets recorded rather than a silence that gets forgotten."
28
+ }
29
+ ],
30
+ "input_types": [
31
+ "lineage-record",
32
+ "lineage-adoption-target"
33
+ ],
34
+ "output_types": [
35
+ "lineage-verdict"
36
+ ]
37
+ }