@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.
- package/README.md +60 -58
- package/dist/agents/kino.js +1 -1
- package/dist/agents/kino.js.map +1 -1
- package/dist/agents/mav.js +1 -1
- package/dist/agents/mav.js.map +1 -1
- package/dist/agents/nico.js +1 -1
- package/dist/agents/nico.js.map +1 -1
- package/dist/compose.d.ts +4 -4
- package/dist/compose.js +14 -16
- package/dist/compose.js.map +1 -1
- package/dist/contracts.js +15 -15
- package/dist/contracts.js.map +1 -1
- package/dist/dimensions/action-scope/integrate.js +1 -1
- package/dist/dimensions/action-scope/integrate.js.map +1 -1
- package/dist/dimensions/assignment/concepts.js +1 -1
- package/dist/dimensions/assignment/concepts.js.map +1 -1
- package/dist/dimensions/assignment/review-request.js +1 -1
- package/dist/dimensions/assignment/review-request.js.map +1 -1
- package/dist/dimensions/assignment/task.js +1 -1
- package/dist/dimensions/assignment/task.js.map +1 -1
- package/dist/dimensions/assignment/{story.d.ts → user-story.d.ts} +1 -1
- package/dist/dimensions/assignment/user-story.js +2 -0
- package/dist/dimensions/assignment/user-story.js.map +1 -0
- package/dist/dimensions/autonomy/management-by-exception.d.ts +2 -0
- package/dist/dimensions/autonomy/management-by-exception.js +2 -0
- package/dist/dimensions/autonomy/management-by-exception.js.map +1 -0
- package/dist/dimensions/communication-style/bottom-line-up-front.js +1 -1
- package/dist/dimensions/communication-style/bottom-line-up-front.js.map +1 -1
- package/dist/dimensions/communication-style/layman.js +1 -1
- package/dist/dimensions/communication-style/layman.js.map +1 -1
- package/dist/dimensions/deliverable/{review.d.ts → code-review.d.ts} +1 -1
- package/dist/dimensions/deliverable/code-review.js +2 -0
- package/dist/dimensions/deliverable/code-review.js.map +1 -0
- package/dist/dimensions/deliverable/outcome.js +1 -1
- package/dist/dimensions/deliverable/outcome.js.map +1 -1
- package/dist/dimensions/deliverable/read-back.js +1 -1
- package/dist/dimensions/deliverable/read-back.js.map +1 -1
- package/dist/dimensions/expertise/evaluation-design.js +1 -1
- package/dist/dimensions/expertise/evaluation-design.js.map +1 -1
- package/dist/dimensions/expertise/semantic-addressing.js +1 -1
- package/dist/dimensions/expertise/semantic-addressing.js.map +1 -1
- package/dist/dimensions/guardrails/append-only.js +1 -1
- package/dist/dimensions/guardrails/append-only.js.map +1 -1
- package/dist/dimensions/guardrails/fixed-acceptance-criteria.js +1 -1
- package/dist/dimensions/guardrails/fixed-acceptance-criteria.js.map +1 -1
- package/dist/dimensions/guardrails/honesty.js +1 -1
- package/dist/dimensions/guardrails/honesty.js.map +1 -1
- package/dist/dimensions/guardrails/input-untrusted.js +1 -1
- package/dist/dimensions/guardrails/input-untrusted.js.map +1 -1
- package/dist/dimensions/guardrails/never-repairs.js +1 -1
- package/dist/dimensions/guardrails/never-repairs.js.map +1 -1
- package/dist/dimensions/guardrails/no-implementation.js +1 -1
- package/dist/dimensions/guardrails/no-implementation.js.map +1 -1
- package/dist/dimensions/guardrails/privacy.js +1 -1
- package/dist/dimensions/guardrails/privacy.js.map +1 -1
- package/dist/dimensions/memory/reconstitution.js +1 -1
- package/dist/dimensions/memory/reconstitution.js.map +1 -1
- package/dist/dimensions/memory/source-of-truth.js +1 -1
- package/dist/dimensions/memory/source-of-truth.js.map +1 -1
- package/dist/dimensions/model/frontier-other-family.js +1 -1
- package/dist/dimensions/model/frontier-other-family.js.map +1 -1
- package/dist/dimensions/objective/conceptual-integrity.js +1 -1
- package/dist/dimensions/objective/conceptual-integrity.js.map +1 -1
- package/dist/dimensions/objective/delivery.js +1 -1
- package/dist/dimensions/objective/delivery.js.map +1 -1
- package/dist/dimensions/objective/review-accuracy.js +1 -1
- package/dist/dimensions/objective/review-accuracy.js.map +1 -1
- package/dist/dimensions/perception-scope/concept-journal.js +1 -1
- package/dist/dimensions/perception-scope/concept-journal.js.map +1 -1
- package/dist/dimensions/perception-scope/held-out-examples.js +1 -1
- package/dist/dimensions/perception-scope/held-out-examples.js.map +1 -1
- package/dist/dimensions/perception-scope/own-task.js +1 -1
- package/dist/dimensions/perception-scope/own-task.js.map +1 -1
- package/dist/dimensions/perception-scope/{work.d.ts → work-product.d.ts} +1 -1
- package/dist/dimensions/perception-scope/work-product.js +2 -0
- package/dist/dimensions/perception-scope/work-product.js.map +1 -0
- package/dist/dimensions/procedure/code-review.js +1 -1
- package/dist/dimensions/procedure/code-review.js.map +1 -1
- package/dist/dimensions/procedure/orchestrator-workers.js +1 -1
- package/dist/dimensions/procedure/orchestrator-workers.js.map +1 -1
- package/dist/dimensions/procedure/reconstitution.js +1 -1
- package/dist/dimensions/procedure/reconstitution.js.map +1 -1
- package/dist/dimensions/procedure/ship-show-ask.js +1 -1
- package/dist/dimensions/procedure/ship-show-ask.js.map +1 -1
- package/dist/dimensions/role/architect.js +1 -1
- package/dist/dimensions/role/architect.js.map +1 -1
- package/dist/dimensions/role/builder.js +1 -1
- package/dist/dimensions/role/builder.js.map +1 -1
- package/dist/dimensions/role/check-writer.js +1 -1
- package/dist/dimensions/role/check-writer.js.map +1 -1
- package/dist/dimensions/role/illustrator.js +1 -1
- package/dist/dimensions/role/illustrator.js.map +1 -1
- package/dist/dimensions/role/lead.js +1 -1
- package/dist/dimensions/role/lead.js.map +1 -1
- package/dist/dimensions/role/reviewer.js +1 -1
- package/dist/dimensions/role/reviewer.js.map +1 -1
- package/dist/dimensions/stance/cold-decode-oracle.js +1 -1
- package/dist/dimensions/stance/cold-decode-oracle.js.map +1 -1
- package/dist/dimensions/stance/conceptual-elevation.js +1 -1
- package/dist/dimensions/stance/conceptual-elevation.js.map +1 -1
- package/dist/dimensions/stance/decisive.js +1 -1
- package/dist/dimensions/stance/decisive.js.map +1 -1
- package/dist/dimensions/stance/{proportionate.d.ts → tailoring.d.ts} +1 -1
- package/dist/dimensions/stance/tailoring.js +2 -0
- package/dist/dimensions/stance/tailoring.js.map +1 -0
- package/dist/dimensions/stance/zero-trust.js +1 -1
- package/dist/dimensions/stance/zero-trust.js.map +1 -1
- package/dist/genus/prime-principle.d.ts +4 -3
- package/dist/genus/prime-principle.js +3 -2
- package/dist/genus/prime-principle.js.map +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.js +10 -11
- package/dist/index.js.map +1 -1
- package/dist/manifest.d.ts +12 -12
- package/dist/manifest.js +20 -26
- package/dist/manifest.js.map +1 -1
- package/dist/operator-lexicon.d.ts +1 -12
- package/dist/operator-lexicon.js +3 -33
- package/dist/operator-lexicon.js.map +1 -1
- package/dist/practices.d.ts +1 -2
- package/dist/practices.js +2 -6
- package/dist/practices.js.map +1 -1
- package/dist/roles/architect.js +16 -34
- package/dist/roles/architect.js.map +1 -1
- package/dist/roles/builder.js +4 -4
- package/dist/roles/builder.js.map +1 -1
- package/dist/roles/check-writer.js +3 -3
- package/dist/roles/check-writer.js.map +1 -1
- package/dist/roles/illustrator.js +2 -2
- package/dist/roles/illustrator.js.map +1 -1
- package/dist/roles/lead.js +16 -22
- package/dist/roles/lead.js.map +1 -1
- package/dist/roles/reviewer.js +11 -10
- package/dist/roles/reviewer.js.map +1 -1
- package/dist/rules/commit-discipline.d.ts +3 -0
- package/dist/rules/commit-discipline.js +26 -0
- package/dist/rules/commit-discipline.js.map +1 -0
- package/dist/rules/conventional-commits.d.ts +3 -0
- package/dist/rules/conventional-commits.js +38 -0
- package/dist/rules/conventional-commits.js.map +1 -0
- package/dist/rules/established-libraries.d.ts +3 -0
- package/dist/rules/established-libraries.js +20 -0
- package/dist/rules/established-libraries.js.map +1 -0
- package/dist/rules/gitflow.d.ts +3 -0
- package/dist/rules/gitflow.js +32 -0
- package/dist/rules/gitflow.js.map +1 -0
- package/dist/rules/green-field.d.ts +3 -0
- package/dist/rules/green-field.js +20 -0
- package/dist/rules/green-field.js.map +1 -0
- package/dist/rulesets.d.ts +2 -0
- package/dist/rulesets.js +17 -0
- package/dist/rulesets.js.map +1 -0
- package/dist/skills/conceptualize/skill.js +2 -3
- package/dist/skills/conceptualize/skill.js.map +1 -1
- package/dist/skills/create-agent/skill.js +1 -1
- package/dist/skills/create-skill/skill.js +1 -1
- package/dist/skills/elicit/skill.js +2 -3
- package/dist/skills/elicit/skill.js.map +1 -1
- package/dist/skills/exemplify/skill.js +3 -4
- package/dist/skills/exemplify/skill.js.map +1 -1
- package/dist/skills/materialize/skill.js +2 -3
- package/dist/skills/materialize/skill.js.map +1 -1
- package/dist/skills/probe/skill.js +24 -25
- package/dist/skills/probe/skill.js.map +1 -1
- package/dist/skills/signify/skill.js +22 -21
- package/dist/skills/signify/skill.js.map +1 -1
- package/package.json +5 -6
- package/dist/dimensions/assignment/story.js +0 -2
- package/dist/dimensions/assignment/story.js.map +0 -1
- package/dist/dimensions/deliverable/review.js +0 -2
- package/dist/dimensions/deliverable/review.js.map +0 -1
- package/dist/dimensions/perception-scope/work.js +0 -2
- package/dist/dimensions/perception-scope/work.js.map +0 -1
- package/dist/dimensions/stance/proportionate.js +0 -2
- package/dist/dimensions/stance/proportionate.js.map +0 -1
- package/dist/genus/persona.d.ts +0 -8
- package/dist/genus/persona.js +0 -30
- package/dist/genus/persona.js.map +0 -1
- package/dist/hook-cells.d.ts +0 -3
- package/dist/hook-cells.js +0 -14
- package/dist/hook-cells.js.map +0 -1
- package/dist/hooks/deploy-drift-notice.d.ts +0 -2
- package/dist/hooks/deploy-drift-notice.js +0 -431
- package/dist/hooks/deploy-drift-notice.js.map +0 -1
- package/dist/rules/repo-preamble.d.ts +0 -2
- package/dist/rules/repo-preamble.js +0 -49
- package/dist/rules/repo-preamble.js.map +0 -1
- package/dist/skills/introspect/skill.d.ts +0 -2
- package/dist/skills/introspect/skill.js +0 -55
- 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,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,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"}
|