@miadi/inquiry-weave 0.6.9 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Miadi
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -235,3 +235,116 @@ calls (`INQUIRY_WEAVE_ISSUE_LIB` injects a fake issue lib).
235
235
  ---
236
236
  🌸: A loom, not a pen — the weave holds artefact, issue, and episode in relation so none
237
237
  drifts from the others, while the question itself stays yours to ask.
238
+
239
+ ## `resolve` — one chronicle reference, answered
240
+
241
+ ```bash
242
+ inquiry-weave resolve "miadi-chronicle:311/services-inventory"
243
+ ```
244
+
245
+ ```
246
+ écoute factorisation logiciels — the relational software factory
247
+ [room·local] [room·tailnet] [room·public] [wheel·captures]
248
+ [wheel·graph] [wheel·node] [wheel·relations] [file·inventory]
249
+ <miadi-chronicle:311/services-inventory>
250
+ episode 311 · 2026-08-05-episode-311-coute-… · matched by number
251
+ path: /srv/miadi/episodes/…/services-inventory.json
252
+ modality: relational
253
+ ```
254
+
255
+ Turns a `miadi-chronicle:` reference into every door it opens. Contract:
256
+ `rispecs/miadi-chronicle-dsl/SPEC.md` (v1.1) and `SPEC-TERMINAL.md` (v1.2);
257
+ grounding in `foundations/resource-addressing-and-terminal-hypermedia/`.
258
+
259
+ Each bracket is its own OSC 8 hyperlink, and the canonical reference stays
260
+ visible beside them — the OSC 8 specification says a hyperlink "should not be
261
+ the only means of figuring out the target", and there is no way to detect
262
+ whether a terminal supports them. `--raw` drops the escape for clean capture.
263
+
264
+ **The reference is host-free.** `miadi-chronicle:311` is the name; a base is
265
+ chosen at render time. That is ARK's Name Mapping Authority rule — the
266
+ resolver's hostport is identity-inert — and it is why the same reference reads
267
+ correctly from this host, the tailnet, or the public front.
268
+
269
+ | flag | does |
270
+ | --- | --- |
271
+ | `--json` | the full result: `canonical`, `resolution`, `artifact`, `destinations[]`, `open`, `shareable`, `path`, `modality` |
272
+ | `--base local\|internal\|public` | lead with one door. Reorders; never removes one |
273
+ | `--local` | lead with the file on this disk |
274
+ | `--verify` | ask the wheel whether the episode is really on it |
275
+ | `--raw` | no escape sequences |
276
+
277
+ **`--verify` exists because a 200 proves nothing.** The wheel's `/graph`,
278
+ `/nodes` and `/relations` pages are client-routed, and so is forgewright's
279
+ chronicle view: both return 200 for an episode name that does not exist
280
+ (measured `?episode=9999-99-99-episode-000-nope` → 200). Only
281
+ `GET /api/nodes/<id>` discriminates, and that is what `--verify` asks.
282
+
283
+ **Two answers, never collapsed.** `open` is where a human click should land —
284
+ the episode room. `path` is the bytes on this host. An earlier draft returned
285
+ only the file, and clicking it opened a text editor on raw JSON: local-first is
286
+ about data ownership and availability, not about presentation.
287
+
288
+ ### Forms
289
+
290
+ ```
291
+ miadi-chronicle:092/126?view=wheel#scene=river # canonical, rootless
292
+ miadi-chronicle://092/126 # accepted forever, normalized away
293
+ ```
294
+
295
+ `//` is RFC 3986 §3.2's authority marker, so a conformant parser reads the
296
+ first path segment as a host — `new URL("miadi-chronicle://126")` yields host
297
+ `"126"` and an **empty path**. Producers emit rootless; parsers accept both.
298
+
299
+ ### Artifact segments
300
+
301
+ `services-inventory` · `state-machine` · `captures` · `recordings` · `inquiry`
302
+ · `plans`. The last four are served by the medicine wheel and are keyed by
303
+ `episode_path` — the **full folder name**. The episode number is not a key
304
+ there: `?episode_number=320` returns 0 records for an episode whose
305
+ `?episode_path=<folder>` returns 1.
306
+
307
+ ### Fragments
308
+
309
+ `#state=` and `#event=` are spellable; `#transition=`, `#parameter=`,
310
+ `#action=` and `#source=` are not. State names are unique tree-wide (SMDF's
311
+ V002) so they survive structural motion; transitions are addressed positionally
312
+ and a sibling insert silently retargets the reference. Name-keyed fragments are
313
+ durable against structural motion and **fragile against rename** — see
314
+ `SPEC-TERMINAL.md` §4.3a.
315
+
316
+ ## `terminal install` — clickable references in Terminator
317
+
318
+ ```bash
319
+ inquiry-weave terminal install --enable
320
+ ```
321
+
322
+ Writes three files and one config line, each printed:
323
+
324
+ | path | is |
325
+ | --- | --- |
326
+ | `~/.config/terminator/plugins/miadi_chronicle_url_handler.py` | the URL handler |
327
+ | `~/.config/environment.d/50-miadi-chronicle.conf` | systemd user environment |
328
+ | `~/bin/miadi-chronicle-open` | the resolver wrapper a click runs |
329
+ | `enabled_plugins` in the Terminator config | only with `--enable`, after a backup |
330
+
331
+ Then restart Terminator and **Ctrl+click** a `miadi-chronicle:` reference
332
+ anywhere in its output. Plain click needs `link_single_click = True`.
333
+
334
+ `--force` overwrites, `--dry-run` previews, `terminal uninstall` reverses it,
335
+ `terminal show` prints the paths. Running install twice is safe.
336
+
337
+ **Why a plugin when OSC 8 exists.** Terminator has two click paths: an OSC 8
338
+ hyperlink calls `open_url(prepare=False)` and goes straight to `xdg-open`,
339
+ while a regex match calls `prepare=True` — the only path that consults
340
+ `url_handler` plugins. So the plugin covers what OSC 8 structurally cannot: a
341
+ bare `miadi-chronicle:311` in output that knows nothing about miadi — a git
342
+ log, a grep hit, an agent's raw text.
343
+
344
+ **Why the environment drop-in.** A GUI process inherits nothing from your
345
+ shell, so `MIADI_URL_BASE`, `MW_API_URL` and `MIADI_CHRONICLE_ROOT` are absent
346
+ at click time and every click falls back to localhost. `environment.d` is the
347
+ OS's own answer — read by systemd's user-environment generator at session
348
+ start, so every GUI process in the session inherits it. Takes effect at the
349
+ next login; the wrapper carries the same values as a fallback until then.
350
+ Test with `env -i`, which is the real click condition. See `jgwill/Miadi#620`.
@@ -0,0 +1,70 @@
1
+ /**
2
+ * Attention-node projection — make "what needs a human" visible on the wheel.
3
+ *
4
+ * Mirrors episode-node.ts: the vessel's `attention.json` stays authoritative;
5
+ * each item projects as ONE dedicated node (`attention:<episode>/<item-id>`),
6
+ * riding `knowledge` facing SOUTH — a decision ask is consent work. Per-item
7
+ * nodes are deliberate: medicine-wheel PATCH replaces the whole metadata
8
+ * object (storage-provider jsonl.ts `metadata: patch.metadata`, no merge), so
9
+ * items sharing a node would race every concurrent writer; one item, one
10
+ * writer, one node. forgewright's chronicle view is wheel-fed only, so this
11
+ * projection IS how attention reaches ilex.
12
+ *
13
+ * POST upserts by id on medicine-wheel ≥0.5.0, so registration preflights GET
14
+ * and UPDATES an existing node via PATCH instead of silently overwriting.
15
+ * Fail-open boundary exactly like registerEpisodeNode: network failure
16
+ * resolves to `pending`, never a throw — the file write upstream must never
17
+ * be lost to a wheel outage.
18
+ */
19
+ import type { AttentionItem } from "@miadi/episodic-memory-schema";
20
+ import { ATTENTION_SCHEMA_VERSION } from "@miadi/episodic-memory-schema";
21
+ export interface AttentionNodeRecord {
22
+ id: string;
23
+ type: "knowledge";
24
+ name: string;
25
+ description: string;
26
+ direction: "south";
27
+ metadata: {
28
+ contract: "miadi.artifact-ref.v1";
29
+ kind: "attention";
30
+ schema_version: typeof ATTENTION_SCHEMA_VERSION;
31
+ root: "MIADI_CHRONICLE_ROOT";
32
+ relative_path: string;
33
+ parent_id: string;
34
+ item_id: string;
35
+ state: "open" | "answered";
36
+ asked?: string;
37
+ unlocks?: string;
38
+ answer?: string;
39
+ answered_at?: string;
40
+ };
41
+ }
42
+ export type AttentionNodeState = "registered" | "updated" | "pending";
43
+ export interface AttentionNodeOutcome {
44
+ state: AttentionNodeState;
45
+ node_id: string;
46
+ /** True only when a read-back confirmed the stored state matches the item. */
47
+ verified: boolean;
48
+ error?: string;
49
+ }
50
+ export declare function attentionNodeId(episodeName: string, itemId: string): string;
51
+ export declare function projectAttentionNode(episodeName: string, item: AttentionItem): AttentionNodeRecord;
52
+ export interface RegisterAttentionNodeOptions {
53
+ fetchImpl?: typeof fetch;
54
+ }
55
+ /**
56
+ * Create or update the wheel node for one item, then read it back.
57
+ * `verified: true` means the wheel now SERVES the item's state — reached,
58
+ * not merely configured.
59
+ */
60
+ export declare function registerAttentionNode(mwUrl: string, episodeName: string, item: AttentionItem, options?: RegisterAttentionNodeOptions): Promise<AttentionNodeOutcome>;
61
+ export interface SyncAttentionOutcome {
62
+ outcomes: AttentionNodeOutcome[];
63
+ registered: number;
64
+ updated: number;
65
+ pending: number;
66
+ verified: number;
67
+ }
68
+ /** Project every item of one episode; never throws past its boundary. */
69
+ export declare function syncEpisodeAttention(mwUrl: string, episodeName: string, items: readonly AttentionItem[], options?: RegisterAttentionNodeOptions): Promise<SyncAttentionOutcome>;
70
+ //# sourceMappingURL=attention-node.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"attention-node.d.ts","sourceRoot":"","sources":["../src/attention-node.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAA;AAClE,OAAO,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAA;AAExE,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,WAAW,CAAA;IACjB,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,EAAE,MAAM,CAAA;IACnB,SAAS,EAAE,OAAO,CAAA;IAClB,QAAQ,EAAE;QACR,QAAQ,EAAE,uBAAuB,CAAA;QACjC,IAAI,EAAE,WAAW,CAAA;QACjB,cAAc,EAAE,OAAO,wBAAwB,CAAA;QAC/C,IAAI,EAAE,sBAAsB,CAAA;QAC5B,aAAa,EAAE,MAAM,CAAA;QACrB,SAAS,EAAE,MAAM,CAAA;QACjB,OAAO,EAAE,MAAM,CAAA;QACf,KAAK,EAAE,MAAM,GAAG,UAAU,CAAA;QAC1B,KAAK,CAAC,EAAE,MAAM,CAAA;QACd,OAAO,CAAC,EAAE,MAAM,CAAA;QAChB,MAAM,CAAC,EAAE,MAAM,CAAA;QACf,WAAW,CAAC,EAAE,MAAM,CAAA;KACrB,CAAA;CACF;AAED,MAAM,MAAM,kBAAkB,GAAG,YAAY,GAAG,SAAS,GAAG,SAAS,CAAA;AAErE,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,kBAAkB,CAAA;IACzB,OAAO,EAAE,MAAM,CAAA;IACf,8EAA8E;IAC9E,QAAQ,EAAE,OAAO,CAAA;IACjB,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED,wBAAgB,eAAe,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAE3E;AAED,wBAAgB,oBAAoB,CAClC,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE,aAAa,GAClB,mBAAmB,CAuBrB;AAED,MAAM,WAAW,4BAA4B;IAC3C,SAAS,CAAC,EAAE,OAAO,KAAK,CAAA;CACzB;AAgBD;;;;GAIG;AACH,wBAAsB,qBAAqB,CACzC,KAAK,EAAE,MAAM,EACb,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE,aAAa,EACnB,OAAO,GAAE,4BAAiC,GACzC,OAAO,CAAC,oBAAoB,CAAC,CAwG/B;AAED,MAAM,WAAW,oBAAoB;IACnC,QAAQ,EAAE,oBAAoB,EAAE,CAAA;IAChC,UAAU,EAAE,MAAM,CAAA;IAClB,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,MAAM,CAAA;IACf,QAAQ,EAAE,MAAM,CAAA;CACjB;AAED,yEAAyE;AACzE,wBAAsB,oBAAoB,CACxC,KAAK,EAAE,MAAM,EACb,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,SAAS,aAAa,EAAE,EAC/B,OAAO,GAAE,4BAAiC,GACzC,OAAO,CAAC,oBAAoB,CAAC,CAY/B"}
@@ -0,0 +1,194 @@
1
+ /**
2
+ * Attention-node projection — make "what needs a human" visible on the wheel.
3
+ *
4
+ * Mirrors episode-node.ts: the vessel's `attention.json` stays authoritative;
5
+ * each item projects as ONE dedicated node (`attention:<episode>/<item-id>`),
6
+ * riding `knowledge` facing SOUTH — a decision ask is consent work. Per-item
7
+ * nodes are deliberate: medicine-wheel PATCH replaces the whole metadata
8
+ * object (storage-provider jsonl.ts `metadata: patch.metadata`, no merge), so
9
+ * items sharing a node would race every concurrent writer; one item, one
10
+ * writer, one node. forgewright's chronicle view is wheel-fed only, so this
11
+ * projection IS how attention reaches ilex.
12
+ *
13
+ * POST upserts by id on medicine-wheel ≥0.5.0, so registration preflights GET
14
+ * and UPDATES an existing node via PATCH instead of silently overwriting.
15
+ * Fail-open boundary exactly like registerEpisodeNode: network failure
16
+ * resolves to `pending`, never a throw — the file write upstream must never
17
+ * be lost to a wheel outage.
18
+ */
19
+ import { ATTENTION_SCHEMA_VERSION } from "@miadi/episodic-memory-schema";
20
+ export function attentionNodeId(episodeName, itemId) {
21
+ return `attention:${episodeName}/${itemId}`;
22
+ }
23
+ export function projectAttentionNode(episodeName, item) {
24
+ const metadata = {
25
+ contract: "miadi.artifact-ref.v1",
26
+ kind: "attention",
27
+ schema_version: ATTENTION_SCHEMA_VERSION,
28
+ root: "MIADI_CHRONICLE_ROOT",
29
+ relative_path: `${episodeName}/attention.json`,
30
+ parent_id: `chronicle:${episodeName}`,
31
+ item_id: item.id,
32
+ state: item.state,
33
+ };
34
+ if (item.asked)
35
+ metadata.asked = item.asked;
36
+ if (item.unlocks)
37
+ metadata.unlocks = item.unlocks;
38
+ if (item.answer)
39
+ metadata.answer = item.answer;
40
+ if (item.answered_at)
41
+ metadata.answered_at = item.answered_at;
42
+ return {
43
+ id: attentionNodeId(episodeName, item.id),
44
+ type: "knowledge",
45
+ name: item.question,
46
+ description: item.unlocks ? `unlocks: ${item.unlocks}` : "",
47
+ direction: "south",
48
+ metadata,
49
+ };
50
+ }
51
+ function describeFailure(error) {
52
+ return error instanceof Error ? error.message : String(error);
53
+ }
54
+ async function readErrorBody(response) {
55
+ try {
56
+ const body = (await response.json());
57
+ if (body && typeof body.error === "string")
58
+ return body.error;
59
+ }
60
+ catch {
61
+ // Non-JSON body — the status line is all we can report.
62
+ }
63
+ return "";
64
+ }
65
+ /**
66
+ * Create or update the wheel node for one item, then read it back.
67
+ * `verified: true` means the wheel now SERVES the item's state — reached,
68
+ * not merely configured.
69
+ */
70
+ export async function registerAttentionNode(mwUrl, episodeName, item, options = {}) {
71
+ const fetchImpl = options.fetchImpl ?? fetch;
72
+ const base = mwUrl.replace(/\/+$/, "");
73
+ const record = projectAttentionNode(episodeName, item);
74
+ const node_id = record.id;
75
+ const nodeUrl = `${base}/api/nodes/${encodeURIComponent(node_id)}`;
76
+ let existing;
77
+ try {
78
+ existing = await fetchImpl(nodeUrl);
79
+ }
80
+ catch (error) {
81
+ return {
82
+ state: "pending",
83
+ node_id,
84
+ verified: false,
85
+ error: `medicine-wheel unreachable at ${base}: ${describeFailure(error)}`,
86
+ };
87
+ }
88
+ let state;
89
+ if (existing.ok) {
90
+ // Full-metadata PATCH by design: the store replaces, so we always send the
91
+ // complete projection — never a partial that would erase sibling fields.
92
+ let patched;
93
+ try {
94
+ patched = await fetchImpl(nodeUrl, {
95
+ method: "PATCH",
96
+ headers: { "content-type": "application/json" },
97
+ body: JSON.stringify({
98
+ name: record.name,
99
+ description: record.description,
100
+ metadata: record.metadata,
101
+ }),
102
+ });
103
+ }
104
+ catch (error) {
105
+ return {
106
+ state: "pending",
107
+ node_id,
108
+ verified: false,
109
+ error: `PATCH ${nodeUrl}: ${describeFailure(error)}`,
110
+ };
111
+ }
112
+ if (!patched.ok) {
113
+ const detail = await readErrorBody(patched);
114
+ return {
115
+ state: "pending",
116
+ node_id,
117
+ verified: false,
118
+ error: `PATCH ${nodeUrl}: HTTP ${patched.status}${detail ? ` — ${detail}` : ""}`,
119
+ };
120
+ }
121
+ state = "updated";
122
+ }
123
+ else if (existing.status === 404) {
124
+ let created;
125
+ try {
126
+ created = await fetchImpl(`${base}/api/nodes`, {
127
+ method: "POST",
128
+ headers: { "content-type": "application/json" },
129
+ body: JSON.stringify(record),
130
+ });
131
+ }
132
+ catch (error) {
133
+ return {
134
+ state: "pending",
135
+ node_id,
136
+ verified: false,
137
+ error: `medicine-wheel unreachable at ${base}: ${describeFailure(error)}`,
138
+ };
139
+ }
140
+ if (!created.ok) {
141
+ const detail = await readErrorBody(created);
142
+ return {
143
+ state: "pending",
144
+ node_id,
145
+ verified: false,
146
+ error: `POST ${base}/api/nodes: HTTP ${created.status}${detail ? ` — ${detail}` : ""}`,
147
+ };
148
+ }
149
+ state = "registered";
150
+ }
151
+ else {
152
+ const detail = await readErrorBody(existing);
153
+ return {
154
+ state: "pending",
155
+ node_id,
156
+ verified: false,
157
+ error: `GET ${nodeUrl}: HTTP ${existing.status}${detail ? ` — ${detail}` : ""}`,
158
+ };
159
+ }
160
+ // The verify leg — the boot-law applied to the write path.
161
+ try {
162
+ const back = await fetchImpl(nodeUrl);
163
+ if (!back.ok)
164
+ return { state, node_id, verified: false, error: `verify GET: HTTP ${back.status}` };
165
+ const body = (await back.json());
166
+ const served = body.node?.metadata?.state ?? body.metadata?.state;
167
+ if (served === item.state)
168
+ return { state, node_id, verified: true };
169
+ return {
170
+ state,
171
+ node_id,
172
+ verified: false,
173
+ error: `verify: wheel serves state=${String(served)}, item is ${item.state}`,
174
+ };
175
+ }
176
+ catch (error) {
177
+ return { state, node_id, verified: false, error: `verify GET: ${describeFailure(error)}` };
178
+ }
179
+ }
180
+ /** Project every item of one episode; never throws past its boundary. */
181
+ export async function syncEpisodeAttention(mwUrl, episodeName, items, options = {}) {
182
+ const outcomes = [];
183
+ for (const item of items) {
184
+ outcomes.push(await registerAttentionNode(mwUrl, episodeName, item, options));
185
+ }
186
+ return {
187
+ outcomes,
188
+ registered: outcomes.filter((o) => o.state === "registered").length,
189
+ updated: outcomes.filter((o) => o.state === "updated").length,
190
+ pending: outcomes.filter((o) => o.state === "pending").length,
191
+ verified: outcomes.filter((o) => o.verified).length,
192
+ };
193
+ }
194
+ //# sourceMappingURL=attention-node.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"attention-node.js","sourceRoot":"","sources":["../src/attention-node.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,191 @@
1
+ /**
2
+ * miadi-chronicle URI parsing, artifact registry, and episode resolution.
3
+ *
4
+ * Contract: rispecs/miadi-chronicle-dsl/SPEC.md (v1.1) and SPEC-TERMINAL.md
5
+ * (v1.2). Grounded in foundations/resource-addressing-and-terminal-hypermedia/.
6
+ *
7
+ * This is the app's three pure modules (`app/chronicle/lib/{dsl,resolveRef,
8
+ * inventoryRef}.ts`) brought into a package that already ships built ESM, so
9
+ * one resolver can answer the browser, the HTTP route, and a terminal. It
10
+ * stays pure — no fs, no fetch, no React. The catalog arrives as an argument.
11
+ *
12
+ * Two changes v1.1 does not have, both from the foundations packet:
13
+ *
14
+ * 1. ROOTLESS FORM. `//` is RFC 3986 §3.2's authority marker, so every
15
+ * conformant parser reads the first path segment as a host:
16
+ * new URL("miadi-chronicle://126") → host "126", pathname ""
17
+ * The most common reference has an EMPTY PATH, stock parsers disagree
18
+ * with this file, and SPEC §8's reserved `//root@…/` growth slot is
19
+ * unreachable because episode data already occupies it. Every non-HTTP
20
+ * scheme that survived — did:, urn:, ark:, swh:, tag:, info: — is
21
+ * rootless. So: `miadi-chronicle:092/126` is canonical, `//` is accepted
22
+ * forever on input and normalized away on output.
23
+ *
24
+ * 2. ARTIFACT REGISTRY. v1.1's "registry" was one const string compared by
25
+ * `===` in three places. It is a map now, with `state-machine` as the
26
+ * second entry.
27
+ */
28
+ export declare const MIADI_CHRONICLE_SCHEME = "miadi-chronicle:";
29
+ /** Rendering options folded into the URI query under the reserved prefix. */
30
+ export declare const OPTION_PREFIX = "mc.";
31
+ /**
32
+ * Reserved artifact segments — the registry SPEC §7.1 named itself after.
33
+ * Each key is a name no episode folder can carry (folder names are
34
+ * date-prefixed); each value is the artifact kind the resolver dispatches on.
35
+ */
36
+ export declare const ARTIFACT_SEGMENTS: {
37
+ readonly "services-inventory": "inventory";
38
+ readonly "state-machine": "state-machine";
39
+ readonly captures: "captures";
40
+ readonly recordings: "captures";
41
+ readonly inquiry: "inquiry";
42
+ readonly plans: "plans";
43
+ };
44
+ export type ArtifactKind = (typeof ARTIFACT_SEGMENTS)[keyof typeof ARTIFACT_SEGMENTS];
45
+ /** Kinds served by the medicine wheel rather than by the vessel on disk. */
46
+ export declare const WHEEL_ARTIFACT_KINDS: readonly ["captures", "inquiry", "plans"];
47
+ /** The wheel node id for an episode. The observed format, not the expected one:
48
+ * `chronicle:2026-08-05-episode-311-coute-…-factory`. */
49
+ export declare function wheelNodeId(episodeFolder: string): string;
50
+ export interface ParsedChronicleUri {
51
+ /** The full original URI, exactly as given. */
52
+ uri: string;
53
+ /** Canonical rootless form with `mc.*` options and fragment preserved. */
54
+ canonical: string;
55
+ /** Raw slash-joined path as written, e.g. "092/126" or "311/state-machine". */
56
+ episodePath: string;
57
+ /** Path split into segments, artifact segment included when present. */
58
+ segments: string[];
59
+ /** Segments that address an EPISODE — the artifact segment stripped. */
60
+ episodeSegments: string[];
61
+ /** Which artifact this reference names, or null for a plain episode ref. */
62
+ artifact: ArtifactKind | null;
63
+ /** Query params minus the mc.* rendering options. */
64
+ query: Record<string, string>;
65
+ /** mc.* rendering options, prefix stripped (show, label, highlight, as, …). */
66
+ options: Record<string, string>;
67
+ /** In-episode navigation hint, e.g. "scene=river" or "state=Gathering". */
68
+ fragment?: string;
69
+ }
70
+ export declare function isMiadiChronicleUri(href: string | undefined): boolean;
71
+ /** Parse one URI. Returns null on anything malformed — never throws. */
72
+ export declare function parseMiadiChronicleUri(uri: string): ParsedChronicleUri | null;
73
+ /**
74
+ * Keys a `state-machine` fragment may use.
75
+ *
76
+ * `state` and `event` are name-keyed: SMDF's validation rule V002 forces
77
+ * tree-wide unique state names, and events are keyed by id, so both survive
78
+ * structural motion. Transitions, parameters, actions and event sources are
79
+ * addressed POSITIONALLY (`{state, index}`) — an index shifts the moment a
80
+ * sibling is inserted, and the reference then resolves to the wrong thing
81
+ * without raising anything. Content drift outruns link rot roughly 3:1
82
+ * (Jones et al. 2016, doi:10.1371/journal.pone.0167475) and the silent
83
+ * variant is the damaging one, so a form that cannot be durable is not
84
+ * spellable here.
85
+ *
86
+ * The narrow claim, precisely: a BARE `{state, index}` pair carries no content
87
+ * by which a shifted reference could be re-matched or a mis-resolution
88
+ * detected. Positional addressing can be hardened (Phelps & Wilensky carry
89
+ * node tags alongside the index and resolve by approximate match) — but
90
+ * hardening it here would amount to describing the transition, at which point
91
+ * the index is doing no work. The sanctioned way to address one is therefore
92
+ * by description, from V002-unique names, which inherits their durability:
93
+ * #transition=(from:<State>,on:<Event>,to:<State>)
94
+ * That form EXTENDS this rule rather than breaching it. It is not implemented.
95
+ *
96
+ * Conditional by design: transitions are positional IN SMDF TODAY. OMG XMI
97
+ * gives every model element an `xmi:id`; if SMDF ever mints author-assigned
98
+ * transition ids under the same uniqueness constraint, `#transition=` becomes
99
+ * durable and this rule's own principle would then REQUIRE permitting it.
100
+ */
101
+ export declare const DURABLE_FRAGMENT_KEYS: readonly ["state", "event"];
102
+ /** Positional keys, refused with a reason rather than silently ignored. */
103
+ export declare const POSITIONAL_FRAGMENT_KEYS: readonly ["transition", "parameter", "action", "source"];
104
+ export interface FragmentVerdict {
105
+ key: string;
106
+ value: string;
107
+ durable: boolean;
108
+ reason?: string;
109
+ }
110
+ /**
111
+ * Judge a `key=value` fragment against the durability rule. An unknown key is
112
+ * neither endorsed nor refused — it is passed through, per SPEC §1's rule that
113
+ * unknown parameters are preserved and never fatal.
114
+ */
115
+ export declare function judgeFragment(fragment: string | undefined): FragmentVerdict | null;
116
+ /**
117
+ * Rename is the hole V002 does not cover.
118
+ *
119
+ * V002 gives tree-wide unique state names AT A POINT IN TIME. It says nothing
120
+ * about immutability: under rename, `#state=Foo` fails exactly as a positional
121
+ * reference fails under insertion, and the worse variant — a name reused for a
122
+ * different state — resolves successfully to the wrong element.
123
+ *
124
+ * The policy this package implements is the middle of the three the packet
125
+ * lists: an alias table. A machine MAY carry `former-names`, and a reference
126
+ * to a former name resolves WITH A DEPRECATION SIGNAL rather than failing.
127
+ * That is XPointer's ordered-fallback pattern applied locally, and Memento's
128
+ * idea (reach a prior state) without an archive. Until SMDF carries
129
+ * `former-names`, the honest status is: name-keyed fragments are durable
130
+ * against structural motion and fragile against rename, and this is stated
131
+ * rather than implied.
132
+ */
133
+ export declare const RENAME_POLICY: "alias-table-pending";
134
+ export type MatchedBy = "folder-name" | "number" | "slug" | "date";
135
+ /** The seven fields resolution actually reads. Structurally satisfied by
136
+ * `EpisodeManifestEntry` from the catalog, and by the app's richer view. */
137
+ export interface ResolvableEpisode {
138
+ name: string;
139
+ number?: number;
140
+ slug?: string;
141
+ date?: string;
142
+ title?: string;
143
+ direction?: string;
144
+ theme?: string;
145
+ }
146
+ export interface ResolvedEpisodeRef {
147
+ segment: string;
148
+ resolved: boolean;
149
+ matchedBy?: MatchedBy;
150
+ name?: string;
151
+ number?: number;
152
+ title?: string;
153
+ date?: string;
154
+ direction?: string;
155
+ theme?: string;
156
+ /** App route to the episode room, fragment already attached for targets. */
157
+ route?: string;
158
+ /**
159
+ * Folder names of OTHER episodes the segment also matched. The catalog
160
+ * really does hold duplicate numbers; resolution stays deterministic and
161
+ * the ambiguity is surfaced instead of hidden.
162
+ *
163
+ * Note what this does NOT yet solve: the tie-break is lexicographically
164
+ * first, so backfilling a newly-discovered OLDER episode with a duplicate
165
+ * number silently retargets every existing reference. Non-reassignment is a
166
+ * primary dimension of identifier validity (Kunze et al. 2017); ARK and DOI
167
+ * forbid reassignment outright. Deterministic-at-an-instant is not
168
+ * stable-over-time, and `alternates` reports the ambiguity without fixing it.
169
+ */
170
+ alternates?: string[];
171
+ }
172
+ export interface ChronicleResolution {
173
+ resolved: boolean;
174
+ matchedBy?: MatchedBy;
175
+ target: ResolvedEpisodeRef;
176
+ waypoints: ResolvedEpisodeRef[];
177
+ }
178
+ /**
179
+ * Resolve an already-parsed URI against the catalog.
180
+ *
181
+ * Resolution runs over `episodeSegments`, so an artifact reference resolves
182
+ * its episode exactly as a plain reference does — the reserved segment is
183
+ * stripped before matching, never matched against a folder.
184
+ */
185
+ export declare function resolveChronicleRef(parsed: ParsedChronicleUri, entries: ResolvableEpisode[]): ChronicleResolution;
186
+ /** One-call convenience: raw URI string → resolution, or null if unparseable. */
187
+ export declare function resolveChronicleUri(uri: string, entries: ResolvableEpisode[]): {
188
+ parsed: ParsedChronicleUri;
189
+ resolution: ChronicleResolution;
190
+ } | null;
191
+ //# sourceMappingURL=chronicle-dsl.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chronicle-dsl.d.ts","sourceRoot":"","sources":["../src/chronicle-dsl.ts"],"names":[],"mappings":"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"}