@cratylus/canon 0.7.0 → 0.9.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 +6 -4
- package/dist/agents/architect.js +2 -2
- package/dist/agents/architect.js.map +1 -1
- package/dist/agents/assayer.js +10 -10
- package/dist/agents/assayer.js.map +1 -1
- package/dist/agents/implementer.js +3 -3
- package/dist/agents/implementer.js.map +1 -1
- package/dist/agents/integrator.d.ts +2 -0
- package/dist/agents/integrator.js +18 -0
- package/dist/agents/integrator.js.map +1 -0
- package/dist/agents/kino.js +5 -4
- package/dist/agents/kino.js.map +1 -1
- package/dist/agents/mav.js +19 -37
- package/dist/agents/mav.js.map +1 -1
- package/dist/agents/nico.js +13 -31
- package/dist/agents/nico.js.map +1 -1
- package/dist/agents/planner.js +5 -5
- package/dist/agents/planner.js.map +1 -1
- package/dist/dimensions/actions/delegation.js +6 -1
- package/dist/dimensions/actions/delegation.js.map +1 -1
- package/dist/dimensions/engineering-principles/cold-decode-oracle.js +1 -1
- package/dist/dimensions/engineering-principles/cold-decode-oracle.js.map +1 -1
- package/dist/dimensions/engineering-principles/trust-but-verify.js +1 -1
- package/dist/dimensions/engineering-principles/trust-but-verify.js.map +1 -1
- package/dist/dimensions/objective/conceptual-integrity.d.ts +2 -0
- package/dist/dimensions/objective/conceptual-integrity.js +2 -0
- package/dist/dimensions/objective/conceptual-integrity.js.map +1 -0
- package/dist/dimensions/role/architect.js +5 -3
- package/dist/dimensions/role/architect.js.map +1 -1
- package/dist/dimensions/role/assayer.js +24 -13
- package/dist/dimensions/role/assayer.js.map +1 -1
- package/dist/dimensions/role/implementer.js +21 -4
- package/dist/dimensions/role/implementer.js.map +1 -1
- package/dist/dimensions/role/integrator.d.ts +2 -0
- package/dist/dimensions/role/integrator.js +27 -0
- package/dist/dimensions/role/integrator.js.map +1 -0
- package/dist/dimensions/role/planner.js +19 -7
- package/dist/dimensions/role/planner.js.map +1 -1
- package/dist/genus/prime-principle.d.ts +10 -0
- package/dist/genus/prime-principle.js +16 -0
- package/dist/genus/prime-principle.js.map +1 -0
- package/dist/hooks/deploy-drift-notice.js +9 -9
- package/dist/hooks/deploy-drift-notice.js.map +1 -1
- package/dist/hooks/purview-guardrail.js +134 -57
- package/dist/hooks/purview-guardrail.js.map +1 -1
- package/dist/hooks/stance-guardrail-pre.js +105 -42
- package/dist/hooks/stance-guardrail-pre.js.map +1 -1
- package/dist/hooks/stance-guardrail.js +161 -57
- package/dist/hooks/stance-guardrail.js.map +1 -1
- package/dist/index.js +1 -4
- package/dist/index.js.map +1 -1
- package/dist/manifest.d.ts +3 -2
- package/dist/manifest.js +6 -6
- package/dist/manifest.js.map +1 -1
- package/dist/roles/architect.js +27 -22
- package/dist/roles/architect.js.map +1 -1
- package/dist/roles/assayer.js +9 -7
- package/dist/roles/assayer.js.map +1 -1
- package/dist/roles/hold.d.ts +1 -1
- package/dist/roles/hold.js +5 -2
- package/dist/roles/hold.js.map +1 -1
- package/dist/roles/implementer.js +15 -5
- package/dist/roles/implementer.js.map +1 -1
- package/dist/roles/integrator.d.ts +2 -0
- package/dist/roles/integrator.js +51 -0
- package/dist/roles/integrator.js.map +1 -0
- package/dist/roles/planner.js +6 -5
- package/dist/roles/planner.js.map +1 -1
- package/dist/skills/create-skill/skill.js +2 -0
- package/dist/skills/create-skill/skill.js.map +1 -1
- package/dist/skills/deliver/skill.js +59 -130
- package/dist/skills/deliver/skill.js.map +1 -1
- package/dist/skills/design/skill.js +20 -10
- package/dist/skills/design/skill.js.map +1 -1
- package/dist/skills/exemplify/skill.js +2 -0
- package/dist/skills/exemplify/skill.js.map +1 -1
- package/dist/skills/formalize/skill.js +2 -0
- package/dist/skills/formalize/skill.js.map +1 -1
- package/dist/skills/introspect/skill.js +2 -0
- package/dist/skills/introspect/skill.js.map +1 -1
- package/dist/skills/materialize/skill.js +2 -0
- package/dist/skills/materialize/skill.js.map +1 -1
- package/dist/skills/plan/skill.js +30 -32
- package/dist/skills/plan/skill.js.map +1 -1
- package/dist/skills/probe/skill.js +2 -0
- package/dist/skills/probe/skill.js.map +1 -1
- package/dist/skills/signify/skill.js +2 -0
- package/dist/skills/signify/skill.js.map +1 -1
- package/package.json +4 -4
- package/dist/genus/founding-doctrine.d.ts +0 -7
- package/dist/genus/founding-doctrine.js +0 -13
- package/dist/genus/founding-doctrine.js.map +0 -1
|
@@ -1,12 +1,29 @@
|
|
|
1
1
|
// The bottom arrow, and the only one that writes the substrate. `C ∉ implementer` is not
|
|
2
2
|
// a deprivation: it is half of the two-description property that makes validation an
|
|
3
|
-
// operation at all. An
|
|
3
|
+
// operation at all. An implementer holding the design would be checking its own work
|
|
4
4
|
// against its own terms, which is the closed loop the ladder exists to open.
|
|
5
|
-
|
|
5
|
+
//
|
|
6
|
+
// WHAT LEAVES THIS POSITION IS THE ARTIFACT AND A NAME, NEVER AN ACCOUNT. The artifact is
|
|
7
|
+
// committed on the implementer's own branch and the return is `landed <unit> of <plan> at
|
|
8
|
+
// <commit>` or `blocked <unit> of <plan>: spec` and nothing else, so the layer above
|
|
9
|
+
// holds an address and nothing to be persuaded by. Acceptance rests on the assayer, who
|
|
10
|
+
// reads the shard and the files at that commit and never the spec or this position's
|
|
11
|
+
// words: a description of its own work handed up by the builder is one description
|
|
12
|
+
// judging itself, which is the closed loop again. What the implementer could not prove,
|
|
13
|
+
// and any finding it meets beside the path, is still owed to someone; it goes out as a
|
|
14
|
+
// note, the design's one channel for a delegate's finding, and not up through the return.
|
|
15
|
+
// A verdict of not achieved comes back to this same implementer, who amends the same
|
|
16
|
+
// unit.
|
|
17
|
+
export const implementer = `implementer ≜ reads⟨spec · artifact⟩ → writes⟨artifact · note⟩
|
|
6
18
|
stratum ≜ intent ≺ C ≺ spec ≺ artifact ⟨≺ ≜ more-abstract-than · C ≜ durative-concept-lattice⟩
|
|
7
19
|
C ∉ implementer ⟨holds spec ¬ design · TWO-descriptions ⇒ validate ≜ operation ¬ re-reading⟩
|
|
8
|
-
|
|
20
|
+
builds ⟨ONE unit ↾ spec ALONE ¬ design⟩ ⟨own branch · commits own work⟩
|
|
21
|
+
reads(spec) ↦ \${cratylus plan show <unit> --plan <plan>} ⟨host-CLI⟩
|
|
22
|
+
reserves ⟨author(artifact) ↾ spec · verify ↾ spec-own-criteria⟩ ⟨proves ↾ spec-asked ∧ ¬ beyond⟩
|
|
9
23
|
verify ⊥ validate ⟨validate ≜ conformance(C) · C ∉ implementer⟩
|
|
10
24
|
exceeding ≜ work ≻ spec ⟨DEFECT ≅ falling-short ∧ subtler ∵ second-concept UNNAMED ⇒ UNCAUGHT downstream⟩
|
|
11
|
-
spec ¬ buildable-as-written ⇒ SURFACED ¬ reinterpreted
|
|
25
|
+
spec ¬ buildable-as-written ⇒ SURFACED ¬ reinterpreted
|
|
26
|
+
returns ⟨name ∧ ¬ account⟩ ⟨landed⟨unit · plan · commit⟩ ∨ blocked⟨unit · plan · spec⟩⟩
|
|
27
|
+
judged ↦ assayer ⟨reads shard ∧ files@commit ¬ spec ¬ account⟩ · ¬achieved ⇒ findings ↦ SAME implementer ⇒ amends SAME unit
|
|
28
|
+
¬proven ∨ finding-beside-path ↦ note ⟨¬ return⟩`;
|
|
12
29
|
//# sourceMappingURL=implementer.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"implementer.js","sourceRoot":"","sources":["../../../src/dimensions/role/implementer.ts"],"names":[],"mappings":"AAEA,yFAAyF;AACzF,qFAAqF;AACrF,
|
|
1
|
+
{"version":3,"file":"implementer.js","sourceRoot":"","sources":["../../../src/dimensions/role/implementer.ts"],"names":[],"mappings":"AAEA,yFAAyF;AACzF,qFAAqF;AACrF,qFAAqF;AACrF,6EAA6E;AAC7E,EAAE;AACF,0FAA0F;AAC1F,0FAA0F;AAC1F,qFAAqF;AACrF,wFAAwF;AACxF,qFAAqF;AACrF,mFAAmF;AACnF,wFAAwF;AACxF,uFAAuF;AACvF,0FAA0F;AAC1F,qFAAqF;AACrF,QAAQ;AAER,MAAM,CAAC,MAAM,WAAW,GAAS;;;;;;;;;;;gDAWe,CAAC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
// THE ARROW THAT MAKES APPROVED WORK WHOLE, and the one whose codomain is not a layer of
|
|
2
|
+
// the ladder at all: it writes the LINE, the place approved work accumulates, and the
|
|
3
|
+
// commits that record the plan's state. Work reaches it already judged; what it adds is a
|
|
4
|
+
// fact no unit's own proof can carry, namely that the units still hold together. That is
|
|
5
|
+
// why the check runs here, once per combination, and never at an implementer or the
|
|
6
|
+
// assayer: a whole is a property of the combination, and a unit proven alone has proven
|
|
7
|
+
// nothing about it.
|
|
8
|
+
//
|
|
9
|
+
// `writes ≠ artifact` is the seam, and it is what the purview judge quotes. Combining is
|
|
10
|
+
// a git act and running the check is a check act, and both are reserved; an Edit or a
|
|
11
|
+
// Write to a source file is the artifact codomain, outside the arrow. A red is therefore
|
|
12
|
+
// a report and never a patch: repairing on the line would hand the architect an
|
|
13
|
+
// approved-looking whole nobody judged, and would make this position the builder its own
|
|
14
|
+
// gate is meant to be independent of.
|
|
15
|
+
//
|
|
16
|
+
// The four prohibitions after `reserves` are the cell. Judging is the assayer's (the
|
|
17
|
+
// verdict arrived before this position was reached), the design is the architect's, plan
|
|
18
|
+
// state is the planner's, and main is the operator's to receive: a release is a sign-off
|
|
19
|
+
// this position asks for and never takes.
|
|
20
|
+
export const integrator = `integrator ≜ reads⟨unit · commit · line⟩ → writes⟨line · commit ⟨records⟩⟩ ⟨unit ≜ assay-verdict achieved · line ≜ integration-line ⟨¬ main⟩⟩
|
|
21
|
+
stratum ≜ intent ≺ C ≺ spec ≺ artifact ⟨≺ ≜ more-abstract-than · C ≜ durative-concept-lattice⟩
|
|
22
|
+
takes ⟨unit ↾ achieved⟩ · ¬takes ⟨unit ¬ achieved⟩
|
|
23
|
+
reserves ⟨combine ⟨unit ⇒ line⟩ · whole-check ⟨project-full-check ↾ combined-tree · ONCE ∀ combination · ∄ check @ ⟨implementer ∨ assayer⟩⟩ · commit ⟨records ⟨plan · design · note⟩ ⟨written-since⟩ · pathspec · green⟩ · report ⟨green ↦ whole(unit) · red ∨ merge-conflict ↦ ⟨unit · failing-check⟩⟩ · ask ⟨operator ⇒ release(line → main)⟩ ⟨architect ↦ plan-close⟩⟩
|
|
24
|
+
red ∨ merge-conflict ⇒ line UNCHANGED ⟨report ↦ architect ↦ implementer(unit)⟩
|
|
25
|
+
writes ≠ artifact ⇒ ∄ write ⟨source · config⟩ @ integrator ⟨combine ≠ author · check ≠ repair⟩
|
|
26
|
+
¬⟨repair · judge ⟨assay ∈ assayer⟩ · decide ⟨design ∈ architect · plan-state ∈ planner⟩ · move(main) ⟨release ≜ operator sign-off⟩⟩`;
|
|
27
|
+
//# sourceMappingURL=integrator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"integrator.js","sourceRoot":"","sources":["../../../src/dimensions/role/integrator.ts"],"names":[],"mappings":"AAEA,yFAAyF;AACzF,sFAAsF;AACtF,0FAA0F;AAC1F,yFAAyF;AACzF,oFAAoF;AACpF,wFAAwF;AACxF,oBAAoB;AACpB,EAAE;AACF,yFAAyF;AACzF,sFAAsF;AACtF,yFAAyF;AACzF,gFAAgF;AAChF,yFAAyF;AACzF,sCAAsC;AACtC,EAAE;AACF,qFAAqF;AACrF,yFAAyF;AACzF,yFAAyF;AACzF,0CAA0C;AAE1C,MAAM,CAAC,MAAM,UAAU,GAAS;;;;;;oIAMoG,CAAC"}
|
|
@@ -3,12 +3,24 @@
|
|
|
3
3
|
// while the work is bounded by where it is USED voids every disjointness proof the
|
|
4
4
|
// waves rest on.
|
|
5
5
|
//
|
|
6
|
-
//
|
|
7
|
-
//
|
|
8
|
-
//
|
|
9
|
-
|
|
6
|
+
// THE PLAN IS THIS ROLE'S, START TO END. It takes the shards the architect hands down,
|
|
7
|
+
// plans them, binds the plan when none is bound, moves each unit's state as work reaches
|
|
8
|
+
// it, closes the plan, and answers a stop by rectifying or rebuilding. What it returns to
|
|
9
|
+
// the architect is names and nothing else: the architect never reads behind a name, so a
|
|
10
|
+
// plan view or a spec that leaked upward would put the substrate back in the design-holder's
|
|
11
|
+
// hands.
|
|
12
|
+
//
|
|
13
|
+
// `writes ≠ C` is the seam. A shard that will not plan is surfaced intact, because a
|
|
14
|
+
// planner permitted to redraw the boundary it was handed is the route by which the
|
|
15
|
+
// design leaks back out into the work. The same seam runs the other way: when a shard
|
|
16
|
+
// the plan builds on is found wrong, the design is corrected by the architect and the
|
|
17
|
+
// plan is re-planned here; it is never the planner that changes the design.
|
|
18
|
+
export const planner = `planner ≜ reads⟨C · artifact⟩ → writes⟨spec · plan-records⟩
|
|
10
19
|
stratum ≜ intent ≺ C ≺ spec ≺ artifact ⟨≺ ≜ more-abstract-than · C ≜ durative-concept-lattice⟩
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
20
|
+
plan-records ≜ ⟨unit · dependency · state · plan-state⟩
|
|
21
|
+
reserves ⟨census ⟨extant · references · resolved-by-use ¬ by-declaration⟩ · decompose ⟨shards ↦ MECE-units · unit ⇀ ONE shard · deps FIRST · effort(unit) ≤ capacity · how-per-harness ⟨plan-owned ¬ shard-owned⟩⟩ · realizes ⟨unit ⇀ anchor⟩ · sequence ⟨waves ⊨ disjoint-outputs⟩ · bind ⟨@ ratification ∧ ∄ plan-bound⟩ · record ⟨ready-unit ↦ active @ name-handed-out · unit ↦ completed @ whole⟩ · close ⟨∀ unit completed⟩ · rectify ∨ rebuild ⟨plan @ stop⟩ · reconcile ⟨plans ∧ units⟩⟩
|
|
22
|
+
returns ⟨plan-name ∧ ready-unit-names⟩ ∧ ¬ spec ∨ plan-view ⟨name ≜ address · architect ¬ reads behind⟩
|
|
23
|
+
state(unit) ∨ state(plan) moves ⊨ planner ⟨bind ∨ close ∨ advance · ∄ move @ implementer ∨ architect⟩
|
|
24
|
+
writes ≠ C ⇒ shard GIVEN ⟨shard ¬ plannable ⇒ SURFACED ¬ redrawn · wrong-shard ⇒ plan re-planned ¬ design changed⟩
|
|
25
|
+
writes ≠ artifact ⇒ ∄ build @ planner ⟨unit ≜ spec · implementer builds⟩`;
|
|
14
26
|
//# sourceMappingURL=planner.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"planner.js","sourceRoot":"","sources":["../../../src/dimensions/role/planner.ts"],"names":[],"mappings":"AAEA,oFAAoF;AACpF,oFAAoF;AACpF,mFAAmF;AACnF,iBAAiB;AACjB,EAAE;AACF,
|
|
1
|
+
{"version":3,"file":"planner.js","sourceRoot":"","sources":["../../../src/dimensions/role/planner.ts"],"names":[],"mappings":"AAEA,oFAAoF;AACpF,oFAAoF;AACpF,mFAAmF;AACnF,iBAAiB;AACjB,EAAE;AACF,uFAAuF;AACvF,yFAAyF;AACzF,0FAA0F;AAC1F,yFAAyF;AACzF,6FAA6F;AAC7F,SAAS;AACT,EAAE;AACF,qFAAqF;AACrF,mFAAmF;AACnF,sFAAsF;AACtF,sFAAsF;AACtF,4EAA4E;AAE5E,MAAM,CAAC,MAAM,OAAO,GAAS;;;;;;;yEAO4C,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The prime principle, as a leading `## Prime Principle` block emitted VERBATIM
|
|
3
|
+
* as the first section of a SKILL.md, set as `preamble` on exactly the skills
|
|
4
|
+
* whose laws apply it: those that name concepts by anchor, optimal sign or cold
|
|
5
|
+
* decode. An agent carries the axiom through its held role's
|
|
6
|
+
* engineering-principles, never through this block. The apex seed: the
|
|
7
|
+
* `cratylism` ground axiom + the intrinsic-carry clause, and nothing whose truth
|
|
8
|
+
* is contingent on this workspace.
|
|
9
|
+
*/
|
|
10
|
+
export declare const primePrinciple: string;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { cratylism } from '../dimensions/engineering-principles/cratylism.js';
|
|
2
|
+
/**
|
|
3
|
+
* The prime principle, as a leading `## Prime Principle` block emitted VERBATIM
|
|
4
|
+
* as the first section of a SKILL.md, set as `preamble` on exactly the skills
|
|
5
|
+
* whose laws apply it: those that name concepts by anchor, optimal sign or cold
|
|
6
|
+
* decode. An agent carries the axiom through its held role's
|
|
7
|
+
* engineering-principles, never through this block. The apex seed: the
|
|
8
|
+
* `cratylism` ground axiom + the intrinsic-carry clause, and nothing whose truth
|
|
9
|
+
* is contingent on this workspace.
|
|
10
|
+
*/
|
|
11
|
+
export const primePrinciple = `## Prime Principle
|
|
12
|
+
|
|
13
|
+
${cratylism}
|
|
14
|
+
|
|
15
|
+
intrinsic ⟨¬ ambient⟩`;
|
|
16
|
+
//# sourceMappingURL=prime-principle.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prime-principle.js","sourceRoot":"","sources":["../../src/genus/prime-principle.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,mDAAmD,CAAC;AAE9E;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG;;EAE5B,SAAS;;sBAEW,CAAC"}
|
|
@@ -97,8 +97,8 @@
|
|
|
97
97
|
// is held by a test rather than remembered.
|
|
98
98
|
//
|
|
99
99
|
// A FULL BYTE COMPARISON of every rendered artifact is therefore what runs — no
|
|
100
|
-
// digest, and above all NO SAMPLE. A
|
|
101
|
-
// reports "in sync", which is the exact failure this cell exists to end. The
|
|
100
|
+
// digest, and above all NO SAMPLE. A sample that skips the ten skills carrying the
|
|
101
|
+
// prime principle reports "in sync", which is the exact failure this cell exists to end. The
|
|
102
102
|
// `deploy-drift-notice` suite re-measures the clean path and fails on a regression, so
|
|
103
103
|
// the number above is a held bound rather than a remembered one.
|
|
104
104
|
//
|
|
@@ -117,7 +117,7 @@
|
|
|
117
117
|
// matches is now THIS harness's, because the projector substitutes this
|
|
118
118
|
// harness's hooks-file name (`harness-hooks-file`) and its own name
|
|
119
119
|
// (`harness-name`, passed to the comparator so it audits the right home). A
|
|
120
|
-
//
|
|
120
|
+
// omp session reports on the omp deployment. The pair lives on
|
|
121
121
|
// `HarnessAdapter` and reaches here through projection, which is the only stage
|
|
122
122
|
// that knows which adapter it is rendering for — the alternative was a
|
|
123
123
|
// shell-side copy of the harness registry, a second home for adapter knowledge.
|
|
@@ -196,7 +196,7 @@ export const deployDriftNotice = {
|
|
|
196
196
|
# - ADVISORY ONLY. Prints to stdout and exits 0. It never emits
|
|
197
197
|
# {"decision":"block"} — a stale deployment must not block a session.
|
|
198
198
|
# - NEVER SAMPLES. The comparison is the tool's own: whole tree, byte for byte.
|
|
199
|
-
# A
|
|
199
|
+
# A sample that skips the ten skills carrying the prime principle reports "in sync".
|
|
200
200
|
# - NOT A COUNT. It relays the tool's report, which carries the superseded lines
|
|
201
201
|
# still running and the rendered lines missing.
|
|
202
202
|
#
|
|
@@ -229,9 +229,9 @@ DEPLOY_TOOL={{fact:deploy-bin}}
|
|
|
229
229
|
|
|
230
230
|
# WHICH HARNESS THIS PROJECTION IS FOR. A hook worker is handed no identity by the
|
|
231
231
|
# session it runs in, so a worker that must LOOK at a deployed tree had to guess —
|
|
232
|
-
# and guessed claude, which made
|
|
232
|
+
# and guessed claude, which made an omp session report on a sibling deployment.
|
|
233
233
|
# These two are the adapter's own \`name\` and \`hooksFile\`, substituted at
|
|
234
|
-
# projection: the
|
|
234
|
+
# projection: the omp render of this cell carries omp's.
|
|
235
235
|
HARNESS={{fact:harness-name}}
|
|
236
236
|
HARNESS_HOOKS_FILE={{fact:harness-hooks-file}}
|
|
237
237
|
|
|
@@ -283,8 +283,8 @@ done
|
|
|
283
283
|
# A render tree is recognized by BEING one: \`agents/\` + \`skills/\` + THIS harness's
|
|
284
284
|
# own hooks file. That file is what distinguishes this harness's tree from another
|
|
285
285
|
# harness's tree sitting beside it, and it is named by projection rather than by
|
|
286
|
-
# this script — so
|
|
287
|
-
# render skips the
|
|
286
|
+
# this script — so an omp render of this worker skips the claude tree and a claude
|
|
287
|
+
# render skips the omp one. The \`--out\` dir is an operator's choice, so the tree
|
|
288
288
|
# is discovered, never named.
|
|
289
289
|
#
|
|
290
290
|
# THE GLOB USED TO BE \`.render*\`, WHICH MADE THE PARAGRAPH ABOVE FALSE. The shape
|
|
@@ -376,7 +376,7 @@ if [ -z "$cli" ]; then
|
|
|
376
376
|
fi
|
|
377
377
|
|
|
378
378
|
# \`--harness\` is what makes the audited HOME this session's. Without it the tool
|
|
379
|
-
# resolves its default root, so
|
|
379
|
+
# resolves its default root, so an omp tree would be compared against the claude
|
|
380
380
|
# deployment — a report that is about neither.
|
|
381
381
|
# The tool reports and repairs nothing, so it is safe to point at a host mid-work.
|
|
382
382
|
set +e
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deploy-drift-notice.js","sourceRoot":"","sources":["../../src/hooks/deploy-drift-notice.ts"],"names":[],"mappings":"AAEA,kFAAkF;AAClF,kEAAkE;AAClE,EAAE;AACF,oFAAoF;AACpF,qFAAqF;AACrF,gFAAgF;AAChF,sFAAsF;AACtF,0EAA0E;AAC1E,mFAAmF;AACnF,gFAAgF;AAChF,qFAAqF;AACrF,EAAE;AACF,sFAAsF;AACtF,sFAAsF;AACtF,qFAAqF;AACrF,iFAAiF;AACjF,8BAA8B;AAC9B,EAAE;AACF,qFAAqF;AACrF,sFAAsF;AACtF,oFAAoF;AACpF,uFAAuF;AACvF,kFAAkF;AAClF,2BAA2B;AAC3B,EAAE;AACF,sFAAsF;AACtF,oFAAoF;AACpF,kEAAkE;AAClE,EAAE;AACF,mFAAmF;AACnF,oFAAoF;AACpF,kFAAkF;AAClF,kFAAkF;AAClF,oFAAoF;AACpF,oFAAoF;AACpF,mFAAmF;AACnF,+BAA+B;AAC/B,EAAE;AACF,qFAAqF;AACrF,qFAAqF;AACrF,oFAAoF;AACpF,oFAAoF;AACpF,uFAAuF;AACvF,sFAAsF;AACtF,kFAAkF;AAClF,mFAAmF;AACnF,uFAAuF;AACvF,EAAE;AACF,uFAAuF;AACvF,qFAAqF;AACrF,uFAAuF;AACvF,wFAAwF;AACxF,wFAAwF;AACxF,yFAAyF;AACzF,yFAAyF;AACzF,yFAAyF;AACzF,0FAA0F;AAC1F,wFAAwF;AACxF,0BAA0B;AAC1B,EAAE;AACF,sFAAsF;AACtF,mFAAmF;AACnF,yFAAyF;AACzF,oFAAoF;AACpF,uEAAuE;AACvE,EAAE;AACF,mFAAmF;AACnF,8CAA8C;AAC9C,gFAAgF;AAChF,2EAA2E;AAC3E,EAAE;AACF,qFAAqF;AACrF,oFAAoF;AACpF,qFAAqF;AACrF,8BAA8B;AAC9B,gDAAgD;AAChD,gDAAgD;AAChD,oFAAoF;AACpF,6EAA6E;AAC7E,qFAAqF;AACrF,kFAAkF;AAClF,sFAAsF;AACtF,oFAAoF;AACpF,EAAE;AACF,sFAAsF;AACtF,mFAAmF;AACnF,wFAAwF;AACxF,gDAAgD;AAChD,gDAAgD;AAChD,qFAAqF;AACrF,sFAAsF;AACtF,sFAAsF;AACtF,wFAAwF;AACxF,qFAAqF;AACrF,sFAAsF;AACtF,sFAAsF;AACtF,4CAA4C;AAC5C,EAAE;AACF,gFAAgF;AAChF,
|
|
1
|
+
{"version":3,"file":"deploy-drift-notice.js","sourceRoot":"","sources":["../../src/hooks/deploy-drift-notice.ts"],"names":[],"mappings":"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"}
|
|
@@ -23,13 +23,15 @@
|
|
|
23
23
|
// every agent in the corpus composed the fragment it claimed to enforce.
|
|
24
24
|
//
|
|
25
25
|
// WHAT IT BLOCKS is what the arrow excludes, and nothing else:
|
|
26
|
-
// · a dispatch
|
|
27
|
-
//
|
|
26
|
+
// · a dispatch carrying a spec the dispatcher wrote, from a holder whose arrow does
|
|
27
|
+
// not write spec — the architect skipping the planner, who alone turns a shard into
|
|
28
|
+
// units;
|
|
28
29
|
// · a write to the substrate by a holder whose arrow does not write artifact;
|
|
29
|
-
// · a dispatch whose prompt is the operator's literal words rather than a
|
|
30
|
+
// · a dispatch whose prompt is the operator's literal words rather than a routed name
|
|
30
31
|
// — the same dispatch-echo the stance guard catches at turn end, refused here
|
|
31
32
|
// because at this moment the contract that convicts it is the ROLE's.
|
|
32
|
-
// WHAT IT PASSES: a dispatch to a planner, a dispatch
|
|
33
|
+
// WHAT IT PASSES: a dispatch to a planner, a dispatch routing a unit name to an
|
|
34
|
+
// implementer, a dispatch to an assayer, a dispatch to the integrator, READING anything,
|
|
33
35
|
// and writing whatever the arrow reserves. Reading is never a block — the architect's
|
|
34
36
|
// contract makes an artifact read a descent, but a read is cheap to undo and a gate
|
|
35
37
|
// that fires on one would wedge every legitimate orientation.
|
|
@@ -40,8 +42,10 @@
|
|
|
40
42
|
// error than a missed one.
|
|
41
43
|
export const purviewGuardrail = {
|
|
42
44
|
id: 'purview-guardrail',
|
|
43
|
-
residue: 'structural-refusal ↾ mid-turn act ∉ role-arrow · deny-before-fire ⟨descent ⟨write(artifact) ∉ writes⟩ · skipped-rung ⟨dispatch(
|
|
45
|
+
residue: 'structural-refusal ↾ mid-turn act ∉ role-arrow · deny-before-fire ⟨descent ⟨write(artifact) ∉ writes⟩ · skipped-rung ⟨dispatch(spec the dispatcher wrote) ∄ planner⟩ · dispatch-echo ⟨literal-words ≠ routed-name⟩⟩ · pass ⟨read · act ∈ reserves · dispatch ↦ plan ∨ implement(unit-name) ∨ assay ∨ integrate⟩ · law = the HOLDER-projected role-section ⟨quoted verbatim · ¬ authored-opinion⟩ · shared judge-backend ⟨sibling⟩ · fail-open ∧ evidence-checked ∧ re-entry-capped',
|
|
44
46
|
substrate: 'harness',
|
|
47
|
+
// Bound by holding a role at all: the arrow it judges against is the role's own.
|
|
48
|
+
binds: { dimension: 'role' },
|
|
45
49
|
order: 1,
|
|
46
50
|
events: ['subagent.dispatch.pre', 'tool.use.pre'],
|
|
47
51
|
entry: 'purview-guardrail.sh',
|
|
@@ -69,19 +73,82 @@ export const purviewGuardrail = {
|
|
|
69
73
|
# - CONTRACT-ENROLLED, one step further. A persona whose Target carries no \`## Role\`
|
|
70
74
|
# section has no arrow to be outside of, so it is allowed. A gate cannot convict
|
|
71
75
|
# against a law that was never declared.
|
|
72
|
-
# - FAILS OPEN. Any error (no jq, no Target, judge failure
|
|
76
|
+
# - FAILS OPEN, NEVER SILENTLY. Any error (no jq, no input, no Target, judge failure,
|
|
77
|
+
# unparseable verdict, unexpected error) -> exit 0, and the call goes through WITH A NOTICE
|
|
78
|
+
# the operator reads (\`say\`: Claude Code's JSON \`systemMessage\`, omp's relayed line) naming
|
|
79
|
+
# this guard and why it could not judge. Silence is reserved for "judged, pass", "not
|
|
80
|
+
# enrolled" and "no arrow declared".
|
|
73
81
|
# - EVIDENCE-CHECKED. A BLOCK must quote a span that is literally present in the
|
|
74
|
-
# payload; a citation that is not there is a fabricated block and is DISCARDED
|
|
75
|
-
#
|
|
82
|
+
# payload; a citation that is not there is a fabricated block and is DISCARDED — and the
|
|
83
|
+
# discard is said, since no verdict then stands.
|
|
84
|
+
# - LOOP-SAFE. A re-entry cap: never deny an identical tool_input twice. The second,
|
|
85
|
+
# identical call goes through unjudged, and says so.
|
|
76
86
|
#
|
|
77
87
|
# INPUT : Claude Code PreToolUse hook JSON on stdin.
|
|
78
88
|
# OUTPUT : on a purview breach -> a deny decision on stdout + exit 0.
|
|
79
|
-
#
|
|
89
|
+
# judged, pass -> no stdout + exit 0.
|
|
90
|
+
# let through with no verdict -> the notice \`say\` prints + exit 0.
|
|
80
91
|
#
|
|
81
|
-
# POSIX sh. Depends on: jq. Missing jq ->
|
|
92
|
+
# POSIX sh. Depends on: jq. Missing jq -> the guard says so and allows the call.
|
|
82
93
|
|
|
83
94
|
set -eu
|
|
84
95
|
|
|
96
|
+
# WHAT AN OPERATOR READS WHEN THE GUARD CANNOT JUDGE, defined before anything that needs a
|
|
97
|
+
# command: the first thing that can be missing is \`jq\`, and a worker run with a PATH holding
|
|
98
|
+
# little beyond \`sh\` and \`cat\` must still say it did not judge, so \`esc\`, \`say\` and \`open\`
|
|
99
|
+
# are builtins only and nothing external runs above the jq check.
|
|
100
|
+
#
|
|
101
|
+
# Claude Code shows the operator a hook's JSON \`systemMessage\` and NOT its plain stdout on
|
|
102
|
+
# exit 0. omp's extension bridge reads the worker's plain stdout, and would relay a JSON object
|
|
103
|
+
# as raw JSON — hence one form per harness, chosen at projection by the harness's own name.
|
|
104
|
+
esc() {
|
|
105
|
+
_in="$1"
|
|
106
|
+
_out=""
|
|
107
|
+
_nl="$(printf '\\nx')"
|
|
108
|
+
_nl="\${_nl%x}"
|
|
109
|
+
_tab="$(printf '\\t')"
|
|
110
|
+
_cr="$(printf '\\r')"
|
|
111
|
+
while [ -n "$_in" ]; do
|
|
112
|
+
_rest="\${_in#?}"
|
|
113
|
+
_c="\${_in%"$_rest"}"
|
|
114
|
+
case "$_c" in
|
|
115
|
+
'\\') _c='\\\\' ;;
|
|
116
|
+
'"') _c='\\"' ;;
|
|
117
|
+
"$_nl") _c='\\n' ;;
|
|
118
|
+
"$_tab") _c='\\t' ;;
|
|
119
|
+
"$_cr") _c='\\r' ;;
|
|
120
|
+
esac
|
|
121
|
+
_out="$_out$_c"
|
|
122
|
+
_in="$_rest"
|
|
123
|
+
done
|
|
124
|
+
printf '%s' "$_out"
|
|
125
|
+
}
|
|
126
|
+
say() {
|
|
127
|
+
case "{{fact:harness-name}}" in
|
|
128
|
+
claude) printf '{"systemMessage":"%s"}\\n' "$(esc "$1")" ;;
|
|
129
|
+
*) printf '%s\\n' "$1" ;;
|
|
130
|
+
esac
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
allow() { exit 0; }
|
|
134
|
+
|
|
135
|
+
# A verdict and a failure are different facts and silence carries only one of them: \`allow\`
|
|
136
|
+
# means "judged, pass" or "not this guard's call", \`open\` means "could not judge" — the call
|
|
137
|
+
# still proceeds, and the operator is told.
|
|
138
|
+
open() {
|
|
139
|
+
[ -z "\${LOG:-}" ] || printf '%s\\n' "open: $1 tool=\${tool_name:-?} agent=\${agent_type:-?}" >> "$LOG" 2>/dev/null || true
|
|
140
|
+
say "PURVIEW GUARDRAIL — DARK: $1. This call was NOT judged; the absence of a deny is an absence of a verdict, not a clean one."
|
|
141
|
+
exit 0
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
# A PreToolUse hook must never break a session. An unexpected error (a nonzero status reaching
|
|
145
|
+
# the trap) is let through AND SAID; every deliberate \`exit 0\` arrives with status 0.
|
|
146
|
+
trap 'rc=$?; [ "$rc" -eq 0 ] || open "an unexpected error stopped it (exit status $rc)"; exit 0' EXIT
|
|
147
|
+
|
|
148
|
+
input="$(cat)"
|
|
149
|
+
[ -n "$input" ] || open "the hook received no input"
|
|
150
|
+
command -v jq >/dev/null 2>&1 || open "jq is not installed, so the hook payload cannot be read"
|
|
151
|
+
|
|
85
152
|
# The sibling Stop hook's deployed dir owns the SHARED judge backend, resolved from
|
|
86
153
|
# this script's own location exactly as the pre-hook resolves it — every hooks root
|
|
87
154
|
# holds the hook dirs as siblings, so this derivation is true at every site this file
|
|
@@ -94,33 +161,32 @@ RUBRIC="\${PURVIEW_RUBRIC:-$NEUTRAL_ROOT/purview-guardrail/purview-judge-prompt.
|
|
|
94
161
|
JUDGE_CMD="\${STANCE_JUDGE_CMD:-sh $JUDGE_DIR/stance-judge.sh}"
|
|
95
162
|
LOG="\${PURVIEW_GUARD_LOG:-$SELF_DIR/misses.log}"
|
|
96
163
|
|
|
97
|
-
trap 'exit 0' EXIT
|
|
98
|
-
|
|
99
|
-
allow() { exit 0; }
|
|
100
|
-
note() { printf '%s\\n' "$1" >> "$LOG" 2>/dev/null || true; }
|
|
101
|
-
|
|
102
|
-
input="$(cat)"
|
|
103
|
-
[ -n "$input" ] || allow
|
|
104
|
-
command -v jq >/dev/null 2>&1 || allow
|
|
105
|
-
|
|
106
164
|
cwd="$(printf '%s' "$input" | jq -r '.cwd // empty' 2>/dev/null || true)"
|
|
107
165
|
[ -n "$cwd" ] && cd "$cwd" 2>/dev/null || true
|
|
108
166
|
|
|
109
167
|
# --- scope gate: the persona's OWN stance manifest -------------------------------------------
|
|
168
|
+
# The scope is the one the harness hands over: \`stance_scope\` where a dispatcher sits in the
|
|
169
|
+
# persona's own scope (omp), else the persona directory of the agent the payload NAMES
|
|
170
|
+
# (\`agent_type\`, Claude Code — none on a bare session) under this harness's home, one hop above
|
|
171
|
+
# the hooks root. Presence of the manifest is enrollment; no agent list lives here.
|
|
110
172
|
stance_scope="$(printf '%s' "$input" | jq -r '.stance_scope // empty' 2>/dev/null || true)"
|
|
111
|
-
[ -
|
|
112
|
-
|
|
173
|
+
if [ -z "$stance_scope" ]; then
|
|
174
|
+
named="$(printf '%s' "$input" | jq -r '.agent_type // empty' 2>/dev/null || true)"
|
|
175
|
+
case "$named" in '' | */* | . | ..) allow ;; esac
|
|
176
|
+
stance_scope="$(dirname -- "$HOOKS_ROOT")/{{fact:harness-persona-root}}/$named"
|
|
177
|
+
fi
|
|
178
|
+
manifest="$stance_scope/{{fact:stance-manifest}}"
|
|
113
179
|
[ -f "$manifest" ] || allow
|
|
114
180
|
agent_type="$(jq -r '.agent // empty' "$manifest" 2>/dev/null || true)"
|
|
115
|
-
[ -n "$agent_type" ] ||
|
|
181
|
+
[ -n "$agent_type" ] || open "the stance manifest at $manifest names no agent, so there is no declared contract to judge against"
|
|
116
182
|
|
|
117
183
|
# --- the LAW: this persona's own projected role contract -------------------------------------
|
|
118
|
-
# A persona scope is \`<root>/
|
|
119
|
-
# from is
|
|
120
|
-
# shape of derivation the judge path above uses. Overridable for test rigs.
|
|
184
|
+
# A persona scope is \`<root>/personas/<name>\` (claude) or \`<root>/agent/personas/<name>\` (omp), and
|
|
185
|
+
# the Target it was projected from is \`agents/<name>.md\` beside \`personas/\` — two levels out and
|
|
186
|
+
# back down, the same shape of derivation the judge path above uses. Overridable for test rigs.
|
|
121
187
|
AGENT_ROOT="$(dirname -- "$(dirname -- "$stance_scope")")"
|
|
122
188
|
AGENT_MD="\${PURVIEW_AGENT_MD:-$AGENT_ROOT/agents/$agent_type.md}"
|
|
123
|
-
[ -f "$AGENT_MD" ] ||
|
|
189
|
+
[ -f "$AGENT_MD" ] || open "the agent's projected Target is not at $AGENT_MD, so its declared contract cannot be read"
|
|
124
190
|
contract="$(awk '/^## Role$/{f=1;next} /^## /{f=0} f' "$AGENT_MD" 2>/dev/null || true)"
|
|
125
191
|
# A contract that is a BARE TOKEN states no arrow, so there is nothing to be outside
|
|
126
192
|
# of. Only a multi-line contract is scoreable, and saying so here is what keeps the
|
|
@@ -129,13 +195,13 @@ contract="$(awk '/^## Role$/{f=1;next} /^## /{f=0} f' "$AGENT_MD" 2>/dev/null ||
|
|
|
129
195
|
|
|
130
196
|
# --- extract the judged payload, branched by act ---------------------------------------------
|
|
131
197
|
tool_name="$(printf '%s' "$input" | jq -r '.tool_name // empty' 2>/dev/null || true)"
|
|
132
|
-
[ -n "$tool_name" ] ||
|
|
198
|
+
[ -n "$tool_name" ] || open "the payload names no tool, so there is no call to judge"
|
|
133
199
|
|
|
134
200
|
case "$tool_name" in
|
|
135
201
|
Agent|SendMessage|Task)
|
|
136
202
|
body="$(printf '%s' "$input" | jq -r '.tool_input.prompt // .tool_input.message // .tool_input.description // ""' 2>/dev/null || true)"
|
|
137
203
|
target="$(printf '%s' "$input" | jq -r '.tool_input.subagent_type // .tool_input.agent // .tool_input.name // ""' 2>/dev/null || true)"
|
|
138
|
-
act="DISPATCH to \\\`\${target:-unnamed}\\\` (codomain:
|
|
204
|
+
act="DISPATCH to \\\`\${target:-unnamed}\\\` (codomain: route when it carries a unit name and address only, spec when it carries instructions the dispatcher wrote)"
|
|
139
205
|
;;
|
|
140
206
|
Write|Edit|MultiEdit|NotebookEdit)
|
|
141
207
|
body="$(printf '%s' "$input" | jq -r '.tool_input.file_path // .tool_input.path // .tool_input.notebook_path // ""' 2>/dev/null || true)"
|
|
@@ -160,28 +226,32 @@ $body"
|
|
|
160
226
|
session_id="$(printf '%s' "$input" | jq -r '.session_id // "nosession"' 2>/dev/null || echo nosession)"
|
|
161
227
|
sig="$(printf '%s' "$input" | jq -c '.tool_input' 2>/dev/null | cksum | cut -d' ' -f1 2>/dev/null || echo 0)"
|
|
162
228
|
seen="\${TMPDIR:-/tmp}/.purview-pre-$session_id-$sig"
|
|
163
|
-
[ -f "$seen" ] &&
|
|
229
|
+
[ -f "$seen" ] && open "this exact call was already denied once, so the re-entry cap lets it through unjudged"
|
|
164
230
|
|
|
165
231
|
# --- judge (SHARED backend, OWN rubric) -----------------------------------------------------
|
|
166
|
-
|
|
232
|
+
# THE SAME SEAM, UNDER THE SAME NAMES, as the two stance workers: a host that holds a model
|
|
233
|
+
# runs this worker twice around a judgment it makes itself (\`STANCE_EMIT_PAYLOAD\` to receive
|
|
234
|
+
# the payload and rubric, \`STANCE_VERDICT_FILE\` naming the answer). This one read
|
|
235
|
+
# \`PURVIEW_\`-prefixed names of its own, so the omp bridge — which speaks the shared names —
|
|
236
|
+
# got no payload back and purview judged nothing there, on every call, while reading as a
|
|
237
|
+
# guard that had found nothing.
|
|
238
|
+
if [ -n "\${STANCE_EMIT_PAYLOAD:-}" ]; then
|
|
167
239
|
jq -cn --arg r "$RUBRIC" --arg p "$payload" '{rubric:$r, payload:$p}'
|
|
168
240
|
exit 0
|
|
169
241
|
fi
|
|
170
|
-
if [ -n "\${
|
|
171
|
-
verdict="$(cat "\${
|
|
172
|
-
[ -n "$verdict" ] ||
|
|
173
|
-
note "$(date -u +%Y-%m-%dT%H:%M:%SZ) judge-empty tool=$tool_name agent=$agent_type"
|
|
174
|
-
allow
|
|
175
|
-
}
|
|
242
|
+
if [ -n "\${STANCE_VERDICT_FILE:-}" ]; then
|
|
243
|
+
verdict="$(cat "\${STANCE_VERDICT_FILE}" 2>/dev/null || true)"
|
|
244
|
+
[ -n "$verdict" ] || open "the judge did not answer"
|
|
176
245
|
else
|
|
177
|
-
verdict="$(printf '%s' "$payload" | $JUDGE_CMD "$RUBRIC" 2>/dev/null)" ||
|
|
178
|
-
note "$(date -u +%Y-%m-%dT%H:%M:%SZ) judge-fail tool=$tool_name agent=$agent_type"
|
|
179
|
-
allow
|
|
180
|
-
}
|
|
246
|
+
verdict="$(printf '%s' "$payload" | $JUDGE_CMD "$RUBRIC" 2>/dev/null)" || open "the judge did not answer"
|
|
181
247
|
fi
|
|
182
248
|
|
|
183
|
-
decision="$(printf '%s\\n' "$verdict" | sed -n 's/^VERDICT:[[:space:]]*//p' | head -1)"
|
|
184
|
-
|
|
249
|
+
decision="$(printf '%s\\n' "$verdict" | sed -n 's/^VERDICT:[[:space:]]*//p' | head -1 | sed 's/[[:space:]]*$//')"
|
|
250
|
+
case "$decision" in
|
|
251
|
+
PASS) allow ;; # judged, pass: the one silent verdict
|
|
252
|
+
BLOCK) ;;
|
|
253
|
+
*) open "the judge's verdict was unparseable (no VERDICT: PASS or VERDICT: BLOCK line)" ;;
|
|
254
|
+
esac
|
|
185
255
|
|
|
186
256
|
reason="$(printf '%s\\n' "$verdict" | sed -n 's/^REASON:[[:space:]]*//p' | head -1)"
|
|
187
257
|
[ -n "$reason" ] || reason="This act falls outside the arrow your role contract declares."
|
|
@@ -193,8 +263,9 @@ reason="$(printf '%s\\n' "$verdict" | sed -n 's/^REASON:[[:space:]]*//p' | head
|
|
|
193
263
|
cited="$(printf '%s\\n' "$verdict" | sed -n 's/^SPAN:[[:space:]]*//p' | head -1)"
|
|
194
264
|
if [ -n "$cited" ]; then
|
|
195
265
|
printf '%s' "$payload" | grep -qF -- "$cited" || {
|
|
196
|
-
|
|
197
|
-
|
|
266
|
+
[ -z "\${LOG:-}" ] || printf '%s\\n' "block-discarded: span=$cited tool=$tool_name agent=$agent_type" >> "$LOG" 2>/dev/null || true
|
|
267
|
+
say "PURVIEW GUARDRAIL — BLOCK DISCARDED: the judge blocked this call but cited a span that is not in it (fabricated): $cited. No verdict stands; this call was NOT judged clean."
|
|
268
|
+
exit 0
|
|
198
269
|
}
|
|
199
270
|
fi
|
|
200
271
|
|
|
@@ -202,10 +273,11 @@ fi
|
|
|
202
273
|
|
|
203
274
|
feedback="PURVIEW GUARDRAIL — denied this $tool_name call: it falls outside the arrow your own \\
|
|
204
275
|
role contract declares. $reason Delegation is a THEOREM of that arrow, not an option: an act whose \\
|
|
205
|
-
domain or codomain lies outside it goes to the role that owns it — a decomposition
|
|
206
|
-
build to an implementer, an artifact reading to an assayer
|
|
207
|
-
|
|
208
|
-
|
|
276
|
+
domain or codomain lies outside it goes to the role that owns it — a decomposition of a shard to a \\
|
|
277
|
+
planner, a build to an implementer, an artifact reading to an assayer, a merge or a whole check to \\
|
|
278
|
+
the integrator. Hand it over by name and carry on with what the contract reserves. (Legitimate and \\
|
|
279
|
+
NOT blocked here: reading anything, dispatching to a planner, routing a unit name to an implementer, \\
|
|
280
|
+
an assayer or the integrator, and performing any act the contract's own \\\`reserves\\\` clause names.)"
|
|
209
281
|
|
|
210
282
|
jq -cn --arg r "$feedback" '{hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"deny",permissionDecisionReason:$r}}'
|
|
211
283
|
exit 0
|
|
@@ -251,7 +323,9 @@ durative concept lattice — the design.
|
|
|
251
323
|
|
|
252
324
|
An act has a **domain** (the layer it consumes) and a **codomain** (the layer it produces):
|
|
253
325
|
|
|
254
|
-
- a DISPATCH
|
|
326
|
+
- a DISPATCH that carries a unit name and its address only produces a **route**; a DISPATCH that
|
|
327
|
+
carries instructions the dispatcher wrote produces a **spec** — those instructions are the layer
|
|
328
|
+
being written;
|
|
255
329
|
- a WRITE to a source or config file produces an **artifact**;
|
|
256
330
|
- reading anything at all produces **nothing**, and is never a breach.
|
|
257
331
|
|
|
@@ -263,20 +337,23 @@ whole test, and it is mechanical.
|
|
|
263
337
|
- **A write whose codomain is \`artifact\` by a holder whose \`writes\` set excludes \`artifact\`.**
|
|
264
338
|
The contract usually names this: \`descent\`. The path in the payload is the evidence.
|
|
265
339
|
- **A dispatch whose codomain is \`spec\` by a holder whose \`writes\` set excludes \`spec\`.** This is
|
|
266
|
-
the skipped rung: a holder that writes only the design has handed a delegate
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
340
|
+
the skipped rung: a holder that writes only the design and its routes has handed a delegate
|
|
341
|
+
instructions it wrote itself, where only a planner turns a shard into units. The prompt is the
|
|
342
|
+
evidence.
|
|
343
|
+
- **A dispatch whose prompt is the operator's literal words rather than a routed name.** The
|
|
344
|
+
contract that convicts this is the same clause: transcription is not authorship, and a dispatch
|
|
345
|
+
carries a name, not instructions. Evidence is the prompt reading as relayed instructions rather
|
|
346
|
+
than a unit name with its address.
|
|
272
347
|
|
|
273
348
|
## What to PASS — and these are the majority
|
|
274
349
|
|
|
275
350
|
- **Any read.** Reading is outside the test by construction. Even where a contract calls
|
|
276
351
|
artifact-reading a descent, that is a standing discipline, not a mid-turn refusal.
|
|
277
352
|
- **A dispatch to a role the contract explicitly routes to.** Contracts name their delegations
|
|
278
|
-
(\`⟨C → spec⟩ ↦
|
|
279
|
-
|
|
353
|
+
(\`⟨C → spec⟩ ↦ planner\`, \`⟨spec → artifact⟩ ↦ implementer\`, \`⟨artifact → C⟩ ↦ assayer\`, the
|
|
354
|
+
integrator for gate, merge and record). A dispatch to a planner, a dispatch routing a unit name
|
|
355
|
+
to an implementer, a dispatch to an assayer and a dispatch to the integrator are the arrow
|
|
356
|
+
WORKING, whether the contract's \`writes\` names \`route\` or not.
|
|
280
357
|
- **Any act the \`reserves\` clause names**, whatever it is.
|
|
281
358
|
- **A write by a holder whose \`writes\` set includes \`artifact\`.** Most agents in most corpora
|
|
282
359
|
build. Do not read a contract's other clauses as narrowing an arrow that plainly permits the act.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"purview-guardrail.js","sourceRoot":"","sources":["../../src/hooks/purview-guardrail.ts"],"names":[],"mappings":"AAEA,qEAAqE;AACrE,EAAE;AACF,oEAAoE;AACpE,oFAAoF;AACpF,mFAAmF;AACnF,kFAAkF;AAClF,qBAAqB;AACrB,EAAE;AACF,iFAAiF;AACjF,uFAAuF;AACvF,uFAAuF;AACvF,uFAAuF;AACvF,mFAAmF;AACnF,wFAAwF;AACxF,EAAE;AACF,sFAAsF;AACtF,oFAAoF;AACpF,uFAAuF;AACvF,uFAAuF;AACvF,uFAAuF;AACvF,+EAA+E;AAC/E,sFAAsF;AACtF,yEAAyE;AACzE,EAAE;AACF,+DAA+D;AAC/D,
|
|
1
|
+
{"version":3,"file":"purview-guardrail.js","sourceRoot":"","sources":["../../src/hooks/purview-guardrail.ts"],"names":[],"mappings":"AAEA,qEAAqE;AACrE,EAAE;AACF,oEAAoE;AACpE,oFAAoF;AACpF,mFAAmF;AACnF,kFAAkF;AAClF,qBAAqB;AACrB,EAAE;AACF,iFAAiF;AACjF,uFAAuF;AACvF,uFAAuF;AACvF,uFAAuF;AACvF,mFAAmF;AACnF,wFAAwF;AACxF,EAAE;AACF,sFAAsF;AACtF,oFAAoF;AACpF,uFAAuF;AACvF,uFAAuF;AACvF,uFAAuF;AACvF,+EAA+E;AAC/E,sFAAsF;AACtF,yEAAyE;AACzE,EAAE;AACF,+DAA+D;AAC/D,sFAAsF;AACtF,wFAAwF;AACxF,aAAa;AACb,gFAAgF;AAChF,wFAAwF;AACxF,kFAAkF;AAClF,0EAA0E;AAC1E,gFAAgF;AAChF,yFAAyF;AACzF,sFAAsF;AACtF,oFAAoF;AACpF,8DAA8D;AAC9D,EAAE;AACF,sFAAsF;AACtF,wFAAwF;AACxF,mFAAmF;AACnF,2BAA2B;AAE3B,MAAM,CAAC,MAAM,gBAAgB,GAAa;IACxC,EAAE,EAAE,mBAAmB;IACvB,OAAO,EACL,odAAod;IACtd,SAAS,EAAE,SAAS;IACpB,iFAAiF;IACjF,KAAK,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE;IAC5B,KAAK,EAAE,CAAC;IACR,MAAM,EAAE,CAAC,uBAAuB,EAAE,cAAc,CAAC;IACjD,KAAK,EAAE,sBAAsB;IAC7B,OAAO,EAAE,EAAE;IACX,IAAI,EAAE,EAAE;IACR,OAAO,EAAE;QACP;YACE,QAAQ,EAAE,sBAAsB;YAChC,UAAU,EAAE,uDAAuD;YACnE,UAAU,EAAE,IAAI;YAChB,OAAO,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAiOd;SACI;QACD;YACE,QAAQ,EAAE,yBAAyB;YACnC,UAAU,EAAE,0DAA0D;YACtE,UAAU,EAAE,KAAK;YACjB,iFAAiF;YACjF,2EAA2E;YAC3E,6EAA6E;YAC7E,8EAA8E;YAC9E,6BAA6B;YAC7B,MAAM,EAAE,IAAI;YACZ,OAAO,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA+Ed;SACI;KACF;CACF,CAAC"}
|