@cratylus/canon 0.1.2 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/dist/agents/architect.d.ts +2 -0
  2. package/dist/agents/architect.js +113 -0
  3. package/dist/agents/architect.js.map +1 -0
  4. package/dist/agents/implementer.d.ts +2 -0
  5. package/dist/agents/implementer.js +74 -0
  6. package/dist/agents/implementer.js.map +1 -0
  7. package/dist/agents/kino.d.ts +2 -0
  8. package/dist/agents/kino.js +120 -0
  9. package/dist/agents/kino.js.map +1 -0
  10. package/dist/agents/mav.js +15 -4
  11. package/dist/agents/mav.js.map +1 -1
  12. package/dist/agents/nico.js +2 -2
  13. package/dist/agents/nico.js.map +1 -1
  14. package/dist/agents/planner.d.ts +2 -0
  15. package/dist/agents/planner.js +85 -0
  16. package/dist/agents/planner.js.map +1 -0
  17. package/dist/dimensions/autonomy/{check-in.d.ts → handoff.d.ts} +1 -1
  18. package/dist/dimensions/autonomy/handoff.js +40 -0
  19. package/dist/dimensions/autonomy/handoff.js.map +1 -0
  20. package/dist/dimensions/capabilities/film-production.d.ts +2 -0
  21. package/dist/dimensions/capabilities/film-production.js +8 -0
  22. package/dist/dimensions/capabilities/film-production.js.map +1 -0
  23. package/dist/dimensions/capabilities/generative-video.d.ts +2 -0
  24. package/dist/dimensions/capabilities/generative-video.js +8 -0
  25. package/dist/dimensions/capabilities/generative-video.js.map +1 -0
  26. package/dist/dimensions/formality/plain.js +23 -3
  27. package/dist/dimensions/formality/plain.js.map +1 -1
  28. package/dist/hooks/stance-guardrail-pre.js +39 -8
  29. package/dist/hooks/stance-guardrail-pre.js.map +1 -1
  30. package/dist/hooks/stance-guardrail.js +169 -11
  31. package/dist/hooks/stance-guardrail.js.map +1 -1
  32. package/dist/plan-states.js +9 -5
  33. package/dist/plan-states.js.map +1 -1
  34. package/dist/skills/deliver/skill.d.ts +2 -0
  35. package/dist/skills/deliver/skill.js +98 -0
  36. package/dist/skills/deliver/skill.js.map +1 -0
  37. package/dist/skills/{praxis → design}/skill.d.ts +1 -1
  38. package/dist/skills/design/skill.js +79 -0
  39. package/dist/skills/design/skill.js.map +1 -0
  40. package/dist/skills/plan/skill.d.ts +2 -0
  41. package/dist/skills/plan/skill.js +89 -0
  42. package/dist/skills/plan/skill.js.map +1 -0
  43. package/package.json +3 -3
  44. package/dist/dimensions/autonomy/check-in.js +0 -2
  45. package/dist/dimensions/autonomy/check-in.js.map +0 -1
  46. package/dist/dimensions/output-format/structured-decision.d.ts +0 -2
  47. package/dist/dimensions/output-format/structured-decision.js +0 -2
  48. package/dist/dimensions/output-format/structured-decision.js.map +0 -1
  49. package/dist/skills/praxis/skill.js +0 -193
  50. package/dist/skills/praxis/skill.js.map +0 -1
@@ -0,0 +1,8 @@
1
+ // The craft the software SERVES, not the software. Its decomposition is the
2
+ // production ladder every studio already runs, and the two laws a generative
3
+ // pipeline most often collapses: IDENTITY (is this the same character) and
4
+ // CONTINUITY (does the staging flow) are different problems with different
5
+ // instruments, and an art-bible entry is approved ONCE and applied everywhere
6
+ // rather than re-specified per shot.
7
+ export const filmProduction = `film-production ≜ ⟨development breakdown art-bible shot-design continuity cut⟩ ⟨identity ⊥ continuity⟩ ⟨art-bible ≜ approve-once · apply-everywhere⟩ ⟨industry-standard ≻ invention⟩`;
8
+ //# sourceMappingURL=film-production.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"film-production.js","sourceRoot":"","sources":["../../../src/dimensions/capabilities/film-production.ts"],"names":[],"mappings":"AAEA,4EAA4E;AAC5E,6EAA6E;AAC7E,2EAA2E;AAC3E,2EAA2E;AAC3E,8EAA8E;AAC9E,qCAAqC;AACrC,MAAM,CAAC,MAAM,cAAc,GAAiB,sLAAsL,CAAC"}
@@ -0,0 +1,2 @@
1
+ import type { Capabilities } from '../../manifest.js';
2
+ export declare const generativeVideo: Capabilities;
@@ -0,0 +1,8 @@
1
+ // The generative half of the craft — what the community, not the studio, has
2
+ // standardized. The load-bearing clause is the third: reference conditioning is
3
+ // STATELESS (every request re-presents every reference; the model remembers
4
+ // nothing between shots), so whatever carries identity across a production is
5
+ // the ledger, never the model. Identity-lock is ranked: a trained adapter beats
6
+ // reference conditioning beats prompt-only description.
7
+ export const generativeVideo = `generative-video ≜ ⟨model-selection conditioning identity-lock drift-control⟩ ⟨conditioning stateless ⇒ ledger = the-memory⟩ ⟨identity-lock ≜ adapter ≻ reference ≻ prompt⟩ ⟨community-recommendation ≻ invention⟩`;
8
+ //# sourceMappingURL=generative-video.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generative-video.js","sourceRoot":"","sources":["../../../src/dimensions/capabilities/generative-video.ts"],"names":[],"mappings":"AAEA,6EAA6E;AAC7E,gFAAgF;AAChF,4EAA4E;AAC5E,8EAA8E;AAC9E,gFAAgF;AAChF,wDAAwD;AACxD,MAAM,CAAC,MAAM,eAAe,GAAiB,oNAAoN,CAAC"}
@@ -9,10 +9,30 @@
9
9
  // the engineering bar and `answer-only` withholds the rationale. Trading either
10
10
  // for shorter replies buys prose with behaviour.
11
11
  //
12
- // THIS DEFINIENS IS PROSE, AND THAT IS THE POINT. ρ(`formality-definiens`) =
12
+ // REGISTER ONLY. The closing tail a report owes its operator is `autonomy`'s —
13
+ // `handoff` names it, because what a reply must CONTAIN at the end is report
14
+ // structure, not a register. A value that governed both would be the one home
15
+ // for two concepts, and would apply the tail to whichever formality happened to
16
+ // be bound.
17
+ //
18
+ // THIS DEFINIENS IS PROSE, AND THAT IS THE POINT. ρ(`emission-definiens`) =
13
19
  // human (`test/reader-register.ts`): a value whose referent is the operator's
14
20
  // reading experience is written in the register it describes. The σ* form of
15
21
  // these same clauses was comprehended and disobeyed — quoted back byte-for-byte
16
- // by a session emitting 0.69 structured reply lines, against 0.45 for this form.
17
- export const plain = `plain ≜ Write in prose: complete sentences joined into paragraphs. Length tracks the weight of the decision, not the volume of work done, and each point is made once. Notation belongs to your reasoning and to artifacts that declare it, never to a reply addressed to the operator. Fragments belong inside list items only, never standing alone as a sentence or a paragraph, and a list is for a genuine enumeration rather than as the default container for prose.`;
22
+ // by the session it governed while that session kept emitting fragments.
23
+ //
24
+ // CONCISE, BUT NOT AT THE COST OF THE PROHIBITIONS. A shorter draft — "Fragments
25
+ // belong inside list items, and a list is for a real enumeration" — dropped
26
+ // `never standing alone`, and body fragmentation rose sharply across three runs.
27
+ // The prohibitions ARE the binding clauses; the positive halves alone are read
28
+ // as a preference. Economy means no wasted words, never a dropped constraint.
29
+ //
30
+ // THE RATIOS IN THIS FILE'S HISTORY WERE MEASURED TWICE, and the first
31
+ // instrument was wrong: it scored every markdown line matching a list OR HEADING
32
+ // marker, so a reply of long prose paragraphs under two section headings scored
33
+ // as fragmented. Direction held under both instruments and the effect was large,
34
+ // which is why the ruling stands; magnitudes from the first are not comparable to
35
+ // the second. Current instrument — body bullet/numbered lines only, action-item
36
+ // tail excluded because it is mandated: 0.11 over five runs, three of them zero.
37
+ export const plain = `plain ≜ Write prose: complete sentences joined into paragraphs, each point made once, no more length than the decision carries. Notation stays in your reasoning and out of any reply to the operator. Fragments belong inside list items only, never standing alone as a sentence or a paragraph. The one list a reply carries is its closing tail of action items; everywhere else, explain in prose.`;
18
38
  //# sourceMappingURL=plain.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"plain.js","sourceRoot":"","sources":["../../../src/dimensions/formality/plain.ts"],"names":[],"mappings":"AAEA,4EAA4E;AAC5E,0EAA0E;AAC1E,2EAA2E;AAC3E,4EAA4E;AAC5E,gEAAgE;AAChE,EAAE;AACF,gFAAgF;AAChF,+EAA+E;AAC/E,gFAAgF;AAChF,iDAAiD;AACjD,EAAE;AACF,6EAA6E;AAC7E,8EAA8E;AAC9E,6EAA6E;AAC7E,gFAAgF;AAChF,iFAAiF;AACjF,MAAM,CAAC,MAAM,KAAK,GAAc,6cAA6c,CAAC"}
1
+ {"version":3,"file":"plain.js","sourceRoot":"","sources":["../../../src/dimensions/formality/plain.ts"],"names":[],"mappings":"AAEA,4EAA4E;AAC5E,0EAA0E;AAC1E,2EAA2E;AAC3E,4EAA4E;AAC5E,gEAAgE;AAChE,EAAE;AACF,gFAAgF;AAChF,+EAA+E;AAC/E,gFAAgF;AAChF,iDAAiD;AACjD,EAAE;AACF,+EAA+E;AAC/E,6EAA6E;AAC7E,8EAA8E;AAC9E,gFAAgF;AAChF,YAAY;AACZ,EAAE;AACF,4EAA4E;AAC5E,8EAA8E;AAC9E,6EAA6E;AAC7E,gFAAgF;AAChF,yEAAyE;AACzE,EAAE;AACF,iFAAiF;AACjF,4EAA4E;AAC5E,iFAAiF;AACjF,+EAA+E;AAC/E,8EAA8E;AAC9E,EAAE;AACF,uEAAuE;AACvE,iFAAiF;AACjF,gFAAgF;AAChF,iFAAiF;AACjF,kFAAkF;AAClF,gFAAgF;AAChF,iFAAiF;AACjF,MAAM,CAAC,MAAM,KAAK,GAAc,yYAAyY,CAAC"}
@@ -65,11 +65,27 @@ export const stanceGuardrailPre = {
65
65
 
66
66
  set -eu
67
67
 
68
- # The sibling Stop hook's deployed dir owns the SHARED judge + rubric (deployed together).
69
- JUDGE_DIR="\${STANCE_GUARD_DIR:-$HOME/.claude/hooks/stance-guardrail}"
70
- RUBRIC="\${STANCE_RUBRIC:-$JUDGE_DIR/stance-judge-prompt.md}"
68
+ # The sibling Stop hook's deployed dir owns the SHARED judge + rubric (deployed
69
+ # together, as siblings under the SAME hooks root).
70
+ #
71
+ # RESOLVED FROM THIS SCRIPT'S OWN LOCATION, never from a harness's home. These four
72
+ # lines named \`$HOME/.claude/...\` outright, so the copy deployed under
73
+ # \`~/.omp/hooks/\` reached across into the CLAUDE tree for its judge — and on a host
74
+ # with no claude deployment it found nothing, failed open, and logged its misses to
75
+ # a directory that does not exist. Every hooks root holds both hook dirs as
76
+ # siblings, so \`../stance-guardrail\` is true at every site this file can land; the
77
+ # sibling Stop worker already derives its own dir this way and this is the same
78
+ # derivation, one level up. The env overrides are unchanged and still win.
79
+ SELF_DIR="$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)"
80
+ HOOKS_ROOT="$(dirname -- "$SELF_DIR")"
81
+ JUDGE_DIR="\${STANCE_GUARD_DIR:-$HOOKS_ROOT/stance-guardrail}"
82
+ # The RUBRIC is not in either hook dir: it is harness-invariant and deploys once
83
+ # to the neutral \`.agents\` root, the sibling of every harness home. Same
84
+ # derivation as the sibling Stop worker, one level further out.
85
+ NEUTRAL_ROOT="$(dirname -- "$(dirname -- "$HOOKS_ROOT")")/.agents"
86
+ RUBRIC="\${STANCE_RUBRIC:-$NEUTRAL_ROOT/stance-guardrail/stance-judge-prompt.md}"
71
87
  JUDGE_CMD="\${STANCE_JUDGE_CMD:-sh $JUDGE_DIR/stance-judge.sh}"
72
- LOG="\${STANCE_GUARD_LOG:-$HOME/.claude/hooks/stance-guardrail-pre/misses.log}"
88
+ LOG="\${STANCE_GUARD_LOG:-$SELF_DIR/misses.log}"
73
89
 
74
90
  # A PreToolUse hook must never break a session. Trap any unexpected error -> allow.
75
91
  trap 'exit 0' EXIT
@@ -139,10 +155,25 @@ seen="\${TMPDIR:-/tmp}/.stance-pre-$session_id-$sig"
139
155
  [ -f "$seen" ] && allow # already denied this exact input once -> let it through
140
156
 
141
157
  # --- judge (SHARED backend + rubric) --------------------------------------------------------
142
- verdict="$(printf '%s' "$payload" | $JUDGE_CMD "$RUBRIC" 2>/dev/null)" || {
143
- note "$(date -u +%Y-%m-%dT%H:%M:%SZ) judge-fail tool=$tool_name agent=\${agent_type:-?}"
144
- allow
145
- }
158
+ # The same out-of-process seam the Stop worker carries, and for the same reason: a
159
+ # host that already holds a model must not be made to spawn another vendor's CLI.
160
+ # The deny-once marker is written AFTER this point, so the emit pass mutates nothing.
161
+ if [ -n "\${STANCE_EMIT_PAYLOAD:-}" ]; then
162
+ jq -cn --arg r "$RUBRIC" --arg p "$payload" '{rubric:$r, payload:$p}'
163
+ exit 0
164
+ fi
165
+ if [ -n "\${STANCE_VERDICT_FILE:-}" ]; then
166
+ verdict="$(cat "\${STANCE_VERDICT_FILE}" 2>/dev/null || true)"
167
+ [ -n "$verdict" ] || {
168
+ note "$(date -u +%Y-%m-%dT%H:%M:%SZ) judge-empty tool=$tool_name agent=\${agent_type:-?}"
169
+ allow
170
+ }
171
+ else
172
+ verdict="$(printf '%s' "$payload" | $JUDGE_CMD "$RUBRIC" 2>/dev/null)" || {
173
+ note "$(date -u +%Y-%m-%dT%H:%M:%SZ) judge-fail tool=$tool_name agent=\${agent_type:-?}"
174
+ allow
175
+ }
176
+ fi
146
177
 
147
178
  decision="$(printf '%s\\n' "$verdict" | sed -n 's/^VERDICT:[[:space:]]*//p' | head -1)"
148
179
  [ "$decision" = "BLOCK" ] || allow # PASS, empty, or anything but BLOCK -> allow
@@ -1 +1 @@
1
- {"version":3,"file":"stance-guardrail-pre.js","sourceRoot":"","sources":["../../src/hooks/stance-guardrail-pre.ts"],"names":[],"mappings":"AAEA,sFAAsF;AACtF,mFAAmF;AACnF,uFAAuF;AACvF,SAAS;AACT,wFAAwF;AACxF,6FAA6F;AAC7F,0FAA0F;AAC1F,uFAAuF;AACvF,qEAAqE;AACrE,EAAE;AACF,wEAAwE;AACxE,sFAAsF;AACtF,iFAAiF;AACjF,mFAAmF;AACnF,sFAAsF;AACtF,qFAAqF;AACrF,sFAAsF;AACtF,sFAAsF;AACtF,mEAAmE;AACnE,2DAA2D;AAC3D,mDAAmD;AAEnD,MAAM,CAAC,MAAM,kBAAkB,GAAa;IAC1C,EAAE,EAAE,sBAAsB;IAC1B,OAAO,EACL,iWAAiW;IACnW,SAAS,EAAE,SAAS;IACpB,KAAK,EAAE,CAAC;IACR,MAAM,EAAE,CAAC,sBAAsB,EAAE,uBAAuB,CAAC;IACzD,KAAK,EAAE,yBAAyB;IAChC,OAAO,EAAE,EAAE;IACX,IAAI,EAAE,EAAE;IACR,OAAO,EAAE;QACP;YACE,QAAQ,EAAE,yBAAyB;YACnC,UAAU,EAAE,0DAA0D;YACtE,UAAU,EAAE,IAAI;YAChB,OAAO,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAkId;SACI;KACF;CACF,CAAC"}
1
+ {"version":3,"file":"stance-guardrail-pre.js","sourceRoot":"","sources":["../../src/hooks/stance-guardrail-pre.ts"],"names":[],"mappings":"AAEA,sFAAsF;AACtF,mFAAmF;AACnF,uFAAuF;AACvF,SAAS;AACT,wFAAwF;AACxF,6FAA6F;AAC7F,0FAA0F;AAC1F,uFAAuF;AACvF,qEAAqE;AACrE,EAAE;AACF,wEAAwE;AACxE,sFAAsF;AACtF,iFAAiF;AACjF,mFAAmF;AACnF,sFAAsF;AACtF,qFAAqF;AACrF,sFAAsF;AACtF,sFAAsF;AACtF,mEAAmE;AACnE,2DAA2D;AAC3D,mDAAmD;AAEnD,MAAM,CAAC,MAAM,kBAAkB,GAAa;IAC1C,EAAE,EAAE,sBAAsB;IAC1B,OAAO,EACL,iWAAiW;IACnW,SAAS,EAAE,SAAS;IACpB,KAAK,EAAE,CAAC;IACR,MAAM,EAAE,CAAC,sBAAsB,EAAE,uBAAuB,CAAC;IACzD,KAAK,EAAE,yBAAyB;IAChC,OAAO,EAAE,EAAE;IACX,IAAI,EAAE,EAAE;IACR,OAAO,EAAE;QACP;YACE,QAAQ,EAAE,yBAAyB;YACnC,UAAU,EAAE,0DAA0D;YACtE,UAAU,EAAE,IAAI;YAChB,OAAO,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAiKd;SACI;KACF;CACF,CAAC"}
@@ -1,4 +1,4 @@
1
- import { checkIn } from '../dimensions/autonomy/check-in.js';
1
+ import { handoff } from '../dimensions/autonomy/handoff.js';
2
2
  // stance-guardrail — the harness-half of the principal stance. A source
3
3
  // `hook` cell (activation=event): its canonical DEFINIENS is the σ*-signified
4
4
  // identity that `accept()` gates; its `workers[].content` are the VERBATIM
@@ -73,9 +73,20 @@ export const stanceGuardrail = {
73
73
  set -eu
74
74
 
75
75
  SELF_DIR="$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)"
76
- RUBRIC="\${STANCE_RUBRIC:-$SELF_DIR/stance-judge-prompt.md}"
77
76
  JUDGE_CMD="\${STANCE_JUDGE_CMD:-sh $SELF_DIR/stance-judge.sh}"
78
77
 
78
+ # THE RUBRIC LIVES AT THE VENDOR-NEUTRAL ROOT, and is reached by DERIVATION so it
79
+ # follows whatever home this copy was deployed under (a real \$HOME, or a test's
80
+ # \`--home\`). This worker sits at \`<harness-home>/hooks/<id>/\`, and \`.agents\` is
81
+ # the SIBLING of every harness home — the same relation deploy already uses to
82
+ # place agents and skills — so three \`dirname\`s and a name is the whole address.
83
+ #
84
+ # Derived rather than baked: a literal \`\$HOME/.agents\` would expand correctly on
85
+ # a host and point outside a sandboxed deploy, which is the class of bug that put
86
+ # \`\$HOME/.claude\` in the sibling worker and made it read another harness's tree.
87
+ NEUTRAL_ROOT="$(dirname -- "$(dirname -- "$(dirname -- "$SELF_DIR")")")/.agents"
88
+ RUBRIC="\${STANCE_RUBRIC:-$NEUTRAL_ROOT/stance-guardrail/stance-judge-prompt.md}"
89
+
79
90
  # A Stop hook must never break a session. Trap any unexpected error → allow the stop.
80
91
  trap 'exit 0' EXIT
81
92
 
@@ -283,8 +294,82 @@ operator="$(jq -rs '
283
294
  ' "$transcript" 2>/dev/null || true)"
284
295
  [ -n "$operator" ] || operator="(no operator instruction found in transcript)"
285
296
 
286
- # The judged payload: the operator's instruction (authorization context) THEN the agent turn.
287
- turn="=== OPERATOR (most recent instruction — the authorization context) ===
297
+ # --- THE STANDING DIRECTIVE: which loop-position is in force, and who set it -----------------
298
+ #
299
+ # THE GUARD'S OLDEST BLIND SPOT, and the reason it reads as crude. \`carry-on\` declares
300
+ # \`loop-position ∈ {on-the-loop, out-of-the-loop}\` as LIVE SESSION STATE, and nothing anywhere
301
+ # wrote it down — so every turn was judged as if the session had just opened. A check-in is
302
+ # CORRECT at rest ("a session opens in orientation · intent is the operator's to set") and is a
303
+ # COLLAPSE under an elevation the operator already granted, and the judge could not tell those
304
+ # two apart because it was never told which one it was in.
305
+ #
306
+ # DERIVED, NOT STORED. The transcript IS the record: the operator's own utterance is what
307
+ # established the elevation, it is already here, it is session-scoped by construction, and it
308
+ # cannot desync from what was actually said the way a state file can. A store would need a
309
+ # session id this worker is not always given, a write path, and a lifecycle — all to hold a
310
+ # value that is a fold over messages already on disk.
311
+ #
312
+ # SCANNED BEFORE THE FILTER ABOVE, which is the whole repair. A slash invocation arrives wrapped
313
+ # in <command-name>, and that wrapper is exactly what the operator slot drops — so the filter
314
+ # added to stop the judge reading a skill BODY as an instruction was also the mechanism hiding
315
+ # every \`/carry-on\` from it. The word is read here, from the unfiltered list, and only the
316
+ # word: no skill body reaches the payload.
317
+ #
318
+ # MECHANICAL EXTRACTION, SEMANTIC WEIGHING — the same split as layer 1. This reports WHICH
319
+ # position is in force, the verbatim utterance that set it, and how many operator turns have
320
+ # passed since; the rubric decides what follows. A false positive therefore costs a misleading
321
+ # context line, never an unguarded turn.
322
+ standing="$(jq -rs '
323
+ [ .[]
324
+ | select(.type == "user")
325
+ | (.message.content)
326
+ | if type == "string" then .
327
+ elif type == "array" then ([ .[] | select(.type == "text") | .text ] | join("\\n"))
328
+ else "" end
329
+ ]
330
+ | map(select(. != ""))
331
+ | map(select(
332
+ (test("^\\\\s*<system-reminder>") | not)
333
+ and (test("\\\\[SYSTEM NOTIFICATION - NOT USER INPUT\\\\]") | not)
334
+ and (test("<task-notification>") | not)
335
+ ))
336
+ | to_entries as $all
337
+ | ($all | length) as $n
338
+ | ($all
339
+ | map(select(.value | test("(^|[^[:alpha:]])(carry[- ]?on|weitermachen|proceed)([^[:alpha:]]|$)"; "i")))
340
+ | last) as $hit
341
+ | if $hit == null then "" else
342
+ ($hit.value
343
+ | if test("<command-message>") then (capture("<command-message>(?<m>[^<]*)").m)
344
+ elif test("<command-name>") then (capture("<command-name>(?<m>[^<]*)").m)
345
+ else . end
346
+ | gsub("\\\\s+"; " ")) as $said
347
+ | "\\($n - 1 - $hit.key)\\n\\($said)" end
348
+ ' "$transcript" 2>/dev/null || true)"
349
+
350
+ if [ -n "$standing" ]; then
351
+ since="$(printf '%s\\n' "$standing" | head -1)"
352
+ grant="$(printf '%s\\n' "$standing" | sed -n '2p' | cut -c1-300)"
353
+ standing_block="=== STANDING DIRECTIVE (loop-position in force) ===
354
+ out-of-the-loop — the operator uttered the re-dispatch word $since operator turn(s) ago, and an
355
+ elevation PERSISTS until the operator redirects or the context is satisfied. It was:
356
+ \\"$grant\\"
357
+ This RAISES the bar, it does not lower it: under an elevation the operator has already said they
358
+ are out of the loop, so a check-in, a permission question, or a handed-back in-remit decision is
359
+ a collapse rather than diligence. It excuses exactly one thing — surfacing a fork the principal
360
+ cannot resolve (irreversible · value · competence), which the elevation itself reserves."
361
+ else
362
+ standing_block="=== STANDING DIRECTIVE (loop-position in force) ===
363
+ on-the-loop (resting) — no re-dispatch word appears in this transcript, so the session is in
364
+ orientation and the intent is still the operator's to set. Surfacing options, checking in, or
365
+ asking which objective to serve is CORRECT here and must not be blocked; what remains a collapse
366
+ is deferring a decision already inside a mandate the operator did give."
367
+ fi
368
+
369
+ # The judged payload: the standing directive, the operator's instruction, THEN the agent turn.
370
+ turn="$standing_block
371
+
372
+ === OPERATOR (most recent instruction — the authorization context) ===
288
373
  $operator
289
374
 
290
375
  === AGENT (last assistant turn — judge THIS) ===
@@ -347,7 +432,30 @@ Unless that commitment is genuinely contingent on something outside this turn (a
347
432
  still running, an operator sign-off, an external event), this is announce-without-act: BLOCK it,
348
433
  and quote the span above as the evidence."
349
434
 
350
- verdict="$(printf '%s' "$judged" | $JUDGE_CMD "$RUBRIC" 2>/dev/null)" || dark "the judge did not answer"
435
+ # THE JUDGE MAY LIVE OUTSIDE THIS PROCESS, and on a harness that already holds a
436
+ # model it MUST. Spawning another vendor's CLI to answer a question the host can
437
+ # answer in-process is a cross-harness dependency wearing a plugin's clothes: it
438
+ # needs that vendor installed, separately authenticated, and warm — and when its
439
+ # OAuth lapses, every verdict on every harness fails open in silence.
440
+ #
441
+ # So the seam is explicit and the PROCEDURE stays here, in one home. A host that
442
+ # can judge runs this worker twice: once with \`STANCE_EMIT_PAYLOAD\` to receive the
443
+ # gated, layer-1-annotated payload and the rubric that scores it, then again with
444
+ # \`STANCE_VERDICT_FILE\` naming its answer. Everything either pass touches before
445
+ # this line is read-only, so the first pass mutates no counter and no hash — the
446
+ # gate, the extraction and the pre-filter simply run twice and agree.
447
+ #
448
+ # A host with no model of its own changes nothing and keeps the subprocess judge.
449
+ if [ -n "\${STANCE_EMIT_PAYLOAD:-}" ]; then
450
+ jq -cn --arg r "$RUBRIC" --arg p "$judged" '{rubric:$r, payload:$p}'
451
+ exit 0
452
+ fi
453
+ if [ -n "\${STANCE_VERDICT_FILE:-}" ]; then
454
+ verdict="$(cat "\${STANCE_VERDICT_FILE}" 2>/dev/null)" || dark "the judge did not answer"
455
+ [ -n "$verdict" ] || dark "the judge did not answer"
456
+ else
457
+ verdict="$(printf '%s' "$judged" | $JUDGE_CMD "$RUBRIC" 2>/dev/null)" || dark "the judge did not answer"
458
+ fi
351
459
 
352
460
  decision="$(printf '%s\\n' "$verdict" | sed -n 's/^VERDICT:[[:space:]]*//p' | head -1)"
353
461
  [ "$decision" = "BLOCK" ] || allow_stop # PASS, empty, or anything but BLOCK → allow stop
@@ -522,8 +630,21 @@ rubric="\${1:?usage: stance-judge.sh <rubric-path> (turn text on stdin)}"
522
630
  turn="$(cat)"
523
631
  [ -n "$turn" ] || { echo "VERDICT: PASS"; exit 0; } # nothing to judge → PASS
524
632
 
525
- # Resolve the judge model CLI. Default: claude headless. Overridable for offline/CI.
526
- judge_bin="\${STANCE_JUDGE_BIN:-claude}"
633
+ # Resolve the judge model CLI — THIS HARNESS'S OWN, carried as a projection fact.
634
+ #
635
+ # It read \`\${STANCE_JUDGE_BIN:-claude}\`, and that one literal made every harness
636
+ # depend on one vendor: codex's stance guard and omp's both needed \`claude\`
637
+ # installed and separately authenticated, and when that OAuth lapsed every verdict
638
+ # on every harness failed open in silence. A harness answers with its own model.
639
+ #
640
+ # EMPTY IS A REAL VALUE: a harness that judges IN-PROCESS (omp) names no CLI here
641
+ # and never reaches this backend at all — its shim supplies the verdict directly.
642
+ # If something does reach it anyway, the only honest answer is to fail open.
643
+ judge_bin="\${STANCE_JUDGE_BIN:-{{fact:harness-judge-bin}}}"
644
+ [ -n "$judge_bin" ] || {
645
+ echo "stance-judge: this harness names no judge CLI (it judges in-process); failing open" >&2
646
+ exit 6
647
+ }
527
648
  command -v "$judge_bin" >/dev/null 2>&1 || {
528
649
  echo "stance-judge: judge binary '$judge_bin' not on PATH; failing open" >&2
529
650
  exit 4
@@ -568,6 +689,13 @@ echo "$verdict" | grep -E '^(VERDICT|REASON|EVIDENCE):' || {
568
689
  filename: 'stance-judge-prompt.md',
569
690
  targetPath: 'packages/canon/targets/guardrail/stance-judge-prompt.md',
570
691
  executable: false,
692
+ // THE RUBRIC IS THE ONE ARTIFACT HERE THAT IS NOT ABOUT A HARNESS. It is
693
+ // the stance contract itself — the same 27 kB scored against on every
694
+ // projection, byte-for-byte — so it deploys once to the neutral `.agents`
695
+ // root rather than being copied into each harness's hooks dir. Duplicating
696
+ // it did more than waste bytes: it left the text with no address another
697
+ // realization could name without reaching into a sibling harness's tree.
698
+ shared: true,
571
699
  content: `# Stance judge — the intent-driven-expert rubric
572
700
 
573
701
  You are a STANCE JUDGE. You are given EITHER the **last assistant turn** of an agent, OR a **mid-turn
@@ -589,6 +717,34 @@ acts**. Everything else — design, naming, architecture, sequencing, how — is
589
717
  execute. A correction from the operator **refines intent**; it never **transfers authority** back. The
590
718
  agent extracts and serves the operator's true intent; it does not transcribe the operator's literal words.
591
719
 
720
+ ## The STANDING DIRECTIVE block — read it FIRST, it re-scores everything below
721
+
722
+ The payload opens with the **loop-position in force**, derived mechanically from the operator's own
723
+ utterances in this transcript. It is a fact about what the operator said, not an inference, and it decides
724
+ which of two different questions you are answering.
725
+
726
+ **\`on-the-loop (resting)\`** — the operator has set no standing mandate. The session is in orientation and
727
+ the intent is still theirs to set. Surfacing options, asking which objective to serve, or checking in
728
+ before committing to a direction is **CORRECT** here: **PASS** it. There is nothing to be autonomous
729
+ _about_ yet, and blocking a turn for "permission-seeking" when no mandate exists punishes the agent for
730
+ the operator's silence. What still BLOCKS at rest is deferring a decision that sits _inside_ a mandate the
731
+ operator did give.
732
+
733
+ **\`out-of-the-loop\`** — the operator uttered the re-dispatch word and has not redirected since. This
734
+ **RAISES** the bar; it never lowers it. The operator has said in as many words that they are out of the
735
+ loop, so a check-in, a permission question, an option menu, or a handed-back in-remit decision is a
736
+ **collapse**, and a plainer one than usual: the agent is asking for input the operator explicitly stepped
737
+ back from giving. Weight these **more** heavily, not less.
738
+
739
+ An elevation excuses exactly one thing: **surfacing a fork the principal cannot resolve** — irreversible,
740
+ or a value judgment, or outside the agent's competence. The elevation itself reserves that case, so
741
+ surfacing one is the grant working rather than failing. Everything else that would block at rest blocks
742
+ harder here.
743
+
744
+ Do not treat the elevation as permission to skip the operator on an irreversible-outward act. Authority
745
+ over _how_ was already the agent's; the grant re-affirms it and adds nothing to the sign-off the operator
746
+ still owns.
747
+
592
748
  ## BLOCK the turn if it exhibits ANY of these collapse signals
593
749
 
594
750
  1. **Permission-seeking for in-remit, reversible work.** Asking "should I…?", "want me to…?", "shall I
@@ -751,13 +907,15 @@ close of an earlier turn, and that turn had honoured it. A confabulated block is
751
907
  a missed one: an agent that yields to a fired gate whose diagnosis the record refutes has updated on a
752
908
  salient signal rather than on argument, which is the very collapse this rubric exists to prevent.
753
909
 
754
- ## The check-in laws (the agent's DECLARED contract — judge against these)
910
+ ## The handoff laws (the agent's DECLARED contract — judge against these)
755
911
 
756
- An agent carrying the \`checkIn\` autonomy value declares:
757
- \`${checkIn}\`. Four laws follow, and a turn
912
+ An agent carrying the \`handoff\` autonomy value declares:
913
+ \`${handoff}\`. Four laws follow, and a turn
758
914
  that breaks any of them is a collapse:
759
915
 
760
- - **L1 · scope.** These govern operator-facing check-ins only, never agent-to-agent traffic.
916
+ - **L1 · scope.** These govern operator-facing turns only, never agent-to-agent traffic. Every
917
+ turn that ends back at the operator IS a handoff; the laws are not reserved for turns the agent
918
+ decides to call one.
761
919
  - **L2 · nothing owed appears in the body.** Anything the operator must decide belongs in the
762
920
  TAIL. An owed item raised mid-report — "needs your call", "I won't touch this unilaterally" —
763
921
  scattered through the body is a breach even when a recommendation appears elsewhere. Putting
@@ -1 +1 @@
1
- {"version":3,"file":"stance-guardrail.js","sourceRoot":"","sources":["../../src/hooks/stance-guardrail.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,oCAAoC,CAAC;AAG7D,wEAAwE;AACxE,8EAA8E;AAC9E,2EAA2E;AAC3E,2EAA2E;AAC3E,8EAA8E;AAC9E,gFAAgF;AAEhF,MAAM,CAAC,MAAM,eAAe,GAAa;IACvC,EAAE,EAAE,kBAAkB;IACtB,OAAO,EACL,8UAA8U;IAChV,SAAS,EAAE,SAAS;IACpB,KAAK,EAAE,CAAC;IACR,MAAM,EAAE,CAAC,UAAU,EAAE,cAAc,CAAC;IACpC,KAAK,EAAE,qBAAqB;IAC5B,OAAO,EAAE,EAAE;IACX,IAAI,EAAE,EAAE;IACR,OAAO,EAAE;QACP;YACE,QAAQ,EAAE,qBAAqB;YAC/B,UAAU,EAAE,sDAAsD;YAClE,UAAU,EAAE,IAAI;YAChB,OAAO,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmdd;SACI;QACD;YACE,QAAQ,EAAE,iBAAiB;YAC3B,UAAU,EAAE,kDAAkD;YAC9D,UAAU,EAAE,IAAI;YAChB,OAAO,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAsEd;SACI;QACD;YACE,QAAQ,EAAE,wBAAwB;YAClC,UAAU,EAAE,yDAAyD;YACrE,UAAU,EAAE,KAAK;YACjB,OAAO,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IA0LX,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAuLV;SACI;KACF;CACF,CAAC"}
1
+ {"version":3,"file":"stance-guardrail.js","sourceRoot":"","sources":["../../src/hooks/stance-guardrail.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,mCAAmC,CAAC;AAG5D,wEAAwE;AACxE,8EAA8E;AAC9E,2EAA2E;AAC3E,2EAA2E;AAC3E,8EAA8E;AAC9E,gFAAgF;AAEhF,MAAM,CAAC,MAAM,eAAe,GAAa;IACvC,EAAE,EAAE,kBAAkB;IACtB,OAAO,EACL,8UAA8U;IAChV,SAAS,EAAE,SAAS;IACpB,KAAK,EAAE,CAAC;IACR,MAAM,EAAE,CAAC,UAAU,EAAE,cAAc,CAAC;IACpC,KAAK,EAAE,qBAAqB;IAC5B,OAAO,EAAE,EAAE;IACX,IAAI,EAAE,EAAE;IACR,OAAO,EAAE;QACP;YACE,QAAQ,EAAE,qBAAqB;YAC/B,UAAU,EAAE,sDAAsD;YAClE,UAAU,EAAE,IAAI;YAChB,OAAO,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA+jBd;SACI;QACD;YACE,QAAQ,EAAE,iBAAiB;YAC3B,UAAU,EAAE,kDAAkD;YAC9D,UAAU,EAAE,IAAI;YAChB,OAAO,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmFd;SACI;QACD;YACE,QAAQ,EAAE,wBAAwB;YAClC,UAAU,EAAE,yDAAyD;YACrE,UAAU,EAAE,KAAK;YACjB,yEAAyE;YACzE,sEAAsE;YACtE,0EAA0E;YAC1E,2EAA2E;YAC3E,yEAAyE;YACzE,yEAAyE;YACzE,MAAM,EAAE,IAAI;YACZ,OAAO,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAsNX,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAyLV;SACI;KACF;CACF,CAAC"}
@@ -1,10 +1,14 @@
1
1
  // plan-states.ts — the CANON home of the sharded-plan-layout state folders, in
2
- // lifecycle order. ONE home, two consumers (DRY): the `praxis` skill's formal
3
- // block (`../skills/praxis.ts`, whose `States ≜ {…}` set derives from here) and
4
- // the canon project template (`./project-template.ts`, whose `planStates` is
5
- // this). It lives here — not as a second export on the praxis skill module — because
6
- // a skill module carries exactly one export (its `Skill`); this is praxis's canon,
2
+ // lifecycle order. ONE home, two consumers (DRY): the `plan` skill's formal block
3
+ // (`../skills/plan/skill.ts`, whose `States ≜ {…}` set derives from here) and the
4
+ // canon project template (`./project-template.ts`, whose `planStates` is this). It
5
+ // lives here — not as a second export on the plan skill module — because a skill
6
+ // module carries exactly one export (its `Skill`); this is the plan cell's canon,
7
7
  // factored out to a sibling both can source.
8
+ //
9
+ // The consumer was `praxis` until that cell was superseded by the design/plan/deliver
10
+ // trio: praxis carried understanding, specification and governance in one place, and
11
+ // the state set belongs to the middle term alone.
8
12
  /** The plan-layout state folders, in task-file lifecycle order. */
9
13
  export const PLAN_STATES = ['pending', 'ready', 'active', 'completed'];
10
14
  /** `frontier(P)` — the states a shard sits in when the plan is workable AT it
@@ -1 +1 @@
1
- {"version":3,"file":"plan-states.js","sourceRoot":"","sources":["../src/plan-states.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,8EAA8E;AAC9E,gFAAgF;AAChF,6EAA6E;AAC7E,qFAAqF;AACrF,mFAAmF;AACnF,6CAA6C;AAE7C,mEAAmE;AACnE,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAE,WAAW,CAAU,CAAC;AAEhF;;;+DAG+D;AAC/D,MAAM,CAAC,MAAM,aAAa,GAAG;IAC3B,OAAO;IACP,QAAQ;CACkD,CAAC;AAE7D;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG;IAC1B,mFAAmF;IACnF,KAAK,EAAE,QAAQ;IACf,mFAAmF;IACnF,UAAU,EAAE,cAAc;CAClB,CAAC"}
1
+ {"version":3,"file":"plan-states.js","sourceRoot":"","sources":["../src/plan-states.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,kFAAkF;AAClF,kFAAkF;AAClF,mFAAmF;AACnF,iFAAiF;AACjF,kFAAkF;AAClF,6CAA6C;AAC7C,EAAE;AACF,sFAAsF;AACtF,qFAAqF;AACrF,kDAAkD;AAElD,mEAAmE;AACnE,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAE,WAAW,CAAU,CAAC;AAEhF;;;+DAG+D;AAC/D,MAAM,CAAC,MAAM,aAAa,GAAG;IAC3B,OAAO;IACP,QAAQ;CACkD,CAAC;AAE7D;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG;IAC1B,mFAAmF;IACnF,KAAK,EAAE,QAAQ;IACf,mFAAmF;IACnF,UAAU,EAAE,cAAc;CAClB,CAAC"}
@@ -0,0 +1,2 @@
1
+ import type { Skill } from '../../manifest.js';
2
+ export declare const deliver: Skill;
@@ -0,0 +1,98 @@
1
+ import { design } from '../design/skill.js';
2
+ import { plan } from '../plan/skill.js';
3
+ // WHERE THE TRUST DEFECT IS CLOSED. Acceptance keyed to a unit's own criteria is a
4
+ // closed loop: the author writes the unit, writes its criteria, and checks the return
5
+ // against them. Every term comes from one source, so an executor satisfying the letter
6
+ // passes while the design goes unmet. Instructing the principal to "actually verify"
7
+ // cannot repair this — verification is a TWO-DESCRIPTION operation, and with one
8
+ // description there is no operation to perform, so it degenerates into re-reading the
9
+ // claim. The second description is the design, which is why this cell composes it.
10
+ //
11
+ // The split that matters: the EXECUTOR verifies ⟨did I build it per the spec⟩ and the
12
+ // PRINCIPAL validates ⟨is this what the design called for⟩. Both are legitimate and
13
+ // neither substitutes. Today only the first exists in most loops.
14
+ //
15
+ // The three validation questions are cheap BY CONSTRUCTION, and that is load-bearing
16
+ // rather than convenient: a check costing more than redoing the work is skipped, and
17
+ // no instruction survives that gradient. Naming discipline is what buys the cheapness —
18
+ // if the artifact spells its concept, two of the three are reading a name.
19
+ const FORMAL_BLOCK = `C @ design
20
+ c ≜ a concept ⟨c ∈ C⟩
21
+ anchor @ design
22
+ gloss @ design
23
+ factors @ design
24
+ denotes @ design
25
+ amend @ design
26
+ yield ≜ what execution established ∧ ¬ derivable from C
27
+ P @ plan
28
+ unit ≜ a unit of work
29
+ wave @ plan
30
+ frontier @ plan
31
+ realizes @ plan
32
+ accept @ plan ⟨the MECHANICAL half⟩
33
+ outputs @ plan
34
+ artifact : P → ℘(path) ⟨what landed · the EVIDENCE⟩
35
+ r ≜ an executor's return
36
+ conform @ signify
37
+ executor : P ⇀ agent
38
+ self ≜ the principal ⟨the design-holder⟩
39
+ spells : path × anchor → 𝔹 ⟨identifiers · path · public surface bear the sign⟩
40
+ covers : path × ℘(C) → 𝔹 ⟨observable behaviour ≅ the factorization · nothing missing
41
+ ∧ nothing extra⟩
42
+ sole : path × anchor → 𝔹 ⟨∄ other artifact realizing the same concept⟩
43
+ verify : P × return → 𝔹 ⟨the EXECUTOR's · built-it-right, against spec⟩
44
+ validate : P → 𝔹 ⟨the PRINCIPAL's · built-the-right-thing, against C⟩
45
+ defect ≜ ⟨symptom, locus, provenance⟩
46
+ impedes : defect × P → 𝔹
47
+ cost : act → effort
48
+ bound : P → 𝔹 ⟨plan-level commitment · persists across sessions⟩
49
+ electable ≜ { P | ¬terminal(P) ∧ ¬occupied(P) }
50
+ terminal : P → 𝔹
51
+ commit @ design
52
+ accepts @ design
53
+
54
+ ∀ unit, r : ¬conform(r) ⇒ ¬accept(unit)(r)
55
+ validate(unit) ⇔ spells(artifact(unit), realizes(unit))
56
+ ∧ covers(artifact(unit), factors(denotes(realizes(unit))))
57
+ ∧ sole(artifact(unit), realizes(unit))
58
+ validate ⊨ artifact ⟨NEVER r · a summary is a CLAIM ∧ the file is EVIDENCE ·
59
+ an acceptance that read only the return has accepted nothing⟩
60
+ validate ⊨ self ⟨¬ delegable · the executor cannot judge its own conformance ∵ it
61
+ holds the spec ∧ ¬ the design⟩
62
+ verify ⊥ validate ⟨two checks, two witnesses · neither substitutes ; an executor's
63
+ green suite proves the EXECUTOR's own assertion ∧ nothing about the design⟩
64
+ judge(unit) ≜ verify(unit, r) ∧ validate(unit) ⇒ advance(unit) ; ¬ ⇒ r rejected back to
65
+ executor(unit) ∧ state(unit) stays active
66
+ ⟨r lands VERBATIM ≺ any verdict on it · the loss mode is read-reason-discard,
67
+ and it takes everything when a run dies mid-judgement⟩
68
+ ⟨fan-in is as order-sensitive as fan-out : ∀ unit dispatched, confirm executor(unit)
69
+ RETURNED · outputs(unit) exist ≠ executor(unit) returned⟩
70
+ cost(validate) < cost(rebuild) ⟨else the gradient points at skipping · the cheapness
71
+ is BOUGHT by conform(anchor) ∴ naming discipline is the verification budget⟩
72
+ ¬spells ⇒ REFUSE ≺ any behavioural read ⟨the traceability arrow breaks at the cheapest
73
+ place it will ever be visible⟩
74
+ ¬covers ∧ extra ⇒ a second concept smuggled in unnamed ⇒ amend(C) ∨ REFUSE
75
+ ¬sole ⇒ duplication ⟨the observable signature of a vision that fragmented⟩
76
+ dispatch(P) ≜ ∀ unit ∈ frontier(P) ⟨state(unit) = ready⟩ concurrently ⟨state(unit) := active ∧
77
+ executor(unit) runs spec(unit)⟩ ; pre bound(P) ∧ ⊨ disjoint-outputs
78
+ yield ≠ ∅ ⇒ amend(C) @ design ⟨LIVE, ¬ at retirement⟩
79
+ ∀ k : amends(k, c) ⇒ ¬accepts(k) ⟨the amendment and the acceptance motivating it are
80
+ two commits · fused, the agent adjusts the concept its artifact failed ∧ declares
81
+ success ⟨evidence MANUFACTURED⟩⟩
82
+ impedes(d, unit) ⇔ d standing ⇒ ∄ r : accept(unit)(r)
83
+ impedes(d, unit) ⇒ fix(d) ⟨a regression in the path is repaired, ¬ surfaced⟩
84
+ ¬impedes(d, unit) ⇒ file(d) ∧ ¬fix(d) ⟨a defect BESIDE the path is filed, ¬ chased⟩
85
+ cost(file) < cost(fix) ⟨else the gradient points at chasing · the load-bearing law⟩
86
+ ∃ P : ¬terminal(P) ⇒ ∃! P : bound(P) ⟨WIP = 1 · finish before starting⟩
87
+ elect ≜ in-flight ≻ gating ≻ operator-intent ⟨lexicographic⟩
88
+ terminal(P) ⇒ retire(P) ⟨obligation ¬ permission · an unretired terminal plan is WIP
89
+ that is not work⟩ ; C persists ⟨plans come ∧ go ABOVE the design⟩
90
+ deliver ≜ bind → dispatch(wave) → verify ⟨executor⟩ → validate ⟨self, on artifact⟩ →
91
+ judge → amend(C) ⇔ yield → advance → retire`;
92
+ export const deliver = {
93
+ name: 'deliver',
94
+ description: `use this skill to execute a plan and ACCEPT its results — dispatch a wave of units to executors, then validate each landed artifact against the design rather than against the executor's report, and integrate. Reach for it whenever delegated work comes back. Validation is three cheap questions — does the artifact spell its concept's name, does its behaviour cover that concept's factorization exactly, and does anything else already realize it — read off the files themselves, never off a summary. It also carries the conduct of the work: one plan bound at a time, finish before starting, repair what blocks the path and merely file what sits beside it.`,
95
+ formalBlock: FORMAL_BLOCK,
96
+ composition: () => [design, plan],
97
+ };
98
+ //# sourceMappingURL=skill.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skill.js","sourceRoot":"","sources":["../../../src/skills/deliver/skill.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAC5C,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAExC,mFAAmF;AACnF,sFAAsF;AACtF,uFAAuF;AACvF,qFAAqF;AACrF,iFAAiF;AACjF,sFAAsF;AACtF,mFAAmF;AACnF,EAAE;AACF,sFAAsF;AACtF,oFAAoF;AACpF,kEAAkE;AAClE,EAAE;AACF,qFAAqF;AACrF,qFAAqF;AACrF,wFAAwF;AACxF,2EAA2E;AAE3E,MAAM,YAAY,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;gDAwE8C,CAAC;AAEpE,MAAM,CAAC,MAAM,OAAO,GAAU;IAC5B,IAAI,EAAE,SAAS;IACf,WAAW,EAAE,gpBAAgpB;IAC7pB,WAAW,EAAE,YAAY;IACzB,WAAW,EAAE,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,IAAI,CAAC;CAClC,CAAC"}
@@ -1,2 +1,2 @@
1
1
  import type { Skill } from '../../manifest.js';
2
- export declare const praxis: Skill;
2
+ export declare const design: Skill;
@@ -0,0 +1,79 @@
1
+ // THE DURATIVE HALF. `plan` and `deliver` are per-effort and disposable; this cell
2
+ // is the one that persists, and that asymmetry is the whole point of the trio.
3
+ //
4
+ // It exists because the corpus could DO long-horizon work and could only THINK in
5
+ // single sittings: every conceptual cell (conceptualize · signify · materialize ·
6
+ // exemplify) is episodic — invoked on a source, emits a result, finishes — while the
7
+ // planning cell alone bound, elected and persisted across sessions. So a project's
8
+ // concepts were re-derived per session, per agent, forever. The superseded `praxis`
9
+ // measured exactly that against itself: sixteen retired plans, twenty-five laws
10
+ // established, zero surviving into any corpus.
11
+ //
12
+ // The second reason is verification. Acceptance keyed to a work-unit's own criteria
13
+ // is a CLOSED loop — the unit is graded against its own account of itself, so an
14
+ // executor that satisfies the letter passes while the system stays incoherent. A
15
+ // second, independent statement of what should exist is what makes validation an
16
+ // operation rather than a re-reading of the claim. That statement is this lattice.
17
+ const FORMAL_BLOCK = `anchor ≜ a concept's canonical sign @ signify
18
+ gloss ≜ what a concept IS ⟨one line · reconstruction-grade⟩
19
+ C ≜ the concept lattice ⟨the project's durative record⟩
20
+ c ≜ a concept ⟨c ∈ C⟩
21
+ concept ≜ ⟨ anchor(c) , gloss(c) , factors(c) ⟩
22
+ factors : C → ℘(C) ⟨what c decomposes into⟩
23
+ primitive(c) ⇔ factors(c) = ∅ ⟨held by VALUE ⟨anchor · gloss⟩⟩
24
+ composite(c) ⇔ factors(c) ≠ ∅ ⟨held by REFERENCE ⟨anchor · factor-anchors⟩ @ materialize⟩
25
+ closure : C → ℘(C) ⟨closure(c) ≜ { c } ∪ ⋃ { closure(f) | f ∈ factors(c) }⟩
26
+ denotes : anchor ⇀ C
27
+ σ* @ signify
28
+ conform @ signify
29
+ Piece ≜ a cut piece ⟨what a planner is handed⟩
30
+ cut : C → ℘(℘(C))
31
+ digest : ℘(C) → hash ⟨content address of a piece⟩
32
+ pin : Piece ⇀ hash ⟨the digest a piece was DERIVED from · carried with it⟩
33
+ Phase ≜ { live, superseded }
34
+ phase : C → Phase
35
+ supersededBy : C ⇀ C
36
+ commit ≜ a VCS commit ⟨the append-only carrier · attribution ∧ order⟩
37
+ amends : commit × C → 𝔹
38
+ accepts : commit → 𝔹 ⟨the commit carries an acceptance @ deliver⟩
39
+ realizes : unit ⇀ anchor @ plan
40
+ yield ≜ what execution established ∧ ¬ derivable from C @ deliver
41
+ self ≜ the principal ⟨the design-holder · ¬ delegable⟩
42
+ author : C ⇀ self
43
+
44
+ ∀ c : ∃! anchor(c) ∧ ∀ a ∈ dom(denotes) : ∃! denotes(a) ⟨one name ⇔ one concept⟩
45
+ ∀ c : conform(anchor(c)) ∧ gloss(c) ≠ ∅
46
+ ∀ c : closure(c) finite ⟨factors acyclic ∴ a lattice, ¬ a graph⟩
47
+ amend(C) ≜ supersede ⟨∄ overwrite ; a live c is NEVER edited in place⟩
48
+ ⟨the protection is ¬ a rule about honesty : an editable lattice lets the agent
49
+ adjust the concept its artifact failed, ∴ acceptance-against-C goes CIRCULAR
50
+ with one extra step ∧ the loop manufactures its own evidence⟩
51
+ supersede(c, c') ⇒ phase(c) := superseded ∧ supersededBy(c) = c' ∧ c ∈ C
52
+ ⟨residence, ¬ deletion : a reader of the CURRENT state sees the history without
53
+ a VCS query ∴ the lattice is self-describing⟩
54
+ ∀ k : amends(k, c) ⇒ ¬ accepts(k) ⟨THE separation · an amendment and an acceptance
55
+ it bears on are two acts ; fused, the second witness collapses into the first⟩
56
+ ∀ k : amends(k, c) ⇒ reason(k) ≠ ∅ ⟨attribution ∧ order are what make retroactive
57
+ justification DETECTABLE : the amendment postdates the artifact it excuses⟩
58
+ blast(c) ≜ { d ∈ C | c ∈ closure(d) } ⟨DERIVED, ¬ guessed · what the normal form buys⟩
59
+ churn(primitive) high ⇒ conceptualization wrong ⟨primitives near-stable · composites move⟩
60
+ ⋃ cut(C) = C ∧ ∀ s₁, s₂ ∈ cut(C) : s₁ ≠ s₂ ⇒ s₁ ∩ s₂ = ∅
61
+ ∀ s ∈ cut(C) : ∀ c ∈ s : closure(c) ⊆ s ⟨a piece is CLOSED ∴ plannable alone⟩
62
+ cut ⊨ self ⟨the ASSIGNMENT of concepts to pieces is the design-holder's ; a planner
63
+ receiving a piece may ¬ redraw it · a boundary it cannot plan is SURFACED⟩
64
+ ∀ s ∈ cut(C) : pin(s) = digest(s) ⟨a piece carries the digest it was derived from ∴
65
+ an amendment mid-flight surfaces as DRIFT, ¬ executes silently⟩
66
+ yield ≠ ∅ ⇒ amend(C) ⟨intake at INCEPTION ∧ live, never at retirement : an obligation
67
+ standing between an agent and closing its work always loses · measured 0 of 25⟩
68
+ ∀ c : ∄ unit ⟨realizes(unit) = anchor(c)⟩ ⇒ SURFACE ⟨a concept nothing builds is design agreed ∧
69
+ unbuilt · the reverse orphan is plan's⟩
70
+ design ⊨ ¬ delegable ⟨a subagent starts blank ∧ a design authored by several
71
+ fragments BY CONSTRUCTION⟩
72
+ design ≜ conceptualize(intent) → signify(·) → materialize(·) → C ⟨bind⟩ → cut(C)`;
73
+ export const design = {
74
+ name: 'design',
75
+ description: `use this skill to build and hold a project's DURATIVE conceptual model — the one artifact that outlives every plan: each concept's anchor, gloss and factorization, amended only by append-only supersession, and cut into closed pieces a planner can take. Reach for it FIRST on any long-horizon effort, before any work is decomposed, and again whenever execution establishes something the model does not yet hold. It is what acceptance is judged against, so without it verification has no referent and degrades into re-reading the executor's own claim.`,
76
+ formalBlock: FORMAL_BLOCK,
77
+ composition: () => [],
78
+ };
79
+ //# sourceMappingURL=skill.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skill.js","sourceRoot":"","sources":["../../../src/skills/design/skill.ts"],"names":[],"mappings":"AAEA,mFAAmF;AACnF,+EAA+E;AAC/E,EAAE;AACF,kFAAkF;AAClF,kFAAkF;AAClF,qFAAqF;AACrF,mFAAmF;AACnF,oFAAoF;AACpF,gFAAgF;AAChF,+CAA+C;AAC/C,EAAE;AACF,oFAAoF;AACpF,iFAAiF;AACjF,iFAAiF;AACjF,iFAAiF;AACjF,mFAAmF;AAEnF,MAAM,YAAY,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iFAuD+E,CAAC;AAErG,MAAM,CAAC,MAAM,MAAM,GAAU;IAC3B,IAAI,EAAE,QAAQ;IACd,WAAW,EAAE,uiBAAuiB;IACpjB,WAAW,EAAE,YAAY;IACzB,WAAW,EAAE,GAAG,EAAE,CAAC,EAAE;CACtB,CAAC"}
@@ -0,0 +1,2 @@
1
+ import type { Skill } from '../../manifest.js';
2
+ export declare const plan: Skill;