@sentropic/focus 0.3.0 → 0.5.0-rc.10

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 (97) hide show
  1. package/README.md +9 -0
  2. package/dist/cli/index.d.ts.map +1 -1
  3. package/dist/editing/anchors.d.ts +14 -0
  4. package/dist/editing/anchors.d.ts.map +1 -0
  5. package/dist/editing/anchors.js +113 -0
  6. package/dist/editing/anchors.js.map +1 -0
  7. package/dist/editing/codec.d.ts +24 -0
  8. package/dist/editing/codec.d.ts.map +1 -0
  9. package/dist/editing/codec.js +143 -0
  10. package/dist/editing/codec.js.map +1 -0
  11. package/dist/editing/contract.d.ts +129 -0
  12. package/dist/editing/contract.d.ts.map +1 -0
  13. package/dist/editing/contract.js +76 -0
  14. package/dist/editing/contract.js.map +1 -0
  15. package/dist/editing/diff.d.ts +12 -0
  16. package/dist/editing/diff.d.ts.map +1 -0
  17. package/dist/editing/diff.js +125 -0
  18. package/dist/editing/diff.js.map +1 -0
  19. package/dist/editing/digest.d.ts +6 -0
  20. package/dist/editing/digest.d.ts.map +1 -0
  21. package/dist/editing/digest.js +56 -0
  22. package/dist/editing/digest.js.map +1 -0
  23. package/dist/editing/index.d.ts +7 -0
  24. package/dist/editing/index.d.ts.map +1 -0
  25. package/dist/editing/index.js +7 -0
  26. package/dist/editing/index.js.map +1 -0
  27. package/dist/editing/reconcile.d.ts +66 -0
  28. package/dist/editing/reconcile.d.ts.map +1 -0
  29. package/dist/editing/reconcile.js +167 -0
  30. package/dist/editing/reconcile.js.map +1 -0
  31. package/dist/editing/structure.d.ts +24 -0
  32. package/dist/editing/structure.d.ts.map +1 -0
  33. package/dist/editing/structure.js +71 -0
  34. package/dist/editing/structure.js.map +1 -0
  35. package/dist/index.d.ts +4 -1
  36. package/dist/index.d.ts.map +1 -1
  37. package/dist/index.js +2 -0
  38. package/dist/index.js.map +1 -1
  39. package/dist/model.d.ts +144 -2
  40. package/dist/model.d.ts.map +1 -1
  41. package/dist/model.js +1 -1
  42. package/dist/model.js.map +1 -1
  43. package/dist/registry/definitions.d.ts +159 -0
  44. package/dist/registry/definitions.d.ts.map +1 -0
  45. package/dist/registry/definitions.js +509 -0
  46. package/dist/registry/definitions.js.map +1 -0
  47. package/dist/render/evidence.d.ts +10 -0
  48. package/dist/render/evidence.d.ts.map +1 -0
  49. package/dist/render/evidence.js +37 -0
  50. package/dist/render/evidence.js.map +1 -0
  51. package/dist/render/html.d.ts.map +1 -1
  52. package/dist/render/html.js +14 -1
  53. package/dist/render/html.js.map +1 -1
  54. package/dist/render/md.d.ts.map +1 -1
  55. package/dist/render/md.js +15 -1
  56. package/dist/render/md.js.map +1 -1
  57. package/dist/render/presentation.d.ts +4 -0
  58. package/dist/render/presentation.d.ts.map +1 -0
  59. package/dist/render/presentation.js +25 -0
  60. package/dist/render/presentation.js.map +1 -0
  61. package/dist/render/terminal.d.ts.map +1 -1
  62. package/dist/render/terminal.js +15 -1
  63. package/dist/render/terminal.js.map +1 -1
  64. package/dist/track/index.d.ts.map +1 -1
  65. package/dist/track/index.js +24 -10
  66. package/dist/track/index.js.map +1 -1
  67. package/dist/validation/evidence-bytes.d.ts +5 -0
  68. package/dist/validation/evidence-bytes.d.ts.map +1 -0
  69. package/dist/validation/evidence-bytes.js +57 -0
  70. package/dist/validation/evidence-bytes.js.map +1 -0
  71. package/dist/validation/evidence-shape.d.ts +12 -0
  72. package/dist/validation/evidence-shape.d.ts.map +1 -0
  73. package/dist/validation/evidence-shape.js +54 -0
  74. package/dist/validation/evidence-shape.js.map +1 -0
  75. package/dist/validation/evidence-sources.d.ts +7 -0
  76. package/dist/validation/evidence-sources.d.ts.map +1 -0
  77. package/dist/validation/evidence-sources.js +56 -0
  78. package/dist/validation/evidence-sources.js.map +1 -0
  79. package/dist/validation/evidence.d.ts +5 -0
  80. package/dist/validation/evidence.d.ts.map +1 -0
  81. package/dist/validation/evidence.js +131 -0
  82. package/dist/validation/evidence.js.map +1 -0
  83. package/dist/validation/index.d.ts +59 -0
  84. package/dist/validation/index.d.ts.map +1 -0
  85. package/dist/validation/index.js +500 -0
  86. package/dist/validation/index.js.map +1 -0
  87. package/dist/validation/readability.d.ts +28 -0
  88. package/dist/validation/readability.d.ts.map +1 -0
  89. package/dist/validation/readability.js +265 -0
  90. package/dist/validation/readability.js.map +1 -0
  91. package/package.json +36 -8
  92. package/registry/entries.v1.json +140 -0
  93. package/schemas/decision-dossier-document.v1.schema.json +193 -0
  94. package/schemas/decision-dossier-document.v2.schema.json +925 -0
  95. package/schemas/focus-edit-return.v1.schema.json +950 -0
  96. package/schemas/focus-editing-manifest.v1.schema.json +167 -0
  97. package/skills/focus/SKILL.md +181 -0
@@ -0,0 +1,167 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "urn:sentropic:focus:FocusEditingManifest:1.0.0",
4
+ "type": "object",
5
+ "additionalProperties": false,
6
+ "properties": {
7
+ "schemaVersion": {
8
+ "const": 1
9
+ },
10
+ "manifestId": {
11
+ "type": "string",
12
+ "minLength": 1
13
+ },
14
+ "documentRef": {
15
+ "type": "string",
16
+ "minLength": 1
17
+ },
18
+ "baseHash": {
19
+ "type": "string",
20
+ "pattern": "^sha256:[a-f0-9]{64}$"
21
+ },
22
+ "manifestBaseHash": {
23
+ "type": "string",
24
+ "pattern": "^sha256:[a-f0-9]{64}$"
25
+ },
26
+ "fields": {
27
+ "type": "array",
28
+ "items": {
29
+ "type": "object",
30
+ "additionalProperties": false,
31
+ "properties": {
32
+ "nodeId": {
33
+ "type": "string",
34
+ "minLength": 1
35
+ },
36
+ "targetRef": {
37
+ "type": "string",
38
+ "minLength": 1
39
+ },
40
+ "field": {
41
+ "enum": [
42
+ "markdown",
43
+ "question",
44
+ "recommendedAnswer",
45
+ "context",
46
+ "label",
47
+ "body",
48
+ "consequence"
49
+ ]
50
+ },
51
+ "contentFormat": {
52
+ "enum": [
53
+ "text/plain",
54
+ "focus.markdown.p0@1"
55
+ ]
56
+ },
57
+ "blockKind": {
58
+ "enum": [
59
+ "prose",
60
+ "question",
61
+ "option"
62
+ ]
63
+ }
64
+ },
65
+ "required": [
66
+ "nodeId",
67
+ "targetRef",
68
+ "field",
69
+ "contentFormat",
70
+ "blockKind"
71
+ ]
72
+ }
73
+ },
74
+ "paragraphs": {
75
+ "type": "array",
76
+ "items": {
77
+ "type": "object",
78
+ "additionalProperties": false,
79
+ "properties": {
80
+ "nodeId": {
81
+ "type": "string",
82
+ "minLength": 1
83
+ },
84
+ "targetRef": {
85
+ "type": "string",
86
+ "minLength": 1
87
+ },
88
+ "field": {
89
+ "enum": [
90
+ "markdown",
91
+ "question",
92
+ "recommendedAnswer",
93
+ "context",
94
+ "label",
95
+ "body",
96
+ "consequence"
97
+ ]
98
+ },
99
+ "paragraphId": {
100
+ "type": "string",
101
+ "minLength": 1
102
+ },
103
+ "blockKind": {
104
+ "const": "paragraph"
105
+ },
106
+ "parentId": {
107
+ "type": "null"
108
+ },
109
+ "order": {
110
+ "type": "integer",
111
+ "minimum": 0
112
+ },
113
+ "range": {
114
+ "type": "object",
115
+ "additionalProperties": false,
116
+ "properties": {
117
+ "start": {
118
+ "type": "integer",
119
+ "minimum": 0
120
+ },
121
+ "end": {
122
+ "type": "integer",
123
+ "minimum": 0
124
+ },
125
+ "unit": {
126
+ "const": "utf16"
127
+ }
128
+ },
129
+ "required": [
130
+ "start",
131
+ "end",
132
+ "unit"
133
+ ]
134
+ }
135
+ },
136
+ "required": [
137
+ "nodeId",
138
+ "targetRef",
139
+ "field",
140
+ "paragraphId",
141
+ "blockKind",
142
+ "parentId",
143
+ "order",
144
+ "range"
145
+ ]
146
+ }
147
+ },
148
+ "retiredParagraphIds": {
149
+ "type": "array",
150
+ "items": {
151
+ "type": "string",
152
+ "minLength": 1
153
+ },
154
+ "uniqueItems": true
155
+ }
156
+ },
157
+ "required": [
158
+ "schemaVersion",
159
+ "manifestId",
160
+ "documentRef",
161
+ "baseHash",
162
+ "manifestBaseHash",
163
+ "fields",
164
+ "paragraphs",
165
+ "retiredParagraphIds"
166
+ ]
167
+ }
@@ -0,0 +1,181 @@
1
+ ---
2
+ name: focus
3
+ version: 2.0.0
4
+ description: Prepare and review readable decision dossiers that trace the owner's request, expose real stakes and offer short explicit choices. Read-only snapshots; no decisions, signatures, amendments or Track writes.
5
+ category: decision
6
+ tools: []
7
+ ---
8
+
9
+ # Focus — help the owner make a real decision
10
+
11
+ Method capability: `sentropic.focus.decision-dossier`. Prepare a
12
+ `DecisionDossierDocument` using schema
13
+ `urn:sentropic:focus:DecisionDossierDocument:1.0.0`
14
+ (`schemas/decision-dossier-document.v1.schema.json`). This instruction-only
15
+ skill grants no tools or write authority.
16
+
17
+ For supporting evidence, select the explicit v2 template with the freshly built
18
+ checkout CLI: `node packages/h2a/dist/bin.js focus template --evidence -o dossier.json`,
19
+ then `node packages/h2a/dist/bin.js focus build dossier.json -o dossier.html`.
20
+ It declares `schemaVersion: 2` and uses the separate schema
21
+ `urn:sentropic:focus:DecisionDossierDocument:2.0.0`. Omitting the discriminant
22
+ selects unchanged v1. Old consumers refuse v2; never strip evidence to bypass that.
23
+ Store original bytes once in `sources` (canonical base64, original SHA-256 and byte
24
+ size). Origins are frozen provenance data, never URLs/paths fetched by the reader.
25
+ Use typed `citations`, section/option `citationRefs`, `evidenceGroups`, and collapsed
26
+ `annexes`; keep choices, material risks and reservations in the primary decision.
27
+ Summaries consume its reading budget; raw evidence volume and estimated consultation
28
+ are disclosed separately. Hashes prove byte identity, not truth or owner approval.
29
+ Embedded H1 supports offline text/capture consultation, complete-source search,
30
+ original download and return to context. It does not advertise H2 DS geometry/CDN
31
+ or H3 linked exploration. DS owns renderer controls inside the canvas; Focus
32
+ declares choices/reference bindings. Do not author coordinates or invent a toolbar.
33
+
34
+ A dossier serves the owner's intention. Ask the owner to choose a path or
35
+ manage a real problem whose risk concerns them. Handle routine technical
36
+ implementation within existing authority. Double review must find missing
37
+ context, hidden commitments and risks; it must also cut jargon and unnecessary
38
+ questions. It is not a reason to produce a longer dossier.
39
+
40
+ ## Prepare a dossier the owner can read on its own
41
+
42
+ - Write `title` and `subject` as non-empty single lines of at most 100
43
+ characters. Name the concrete subject and what the owner must decide:
44
+ “Garden shed — choose its location”, not “Ratify the plan”. Review their
45
+ meaning against the request; the gate checks length and form, not meaning.
46
+ - Quote the owner's literal request in `readability.ownerRequestQuote`.
47
+ Preserve their words and trace how the questions serve them. Never invent
48
+ a quotation. If no request exists, set `noOwnerRequest: true`; this blocks
49
+ presentation until the request is established. Do not combine it with a quote.
50
+ - State the scope and why it matters to the owner in `readability.stakes`:
51
+ cost, disruption, consequences, reversibility. Declare `stakesLevel`: `low`
52
+ for a small reversible inconvenience, `medium` for meaningful cost or
53
+ disruption, `high` for lasting, contractual or major personal impact.
54
+ - Set `readingBudgetMinutes` proportionately: at most 2 / 8 / 30 minutes for
55
+ low / medium / high stakes, including shared context and glossary. These
56
+ caps are defaults, not permission to inflate the stakes or fill the budget.
57
+ - Each question needs representative `context`, 2–4 short options, a
58
+ `recommendedOptionId`, and a short reason in `recommendedAnswer`. Context
59
+ must explain the situation, scope and trade-off without making the reader
60
+ chase another document or decode an identifier.
61
+ Keep questions and recommendations to one line of at most 300 characters,
62
+ option-set titles to 100. No nested lists or inline a/b branches.
63
+ - Each option needs a one-line `consequence` for the owner. Labels are at most
64
+ 100 characters, consequences 160, optional bodies/comments 300. Keep them
65
+ flat: no nested lists, inline a/b branches or multiple decisions in one
66
+ option. Move essential explanation to question context.
67
+ - Estimate `readingTimeMinutes` for each question, context and options together:
68
+ positive and at most 2 minutes. The gate checks a 180-word/minute lower bound.
69
+ Allow time to understand the trade-off, not just pronounce the words. Shorten
70
+ or split long questions; never understate the time to pass the gate.
71
+ - Every option set names its `questionId`; every decision, orientation or
72
+ amendment outcome names the question it resolves. Choice-bearing prose also
73
+ names its question. Audit *every* implied commitment, including defaults,
74
+ rollout, spending and permissions. Split independent commitments into explicit
75
+ questions. A reference alone does not prove that the question covers the text.
76
+ - Prefer plain words to codes such as `L06b`, `MH-L3`, `R5` or build identifiers,
77
+ and to unexplained acronyms. If necessary, define each term in
78
+ `readability.glossary` with a meaning the owner understands. The renderers show
79
+ this glossary. Each definition must stand alone in plain words, with no
80
+ self-reference or other code, even one defined elsewhere in the glossary.
81
+
82
+ Bad: “Ratify L06b under MH-L3? A: migrate, with a/b variants. B: defer.”
83
+ The request, stakes, consequences and recommendation are missing; several
84
+ choices are hidden behind codes.
85
+
86
+ Good (about one minute):
87
+ > Your request: “Keep the garden shed handy without spoiling the terrace view.”
88
+ > Stakes: the wrong spot means a longer walk every week or a blocked view for years.
89
+ > Question: where should the shed go? The permit covers both spots; only comfort differs.
90
+ > Side wall: a short walk and a clear terrace view.
91
+ > Back of garden: a longer walk, invisible from the house.
92
+ > Recommendation: side wall, because it meets both parts of your request.
93
+
94
+ Encode the good example as one question, two linked options, the recommended
95
+ option's id and reason, the literal quote and stakes, a declared stakes level,
96
+ and reading estimates. Let the renderer arrange the supplied questions/options;
97
+ never hand-author four parallel walls of text or imply that snapshot cards are
98
+ clickable.
99
+
100
+ ## Validate before presentation
101
+
102
+ Use `validateDecisionDossierForPresentation` (or its throwing counterpart
103
+ `assertDecisionDossierForPresentation`) from `@sentropic/focus/validate`.
104
+ The three public renderers enforce this gate before invoking host hooks.
105
+ Refusals carry a field path, code and an actionable explanation. Correct the
106
+ content and present the complete dossier; do not silently omit refused material.
107
+
108
+ New fields stay optional in schema version 1 so historical data still parses
109
+ through `validateDecisionDossierDocument`. Structural validity is insufficient
110
+ for presentation. Legacy Track projections lacking readability information are
111
+ blocked; never synthesize an owner request to make them pass. New Track dossiers
112
+ carry `subject`, `readability`, `questionId` for shared context/outcome, and
113
+ question context, reading time and recommendation on `qa`. Each option summary
114
+ is its consequence; `options[].questionId` overrides the shared question link
115
+ when a dossier contains several questions.
116
+
117
+ The gate checks structure, code definitions, reading lengths and explicit links.
118
+ It cannot prove a quotation is authentic, prose is clear, stakes are honest,
119
+ or every semantic choice has been exposed. Author and reviewer must verify
120
+ those properties against the request. Review should reduce the owner's reading
121
+ burden while preserving the real stakes and every relevant choice.
122
+
123
+ ## Host parameters and presentation availability
124
+
125
+ Closed parameters: `mode: "snapshot"`; `preferredPresentation` is `terminal`,
126
+ `markdown`, `html` or `mcp-app`; `locale` is `en` or `fr`. Defaults:
127
+ `snapshot` / `markdown` / `en`. Unknown keys refuse. Parameters choose presentation
128
+ and instruction selection; they do not change content or authority.
129
+
130
+ Terminal and Markdown are always available. HTML requires the host sanitization
131
+ hook. `mcp-app` requires registered, selected **and qualified** `sentropic.h2a.ui`.
132
+ Otherwise refuse with `unsupported_presentation` before reading any instruction;
133
+ never silently change the requested presentation.
134
+
135
+ ## Snapshot and provenance boundaries
136
+
137
+ `interactions[].enabled` is always `false`; never act on an affordance or present
138
+ it as available. Live decisions, signatures, amendments and Track writes require
139
+ separately qualified capabilities and current human authority.
140
+
141
+ Carry `provenance.comprehensionEvidence` (subject, dossier hash, signature)
142
+ verbatim. Never regenerate it or substitute a relay principal for the named
143
+ subject. `provenance.source` is an opaque read-backend binding; never infer
144
+ authority or invent filesystem paths from it.
145
+
146
+ Markdown conversion and HTML sanitization are explicit host hooks. Unsupported
147
+ nodes, unknown fields, enabled interactions, duplicate ids, unresolved targets
148
+ and forged evidence refuse with field diagnostics; never render an incomplete
149
+ dossier as complete.
150
+
151
+ ## Manual edit-return preview (separate from snapshot authority)
152
+
153
+ The new `@sentropic/focus/editing` subpath defines versioned sidecar manifests,
154
+ paragraph diffs and a pure reconciler. The portable editor is not qualified yet:
155
+ it awaits the published DS `RichTextEditor`, then offline browser/distribution
156
+ and reactivity gates. Do not advertise snapshot cards as editable.
157
+
158
+ Before an editable production, retain its exact source, manifest and opaque
159
+ producer/generation/request references. The checkout command
160
+ `node packages/h2a/dist/bin.js focus feedback retain <source.json> --state <dir>
161
+ --producer <id> --generation <id> --request <id>` prepares that manual state.
162
+ Only an explicitly selected state/source is authoritative; never open paths from
163
+ `provenance.source`, notes or the return payload.
164
+
165
+ Within the consumer's existing mandate, manually consume a complete return with
166
+ `focus feedback apply <return.json|yaml> --state <dir>`. Validate version, digest,
167
+ correlation and baseline mapping; re-read the current source, then check the
168
+ durable lineage before paragraph preconditions. Keep exact wording and notes.
169
+ An empty superseding return can revoke earlier corrections. Late superseded,
170
+ forked or order-indeterminate returns cannot resurrect them. Preserve drafts on
171
+ conflict; distinguish processed, source-applied, rebuilt and recorded in Track.
172
+ Receipts identify the consumed return/changes and actual source digests; replay
173
+ also identifies the previous outcome.
174
+
175
+ This preview publishes source JSON under a cooperating single-writer lock and
176
+ journal. It does not rebuild presentation or write Track. Revalidate/rebuild the
177
+ new presentation separately before presenting it. Original comprehension
178
+ evidence remains evidence about the original version. Live routing, amendment
179
+ translation, snapshot registry edit capabilities and policy defaults remain
180
+ unqualified; this skill grants no additional tool or write authority. Details:
181
+ `docs/focus/document-editing.md` in the source repository.