@shardworks/astrolabe-apparatus 0.1.234 → 0.1.236

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  # `@shardworks/astrolabe-apparatus`
2
2
 
3
- The Astrolabe transforms patron briefs into structured work specifications and carries them through implementation. A single combined rig (`astrolabe.plan-and-ship`) runs the planning pipeline — inventory, analysis, optional Patron Anima pre-review, patron review, specification writing — and then continues into draft → implement → review → revise → seal on the same brief writ. The brief reaches `completed` only after the final seal engine finishes. It sits between the Clerk (writ lifecycle) and the Spider (rig execution), contributing kit pieces to both.
3
+ The Astrolabe transforms patron briefs into structured work specifications and carries them through implementation. A single combined rig (`astrolabe.plan-and-ship`) runs the planning pipeline — inventory, analysis, optional Patron Anima pre-fill, patron review, specification writing — and then continues into draft → implement → review → revise → seal on the same brief writ. The brief reaches `completed` only after the final seal engine finishes. It sits between the Clerk (writ lifecycle) and the Spider (rig execution), contributing kit pieces to both.
4
4
 
5
5
  ---
6
6
 
@@ -95,7 +95,7 @@ Add an `astrolabe` section to `guild.json` to configure behaviour:
95
95
 
96
96
  | Field | Type | Default | Description |
97
97
  |---|---|---|---|
98
- | `patronRole` | `string` | `""` (unset) | Qualified role name of the Patron Anima consulted before decision-review. When unset or empty, the `patron-anima` engine no-ops and decision-review behaves exactly as it did before the engine existed. |
98
+ | `patronRole` | `string` | `""` (unset) | Qualified role name of the Patron Anima consulted before decision-review. When set, the `patron-anima` engine launches an anima in this role under a tailored operational prompt (see `patron-anima-prompt.md`) that encodes the engine's mode discipline — one option per decision, principle-structural confidence calibration, abstain-by-omission, and an out-of-lane prohibition on codebase audit work. The anima pre-fills decisions it can confidently resolve; the rest fall through to decision-review as usual. When unset or empty, the engine no-ops and decision-review behaves exactly as it did before the engine existed. |
99
99
 
100
100
  ## Support Kit
101
101
 
@@ -128,7 +128,7 @@ The Astrolabe declares one book in Stacks:
128
128
  |---|---|
129
129
  | `astrolabe.plan-init` | Creates a PlanDoc from the brief writ; validates codex presence |
130
130
  | `astrolabe.inventory-check` | Validates that the reader produced a non-empty inventory |
131
- | `astrolabe.patron-anima` | Consults a configured Patron Anima to pre-fill decisions on behalf of the patron. Reads the plan's reviewable decisions (those without `selected` already set), launches the configured `patronRole` via an anima session, parses a single structured emission, and applies each valid verdict to `Decision.selected` (plus records the full verdict — confirm/override/fill-in with selection, confidence, rationale — on `Decision.patron`). No-ops when `astrolabe.patronRole` is unset or empty, or when no reviewable decisions remain. Unparseable output or invalid verdicts are silently skipped — decision-review surfaces the remainder to the patron. |
131
+ | `astrolabe.patron-anima` | Consults a configured Patron Anima to pre-fill decisions on behalf of the patron, under a tailored operational prompt that encodes the engine's mode discipline — one option per decision, principle-structural confidence calibration, abstain-by-omission (decisions the anima cannot confidently resolve are absent from its emission, not emitted as low-confidence placeholders), and an explicit out-of-lane prohibition on codebase audit work. Reads the plan's reviewable decisions (those without `selected` already set), launches the configured `patronRole` via a single-pass anima session, parses a single structured emission, and applies each valid verdict to `Decision.selected` (plus records the full verdict — confirm / override / fill-in with selection, confidence, rationale — on `Decision.patron`). No-ops when `astrolabe.patronRole` is unset or empty, or when no reviewable decisions remain. Unparseable output, invalid verdicts, and abstained decisions are left unfilled — decision-review surfaces the remainder to the patron in the normal flow. |
132
132
  | `astrolabe.decision-review` | Two-pass engine: blocks for patron review, then reconciles answers. Decisions with `selected` already pre-set by the analyst or the patron anima are auto-accepted — they are excluded from the InputRequestDoc, and if nothing remains reviewable the engine fast-paths to `writing` without opening the gate. |
133
133
  | `astrolabe.plan-finalize` | Transitions the plan to `completed` and yields the written `spec` downstream. Does not post any writ. Used inside `plan-and-ship` to hand the spec off to the implement engine on the same brief rig. |
134
134
  | `astrolabe.spec-publish` | Publishes the generated specification as a new mandate writ. Used only by the legacy two-phase / three-phase rigs that split planning from implementation across two writs. |
@@ -145,7 +145,7 @@ The `resolutionEngine` is `seal` for `plan-and-ship` (brief completes when imple
145
145
 
146
146
  #### Rig Template Selection
147
147
 
148
- The `brief` writ type maps to `astrolabe.plan-and-ship` by default. This single combined rig carries the brief through planning and implementation on one writ — the `plan-finalize` engine hands the written spec directly to the downstream `implement` engine via `${yields.plan-finalize.spec}`, and no separate mandate writ is posted. The optional `patron-anima` stage between `inventory-check` and `decision-review` can pre-fill decisions on the patron's behalf when `astrolabe.patronRole` is configured, letting decision-review fast-path past any pre-decided items. The brief reaches `completed` only when the final seal engine completes.
148
+ The `brief` writ type maps to `astrolabe.plan-and-ship` by default. This single combined rig carries the brief through planning and implementation on one writ — the `plan-finalize` engine hands the written spec directly to the downstream `implement` engine via `${yields.plan-finalize.spec}`, and no separate mandate writ is posted. The optional `patron-anima` stage between `inventory-check` and `decision-review` consults the configured `patronRole` under a tailored operational prompt (see `patron-anima-prompt.md` packaged with the plugin) whenever `astrolabe.patronRole` is set, pre-filling the decisions the anima can confidently resolve and letting decision-review fast-path past those items. Decisions the anima abstains on (or cannot cleanly resolve) are left unfilled and flow through to decision-review in the normal path. The brief reaches `completed` only when the final seal engine completes.
149
149
 
150
150
  To use a legacy planning-only template (which posts a separate mandate writ and ends the brief's lifecycle at spec-writer), add a rig template mapping override in `guild.json`:
151
151
 
@@ -7,6 +7,33 @@
7
7
  * `selected` value — `decision-review` then auto-skips it via the existing
8
8
  * "analyst pre-decides → patron-input omitted" semantics.
9
9
  *
10
+ * Operational discipline (the tailored work prompt):
11
+ * The anima runs under a checked-in operational prompt — the static
12
+ * portions live in `patron-anima-prompt.md` (packaged alongside the
13
+ * plugin) and are loaded at startup; per-decision content (ids,
14
+ * questions, options, analyst recommendations) is interpolated in this
15
+ * module at build time. The prompt encodes the engine's mode discipline,
16
+ * which is structurally distinct from the anima's taste (which lives in
17
+ * the role's system prompt):
18
+ *
19
+ * - One option per decision. `selection` must be one of the offered
20
+ * option keys — no custom answers, no free-text, no multi-select.
21
+ * - Principle-structural confidence. `high` = a single principle from
22
+ * the role fires cleanly; `med` = multiple principles conflict and
23
+ * the anima resolves the conflict; `low` = no principle speaks,
24
+ * which is the abstain case.
25
+ * - Abstain by omission. A decision that would resolve to `low` —
26
+ * or that the anima cannot confidently resolve at all — is
27
+ * **absent** from the emission array entirely. There is no
28
+ * sentinel, no placeholder, no low-confidence confirm fallback.
29
+ * The engine treats a missing verdict as "unfilled" and flows it
30
+ * through to `decision-review` in the normal path.
31
+ * - Out-of-lane prohibition. The draft worktree `cwd` passed to the
32
+ * anima permits filesystem access, but the prompt explicitly
33
+ * forbids file reads, grep, codebase audit, and second-guessing
34
+ * the analyst's framing. The anima's entire input is the role's
35
+ * principles plus the decisions listed in the prompt.
36
+ *
10
37
  * Config:
11
38
  * guild.json["astrolabe"]["patronRole"]
12
39
  * Qualified role name for the Patron Anima (e.g. 'guild.patron').
@@ -28,31 +55,38 @@
28
55
  * - `id` — the decision id
29
56
  * - `verdict` — 'confirm' | 'override' | 'fill-in'
30
57
  * - `selection` — one of the decision's offered option keys
31
- * - `confidence` — 'low' | 'med' | 'high'
58
+ * - `confidence` — 'high' | 'med' (`low` means abstain → omit)
32
59
  * - `rationale` — short free-text note (optional)
60
+ * Decisions the anima abstains on are absent from the array — the
61
+ * engine and the parser treat absence as "unfilled, surface to patron."
33
62
  *
34
63
  * Exhaustiveness:
35
64
  * Single pass. Any decision not carrying a well-formed verdict —
36
- * because the anima omitted it, emitted malformed JSON, picked an
37
- * unknown option, or the session failed entirely — is left unfilled
38
- * on the PlanDoc and flows to `decision-review` in the normal flow.
39
- * The engine does not retry.
65
+ * because the anima abstained (omitted it), emitted malformed JSON,
66
+ * picked an unknown option, or the session failed entirely — is left
67
+ * unfilled on the PlanDoc and flows to `decision-review` in the
68
+ * normal flow. The engine does not retry.
40
69
  *
41
- * Self-uncertainty:
42
- * A `confirm` at `confidence: 'low'` is the expected encoding for
43
- * "anima doesn't know patron well enough on this surface." It still
44
- * applies the analyst's recommendation; the high-confirm / low-
45
- * confidence signal is the diagnostic substrate for override-rate
46
- * × confidence, not an escalation trigger.
70
+ * Defensive parser leniency:
71
+ * The parser still accepts `confidence: 'low'` as a valid value for
72
+ * schema-stability reasons if a stray low-confidence verdict reaches
73
+ * the engine, it is applied rather than dropped. The operational
74
+ * prompt instructs the anima to abstain rather than emit `low`, but
75
+ * the schema and parser do not depend on that instruction being
76
+ * followed. This is defensive leniency, not a supported emission path.
47
77
  */
48
78
  import type { EngineDesign } from '@shardworks/fabricator-apparatus';
49
79
  import type { Book } from '@shardworks/stacks-apparatus';
50
80
  import type { Decision, PatronEmission, PlanDoc } from '../types.ts';
51
81
  /**
52
- * Assemble the patron prompt from the reviewable decisions. Each decision
53
- * is rendered with its question, optional context, options, and optional
54
- * analyst recommendation / rationale. The anima is instructed to return a
55
- * single fenced JSON block with one verdict per decision.
82
+ * Assemble the patron work prompt from the reviewable decisions.
83
+ *
84
+ * The static portion (preamble, mode discipline, out-of-lane prohibition,
85
+ * output contract, worked example) lives in `patron-anima-prompt.md` and is
86
+ * loaded into `PROMPT_TEMPLATE` at module load. This function renders each
87
+ * reviewable decision — question, optional context, options, optional
88
+ * analyst recommendation / rationale — and substitutes the listing into
89
+ * the template's `{{DECISIONS}}` placeholder.
56
90
  */
57
91
  export declare function buildPatronPrompt(decisions: Decision[]): string;
58
92
  /** Extract the last fenced JSON block from an anima's output. Returns null if none. */
@@ -1 +1 @@
1
- {"version":3,"file":"patron-anima.d.ts","sourceRoot":"","sources":["../../src/engines/patron-anima.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8CG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAqC,MAAM,kCAAkC,CAAC;AACxG,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,8BAA8B,CAAC;AAKzD,OAAO,KAAK,EAAE,QAAQ,EAAE,cAAc,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AASrE;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,QAAQ,EAAE,GAAG,MAAM,CA2E/D;AAED,uFAAuF;AACvF,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAa9D;AAED,MAAM,WAAW,UAAU;IACzB,EAAE,CAAC,EAAE,OAAO,CAAC;IACb,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAC3B,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,QAAQ,EAAE,GACpB,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,CA8E7B;AAID,wBAAgB,uBAAuB,CAAC,YAAY,EAAE,MAAM,IAAI,CAAC,OAAO,CAAC,GAAG,YAAY,CA2GvF"}
1
+ {"version":3,"file":"patron-anima.d.ts","sourceRoot":"","sources":["../../src/engines/patron-anima.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4EG;AAOH,OAAO,KAAK,EAAE,YAAY,EAAqC,MAAM,kCAAkC,CAAC;AACxG,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,8BAA8B,CAAC;AAKzD,OAAO,KAAK,EAAE,QAAQ,EAAE,cAAc,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AA6BrE;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,QAAQ,EAAE,GAAG,MAAM,CAmC/D;AAED,uFAAuF;AACvF,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAa9D;AAED,MAAM,WAAW,UAAU;IACzB,EAAE,CAAC,EAAE,OAAO,CAAC;IACb,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAC3B,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,QAAQ,EAAE,GACpB,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,CA8E7B;AAID,wBAAgB,uBAAuB,CAAC,YAAY,EAAE,MAAM,IAAI,CAAC,OAAO,CAAC,GAAG,YAAY,CA2GvF"}
@@ -7,6 +7,33 @@
7
7
  * `selected` value — `decision-review` then auto-skips it via the existing
8
8
  * "analyst pre-decides → patron-input omitted" semantics.
9
9
  *
10
+ * Operational discipline (the tailored work prompt):
11
+ * The anima runs under a checked-in operational prompt — the static
12
+ * portions live in `patron-anima-prompt.md` (packaged alongside the
13
+ * plugin) and are loaded at startup; per-decision content (ids,
14
+ * questions, options, analyst recommendations) is interpolated in this
15
+ * module at build time. The prompt encodes the engine's mode discipline,
16
+ * which is structurally distinct from the anima's taste (which lives in
17
+ * the role's system prompt):
18
+ *
19
+ * - One option per decision. `selection` must be one of the offered
20
+ * option keys — no custom answers, no free-text, no multi-select.
21
+ * - Principle-structural confidence. `high` = a single principle from
22
+ * the role fires cleanly; `med` = multiple principles conflict and
23
+ * the anima resolves the conflict; `low` = no principle speaks,
24
+ * which is the abstain case.
25
+ * - Abstain by omission. A decision that would resolve to `low` —
26
+ * or that the anima cannot confidently resolve at all — is
27
+ * **absent** from the emission array entirely. There is no
28
+ * sentinel, no placeholder, no low-confidence confirm fallback.
29
+ * The engine treats a missing verdict as "unfilled" and flows it
30
+ * through to `decision-review` in the normal path.
31
+ * - Out-of-lane prohibition. The draft worktree `cwd` passed to the
32
+ * anima permits filesystem access, but the prompt explicitly
33
+ * forbids file reads, grep, codebase audit, and second-guessing
34
+ * the analyst's framing. The anima's entire input is the role's
35
+ * principles plus the decisions listed in the prompt.
36
+ *
10
37
  * Config:
11
38
  * guild.json["astrolabe"]["patronRole"]
12
39
  * Qualified role name for the Patron Anima (e.g. 'guild.patron').
@@ -28,76 +55,90 @@
28
55
  * - `id` — the decision id
29
56
  * - `verdict` — 'confirm' | 'override' | 'fill-in'
30
57
  * - `selection` — one of the decision's offered option keys
31
- * - `confidence` — 'low' | 'med' | 'high'
58
+ * - `confidence` — 'high' | 'med' (`low` means abstain → omit)
32
59
  * - `rationale` — short free-text note (optional)
60
+ * Decisions the anima abstains on are absent from the array — the
61
+ * engine and the parser treat absence as "unfilled, surface to patron."
33
62
  *
34
63
  * Exhaustiveness:
35
64
  * Single pass. Any decision not carrying a well-formed verdict —
36
- * because the anima omitted it, emitted malformed JSON, picked an
37
- * unknown option, or the session failed entirely — is left unfilled
38
- * on the PlanDoc and flows to `decision-review` in the normal flow.
39
- * The engine does not retry.
65
+ * because the anima abstained (omitted it), emitted malformed JSON,
66
+ * picked an unknown option, or the session failed entirely — is left
67
+ * unfilled on the PlanDoc and flows to `decision-review` in the
68
+ * normal flow. The engine does not retry.
40
69
  *
41
- * Self-uncertainty:
42
- * A `confirm` at `confidence: 'low'` is the expected encoding for
43
- * "anima doesn't know patron well enough on this surface." It still
44
- * applies the analyst's recommendation; the high-confirm / low-
45
- * confidence signal is the diagnostic substrate for override-rate
46
- * × confidence, not an escalation trigger.
70
+ * Defensive parser leniency:
71
+ * The parser still accepts `confidence: 'low'` as a valid value for
72
+ * schema-stability reasons if a stray low-confidence verdict reaches
73
+ * the engine, it is applied rather than dropped. The operational
74
+ * prompt instructs the anima to abstain rather than emit `low`, but
75
+ * the schema and parser do not depend on that instruction being
76
+ * followed. This is defensive leniency, not a supported emission path.
47
77
  */
78
+ import { readFileSync } from 'node:fs';
79
+ import { dirname, resolve } from 'node:path';
80
+ import { fileURLToPath } from 'node:url';
48
81
  import { guild } from '@shardworks/nexus-core';
49
82
  import { resolveAstrolabeConfig } from "../astrolabe.js";
83
+ // ── Prompt template ──────────────────────────────────────────────────
84
+ const __filename = fileURLToPath(import.meta.url);
85
+ const __dirname = dirname(__filename);
86
+ /**
87
+ * The static portion of the patron-anima operational prompt, loaded at module
88
+ * load time from the checked-in markdown file packaged alongside this plugin.
89
+ * The sentinel `{{DECISIONS}}` is replaced by the per-decision listing at
90
+ * prompt-build time. The markdown file lives at the package root so it is
91
+ * reachable via the same relative path from both `src/engines/` (source
92
+ * mode) and `dist/engines/` (published distribution).
93
+ */
94
+ const PROMPT_TEMPLATE = readFileSync(resolve(__dirname, '../../patron-anima-prompt.md'), 'utf-8');
95
+ const DECISIONS_PLACEHOLDER = '{{DECISIONS}}';
50
96
  // ── Helpers ──────────────────────────────────────────────────────────
51
97
  /** Reviewable = not yet pre-decided by the analyst. Mirrors decision-review. */
52
98
  function reviewableDecisions(plan) {
53
99
  return (plan.decisions ?? []).filter(d => d.selected === undefined);
54
100
  }
55
101
  /**
56
- * Assemble the patron prompt from the reviewable decisions. Each decision
57
- * is rendered with its question, optional context, options, and optional
58
- * analyst recommendation / rationale. The anima is instructed to return a
59
- * single fenced JSON block with one verdict per decision.
102
+ * Assemble the patron work prompt from the reviewable decisions.
103
+ *
104
+ * The static portion (preamble, mode discipline, out-of-lane prohibition,
105
+ * output contract, worked example) lives in `patron-anima-prompt.md` and is
106
+ * loaded into `PROMPT_TEMPLATE` at module load. This function renders each
107
+ * reviewable decision — question, optional context, options, optional
108
+ * analyst recommendation / rationale — and substitutes the listing into
109
+ * the template's `{{DECISIONS}}` placeholder.
60
110
  */
61
111
  export function buildPatronPrompt(decisions) {
62
- const parts = [
63
- '# Patron Decision Review',
64
- '',
65
- 'You are the patron anima. The analyst has surfaced the following',
66
- 'decisions. For each one, emit a structured verdict in the patron\'s',
67
- 'voice so the planning pipeline can proceed without a human block.',
68
- '',
69
- '## Decisions',
70
- '',
71
- ];
112
+ const lines = [];
72
113
  for (const decision of decisions) {
73
- parts.push(`### ${decision.id}: ${decision.question}`);
114
+ lines.push(`### ${decision.id}: ${decision.question}`);
74
115
  if (decision.context) {
75
- parts.push('');
76
- parts.push(`Context: ${decision.context}`);
116
+ lines.push('');
117
+ lines.push(`Context: ${decision.context}`);
77
118
  }
78
- parts.push('');
79
- parts.push('Options:');
119
+ lines.push('');
120
+ lines.push('Options:');
80
121
  for (const [key, label] of Object.entries(decision.options)) {
81
- parts.push(`- \`${key}\` — ${label}`);
122
+ lines.push(`- \`${key}\` — ${label}`);
82
123
  }
83
124
  if (decision.recommendation) {
84
- parts.push('');
125
+ lines.push('');
85
126
  const recLabel = decision.options[decision.recommendation] ?? decision.recommendation;
86
- parts.push(`Analyst recommendation: \`${decision.recommendation}\` (${recLabel})`);
127
+ lines.push(`Analyst recommendation: \`${decision.recommendation}\` (${recLabel})`);
87
128
  if (decision.rationale) {
88
- parts.push(`Analyst rationale: ${decision.rationale}`);
129
+ lines.push(`Analyst rationale: ${decision.rationale}`);
89
130
  }
90
131
  }
91
132
  else {
92
- parts.push('');
93
- parts.push('Analyst recommendation: (none — you must fill in)');
133
+ lines.push('');
134
+ lines.push('Analyst recommendation: (none — you must fill in)');
94
135
  }
95
- parts.push('');
136
+ lines.push('');
96
137
  }
97
- parts.push('## Output contract');
98
- parts.push('');
99
- parts.push('Respond with a single fenced JSON block containing an array of', 'verdict objects — one per decision, keyed by decision id. Do not', 'emit prose outside the fenced block; anything outside is ignored.', '', 'Each verdict object MUST have these fields:', '', '- `id` — the decision id (copy from above)', '- `verdict` — one of `confirm` | `override` | `fill-in`', ' - `confirm` — you accept the analyst\'s recommendation', ' - `override` — you pick a different option than the recommendation', ' - `fill-in` — no analyst recommendation existed; you supply one', '- `selection` — the option key you are selecting (MUST be one of the', ' offered option keys above — no custom / free-text answers)', '- `confidence` — one of `low` | `med` | `high`, calibrated against the', ' patron role\'s principles list:', ' - `high` — exactly one principle applies cleanly', ' - `med` — multiple principles conflict (note the conflict in rationale)', ' - `low` — no principle applies (default to `confirm` at `low` rather', ' than abstaining or improvising — leaving decisions unfilled is the', ' fallback path when you genuinely cannot answer)', '- `rationale` — short free-text note (≤ 1 sentence) citing which', ' principle (or conflict) produced this verdict', '', 'Example:', '', '```json', '[', ' { "id": "D1", "verdict": "confirm", "selection": "A", "confidence": "high", "rationale": "Matches simplicity principle." }', ']', '```');
100
- return parts.join('\n');
138
+ // Drop the trailing blank line so the substitution sits cleanly in the
139
+ // template's final section.
140
+ const decisionsBlock = lines.join('\n').replace(/\n+$/, '');
141
+ return PROMPT_TEMPLATE.replace(DECISIONS_PLACEHOLDER, decisionsBlock);
101
142
  }
102
143
  /** Extract the last fenced JSON block from an anima's output. Returns null if none. */
103
144
  export function extractJsonBlock(output) {
@@ -1 +1 @@
1
- {"version":3,"file":"patron-anima.js","sourceRoot":"","sources":["../../src/engines/patron-anima.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"patron-anima.js","sourceRoot":"","sources":["../../src/engines/patron-anima.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shardworks/astrolabe-apparatus",
3
- "version": "0.1.234",
3
+ "version": "0.1.236",
4
4
  "license": "ISC",
5
5
  "repository": {
6
6
  "type": "git",
@@ -20,17 +20,17 @@
20
20
  },
21
21
  "dependencies": {
22
22
  "zod": "4.3.6",
23
- "@shardworks/clerk-apparatus": "0.1.234",
24
- "@shardworks/stacks-apparatus": "0.1.234",
25
- "@shardworks/spider-apparatus": "0.1.234",
26
- "@shardworks/tools-apparatus": "0.1.234",
27
- "@shardworks/fabricator-apparatus": "0.1.234",
28
- "@shardworks/animator-apparatus": "0.1.234",
29
- "@shardworks/loom-apparatus": "0.1.234"
23
+ "@shardworks/stacks-apparatus": "0.1.236",
24
+ "@shardworks/clerk-apparatus": "0.1.236",
25
+ "@shardworks/spider-apparatus": "0.1.236",
26
+ "@shardworks/tools-apparatus": "0.1.236",
27
+ "@shardworks/fabricator-apparatus": "0.1.236",
28
+ "@shardworks/loom-apparatus": "0.1.236",
29
+ "@shardworks/animator-apparatus": "0.1.236"
30
30
  },
31
31
  "devDependencies": {
32
32
  "@types/node": "25.5.0",
33
- "@shardworks/nexus-core": "0.1.234"
33
+ "@shardworks/nexus-core": "0.1.236"
34
34
  },
35
35
  "files": [
36
36
  "dist",
@@ -38,6 +38,7 @@
38
38
  "sage-analyst.md",
39
39
  "sage-writer.md",
40
40
  "sage-reading-analyst.md",
41
+ "patron-anima-prompt.md",
41
42
  "pages"
42
43
  ],
43
44
  "scripts": {
@@ -0,0 +1,131 @@
1
+ # Patron Anima — Operational Prompt
2
+
3
+ You are the Patron Anima. Between the analyst and the patron's own review, your
4
+ job — for this single run of the engine — is to pre-fill the decisions the
5
+ patron would confidently resolve, so that `decision-review` can fast-path past
6
+ them, and to leave the rest unfilled for the patron to answer directly.
7
+
8
+ Your taste and principles are supplied separately, by your role's system
9
+ prompt. This document governs how you **operate** inside a single run: how to
10
+ select among the options in front of you, how to calibrate confidence, when
11
+ to abstain, and what is out of lane.
12
+
13
+ ## Mode discipline
14
+
15
+ ### One option per decision
16
+
17
+ Each decision below offers a fixed set of option keys. Your `selection` for
18
+ any decision must be exactly one of the offered option keys — no custom
19
+ answers, no free-text substitutions, no multi-selections, no compound
20
+ answers. Decisions that do not fit any offered key belong in the abstain
21
+ bucket (see below), not squeezed into an approximate match.
22
+
23
+ ### Principle-structural confidence
24
+
25
+ Confidence is **structural** — it is derived from how your role's principles
26
+ engage with the decision, not from how familiar the domain feels, how hard
27
+ the decision seems, or how high the stakes are. Do not calibrate confidence
28
+ from content. There are exactly three structural calibrations:
29
+
30
+ - **`high`** — exactly one principle from your role fires cleanly on this
31
+ decision and there is no conflict. Your rationale names that principle.
32
+ - **`med`** — multiple principles speak and they conflict. You resolve the
33
+ conflict with a judgement. Your rationale names the principles in
34
+ conflict and the direction you resolved toward.
35
+ - **`low`** — no principle speaks to the decision at all. In that case,
36
+ **abstain**. See the next section — do not emit a `low` verdict.
37
+
38
+ Do not reach for `low` as a soft vote, as a polite compromise, or as a
39
+ "default confirm" when you are uncertain. Uncertainty that is content-driven
40
+ — "I don't know this domain well" — is not a structural calibration and
41
+ must not become a verdict. If no principle speaks, abstain.
42
+
43
+ ### Abstain by omission
44
+
45
+ If your principles do not speak to a decision, or if a principle conflict
46
+ cannot be resolved without inventing judgement you do not have a basis for,
47
+ **leave the decision out of your emission array entirely**. Do not emit a
48
+ placeholder verdict. Do not emit a low-confidence confirm. Do not improvise
49
+ a selection.
50
+
51
+ Omission is the abstain mechanism. The engine treats a missing verdict as
52
+ "this decision is unfilled" and `decision-review` surfaces it to the patron
53
+ in the normal flow. An abstained decision is indistinguishable — by design
54
+ — from one you never saw.
55
+
56
+ ## Out of lane
57
+
58
+ The environment you are running in happens to have filesystem access and a
59
+ worktree `cwd`. **Do not use it.** Specifically:
60
+
61
+ - Do not read files.
62
+ - Do not run `grep`, `glob`, or any other code-search command.
63
+ - Do not audit the codebase.
64
+ - Do not probe implementation feasibility.
65
+ - Do not second-guess the analyst's framing of each decision. If the analyst's
66
+ framing were untrustworthy, this run would not exist.
67
+
68
+ Your world is exactly (a) the principles supplied by your role and (b) the
69
+ decisions below. That is the complete input. Treating this run as a codebase
70
+ audit opportunity — or as a chance to re-do the analyst's work — is the
71
+ failure mode this section exists to prevent.
72
+
73
+ ## Output contract
74
+
75
+ Respond with a **single fenced JSON block** containing an array of verdict
76
+ objects — one entry per decision that you resolve. Do not emit prose
77
+ outside the fenced block; anything outside is discarded.
78
+
79
+ Each verdict object MUST have these fields:
80
+
81
+ - `id` — the decision id, copied exactly from the decision listing below.
82
+ - `verdict` — one of `confirm` | `override` | `fill-in`:
83
+ - `confirm` — the analyst recommended an option and you accept it.
84
+ `selection` must equal the analyst's recommendation.
85
+ - `override` — the analyst recommended an option and you pick a different
86
+ one. `selection` must differ from the analyst's recommendation.
87
+ - `fill-in` — the analyst offered no recommendation and you supply one.
88
+ - `selection` — the option key you are selecting. **Must be one of the
89
+ offered option keys** listed under that decision. No custom strings.
90
+ - `confidence` — one of `high` | `med`. (A `low` calibration means abstain,
91
+ which is encoded as omission — see above.)
92
+ - `rationale` — short free-text note, one sentence, naming the principle
93
+ (for `high`) or the principle conflict and its resolution (for `med`).
94
+
95
+ Decisions you abstain on are **absent** from the array. They are not
96
+ represented by any object, placeholder, null entry, or sentinel value.
97
+ Absence is the signal.
98
+
99
+ ### Worked example
100
+
101
+ Suppose (for illustration only — these ids will not match any real
102
+ decision you see below) the decision listing contains four decisions,
103
+ `EX-1`, `EX-2`, `EX-3`, and `EX-4`:
104
+
105
+ - `EX-1` — analyst recommended option `A`. A single principle on simplicity
106
+ fires cleanly in favour of `A`.
107
+ - `EX-2` — analyst recommended option `B`. A single principle on
108
+ correctness fires cleanly in favour of option `C`.
109
+ - `EX-3` — analyst offered no recommendation. Two principles —
110
+ reversibility and ergonomics — both speak and conflict. You resolve
111
+ toward reversibility, selecting `Y`.
112
+ - `EX-4` — no principle speaks at all. You abstain.
113
+
114
+ Your emission is:
115
+
116
+ ```json
117
+ [
118
+ { "id": "EX-1", "verdict": "confirm", "selection": "A", "confidence": "high", "rationale": "Simplicity principle fires cleanly." },
119
+ { "id": "EX-2", "verdict": "override", "selection": "C", "confidence": "high", "rationale": "Correctness principle fires cleanly against the recommendation." },
120
+ { "id": "EX-3", "verdict": "fill-in", "selection": "Y", "confidence": "med", "rationale": "Reversibility and ergonomics conflict; resolved toward reversibility." }
121
+ ]
122
+ ```
123
+
124
+ Note that `EX-4` is **absent** from the array. That is how abstain is
125
+ encoded — the decision is not represented in the output at all, not by a
126
+ placeholder, not by a low-confidence confirm, not by any sentinel. Absence
127
+ alone says "patron, please answer this one yourself."
128
+
129
+ ## Decisions
130
+
131
+ {{DECISIONS}}