@sentropic/focus 0.3.0 → 0.5.0-rc.3
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 +9 -0
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/model.d.ts +73 -1
- package/dist/model.d.ts.map +1 -1
- package/dist/registry/definitions.d.ts +159 -0
- package/dist/registry/definitions.d.ts.map +1 -0
- package/dist/registry/definitions.js +501 -0
- package/dist/registry/definitions.js.map +1 -0
- package/dist/render/html.d.ts.map +1 -1
- package/dist/render/html.js +12 -1
- package/dist/render/html.js.map +1 -1
- package/dist/render/md.d.ts.map +1 -1
- package/dist/render/md.js +12 -1
- package/dist/render/md.js.map +1 -1
- package/dist/render/presentation.d.ts +4 -0
- package/dist/render/presentation.d.ts.map +1 -0
- package/dist/render/presentation.js +25 -0
- package/dist/render/presentation.js.map +1 -0
- package/dist/render/terminal.d.ts.map +1 -1
- package/dist/render/terminal.js +12 -1
- package/dist/render/terminal.js.map +1 -1
- package/dist/track/index.d.ts.map +1 -1
- package/dist/track/index.js +24 -10
- package/dist/track/index.js.map +1 -1
- package/dist/validation/index.d.ts +59 -0
- package/dist/validation/index.d.ts.map +1 -0
- package/dist/validation/index.js +490 -0
- package/dist/validation/index.js.map +1 -0
- package/dist/validation/readability.d.ts +28 -0
- package/dist/validation/readability.d.ts.map +1 -0
- package/dist/validation/readability.js +244 -0
- package/dist/validation/readability.js.map +1 -0
- package/package.json +25 -8
- package/registry/entries.v1.json +127 -0
- package/schemas/decision-dossier-document.v1.schema.json +193 -0
- package/skills/focus/SKILL.md +132 -0
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "urn:sentropic:focus:DecisionDossierDocument:1.0.0",
|
|
4
|
+
"title": "DecisionDossierDocument",
|
|
5
|
+
"description": "Read-only decision-dossier snapshot published by @sentropic/focus. Closed: unknown fields refuse. Snapshot interactions are disabled metadata (enabled:false); live decisions, signatures and amendments require separately qualified runtime capabilities.",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"additionalProperties": false,
|
|
8
|
+
"required": ["ref", "subject", "title", "hash", "cursor", "sections", "interactions", "provenance", "amendmentTrace"],
|
|
9
|
+
"properties": {
|
|
10
|
+
"ref": { "type": "string" },
|
|
11
|
+
"subject": { "type": "string" },
|
|
12
|
+
"title": { "type": "string" },
|
|
13
|
+
"hash": { "type": "string" },
|
|
14
|
+
"cursor": { "type": "string" },
|
|
15
|
+
"sections": { "type": "array", "items": { "$ref": "#/$defs/section" } },
|
|
16
|
+
"interactions": { "type": "array", "items": { "$ref": "#/$defs/interaction" } },
|
|
17
|
+
"provenance": { "$ref": "#/$defs/provenance" },
|
|
18
|
+
"amendmentTrace": { "type": "array", "items": { "$ref": "#/$defs/amendmentStep" } },
|
|
19
|
+
"readability": { "$ref": "#/$defs/readability" }
|
|
20
|
+
},
|
|
21
|
+
"$defs": {
|
|
22
|
+
"readability": {
|
|
23
|
+
"type": "object",
|
|
24
|
+
"additionalProperties": false,
|
|
25
|
+
"properties": {
|
|
26
|
+
"ownerRequestQuote": { "type": "string" },
|
|
27
|
+
"noOwnerRequest": { "type": "boolean" },
|
|
28
|
+
"stakes": { "type": "string" },
|
|
29
|
+
"stakesLevel": { "enum": ["low", "medium", "high"] },
|
|
30
|
+
"readingBudgetMinutes": { "type": "number" },
|
|
31
|
+
"glossary": { "type": "array", "items": { "$ref": "#/$defs/glossaryEntry" } }
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
"glossaryEntry": {
|
|
35
|
+
"type": "object",
|
|
36
|
+
"additionalProperties": false,
|
|
37
|
+
"required": ["term", "definition"],
|
|
38
|
+
"properties": {
|
|
39
|
+
"term": { "type": "string" },
|
|
40
|
+
"definition": { "type": "string" }
|
|
41
|
+
}
|
|
42
|
+
},
|
|
43
|
+
"section": {
|
|
44
|
+
"oneOf": [
|
|
45
|
+
{ "$ref": "#/$defs/proseNode" },
|
|
46
|
+
{ "$ref": "#/$defs/questionNode" },
|
|
47
|
+
{ "$ref": "#/$defs/optionSetNode" },
|
|
48
|
+
{ "$ref": "#/$defs/outcomeNode" },
|
|
49
|
+
{ "$ref": "#/$defs/amendmentTraceNode" },
|
|
50
|
+
{ "$ref": "#/$defs/diagramNode" }
|
|
51
|
+
]
|
|
52
|
+
},
|
|
53
|
+
"proseNode": {
|
|
54
|
+
"type": "object",
|
|
55
|
+
"additionalProperties": false,
|
|
56
|
+
"required": ["kind", "id", "targetRef", "markdown"],
|
|
57
|
+
"properties": {
|
|
58
|
+
"kind": { "const": "prose" },
|
|
59
|
+
"id": { "type": "string" },
|
|
60
|
+
"targetRef": { "type": "string" },
|
|
61
|
+
"markdown": { "type": "string" },
|
|
62
|
+
"questionId": { "type": "string" }
|
|
63
|
+
}
|
|
64
|
+
},
|
|
65
|
+
"questionNode": {
|
|
66
|
+
"type": "object",
|
|
67
|
+
"additionalProperties": false,
|
|
68
|
+
"required": ["kind", "id", "targetRef", "question", "state"],
|
|
69
|
+
"properties": {
|
|
70
|
+
"kind": { "const": "question" },
|
|
71
|
+
"id": { "type": "string" },
|
|
72
|
+
"targetRef": { "type": "string" },
|
|
73
|
+
"question": { "type": "string" },
|
|
74
|
+
"recommendedAnswer": { "type": "string" },
|
|
75
|
+
"answer": { "type": "string" },
|
|
76
|
+
"state": { "enum": ["open", "answered", "validated"] },
|
|
77
|
+
"context": { "type": "string" },
|
|
78
|
+
"readingTimeMinutes": { "type": "number" },
|
|
79
|
+
"recommendedOptionId": { "type": "string" }
|
|
80
|
+
}
|
|
81
|
+
},
|
|
82
|
+
"optionNode": {
|
|
83
|
+
"type": "object",
|
|
84
|
+
"additionalProperties": false,
|
|
85
|
+
"required": ["kind", "id", "targetRef", "label", "annotation"],
|
|
86
|
+
"properties": {
|
|
87
|
+
"kind": { "const": "option" },
|
|
88
|
+
"id": { "type": "string" },
|
|
89
|
+
"targetRef": { "type": "string" },
|
|
90
|
+
"label": { "type": "string" },
|
|
91
|
+
"body": { "type": "string" },
|
|
92
|
+
"annotation": { "enum": ["none", "accept", "reject", "comment"] },
|
|
93
|
+
"annotationComment": { "type": "string" },
|
|
94
|
+
"consequence": { "type": "string" }
|
|
95
|
+
}
|
|
96
|
+
},
|
|
97
|
+
"optionSetNode": {
|
|
98
|
+
"type": "object",
|
|
99
|
+
"additionalProperties": false,
|
|
100
|
+
"required": ["kind", "id", "targetRef", "options"],
|
|
101
|
+
"properties": {
|
|
102
|
+
"kind": { "const": "optionSet" },
|
|
103
|
+
"id": { "type": "string" },
|
|
104
|
+
"targetRef": { "type": "string" },
|
|
105
|
+
"title": { "type": "string" },
|
|
106
|
+
"options": { "type": "array", "items": { "$ref": "#/$defs/optionNode" } },
|
|
107
|
+
"questionId": { "type": "string" }
|
|
108
|
+
}
|
|
109
|
+
},
|
|
110
|
+
"outcomeNode": {
|
|
111
|
+
"type": "object",
|
|
112
|
+
"additionalProperties": false,
|
|
113
|
+
"required": ["kind", "id", "targetRef", "modality", "statement"],
|
|
114
|
+
"properties": {
|
|
115
|
+
"kind": { "const": "outcome" },
|
|
116
|
+
"id": { "type": "string" },
|
|
117
|
+
"targetRef": { "type": "string" },
|
|
118
|
+
"modality": { "enum": ["decision", "orientation", "amendment", "comment"] },
|
|
119
|
+
"statement": { "type": "string" },
|
|
120
|
+
"questionId": { "type": "string" }
|
|
121
|
+
}
|
|
122
|
+
},
|
|
123
|
+
"amendmentTraceNode": {
|
|
124
|
+
"type": "object",
|
|
125
|
+
"additionalProperties": false,
|
|
126
|
+
"required": ["kind", "id", "targetRef", "steps"],
|
|
127
|
+
"properties": {
|
|
128
|
+
"kind": { "const": "amendmentTrace" },
|
|
129
|
+
"id": { "type": "string" },
|
|
130
|
+
"targetRef": { "type": "string" },
|
|
131
|
+
"steps": { "type": "array", "items": { "$ref": "#/$defs/amendmentStep" } }
|
|
132
|
+
}
|
|
133
|
+
},
|
|
134
|
+
"diagramNode": {
|
|
135
|
+
"type": "object",
|
|
136
|
+
"additionalProperties": false,
|
|
137
|
+
"required": ["kind", "id", "targetRef", "syntax", "source", "alt"],
|
|
138
|
+
"properties": {
|
|
139
|
+
"kind": { "const": "diagram" },
|
|
140
|
+
"id": { "type": "string" },
|
|
141
|
+
"targetRef": { "type": "string" },
|
|
142
|
+
"syntax": { "enum": ["mermaid", "plantuml"] },
|
|
143
|
+
"source": { "type": "string" },
|
|
144
|
+
"alt": { "type": "string" },
|
|
145
|
+
"scene": {
|
|
146
|
+
"type": "object",
|
|
147
|
+
"description": "diagram-core SemanticDocument, profile generic@1, without views, geometry or layout hints. Opaque JSON until the design-system publishes its authoritative schema; no Focus-specific scene model."
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
},
|
|
151
|
+
"interaction": {
|
|
152
|
+
"type": "object",
|
|
153
|
+
"additionalProperties": false,
|
|
154
|
+
"required": ["name", "targetRef", "label", "enabled"],
|
|
155
|
+
"properties": {
|
|
156
|
+
"name": { "type": "string" },
|
|
157
|
+
"targetRef": { "type": "string" },
|
|
158
|
+
"label": { "type": "string" },
|
|
159
|
+
"enabled": { "const": false }
|
|
160
|
+
}
|
|
161
|
+
},
|
|
162
|
+
"comprehensionEvidence": {
|
|
163
|
+
"type": "object",
|
|
164
|
+
"additionalProperties": false,
|
|
165
|
+
"required": ["subject", "dossierHash"],
|
|
166
|
+
"properties": {
|
|
167
|
+
"subject": { "type": "string" },
|
|
168
|
+
"dossierHash": { "type": "string" },
|
|
169
|
+
"signature": { "type": "string" }
|
|
170
|
+
}
|
|
171
|
+
},
|
|
172
|
+
"provenance": {
|
|
173
|
+
"type": "object",
|
|
174
|
+
"additionalProperties": false,
|
|
175
|
+
"required": ["source", "readAt"],
|
|
176
|
+
"properties": {
|
|
177
|
+
"source": { "type": "string" },
|
|
178
|
+
"readAt": { "type": "string" },
|
|
179
|
+
"comprehensionEvidence": { "$ref": "#/$defs/comprehensionEvidence" }
|
|
180
|
+
}
|
|
181
|
+
},
|
|
182
|
+
"amendmentStep": {
|
|
183
|
+
"type": "object",
|
|
184
|
+
"additionalProperties": false,
|
|
185
|
+
"required": ["at", "author", "summary"],
|
|
186
|
+
"properties": {
|
|
187
|
+
"at": { "type": "string" },
|
|
188
|
+
"author": { "type": "string" },
|
|
189
|
+
"summary": { "type": "string" }
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: focus
|
|
3
|
+
version: 1.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
|
+
A dossier serves the owner's intention. Ask the owner to choose a path or
|
|
18
|
+
manage a real problem whose risk concerns them. Handle routine technical
|
|
19
|
+
implementation within existing authority. Double review must find missing
|
|
20
|
+
context, hidden commitments and risks; it must also cut jargon and unnecessary
|
|
21
|
+
questions. It is not a reason to produce a longer dossier.
|
|
22
|
+
|
|
23
|
+
## Prepare a dossier the owner can read on its own
|
|
24
|
+
|
|
25
|
+
- Write `title` and `subject` as non-empty single lines of at most 100
|
|
26
|
+
characters. Name the concrete subject and what the owner must decide:
|
|
27
|
+
“Garden shed — choose its location”, not “Ratify the plan”. Review their
|
|
28
|
+
meaning against the request; the gate checks length and form, not meaning.
|
|
29
|
+
- Quote the owner's literal request in `readability.ownerRequestQuote`.
|
|
30
|
+
Preserve their words and trace how the questions serve them. Never invent
|
|
31
|
+
a quotation. If no request exists, set `noOwnerRequest: true`; this blocks
|
|
32
|
+
presentation until the request is established. Do not combine it with a quote.
|
|
33
|
+
- State the scope and why it matters to the owner in `readability.stakes`:
|
|
34
|
+
cost, disruption, consequences, reversibility. Declare `stakesLevel`: `low`
|
|
35
|
+
for a small reversible inconvenience, `medium` for meaningful cost or
|
|
36
|
+
disruption, `high` for lasting, contractual or major personal impact.
|
|
37
|
+
- Set `readingBudgetMinutes` proportionately: at most 2 / 8 / 30 minutes for
|
|
38
|
+
low / medium / high stakes, including shared context and glossary. These
|
|
39
|
+
caps are defaults, not permission to inflate the stakes or fill the budget.
|
|
40
|
+
- Each question needs representative `context`, 2–4 short options, a
|
|
41
|
+
`recommendedOptionId`, and a short reason in `recommendedAnswer`. Context
|
|
42
|
+
must explain the situation, scope and trade-off without making the reader
|
|
43
|
+
chase another document or decode an identifier.
|
|
44
|
+
Keep questions and recommendations to one line of at most 300 characters,
|
|
45
|
+
option-set titles to 100. No nested lists or inline a/b branches.
|
|
46
|
+
- Each option needs a one-line `consequence` for the owner. Labels are at most
|
|
47
|
+
100 characters, consequences 160, optional bodies/comments 300. Keep them
|
|
48
|
+
flat: no nested lists, inline a/b branches or multiple decisions in one
|
|
49
|
+
option. Move essential explanation to question context.
|
|
50
|
+
- Estimate `readingTimeMinutes` for each question, context and options together:
|
|
51
|
+
positive and at most 2 minutes. The gate checks a 180-word/minute lower bound.
|
|
52
|
+
Allow time to understand the trade-off, not just pronounce the words. Shorten
|
|
53
|
+
or split long questions; never understate the time to pass the gate.
|
|
54
|
+
- Every option set names its `questionId`; every decision, orientation or
|
|
55
|
+
amendment outcome names the question it resolves. Choice-bearing prose also
|
|
56
|
+
names its question. Audit *every* implied commitment, including defaults,
|
|
57
|
+
rollout, spending and permissions. Split independent commitments into explicit
|
|
58
|
+
questions. A reference alone does not prove that the question covers the text.
|
|
59
|
+
- Prefer plain words to codes such as `L06b`, `MH-L3`, `R5` or build identifiers,
|
|
60
|
+
and to unexplained acronyms. If necessary, define each term in
|
|
61
|
+
`readability.glossary` with a meaning the owner understands. The renderers show
|
|
62
|
+
this glossary. Each definition must stand alone in plain words, with no
|
|
63
|
+
self-reference or other code, even one defined elsewhere in the glossary.
|
|
64
|
+
|
|
65
|
+
Bad: “Ratify L06b under MH-L3? A: migrate, with a/b variants. B: defer.”
|
|
66
|
+
The request, stakes, consequences and recommendation are missing; several
|
|
67
|
+
choices are hidden behind codes.
|
|
68
|
+
|
|
69
|
+
Good (about one minute):
|
|
70
|
+
> Your request: “Keep the garden shed handy without spoiling the terrace view.”
|
|
71
|
+
> Stakes: the wrong spot means a longer walk every week or a blocked view for years.
|
|
72
|
+
> Question: where should the shed go? The permit covers both spots; only comfort differs.
|
|
73
|
+
> Side wall: a short walk and a clear terrace view.
|
|
74
|
+
> Back of garden: a longer walk, invisible from the house.
|
|
75
|
+
> Recommendation: side wall, because it meets both parts of your request.
|
|
76
|
+
|
|
77
|
+
Encode the good example as one question, two linked options, the recommended
|
|
78
|
+
option's id and reason, the literal quote and stakes, a declared stakes level,
|
|
79
|
+
and reading estimates. Let the renderer arrange the supplied questions/options;
|
|
80
|
+
never hand-author four parallel walls of text or imply that snapshot cards are
|
|
81
|
+
clickable.
|
|
82
|
+
|
|
83
|
+
## Validate before presentation
|
|
84
|
+
|
|
85
|
+
Use `validateDecisionDossierForPresentation` (or its throwing counterpart
|
|
86
|
+
`assertDecisionDossierForPresentation`) from `@sentropic/focus/validate`.
|
|
87
|
+
The three public renderers enforce this gate before invoking host hooks.
|
|
88
|
+
Refusals carry a field path, code and an actionable explanation. Correct the
|
|
89
|
+
content and present the complete dossier; do not silently omit refused material.
|
|
90
|
+
|
|
91
|
+
New fields stay optional in schema version 1 so historical data still parses
|
|
92
|
+
through `validateDecisionDossierDocument`. Structural validity is insufficient
|
|
93
|
+
for presentation. Legacy Track projections lacking readability information are
|
|
94
|
+
blocked; never synthesize an owner request to make them pass. New Track dossiers
|
|
95
|
+
carry `subject`, `readability`, `questionId` for shared context/outcome, and
|
|
96
|
+
question context, reading time and recommendation on `qa`. Each option summary
|
|
97
|
+
is its consequence; `options[].questionId` overrides the shared question link
|
|
98
|
+
when a dossier contains several questions.
|
|
99
|
+
|
|
100
|
+
The gate checks structure, code definitions, reading lengths and explicit links.
|
|
101
|
+
It cannot prove a quotation is authentic, prose is clear, stakes are honest,
|
|
102
|
+
or every semantic choice has been exposed. Author and reviewer must verify
|
|
103
|
+
those properties against the request. Review should reduce the owner's reading
|
|
104
|
+
burden while preserving the real stakes and every relevant choice.
|
|
105
|
+
|
|
106
|
+
## Host parameters and presentation availability
|
|
107
|
+
|
|
108
|
+
Closed parameters: `mode: "snapshot"`; `preferredPresentation` is `terminal`,
|
|
109
|
+
`markdown`, `html` or `mcp-app`; `locale` is `en` or `fr`. Defaults:
|
|
110
|
+
`snapshot` / `markdown` / `en`. Unknown keys refuse. Parameters choose presentation
|
|
111
|
+
and instruction selection; they do not change content or authority.
|
|
112
|
+
|
|
113
|
+
Terminal and Markdown are always available. HTML requires the host sanitization
|
|
114
|
+
hook. `mcp-app` requires registered, selected **and qualified** `sentropic.h2a.ui`.
|
|
115
|
+
Otherwise refuse with `unsupported_presentation` before reading any instruction;
|
|
116
|
+
never silently change the requested presentation.
|
|
117
|
+
|
|
118
|
+
## Snapshot and provenance boundaries
|
|
119
|
+
|
|
120
|
+
`interactions[].enabled` is always `false`; never act on an affordance or present
|
|
121
|
+
it as available. Live decisions, signatures, amendments and Track writes require
|
|
122
|
+
separately qualified capabilities and current human authority.
|
|
123
|
+
|
|
124
|
+
Carry `provenance.comprehensionEvidence` (subject, dossier hash, signature)
|
|
125
|
+
verbatim. Never regenerate it or substitute a relay principal for the named
|
|
126
|
+
subject. `provenance.source` is an opaque read-backend binding; never infer
|
|
127
|
+
authority or invent filesystem paths from it.
|
|
128
|
+
|
|
129
|
+
Markdown conversion and HTML sanitization are explicit host hooks. Unsupported
|
|
130
|
+
nodes, unknown fields, enabled interactions, duplicate ids, unresolved targets
|
|
131
|
+
and forged evidence refuse with field diagnostics; never render an incomplete
|
|
132
|
+
dossier as complete.
|