@open-agent-toolkit/cli 0.2.30 → 0.2.31

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 (72) hide show
  1. package/assets/bundle-metadata.json +1 -1
  2. package/assets/docs/cli-utilities/configuration.md +41 -0
  3. package/assets/docs/contributing/code.md +19 -7
  4. package/assets/docs/contributing/explainer-kit-verification.md +9 -1
  5. package/assets/docs/contributing/skills.md +9 -0
  6. package/assets/docs/workflows/skills/explainer-kit-providers.md +16 -5
  7. package/assets/docs/workflows/skills/explainer-kit.md +98 -38
  8. package/assets/public-package-versions.json +4 -4
  9. package/assets/skills/explainer-kit/SKILL.md +33 -8
  10. package/assets/skills/explainer-kit/briefs/project-recap.md +25 -7
  11. package/assets/skills/explainer-kit/recipes/project-recap.v2.json +72 -0
  12. package/assets/skills/explainer-kit/references/contracts.md +49 -17
  13. package/assets/skills/explainer-kit/references/destination-contract.md +141 -25
  14. package/assets/skills/explainer-kit/references/extension-contract.md +19 -10
  15. package/assets/skills/explainer-kit/references/visual-authoring.md +24 -0
  16. package/assets/skills/explainer-kit/references/visual-review.md +19 -5
  17. package/assets/skills/explainer-kit/schemas/author-request.v3.schema.json +241 -0
  18. package/assets/skills/explainer-kit/schemas/publish-receipt.v2.schema.json +215 -0
  19. package/assets/skills/explainer-kit/schemas/publish-request.v2.schema.json +34 -0
  20. package/assets/skills/explainer-kit/schemas/run-request.schema.json +4 -1
  21. package/assets/skills/explainer-kit/schemas/terminal-evidence.v1.schema.json +81 -0
  22. package/assets/skills/explainer-kit/schemas/visual-review-evidence.v1.schema.json +66 -0
  23. package/assets/skills/explainer-kit/scripts/lib/catalog.mjs +109 -3
  24. package/assets/skills/explainer-kit/scripts/lib/contracts.mjs +550 -17
  25. package/assets/skills/explainer-kit/scripts/lib/durability.mjs +90 -8
  26. package/assets/skills/explainer-kit/scripts/lib/fs-safe.mjs +5 -0
  27. package/assets/skills/explainer-kit/scripts/lib/internal-references.mjs +538 -0
  28. package/assets/skills/explainer-kit/scripts/lib/package-coverage.mjs +129 -11
  29. package/assets/skills/explainer-kit/scripts/lib/publication-policy.mjs +54 -0
  30. package/assets/skills/explainer-kit/scripts/lib/recipes.mjs +2 -1
  31. package/assets/skills/explainer-kit/scripts/lib/records.mjs +139 -22
  32. package/assets/skills/explainer-kit/scripts/lib/s3-roots.mjs +353 -0
  33. package/assets/skills/explainer-kit/scripts/lib/s3-static.mjs +237 -107
  34. package/assets/skills/explainer-kit/scripts/lib/set-plan.mjs +1 -0
  35. package/assets/skills/explainer-kit/scripts/lib/terminal-evidence.mjs +157 -0
  36. package/assets/skills/explainer-kit/scripts/lib/visual-review.mjs +26 -6
  37. package/assets/skills/explainer-kit/scripts/run.mjs +1006 -144
  38. package/assets/skills/oat-explainer-kit/SKILL.md +16 -3
  39. package/assets/skills/oat-explainer-kit/references/config-contract.md +13 -8
  40. package/assets/skills/oat-explainer-kit/references/lifecycle-contract.md +50 -6
  41. package/assets/skills/oat-explainer-kit/references/migration.md +2 -1
  42. package/assets/skills/oat-explainer-kit/references/visual-review-callback.md +11 -0
  43. package/assets/skills/oat-explainer-kit/scripts/bind-project-sources.mjs +37 -15
  44. package/assets/skills/oat-explainer-kit/scripts/check-terminal-outcome.mjs +83 -0
  45. package/assets/skills/oat-explainer-kit/scripts/derive-destination.mjs +91 -0
  46. package/assets/skills/oat-explainer-kit/scripts/finalize-tracked-run.mjs +66 -10
  47. package/assets/skills/oat-explainer-kit/scripts/resolve-config.mjs +60 -21
  48. package/assets/skills/oat-explainer-kit/scripts/resolve-paths.mjs +52 -8
  49. package/assets/skills/oat-explainer-kit/scripts/run.mjs +271 -36
  50. package/assets/skills/oat-project-autonomous/references/gate-inventory.md +2 -2
  51. package/assets/skills/oat-project-complete/SKILL.md +19 -3
  52. package/assets/skills/oat-project-document/references/docs/autonomy-contract.md +2 -2
  53. package/assets/skills/oat-project-implement/references/completion-and-closeout.md +8 -0
  54. package/assets/skills/oat-project-implement/references/docs/autonomy-contract.md +2 -2
  55. package/assets/skills/oat-project-pr-final/references/docs/autonomy-contract.md +2 -2
  56. package/assets/skills/oat-project-quick-start/references/docs/autonomy-contract.md +2 -2
  57. package/dist/commands/config/index.d.ts.map +1 -1
  58. package/dist/commands/config/index.js +18 -0
  59. package/dist/commands/project/archive/archive-utils.d.ts.map +1 -1
  60. package/dist/commands/project/archive/archive-utils.js +57 -7
  61. package/dist/commands/project/archive/explainer-terminal-evidence.d.ts +29 -0
  62. package/dist/commands/project/archive/explainer-terminal-evidence.d.ts.map +1 -0
  63. package/dist/commands/project/archive/explainer-terminal-evidence.js +37 -0
  64. package/dist/config/oat-config.d.ts +2 -0
  65. package/dist/config/oat-config.d.ts.map +1 -1
  66. package/dist/config/oat-config.js +4 -0
  67. package/dist/config/resolve.d.ts.map +1 -1
  68. package/dist/config/resolve.js +1 -0
  69. package/package.json +2 -2
  70. /package/assets/skills/explainer-kit/recipes/{project-recap.json → project-recap.v1.json} +0 -0
  71. /package/assets/skills/explainer-kit/schemas/{publish-receipt.schema.json → publish-receipt.v1.schema.json} +0 -0
  72. /package/assets/skills/explainer-kit/schemas/{publish-request.schema.json → publish-request.v1.schema.json} +0 -0
@@ -34,25 +34,34 @@ Every run, interactive or unattended, also requires a provider-neutral author
34
34
  callback; a run without one fails `E_AUTHOR_REQUIRED`. An in-process caller
35
35
  supplies `options.author(request)`; a JSON-only CLI caller uses
36
36
  `--author-module author.mjs`. The core invokes it once per resolved artifact
37
- with an `explainer-kit.author-request/v2` payload containing the artifact
37
+ with an `explainer-kit.author-request/v3` payload containing the artifact
38
38
  identity and type, the artifact's authoring path, the inlined brief, the bundled
39
39
  `visualAuthoringGuidance`, the reconciled fact base, the resolved theme, the
40
40
  shell source for artistic artifacts, the required narrative sections for
41
- narrative floor artifacts, and bounded-discovery context. The guidance is
41
+ narrative floor artifacts, bounded-discovery context, and `artifactLinks`.
42
+ Each canonical link entry names the planned artifact, its explicit site-relative
43
+ path ending in `index.html`, and the relative `href` from the receiving
44
+ artifact's own location. The guidance is
42
45
  loaded only from the installed skill's `references/visual-authoring.md`; no
43
46
  ambient or home-directory file is consulted. The callback must return an
44
47
  `explainer-kit.author-result/v2` carrying exactly one of `content.markdown` or
45
48
  `content.html`, matching the artifact's declared authoring path, plus non-secret
46
49
  provenance. The executable callback is never persisted in `run-request.json`.
47
50
 
48
- Project recap requests have an explicit `recapMode`. Omitting it selects and
49
- persists `artistic`, which keeps the recipe's rich HTML floor. Selecting
50
- `deterministic-markdown` before the run applies the recipe-owned fallback to
51
- the complete planned portfolio, including optional expansions, while retaining
52
- the same adaptive hub, architecture, and deck identities. The resulting
53
- Markdown author records and `source/content/*.md` paths remain distinct in the
54
- manifest and immutable rebuild package. An artistic author failure fails the
55
- run; the core never silently retries or downgrades it as Markdown.
51
+ New project recap producers select immutable `project-recap@2`. Its
52
+ navigational hub is the only mandatory artifact. A diagram, deck, or deep dive
53
+ is an optional expansion only when its justification states a distinct reader
54
+ question, supporting source evidence, and the rationale for using that medium.
55
+ Project recap requests also have an explicit `recapMode`. Omitting it selects
56
+ and persists `artistic`, which keeps the recipe's rich HTML floor. Selecting
57
+ `deterministic-markdown` before the run applies the recipe-owned fallback to the
58
+ complete planned portfolio the hub plus any accepted expansions — without
59
+ changing its artifact identities. The resulting Markdown author records and
60
+ `source/content/*.md` paths remain distinct in the manifest and immutable
61
+ rebuild package. An artistic author failure fails the run; the core never
62
+ silently retries or downgrades it as Markdown. `project-recap@1` is immutable
63
+ replay guidance only: retained v1 requests remain readable, but current
64
+ producers do not select it.
56
65
 
57
66
  Before artifact authoring, a caller supplies one provider-neutral `planSet`
58
67
  callback. It receives the reconciled fact base and recipe policy and returns
@@ -62,7 +71,7 @@ callback. It receives the reconciled fact base and recipe policy and returns
62
71
  {
63
72
  "schemaVersion": "explainer-kit.set-plan/v1",
64
73
  "planId": "project-recap-set",
65
- "recipe": { "id": "project-recap", "version": "1" },
74
+ "recipe": { "id": "project-recap", "version": "2" },
66
75
  "sourceIds": ["plan"],
67
76
  "ledger": {
68
77
  "terminology": [],
@@ -87,9 +96,11 @@ The set plan owns the shared terminology/status/number ledger, source coverage,
87
96
  adaptive portfolio, per-artifact draft, and visual intent. Optional entries add
88
97
  a source-backed `justification`; undeclared sources, conflicting ledger values,
89
98
  duplicate artifact IDs, and unjustified optional entries are invalid. Each
90
- `author-request/v2` carries the complete immutable `setContext` plus the exact
99
+ `author-request/v3` carries the complete immutable `setContext` plus the exact
91
100
  matching `plannedArtifact`. The planner finalizes floor and expansion entries
92
101
  before authoring; author results cannot add, remove, or replace artifacts.
102
+ Version 2 requests remain valid for deterministic replay; new runs emit only
103
+ the complete v3 request.
93
104
  When a planner draft contains a supported non-linear graph, the request also
94
105
  carries its closed `graphSemantics` (direction, nodes, edges, and topology).
95
106
  Artistic HTML must expose one exact `data-direction`. Each planned node requires
@@ -183,12 +194,33 @@ The core executes:
183
194
  5. author every planned artifact against the same set context
184
195
  6. render typed artifacts through the narrative renderer or validate
185
196
  agent-composed HTML, per each artifact's declared authoring path
186
- 7. run structural and guideline QA, plus required browser and independent
197
+ 7. validate every post-render `href`, `src`, `srcset`, and embedded reference
198
+ against the manifest paths and generated site tree; reject directory links,
199
+ escapes, missing files or fragments, malformed references, and unsafe
200
+ embedded resources
201
+ 8. optionally apply one bounded author correction, then rerender and revalidate
202
+ the complete site before any browser callback
203
+ 9. run structural and guideline QA, plus required browser and independent
187
204
  visual review for unattended project recaps
188
- 8. close any unresolved recap review gate before external persistence
189
- 9. resolve content approval — the interactive gate pauses here, after render and
190
- QA and before anything is published or persisted externally
191
- 10. write the manifest and build record
205
+ 10. close any unresolved recap review gate before external persistence
206
+ 11. resolve content approval — the interactive gate pauses here, after render and
207
+ QA and before anything is published or persisted externally
208
+ 12. write the manifest and build record
209
+
210
+ The internal-reference gate uses a bounded tokenizer/classifier rather than a
211
+ general HTML parser. Relative references resolve from the current explicit file
212
+ with an isolated HTTPS base, then must bind exactly to the manifest/site tree.
213
+ Referenced fragments must resolve to exactly one ID in the target document;
214
+ unused duplicate renderer-generated IDs do not fail indexing. Safe base64 image
215
+ data references and same-document fragments are classified separately. A
216
+ malformed, unresolved, or ambiguous reference fails `E_INTERNAL_REFERENCE`.
217
+ Once the one correction is exhausted, including after visual correction, the run
218
+ fails hard: the QA stage is recorded `failed` with code-only evidence and the
219
+ scrubbed message `The qa stage failed.`, and the run is not durability- or
220
+ publication-eligible. No finding is retained and nothing names the broken
221
+ reference — terminal evidence is code-only by design, and the failure is
222
+ attributed to the `link-validation` evidence stage rather than to
223
+ `browser-review`.
192
224
 
193
225
  An incomplete interactive result includes
194
226
  `approval.resumeToken: "ekrt2:<64 lowercase hex characters>"`. The token is an
@@ -10,15 +10,39 @@ node scripts/publish.mjs \
10
10
  --confirm-publish
11
11
  ```
12
12
 
13
- The request uses `explainer-kit.publish-request/v1`. Credentials come only from
14
- the standard AWS credential chain or the request's optional profile. Never put
15
- access keys, secret keys, session tokens, or SSO tokens in a request.
16
-
17
- ## Corresponding roots
18
-
19
- `s3Uri` and `publicBaseUrl` must identify corresponding roots. Both are
20
- normalized without trailing slashes. For a path `P` relative to `siteRoot`, the
21
- connector writes `<s3Uri>/P` and verifies `<publicBaseUrl>/P`.
13
+ New requests use `explainer-kit.publish-request/v2` and explicitly declare
14
+ `publicAccess` as `public` or `protected`. V1 remains readable as public-mode
15
+ replay. Credentials come only from the standard AWS credential chain or the
16
+ request's optional profile. Never put access keys, secret keys, session tokens,
17
+ or SSO tokens in a request.
18
+
19
+ ## How the two roots compose
20
+
21
+ `s3Uri` and `publicBaseUrl` are each normalized without trailing slashes. For a
22
+ path `P` relative to `siteRoot`, the connector writes `<s3Uri>/P` and verifies
23
+ `<publicBaseUrl>/P`. That composition is the whole of the relationship.
24
+
25
+ **No relational validation is performed between the two roots, by design.** The
26
+ mapping from an S3 key to a public URL is underdetermined by these two strings:
27
+ it lives in CDN configuration the connector cannot read. Both of these are
28
+ legitimate, and they disagree structurally:
29
+
30
+ | Shape | `s3Uri` | `publicBaseUrl` |
31
+ | ----- | ---------------------------- | ----------------------------- |
32
+ | A | `s3://bucket/repositories/x` | `https://host/repositories/x` |
33
+ | B | `s3://bucket/explainers` | `https://host` |
34
+
35
+ B is an ordinary CloudFront **Origin Path** deployment, where a bucket prefix is
36
+ mapped to the distribution root. Requiring the public path to equal the S3 key
37
+ prefix rejects it. Suffix-containment does not rescue the rule either — an empty
38
+ public path is a suffix of everything, so B would pass vacuously while
39
+ path-rewriting deployments (CloudFront Functions, Lambda@Edge, custom origins)
40
+ still produce false rejections.
41
+
42
+ Divergence between the two paths is therefore reported as a **non-blocking
43
+ warning**, never a failure. Correctness of an advertised URL is established by
44
+ verification, not by string shape — which is also why `publicAccess: protected`,
45
+ where no anonymous fetch happens, cannot establish it at all.
22
46
 
23
47
  For example:
24
48
 
@@ -32,7 +56,39 @@ For example:
32
56
  | public URL | `https://cdn.example.com/published/initiatives/demo/index.html` |
33
57
 
34
58
  Use explicit `index.html` URLs. Directory redirects are not portable evidence.
35
- The destination must serve uploaded bytes at the corresponding public path.
59
+ The destination must serve the uploaded bytes at the composed public path. That
60
+ is a requirement on the deployment, not something the connector validates from
61
+ the two root strings; see below.
62
+
63
+ ## The manifest a connector receives is intentionally incomplete
64
+
65
+ The core persists the manifest **before** it invokes the publisher callback, so
66
+ the file at `manifestPath` carries `outcome: "incomplete"` while the `publish`
67
+ stage is still `running`. This is a contractually intended intermediate state,
68
+ not a corrupt or half-written record, and a connector must not reject it on the
69
+ strength of `outcome` alone.
70
+
71
+ Do not decide publishability from the manifest by itself. Read the build record
72
+ named by `manifest.buildRecord.path` (resolved relative to the manifest) and
73
+ require all of:
74
+
75
+ - the manifest carries no `visual-review-required:` warning;
76
+ - the build record's own `outcome` is `incomplete`;
77
+ - its `publish` stage exists and is `running`; and
78
+ - every stage before `publish` is `passed`, `warned`, or `skipped` and carries
79
+ no `visual-review-required:` warning.
80
+
81
+ Only that combination makes an `incomplete` manifest publishable. The one other
82
+ eligible shape is a finalized `built-durable` manifest that is not
83
+ review-flagged. Any other `incomplete` manifest, and every manifest whose run is
84
+ flagged, failed, or superseded, must be refused. The built-in connector performs
85
+ exactly this check before its first network call; third-party connectors are
86
+ required to perform an equivalent one.
87
+
88
+ The published bytes cannot diverge from the finalized manifest: the catalog
89
+ projection omits `outcome` and `warnings`, and both manifest writes share one
90
+ `finalizedAt`. After the callback returns a valid receipt, the core rewrites the
91
+ manifest with its terminal outcome.
36
92
 
37
93
  ## Safety and ordering
38
94
 
@@ -41,16 +97,22 @@ site-relative paths before network access. It then:
41
97
 
42
98
  1. uploads a sentinel whose path contains the run ID and a random 128-bit
43
99
  suffix;
44
- 2. verifies the sentinel with `head-object`;
45
- 3. fetches that exact sentinel through the public root;
100
+ 2. verifies the sentinel with a service-computed SHA-256 checksum or an
101
+ authenticated download hash;
102
+ 3. for public destinations, fetches that exact sentinel anonymously through the
103
+ public root; protected destinations skip this public fetch explicitly;
46
104
  4. deletes only that sentinel;
47
105
  5. uploads or idempotently skips each declared artifact;
48
- 6. verifies object metadata, content type, and SHA-256 of the exact response
49
- bytes from each public artifact URL; and
50
- 7. atomically writes `explainer-kit.publish-receipt/v1`.
106
+ 6. verifies exact object bytes from service-computed SHA-256 evidence or an
107
+ authenticated download hash, then additionally verifies the exact anonymous
108
+ response bytes for public destinations; and
109
+ 7. atomically writes `explainer-kit.publish-receipt/v2` with separate
110
+ authenticated-object and anonymous-public verification facts.
51
111
 
52
- If public sentinel verification fails, no artifact is uploaded. The connector
53
- attempts sentinel cleanup and emits no successful receipt.
112
+ If required sentinel verification fails or its verification capability is
113
+ unavailable, no artifact is uploaded. The connector attempts sentinel cleanup
114
+ and emits no successful receipt. An undeclared `401` or `403` in public mode is
115
+ a verification failure, never evidence that the destination is protected.
54
116
 
55
117
  Publishing is additive. The implementation uses individual `put-object`,
56
118
  `head-object`, and sentinel-only `delete-object` operations. It never performs
@@ -74,10 +136,13 @@ Every upload sets metadata explicitly:
74
136
  | other | manifest media type or `application/octet-stream` |
75
137
 
76
138
  Artifacts use `Cache-Control: public, max-age=300`. The connector stores the
77
- SHA-256 digest as object metadata for idempotency and verifies content type,
78
- cache control, and digest after upload. Public verification hashes response
79
- bytes without text decoding, so binary artifacts and stale wrong-byte 200
80
- responses are covered.
139
+ SHA-256 digest as object metadata for idempotency and supplies
140
+ `--checksum-sha256` on upload. It requests service checksum evidence with
141
+ `--checksum-mode ENABLED`; caller-authored metadata and ETags are never treated
142
+ as object-byte proof. When service SHA-256 evidence is unavailable, the
143
+ connector hashes bytes from an authenticated download. Public verification
144
+ separately hashes response bytes without text decoding, so binary artifacts and
145
+ stale wrong-byte 200 responses are covered.
81
146
 
82
147
  ## Failures and retries
83
148
 
@@ -86,9 +151,60 @@ not run `aws sso login`, retry with another profile, expose AWS diagnostics, or
86
151
  persist credentials. Refresh credentials separately and rerun after approval.
87
152
 
88
153
  Only transient individual object-operation failures receive bounded retries.
89
- Input, authorization, root-correspondence, metadata, and public-verification
90
- failures are not retried. A failed publish preserves the local package.
154
+ Input, authorization, metadata, and public-verification failures are not
155
+ retried. A failed publish preserves the local package.
91
156
 
92
157
  Public roots must be credential-free HTTPS URLs with no username, password,
93
- query, or fragment. Invalid roots fail before AWS or HTTP operations and are
94
- never persisted in receipts.
158
+ query, or fragment. Three further rejections apply, all before any AWS or HTTP
159
+ operation, and none of them are ever persisted in receipts:
160
+
161
+ - **Control characters.** Any codepoint in `0x00`–`0x1f` or `0x7f`–`0x9f`, and
162
+ any backslash, in either root. These otherwise reach S3 object keys, composed
163
+ public URLs, the catalog, the receipt and `aws` argv; `0x9b` is the 8-bit CSI.
164
+ - **Non-public addresses.** Loopback, link-local (`169.254.0.0/16`, `fe80::/10`,
165
+ including the `169.254.169.254` instance-metadata address), unique-local
166
+ (`fc00::/7`) and RFC 1918 private hosts, in both literal IPv4 and IPv6 forms
167
+ including IPv4-mapped spellings. Public verification issues an outbound GET
168
+ against whatever the root names, so an unconstrained root is a request
169
+ primitive aimed at internal addresses. Set
170
+ `EXPLAINER_KIT_ALLOW_PRIVATE_PUBLIC_ROOT=1` to opt back in for a genuinely
171
+ internal mirror. The policy is address-literal only: a hostname that happens
172
+ to resolve inward is not detected.
173
+ - **Redirects.** Public verification uses `redirect: 'error'`. A canonical
174
+ artifact URL is uploaded to a known key and should never legitimately
175
+ redirect, so any redirecting destination is a hard verification failure rather
176
+ than something to follow. A destination that requires redirects is
177
+ incompatible with this connector and will report as such rather than failing
178
+ opaquely later.
179
+
180
+ ## The generated initiative catalog
181
+
182
+ The connector generates one auxiliary artifact the manifest does not declare: an
183
+ initiative catalog at `site/initiatives/<slug>/catalog.json`, uploaded alongside
184
+ the declared artifacts and recorded in the receipt as
185
+ `source: { kind: 'auxiliary', name: 'catalog' }`.
186
+
187
+ A third-party connector must reproduce it **byte for byte**, because
188
+ `recordDurability` rebuilds it from the manifest and compares hashes; a mismatch
189
+ rejects the publication with `cross-record-mismatch`. Build it with
190
+ `catalogFromManifest(manifest, publicBaseUrl, { publicAccess })` and serialize
191
+ with `serializeInitiativeCatalog`, rather than constructing it by hand.
192
+
193
+ Two properties matter most:
194
+
195
+ - The `{ publicAccess }` option is **required**. Omitting it raises a
196
+ `TypeError` rather than defaulting, because the policy selects a field inside
197
+ the serialized bytes and therefore changes the hash. Pass
198
+ `{ publicAccess: undefined }` for `publish-request/v1`, which has no such
199
+ field and is public by definition.
200
+ - `publicVerification` carries **policy, never outcome**: `"required"` for
201
+ public destinations and `"skipped-by-policy"` for protected ones. The catalog
202
+ is serialized and hashed before the first upload and long before any
203
+ per-artifact verification runs, so it cannot carry a verification result
204
+ without invalidating its own hash. The authoritative outcome lives in the
205
+ publish receipt, which the catalog's `runId` identifies. Never write
206
+ `"verified"` into a catalog.
207
+
208
+ Publishability is gated by `assertManifestPublishable`, which raises
209
+ `E_PUBLISH_OUTCOME` for a manifest that is not eligible; see the intermediate
210
+ `incomplete` state described above.
@@ -20,13 +20,18 @@ Private wrappers may retain presets, vault conventions, Google Docs behavior,
20
20
  and personal destinations around this seam. Those values are wrapper-owned;
21
21
  they are not OAT config keys and must not be discovered by the core.
22
22
 
23
- ## Frozen v1 boundary
23
+ ## Frozen versioned boundary
24
24
 
25
25
  The versioned request, artifact package, manifest, build record, durability
26
- request, publish request, and publish receipt are the public boundary. V1 has
27
- no plugin registry and no mid-pipeline callback API for private destinations.
28
- Provider-neutral callbacks already documented by the core remain explicit run
29
- options; they do not transfer stage ownership to a wrapper.
26
+ request, publish request, and publish receipt are the public boundary. New
27
+ publication work uses the immutable `explainer-kit.publish-request/v2` and
28
+ `explainer-kit.publish-receipt/v2` contracts. The corresponding
29
+ `publish-request/v1` and `publish-receipt/v1` contracts remain readable for
30
+ replay; v2 is a new contract version, not an in-place mutation of v1. The
31
+ extension seam has no plugin registry and no mid-pipeline callback API for
32
+ private destinations. Provider-neutral callbacks already documented by the
33
+ core remain explicit run options; they do not transfer stage ownership to a
34
+ wrapper.
30
35
 
31
36
  V1 readers reject unsupported contract majors and identity mismatches rather
32
37
  than guessing. Wrappers should preserve unknown future versions for diagnosis,
@@ -59,13 +64,17 @@ or private content.
59
64
 
60
65
  After the core command returns, the wrapper performs its post-run publication
61
66
  and linking work. It retains the immutable core manifest as
62
- `private-wrapper-manifest.json`, the complete `PublishReceiptV1` as
67
+ `private-wrapper-manifest.json`, the complete `publish-receipt/v2` as
63
68
  `private-wrapper-publish-receipt.json`, and its sanitized wrapper result as
64
69
  `private-wrapper-result.json`. The wrapper result repeats canonical hashes for
65
70
  the request, manifest, and post-run receipt.
66
71
 
67
72
  The wrapper acceptance stage reads those post-run files separately. It
68
- validates the closed receipt contract, every manifest artifact/hash and
69
- destination, the run-unique sentinel, the manifest hash, and the core run ID
70
- against `private-wrapper-execution.json`. Repeating a matching hash cannot make
71
- a foreign or stale receipt attributable to the packaged run.
73
+ validates the closed receipt contract, complete manifest and catalog evidence,
74
+ every source identity, path, artifact hash, destination, and verification fact,
75
+ the run-unique sentinel, the manifest hash, and the core run ID against
76
+ `private-wrapper-execution.json`. Public and protected v2 receipts must each
77
+ provide exactly one entry for every finalized manifest artifact and exactly one
78
+ generated catalog entry. A `publish-receipt/v1` remains consumable only for
79
+ replay. Repeating a matching hash cannot make a foreign, duplicate, incomplete,
80
+ or stale receipt attributable to the packaged run.
@@ -28,10 +28,30 @@ stands. Use one dominant title, a short framing statement, and the most useful
28
28
  visual or status summary before secondary detail. Keep headings descriptive,
29
29
  group related items, and use size, spacing, and contrast consistently.
30
30
 
31
+ Assign intentional typography roles to the title, framing statement, section
32
+ headings, labels, body copy, evidence, and annotations. Use weight, scale,
33
+ measure, and contrast to clarify those roles rather than making every text block
34
+ equally loud. Keep the role system consistent across artifacts without forcing
35
+ every medium into the same composition.
36
+
31
37
  Use the shared terminology, status labels, and numbers exactly. Never create a
32
38
  shorter synonym that changes meaning. Keep source-backed uncertainty visible as
33
39
  `needs confirmation`.
34
40
 
41
+ ## Compose to the evidence
42
+
43
+ Treat composition and density as editorial choices. Group facts that belong
44
+ together, give the main claim enough emphasis, and let supporting evidence
45
+ recede without becoming hard to find. Restructure crowded content instead of
46
+ shrinking it, and remove decorative filler instead of stretching sparse
47
+ material.
48
+
49
+ Seek medium leverage: a visual artifact should make a relationship, comparison,
50
+ sequence, or decision easier to understand than prose alone. Vary the treatment
51
+ to fit the evidence and avoid template repetition across sections, cards, or
52
+ slides. Shared visual language should create cross-artifact cohesion, not a set
53
+ of cloned layouts.
54
+
35
55
  ## Hubs and responsive navigation
36
56
 
37
57
  - Lead with the project outcome and current state, then expose architecture,
@@ -45,6 +65,8 @@ shorter synonym that changes meaning. Keep source-backed uncertainty visible as
45
65
 
46
66
  ## Diagrams and system visuals
47
67
 
68
+ - Preserve diagram semantics: topology, direction, ownership, state, and edge
69
+ meaning must survive the visual treatment.
48
70
  - Encode relationships with position and connectors, not color alone.
49
71
  - Label nodes with concrete nouns and edges with actions or data movement.
50
72
  - Make direction explicit and include a legend only when the encoding needs it.
@@ -58,6 +80,8 @@ shorter synonym that changes meaning. Keep source-backed uncertainty visible as
58
80
  attribute escaping, including `data-edge-label=""` for an unlabeled edge.
59
81
  - Give the canvas an accessible name and description. Keep labels readable at
60
82
  the required viewport widths and provide bounded pan or zoom for large maps.
83
+ - Fit the frame to the content so the meaningful topology is prominent rather
84
+ than stranded in unused canvas.
61
85
  - Use the same component names and status vocabulary as the hub and deck.
62
86
 
63
87
  ## Decks
@@ -12,17 +12,30 @@ Inspect the complete set before assigning artifact findings. Verify:
12
12
 
13
13
  - **First viewport:** each artifact establishes purpose, project state, and the
14
14
  primary reader question without scrolling.
15
+ - **Typography:** titles, framing text, headings, labels, body copy, and
16
+ annotations have distinct, readable roles that remain consistent across the
17
+ set.
15
18
  - **Hierarchy:** the most important outcome or relationship is dominant, with
16
19
  secondary detail grouped and ordered consistently.
17
- - **Representation choice:** the selected medium makes the evidence easier to
18
- understand than plain prose would.
20
+ - **Composition:** grouping, alignment, spacing, and emphasis create a clear
21
+ reading path suited to the artifact's evidence.
22
+ - **Density:** crowded material is restructured instead of miniaturized, while
23
+ sparse material is not padded with decorative filler.
24
+ - **Medium leverage:** the selected medium makes a relationship, comparison,
25
+ sequence, or decision easier to understand than plain prose would.
19
26
  - **Legibility:** text, labels, status cues, tables, and connectors remain
20
27
  readable at every required viewport.
21
28
  - **Medium fit:** the hub orients and links, the system visual preserves
22
29
  relationships, the deck paces a narrative, and optional artifacts add a
23
30
  distinct source-backed perspective.
24
- - **Cohesion:** terminology, status labels, numbers, color meaning, and visual
25
- language match the shared ledger and one another.
31
+ - **Template repetition:** sections, cards, and slides vary when the evidence
32
+ calls for a different treatment instead of repeating one shell mechanically.
33
+ - **Diagram semantics:** topology, direction, labels, edge meaning, and
34
+ fit-to-content framing communicate the planned relationships without false
35
+ linearization or decorative ambiguity.
36
+ - **Cross-artifact cohesion:** terminology, status labels, numbers, color
37
+ meaning, typographic roles, and visual language match the shared ledger and
38
+ one another.
26
39
  - **Coverage and redundancy:** planned sources and reader questions are covered
27
40
  once at the right depth; optional artifacts do not repeat the hub or deck
28
41
  without a justified purpose.
@@ -49,7 +62,8 @@ Use severity proportionally:
49
62
  Return exactly one provider-neutral disposition:
50
63
 
51
64
  - `pass` when the full set clears the rubric with no required correction.
52
- - `correct` when bounded artifact-scoped changes can clear the rubric.
65
+ - `correct` when bounded artifact-scoped changes can clear the rubric; every
66
+ finding must name a concrete, actionable correction.
53
67
  - `fail` when evidence is missing, the plan or ledger is internally invalid, or
54
68
  correction would require unsupported facts or a different artifact set.
55
69