@shardworks/astrolabe-apparatus 0.1.241 → 0.1.242

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
@@ -56,20 +56,31 @@ A `PlanDoc` is keyed by the brief writ ID and tracks the full planning lifecycle
56
56
 
57
57
  ```typescript
58
58
  interface PlanDoc {
59
- id: string; // Brief writ ID
60
- codex: string; // Target codex
61
- status: PlanStatus; // 'reading' | 'analyzing' | 'reviewing' | 'writing' | 'completed' | 'failed'
62
- inventory?: string; // Markdown: affected files, types, interfaces, patterns
63
- observations?: string; // Markdown: refactoring opportunities, risks, conventions
64
- scope?: ScopeItem[]; // What's in and what's out
65
- decisions?: Decision[]; // Architectural/design decisions with options
66
- spec?: string; // The generated specification (implementation brief + task manifest)
59
+ id: string; // Brief writ ID
60
+ codex: string; // Target codex
61
+ status: PlanStatus; // 'reading' | 'analyzing' | 'reviewing' | 'writing' | 'completed' | 'failed'
62
+ inventory?: string; // Markdown: affected files, types, interfaces, patterns
63
+ observations?: Observation[]; // Atomic, commissionable concerns (see Observation below)
64
+ scope?: ScopeItem[]; // What's in and what's out
65
+ decisions?: Decision[]; // Architectural/design decisions with options
66
+ spec?: string; // The generated specification (implementation brief + task manifest)
67
67
  generatedWritId?: string; // ID of the generated mandate
68
68
  createdAt: string;
69
69
  updatedAt: string;
70
70
  }
71
+
72
+ interface Observation {
73
+ /** Plandoc-local identifier assigned by the sage (convention: obs-1, obs-2, …). */
74
+ id: string;
75
+ /** One-line commission-title-style phrase (~10 words, no trailing punctuation). */
76
+ title: string;
77
+ /** Tactical markdown — file paths, symbols, preconditions, etc. */
78
+ body: string;
79
+ }
71
80
  ```
72
81
 
82
+ Each `Observation` names one concern — a refactoring opportunity, risk, convention drift, or bug — that the sage noticed but that sits outside the brief's scope. The `astrolabe.observation-lift` engine lifts each record into a draft child `brief` writ under the originating brief so a curator (human or automated) can promote it.
83
+
73
84
  ### `PlanFilters`
74
85
 
75
86
  ```typescript
@@ -134,14 +145,15 @@ The Astrolabe declares one book in Stacks:
134
145
  | `astrolabe.decision-review` | Two-pass engine: blocks for patron review, then reconciles answers. Decisions with `selected` already pre-set by the primer 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. |
135
146
  | `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. |
136
147
  | `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. |
148
+ | `astrolabe.observation-lift` | Walks `plan.observations` after the planning-terminator engine has transitioned the plan to `completed` and calls `clerk.post({ type: 'brief', title, body, codex, parentId, draft: true })` once per record. Each created writ enters `new` (draft) phase, invisible to the Spider until a curator publishes it. Silently no-ops when `observations` is empty, absent, or a legacy string; fails fast on the first `clerk.post` error. Does not mutate the plan — the parent-child relationship on the Clerk side is the sole audit trail. Wired unconditionally into all three rig templates. |
137
149
 
138
150
  ### Rig Templates (contributed to Spider)
139
151
 
140
152
  | Template | Mapped Writ Type | Engines |
141
153
  |---|---|---|
142
- | `astrolabe.plan-and-ship` | `brief` (default) | plan-init → draft → reader-analyst → inventory-check → patron-anima → decision-review → spec-writer → plan-finalize → implement → review → revise → seal |
143
- | `astrolabe.two-phase-planning` | — (opt-in) | plan-init → draft → reader-analyst → inventory-check → decision-review → spec-writer → spec-publish → seal |
144
- | `astrolabe.three-phase-planning` | — (opt-in) | plan-init → draft → reader → inventory-check → analyst → decision-review → spec-writer → spec-publish → seal |
154
+ | `astrolabe.plan-and-ship` | `brief` (default) | plan-init → draft → reader-analyst → inventory-check → patron-anima → decision-review → spec-writer → plan-finalize → observation-lift → implement → review → revise → seal |
155
+ | `astrolabe.two-phase-planning` | — (opt-in) | plan-init → draft → reader-analyst → inventory-check → decision-review → spec-writer → spec-publish → observation-lift → seal |
156
+ | `astrolabe.three-phase-planning` | — (opt-in) | plan-init → draft → reader → inventory-check → analyst → decision-review → spec-writer → spec-publish → observation-lift → seal |
145
157
 
146
158
  The `resolutionEngine` is `seal` for `plan-and-ship` (brief completes when implementation seals) and `spec-writer` for the two legacy planning-only templates (where the brief's rig terminates at spec-writer and a follow-up mandate writ carries the implementation separately).
147
159
 
@@ -172,7 +184,7 @@ Substitute `astrolabe.three-phase-planning` for the split reader / scoping-prime
172
184
  | `inventory-write` | `astrolabe:write` | Write or replace the codebase inventory |
173
185
  | `scope-write` | `astrolabe:write` | Write or replace the scope items array |
174
186
  | `decisions-write` | `astrolabe:write` | Write or replace the decisions array |
175
- | `observations-write` | `astrolabe:write` | Write or replace primer observations |
187
+ | `observations-write` | `astrolabe:write` | Write or replace primer observations (strict `Observation[]` array — `{ id, title, body }` records with non-empty strings; legacy prose-string payloads are rejected at zod validation) |
176
188
  | `spec-write` | `astrolabe:write` | Write or replace the generated specification |
177
189
 
178
190
  Write tools only update their artifact field plus `updatedAt`. Status transitions are the exclusive responsibility of the clockwork engines.
@@ -187,6 +199,7 @@ The Astrolabe page provides a list/detail dashboard for PlanDoc records:
187
199
 
188
200
  - **List view** — filterable by status, paginated (20 per page), showing status badge, codex, brief writ title, plan ID, and creation date.
189
201
  - **Detail view** — metadata card with plan ID, status, codex, cross-links to brief and mandate writs (linking to the Clerk writs page via `?writ=ID`), per-step AI cost breakdowns (input/output tokens and USD cost for each anima-session engine), and tabbed content sections for Inventory, Scope, Decisions, Observations, and Spec.
202
+ - **Observations tab** — renders the `Observation[]` array as a card-per-record list (id, title, markdown body). Card bodies flow through the same markdown renderer used by inventory and spec. An empty or absent array renders as an empty tab. A legacy prose-string payload renders as empty rather than corrupting the tab.
190
203
  - **Deep linking** — supports `?plan=ID` query parameter to open directly to a plan's detail view.
191
204
 
192
- Markdown fields (inventory, observations, spec) are rendered client-side with a minimal renderer supporting headings, bold, italic, inline code, fenced code blocks, and lists. All content is HTML-escaped before rendering to prevent XSS.
205
+ Markdown fields (inventory, spec, and each observation body) are rendered client-side with a minimal renderer supporting headings, bold, italic, inline code, fenced code blocks, and lists. All content is HTML-escaped before rendering to prevent XSS.
@@ -1 +1 @@
1
- {"version":3,"file":"astrolabe.d.ts","sourceRoot":"","sources":["../src/astrolabe.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAkB,MAAM,wBAAwB,CAAC;AAQrE,OAAO,KAAK,EAEV,eAAe,EAGhB,MAAM,YAAY,CAAC;AAkBpB,iBAAS,sBAAsB,IAAI,eAAe,CAEjD;AAED;;;;;;;;GAQG;AACH,iBAAS,iBAAiB,IAAI,MAAM,CAGnC;AAID,wBAAgB,eAAe,IAAI,MAAM,CA2RxC;AAGD,OAAO,EAAE,sBAAsB,EAAE,iBAAiB,EAAE,CAAC"}
1
+ {"version":3,"file":"astrolabe.d.ts","sourceRoot":"","sources":["../src/astrolabe.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAkB,MAAM,wBAAwB,CAAC;AAQrE,OAAO,KAAK,EAEV,eAAe,EAGhB,MAAM,YAAY,CAAC;AAmBpB,iBAAS,sBAAsB,IAAI,eAAe,CAEjD;AAED;;;;;;;;GAQG;AACH,iBAAS,iBAAiB,IAAI,MAAM,CAGnC;AAID,wBAAgB,eAAe,IAAI,MAAM,CAySxC;AAGD,OAAO,EAAE,sBAAsB,EAAE,iBAAiB,EAAE,CAAC"}
package/dist/astrolabe.js CHANGED
@@ -10,7 +10,7 @@
10
10
  import { guild } from '@shardworks/nexus-core';
11
11
  import { tool } from '@shardworks/tools-apparatus';
12
12
  import { z } from 'zod';
13
- import { createPlanInitEngine, createInventoryCheckEngine, createPatronAnimaEngine, createDecisionReviewEngine, createSpecPublishEngine, createPlanFinalizeEngine, createReaderAnalystEngine, } from "./engines/index.js";
13
+ import { createPlanInitEngine, createInventoryCheckEngine, createPatronAnimaEngine, createDecisionReviewEngine, createSpecPublishEngine, createPlanFinalizeEngine, createObservationLiftEngine, createReaderAnalystEngine, } from "./engines/index.js";
14
14
  import { twoPhaseRigTemplate } from "./two-phase-planning.js";
15
15
  import { threePhaseRigTemplate } from "./three-phase-planning.js";
16
16
  import { planAndShipRigTemplate } from "./plan-and-ship.js";
@@ -41,6 +41,7 @@ export function createAstrolabe() {
41
41
  const decisionReviewEngine = createDecisionReviewEngine(() => plansBook);
42
42
  const specPublishEngine = createSpecPublishEngine(() => plansBook);
43
43
  const planFinalizeEngine = createPlanFinalizeEngine(() => plansBook);
44
+ const observationLiftEngine = createObservationLiftEngine(() => plansBook);
44
45
  const readerAnalystEngine = createReaderAnalystEngine();
45
46
  // ── API ────────────────────────────────────────────────────────
46
47
  const api = {
@@ -180,11 +181,21 @@ export function createAstrolabe() {
180
181
  const observationsWriteTool = tool({
181
182
  name: 'observations-write',
182
183
  description: 'Write primer observations for a plan',
183
- instructions: 'Writes or replaces the observations field. The observations should be a markdown ' +
184
- 'document noting refactoring opportunities, risks, and conventions.',
184
+ instructions: 'Writes or replaces the observations field. The observations array carries one record ' +
185
+ 'per atomic concern noticed during the planning pass. Each record has a plandoc-local ' +
186
+ 'id (convention: obs-1, obs-2, ...), a one-line commission-title style title, and a ' +
187
+ 'markdown body with tactical detail (file paths, symbols, preconditions). Downstream ' +
188
+ 'the astrolabe.observation-lift engine creates one draft brief writ per record as a ' +
189
+ 'child of the originating brief, ready for a curator to promote.',
185
190
  params: {
186
191
  planId: z.string().describe('Plan id'),
187
- observations: z.string().describe('Observations content (markdown)'),
192
+ observations: z
193
+ .array(z.object({
194
+ id: z.string().min(1),
195
+ title: z.string().min(1),
196
+ body: z.string().min(1),
197
+ }))
198
+ .describe('Observation records'),
188
199
  },
189
200
  permission: 'write',
190
201
  handler: async ({ planId, observations }) => {
@@ -252,6 +263,7 @@ export function createAstrolabe() {
252
263
  'astrolabe.decision-review': decisionReviewEngine,
253
264
  'astrolabe.spec-publish': specPublishEngine,
254
265
  'astrolabe.plan-finalize': planFinalizeEngine,
266
+ 'astrolabe.observation-lift': observationLiftEngine,
255
267
  'astrolabe.reader-analyst': readerAnalystEngine,
256
268
  },
257
269
  rigTemplates: {
@@ -1 +1 @@
1
- {"version":3,"file":"astrolabe.js","sourceRoot":"","sources":["../src/astrolabe.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"astrolabe.js","sourceRoot":"","sources":["../src/astrolabe.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,EAAE,KAAK,EAAE,MAAM,wBAAwB,CAAC;AAC/C,OAAO,EAAE,IAAI,EAAE,MAAM,6BAA6B,CAAC;AAInD,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AASxB,OAAO,EACL,oBAAoB,EACpB,0BAA0B,EAC1B,uBAAuB,EACvB,0BAA0B,EAC1B,uBAAuB,EACvB,wBAAwB,EACxB,2BAA2B,EAC3B,yBAAyB,GAC1B,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAClE,OAAO,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAE5D,wEAAwE;AAExE,SAAS,sBAAsB;IAC7B,OAAO,KAAK,EAAE,CAAC,WAAW,EAAE,CAAC,SAAS,IAAI,EAAE,CAAC;AAC/C,CAAC;AAED;;;;;;;;GAQG;AACH,SAAS,iBAAiB;IACxB,MAAM,MAAM,GAAG,sBAAsB,EAAE,CAAC;IACxC,OAAO,OAAO,MAAM,CAAC,UAAU,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;AAC/E,CAAC;AAED,wEAAwE;AAExE,MAAM,UAAU,eAAe;IAC7B,IAAI,SAAwB,CAAC;IAE7B,kEAAkE;IAElE,MAAM,cAAc,GAAG,oBAAoB,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;IAC7D,MAAM,oBAAoB,GAAG,0BAA0B,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;IACzE,MAAM,iBAAiB,GAAG,uBAAuB,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;IACnE,MAAM,oBAAoB,GAAG,0BAA0B,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;IACzE,MAAM,iBAAiB,GAAG,uBAAuB,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;IACnE,MAAM,kBAAkB,GAAG,wBAAwB,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;IACrE,MAAM,qBAAqB,GAAG,2BAA2B,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;IAC3E,MAAM,mBAAmB,GAAG,yBAAyB,EAAE,CAAC;IAExD,kEAAkE;IAElE,MAAM,GAAG,GAAiB;QACxB,KAAK,CAAC,IAAI,CAAC,MAAc;YACvB,MAAM,IAAI,GAAG,MAAM,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YACzC,IAAI,CAAC,IAAI,EAAE,CAAC;gBACV,MAAM,IAAI,KAAK,CAAC,SAAS,MAAM,cAAc,CAAC,CAAC;YACjD,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC;QAED,KAAK,CAAC,IAAI,CAAC,OAAqB;YAC9B,MAAM,UAAU,GAAgB,EAAE,CAAC;YACnC,IAAI,OAAO,EAAE,MAAM;gBAAE,UAAU,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,GAAG,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;YACtE,IAAI,OAAO,EAAE,KAAK;gBAAE,UAAU,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,GAAG,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC;YACnE,MAAM,KAAK,GAAG,OAAO,EAAE,KAAK,IAAI,EAAE,CAAC;YACnC,MAAM,MAAM,GAAG,OAAO,EAAE,MAAM,CAAC;YAE/B,OAAO,SAAS,CAAC,IAAI,CAAC;gBACpB,KAAK,EAAE,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS;gBACrD,OAAO,EAAE,CAAC,WAAW,EAAE,MAAM,CAAC;gBAC9B,KAAK;gBACL,GAAG,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aAC5C,CAAC,CAAC;QACL,CAAC;QAED,KAAK,CAAC,KAAK,CAAC,MAAc,EAAE,MAAoC;YAC9D,OAAO,SAAS,CAAC,KAAK,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACzC,CAAC;KACF,CAAC;IAEF,kEAAkE;IAElE,MAAM,YAAY,GAAG,IAAI,CAAC;QACxB,IAAI,EAAE,WAAW;QACjB,WAAW,EAAE,6BAA6B;QAC1C,YAAY,EACV,4EAA4E;YAC5E,iEAAiE;QACnE,MAAM,EAAE;YACN,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,qCAAqC,CAAC;SACnE;QACD,UAAU,EAAE,MAAM;QAClB,OAAO,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE;YAC5B,MAAM,IAAI,GAAG,MAAM,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YACzC,IAAI,CAAC,IAAI;gBAAE,MAAM,IAAI,KAAK,CAAC,SAAS,MAAM,cAAc,CAAC,CAAC;YAC1D,OAAO,IAAI,CAAC;QACd,CAAC;KACF,CAAC,CAAC;IAEH,MAAM,YAAY,GAAG,IAAI,CAAC;QACxB,IAAI,EAAE,WAAW;QACjB,WAAW,EAAE,kCAAkC;QAC/C,YAAY,EACV,yEAAyE;YACzE,8CAA8C;QAChD,MAAM,EAAE;YACN,MAAM,EAAE,CAAC;iBACN,IAAI,CAAC,CAAC,SAAS,EAAE,WAAW,EAAE,WAAW,EAAE,SAAS,EAAE,WAAW,EAAE,QAAQ,CAAC,CAAC;iBAC7E,QAAQ,EAAE;iBACV,QAAQ,CAAC,uBAAuB,CAAC;YACpC,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,sBAAsB,CAAC;YAC7D,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,+BAA+B,CAAC;YAClF,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,2BAA2B,CAAC;SACpE;QACD,UAAU,EAAE,MAAM;QAClB,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE;YACxB,MAAM,KAAK,GAAgB,EAAE,CAAC;YAC9B,IAAI,MAAM,CAAC,MAAM;gBAAE,KAAK,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,GAAG,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;YAC9D,IAAI,MAAM,CAAC,KAAK;gBAAE,KAAK,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,GAAG,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;YAC3D,OAAO,SAAS,CAAC,IAAI,CAAC;gBACpB,KAAK,EAAE,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS;gBAC3C,OAAO,EAAE,CAAC,WAAW,EAAE,MAAM,CAAC;gBAC9B,KAAK,EAAE,MAAM,CAAC,KAAK;gBACnB,GAAG,CAAC,MAAM,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aAClE,CAAC,CAAC;QACL,CAAC;KACF,CAAC,CAAC;IAEH,MAAM,kBAAkB,GAAG,IAAI,CAAC;QAC9B,IAAI,EAAE,iBAAiB;QACvB,WAAW,EAAE,yCAAyC;QACtD,YAAY,EACV,gFAAgF;YAChF,+EAA+E;QACjF,MAAM,EAAE;YACN,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC;YACtC,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,8BAA8B,CAAC;SAC/D;QACD,UAAU,EAAE,OAAO;QACnB,OAAO,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,EAAE,EAAE;YACvC,OAAO,SAAS,CAAC,KAAK,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;QACrF,CAAC;KACF,CAAC,CAAC;IAEH,MAAM,cAAc,GAAG,IAAI,CAAC;QAC1B,IAAI,EAAE,aAAa;QACnB,WAAW,EAAE,6CAA6C;QAC1D,YAAY,EACV,kFAAkF;YAClF,oBAAoB;QACtB,MAAM,EAAE;YACN,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC;YACtC,KAAK,EAAE,CAAC;iBACL,KAAK,CACJ,CAAC,CAAC,MAAM,CAAC;gBACP,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE;gBACd,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE;gBACvB,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE;gBACrB,QAAQ,EAAE,CAAC,CAAC,OAAO,EAAE;aACtB,CAAC,CACH;iBACA,QAAQ,CAAC,aAAa,CAAC;SAC3B;QACD,UAAU,EAAE,OAAO;QACnB,OAAO,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,EAAE;YACnC,OAAO,SAAS,CAAC,KAAK,CAAC,MAAM,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;QACjF,CAAC;KACF,CAAC,CAAC;IAEH,MAAM,kBAAkB,GAAG,IAAI,CAAC;QAC9B,IAAI,EAAE,iBAAiB;QACvB,WAAW,EAAE,2CAA2C;QACxD,YAAY,EACV,wFAAwF;YACxF,wDAAwD;QAC1D,MAAM,EAAE;YACN,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC;YACtC,SAAS,EAAE,CAAC;iBACT,KAAK,CACJ,CAAC,CAAC,MAAM,CAAC;gBACP,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE;gBACd,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;gBAC1B,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE;gBACpB,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;gBAC9B,OAAO,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC;gBACzC,cAAc,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;gBACrC,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;gBAChC,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;gBAC/B,cAAc,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;aACtC,CAAC,CACH;iBACA,QAAQ,CAAC,gBAAgB,CAAC;SAC9B;QACD,UAAU,EAAE,OAAO;QACnB,OAAO,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,EAAE,EAAE;YACvC,OAAO,SAAS,CAAC,KAAK,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;QACrF,CAAC;KACF,CAAC,CAAC;IAEH,MAAM,qBAAqB,GAAG,IAAI,CAAC;QACjC,IAAI,EAAE,oBAAoB;QAC1B,WAAW,EAAE,sCAAsC;QACnD,YAAY,EACV,uFAAuF;YACvF,uFAAuF;YACvF,qFAAqF;YACrF,sFAAsF;YACtF,qFAAqF;YACrF,iEAAiE;QACnE,MAAM,EAAE;YACN,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC;YACtC,YAAY,EAAE,CAAC;iBACZ,KAAK,CACJ,CAAC,CAAC,MAAM,CAAC;gBACP,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;gBACrB,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;gBACxB,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;aACxB,CAAC,CACH;iBACA,QAAQ,CAAC,qBAAqB,CAAC;SACnC;QACD,UAAU,EAAE,OAAO;QACnB,OAAO,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,YAAY,EAAE,EAAE,EAAE;YAC1C,OAAO,SAAS,CAAC,KAAK,CAAC,MAAM,EAAE,EAAE,YAAY,EAAE,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;QACxF,CAAC;KACF,CAAC,CAAC;IAEH,MAAM,aAAa,GAAG,IAAI,CAAC;QACzB,IAAI,EAAE,YAAY;QAClB,WAAW,EAAE,8CAA8C;QAC3D,YAAY,EACV,4EAA4E;YAC5E,8CAA8C;QAChD,MAAM,EAAE;YACN,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC;YACtC,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,kCAAkC,CAAC;SAC9D;QACD,UAAU,EAAE,OAAO;QACnB,OAAO,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE;YAClC,OAAO,SAAS,CAAC,KAAK,CAAC,MAAM,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;QAChF,CAAC;KACF,CAAC,CAAC;IAEH,kEAAkE;IAElE,OAAO;QACL,SAAS,EAAE;YACT,QAAQ,EAAE,CAAC,QAAQ,EAAE,OAAO,CAAC;YAC7B,UAAU,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,YAAY,EAAE,QAAQ,EAAE,SAAS,EAAE,UAAU,CAAC;YAE7E,UAAU,EAAE;gBACV,KAAK,EAAE;oBACL,KAAK,EAAE,EAAE,OAAO,EAAE,CAAC,QAAQ,EAAE,OAAO,EAAE,WAAW,CAAC,EAAE;iBACrD;gBAED,SAAS,EAAE;oBACT,EAAE,IAAI,EAAE,OAAO,EAAE,WAAW,EAAE,iDAAiD,EAAE;oBACjF,EAAE,IAAI,EAAE,OAAO,EAAE,WAAW,EAAE,8DAA8D,EAAE;iBAC/F;gBAED,KAAK,EAAE;oBACL,oBAAoB,EAAE;wBACpB,WAAW,EAAE,CAAC,gBAAgB,EAAE,iBAAiB,EAAE,YAAY,EAAE,cAAc,CAAC;wBAChF,MAAM,EAAE,IAAI;wBACZ,gBAAgB,EAAE,uBAAuB;qBAC1C;oBACD,qBAAqB,EAAE;wBACrB,WAAW,EAAE,CAAC,gBAAgB,EAAE,iBAAiB,EAAE,YAAY,EAAE,cAAc,CAAC;wBAChF,MAAM,EAAE,IAAI;wBACZ,gBAAgB,EAAE,wBAAwB;qBAC3C;oBACD,aAAa,EAAE;wBACb,WAAW,EAAE,CAAC,gBAAgB,EAAE,iBAAiB,EAAE,YAAY,EAAE,cAAc,CAAC;wBAChF,MAAM,EAAE,IAAI;wBACZ,gBAAgB,EAAE,gBAAgB;qBACnC;oBACD,kBAAkB,EAAE;wBAClB,WAAW,EAAE,CAAC,gBAAgB,EAAE,iBAAiB,EAAE,YAAY,EAAE,cAAc,CAAC;wBAChF,MAAM,EAAE,IAAI;wBACZ,gBAAgB,EAAE,qBAAqB;qBACxC;oBACD,sBAAsB,EAAE;wBACtB,WAAW,EAAE,CAAC,gBAAgB,EAAE,iBAAiB,EAAE,YAAY,EAAE,cAAc,CAAC;wBAChF,MAAM,EAAE,IAAI;wBACZ,gBAAgB,EAAE,yBAAyB;qBAC5C;iBAC0C;gBAE7C,OAAO,EAAE;oBACP,qBAAqB,EAAE,cAAc;oBACrC,2BAA2B,EAAE,oBAAoB;oBACjD,wBAAwB,EAAE,iBAAiB;oBAC3C,2BAA2B,EAAE,oBAAoB;oBACjD,wBAAwB,EAAE,iBAAiB;oBAC3C,yBAAyB,EAAE,kBAAkB;oBAC7C,4BAA4B,EAAE,qBAAqB;oBACnD,0BAA0B,EAAE,mBAAmB;iBAChD;gBAED,YAAY,EAAE;oBACZ,oBAAoB,EAAE,mBAAmB;oBACzC,sBAAsB,EAAE,qBAAqB;oBAC7C,eAAe,EAAE,sBAAsB;iBACxC;gBAED,mBAAmB,EAAE;oBACnB,KAAK,EAAE,yBAAyB;iBACjC;gBAED,KAAK,EAAE;oBACL,YAAY;oBACZ,YAAY;oBACZ,kBAAkB;oBAClB,cAAc;oBACd,kBAAkB;oBAClB,qBAAqB;oBACrB,aAAa;iBACd;gBAED,KAAK,EAAE;oBACL,EAAE,EAAE,EAAE,WAAW,EAAE,KAAK,EAAE,WAAW,EAAE,GAAG,EAAE,iBAAiB,EAAE;iBAChE;aACF;YAED,QAAQ,EAAE,GAAG;YAEb,KAAK,CAAC,IAAoB;gBACxB,MAAM,MAAM,GAAG,KAAK,EAAE,CAAC,SAAS,CAAY,QAAQ,CAAC,CAAC;gBACtD,SAAS,GAAG,MAAM,CAAC,IAAI,CAAU,WAAW,EAAE,OAAO,CAAC,CAAC;YACzD,CAAC;SACF;KACF,CAAC;AACJ,CAAC;AAED,0FAA0F;AAC1F,OAAO,EAAE,sBAAsB,EAAE,iBAAiB,EAAE,CAAC"}
@@ -4,5 +4,6 @@ export { createPatronAnimaEngine } from './patron-anima.ts';
4
4
  export { createDecisionReviewEngine } from './decision-review.ts';
5
5
  export { createSpecPublishEngine } from './spec-publish.ts';
6
6
  export { createPlanFinalizeEngine } from './plan-finalize.ts';
7
+ export { createObservationLiftEngine } from './observation-lift.ts';
7
8
  export { createReaderAnalystEngine, selectPrimerRole, PRIMER_ATTENDED_ROLE, PRIMER_SOLO_ROLE, } from './reader-analyst.ts';
8
9
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/engines/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AACtD,OAAO,EAAE,0BAA0B,EAAE,MAAM,sBAAsB,CAAC;AAClE,OAAO,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,EAAE,0BAA0B,EAAE,MAAM,sBAAsB,CAAC;AAClE,OAAO,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,EAAE,wBAAwB,EAAE,MAAM,oBAAoB,CAAC;AAC9D,OAAO,EACL,yBAAyB,EACzB,gBAAgB,EAChB,oBAAoB,EACpB,gBAAgB,GACjB,MAAM,qBAAqB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/engines/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AACtD,OAAO,EAAE,0BAA0B,EAAE,MAAM,sBAAsB,CAAC;AAClE,OAAO,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,EAAE,0BAA0B,EAAE,MAAM,sBAAsB,CAAC;AAClE,OAAO,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,EAAE,wBAAwB,EAAE,MAAM,oBAAoB,CAAC;AAC9D,OAAO,EAAE,2BAA2B,EAAE,MAAM,uBAAuB,CAAC;AACpE,OAAO,EACL,yBAAyB,EACzB,gBAAgB,EAChB,oBAAoB,EACpB,gBAAgB,GACjB,MAAM,qBAAqB,CAAC"}
@@ -4,5 +4,6 @@ export { createPatronAnimaEngine } from "./patron-anima.js";
4
4
  export { createDecisionReviewEngine } from "./decision-review.js";
5
5
  export { createSpecPublishEngine } from "./spec-publish.js";
6
6
  export { createPlanFinalizeEngine } from "./plan-finalize.js";
7
+ export { createObservationLiftEngine } from "./observation-lift.js";
7
8
  export { createReaderAnalystEngine, selectPrimerRole, PRIMER_ATTENDED_ROLE, PRIMER_SOLO_ROLE, } from "./reader-analyst.js";
8
9
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/engines/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AACtD,OAAO,EAAE,0BAA0B,EAAE,MAAM,sBAAsB,CAAC;AAClE,OAAO,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,EAAE,0BAA0B,EAAE,MAAM,sBAAsB,CAAC;AAClE,OAAO,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,EAAE,wBAAwB,EAAE,MAAM,oBAAoB,CAAC;AAC9D,OAAO,EACL,yBAAyB,EACzB,gBAAgB,EAChB,oBAAoB,EACpB,gBAAgB,GACjB,MAAM,qBAAqB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/engines/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AACtD,OAAO,EAAE,0BAA0B,EAAE,MAAM,sBAAsB,CAAC;AAClE,OAAO,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,EAAE,0BAA0B,EAAE,MAAM,sBAAsB,CAAC;AAClE,OAAO,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,EAAE,wBAAwB,EAAE,MAAM,oBAAoB,CAAC;AAC9D,OAAO,EAAE,2BAA2B,EAAE,MAAM,uBAAuB,CAAC;AACpE,OAAO,EACL,yBAAyB,EACzB,gBAAgB,EAChB,oBAAoB,EACpB,gBAAgB,GACjB,MAAM,qBAAqB,CAAC"}
@@ -0,0 +1,38 @@
1
+ /**
2
+ * observation-lift clockwork engine.
3
+ *
4
+ * Walks the plan's `observations` array once it has reached its final
5
+ * state and creates one draft brief writ per record as a child of the
6
+ * originating brief. This turns the sage's "things we noticed but
7
+ * didn't action" output from an inert note into commissionable drafts
8
+ * visible in the same writ surfaces as any other brief — a downstream
9
+ * curator (human or automated) promotes each draft to `open` by hand
10
+ * or via writ-publish.
11
+ *
12
+ * Behavior:
13
+ * - Validates that the plan exists and its status is `completed`.
14
+ * (Placement inside each rig guarantees this — observation-lift
15
+ * runs after plan-finalize / spec-publish, which transition the
16
+ * plan to `completed`.)
17
+ * - Silently no-ops if `plan.observations` is not an array (legacy
18
+ * string-shaped plandocs) or is an empty array.
19
+ * - Otherwise, iterates the array in order and calls
20
+ * `clerk.post({ type: 'brief', title, body, codex, parentId, draft })`
21
+ * once per record. The brief writ must still be in a non-terminal
22
+ * phase at this point — in all three rigs the engine runs before
23
+ * seal, which is what finally transitions the brief to `completed`.
24
+ * - Fails fast on the first `clerk.post` error. Already-created
25
+ * drafts persist as `new`-status writs under the brief; they are
26
+ * invisible to the Spider until a curator publishes them.
27
+ * - Does not mutate the plandoc — the parentId relationship on the
28
+ * created writs is the sole audit trail.
29
+ *
30
+ * Yields:
31
+ * `{ writIds }` — the ids of the draft writs created, in the same
32
+ * order as the observation records. Empty when the engine no-ops.
33
+ */
34
+ import type { EngineDesign } from '@shardworks/fabricator-apparatus';
35
+ import type { Book } from '@shardworks/stacks-apparatus';
36
+ import type { PlanDoc } from '../types.ts';
37
+ export declare function createObservationLiftEngine(getPlansBook: () => Book<PlanDoc>): EngineDesign;
38
+ //# sourceMappingURL=observation-lift.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"observation-lift.d.ts","sourceRoot":"","sources":["../../src/engines/observation-lift.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAqC,MAAM,kCAAkC,CAAC;AACxG,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,8BAA8B,CAAC;AAEzD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAE3C,wBAAgB,2BAA2B,CAAC,YAAY,EAAE,MAAM,IAAI,CAAC,OAAO,CAAC,GAAG,YAAY,CAuD3F"}
@@ -0,0 +1,79 @@
1
+ /**
2
+ * observation-lift clockwork engine.
3
+ *
4
+ * Walks the plan's `observations` array once it has reached its final
5
+ * state and creates one draft brief writ per record as a child of the
6
+ * originating brief. This turns the sage's "things we noticed but
7
+ * didn't action" output from an inert note into commissionable drafts
8
+ * visible in the same writ surfaces as any other brief — a downstream
9
+ * curator (human or automated) promotes each draft to `open` by hand
10
+ * or via writ-publish.
11
+ *
12
+ * Behavior:
13
+ * - Validates that the plan exists and its status is `completed`.
14
+ * (Placement inside each rig guarantees this — observation-lift
15
+ * runs after plan-finalize / spec-publish, which transition the
16
+ * plan to `completed`.)
17
+ * - Silently no-ops if `plan.observations` is not an array (legacy
18
+ * string-shaped plandocs) or is an empty array.
19
+ * - Otherwise, iterates the array in order and calls
20
+ * `clerk.post({ type: 'brief', title, body, codex, parentId, draft })`
21
+ * once per record. The brief writ must still be in a non-terminal
22
+ * phase at this point — in all three rigs the engine runs before
23
+ * seal, which is what finally transitions the brief to `completed`.
24
+ * - Fails fast on the first `clerk.post` error. Already-created
25
+ * drafts persist as `new`-status writs under the brief; they are
26
+ * invisible to the Spider until a curator publishes them.
27
+ * - Does not mutate the plandoc — the parentId relationship on the
28
+ * created writs is the sole audit trail.
29
+ *
30
+ * Yields:
31
+ * `{ writIds }` — the ids of the draft writs created, in the same
32
+ * order as the observation records. Empty when the engine no-ops.
33
+ */
34
+ import { guild } from '@shardworks/nexus-core';
35
+ export function createObservationLiftEngine(getPlansBook) {
36
+ return {
37
+ id: 'astrolabe.observation-lift',
38
+ async run(givens, _context) {
39
+ const planId = givens.planId;
40
+ const book = getPlansBook();
41
+ const plan = await book.get(planId);
42
+ if (!plan) {
43
+ throw new Error(`Plan "${planId}" not found.`);
44
+ }
45
+ if (plan.status !== 'completed') {
46
+ throw new Error(`observation-lift: expected plan status "completed" but got "${plan.status}" for plan "${planId}".`);
47
+ }
48
+ const observations = plan.observations;
49
+ if (!Array.isArray(observations) || observations.length === 0) {
50
+ // Legacy string-shaped plandocs or empty arrays: no-op.
51
+ return {
52
+ status: 'completed',
53
+ yields: { writIds: [] },
54
+ };
55
+ }
56
+ const clerk = guild().apparatus('clerk');
57
+ const writIds = [];
58
+ for (const observation of observations) {
59
+ // Fail-fast: any clerk.post error propagates immediately.
60
+ // Previously-created drafts persist (invisible to Spider) and
61
+ // a curator can reconcile manually — rollback is not attempted.
62
+ const writ = await clerk.post({
63
+ type: 'brief',
64
+ title: observation.title,
65
+ body: observation.body,
66
+ codex: plan.codex,
67
+ parentId: planId,
68
+ draft: true,
69
+ });
70
+ writIds.push(writ.id);
71
+ }
72
+ return {
73
+ status: 'completed',
74
+ yields: { writIds },
75
+ };
76
+ },
77
+ };
78
+ }
79
+ //# sourceMappingURL=observation-lift.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"observation-lift.js","sourceRoot":"","sources":["../../src/engines/observation-lift.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAEH,OAAO,EAAE,KAAK,EAAE,MAAM,wBAAwB,CAAC;AAM/C,MAAM,UAAU,2BAA2B,CAAC,YAAiC;IAC3E,OAAO;QACL,EAAE,EAAE,4BAA4B;QAEhC,KAAK,CAAC,GAAG,CACP,MAA+B,EAC/B,QAA0B;YAE1B,MAAM,MAAM,GAAG,MAAM,CAAC,MAAgB,CAAC;YACvC,MAAM,IAAI,GAAG,YAAY,EAAE,CAAC;YAE5B,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YACpC,IAAI,CAAC,IAAI,EAAE,CAAC;gBACV,MAAM,IAAI,KAAK,CAAC,SAAS,MAAM,cAAc,CAAC,CAAC;YACjD,CAAC;YAED,IAAI,IAAI,CAAC,MAAM,KAAK,WAAW,EAAE,CAAC;gBAChC,MAAM,IAAI,KAAK,CACb,+DAA+D,IAAI,CAAC,MAAM,eAAe,MAAM,IAAI,CACpG,CAAC;YACJ,CAAC;YAED,MAAM,YAAY,GAAG,IAAI,CAAC,YAAY,CAAC;YACvC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,YAAY,CAAC,IAAI,YAAY,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAC9D,wDAAwD;gBACxD,OAAO;oBACL,MAAM,EAAE,WAAW;oBACnB,MAAM,EAAE,EAAE,OAAO,EAAE,EAAc,EAAE;iBACpC,CAAC;YACJ,CAAC;YAED,MAAM,KAAK,GAAG,KAAK,EAAE,CAAC,SAAS,CAAW,OAAO,CAAC,CAAC;YACnD,MAAM,OAAO,GAAa,EAAE,CAAC;YAE7B,KAAK,MAAM,WAAW,IAAI,YAAY,EAAE,CAAC;gBACvC,0DAA0D;gBAC1D,8DAA8D;gBAC9D,gEAAgE;gBAChE,MAAM,IAAI,GAAG,MAAM,KAAK,CAAC,IAAI,CAAC;oBAC5B,IAAI,EAAE,OAAO;oBACb,KAAK,EAAE,WAAW,CAAC,KAAK;oBACxB,IAAI,EAAE,WAAW,CAAC,IAAI;oBACtB,KAAK,EAAE,IAAI,CAAC,KAAK;oBACjB,QAAQ,EAAE,MAAM;oBAChB,KAAK,EAAE,IAAI;iBACZ,CAAC,CAAC;gBACH,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACxB,CAAC;YAED,OAAO;gBACL,MAAM,EAAE,WAAW;gBACnB,MAAM,EAAE,EAAE,OAAO,EAAE;aACpB,CAAC;QACJ,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -10,7 +10,14 @@
10
10
  *
11
11
  * Stages: plan-init → draft → reader-analyst → inventory-check →
12
12
  * patron-anima → decision-review → spec-writer → plan-finalize →
13
- * implement → review → revise → seal.
13
+ * observation-lift → implement → review → revise → seal.
14
+ *
15
+ * The `observation-lift` engine runs after `plan-finalize` has transitioned
16
+ * the plan to `completed` but while the brief writ itself is still `open`.
17
+ * It lifts each record in `plan.observations` into a draft child writ under
18
+ * the brief, so a curator (human or overseer) can promote it later. The
19
+ * engine internally no-ops on empty or legacy-string observations, so it is
20
+ * wired unconditionally (no `when:` guard).
14
21
  *
15
22
  * The `reader-analyst` slot uses the astrolabe-owned
16
23
  * `astrolabe.reader-analyst` engine, which selects the primer role at
@@ -1 +1 @@
1
- {"version":3,"file":"plan-and-ship.d.ts","sourceRoot":"","sources":["../src/plan-and-ship.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAEhE,eAAO,MAAM,sBAAsB,EAAE,WAsGpC,CAAC"}
1
+ {"version":3,"file":"plan-and-ship.d.ts","sourceRoot":"","sources":["../src/plan-and-ship.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAEhE,eAAO,MAAM,sBAAsB,EAAE,WA4GpC,CAAC"}
@@ -10,7 +10,14 @@
10
10
  *
11
11
  * Stages: plan-init → draft → reader-analyst → inventory-check →
12
12
  * patron-anima → decision-review → spec-writer → plan-finalize →
13
- * implement → review → revise → seal.
13
+ * observation-lift → implement → review → revise → seal.
14
+ *
15
+ * The `observation-lift` engine runs after `plan-finalize` has transitioned
16
+ * the plan to `completed` but while the brief writ itself is still `open`.
17
+ * It lifts each record in `plan.observations` into a draft child writ under
18
+ * the brief, so a curator (human or overseer) can promote it later. The
19
+ * engine internally no-ops on empty or legacy-string observations, so it is
20
+ * wired unconditionally (no `when:` guard).
14
21
  *
15
22
  * The `reader-analyst` slot uses the astrolabe-owned
16
23
  * `astrolabe.reader-analyst` engine, which selects the primer role at
@@ -101,10 +108,16 @@ export const planAndShipRigTemplate = {
101
108
  upstream: ['spec-writer'],
102
109
  givens: { planId: '${yields.plan-init.planId}' },
103
110
  },
111
+ {
112
+ id: 'observation-lift',
113
+ designId: 'astrolabe.observation-lift',
114
+ upstream: ['plan-finalize'],
115
+ givens: { planId: '${yields.plan-init.planId}' },
116
+ },
104
117
  {
105
118
  id: 'implement',
106
119
  designId: 'implement',
107
- upstream: ['plan-finalize'],
120
+ upstream: ['observation-lift'],
108
121
  givens: {
109
122
  writ: '${writ}',
110
123
  role: '${vars.role}',
@@ -1 +1 @@
1
- {"version":3,"file":"plan-and-ship.js","sourceRoot":"","sources":["../src/plan-and-ship.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"plan-and-ship.js","sourceRoot":"","sources":["../src/plan-and-ship.ts"],"names":[],"mappings":"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"}
@@ -7,7 +7,14 @@
7
7
  * backward compatibility with downstream yield references even though
8
8
  * the role it summons is now `sage-primer-scoping`.
9
9
  * Stages: plan-init → draft → reader → inventory-check → analyst →
10
- * decision-review → spec-writer → spec-publish → seal.
10
+ * decision-review → spec-writer → spec-publish → observation-lift → seal.
11
+ *
12
+ * The `observation-lift` engine runs after `spec-publish` transitions the
13
+ * plan to `completed` but while the brief writ is still `open` (seal is
14
+ * what transitions the brief). It lifts each record in `plan.observations`
15
+ * into a draft child writ under the brief. The engine internally no-ops on
16
+ * empty or legacy-string observations, so it is wired unconditionally (no
17
+ * `when:` guard).
11
18
  */
12
19
  import type { RigTemplate } from '@shardworks/spider-apparatus';
13
20
  export declare const threePhaseRigTemplate: RigTemplate;
@@ -1 +1 @@
1
- {"version":3,"file":"three-phase-planning.d.ts","sourceRoot":"","sources":["../src/three-phase-planning.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAEhE,eAAO,MAAM,qBAAqB,EAAE,WA8EnC,CAAC"}
1
+ {"version":3,"file":"three-phase-planning.d.ts","sourceRoot":"","sources":["../src/three-phase-planning.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAEhE,eAAO,MAAM,qBAAqB,EAAE,WAoFnC,CAAC"}
@@ -7,7 +7,14 @@
7
7
  * backward compatibility with downstream yield references even though
8
8
  * the role it summons is now `sage-primer-scoping`.
9
9
  * Stages: plan-init → draft → reader → inventory-check → analyst →
10
- * decision-review → spec-writer → spec-publish → seal.
10
+ * decision-review → spec-writer → spec-publish → observation-lift → seal.
11
+ *
12
+ * The `observation-lift` engine runs after `spec-publish` transitions the
13
+ * plan to `completed` but while the brief writ is still `open` (seal is
14
+ * what transitions the brief). It lifts each record in `plan.observations`
15
+ * into a draft child writ under the brief. The engine internally no-ops on
16
+ * empty or legacy-string observations, so it is wired unconditionally (no
17
+ * `when:` guard).
11
18
  */
12
19
  export const threePhaseRigTemplate = {
13
20
  engines: [
@@ -78,10 +85,16 @@ export const threePhaseRigTemplate = {
78
85
  upstream: ['spec-writer'],
79
86
  givens: { planId: '${yields.plan-init.planId}' },
80
87
  },
88
+ {
89
+ id: 'observation-lift',
90
+ designId: 'astrolabe.observation-lift',
91
+ upstream: ['spec-publish'],
92
+ givens: { planId: '${yields.plan-init.planId}' },
93
+ },
81
94
  {
82
95
  id: 'seal',
83
96
  designId: 'seal',
84
- upstream: ['spec-publish'],
97
+ upstream: ['observation-lift'],
85
98
  givens: { abandon: true },
86
99
  },
87
100
  ],
@@ -1 +1 @@
1
- {"version":3,"file":"three-phase-planning.js","sourceRoot":"","sources":["../src/three-phase-planning.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAIH,MAAM,CAAC,MAAM,qBAAqB,GAAgB;IAChD,OAAO,EAAE;QACP;YACE,EAAE,EAAE,WAAW;YACf,QAAQ,EAAE,qBAAqB;YAC/B,QAAQ,EAAE,EAAE;YACZ,MAAM,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE;SAC5B;QACD;YACE,EAAE,EAAE,OAAO;YACX,QAAQ,EAAE,OAAO;YACjB,QAAQ,EAAE,CAAC,WAAW,CAAC;YACvB,MAAM,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE;SAC5B;QACD;YACE,EAAE,EAAE,QAAQ;YACZ,QAAQ,EAAE,eAAe;YACzB,QAAQ,EAAE,CAAC,OAAO,CAAC;YACnB,MAAM,EAAE;gBACN,IAAI,EAAE,8BAA8B;gBACpC,MAAM,EAAE,qCAAqC;gBAC7C,GAAG,EAAE,sBAAsB;gBAC3B,IAAI,EAAE,SAAS;gBACf,QAAQ,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE;aACjC;SACF;QACD;YACE,EAAE,EAAE,iBAAiB;YACrB,QAAQ,EAAE,2BAA2B;YACrC,QAAQ,EAAE,CAAC,QAAQ,CAAC;YACpB,MAAM,EAAE,EAAE,MAAM,EAAE,4BAA4B,EAAE;SACjD;QACD;YACE,EAAE,EAAE,SAAS;YACb,QAAQ,EAAE,eAAe;YACzB,QAAQ,EAAE,CAAC,iBAAiB,CAAC;YAC7B,MAAM,EAAE;gBACN,IAAI,EAAE,+BAA+B;gBACrC,MAAM,EAAE,qCAAqC;gBAC7C,GAAG,EAAE,sBAAsB;gBAC3B,IAAI,EAAE,SAAS;gBACf,QAAQ,EAAE,EAAE,QAAQ,EAAE,SAAS,EAAE;aAClC;SACF;QACD;YACE,EAAE,EAAE,iBAAiB;YACrB,QAAQ,EAAE,2BAA2B;YACrC,QAAQ,EAAE,CAAC,SAAS,CAAC;YACrB,MAAM,EAAE,EAAE,MAAM,EAAE,4BAA4B,EAAE;SACjD;QACD;YACE,EAAE,EAAE,aAAa;YACjB,QAAQ,EAAE,eAAe;YACzB,QAAQ,EAAE,CAAC,iBAAiB,CAAC;YAC7B,MAAM,EAAE;gBACN,IAAI,EAAE,uBAAuB;gBAC7B,MAAM,EACJ,yCAAyC;oBACzC,8DAA8D;gBAChE,GAAG,EAAE,sBAAsB;gBAC3B,IAAI,EAAE,SAAS;gBACf,QAAQ,EAAE,EAAE,QAAQ,EAAE,aAAa,EAAE;aACtC;SACF;QACD;YACE,EAAE,EAAE,cAAc;YAClB,QAAQ,EAAE,wBAAwB;YAClC,QAAQ,EAAE,CAAC,aAAa,CAAC;YACzB,MAAM,EAAE,EAAE,MAAM,EAAE,4BAA4B,EAAE;SACjD;QACD;YACE,EAAE,EAAE,MAAM;YACV,QAAQ,EAAE,MAAM;YAChB,QAAQ,EAAE,CAAC,cAAc,CAAC;YAC1B,MAAM,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE;SAC1B;KACF;IACD,gBAAgB,EAAE,aAAa;CAChC,CAAC"}
1
+ {"version":3,"file":"three-phase-planning.js","sourceRoot":"","sources":["../src/three-phase-planning.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAIH,MAAM,CAAC,MAAM,qBAAqB,GAAgB;IAChD,OAAO,EAAE;QACP;YACE,EAAE,EAAE,WAAW;YACf,QAAQ,EAAE,qBAAqB;YAC/B,QAAQ,EAAE,EAAE;YACZ,MAAM,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE;SAC5B;QACD;YACE,EAAE,EAAE,OAAO;YACX,QAAQ,EAAE,OAAO;YACjB,QAAQ,EAAE,CAAC,WAAW,CAAC;YACvB,MAAM,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE;SAC5B;QACD;YACE,EAAE,EAAE,QAAQ;YACZ,QAAQ,EAAE,eAAe;YACzB,QAAQ,EAAE,CAAC,OAAO,CAAC;YACnB,MAAM,EAAE;gBACN,IAAI,EAAE,8BAA8B;gBACpC,MAAM,EAAE,qCAAqC;gBAC7C,GAAG,EAAE,sBAAsB;gBAC3B,IAAI,EAAE,SAAS;gBACf,QAAQ,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE;aACjC;SACF;QACD;YACE,EAAE,EAAE,iBAAiB;YACrB,QAAQ,EAAE,2BAA2B;YACrC,QAAQ,EAAE,CAAC,QAAQ,CAAC;YACpB,MAAM,EAAE,EAAE,MAAM,EAAE,4BAA4B,EAAE;SACjD;QACD;YACE,EAAE,EAAE,SAAS;YACb,QAAQ,EAAE,eAAe;YACzB,QAAQ,EAAE,CAAC,iBAAiB,CAAC;YAC7B,MAAM,EAAE;gBACN,IAAI,EAAE,+BAA+B;gBACrC,MAAM,EAAE,qCAAqC;gBAC7C,GAAG,EAAE,sBAAsB;gBAC3B,IAAI,EAAE,SAAS;gBACf,QAAQ,EAAE,EAAE,QAAQ,EAAE,SAAS,EAAE;aAClC;SACF;QACD;YACE,EAAE,EAAE,iBAAiB;YACrB,QAAQ,EAAE,2BAA2B;YACrC,QAAQ,EAAE,CAAC,SAAS,CAAC;YACrB,MAAM,EAAE,EAAE,MAAM,EAAE,4BAA4B,EAAE;SACjD;QACD;YACE,EAAE,EAAE,aAAa;YACjB,QAAQ,EAAE,eAAe;YACzB,QAAQ,EAAE,CAAC,iBAAiB,CAAC;YAC7B,MAAM,EAAE;gBACN,IAAI,EAAE,uBAAuB;gBAC7B,MAAM,EACJ,yCAAyC;oBACzC,8DAA8D;gBAChE,GAAG,EAAE,sBAAsB;gBAC3B,IAAI,EAAE,SAAS;gBACf,QAAQ,EAAE,EAAE,QAAQ,EAAE,aAAa,EAAE;aACtC;SACF;QACD;YACE,EAAE,EAAE,cAAc;YAClB,QAAQ,EAAE,wBAAwB;YAClC,QAAQ,EAAE,CAAC,aAAa,CAAC;YACzB,MAAM,EAAE,EAAE,MAAM,EAAE,4BAA4B,EAAE;SACjD;QACD;YACE,EAAE,EAAE,kBAAkB;YACtB,QAAQ,EAAE,4BAA4B;YACtC,QAAQ,EAAE,CAAC,cAAc,CAAC;YAC1B,MAAM,EAAE,EAAE,MAAM,EAAE,4BAA4B,EAAE;SACjD;QACD;YACE,EAAE,EAAE,MAAM;YACV,QAAQ,EAAE,MAAM;YAChB,QAAQ,EAAE,CAAC,kBAAkB,CAAC;YAC9B,MAAM,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE;SAC1B;KACF;IACD,gBAAgB,EAAE,aAAa;CAChC,CAAC"}
@@ -9,7 +9,14 @@
9
9
  * `sage-primer-solo` otherwise. One pass produces inventory, scope,
10
10
  * decisions, and observations. Stages: plan-init → draft →
11
11
  * reader-analyst → inventory-check → decision-review → spec-writer →
12
- * spec-publish → seal.
12
+ * spec-publish → observation-lift → seal.
13
+ *
14
+ * The `observation-lift` engine runs after `spec-publish` transitions the
15
+ * plan to `completed` but while the brief writ is still `open` (seal is
16
+ * what transitions the brief). It lifts each record in `plan.observations`
17
+ * into a draft child writ under the brief. The engine internally no-ops on
18
+ * empty or legacy-string observations, so it is wired unconditionally (no
19
+ * `when:` guard).
13
20
  */
14
21
  import type { RigTemplate } from '@shardworks/spider-apparatus';
15
22
  export declare const twoPhaseRigTemplate: RigTemplate;
@@ -1 +1 @@
1
- {"version":3,"file":"two-phase-planning.d.ts","sourceRoot":"","sources":["../src/two-phase-planning.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAEhE,eAAO,MAAM,mBAAmB,EAAE,WAiEjC,CAAC"}
1
+ {"version":3,"file":"two-phase-planning.d.ts","sourceRoot":"","sources":["../src/two-phase-planning.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAEhE,eAAO,MAAM,mBAAmB,EAAE,WAuEjC,CAAC"}
@@ -9,7 +9,14 @@
9
9
  * `sage-primer-solo` otherwise. One pass produces inventory, scope,
10
10
  * decisions, and observations. Stages: plan-init → draft →
11
11
  * reader-analyst → inventory-check → decision-review → spec-writer →
12
- * spec-publish → seal.
12
+ * spec-publish → observation-lift → seal.
13
+ *
14
+ * The `observation-lift` engine runs after `spec-publish` transitions the
15
+ * plan to `completed` but while the brief writ is still `open` (seal is
16
+ * what transitions the brief). It lifts each record in `plan.observations`
17
+ * into a draft child writ under the brief. The engine internally no-ops on
18
+ * empty or legacy-string observations, so it is wired unconditionally (no
19
+ * `when:` guard).
13
20
  */
14
21
  export const twoPhaseRigTemplate = {
15
22
  engines: [
@@ -67,10 +74,16 @@ export const twoPhaseRigTemplate = {
67
74
  upstream: ['spec-writer'],
68
75
  givens: { planId: '${yields.plan-init.planId}' },
69
76
  },
77
+ {
78
+ id: 'observation-lift',
79
+ designId: 'astrolabe.observation-lift',
80
+ upstream: ['spec-publish'],
81
+ givens: { planId: '${yields.plan-init.planId}' },
82
+ },
70
83
  {
71
84
  id: 'seal',
72
85
  designId: 'seal',
73
- upstream: ['spec-publish'],
86
+ upstream: ['observation-lift'],
74
87
  givens: { abandon: true },
75
88
  },
76
89
  ],
@@ -1 +1 @@
1
- {"version":3,"file":"two-phase-planning.js","sourceRoot":"","sources":["../src/two-phase-planning.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAIH,MAAM,CAAC,MAAM,mBAAmB,GAAgB;IAC9C,OAAO,EAAE;QACP;YACE,EAAE,EAAE,WAAW;YACf,QAAQ,EAAE,qBAAqB;YAC/B,QAAQ,EAAE,EAAE;YACZ,MAAM,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE;SAC5B;QACD;YACE,EAAE,EAAE,OAAO;YACX,QAAQ,EAAE,OAAO;YACjB,QAAQ,EAAE,CAAC,WAAW,CAAC;YACvB,MAAM,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE;SAC5B;QACD;YACE,EAAE,EAAE,gBAAgB;YACpB,QAAQ,EAAE,0BAA0B;YACpC,QAAQ,EAAE,CAAC,OAAO,CAAC;YACnB,MAAM,EAAE;gBACN,MAAM,EAAE,qCAAqC;gBAC7C,GAAG,EAAE,sBAAsB;gBAC3B,IAAI,EAAE,SAAS;gBACf,QAAQ,EAAE,EAAE,QAAQ,EAAE,gBAAgB,EAAE;aACzC;SACF;QACD;YACE,EAAE,EAAE,iBAAiB;YACrB,QAAQ,EAAE,2BAA2B;YACrC,QAAQ,EAAE,CAAC,gBAAgB,CAAC;YAC5B,MAAM,EAAE,EAAE,MAAM,EAAE,4BAA4B,EAAE;SACjD;QACD;YACE,EAAE,EAAE,iBAAiB;YACrB,QAAQ,EAAE,2BAA2B;YACrC,QAAQ,EAAE,CAAC,iBAAiB,CAAC;YAC7B,MAAM,EAAE,EAAE,MAAM,EAAE,4BAA4B,EAAE;SACjD;QACD;YACE,EAAE,EAAE,aAAa;YACjB,QAAQ,EAAE,eAAe;YACzB,QAAQ,EAAE,CAAC,iBAAiB,CAAC;YAC7B,MAAM,EAAE;gBACN,IAAI,EAAE,uBAAuB;gBAC7B,MAAM,EACJ,yCAAyC;oBACzC,8DAA8D;gBAChE,GAAG,EAAE,sBAAsB;gBAC3B,IAAI,EAAE,SAAS;gBACf,QAAQ,EAAE,EAAE,QAAQ,EAAE,aAAa,EAAE;aACtC;SACF;QACD;YACE,EAAE,EAAE,cAAc;YAClB,QAAQ,EAAE,wBAAwB;YAClC,QAAQ,EAAE,CAAC,aAAa,CAAC;YACzB,MAAM,EAAE,EAAE,MAAM,EAAE,4BAA4B,EAAE;SACjD;QACD;YACE,EAAE,EAAE,MAAM;YACV,QAAQ,EAAE,MAAM;YAChB,QAAQ,EAAE,CAAC,cAAc,CAAC;YAC1B,MAAM,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE;SAC1B;KACF;IACD,gBAAgB,EAAE,aAAa;CAChC,CAAC"}
1
+ {"version":3,"file":"two-phase-planning.js","sourceRoot":"","sources":["../src/two-phase-planning.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAIH,MAAM,CAAC,MAAM,mBAAmB,GAAgB;IAC9C,OAAO,EAAE;QACP;YACE,EAAE,EAAE,WAAW;YACf,QAAQ,EAAE,qBAAqB;YAC/B,QAAQ,EAAE,EAAE;YACZ,MAAM,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE;SAC5B;QACD;YACE,EAAE,EAAE,OAAO;YACX,QAAQ,EAAE,OAAO;YACjB,QAAQ,EAAE,CAAC,WAAW,CAAC;YACvB,MAAM,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE;SAC5B;QACD;YACE,EAAE,EAAE,gBAAgB;YACpB,QAAQ,EAAE,0BAA0B;YACpC,QAAQ,EAAE,CAAC,OAAO,CAAC;YACnB,MAAM,EAAE;gBACN,MAAM,EAAE,qCAAqC;gBAC7C,GAAG,EAAE,sBAAsB;gBAC3B,IAAI,EAAE,SAAS;gBACf,QAAQ,EAAE,EAAE,QAAQ,EAAE,gBAAgB,EAAE;aACzC;SACF;QACD;YACE,EAAE,EAAE,iBAAiB;YACrB,QAAQ,EAAE,2BAA2B;YACrC,QAAQ,EAAE,CAAC,gBAAgB,CAAC;YAC5B,MAAM,EAAE,EAAE,MAAM,EAAE,4BAA4B,EAAE;SACjD;QACD;YACE,EAAE,EAAE,iBAAiB;YACrB,QAAQ,EAAE,2BAA2B;YACrC,QAAQ,EAAE,CAAC,iBAAiB,CAAC;YAC7B,MAAM,EAAE,EAAE,MAAM,EAAE,4BAA4B,EAAE;SACjD;QACD;YACE,EAAE,EAAE,aAAa;YACjB,QAAQ,EAAE,eAAe;YACzB,QAAQ,EAAE,CAAC,iBAAiB,CAAC;YAC7B,MAAM,EAAE;gBACN,IAAI,EAAE,uBAAuB;gBAC7B,MAAM,EACJ,yCAAyC;oBACzC,8DAA8D;gBAChE,GAAG,EAAE,sBAAsB;gBAC3B,IAAI,EAAE,SAAS;gBACf,QAAQ,EAAE,EAAE,QAAQ,EAAE,aAAa,EAAE;aACtC;SACF;QACD;YACE,EAAE,EAAE,cAAc;YAClB,QAAQ,EAAE,wBAAwB;YAClC,QAAQ,EAAE,CAAC,aAAa,CAAC;YACzB,MAAM,EAAE,EAAE,MAAM,EAAE,4BAA4B,EAAE;SACjD;QACD;YACE,EAAE,EAAE,kBAAkB;YACtB,QAAQ,EAAE,4BAA4B;YACtC,QAAQ,EAAE,CAAC,cAAc,CAAC;YAC1B,MAAM,EAAE,EAAE,MAAM,EAAE,4BAA4B,EAAE;SACjD;QACD;YACE,EAAE,EAAE,MAAM;YACV,QAAQ,EAAE,MAAM;YAChB,QAAQ,EAAE,CAAC,kBAAkB,CAAC;YAC9B,MAAM,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE;SAC1B;KACF;IACD,gBAAgB,EAAE,aAAa;CAChC,CAAC"}
package/dist/types.d.ts CHANGED
@@ -15,8 +15,15 @@ export interface PlanDoc {
15
15
  status: PlanStatus;
16
16
  /** Codebase inventory: affected files, types, interfaces, patterns. */
17
17
  inventory?: string;
18
- /** Primer observations: refactoring opportunities, risks, conventions. */
19
- observations?: string;
18
+ /**
19
+ * Primer observations: refactoring opportunities, risks, conventions.
20
+ *
21
+ * Each entry is an atomic, commissionable concern — the
22
+ * `astrolabe.observation-lift` engine lifts each record into a
23
+ * draft child writ under the originating brief so a curator
24
+ * (human or automated) can promote it to open status.
25
+ */
26
+ observations?: Observation[];
20
27
  /** Scope items: what's in and what's out. */
21
28
  scope?: ScopeItem[];
22
29
  /** Architectural/design decisions with options. */
@@ -34,6 +41,28 @@ export interface ScopeItem {
34
41
  rationale: string;
35
42
  included: boolean;
36
43
  }
44
+ /**
45
+ * A single observation recorded by a sage during the planning pass.
46
+ *
47
+ * Each observation names one concern — a refactoring opportunity,
48
+ * risk, convention drift, or bug — that the sage noticed but that
49
+ * is outside the brief's scope. Observations flow downstream into
50
+ * the `astrolabe.observation-lift` engine, which creates one draft
51
+ * brief writ per record as a child of the originating brief.
52
+ *
53
+ * Fields are deliberately minimal (D1 in the commission spec):
54
+ * - `id` — plandoc-local identifier assigned by the sage (e.g. `obs-1`).
55
+ * - `title` — one-line commission-title style (imperative or noun
56
+ * phrase, ~10 words, no trailing punctuation). Becomes the title of
57
+ * the lifted draft writ.
58
+ * - `body` — tactical detail (file paths, symbols, preconditions)
59
+ * rendered as markdown. Becomes the body of the lifted draft writ.
60
+ */
61
+ export interface Observation {
62
+ id: string;
63
+ title: string;
64
+ body: string;
65
+ }
37
66
  export interface Decision {
38
67
  id: string;
39
68
  scope: string[];
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,MAAM,MAAM,UAAU,GAAG,SAAS,GAAG,WAAW,GAAG,WAAW,GAAG,SAAS,GAAG,WAAW,GAAG,QAAQ,CAAC;AAIpG,MAAM,WAAW,OAAO;IACtB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;IACvB,uCAAuC;IACvC,EAAE,EAAE,MAAM,CAAC;IACX,mCAAmC;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,uBAAuB;IACvB,MAAM,EAAE,UAAU,CAAC;IAGnB,uEAAuE;IACvE,SAAS,CAAC,EAAE,MAAM,CAAC;IAGnB,0EAA0E;IAC1E,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,6CAA6C;IAC7C,KAAK,CAAC,EAAE,SAAS,EAAE,CAAC;IACpB,mDAAmD;IACnD,SAAS,CAAC,EAAE,QAAQ,EAAE,CAAC;IAGvB,mCAAmC;IACnC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,4CAA4C;IAC5C,eAAe,CAAC,EAAE,MAAM,CAAC;IAEzB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;;;;OAKG;IACH,MAAM,CAAC,EAAE,cAAc,CAAC;CACzB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,SAAS,GAAG,UAAU,GAAG,SAAS,CAAC;IAC5C,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,KAAK,GAAG,KAAK,GAAG,MAAM,CAAC;IACnC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAID,MAAM,WAAW,WAAW;IAC1B,wBAAwB;IACxB,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,4BAA4B;IAC5B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,+CAA+C;IAC/C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,iCAAiC;IACjC,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAID,MAAM,WAAW,eAAe;IAC9B;;;;;;;OAOG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,OAAO,QAAQ,wBAAwB,CAAC;IACtC,UAAU,WAAW;QACnB,SAAS,CAAC,EAAE,eAAe,CAAC;KAC7B;CACF;AAID,MAAM,WAAW,YAAY;IAC3B,8CAA8C;IAC9C,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACvC,yEAAyE;IACzE,IAAI,CAAC,OAAO,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;IAChD,kFAAkF;IAClF,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CAC/E"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.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.241",
3
+ "version": "0.1.242",
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/stacks-apparatus": "0.1.241",
24
- "@shardworks/tools-apparatus": "0.1.241",
25
- "@shardworks/spider-apparatus": "0.1.241",
26
- "@shardworks/clerk-apparatus": "0.1.241",
27
- "@shardworks/fabricator-apparatus": "0.1.241",
28
- "@shardworks/loom-apparatus": "0.1.241",
29
- "@shardworks/animator-apparatus": "0.1.241"
23
+ "@shardworks/stacks-apparatus": "0.1.242",
24
+ "@shardworks/tools-apparatus": "0.1.242",
25
+ "@shardworks/clerk-apparatus": "0.1.242",
26
+ "@shardworks/spider-apparatus": "0.1.242",
27
+ "@shardworks/fabricator-apparatus": "0.1.242",
28
+ "@shardworks/loom-apparatus": "0.1.242",
29
+ "@shardworks/animator-apparatus": "0.1.242"
30
30
  },
31
31
  "devDependencies": {
32
32
  "@types/node": "25.5.0",
33
- "@shardworks/nexus-core": "0.1.241"
33
+ "@shardworks/nexus-core": "0.1.242"
34
34
  },
35
35
  "files": [
36
36
  "dist",
@@ -476,7 +476,7 @@
476
476
  tabContent.innerHTML = renderMarkdown(currentPlan.inventory);
477
477
  break;
478
478
  case 'observations':
479
- tabContent.innerHTML = renderMarkdown(currentPlan.observations);
479
+ tabContent.innerHTML = renderObservations(currentPlan.observations);
480
480
  break;
481
481
  case 'spec':
482
482
  tabContent.innerHTML = renderMarkdown(currentPlan.spec);
@@ -512,6 +512,27 @@
512
512
  return html;
513
513
  }
514
514
 
515
+ // ── Observations Card List ─────────────────────────────────────────────
516
+
517
+ function renderObservations(observations) {
518
+ if (!Array.isArray(observations) || observations.length === 0) {
519
+ return '<p class="empty-state">No observations.</p>';
520
+ }
521
+ var html = '<div class="observation-list">';
522
+ for (var i = 0; i < observations.length; i++) {
523
+ var o = observations[i];
524
+ html += '<section class="observation-card">' +
525
+ '<header class="observation-head">' +
526
+ '<code class="observation-id">' + esc(o.id) + '</code>' +
527
+ '<h3 class="observation-title">' + esc(o.title) + '</h3>' +
528
+ '</header>' +
529
+ '<div class="observation-body">' + renderMarkdown(o.body) + '</div>' +
530
+ '</section>';
531
+ }
532
+ html += '</div>';
533
+ return html;
534
+ }
535
+
515
536
  // ── Decisions Table ────────────────────────────────────────────────────
516
537
 
517
538
  function renderDecisionsTable(decisions) {
@@ -3,7 +3,8 @@
3
3
  *
4
4
  * Since astrolabe.js is a browser IIFE, we extract and test the pure
5
5
  * functions (esc, formatDate, statusBadge, renderMarkdown, renderScopeTable,
6
- * renderDecisionsTable) by re-defining them here in an identical manner.
6
+ * renderDecisionsTable, renderObservations) by re-defining them here in an
7
+ * identical manner.
7
8
  *
8
9
  * This validates the rendering logic without requiring a browser environment.
9
10
  */
@@ -169,6 +170,25 @@ function renderDecisionsTable(decisions) {
169
170
  return html;
170
171
  }
171
172
 
173
+ function renderObservations(observations) {
174
+ if (!Array.isArray(observations) || observations.length === 0) {
175
+ return '<p class="empty-state">No observations.</p>';
176
+ }
177
+ var html = '<div class="observation-list">';
178
+ for (var i = 0; i < observations.length; i++) {
179
+ var o = observations[i];
180
+ html += '<section class="observation-card">' +
181
+ '<header class="observation-head">' +
182
+ '<code class="observation-id">' + esc(o.id) + '</code>' +
183
+ '<h3 class="observation-title">' + esc(o.title) + '</h3>' +
184
+ '</header>' +
185
+ '<div class="observation-body">' + renderMarkdown(o.body) + '</div>' +
186
+ '</section>';
187
+ }
188
+ html += '</div>';
189
+ return html;
190
+ }
191
+
172
192
  // ── Tests ────────────────────────────────────────────────────────────
173
193
 
174
194
  describe('esc()', () => {
@@ -429,6 +449,108 @@ describe('renderDecisionsTable()', () => {
429
449
  });
430
450
  });
431
451
 
452
+ describe('renderObservations()', () => {
453
+ it('returns empty state for null', () => {
454
+ assert.ok(renderObservations(null).includes('No observations'));
455
+ });
456
+
457
+ it('returns empty state for undefined', () => {
458
+ assert.ok(renderObservations(undefined).includes('No observations'));
459
+ });
460
+
461
+ it('returns empty state for empty array', () => {
462
+ assert.ok(renderObservations([]).includes('No observations'));
463
+ });
464
+
465
+ it('returns empty state for non-array input (legacy string payload)', () => {
466
+ // Defensive: the new contract is array-only, but a legacy plandoc
467
+ // might still carry a prose string. Render as empty rather than
468
+ // crashing with a .length access on a string or concatenating junk.
469
+ var html = renderObservations('## Risks\n- Something');
470
+ assert.ok(html.includes('No observations'));
471
+ assert.ok(!html.includes('Risks'));
472
+ });
473
+
474
+ it('renders a single observation as a card with id, title, and markdown body', () => {
475
+ var observations = [
476
+ {
477
+ id: 'obs-1',
478
+ title: 'Replace deprecated helper in src/foo.ts',
479
+ body: '`renderLegacy` in `src/foo.ts` is superseded by `renderCard`.',
480
+ },
481
+ ];
482
+ var html = renderObservations(observations);
483
+ assert.ok(html.includes('observation-list'));
484
+ assert.ok(html.includes('observation-card'));
485
+ assert.ok(html.includes('obs-1'));
486
+ assert.ok(html.includes('Replace deprecated helper in src/foo.ts'));
487
+ // Body goes through renderMarkdown, which wraps text in md-content
488
+ assert.ok(html.includes('md-content'));
489
+ // Inline code from the body's markdown made it through
490
+ assert.ok(html.includes('<code>renderLegacy</code>'));
491
+ });
492
+
493
+ it('renders many observations as distinct cards in order', () => {
494
+ var observations = [
495
+ { id: 'obs-1', title: 'First concern', body: 'Body one' },
496
+ { id: 'obs-2', title: 'Second concern', body: 'Body two' },
497
+ { id: 'obs-3', title: 'Third concern', body: 'Body three' },
498
+ ];
499
+ var html = renderObservations(observations);
500
+ var cardCount = (html.match(/observation-card/g) || []).length;
501
+ assert.equal(cardCount, 3);
502
+ assert.ok(html.includes('obs-1'));
503
+ assert.ok(html.includes('obs-2'));
504
+ assert.ok(html.includes('obs-3'));
505
+ assert.ok(html.indexOf('First concern') < html.indexOf('Second concern'));
506
+ assert.ok(html.indexOf('Second concern') < html.indexOf('Third concern'));
507
+ });
508
+
509
+ it('escapes HTML in observation id and title fields', () => {
510
+ var observations = [
511
+ { id: '<xss-id>', title: '<b>sneaky</b>', body: 'safe body' },
512
+ ];
513
+ var html = renderObservations(observations);
514
+ assert.ok(html.includes('&lt;xss-id&gt;'));
515
+ assert.ok(html.includes('&lt;b&gt;sneaky&lt;/b&gt;'));
516
+ // Raw tags must not leak through
517
+ assert.ok(!html.includes('<xss-id>'));
518
+ assert.ok(!html.includes('<b>sneaky</b>'));
519
+ });
520
+
521
+ it('renders body through the markdown pipeline (lists, bold, code)', () => {
522
+ var observations = [
523
+ {
524
+ id: 'obs-1',
525
+ title: 'Refactor opportunity',
526
+ body: '**Why:** duplication.\n\n- `src/a.ts` has the old pattern\n- `src/b.ts` mirrors it',
527
+ },
528
+ ];
529
+ var html = renderObservations(observations);
530
+ assert.ok(html.includes('<strong>Why:</strong>'));
531
+ assert.ok(html.includes('<ul>'));
532
+ assert.ok(html.includes('<code>src/a.ts</code>'));
533
+ });
534
+ });
535
+
536
+ describe('astrolabe.js observations tab wiring', () => {
537
+ // Guard that the observations tab dispatches through renderObservations,
538
+ // not through the generic renderMarkdown. renderMarkdown on an array
539
+ // produces "[object Object]" concatenation garbage.
540
+ it('observations tab case calls renderObservations in astrolabe.js', () => {
541
+ assert.match(
542
+ astrolabeJs,
543
+ /case 'observations':[\s\S]*?renderObservations\(currentPlan\.observations\)/,
544
+ 'observations tab must call renderObservations, not renderMarkdown',
545
+ );
546
+ assert.doesNotMatch(
547
+ astrolabeJs,
548
+ /case 'observations':[\s\S]*?renderMarkdown\(currentPlan\.observations\)/,
549
+ 'observations tab must not call renderMarkdown on the array-typed field',
550
+ );
551
+ });
552
+ });
553
+
432
554
  describe('astrolabe.js plan-detail writ cross-link URL', () => {
433
555
  // Regression guard: the plan-detail brief-writ and mandate-writ anchors
434
556
  // historically targeted '/pages/clerk/?writ=…', but no plugin registers
@@ -192,7 +192,16 @@ Accumulate a punch list of things noticed during your pass that are outside the
192
192
  - **Doc/code discrepancies** found during inventory
193
193
  - **Potential bugs or risks** noticed in adjacent code
194
194
 
195
- Each entry should be actionable: specific enough that a future commission could address it without re-doing the analysis.
195
+ Each observation is **one record per atomic concern**. Downstream, the `astrolabe.observation-lift` engine creates one draft brief writ per record as a child of the originating brief, so a curator (human or automated) can promote it to open status. Your job is to package the concerns; you do not decide which ones get promoted.
196
+
197
+ Atomicity guidance has not changed from prior practice — if two noticings would be addressed by the same follow-up commission, they belong in one record; if they would be addressed by two different commissions, they are two records.
198
+
199
+ Each observation record needs:
200
+ - `id` — sequential plandoc-local identifier (`obs-1`, `obs-2`, …). Assigned by you; stored verbatim.
201
+ - `title` — one line, commission-title style: imperative verb phrase or noun phrase, ~10 words maximum, no trailing punctuation. This becomes the title of the draft writ downstream, so it should read naturally in a writ list.
202
+ - `body` — tactical detail, markdown. Name the specific files, symbols, and preconditions — the same level of detail a good brief carries today. Do not rewrite into a formal brief register; the body stays tactical.
203
+
204
+ Write observations using `observations-write`. The parameter is a strict array of the records described above — a legacy prose blob is rejected at validation time.
196
205
 
197
206
  ### Boundaries
198
207
 
@@ -188,9 +188,16 @@ Accumulate a punch list of things noticed during analysis that are outside the b
188
188
  - **Doc/code discrepancies** found during inventory
189
189
  - **Potential bugs or risks** noticed in adjacent code
190
190
 
191
- Each entry should be actionable: specific enough that a future commission could address it without re-doing the analysis.
191
+ Each observation is **one record per atomic concern**. Downstream, the `astrolabe.observation-lift` engine creates one draft brief writ per record as a child of the originating brief, so a curator (human or automated) can promote it to open status. Your job is to package the concerns; you do not decide which ones get promoted.
192
192
 
193
- Write observations using `observations-write`.
193
+ Atomicity guidance has not changed from prior practice — if two noticings would be addressed by the same follow-up commission, they belong in one record; if they would be addressed by two different commissions, they are two records.
194
+
195
+ Each observation record needs:
196
+ - `id` — sequential plandoc-local identifier (`obs-1`, `obs-2`, …). Assigned by you; stored verbatim.
197
+ - `title` — one line, commission-title style: imperative verb phrase or noun phrase, ~10 words maximum, no trailing punctuation. This becomes the title of the draft writ downstream, so it should read naturally in a writ list.
198
+ - `body` — tactical detail, markdown. Name the specific files, symbols, and preconditions — the same level of detail a good brief carries today. Do not rewrite into a formal brief register; the body stays tactical.
199
+
200
+ Write observations using `observations-write`. The parameter is a strict array of the records described above — a legacy prose blob is rejected at validation time.
194
201
 
195
202
  ### Boundaries
196
203
 
@@ -223,7 +223,16 @@ Accumulate a punch list of things noticed during your pass that are outside the
223
223
  - **Doc/code discrepancies** found during inventory
224
224
  - **Potential bugs or risks** noticed in adjacent code
225
225
 
226
- Each entry should be actionable: specific enough that a future commission could address it without re-doing the analysis.
226
+ Each observation is **one record per atomic concern**. Downstream, the `astrolabe.observation-lift` engine creates one draft brief writ per record as a child of the originating brief, so a curator (human or automated) can promote it to open status. Your job is to package the concerns; you do not decide which ones get promoted.
227
+
228
+ Atomicity guidance has not changed from prior practice — if two noticings would be addressed by the same follow-up commission, they belong in one record; if they would be addressed by two different commissions, they are two records.
229
+
230
+ Each observation record needs:
231
+ - `id` — sequential plandoc-local identifier (`obs-1`, `obs-2`, …). Assigned by you; stored verbatim.
232
+ - `title` — one line, commission-title style: imperative verb phrase or noun phrase, ~10 words maximum, no trailing punctuation. This becomes the title of the draft writ downstream, so it should read naturally in a writ list.
233
+ - `body` — tactical detail, markdown. Name the specific files, symbols, and preconditions — the same level of detail a good brief carries today. Do not rewrite into a formal brief register; the body stays tactical.
234
+
235
+ Write observations using `observations-write`. The parameter is a strict array of the records described above — a legacy prose blob is rejected at validation time.
227
236
 
228
237
  ### Boundaries
229
238
 
package/sage-writer.md CHANGED
@@ -65,7 +65,9 @@ The **decision summary** in your prompt provides a quick-reference digest. When
65
65
 
66
66
  Before writing anything, verify that the decisions fully cover the design space. For each in-scope item, ask: can I write the brief for this without making any choices that aren't already in the plan's decisions?
67
67
 
68
- If you find a gap — a choice you'd need to make that isn't covered — **stop.** Write the gaps into observations using `observations-write` (describe each missing decision clearly: what question needs answering, what scope item it affects, why you can't proceed without it). Do **not** call `spec-write`. The absence of a spec will cause the downstream publish engine to fail, signaling that the planning pipeline needs revision.
68
+ If you find a gap — a choice you'd need to make that isn't covered — **stop.** Write the gaps into observations using `observations-write` (one observation record per missing decision: describe what question needs answering, what scope item it affects, and why you can't proceed without it). Do **not** call `spec-write`. The absence of a spec will cause the downstream publish engine to fail, signaling that the planning pipeline needs revision.
69
+
70
+ **Note — observation-vs-gap semantic fork.** The primer stages use `observations-write` to record follow-up *commissions* (refactors, risks, bugs worth a future writ). The writer stage uses the same tool to record *gap reports* — places where the plan is missing a decision and the pipeline must stop. Both paths share the structured-array packaging: one record per concern, with `id`, `title`, and `body`. The *semantic* difference is what the records mean downstream — promotable follow-up work (primer) vs. a blocking pipeline signal (writer) — and that the writer's path is accompanied by the deliberate omission of `spec-write`. When you write a gap report, use titles that read as commission-title-style questions (e.g. `Decide serialization format for foo-cache`) and bodies that name the affected scope item, the design question, and the files or patterns that make the question unavoidable.
69
71
 
70
72
  Do not fill the gap yourself, do not make a "reasonable assumption," do not pick the "obvious" choice. The entire point of this pipeline is that decisions are made explicitly and reviewed — never silently embedded in brief text.
71
73