@sentropic/track 0.83.0 → 0.85.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/dist/cli/bin.js +1 -1
  2. package/dist/cli/bin.js.map +1 -1
  3. package/dist/cli/index.js +7 -7
  4. package/dist/cli/index.js.map +1 -1
  5. package/dist/focus-vendor/cli/index.d.ts +4 -0
  6. package/dist/focus-vendor/cli/index.d.ts.map +1 -0
  7. package/dist/focus-vendor/cli/index.js +181 -0
  8. package/dist/focus-vendor/cli/index.js.map +1 -0
  9. package/dist/focus-vendor/index.d.ts +4 -0
  10. package/dist/focus-vendor/index.d.ts.map +1 -0
  11. package/dist/focus-vendor/index.js +13 -0
  12. package/dist/focus-vendor/index.js.map +1 -0
  13. package/dist/focus-vendor/model.d.ts +2 -0
  14. package/dist/focus-vendor/model.d.ts.map +1 -0
  15. package/dist/focus-vendor/model.js +13 -0
  16. package/dist/focus-vendor/model.js.map +1 -0
  17. package/dist/focus-vendor/render/hooks.d.ts +2 -0
  18. package/dist/focus-vendor/render/hooks.d.ts.map +1 -0
  19. package/dist/focus-vendor/render/hooks.js +10 -0
  20. package/dist/focus-vendor/render/hooks.js.map +1 -0
  21. package/dist/focus-vendor/render/html.d.ts +2 -0
  22. package/dist/focus-vendor/render/html.d.ts.map +1 -0
  23. package/dist/focus-vendor/render/html.js +89 -0
  24. package/dist/focus-vendor/render/html.js.map +1 -0
  25. package/dist/focus-vendor/render/md.d.ts +2 -0
  26. package/dist/focus-vendor/render/md.d.ts.map +1 -0
  27. package/dist/focus-vendor/render/md.js +75 -0
  28. package/dist/focus-vendor/render/md.js.map +1 -0
  29. package/dist/focus-vendor/render/terminal.d.ts +2 -0
  30. package/dist/focus-vendor/render/terminal.d.ts.map +1 -0
  31. package/dist/focus-vendor/render/terminal.js +83 -0
  32. package/dist/focus-vendor/render/terminal.js.map +1 -0
  33. package/dist/focus-vendor/track/index.d.ts +123 -0
  34. package/dist/focus-vendor/track/index.d.ts.map +1 -0
  35. package/dist/focus-vendor/track/index.js +223 -0
  36. package/dist/focus-vendor/track/index.js.map +1 -0
  37. package/package.json +1 -5
@@ -0,0 +1,89 @@
1
+ /**
2
+ * HTML renderer (Focus-M1 L1) — MANDATORY surface.
3
+ *
4
+ * Renders a `DecisionDossierDocument` to an HTML string. Read-only FocusSnapshot:
5
+ * affordances appear as DISABLED metadata; diagrams fall back to a `<pre>` block (no diagram
6
+ * adapter). Markdown prose is converted via the host-supplied `renderMarkdown` hook (NO `marked`
7
+ * dep, NO mdast core); the full document HTML is run through the host `sanitizeHtml` hook before
8
+ * emission. The renderer core owns structure only; hosts own sanitization/styling.
9
+ */
10
+ /** Minimal HTML text escaping for attribute/text content the renderer itself emits. */
11
+ const escapeHtml = (value) => value
12
+ .replace(/&/g, "&amp;")
13
+ .replace(/</g, "&lt;")
14
+ .replace(/>/g, "&gt;")
15
+ .replace(/"/g, "&quot;")
16
+ .replace(/'/g, "&#39;");
17
+ const renderQuestion = (q) => {
18
+ const parts = [
19
+ `<p class="focus-q"><strong>Q:</strong> ${escapeHtml(q.question)} <em>(${escapeHtml(q.state)})</em></p>`,
20
+ ];
21
+ if (q.recommendedAnswer !== undefined) {
22
+ parts.push(`<p class="focus-preco">préco: ${escapeHtml(q.recommendedAnswer)}</p>`);
23
+ }
24
+ if (q.answer !== undefined) {
25
+ parts.push(`<p class="focus-answer">answer: ${escapeHtml(q.answer)}</p>`);
26
+ }
27
+ return `<section class="focus-question">${parts.join("")}</section>`;
28
+ };
29
+ const renderOptionSet = (s) => {
30
+ const head = s.title !== undefined
31
+ ? `<h3>Options — ${escapeHtml(s.title)}</h3>`
32
+ : "<h3>Options</h3>";
33
+ const items = s.options.map((o) => {
34
+ const comment = o.annotationComment !== undefined
35
+ ? ` <span class="focus-option-comment">— ${escapeHtml(o.annotationComment)}</span>`
36
+ : "";
37
+ const body = o.body !== undefined
38
+ ? `<div class="focus-option-body">${escapeHtml(o.body)}</div>`
39
+ : "";
40
+ return `<li class="focus-option" data-annotation="${escapeHtml(o.annotation)}"><strong>${escapeHtml(o.label)}</strong>${comment}${body}</li>`;
41
+ });
42
+ return `<section class="focus-optionset">${head}<ul>${items.join("")}</ul></section>`;
43
+ };
44
+ const renderAmendmentTrace = (steps) => {
45
+ if (steps.length === 0) {
46
+ return `<section class="focus-amendment-trace"><h3>Amendment trace</h3><p><em>(none)</em></p></section>`;
47
+ }
48
+ const items = steps.map((st) => `<li><code>${escapeHtml(st.at)}</code> <strong>${escapeHtml(st.author)}</strong> — ${escapeHtml(st.summary)}</li>`);
49
+ return `<section class="focus-amendment-trace"><h3>Amendment trace</h3><ol>${items.join("")}</ol></section>`;
50
+ };
51
+ const renderDiagram = (d) => `<figure class="focus-diagram" data-syntax="${escapeHtml(d.syntax)}"><figcaption>${escapeHtml(d.alt)}</figcaption><pre><code class="language-${escapeHtml(d.syntax)}">${escapeHtml(d.source)}</code></pre></figure>`;
52
+ const renderNode = (node, hooks) => {
53
+ switch (node.kind) {
54
+ case "prose":
55
+ return `<section class="focus-prose">${hooks.renderMarkdown(node.markdown)}</section>`;
56
+ case "question":
57
+ return renderQuestion(node);
58
+ case "optionSet":
59
+ return renderOptionSet(node);
60
+ case "outcome":
61
+ return `<section class="focus-outcome" data-modality="${escapeHtml(node.modality)}"><h3>Outcome (${escapeHtml(node.modality)})</h3><p>${escapeHtml(node.statement)}</p></section>`;
62
+ case "amendmentTrace":
63
+ return renderAmendmentTrace(node.steps);
64
+ case "diagram":
65
+ return renderDiagram(node);
66
+ }
67
+ };
68
+ const renderAffordances = (affordances) => {
69
+ if (affordances.length === 0)
70
+ return "";
71
+ const items = affordances.map((a) => `<li class="focus-affordance" data-affordance="${escapeHtml(a.name)}" data-target="${escapeHtml(a.targetRef)}" aria-disabled="true"><del>${escapeHtml(a.label)}</del> <span class="focus-affordance-meta">${escapeHtml(a.name)} → ${escapeHtml(a.targetRef)} (disabled)</span></li>`);
72
+ return `<section class="focus-affordances"><h3>Affordances (read-only snapshot)</h3><ul>${items.join("")}</ul></section>`;
73
+ };
74
+ /** Render a decision-dossier document to a sanitized HTML string. */
75
+ export const renderHtml = (doc, hooks) => {
76
+ const header = `<header class="focus-header"><h1>${escapeHtml(doc.title)}</h1>` +
77
+ `<p class="focus-meta">subject: ${escapeHtml(doc.subject)} · ref: <code>${escapeHtml(doc.ref)}</code> · cursor: <code>${escapeHtml(doc.cursor)}</code></p></header>`;
78
+ const sections = doc.sections.map((node) => renderNode(node, hooks)).join("");
79
+ const amendment = renderAmendmentTrace(doc.amendmentTrace);
80
+ const affordances = renderAffordances(doc.interactions);
81
+ const html = `<article class="focus-document" data-ref="${escapeHtml(doc.ref)}">` +
82
+ header +
83
+ sections +
84
+ amendment +
85
+ affordances +
86
+ "</article>";
87
+ return hooks.sanitizeHtml(html);
88
+ };
89
+ //# sourceMappingURL=html.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"html.js","sourceRoot":"","sources":["../../../src/focus-vendor/render/html.js"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export function renderMd(doc: any, hooks?: {}): string;
2
+ //# sourceMappingURL=md.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"md.d.ts","sourceRoot":"","sources":["../../../src/focus-vendor/render/md.js"],"names":[],"mappings":"AA4DO,uDAaN"}
@@ -0,0 +1,75 @@
1
+ /**
2
+ * Markdown renderer (Focus-M1 L1).
3
+ *
4
+ * Renders a `DecisionDossierDocument` to a Markdown string. Read-only FocusSnapshot:
5
+ * affordances appear as disabled metadata; diagrams fall back to a FENCED code block
6
+ * (```mermaid / ```plantuml — no diagram adapter). Prose markdown is emitted verbatim
7
+ * (or passed through an optional host `renderMarkdown` hook for normalization).
8
+ */
9
+ const renderQuestion = (q) => {
10
+ const lines = [`**Q:** ${q.question} _(${q.state})_`];
11
+ if (q.recommendedAnswer !== undefined) {
12
+ lines.push(`- préco: ${q.recommendedAnswer}`);
13
+ }
14
+ if (q.answer !== undefined) {
15
+ lines.push(`- answer: ${q.answer}`);
16
+ }
17
+ return lines.join("\n");
18
+ };
19
+ const renderOptionSet = (s) => {
20
+ const head = s.title !== undefined ? `### Options — ${s.title}` : "### Options";
21
+ const opts = s.options.map((o) => {
22
+ const mark = o.annotation === "none" ? "[ ]" : `[${o.annotation}]`;
23
+ const comment = o.annotationComment !== undefined ? ` — ${o.annotationComment}` : "";
24
+ const body = o.body !== undefined ? `\n ${o.body}` : "";
25
+ return `- ${mark} **${o.label}**${comment}${body}`;
26
+ });
27
+ return [head, ...opts].join("\n");
28
+ };
29
+ const renderAmendmentTrace = (steps) => {
30
+ if (steps.length === 0)
31
+ return "### Amendment trace\n\n_(none)_";
32
+ const lines = steps.map((st, i) => `${i + 1}. \`${st.at}\` **${st.author}** — ${st.summary}`);
33
+ return ["### Amendment trace", "", ...lines].join("\n");
34
+ };
35
+ const renderDiagram = (d) => [`_${d.alt}_`, "", "```" + d.syntax, d.source, "```"].join("\n");
36
+ const renderNode = (node, hooks) => {
37
+ switch (node.kind) {
38
+ case "prose":
39
+ return hooks.renderMarkdown !== undefined
40
+ ? hooks.renderMarkdown(node.markdown)
41
+ : node.markdown;
42
+ case "question":
43
+ return renderQuestion(node);
44
+ case "optionSet":
45
+ return renderOptionSet(node);
46
+ case "outcome":
47
+ return `### Outcome (${node.modality})\n\n${node.statement}`;
48
+ case "amendmentTrace":
49
+ return renderAmendmentTrace(node.steps);
50
+ case "diagram":
51
+ return renderDiagram(node);
52
+ }
53
+ };
54
+ const renderAffordances = (affordances) => {
55
+ if (affordances.length === 0)
56
+ return "";
57
+ const lines = affordances.map((a) => `- ~~${a.label}~~ \`${a.name}\` → \`${a.targetRef}\` _(disabled)_`);
58
+ return ["### Affordances (read-only snapshot)", "", ...lines].join("\n");
59
+ };
60
+ /** Render a decision-dossier document to a Markdown string. */
61
+ export const renderMd = (doc, hooks = {}) => {
62
+ const blocks = [
63
+ `# ${doc.title}`,
64
+ `> subject: ${doc.subject} · ref: \`${doc.ref}\` · cursor: \`${doc.cursor}\``,
65
+ ];
66
+ for (const node of doc.sections) {
67
+ blocks.push(renderNode(node, hooks));
68
+ }
69
+ blocks.push(renderAmendmentTrace(doc.amendmentTrace));
70
+ const affordances = renderAffordances(doc.interactions);
71
+ if (affordances !== "")
72
+ blocks.push(affordances);
73
+ return blocks.join("\n\n") + "\n";
74
+ };
75
+ //# sourceMappingURL=md.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"md.js","sourceRoot":"","sources":["../../../src/focus-vendor/render/md.js"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export function renderTerminal(doc: any, opts?: {}): string;
2
+ //# sourceMappingURL=terminal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"terminal.d.ts","sourceRoot":"","sources":["../../../src/focus-vendor/render/terminal.js"],"names":[],"mappings":"AAgEO,4DAiBN"}
@@ -0,0 +1,83 @@
1
+ /**
2
+ * Terminal renderer (Focus-M1 L1).
3
+ *
4
+ * Renders a `DecisionDossierDocument` to a plain-text terminal string. Read-only FocusSnapshot:
5
+ * affordances appear as disabled metadata; diagrams fall back to text (no diagram adapter);
6
+ * markdown prose is emitted as-is (terminal has no markdown engine).
7
+ *
8
+ * Align the CLI/terminal render with ARCH-21 resource_terminal / RF11 renderer (no duplication):
9
+ * this stays a pure string builder with no ANSI/color side effects.
10
+ */
11
+ const rule = (width) => "=".repeat(Math.max(8, width));
12
+ const renderQuestion = (q) => {
13
+ const lines = [`Q: ${q.question} [${q.state}]`];
14
+ if (q.recommendedAnswer !== undefined) {
15
+ lines.push(` préco: ${q.recommendedAnswer}`);
16
+ }
17
+ if (q.answer !== undefined) {
18
+ lines.push(` answer: ${q.answer}`);
19
+ }
20
+ return lines.join("\n");
21
+ };
22
+ const renderOptionSet = (s) => {
23
+ const head = s.title !== undefined ? `Options — ${s.title}` : "Options";
24
+ const opts = s.options.map((o) => {
25
+ const mark = o.annotation === "none" ? "( )" : `(${o.annotation})`;
26
+ const comment = o.annotationComment !== undefined ? ` — ${o.annotationComment}` : "";
27
+ const body = o.body !== undefined ? `\n ${o.body}` : "";
28
+ return ` ${mark} ${o.label}${comment}${body}`;
29
+ });
30
+ return [head, ...opts].join("\n");
31
+ };
32
+ const renderAmendmentTrace = (steps) => {
33
+ if (steps.length === 0)
34
+ return "Amendment trace: (none)";
35
+ const lines = steps.map((st, i) => ` ${i + 1}. [${st.at}] ${st.author}: ${st.summary}`);
36
+ return ["Amendment trace:", ...lines].join("\n");
37
+ };
38
+ const renderDiagram = (d) => [
39
+ `Diagram (${d.syntax}) — ${d.alt}`,
40
+ ...d.source.split("\n").map((l) => ` | ${l}`),
41
+ ].join("\n");
42
+ const renderNode = (node) => {
43
+ switch (node.kind) {
44
+ case "prose":
45
+ return node.markdown;
46
+ case "question":
47
+ return renderQuestion(node);
48
+ case "optionSet":
49
+ return renderOptionSet(node);
50
+ case "outcome":
51
+ return `Outcome [${node.modality}]: ${node.statement}`;
52
+ case "amendmentTrace":
53
+ return renderAmendmentTrace(node.steps);
54
+ case "diagram":
55
+ return renderDiagram(node);
56
+ }
57
+ };
58
+ const renderAffordances = (affordances) => {
59
+ if (affordances.length === 0)
60
+ return "";
61
+ const lines = affordances.map((a) => ` [disabled] ${a.label} (${a.name} → ${a.targetRef})`);
62
+ return ["Affordances (read-only snapshot):", ...lines].join("\n");
63
+ };
64
+ /** Render a decision-dossier document to a terminal string. */
65
+ export const renderTerminal = (doc, opts = {}) => {
66
+ const width = opts.width ?? 72;
67
+ const blocks = [
68
+ rule(width),
69
+ `${doc.title}`,
70
+ `subject: ${doc.subject}`,
71
+ `ref: ${doc.ref} cursor: ${doc.cursor}`,
72
+ rule(width),
73
+ ];
74
+ for (const node of doc.sections) {
75
+ blocks.push(renderNode(node));
76
+ }
77
+ blocks.push(renderAmendmentTrace(doc.amendmentTrace));
78
+ const affordances = renderAffordances(doc.interactions);
79
+ if (affordances !== "")
80
+ blocks.push(affordances);
81
+ return blocks.join("\n\n") + "\n";
82
+ };
83
+ //# sourceMappingURL=terminal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"terminal.js","sourceRoot":"","sources":["../../../src/focus-vendor/render/terminal.js"],"names":[],"mappings":"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"}
@@ -0,0 +1,123 @@
1
+ /**
2
+ * The major-compatible `@sentropic/track/read` READ contract this binding was written against.
3
+ * The contract is additive-only within a major; we accept any matching major (gate below).
4
+ */
5
+ export const EXPECTED_TRACK_READ_MAJOR: 1;
6
+ /** Thrown when the installed `@sentropic/track/read` contract major is incompatible. */
7
+ export class TrackContractMismatchError extends Error {
8
+ constructor(actual: any, expectedMajor: any);
9
+ actual: any;
10
+ expectedMajor: any;
11
+ }
12
+ /** Thrown when a `decisionId` is not present (or not a decision) in the read log. */
13
+ export class DecisionNotFoundError extends Error {
14
+ constructor(decisionId: any);
15
+ decisionId: any;
16
+ }
17
+ export function toDecisionDossierDocument(view: any, amendmentTrace: any, meta: any): {
18
+ ref: any;
19
+ subject: any;
20
+ title: any;
21
+ hash: any;
22
+ cursor: any;
23
+ sections: ({
24
+ state: string;
25
+ answer?: any;
26
+ kind: string;
27
+ id: any;
28
+ targetRef: any;
29
+ question: any;
30
+ } | {
31
+ kind: string;
32
+ id: string;
33
+ targetRef: string;
34
+ markdown: any;
35
+ title?: never;
36
+ options?: never;
37
+ modality?: never;
38
+ statement?: never;
39
+ } | {
40
+ kind: string;
41
+ id: string;
42
+ targetRef: string;
43
+ title: string;
44
+ options: any;
45
+ markdown?: never;
46
+ modality?: never;
47
+ statement?: never;
48
+ } | {
49
+ kind: string;
50
+ id: string;
51
+ targetRef: string;
52
+ modality: string;
53
+ statement: string | undefined;
54
+ markdown?: never;
55
+ title?: never;
56
+ options?: never;
57
+ })[];
58
+ interactions: never[];
59
+ provenance: {
60
+ comprehensionEvidence?: {
61
+ signature?: any;
62
+ subject: any;
63
+ dossierHash: any;
64
+ };
65
+ source: any;
66
+ readAt: any;
67
+ };
68
+ amendmentTrace: any;
69
+ };
70
+ export function readDecisionDossier(eventsPath: any, query: any, readAt: any): {
71
+ ref: any;
72
+ subject: any;
73
+ title: any;
74
+ hash: any;
75
+ cursor: any;
76
+ sections: ({
77
+ state: string;
78
+ answer?: any;
79
+ kind: string;
80
+ id: any;
81
+ targetRef: any;
82
+ question: any;
83
+ } | {
84
+ kind: string;
85
+ id: string;
86
+ targetRef: string;
87
+ markdown: any;
88
+ title?: never;
89
+ options?: never;
90
+ modality?: never;
91
+ statement?: never;
92
+ } | {
93
+ kind: string;
94
+ id: string;
95
+ targetRef: string;
96
+ title: string;
97
+ options: any;
98
+ markdown?: never;
99
+ modality?: never;
100
+ statement?: never;
101
+ } | {
102
+ kind: string;
103
+ id: string;
104
+ targetRef: string;
105
+ modality: string;
106
+ statement: string | undefined;
107
+ markdown?: never;
108
+ title?: never;
109
+ options?: never;
110
+ })[];
111
+ interactions: never[];
112
+ provenance: {
113
+ comprehensionEvidence?: {
114
+ signature?: any;
115
+ subject: any;
116
+ dossierHash: any;
117
+ };
118
+ source: any;
119
+ readAt: any;
120
+ };
121
+ amendmentTrace: any;
122
+ };
123
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/focus-vendor/track/index.js"],"names":[],"mappings":"AAgBA;;;GAGG;AACH,wCAAyC,CAAC,CAAC;AAC3C,wFAAwF;AACxF;IAGI,6CAMC;IARD,YAAO;IACP,mBAAc;CAQjB;AACD,qFAAqF;AACrF;IAEI,6BAIC;IALD,gBAAW;CAMd;AA4HM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAyBN;AAYM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAmBN"}
@@ -0,0 +1,223 @@
1
+ /**
2
+ * `@sentropic/focus/track` — the read binding over `@sentropic/track/read` (Focus-M1 L2).
3
+ *
4
+ * Per SPEC_VOL_FOCUS §4b L2: binds the private `packages/focus` render-core to the REAL
5
+ * `@sentropic/track` read API, replacing L1's local `DecisionDossierViewFixture` type + mapper.
6
+ * A `TrackReader` read is PURE / read-only / clockless — NO auth, NO identity, NO clock (the L4
7
+ * write lot is where identity enters). This module:
8
+ * 1. reads a real `DecisionDossierView` from a track event log via
9
+ * `new TrackReader(eventsPath).canevas(workspace, { baselineCommit, decisionId }).dossier`,
10
+ * 2. reads the ordered `amendmentTrace(decisionId)` for the same decision,
11
+ * 3. maps both into the concrete L1 `DecisionDossierDocument`.
12
+ *
13
+ * It binds to the VERSIONED `@sentropic/track/read` subpath (NOT track's non-versioned barrel) and
14
+ * gates on `reader.contractVersion` (the additive-only READ contract — consumers gate on it).
15
+ */
16
+ import { TrackReader } from "@sentropic/track/read";
17
+ /**
18
+ * The major-compatible `@sentropic/track/read` READ contract this binding was written against.
19
+ * The contract is additive-only within a major; we accept any matching major (gate below).
20
+ */
21
+ export const EXPECTED_TRACK_READ_MAJOR = 1;
22
+ /** Thrown when the installed `@sentropic/track/read` contract major is incompatible. */
23
+ export class TrackContractMismatchError extends Error {
24
+ actual;
25
+ expectedMajor;
26
+ constructor(actual, expectedMajor) {
27
+ super(`@sentropic/track/read contract ${actual} is incompatible with focus/track ` +
28
+ `(expects major ${expectedMajor}.x)`);
29
+ this.actual = actual;
30
+ this.expectedMajor = expectedMajor;
31
+ this.name = "TrackContractMismatchError";
32
+ }
33
+ }
34
+ /** Thrown when a `decisionId` is not present (or not a decision) in the read log. */
35
+ export class DecisionNotFoundError extends Error {
36
+ decisionId;
37
+ constructor(decisionId) {
38
+ super(`decision ${decisionId} not found in the track read log`);
39
+ this.decisionId = decisionId;
40
+ this.name = "DecisionNotFoundError";
41
+ }
42
+ }
43
+ const majorOf = (version) => {
44
+ const major = Number.parseInt(version.split(".")[0] ?? "", 10);
45
+ return Number.isNaN(major) ? -1 : major;
46
+ };
47
+ /** A `track` `Outcome` ('pending'|'go'|'no-go'|'deferred') → the focus outcome statement. */
48
+ const outcomeStatement = (outcome) => {
49
+ switch (outcome) {
50
+ case "go":
51
+ return "GO — the decision is ratified.";
52
+ case "no-go":
53
+ return "NO-GO — the decision is declined.";
54
+ case "deferred":
55
+ return "DEFERRED — the decision is postponed.";
56
+ case "pending":
57
+ return "PENDING — the decision is not yet settled.";
58
+ }
59
+ };
60
+ /** Map an `Option` (id/title/summary/pros?/cons?) into the focus `optionSet` body text. */
61
+ const optionBody = (option) => {
62
+ const parts = [];
63
+ if (option.pros !== undefined && option.pros.length > 0) {
64
+ parts.push(`pros: ${option.pros.join("; ")}`);
65
+ }
66
+ if (option.cons !== undefined && option.cons.length > 0) {
67
+ parts.push(`cons: ${option.cons.join("; ")}`);
68
+ }
69
+ return parts.length > 0 ? parts.join("\n") : undefined;
70
+ };
71
+ /**
72
+ * Extract the comprehension evidence carried VERBATIM on the dossier's
73
+ * `kind:'h2a-decision-dossier'` artifacts. ComprehensionEvidence is NESTED (not a top-level
74
+ * sibling of the view): `dossier.artifacts[] → .comprehension[]`. We keep `subject` (the NAMED
75
+ * attester/decider) intact — it is DISTINCT from any channel principal that merely relayed the
76
+ * write (the anti-confused-deputy invariant: never launder the origin).
77
+ */
78
+ const collectComprehension = (dossier) => {
79
+ const out = [];
80
+ for (const artifact of dossier.artifacts ?? []) {
81
+ if (artifact.kind === "h2a-decision-dossier") {
82
+ for (const ev of artifact.comprehension ?? []) {
83
+ out.push(ev);
84
+ }
85
+ }
86
+ }
87
+ return out;
88
+ };
89
+ /** Map a track `ComprehensionEvidence` into the focus model's verbatim shape (subject intact). */
90
+ const toFocusComprehension = (ev) => ({
91
+ subject: ev.subject,
92
+ dossierHash: ev.dossierHash,
93
+ ...(ev.sig !== undefined ? { signature: ev.sig.value } : {}),
94
+ });
95
+ /** Map a track `AmendmentStep` (seq/at/by/kind/prov/origin/...) into the focus amendment step. */
96
+ const toFocusAmendmentStep = (step) => ({
97
+ at: step.at,
98
+ // `by` is the actor on whose behalf the write was recorded; `origin` ('human'|'machine')
99
+ // derives PURELY from `prov.proposed` — the machine origin is never laundered. We surface the
100
+ // origin alongside the actor so the rendered trace is honest about machine-proposed steps.
101
+ author: `${step.by} (${step.origin})`,
102
+ summary: step.summary ?? step.kind,
103
+ });
104
+ /**
105
+ * Build the focus `DecisionDossierDocument` sections from a real track `Dossier`:
106
+ * a `prose` context node, one `question` per QA entry (préco = recommendation rationale when it
107
+ * targets the answered option), an `optionSet` of the options, and a terminal `outcome` node.
108
+ */
109
+ const buildSections = (view) => {
110
+ const dossier = view.dossier;
111
+ const sections = [];
112
+ sections.push({
113
+ kind: "prose",
114
+ id: `${view.id}:context`,
115
+ targetRef: `${view.id}:context`,
116
+ markdown: dossier.context,
117
+ });
118
+ for (const qa of dossier.qa) {
119
+ sections.push(mapQa(view.id, qa));
120
+ }
121
+ if (dossier.options.length > 0) {
122
+ sections.push({
123
+ kind: "optionSet",
124
+ id: `${view.id}:options`,
125
+ targetRef: `${view.id}:options`,
126
+ title: "Options",
127
+ options: dossier.options.map((opt) => ({
128
+ kind: "option",
129
+ id: opt.id,
130
+ targetRef: opt.id,
131
+ label: opt.title,
132
+ ...(optionBody(opt) !== undefined ? { body: optionBody(opt) } : {}),
133
+ // The annotation reflects the dossier's selection/recommendation, NOT a live action:
134
+ // the selected option is 'accept'; the others are 'none' in this read-only snapshot.
135
+ annotation: opt.id === dossier.selectedOptionId ? "accept" : "none",
136
+ ...(dossier.recommendation?.optionId === opt.id
137
+ ? { annotationComment: dossier.recommendation.rationale }
138
+ : {}),
139
+ })),
140
+ });
141
+ }
142
+ sections.push({
143
+ kind: "outcome",
144
+ id: `${view.id}:outcome`,
145
+ targetRef: `${view.id}:outcome`,
146
+ modality: "decision",
147
+ statement: outcomeStatement(view.outcome),
148
+ });
149
+ return sections;
150
+ };
151
+ const mapQa = (decisionId, qa) => ({
152
+ kind: "question",
153
+ id: qa.id,
154
+ targetRef: qa.id,
155
+ question: qa.question,
156
+ ...(qa.answer !== undefined ? { answer: qa.answer } : {}),
157
+ // A QA entry carries no separate préco field in the track contract; an answered entry is
158
+ // 'answered', an open one is 'open'. (The validated state is only reachable via a live write.)
159
+ state: qa.answer !== undefined ? "answered" : "open",
160
+ });
161
+ /**
162
+ * Map a REAL track `DecisionDossierView` + its ordered `amendmentTrace` into the concrete L1
163
+ * `DecisionDossierDocument`. The comprehension evidence is carried VERBATIM from the nested
164
+ * `dossier.artifacts[] (kind:'h2a-decision-dossier').comprehension[]` (subject/hash/sig intact).
165
+ */
166
+ export const toDecisionDossierDocument = (view, amendmentTrace, meta) => {
167
+ const comprehension = collectComprehension(view.dossier);
168
+ const firstComprehension = comprehension[0];
169
+ return {
170
+ ref: view.id,
171
+ subject: view.workspace,
172
+ title: view.title,
173
+ // The dossier hash is the integrity tag the attester signed over; surface the first one as the
174
+ // snapshot hash when present, else fall back to the read cursor.
175
+ hash: firstComprehension?.dossierHash ?? meta.cursor,
176
+ cursor: meta.cursor,
177
+ sections: buildSections(view),
178
+ // The read is a snapshot: the affordances are surfaced disabled by the renderers; this binding
179
+ // does not invent live actions (those are L3+/L4). We leave interactions empty here — the
180
+ // canevas affordances are NOT laundered into the read-only doc.
181
+ interactions: [],
182
+ provenance: {
183
+ source: meta.source,
184
+ readAt: meta.readAt,
185
+ ...(firstComprehension !== undefined
186
+ ? { comprehensionEvidence: toFocusComprehension(firstComprehension) }
187
+ : {}),
188
+ },
189
+ amendmentTrace: amendmentTrace.map(toFocusAmendmentStep),
190
+ };
191
+ };
192
+ /**
193
+ * Read a real decision from a track event log and project it into a `DecisionDossierDocument`.
194
+ *
195
+ * PURE / read-only / clockless: the `readAt` timestamp is CALLER-supplied (track holds no clock),
196
+ * and no auth/identity is involved. The binding gates on `reader.contractVersion` (additive-only
197
+ * READ contract) and throws `TrackContractMismatchError` on an incompatible major.
198
+ *
199
+ * @param eventsPath path to the track event log (`.track/events.jsonl`)
200
+ * @param query workspace + baseline commit + decision id
201
+ * @param readAt caller-supplied ISO-8601 read timestamp (no clock in track)
202
+ */
203
+ export const readDecisionDossier = (eventsPath, query, readAt) => {
204
+ const reader = new TrackReader(eventsPath);
205
+ if (majorOf(reader.contractVersion) !== EXPECTED_TRACK_READ_MAJOR) {
206
+ throw new TrackContractMismatchError(reader.contractVersion, EXPECTED_TRACK_READ_MAJOR);
207
+ }
208
+ const canevas = reader.canevas(query.workspace, {
209
+ baselineCommit: query.baselineCommit,
210
+ decisionId: query.decisionId,
211
+ });
212
+ if (canevas.dossier === undefined) {
213
+ throw new DecisionNotFoundError(query.decisionId);
214
+ }
215
+ const amendmentTrace = reader.amendmentTrace(query.decisionId);
216
+ const cursor = reader.cursor();
217
+ return toDecisionDossierDocument(canevas.dossier, amendmentTrace, {
218
+ source: `track:${eventsPath}`,
219
+ readAt,
220
+ cursor: `count:${cursor.count}`,
221
+ });
222
+ };
223
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/focus-vendor/track/index.js"],"names":[],"mappings":"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"}