@cratylus/canon 0.18.0 → 0.20.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 (190) hide show
  1. package/README.md +60 -58
  2. package/dist/agents/kino.js +1 -1
  3. package/dist/agents/kino.js.map +1 -1
  4. package/dist/agents/mav.js +1 -1
  5. package/dist/agents/mav.js.map +1 -1
  6. package/dist/agents/nico.js +1 -1
  7. package/dist/agents/nico.js.map +1 -1
  8. package/dist/compose.d.ts +4 -4
  9. package/dist/compose.js +14 -16
  10. package/dist/compose.js.map +1 -1
  11. package/dist/contracts.js +15 -15
  12. package/dist/contracts.js.map +1 -1
  13. package/dist/dimensions/action-scope/integrate.js +1 -1
  14. package/dist/dimensions/action-scope/integrate.js.map +1 -1
  15. package/dist/dimensions/assignment/concepts.js +1 -1
  16. package/dist/dimensions/assignment/concepts.js.map +1 -1
  17. package/dist/dimensions/assignment/review-request.js +1 -1
  18. package/dist/dimensions/assignment/review-request.js.map +1 -1
  19. package/dist/dimensions/assignment/task.js +1 -1
  20. package/dist/dimensions/assignment/task.js.map +1 -1
  21. package/dist/dimensions/assignment/{story.d.ts → user-story.d.ts} +1 -1
  22. package/dist/dimensions/assignment/user-story.js +2 -0
  23. package/dist/dimensions/assignment/user-story.js.map +1 -0
  24. package/dist/dimensions/autonomy/management-by-exception.d.ts +2 -0
  25. package/dist/dimensions/autonomy/management-by-exception.js +2 -0
  26. package/dist/dimensions/autonomy/management-by-exception.js.map +1 -0
  27. package/dist/dimensions/communication-style/bottom-line-up-front.js +1 -1
  28. package/dist/dimensions/communication-style/bottom-line-up-front.js.map +1 -1
  29. package/dist/dimensions/communication-style/layman.js +1 -1
  30. package/dist/dimensions/communication-style/layman.js.map +1 -1
  31. package/dist/dimensions/deliverable/{review.d.ts → code-review.d.ts} +1 -1
  32. package/dist/dimensions/deliverable/code-review.js +2 -0
  33. package/dist/dimensions/deliverable/code-review.js.map +1 -0
  34. package/dist/dimensions/deliverable/outcome.js +1 -1
  35. package/dist/dimensions/deliverable/outcome.js.map +1 -1
  36. package/dist/dimensions/deliverable/read-back.js +1 -1
  37. package/dist/dimensions/deliverable/read-back.js.map +1 -1
  38. package/dist/dimensions/expertise/evaluation-design.js +1 -1
  39. package/dist/dimensions/expertise/evaluation-design.js.map +1 -1
  40. package/dist/dimensions/expertise/semantic-addressing.js +1 -1
  41. package/dist/dimensions/expertise/semantic-addressing.js.map +1 -1
  42. package/dist/dimensions/guardrails/append-only.js +1 -1
  43. package/dist/dimensions/guardrails/append-only.js.map +1 -1
  44. package/dist/dimensions/guardrails/fixed-acceptance-criteria.js +1 -1
  45. package/dist/dimensions/guardrails/fixed-acceptance-criteria.js.map +1 -1
  46. package/dist/dimensions/guardrails/honesty.js +1 -1
  47. package/dist/dimensions/guardrails/honesty.js.map +1 -1
  48. package/dist/dimensions/guardrails/input-untrusted.js +1 -1
  49. package/dist/dimensions/guardrails/input-untrusted.js.map +1 -1
  50. package/dist/dimensions/guardrails/never-repairs.js +1 -1
  51. package/dist/dimensions/guardrails/never-repairs.js.map +1 -1
  52. package/dist/dimensions/guardrails/no-implementation.js +1 -1
  53. package/dist/dimensions/guardrails/no-implementation.js.map +1 -1
  54. package/dist/dimensions/guardrails/privacy.js +1 -1
  55. package/dist/dimensions/guardrails/privacy.js.map +1 -1
  56. package/dist/dimensions/memory/reconstitution.js +1 -1
  57. package/dist/dimensions/memory/reconstitution.js.map +1 -1
  58. package/dist/dimensions/memory/source-of-truth.js +1 -1
  59. package/dist/dimensions/memory/source-of-truth.js.map +1 -1
  60. package/dist/dimensions/model/frontier-other-family.js +1 -1
  61. package/dist/dimensions/model/frontier-other-family.js.map +1 -1
  62. package/dist/dimensions/objective/conceptual-integrity.js +1 -1
  63. package/dist/dimensions/objective/conceptual-integrity.js.map +1 -1
  64. package/dist/dimensions/objective/delivery.js +1 -1
  65. package/dist/dimensions/objective/delivery.js.map +1 -1
  66. package/dist/dimensions/objective/review-accuracy.js +1 -1
  67. package/dist/dimensions/objective/review-accuracy.js.map +1 -1
  68. package/dist/dimensions/perception-scope/concept-journal.js +1 -1
  69. package/dist/dimensions/perception-scope/concept-journal.js.map +1 -1
  70. package/dist/dimensions/perception-scope/held-out-examples.js +1 -1
  71. package/dist/dimensions/perception-scope/held-out-examples.js.map +1 -1
  72. package/dist/dimensions/perception-scope/own-task.js +1 -1
  73. package/dist/dimensions/perception-scope/own-task.js.map +1 -1
  74. package/dist/dimensions/perception-scope/{work.d.ts → work-product.d.ts} +1 -1
  75. package/dist/dimensions/perception-scope/work-product.js +2 -0
  76. package/dist/dimensions/perception-scope/work-product.js.map +1 -0
  77. package/dist/dimensions/procedure/code-review.js +1 -1
  78. package/dist/dimensions/procedure/code-review.js.map +1 -1
  79. package/dist/dimensions/procedure/orchestrator-workers.js +1 -1
  80. package/dist/dimensions/procedure/orchestrator-workers.js.map +1 -1
  81. package/dist/dimensions/procedure/reconstitution.js +1 -1
  82. package/dist/dimensions/procedure/reconstitution.js.map +1 -1
  83. package/dist/dimensions/procedure/ship-show-ask.js +1 -1
  84. package/dist/dimensions/procedure/ship-show-ask.js.map +1 -1
  85. package/dist/dimensions/role/architect.js +1 -1
  86. package/dist/dimensions/role/architect.js.map +1 -1
  87. package/dist/dimensions/role/builder.js +1 -1
  88. package/dist/dimensions/role/builder.js.map +1 -1
  89. package/dist/dimensions/role/check-writer.js +1 -1
  90. package/dist/dimensions/role/check-writer.js.map +1 -1
  91. package/dist/dimensions/role/illustrator.js +1 -1
  92. package/dist/dimensions/role/illustrator.js.map +1 -1
  93. package/dist/dimensions/role/lead.js +1 -1
  94. package/dist/dimensions/role/lead.js.map +1 -1
  95. package/dist/dimensions/role/reviewer.js +1 -1
  96. package/dist/dimensions/role/reviewer.js.map +1 -1
  97. package/dist/dimensions/stance/cold-decode-oracle.js +1 -1
  98. package/dist/dimensions/stance/cold-decode-oracle.js.map +1 -1
  99. package/dist/dimensions/stance/conceptual-elevation.js +1 -1
  100. package/dist/dimensions/stance/conceptual-elevation.js.map +1 -1
  101. package/dist/dimensions/stance/decisive.js +1 -1
  102. package/dist/dimensions/stance/decisive.js.map +1 -1
  103. package/dist/dimensions/stance/{proportionate.d.ts → tailoring.d.ts} +1 -1
  104. package/dist/dimensions/stance/tailoring.js +2 -0
  105. package/dist/dimensions/stance/tailoring.js.map +1 -0
  106. package/dist/dimensions/stance/zero-trust.js +1 -1
  107. package/dist/dimensions/stance/zero-trust.js.map +1 -1
  108. package/dist/genus/prime-principle.d.ts +4 -3
  109. package/dist/genus/prime-principle.js +3 -2
  110. package/dist/genus/prime-principle.js.map +1 -1
  111. package/dist/index.d.ts +3 -3
  112. package/dist/index.js +10 -11
  113. package/dist/index.js.map +1 -1
  114. package/dist/manifest.d.ts +12 -12
  115. package/dist/manifest.js +20 -26
  116. package/dist/manifest.js.map +1 -1
  117. package/dist/operator-lexicon.d.ts +1 -12
  118. package/dist/operator-lexicon.js +3 -33
  119. package/dist/operator-lexicon.js.map +1 -1
  120. package/dist/practices.d.ts +1 -2
  121. package/dist/practices.js +2 -6
  122. package/dist/practices.js.map +1 -1
  123. package/dist/roles/architect.js +16 -34
  124. package/dist/roles/architect.js.map +1 -1
  125. package/dist/roles/builder.js +4 -4
  126. package/dist/roles/builder.js.map +1 -1
  127. package/dist/roles/check-writer.js +3 -3
  128. package/dist/roles/check-writer.js.map +1 -1
  129. package/dist/roles/illustrator.js +2 -2
  130. package/dist/roles/illustrator.js.map +1 -1
  131. package/dist/roles/lead.js +16 -22
  132. package/dist/roles/lead.js.map +1 -1
  133. package/dist/roles/reviewer.js +11 -10
  134. package/dist/roles/reviewer.js.map +1 -1
  135. package/dist/rules/commit-discipline.d.ts +3 -0
  136. package/dist/rules/commit-discipline.js +26 -0
  137. package/dist/rules/commit-discipline.js.map +1 -0
  138. package/dist/rules/conventional-commits.d.ts +3 -0
  139. package/dist/rules/conventional-commits.js +38 -0
  140. package/dist/rules/conventional-commits.js.map +1 -0
  141. package/dist/rules/established-libraries.d.ts +3 -0
  142. package/dist/rules/established-libraries.js +20 -0
  143. package/dist/rules/established-libraries.js.map +1 -0
  144. package/dist/rules/gitflow.d.ts +3 -0
  145. package/dist/rules/gitflow.js +32 -0
  146. package/dist/rules/gitflow.js.map +1 -0
  147. package/dist/rules/green-field.d.ts +3 -0
  148. package/dist/rules/green-field.js +20 -0
  149. package/dist/rules/green-field.js.map +1 -0
  150. package/dist/rulesets.d.ts +2 -0
  151. package/dist/rulesets.js +17 -0
  152. package/dist/rulesets.js.map +1 -0
  153. package/dist/skills/conceptualize/skill.js +2 -3
  154. package/dist/skills/conceptualize/skill.js.map +1 -1
  155. package/dist/skills/create-agent/skill.js +1 -1
  156. package/dist/skills/create-skill/skill.js +1 -1
  157. package/dist/skills/elicit/skill.js +2 -3
  158. package/dist/skills/elicit/skill.js.map +1 -1
  159. package/dist/skills/exemplify/skill.js +3 -4
  160. package/dist/skills/exemplify/skill.js.map +1 -1
  161. package/dist/skills/materialize/skill.js +2 -3
  162. package/dist/skills/materialize/skill.js.map +1 -1
  163. package/dist/skills/probe/skill.js +24 -25
  164. package/dist/skills/probe/skill.js.map +1 -1
  165. package/dist/skills/signify/skill.js +22 -21
  166. package/dist/skills/signify/skill.js.map +1 -1
  167. package/package.json +5 -6
  168. package/dist/dimensions/assignment/story.js +0 -2
  169. package/dist/dimensions/assignment/story.js.map +0 -1
  170. package/dist/dimensions/deliverable/review.js +0 -2
  171. package/dist/dimensions/deliverable/review.js.map +0 -1
  172. package/dist/dimensions/perception-scope/work.js +0 -2
  173. package/dist/dimensions/perception-scope/work.js.map +0 -1
  174. package/dist/dimensions/stance/proportionate.js +0 -2
  175. package/dist/dimensions/stance/proportionate.js.map +0 -1
  176. package/dist/genus/persona.d.ts +0 -8
  177. package/dist/genus/persona.js +0 -30
  178. package/dist/genus/persona.js.map +0 -1
  179. package/dist/hook-cells.d.ts +0 -3
  180. package/dist/hook-cells.js +0 -14
  181. package/dist/hook-cells.js.map +0 -1
  182. package/dist/hooks/deploy-drift-notice.d.ts +0 -2
  183. package/dist/hooks/deploy-drift-notice.js +0 -431
  184. package/dist/hooks/deploy-drift-notice.js.map +0 -1
  185. package/dist/rules/repo-preamble.d.ts +0 -2
  186. package/dist/rules/repo-preamble.js +0 -49
  187. package/dist/rules/repo-preamble.js.map +0 -1
  188. package/dist/skills/introspect/skill.d.ts +0 -2
  189. package/dist/skills/introspect/skill.js +0 -55
  190. package/dist/skills/introspect/skill.js.map +0 -1
@@ -1,431 +0,0 @@
1
- // deploy-drift-notice — the advisory that answers, before the agent acts, whether
2
- // the doctrine THIS HOST runs is the doctrine the corpus renders.
3
- //
4
- // THE INCIDENT. `~/.omp/agent/agents/<name>.md` and the render tree diverged. An agent
5
- // edited the corpus for a full session under a superseded first principle, and every
6
- // gate in the repository stayed green the entire time — because every gate that
7
- // existed was a claim about how a target is PRODUCED, and none was a claim about what
8
- // a host is RUNNING. The comparison that would have caught it landed with
9
- // `deploy --check`: reachable, correct, and speaking only when asked. A check that
10
- // must be remembered is a check that will be forgotten at exactly the moment it
11
- // matters — the session where the doctrine is already wrong. This cell is what asks.
12
- //
13
- // SILENCE WHEN CLEAN IS THE LOAD-BEARING HALF, not a courtesy. An advisory that fires
14
- // every session trains its reader to skip it, and a skipped advisory is worse than an
15
- // absent one: it occupies the slot where a real warning would have been read. So the
16
- // in-sync path emits nothing at all, and the cost of that path is what makes the
17
- // silence affordable (below).
18
- //
19
- // IT RELAYS A REPORT, IT DOES NOT COMPUTE ONE. `deploy --check` already produces the
20
- // only thing worth saying — per artifact, the rendered lines this host is MISSING and
21
- // the superseded lines it is STILL RUNNING. "3 files differ" does not tell an agent
22
- // its own first principle is stale; the axiom does. Recomputing any of that here would
23
- // put a second home under the one claim that must never fork, and the second home
24
- // would be a shell script.
25
- //
26
- // WHAT IT MAY NOT DO: refuse. `ARCHITECTURE`'s fidelity ladder — a shortfall degrades
27
- // and warns, it never refuses and never widens. A stale deployment must not block a
28
- // session; it must be impossible to start one without being told.
29
- //
30
- // IT ASKS AGAIN, BECAUSE THE HOST GOES STALE MID-SESSION. Bound to `session.start`
31
- // alone, the cell answered a question that expires: a projection landing during the
32
- // session it was authored in left the rest of that session running the superseded
33
- // copy with nothing further to say. That is not hypothetical and it is not rare —
34
- // it is the ORDINARY shape of work here, where a session edits a cell, projects it,
35
- // and keeps going under the version it just replaced. The 16-hour-old projection of
36
- // an agent's own governing cell was this; so was an authored skill edit that landed under a
37
- // running session hours later.
38
- //
39
- // `prompt.submit` IS THE RE-ARM, and it is the same question at a finer grain rather
40
- // than a second mechanism. Both moments put the notice before the agent acts on an
41
- // instruction, where the false premise can be corrected. `turn.end` is the wrong end
42
- // of the turn: it speaks after the acting is done. `file.edit.post` was rejected as
43
- // a category error — a cell EDIT is not drift; drift begins when the render tree moves,
44
- // which happens under a shell command.
45
- //
46
- // A RE-ARM IS ONLY AS GOOD AS ITS SILENCE, and this one is where the silence had to be
47
- // re-earned. Fired every prompt, an unchanged verdict would repeat the same advisory
48
- // until the reader stopped seeing it — the exact failure the in-sync path was built to
49
- // avoid, re-entering through the door held open for the fix. So the trigger is a CHANGE
50
- // in the verdict, never a verdict that is merely non-empty: the worker records the last
51
- // verdict this session was told (keyed by ⟨harness, session⟩, carrying ⟨corpus, tree⟩ so
52
- // the same session moved to another checkout asks a fresh question) and speaks only when
53
- // the new one differs. Said once, a standing drift is then silent until it changes or is
54
- // repaired. THE CLEAN VERDICT IS RECORDED TOO, and that is what makes a REAPPEARING drift
55
- // audible: without it, drift → deploy → the identical drift again would match the stale
56
- // record and say nothing.
57
- //
58
- // NO SESSION IDENTITY MEANS NO SUPPRESSION, deliberately, in that direction. When the
59
- // payload carries no usable `session_id` or the state cannot be written, every run
60
- // speaks. A repeated advisory under genuine drift is noise the operator can end with one
61
- // command; a suppressed one is silence, and this cell's own residue says silence is
62
- // borrowed from the in-sync path and may never be handed to any other.
63
- //
64
- // COST, MEASURED (2026-08-05, darwin/arm64, warm page cache, 39 rendered artifacts
65
- // against a deployed `.claude` of ~40 files):
66
- // clean path, end to end 45 ms (10 ms shell discovery + ~35 ms comparator)
67
- // drift path, end to end 60 ms (the report is longer, and is printed)
68
- //
69
- // RE-MEASURED after the three repairs above, and reported as an A/B rather than as a
70
- // new absolute, because an absolute is a claim about the rig as much as the worker.
71
- // Same corpus, same real deployment, best-of-7, the PREVIOUS worker and this one run
72
- // alternately in one session:
73
- // previous worker 56 ms clean · 58 ms drift
74
- // this worker 56 ms clean · 56 ms drift
75
- // The change is free, and the whole spread between 45 and 56 belongs to the harness
76
- // the numbers were taken through (a `sh` under a `bash` under a timestamping
77
- // `python3`), not to anything the worker does. It could not have been otherwise: the
78
- // three facts are SUBSTITUTED AT PROJECTION, so the resolved worker does the same
79
- // three variable assignments it always did, and the one thing that got cheaper is the
80
- // non-zero path, which no longer forks `printf | tail | grep` to recover a verdict.
81
- //
82
- // RE-MEASURED AGAIN for the re-arm, same rig, same A/B discipline (best-of-7, the two
83
- // workers run alternately; the clean leg against a fixture host deployed from this
84
- // corpus's own render tree, so it is a real in-sync verdict rather than an early exit):
85
- // previous worker 62 ms clean · 62 ms drift
86
- // this worker 60 ms clean · 64 ms drift
87
- // Per run it is free — the state costs one `cat` and one small write, which is under
88
- // this rig's noise. THE COST THAT ACTUALLY CHANGED IS FREQUENCY, and saying so is the
89
- // point of measuring: the hook now runs once per PROMPT rather than once per session,
90
- // so a 40-prompt session pays ~2.4 s of wall clock it did not pay before, spread across
91
- // 40 moments where the agent is already waiting on a model. That is the price of not
92
- // running superseded doctrine for the other 39 of them, and it is the trade this cell
93
- // exists to take. The per-run number is what keeps it payable, which is why the bound
94
- // is held by a test rather than remembered.
95
- //
96
- // A FULL BYTE COMPARISON of every rendered artifact is therefore what runs — no
97
- // digest, and above all NO SAMPLE. A sample that skips the ten skills carrying the
98
- // prime principle reports "in sync", which is the exact failure this cell exists to end. The
99
- // `deploy-drift-notice` suite re-measures the clean path and fails on a regression, so
100
- // the number above is a held bound rather than a remembered one.
101
- //
102
- // THE CELL NAMES A CAPABILITY, NOT A PATH, and it now ASKS for everything it used to
103
- // infer. TWO LAWS BIND A CELL. The first: a cell must not restate a location the
104
- // projector already computes. The harder companion: a cell must not GUESS what the
105
- // projector could have told it. Three guesses lived here and all three are gone:
106
- //
107
- // 1. THE COMPARATOR'S NAME was a shell literal, because the forge CLI's name had no
108
- // compile-time home the way `CLI_BIN` does. It has one now — derived, not
109
- // declared: `forge/src/bin-name.ts` reads the `bin` key npm itself obeys, so
110
- // there is one authored spelling in the package and the cell names the fact
111
- // (`deploy-bin`) rather than repeating it.
112
- // 2. THE HARNESS was assumed to be claude. The tree is still identified by SHAPE —
113
- // `--out` is an operator's choice and must never be assumed — but the shape it
114
- // matches is now THIS harness's, because the projector substitutes this
115
- // harness's hooks-file name (`harness-hooks-file`) and its own name
116
- // (`harness-name`, passed to the comparator so it audits the right home). A
117
- // omp session reports on the omp deployment. The pair lives on
118
- // `HarnessAdapter` and reaches here through projection, which is the only stage
119
- // that knows which adapter it is rendering for — the alternative was a
120
- // shell-side copy of the harness registry, a second home for adapter knowledge.
121
- // 3. THE VERDICT was recovered by matching the report's closing line. `deploy
122
- // --check` exited 1 both when the host was stale and when the check itself
123
- // failed, so the exit status could not separate them and the worker read the
124
- // TEXT — coupling a hook worker to the comparator's output FORMAT because its
125
- // exit CONTRACT could not carry the distinction. The contract carries it now
126
- // (`forge/src/deploy/check-exit.ts`: 0 in sync · 1 drift · 2 no verdict), and
127
- // the one code that is forge's choice rather than POSIX's arrives as a fact.
128
- //
129
- // EVERY HOOK WORKER ON EVERY HARNESS HAD (2). This cell is only the first whose job
130
- // made it visible, because it is the first that has to LOOK at the deployed tree
131
- // rather than merely run in it — and the repair is on the shared channel, so the next
132
- // one asks by name instead of rediscovering the blindness.
133
- //
134
- // The `workers[].content` is the TEMPLATE the committed worker at `targetPath`
135
- // regenerates from — resolved bytes, byte-locked by `test/hook-rule-boundary.test.ts`.
136
- // The committed resolution is the OMP one (`COMMITTED_TARGET_HARNESS`), because a
137
- // template with an adapter-relative fact has one resolution per harness and
138
- // `targetPath` names one file; every DEPLOYED copy is resolved for the harness that
139
- // session runs. EDIT THE CELL AND REGENERATE (`pnpm canon:project:targets`) — never
140
- // the committed `.sh` alone.
141
- export const deployDriftNotice = {
142
- id: 'deploy-drift-notice',
143
- residue: 'advisory ↾ session.start ∧ prompt.submit ⟨re-arm ∴ mid-session projection ⇏ stale ∀remaining-turns⟩ · deployed ≢ rendered ⇒ emit ⟨superseded-lines ∧ missing-lines ; ¬count · ¬digest · ¬sample⟩ ↾ verdict ≢ last-told ⟨trigger ≜ verdict-change · ¬verdict-non-empty ∴ re-arm ⇏ re-notify · memory ↾ ⟨harness · session⟩ ∧ ⟨corpus · tree⟩ · in-sync recorded ∴ recurrence audible · ∄session-id ⇒ ¬suppress ⟨noise ≻ borrowed-silence⟩⟩ · deployed ≡ rendered ⇒ ∅ ⟨silence-when-clean MANDATORY ⟨fires ∀session ⇒ reader-skips ⇒ worse-than-absent⟩⟩ · verdict ↦ comparator ⟨corpus-owned · ¬face-computed · ¬reimplemented⟩ · corpus ↦ walk-up ⟨cwd · corpus-marker⟩ ⟨∄ ⇒ ∅ ⟨¬in-scope ∴ ¬wrong⟩⟩ · tree ↦ shape ⟨agents ∧ skills ∧ THIS-harness-hooks-file ; ¬named-path⟩ · harness ↦ projection ⟨¬inferred ∴ session-own-deployment⟩ · stale ⊻ ¬ran ↦ exit-code ⟨¬report-text ∴ format ⊥ verdict⟩ · reached ∧ ∄verdict ⇒ SAY-SO ⟨silence ≡ in-sync ∴ ¬borrowable⟩ · ¬block · exit-0 ∀error',
144
- substrate: 'harness',
145
- events: ['session.start', 'prompt.submit'],
146
- entry: 'deploy-drift-notice.sh',
147
- timeout: 10,
148
- refs: [],
149
- speech: [
150
- {
151
- id: 'drift',
152
- text: 'DEPLOY DRIFT — this host runs a SUPERSEDED projection of the canon. In the report below, a `-` line is doctrine THIS SESSION is operating under and the corpus no longer says; a `+` line is what the corpus says and this host never received. Read every `-` line as a false premise, not as background. `pnpm canon:deploy` converges the host.',
153
- },
154
- {
155
- id: 'no-verdict',
156
- // `%s` is the worker's printf arg for the comparator it actually invoked. A
157
- // BLIND line naming nothing sends the reader hunting for what failed.
158
- text: 'DEPLOY DRIFT — the comparator (`%s`) returned no verdict, so whether this host runs the current canon is UNKNOWN. This is not an in-sync report; nothing here establishes that the doctrine in force is the corpus.',
159
- },
160
- {
161
- id: 'no-comparator',
162
- text: 'DEPLOY DRIFT — this corpus is in scope and its deploy comparator (`%s`) is not installed here, so whether this host runs the current canon is UNKNOWN. Install the workspace dependencies to make the question answerable; until then this is not an in-sync report.',
163
- },
164
- ],
165
- workers: [
166
- {
167
- filename: 'deploy-drift-notice.sh',
168
- targetPath: 'packages/canon/targets/guardrail/deploy-drift-notice.sh',
169
- executable: true,
170
- content: `#!/usr/bin/env sh
171
- # deploy-drift-notice — an ADVISORY, at session start and again before every
172
- # prompt. It asks the corpus's own deploy tool whether the tree this host RUNS is
173
- # the tree the corpus RENDERS, and speaks only when the answer CHANGES to "no".
174
- #
175
- # WHY (the incident): a deployed agent definition and the render tree diverged, an
176
- # agent ran a superseded first principle for a whole session, and every gate in the
177
- # repository stayed green throughout. The comparison was already reachable —
178
- # \`deploy --check\` — and nothing ran it, so the drift stayed silent by default.
179
- #
180
- # WHY AGAIN (the second incident): bound to session start alone, it answered a
181
- # question that expires. A projection landing MID-session left the rest of that
182
- # session running the superseded copy with nothing further to say — which is the
183
- # ordinary shape of work here, not an edge case. \`prompt.submit\` re-asks it in the
184
- # same position that made the first answer worth having: before the agent acts.
185
- #
186
- # CONTRACT:
187
- # - SILENT WHEN IN SYNC. An advisory that fires every session trains its reader
188
- # to skip it, and is then worse than absent.
189
- # - SPEAKS ON A CHANGE, NOT ON A STATE. Re-armed per prompt, a standing drift
190
- # would otherwise repeat until it stopped being read — the same failure, back
191
- # through the door the re-arm opened. The last verdict this session was told is
192
- # recorded; an identical one is silent.
193
- # - ADVISORY ONLY. Prints to stdout and exits 0. It never emits
194
- # {"decision":"block"} — a stale deployment must not block a session.
195
- # - NEVER SAMPLES. The comparison is the tool's own: whole tree, byte for byte.
196
- # A sample that skips the ten skills carrying the prime principle reports "in sync".
197
- # - NOT A COUNT. It relays the tool's report, which carries the superseded lines
198
- # still running and the rendered lines missing.
199
- #
200
- # NOTHING BELOW IS INFERRED THAT PROJECTION COULD STATE. The four values this
201
- # worker cannot compute for itself are SUBSTITUTED into it when the cell is
202
- # rendered — the comparator's name, this harness's name and hooks file, and the
203
- # exit code the comparator returns for drift. A copy of any of them, spelled here,
204
- # would be a second home in a file no compiler reads.
205
- #
206
- # COST: the cell header carries the measurement and its A/B. Not repeated here — a
207
- # number in two places is a number that will disagree with itself. What is worth
208
- # saying at this grain: the discovery below is a small fraction of it, and the rest
209
- # is the comparator reading both trees whole, which is the point.
210
- #
211
- # INPUT : SessionStart / UserPromptSubmit hook JSON on stdin (cwd, session_id, ...).
212
- # OUTPUT : a CHANGED drift verdict -> advisory + the report; a changed unanswerable
213
- # one -> a BLIND line; in sync, or unchanged since this session was told -> none.
214
-
215
- set -eu
216
-
217
- # Neither a session start nor a prompt may be broken by an advisory. Any unexpected
218
- # error -> silence.
219
- trap 'exit 0' EXIT
220
-
221
- # ── WHAT PROJECTION TOLD US ────────────────────────────────────────────────────
222
- # The corpus's own deploy tool. ONE authored spelling exists in the whole
223
- # repository — \`packages/forge/package.json\`'s \`bin\` key, the one npm obeys — and
224
- # \`forge/src/bin-name.ts\` derives from it, so this line is that key, relayed.
225
- DEPLOY_TOOL={{fact:deploy-bin}}
226
-
227
- # WHICH HARNESS THIS PROJECTION IS FOR. A hook worker is handed no identity by the
228
- # session it runs in, so a worker that must LOOK at a deployed tree had to guess —
229
- # and guessed claude, which made an omp session report on a sibling deployment.
230
- # These two are the adapter's own \`name\` and \`hooksFile\`, substituted at
231
- # projection: the omp render of this cell carries omp's.
232
- HARNESS={{fact:harness-name}}
233
- HARNESS_HOOKS_FILE={{fact:harness-hooks-file}}
234
-
235
- # The status the comparator returns when it FOUND drift. \`0\` means success to
236
- # POSIX and needs no telling; this one is the tool's own choice, so it is told.
237
- DRIFT_RC={{fact:deploy-check-drift-code}}
238
-
239
- # ── THE PAYLOAD, DRAINED ONCE ──────────────────────────────────────────────────
240
- # Two fields are needed and stdin can only be read once, so both come off ONE jq —
241
- # the same single fork the cwd lookup already cost, not a second one. \`.cwd\` says
242
- # which corpus; \`.session_id\` says who is being told, which is what lets a re-armed
243
- # advisory stay quiet about a verdict it has already delivered.
244
- input="$(cat 2>/dev/null || true)"
245
- cwd=""
246
- sid=""
247
- if command -v jq >/dev/null 2>&1 && [ -n "$input" ]; then
248
- fields="$(printf '%s' "$input" | jq -r '.cwd // "", .session_id // ""' 2>/dev/null || true)"
249
- {
250
- read -r cwd || true
251
- read -r sid || true
252
- } <<EOF
253
- $fields
254
- EOF
255
- fi
256
-
257
- # ── WHERE ARE WE? the corpus, by its own marker ────────────────────────────────
258
- # \`cratylus.config.ts\` is the file \`deploy\` itself reads to learn which corpus it is
259
- # operating on. Walking up for it asks the same question the tool asks, instead of
260
- # inventing a second convention for "a checkout of the canon".
261
- start="\${CRATYLUS_CORPUS:-$cwd}"
262
- [ -n "$start" ] || start="\${CLAUDE_PROJECT_DIR:-$PWD}"
263
-
264
- root=""
265
- d="$start"
266
- while [ -n "$d" ] && [ "$d" != "/" ]; do
267
- if [ -f "$d/cratylus.config.ts" ]; then
268
- root="$d"
269
- break
270
- fi
271
- d="\${d%/*}"
272
- done
273
- # NO CORPUS IN SCOPE IS SILENCE, and it is not the "clean" silence above. A session
274
- # outside every checkout has no rendered doctrine to be compared against, so there is
275
- # nothing here this hook could be right or wrong about — and speaking would fire it on
276
- # every unrelated session, which is the one failure that makes an advisory worthless.
277
- [ -n "$root" ] || exit 0
278
-
279
- # ── WHICH TREE? this harness's render tree, by its SHAPE ───────────────────────
280
- # A render tree is recognized by BEING one: \`agents/\` + \`skills/\` + THIS harness's
281
- # own hooks file. That file is what distinguishes this harness's tree from another
282
- # harness's tree sitting beside it, and it is named by projection rather than by
283
- # this script — so an omp render of this worker skips the claude tree and a claude
284
- # render skips the omp one. The \`--out\` dir is an operator's choice, so the tree
285
- # is discovered, never named.
286
- #
287
- # THE GLOB USED TO BE \`.render*\`, WHICH MADE THE PARAGRAPH ABOVE FALSE. The shape
288
- # test only ever ran on candidates a NAME had already selected, so "discovered, never
289
- # named" described the second half of a two-stage filter whose first stage was a
290
- # hard-coded prefix. Any operator honouring the documented freedom — \`--out
291
- # build/corpus\` — got silence, and silence here is indistinguishable from in-sync.
292
- # The rename of the corpus's own tree is what surfaced it; the defect predates it.
293
- #
294
- # So the candidate set is now DOTTED DIRECTORIES at the same depths, plus one level
295
- # beneath each, because a tree that splits per harness puts the shape one deeper
296
- # (\`.cratylus/claude\`, not \`.render-ts\`). Dotted, because that is the convention
297
- # for generated trees (\`.next\`, \`.turbo\`, \`.svelte-kit\`) and because walking every
298
- # directory in a checkout to find one that has \`agents/\` is a cost this hook cannot
299
- # pay on every prompt. The shape test is still what decides; the glob now only bounds
300
- # where to look, and it no longer bounds it to one spelling.
301
- tree="\${CRATYLUS_RENDER_TREE:-}"
302
- if [ -z "$tree" ]; then
303
- for c in \\
304
- "$root"/.*/ "$root"/*/.*/ "$root"/*/*/.*/ \\
305
- "$root"/.*/*/ "$root"/*/.*/*/ "$root"/*/*/.*/*/; do
306
- case "$c" in
307
- */node_modules/*) continue ;;
308
- */.git/*) continue ;;
309
- */./ | */../) continue ;;
310
- esac
311
- c="\${c%/}"
312
- [ -d "$c/agents" ] && [ -d "$c/skills" ] && [ -f "$c/$HARNESS_HOOKS_FILE" ] || continue
313
- tree="$c"
314
- break
315
- done
316
- fi
317
- # A corpus that has rendered nothing for THIS harness has nothing to be compared
318
- # against — the same not-in-scope silence, one step in.
319
- [ -n "$tree" ] || exit 0
320
-
321
- # ── WHAT WAS THIS SESSION ALREADY TOLD? ────────────────────────────────────────
322
- # The re-arm's whole cost is here. Asked before every prompt, an unchanged verdict
323
- # repeated until the reader stopped seeing it would be the in-sync failure re-entering
324
- # through the door opened to fix the stale one. So one small file per session holds the
325
- # last verdict delivered, and the trigger is the DIFFERENCE.
326
- #
327
- # The key is \`⟨harness, session⟩\` and the CONTENT carries \`⟨corpus, tree⟩\`: two
328
- # harnesses in one session audit two hosts and must not overwrite each other's answer,
329
- # and the same session moved to another checkout is asking a different question rather
330
- # than repeating one. A session id that is not a plain token is treated as absent —
331
- # nothing here builds a path out of an unexamined payload field.
332
- state=""
333
- case "$sid" in
334
- '' | *[!A-Za-z0-9._-]*) ;;
335
- *)
336
- stash="\${TMPDIR:-/tmp}/cratylus-deploy-drift"
337
- if [ -d "$stash" ] || mkdir -p "$stash" 2>/dev/null; then
338
- state="$stash/$HARNESS-$sid"
339
- fi
340
- ;;
341
- esac
342
-
343
- # \`changed <verdict>\` — record it as the last thing this session was told, and
344
- # answer whether it DIFFERS from what was recorded before.
345
- #
346
- # NO STATE MEANS EVERY RUN SPEAKS, and the asymmetry is deliberate. Without a session
347
- # id there is nothing to suppress against, and a repeated advisory under real drift is
348
- # noise one \`deploy\` ends, while a suppressed one is SILENCE — which this cell spends
349
- # its whole contract making mean "in sync", and may therefore lend to nothing else.
350
- changed() {
351
- now="$root|$tree|$1"
352
- [ -n "$state" ] || return 0
353
- last=""
354
- [ ! -f "$state" ] || last="$(cat "$state" 2>/dev/null || true)"
355
- printf '%s' "$now" >"$state" 2>/dev/null || true
356
- [ "$last" != "$now" ]
357
- }
358
-
359
- # ── WHAT ASKS? the tool, never a reimplementation ──────────────────────────────
360
- cli="\${CRATYLUS_DEPLOY_CHECK:-}"
361
- if [ -z "$cli" ]; then
362
- if [ -x "$root/node_modules/.bin/$DEPLOY_TOOL" ]; then
363
- cli="$root/node_modules/.bin/$DEPLOY_TOOL"
364
- elif command -v "$DEPLOY_TOOL" >/dev/null 2>&1; then
365
- cli="$DEPLOY_TOOL"
366
- fi
367
- fi
368
- if [ -z "$cli" ]; then
369
- if changed "no-comparator"; then
370
- printf '{{speech:no-comparator}}\\n' "$DEPLOY_TOOL"
371
- fi
372
- exit 0
373
- fi
374
-
375
- # \`--harness\` is what makes the audited HOME this session's. Without it the tool
376
- # resolves its default root, so an omp tree would be compared against the claude
377
- # deployment — a report that is about neither.
378
- # The tool reports and repairs nothing, so it is safe to point at a host mid-work.
379
- set +e
380
- out="$("$cli" deploy --check \\
381
- --harness "$HARNESS" \\
382
- --agents-dir "$tree/agents" \\
383
- --skills-dir "$tree/skills" \\
384
- --hooks-dir "$tree" 2>&1)"
385
- rc=$?
386
- set -e
387
-
388
- # rc 0 IS the tool's verdict that no artifact is stale and none is absent (a foreign
389
- # artifact is reported by it, and is not a defect). The silence is earned here, and
390
- # nowhere else — every other exit takes a branch below.
391
- #
392
- # IT IS RECORDED ANYWAY, and that is what makes a RETURNING drift audible: drift, then
393
- # a deploy, then the identical drift again would match a record that still said "drift"
394
- # and be swallowed. Recording the clean verdict makes the second one a change. Its own
395
- # result is discarded — a host that has just gone from stale to in-sync gets no all-clear
396
- # either, because silence-when-clean is unconditional.
397
- if [ "$rc" -eq 0 ]; then
398
- changed in-sync || true
399
- exit 0
400
- fi
401
-
402
- # WHICH KIND OF NON-ZERO — asked of the EXIT CODE, which is a contract, and not of
403
- # the report's wording, which is a format. Drift has a code of its own; everything
404
- # else that is not success is the check failing to produce a verdict, including the
405
- # codes this worker was never told about (a crash, a signal, a missing file). The
406
- # two demand opposite responses: relaying a broken tool as drift fabricates a
407
- # verdict, and relaying it as silence is the bypass-by-omission this cell exists to
408
- # end.
409
- #
410
- # THE REPORT IS PART OF THE VERDICT, not decoration on it. Two drifts that differ in
411
- # WHICH doctrine is superseded are two things to be told, so the report's bytes are what
412
- # the session remembers — a key of "drift" alone would announce the first stale artifact
413
- # and swallow every one after it.
414
- if [ "$rc" -eq "$DRIFT_RC" ]; then
415
- if changed "drift
416
- $out"; then
417
- printf '%s\\n' '{{speech:drift}}'
418
- printf '%s\\n' "$out"
419
- fi
420
- else
421
- if changed "no-verdict $rc
422
- $out"; then
423
- printf '{{speech:no-verdict}}\\n' "$cli"
424
- fi
425
- fi
426
- exit 0
427
- `,
428
- },
429
- ],
430
- };
431
- //# sourceMappingURL=deploy-drift-notice.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"deploy-drift-notice.js","sourceRoot":"","sources":["../../src/hooks/deploy-drift-notice.ts"],"names":[],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- import type { RuleCell } from '@cratylus/schema';
2
- export declare const repoPreamble: RuleCell;
@@ -1,49 +0,0 @@
1
- // repo-preamble — the FIRST `rule` corpus instance (MODEL `Kind ∋ rule`,
2
- // `activation: rule↦scope`). The workspace-root standing instruction (`AGENTS.md`):
3
- // the always-loaded orientation every session binds on entry. Retiring the
4
- // `AGENTS.md@node` memory-sink route (no cell routes a record to a node/plan
5
- // `AGENTS.md`) removed the sole blocker to treating the repo-root `AGENTS.md` as a
6
- // byte-locked rule TARGET — it is no longer SelfAuthored memory (`SelfAuthored ∉
7
- // Target` no longer applies), so it is a curated source-of-truth cell whose
8
- // `content` projects + byte-locks to `/AGENTS.md`.
9
- //
10
- // residue — the σ*-signified canonical identity (`body = ⟨α, residue⟩`), the
11
- // `accept()`/REFLEXIVE target. It is `residue`, NOT `definiens`: it has
12
- // already paid the `∖ fired(α)` subtraction (`schema/src/rule-cell.ts`).
13
- // content — the VERBATIM directive payload, regenerated to `targetPath` by
14
- // `project-targets` and byte-locked by `test/hook-rule-boundary.test.ts`.
15
- // `content`, NOT `body`: `body(c) = ⟨α, residue⟩` is the whole cell, and
16
- // this is the sibling of `HookWorker.content` (`schema/src/rule-cell.ts`).
17
- export const repoPreamble = {
18
- kind: 'rule',
19
- id: 'repo-preamble',
20
- slug: 'repo-preamble',
21
- residue: 'scope-rule ↾ workspace-root · loaded ∀ session on entry — the standing orientation: doctrine-pointers ⟨why · what · how · corpus-index ; LOCKED-immutable-grounding : source-aligns-up · ¬regenerated-from-source⟩ · working-convention ⟨conventional-commits ; header ≤100 ; commit-autonomous@natural-boundaries ; push ⟨¬say-so⟩ ; green-field ⟨constrains-only-where-declared ; ¬compatibility-goal⟩ ; library-first ⟨maintained · small-API · ¬workflow-engine ; wrapped behind a cratylus capability⟩ ; branching=git-flow dev/main ⟨¬release · ¬hotfix branches ; change-branch ← dev ; local merge → dev once the check passes on the merged result ; dev → main by PR = release ↦ operator ; ¬direct-commit@main⟩ ; the-check ⟨pnpm check = pre-push = CI ; build · lint · typecheck · deterministic tests ; deps declared ; omp version stated, ¬prerequisite⟩ ; history ⟨review ; ¬refusal⟩ ; commit-own-paths ⟨by name ; ¬amend · ¬rewrite-shared⟩⟩ ; activation=scope ⟨curated source, projected + byte-locked⟩',
22
- scope: '',
23
- targetPath: 'AGENTS.md',
24
- refs: [],
25
- content: `# AGENTS
26
-
27
- **CRITICAL INVARIANT:** You **MUST Read** these documents upon session-start:
28
-
29
- - [\`CANON.md\`](./CANON.md) — **overview and primer**
30
- - [\`CRATYLISM\`](./packages/canon/src/genus/prime-principle.ts) — The First Principle (**LOCKED**)
31
- - [\`VISION.md\`](./VISION.md) — **why** the canon exists
32
- - [\`MODEL.md\`](./MODEL.md) — **what** exists: conceptual objectives and acceptance criteria
33
- - [\`ENGINE.md\`](./ENGINE.md) — **how** primitives are discovered, validated, and projected
34
- - [\`ARCHITECTURE\`](./ARCHITECTURE.md) — purpose and relationship of the packages, and the seams that separate their concerns.
35
-
36
- ## Working conventions
37
-
38
- - Conventional Commits, header ≤100 chars (commitlint, \`commit-msg\` hook).
39
- - **Commit autonomously at natural boundaries,** without asking; this overrides the generic harness default of committing only when the user asks. Pushing a branch needs no say-so.
40
- - **Green-field register:** existing code, records, and docs constrain work only where explicitly declared; compatibility is never a goal.
41
- - **Reach for an established library before writing or adopting machinery.** Where a well-known problem has an actively maintained, widely used library with a small API, use it; never adopt a workflow or orchestration engine. Wrap it behind cratylus's own capability, so agents learn one small cratylus API, not the library's.
42
- - **Branching: Git flow's \`dev\`/\`main\` split, without release or hotfix branches.** Each change is made on a short-lived branch from \`dev\` and merged locally into \`dev\` once \`pnpm check\` passes on the merged result. Release is a pull request from \`dev\` into \`main\`, and it is the operator's. Never commit to \`main\` directly.
43
- - **One check:** \`pnpm check\` builds, lints, typechecks and runs the deterministic tests, and fails when any of them fails. The \`pre-push\` hook runs it, and CI runs exactly it after checkout and \`pnpm install\`, with nothing before or after. Every dependency it needs is declared in the workspace's manifests; nothing checks what else is installed.
44
- - **Tests cover cratylus's own deterministic code only:** the check tests cratylus's code and the files it produces, never by starting omp, an agent or a model. Agent behaviour is judged in real use. The supported omp version is 18.10.2; the check neither needs nor starts omp, and after an omp upgrade the operator or the architect tries one real session by hand.
45
- - **History is controlled by review, not by refusal:** no hook, CI step or command refuses a change to existing records; the concept journal stays append-only because its verbs only append.
46
- - **Commit only what you changed:** stage and commit your own paths by name, never everything in the tree, and never amend or rewrite shared history.
47
- `,
48
- };
49
- //# sourceMappingURL=repo-preamble.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"repo-preamble.js","sourceRoot":"","sources":["../../src/rules/repo-preamble.ts"],"names":[],"mappings":"AAEA,yEAAyE;AACzE,oFAAoF;AACpF,2EAA2E;AAC3E,6EAA6E;AAC7E,mFAAmF;AACnF,iFAAiF;AACjF,4EAA4E;AAC5E,mDAAmD;AACnD,EAAE;AACF,+EAA+E;AAC/E,oFAAoF;AACpF,qFAAqF;AACrF,6EAA6E;AAC7E,sFAAsF;AACtF,qFAAqF;AACrF,uFAAuF;AAEvF,MAAM,CAAC,MAAM,YAAY,GAAa;IACpC,IAAI,EAAE,MAAM;IACZ,EAAE,EAAE,eAAe;IACnB,IAAI,EAAE,eAAe;IACrB,OAAO,EACL,89BAA89B;IACh+B,KAAK,EAAE,EAAE;IACT,UAAU,EAAE,WAAW;IACvB,IAAI,EAAE,EAAE;IACR,OAAO,EAAE;;;;;;;;;;;;;;;;;;;;;;CAsBV;CACA,CAAC"}
@@ -1,2 +0,0 @@
1
- import type { Skill } from '../../manifest.js';
2
- export declare const introspect: Skill;
@@ -1,55 +0,0 @@
1
- import { primePrinciple } from '../../genus/prime-principle.js';
2
- export const introspect = {
3
- name: 'introspect',
4
- description: `use this skill when an agent needs to self-audit — compare each factor's defined values (each at its enforcement level) against the values actually in effect this session, and name the cause of every divergence.`,
5
- formalBlock: `A ≜ the agent introspecting itself
6
- O_text ≜ enumerate(\`###\` factor headings @ A's live Target) ⟨READ · ¬ recalled · \`##\` ≜ a group ∴ ∉ O⟩
7
- O_bind ≜ enumerate(binding factors @ \`cratylus catalog\`) ⟨never text · compiled to harness tool · dispatch · model-role settings⟩
8
- O ≜ O_text ∪ O_bind ⟨∄ fixed-list ∵ corpus declares its own catalog · enforcement-level ≜ an attribute of each entry ∴ ∉ O⟩
9
- |O| ≜ |O_text| + |O_bind| ⟨the DENOMINATOR⟩
10
- V ≜ the entry value-space { one-entry · entry-set · one-entry-per-slot · unobservable } ⟨entry ≜ value @ level { advisory · firm · fixed }⟩
11
- src_def ≜ A's in-prompt \`###\` Target factors ∪ agent/<A>.md ⟨front-matter ↦ O_bind⟩ ⟨the entries held per factor⟩
12
- src_rt ≜ runtime sources observed this session { live tool/action-set · live dispatchable agents · live model · system-prompt-as-given · autonomy-mode + transient-elevation · deployed front-matter⟨color · mark⟩ · env · granted-permissions }
13
- addresses : O → concept @ A's identity ⟨name · description · mark · key ≜ ∅⟩ ∪ each factor's role ⟨the concept the fragment must express⟩
14
-
15
- def : O → V @ src_def
16
- rt : O → V @ src_rt
17
- decode : O → concept ≜ decode_cold(def(o)) ⟨isolated tool-less read of the declared sign · its own priors · zero project-causes⟩
18
- why : div → causes
19
-
20
- harness-override ≜ runtime substituted the value ⟨tool-gating · model-pin · env⟩
21
- deploy-drift ≜ deployed def ≠ source vector ⟨stale ∨ partial deploy⟩
22
- profile-projection ≜ def projected at a reader/profile that reshaped the value
23
- transient-elevation ≜ a session act flipped it ⟨autonomy human-in-the-loop ↦ human-on-the-loop⟩
24
- composer-dropped ≜ projection dropped a facet ⟨the color/mark regression class⟩
25
- env-conditioned ≜ a host/env fact changed the effective value
26
- unobservable ≜ runtime value ¬ inspectable ∴ report-as-such ∧ ¬ guess
27
- misnomer ≜ def faithfully in effect yet the wrong sign for its concept ⟨match(o) ∧ ¬ signifies(o) · a signification defect at def, ¬ a configuration one; the class that hides when rt conforms to a def that is itself mis-signified⟩
28
- K_cfg ≜ { harness-override · deploy-drift · profile-projection · transient-elevation · composer-dropped · env-conditioned · unobservable }
29
- causes ≜ K_cfg ∪ { misnomer }
30
-
31
- ∀ o ∈ O : rt(o) @ src_rt
32
- ¬ ( rt ≜ def )
33
- match(o) ≜ def(o) ≅ rt(o) ⟨values ∧ their levels⟩
34
- signifies(o) ≜ decode(o) ≅ addresses(o)
35
- sound(o) ≜ match(o) ∧ signifies(o)
36
- div ≜ { o ∈ O | ¬ sound(o) }
37
- ¬ match(o) ⇒ why(o) ∈ K_cfg
38
- match(o) ∧ ¬ signifies(o) ⇒ why(o) = misnomer
39
- why(o) ∈ causes , o ∈ div
40
- row(o) ≜ ⟨ o, def(o), rt(o), match(o), signifies(o), why(o) ↾ o ∈ div ⟩
41
- summary ≜ { ⟨ o, why(o) ⟩ | o ∈ div }
42
- report ≜ ⟨ |O|, { row(o) | o ∈ O }, summary ⟩ ⟨|O| STATED⟩
43
- introspect(A) ≜ report
44
- |{ row(o) }| ≠ |O| ⇒ ⊥
45
- rt(o) ⊨ EXERCISED ⟨¬ inferred-from-absence⟩
46
- ¬ exercised(o) ⇒ why(o) = unobservable ∧ why(o) ≠ harness-override
47
-
48
- ¬ edit(agent/<A>.md) ∧ ¬ redeploy ∧ ¬ mint(V)
49
- why(o) ∈ K_cfg ⇒ reconcile @ { create-agent · deploy }
50
- why(o) = misnomer ⇒ reconcile @ signify ≺ { create-agent · deploy }
51
- O · causes @ live-anatomy`,
52
- composition: () => [],
53
- preamble: primePrinciple,
54
- };
55
- //# sourceMappingURL=skill.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"skill.js","sourceRoot":"","sources":["../../../src/skills/introspect/skill.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAGhE,MAAM,CAAC,MAAM,UAAU,GAAU;IAC/B,IAAI,EAAE,YAAY;IAClB,WAAW,EAAE,qNAAqN;IAClO,WAAW,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iCA8CqC;IAClD,WAAW,EAAE,GAAG,EAAE,CAAC,EAAE;IACrB,QAAQ,EAAE,cAAc;CACzB,CAAC"}