@open-agent-toolkit/cli 0.2.10 → 0.2.12
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/assets/docs/cli-utilities/configuration.md +28 -14
- package/assets/docs/reference/cli-reference.md +1 -1
- package/assets/docs/workflows/projects/artifacts.md +16 -4
- package/assets/docs/workflows/skills/explainer-kit.md +70 -27
- package/assets/public-package-versions.json +4 -4
- package/assets/skills/explainer-kit/SKILL.md +9 -3
- package/assets/skills/explainer-kit/references/contracts.md +22 -7
- package/assets/skills/explainer-kit/schemas/author-request.schema.json +85 -0
- package/assets/skills/explainer-kit/schemas/author-result.schema.json +65 -0
- package/assets/skills/explainer-kit/schemas/manifest.schema.json +7 -1
- package/assets/skills/explainer-kit/schemas/run-request.schema.json +8 -0
- package/assets/skills/explainer-kit/schemas/theme.schema.json +8 -0
- package/assets/skills/explainer-kit/scripts/lib/content-approval.mjs +26 -1
- package/assets/skills/explainer-kit/scripts/lib/contracts.mjs +61 -0
- package/assets/skills/explainer-kit/scripts/lib/durability.mjs +2 -14
- package/assets/skills/explainer-kit/scripts/lib/qa.mjs +56 -0
- package/assets/skills/explainer-kit/scripts/lib/theme.mjs +102 -4
- package/assets/skills/explainer-kit/scripts/run.mjs +144 -11
- package/assets/skills/explainer-kit/styles/business-corporate.json +77 -0
- package/assets/skills/explainer-kit/styles/clean-neutral.json +77 -0
- package/assets/skills/explainer-kit/styles/dark-edgy.json +77 -0
- package/assets/skills/explainer-kit/styles/navy-ocean.json +82 -0
- package/assets/skills/explainer-kit/templates/deck-shell.html +57 -2
- package/assets/skills/oat-explainer-kit/SKILL.md +15 -9
- package/assets/skills/oat-explainer-kit/references/config-contract.md +11 -6
- package/assets/skills/oat-explainer-kit/references/lifecycle-contract.md +13 -0
- package/assets/skills/oat-explainer-kit/scripts/finalize-tracked-run.mjs +10 -14
- package/assets/skills/oat-explainer-kit/scripts/resolve-config.mjs +53 -9
- package/assets/skills/oat-explainer-kit/scripts/run.mjs +68 -0
- package/assets/skills/oat-wave-execute/SKILL.md +126 -23
- package/assets/skills/oat-wave-program/SKILL.md +41 -7
- package/dist/commands/config/index.d.ts.map +1 -1
- package/dist/commands/config/index.js +34 -8
- package/dist/commands/project/archive/archive-utils.d.ts.map +1 -1
- package/dist/commands/project/archive/archive-utils.js +14 -5
- package/dist/config/oat-config.d.ts +2 -0
- package/dist/config/oat-config.d.ts.map +1 -1
- package/dist/config/oat-config.js +11 -0
- package/dist/config/resolve.d.ts.map +1 -1
- package/dist/config/resolve.js +3 -2
- package/dist/providers/codex/codec/config-merge.d.ts.map +1 -1
- package/dist/providers/codex/codec/config-merge.js +39 -1
- package/package.json +2 -2
|
@@ -106,18 +106,19 @@ The `oat-explainer-kit` adapter owns two typed config groups. Build and publish
|
|
|
106
106
|
plumbing uses `explainers.*`; project lifecycle preferences use
|
|
107
107
|
`workflow.explainers.*`.
|
|
108
108
|
|
|
109
|
-
| Key | Type
|
|
110
|
-
| -------------------------------------- |
|
|
111
|
-
| `explainers.defaults.
|
|
112
|
-
| `explainers.defaults.
|
|
113
|
-
| `explainers.defaults.
|
|
114
|
-
| `explainers.
|
|
115
|
-
| `explainers.publish.
|
|
116
|
-
| `explainers.publish.
|
|
117
|
-
| `explainers.publish.
|
|
118
|
-
| `explainers.publish.
|
|
119
|
-
| `
|
|
120
|
-
| `workflow.explainers.
|
|
109
|
+
| Key | Type | Stored scopes | Default |
|
|
110
|
+
| -------------------------------------- | ---------------------------- | ------------------- | --------------- |
|
|
111
|
+
| `explainers.defaults.style` | curated style name | local, shared, user | `clean-neutral` |
|
|
112
|
+
| `explainers.defaults.palette` | nullable string (deprecated) | local, shared, user | `null` |
|
|
113
|
+
| `explainers.defaults.visualProfile` | nullable string (deprecated) | local, shared, user | `null` |
|
|
114
|
+
| `explainers.defaults.themeBundlePath` | path | local, shared | unset |
|
|
115
|
+
| `explainers.publish.provider` | `s3-static` | shared | unset |
|
|
116
|
+
| `explainers.publish.s3Uri` | `s3://` URI | shared | unset |
|
|
117
|
+
| `explainers.publish.publicBaseUrl` | HTTPS URL | shared | unset |
|
|
118
|
+
| `explainers.publish.awsRegion` | non-empty string | shared | unset |
|
|
119
|
+
| `explainers.publish.awsProfile` | non-empty string | local, user | unset |
|
|
120
|
+
| `workflow.explainers.projectExplainer` | `always\|ask\|never` | local, shared, user | `ask` |
|
|
121
|
+
| `workflow.explainers.projectRecap` | `always\|ask\|never` | local, shared, user | `ask` |
|
|
121
122
|
|
|
122
123
|
Stored values resolve `local > shared > user > default` where the key permits
|
|
123
124
|
each scope. Explicit runtime inputs take precedence for one invocation without
|
|
@@ -125,10 +126,23 @@ mutating stored config. Use `oat config get <key> --json` to inspect both the
|
|
|
125
126
|
resolved value and its source, and `oat config describe <key>` for its exact
|
|
126
127
|
scope and type contract.
|
|
127
128
|
|
|
129
|
+
For example:
|
|
130
|
+
|
|
131
|
+
```bash
|
|
132
|
+
oat config set explainers.defaults.style navy-ocean --shared
|
|
133
|
+
oat config get explainers.defaults.style --json
|
|
134
|
+
oat config describe explainers.defaults.style
|
|
135
|
+
```
|
|
136
|
+
|
|
128
137
|
Shared theme-bundle paths must be repository-relative. Local paths may be
|
|
129
138
|
repository-relative or absolute; user config cannot set a theme-bundle path.
|
|
130
|
-
A supplied bundle takes precedence over named
|
|
131
|
-
|
|
139
|
+
A supplied bundle takes precedence over all named selections. Otherwise choose
|
|
140
|
+
one of `clean-neutral`, `business-corporate`, `navy-ocean`, or `dark-edgy` with
|
|
141
|
+
`explainers.defaults.style`. An explicit style takes precedence over legacy
|
|
142
|
+
`palette` and `visualProfile` values. Those matrix fields remain available for
|
|
143
|
+
advanced compatibility but emit deprecation warnings. When no source explicitly
|
|
144
|
+
selects a theme, the core uses `clean-neutral` and records a visible fallback
|
|
145
|
+
warning.
|
|
132
146
|
|
|
133
147
|
Publishing remains build-only when `explainers.publish.provider` is unset.
|
|
134
148
|
When it is `s3-static`, `s3Uri`, `publicBaseUrl`, and `awsRegion` are all
|
|
@@ -64,7 +64,7 @@ Notable commands introduced in the current CLI surface:
|
|
|
64
64
|
- `oat review latest --json` - find the newest review artifact by `oat_generated_at`, scanning the active or specified project's `reviews/` and `reviews/archived/` directories plus ad-hoc review locations. Same-time candidates use target priority, then lifecycle recency (`final` > higher phase/task > lower phase/task). The JSON contract returns `path`, `scope`, `generatedAt`, `kind` (`project` or `adhoc`), `archived`, and `actionable`, with `null` values when no review exists. Archived project reviews remain discoverable as history but return `actionable: false`.
|
|
65
65
|
- `oat project list --json` - summary state for tracked projects under the configured projects root
|
|
66
66
|
- `oat project complete-state <project-path>` - apply the canonical completed-state mutation to a project's `state.md`; used by `oat-project-complete` during lifecycle closeout
|
|
67
|
-
- `oat project archive [project-path]` - archive a tracked project through the same local move, summary export, and optional S3 upload path used by completion. When omitted, the project path falls back to the active project.
|
|
67
|
+
- `oat project archive [project-path] [--project-recap-run <project-relative-path>]` - archive a tracked project through the same local move, summary export, and optional S3 upload path used by completion. When omitted, the project path falls back to the active project. The optional recap path must identify a `project-recap` run inside the project's `explainers/` directory. Archive stages the selected complete package into `.oat/repo/reference/project-recaps/<YYYYMMDD-project-slug>/`, verifies every manifest-declared immutable file byte, then atomically installs the export before deleting the active project. Existing destinations, incomplete legacy hash coverage, stale bytes, path escapes, and recipe mismatches fail without removing the active project.
|
|
68
68
|
- `oat repo archive sync [project-name]` - hydrate archived project snapshots from the configured repo-scoped S3 archive into `.oat/projects/archived/`. The old `oat project archive sync` path remains as a deprecated shim.
|
|
69
69
|
- `oat project validate-plan --project-path <path>` - validates `oat_plan_parallel_groups` metadata in `plan.md`; exits non-zero on invalid. See [Implementation Execution](../workflows/projects/implementation-execution.md#plan-declared-parallelism).
|
|
70
70
|
- `oat project log append|check|synthesize|rollup` - manage the optional append-only project observation log: append validated judgment or structural entries, inspect grammar and synthesis status, complete end-of-run synthesis, and roll observations into `summary.md` plus the configured repository ledger. See [Project Log](../cli-utilities/project-log.md).
|
|
@@ -44,13 +44,25 @@ different retention contracts:
|
|
|
44
44
|
- A selected final `project-recap` is a durable completion record. Before a
|
|
45
45
|
shared project is removed, archive copies the complete selected run to
|
|
46
46
|
`.oat/repo/reference/project-recaps/<YYYYMMDD-project-slug>/`, verifies its
|
|
47
|
-
|
|
48
|
-
PR links use this export, never the gitignored local archive.
|
|
47
|
+
immutable package hashes, and reports that tracked export path. Summary and
|
|
48
|
+
PR links use this export, never the gitignored local archive. Lifecycle
|
|
49
|
+
callers identify the selected project-relative run with:
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
oat project archive <project-path> \
|
|
53
|
+
--project-recap-run explainers/<recap-slug>
|
|
54
|
+
```
|
|
49
55
|
|
|
50
56
|
The archive exports at most one selected recap package. It preserves structured
|
|
51
57
|
failure outcomes and successful intermediates, rejects an existing dated
|
|
52
|
-
destination, and
|
|
53
|
-
|
|
58
|
+
destination, and requires the selected path to stay under the project's
|
|
59
|
+
`explainers/` directory with a `project-recap` manifest. Verification covers
|
|
60
|
+
the exact retained bytes for the privacy-safe request, content approval, fact
|
|
61
|
+
base JSON and Markdown, declared author results, authored Markdown, resolved
|
|
62
|
+
theme, and every built artifact. Canonical fact-base and theme hashes remain
|
|
63
|
+
normalized-object identities; `manifest.immutableHashes` independently covers
|
|
64
|
+
serialized file bytes. Missing, stale, or tampered coverage fails before the
|
|
65
|
+
active project is deleted.
|
|
54
66
|
|
|
55
67
|
Local-scope projects are not archived through this export path. Their explainer
|
|
56
68
|
packages inherit the local project's untracked posture and remain
|
|
@@ -20,38 +20,81 @@ OAT lifecycle callers use the adapter.
|
|
|
20
20
|
|
|
21
21
|
## Recipes
|
|
22
22
|
|
|
23
|
-
The
|
|
24
|
-
|
|
25
|
-
| Recipe |
|
|
26
|
-
| ------------------- |
|
|
27
|
-
| `project-explainer` | Working explanation after project planning
|
|
28
|
-
| `project-recap` | Final record after implementation and final review
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
23
|
+
The core ships four versioned recipes:
|
|
24
|
+
|
|
25
|
+
| Recipe | Use | Required narrative |
|
|
26
|
+
| ------------------- | ------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------- |
|
|
27
|
+
| `project-explainer` | Working explanation after project planning | planned architecture, decisions, risks, phases, and validation approach |
|
|
28
|
+
| `project-recap` | Final record after implementation and final review | original request, key agent decisions, as-built architecture, implementation record, validation evidence, and outcome |
|
|
29
|
+
| `program-recap` | Bird's-eye record of a multi-wave delivery program | program overview, wave map and outcomes, convention evolution, aggregate numbers, and follow-up ledger |
|
|
30
|
+
| `engineer-tour` | Engineer-facing orientation to a codebase and its flow | orientation, architecture, execution flow, key code, and validation |
|
|
31
|
+
|
|
32
|
+
The OAT project lifecycle owns `project-explainer` and `project-recap`. Both
|
|
33
|
+
bind one project source set. The adapter binds `plan.md`, `design.md`, and
|
|
34
|
+
`spec.md` for a project explainer; a project recap can also include
|
|
35
|
+
`implementation.md` and `summary.md`. Wave callers supply the program source
|
|
36
|
+
set for `program-recap`; direct core callers can use `engineer-tour` without
|
|
37
|
+
adding an OAT dependency.
|
|
38
|
+
|
|
39
|
+
## Content authoring and review
|
|
40
|
+
|
|
41
|
+
Every unattended run requires one provider-neutral author. The core invokes
|
|
42
|
+
the author once per recipe artifact with the exact narrative outline,
|
|
43
|
+
reconciled fact base, and bounded-discovery context. It accepts only a
|
|
44
|
+
schema-valid result with the required section IDs, substantive prose, and
|
|
45
|
+
non-secret provenance. Each section is checked independently for excessive
|
|
46
|
+
verbatim overlap with the fact base so one copied section cannot be hidden by
|
|
47
|
+
otherwise original prose.
|
|
48
|
+
|
|
49
|
+
In-process core callers supply `options.author`; core CLI callers use
|
|
50
|
+
`--author-module`. The OAT adapter accepts either an in-process `author` or an
|
|
51
|
+
`authorModulePath` and rejects zero or two seams for unattended runs before it
|
|
52
|
+
invokes the core. Callback and module paths are transient. Validated results
|
|
53
|
+
are retained under `source/author/` and covered by the run's immutable hashes.
|
|
54
|
+
|
|
55
|
+
Interactive runs may omit an author. They pause after writing
|
|
56
|
+
`source/content/*.md`, require an explicit content-review decision, and resume
|
|
57
|
+
the same run only after approval. Content approval never authorizes publishing.
|
|
58
|
+
|
|
59
|
+
## Curated styles and themes
|
|
60
|
+
|
|
61
|
+
Every artifact set uses one resolved theme. The primary selection surface is
|
|
62
|
+
one of four complete curated styles:
|
|
63
|
+
|
|
64
|
+
- `clean-neutral` — restrained neutral default
|
|
65
|
+
- `business-corporate` — structured corporate presentation
|
|
66
|
+
- `navy-ocean` — navy-led technical and operational presentation
|
|
67
|
+
- `dark-edgy` — solid dark canvas with high-contrast editorial accents
|
|
68
|
+
|
|
69
|
+
A caller may select a style, supply a validated theme bundle, or provide
|
|
70
|
+
per-run art direction. A supplied bundle takes precedence over a style. Legacy
|
|
71
|
+
`palette` and `visualProfile` inputs remain nullable compatibility fields, but
|
|
72
|
+
an explicit style wins and legacy use emits a deprecation warning. When no
|
|
73
|
+
selection is explicit, the core uses `clean-neutral` and records the fallback.
|
|
74
|
+
|
|
75
|
+
The resolved concrete bundle is retained with the run; raw art-direction text
|
|
76
|
+
is not retained by default. Every bundle contains validated light and dark
|
|
77
|
+
modes. The render strategy chooses either the default mode or a user-switchable
|
|
78
|
+
result without changing the bundle identity.
|
|
47
79
|
|
|
48
80
|
## Build, durability, and publish
|
|
49
81
|
|
|
50
82
|
Missing publish configuration means build-only. A completed build writes the
|
|
51
|
-
|
|
52
|
-
|
|
83
|
+
privacy-safe request, content approval, fact base, author results, authored
|
|
84
|
+
content, resolved theme, `manifest.json`, `build-record.json`, and the rendered
|
|
85
|
+
`site/` tree. Rendering or publishing failures preserve successful
|
|
53
86
|
intermediates and recovery information.
|
|
54
87
|
|
|
88
|
+
`manifest.immutableHashes` covers the exact retained bytes for
|
|
89
|
+
`run-request.json`, content approval, fact-base JSON and Markdown, declared
|
|
90
|
+
author results, authored Markdown, the resolved theme, and every built
|
|
91
|
+
artifact. Canonical fact-base and theme hashes identify normalized objects;
|
|
92
|
+
they are intentionally distinct from serialized file-byte hashes. The mutable
|
|
93
|
+
manifest and build record are excluded from their own durability evidence and
|
|
94
|
+
are committed separately after verification. Older v1 manifests without
|
|
95
|
+
complete coverage fail with a legacy-manifest diagnostic and must be
|
|
96
|
+
regenerated.
|
|
97
|
+
|
|
55
98
|
Build success and durability are separate:
|
|
56
99
|
|
|
57
100
|
- `built-not-durable` means artifacts exist but verified commit or publish
|
|
@@ -69,7 +112,7 @@ content type and SHA-256 response bytes at public URLs, and writes
|
|
|
69
112
|
fragments. Publishing is additive and does not run a root-wide destructive
|
|
70
113
|
sync.
|
|
71
114
|
|
|
72
|
-
Release validation drives the bounded
|
|
115
|
+
Release validation drives the bounded curated-style/template matrix in a real
|
|
73
116
|
installed Chromium browser and retains machine-readable viewport, clipping,
|
|
74
117
|
motion, keyboard, no-JavaScript, and print measurements. The gate fails closed
|
|
75
118
|
when no supported browser executable is available.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: explainer-kit
|
|
3
|
-
version: 1.0.
|
|
3
|
+
version: 1.0.2
|
|
4
4
|
description: Use when building destination-neutral visual explainer artifacts from explicit, versioned inputs.
|
|
5
5
|
user-invocable: true
|
|
6
6
|
allowed-tools: Read, Write, Edit, Bash, Grep, Glob, Agent, mcp__*
|
|
@@ -58,8 +58,14 @@ require a provider-neutral critic callback and invoke it exactly once.
|
|
|
58
58
|
Optional claim `sections` tags route facts to matching recipe narrative
|
|
59
59
|
sections; untagged claims remain shared context for every required section.
|
|
60
60
|
|
|
61
|
-
Unattended calls use explicit, already-approved source artifacts
|
|
62
|
-
|
|
61
|
+
Unattended calls use explicit, already-approved source artifacts and require a
|
|
62
|
+
provider-neutral author callback once per recipe artifact. In-process callers
|
|
63
|
+
supply `options.author`; JSON-only CLI callers supply `--author-module`. The
|
|
64
|
+
core validates exact narrative sections and non-secret author provenance,
|
|
65
|
+
rejects excessive verbatim source overlap, retains each validated result under
|
|
66
|
+
`source/author/`, persists review provenance in
|
|
67
|
+
`source/content-approval.json`, and never prompts. Keep executable callback
|
|
68
|
+
references out of the persisted run request.
|
|
63
69
|
|
|
64
70
|
Interactive runs stop with an `incomplete` outcome after writing
|
|
65
71
|
`source/content/*.md`. Review and correct that Markdown, then provide an
|
|
@@ -30,6 +30,14 @@ claims, sources, overrides, and the freshness policy. It returns:
|
|
|
30
30
|
No provider name, command, credential, or dispatch protocol is part of this
|
|
31
31
|
contract.
|
|
32
32
|
|
|
33
|
+
Every unattended run also requires a provider-neutral author callback. An
|
|
34
|
+
in-process caller supplies `options.author(request)`; a JSON-only CLI caller
|
|
35
|
+
uses `--author-module author.mjs`. The core invokes it once per recipe artifact
|
|
36
|
+
with an `AuthorRequestV1` containing the exact narrative outline, reconciled
|
|
37
|
+
fact base, and bounded-discovery context. It must return an `AuthorResultV1`
|
|
38
|
+
with every required section in order, non-empty prose, and non-secret
|
|
39
|
+
provenance. The executable callback is never persisted in `run-request.json`.
|
|
40
|
+
|
|
33
41
|
## Explicit source forms
|
|
34
42
|
|
|
35
43
|
- `factBase.mode: supplied` points to a valid `FactBaseV1` JSON file. The core
|
|
@@ -47,8 +55,9 @@ contract.
|
|
|
47
55
|
reconciles the loaded claims and invokes the critic exactly once.
|
|
48
56
|
|
|
49
57
|
An unattended request asserts that its explicit source artifacts are already
|
|
50
|
-
approved. It does not prompt
|
|
51
|
-
|
|
58
|
+
approved. It does not prompt, and it fails before narrative serialization when
|
|
59
|
+
the author is absent, returns an invalid result, or copies excessive verbatim
|
|
60
|
+
source text. Interactive review and same-run approval/resume remain unchanged.
|
|
52
61
|
|
|
53
62
|
## Pipeline and retained package
|
|
54
63
|
|
|
@@ -56,14 +65,16 @@ The core executes:
|
|
|
56
65
|
|
|
57
66
|
1. validate request and recipe
|
|
58
67
|
2. reconcile or check the fact base
|
|
59
|
-
3. apply bounded discovery and create recipe content
|
|
68
|
+
3. apply bounded discovery and obtain or create recipe content
|
|
60
69
|
4. resolve one theme
|
|
61
70
|
5. render typed artifacts
|
|
62
71
|
6. run structural and optional browser QA
|
|
63
72
|
7. write the manifest and build record
|
|
64
73
|
|
|
65
|
-
The run package retains
|
|
66
|
-
`source/content
|
|
74
|
+
The run package retains the privacy-safe `run-request.json`,
|
|
75
|
+
`source/content-approval.json`, `source/fact-base.json`,
|
|
76
|
+
`source/fact-base.md`, `source/content/*.md`, optional structured
|
|
77
|
+
`source/author/*.json` results, `theme.resolved.json`, rendered `site/` files,
|
|
67
78
|
`manifest.json`, and `build-record.json` as far as each stage succeeds. A stage
|
|
68
79
|
failure records a structured error and recovery action without deleting earlier
|
|
69
80
|
outputs. Raw art direction is omitted unless the request explicitly opts in.
|
|
@@ -81,9 +92,13 @@ Durability and publishing are never implicit.
|
|
|
81
92
|
Caller-created commit evidence is subsequently verified with
|
|
82
93
|
`record-durability.mjs`; the core never creates commits. The first evidence
|
|
83
94
|
commit must contain every path and byte hash in `manifest.immutableHashes`:
|
|
84
|
-
|
|
85
|
-
|
|
95
|
+
the privacy-safe request, content approval, fact-base JSON and Markdown,
|
|
96
|
+
declared author results, all content Markdown, the resolved theme, and every
|
|
97
|
+
built artifact retained in the package. Mutable `manifest.json` and
|
|
86
98
|
`build-record.json` remain excluded for the separate evidence update.
|
|
99
|
+
Schema-v1 manifests created before complete-package coverage are rejected
|
|
100
|
+
with a legacy-manifest diagnostic and must be regenerated; validators never
|
|
101
|
+
invent missing hashes.
|
|
87
102
|
- `durability.strategy: publish` invokes the explicit `publish` callback with
|
|
88
103
|
the complete publish request. A verified receipt is subsequently recorded as
|
|
89
104
|
durability evidence.
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "explainer-kit.author-request/v1",
|
|
4
|
+
"title": "AuthorRequestV1",
|
|
5
|
+
"type": "object",
|
|
6
|
+
"additionalProperties": false,
|
|
7
|
+
"required": [
|
|
8
|
+
"schemaVersion",
|
|
9
|
+
"run",
|
|
10
|
+
"recipe",
|
|
11
|
+
"artifact",
|
|
12
|
+
"narrativeOutline",
|
|
13
|
+
"factBase",
|
|
14
|
+
"discovery"
|
|
15
|
+
],
|
|
16
|
+
"properties": {
|
|
17
|
+
"schemaVersion": { "const": "explainer-kit.author-request/v1" },
|
|
18
|
+
"run": {
|
|
19
|
+
"type": "object",
|
|
20
|
+
"additionalProperties": false,
|
|
21
|
+
"required": ["runId", "slug"],
|
|
22
|
+
"properties": {
|
|
23
|
+
"runId": { "type": "string", "minLength": 1 },
|
|
24
|
+
"slug": {
|
|
25
|
+
"type": "string",
|
|
26
|
+
"pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$"
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
"recipe": {
|
|
31
|
+
"type": "object",
|
|
32
|
+
"additionalProperties": false,
|
|
33
|
+
"required": ["id", "version", "requiredNarrative"],
|
|
34
|
+
"properties": {
|
|
35
|
+
"id": { "type": "string", "minLength": 1 },
|
|
36
|
+
"version": { "type": "string", "minLength": 1 },
|
|
37
|
+
"requiredNarrative": {
|
|
38
|
+
"type": "array",
|
|
39
|
+
"items": { "type": "string", "minLength": 1 },
|
|
40
|
+
"minItems": 1,
|
|
41
|
+
"uniqueItems": true
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
"artifact": {
|
|
46
|
+
"type": "object",
|
|
47
|
+
"additionalProperties": false,
|
|
48
|
+
"required": ["id", "type"],
|
|
49
|
+
"properties": {
|
|
50
|
+
"id": { "type": "string", "minLength": 1 },
|
|
51
|
+
"type": { "enum": ["hub", "diagram", "explainer", "deck", "catalog"] }
|
|
52
|
+
}
|
|
53
|
+
},
|
|
54
|
+
"narrativeOutline": {
|
|
55
|
+
"type": "array",
|
|
56
|
+
"items": {
|
|
57
|
+
"type": "object",
|
|
58
|
+
"additionalProperties": false,
|
|
59
|
+
"required": ["id", "title"],
|
|
60
|
+
"properties": {
|
|
61
|
+
"id": { "type": "string", "minLength": 1 },
|
|
62
|
+
"title": { "type": "string", "minLength": 1 }
|
|
63
|
+
}
|
|
64
|
+
},
|
|
65
|
+
"minItems": 1,
|
|
66
|
+
"uniqueItems": true
|
|
67
|
+
},
|
|
68
|
+
"factBase": { "$ref": "explainer-kit.fact-base/v1" },
|
|
69
|
+
"discovery": {
|
|
70
|
+
"type": "object",
|
|
71
|
+
"additionalProperties": false,
|
|
72
|
+
"required": ["rounds", "findings", "reason"],
|
|
73
|
+
"properties": {
|
|
74
|
+
"rounds": { "type": "integer", "minimum": 0 },
|
|
75
|
+
"findings": {
|
|
76
|
+
"type": "array",
|
|
77
|
+
"items": { "type": "string", "minLength": 1 }
|
|
78
|
+
},
|
|
79
|
+
"reason": {
|
|
80
|
+
"enum": ["not-requested", "two-empty-rounds", "hard-maximum"]
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "explainer-kit.author-result/v1",
|
|
4
|
+
"title": "AuthorResultV1",
|
|
5
|
+
"type": "object",
|
|
6
|
+
"additionalProperties": false,
|
|
7
|
+
"required": ["schemaVersion", "artifactId", "content", "provenance"],
|
|
8
|
+
"properties": {
|
|
9
|
+
"schemaVersion": { "const": "explainer-kit.author-result/v1" },
|
|
10
|
+
"artifactId": { "type": "string", "minLength": 1 },
|
|
11
|
+
"content": {
|
|
12
|
+
"type": "object",
|
|
13
|
+
"additionalProperties": false,
|
|
14
|
+
"required": ["title", "description", "sections"],
|
|
15
|
+
"properties": {
|
|
16
|
+
"title": { "type": "string", "minLength": 1 },
|
|
17
|
+
"description": { "type": "string", "minLength": 1 },
|
|
18
|
+
"eyebrow": { "type": "string", "minLength": 1 },
|
|
19
|
+
"footer": { "type": "string", "minLength": 1 },
|
|
20
|
+
"sections": {
|
|
21
|
+
"type": "array",
|
|
22
|
+
"items": {
|
|
23
|
+
"type": "object",
|
|
24
|
+
"additionalProperties": false,
|
|
25
|
+
"required": ["id", "title", "prose"],
|
|
26
|
+
"properties": {
|
|
27
|
+
"id": { "type": "string", "minLength": 1 },
|
|
28
|
+
"title": { "type": "string", "minLength": 1 },
|
|
29
|
+
"prose": { "type": "string", "minLength": 1 }
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
"minItems": 1,
|
|
33
|
+
"uniqueItems": true
|
|
34
|
+
},
|
|
35
|
+
"artifactLinks": {
|
|
36
|
+
"type": "array",
|
|
37
|
+
"items": {
|
|
38
|
+
"type": "object",
|
|
39
|
+
"additionalProperties": false,
|
|
40
|
+
"required": ["id", "type", "label"],
|
|
41
|
+
"properties": {
|
|
42
|
+
"id": { "type": "string", "minLength": 1 },
|
|
43
|
+
"type": {
|
|
44
|
+
"enum": ["hub", "diagram", "explainer", "deck", "catalog"]
|
|
45
|
+
},
|
|
46
|
+
"label": { "type": "string", "minLength": 1 }
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
"uniqueItems": true
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
"provenance": {
|
|
54
|
+
"type": "object",
|
|
55
|
+
"additionalProperties": false,
|
|
56
|
+
"required": ["authorId", "generatedAt"],
|
|
57
|
+
"properties": {
|
|
58
|
+
"authorId": { "type": "string", "minLength": 1 },
|
|
59
|
+
"generatedAt": { "type": "string", "format": "date-time" },
|
|
60
|
+
"method": { "type": "string", "minLength": 1 },
|
|
61
|
+
"model": { "type": "string", "minLength": 1 }
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
@@ -43,7 +43,13 @@
|
|
|
43
43
|
"factBasePath": { "$ref": "#/$defs/safeRelativePath" },
|
|
44
44
|
"factBaseHash": { "$ref": "#/$defs/hash" },
|
|
45
45
|
"sourceRevision": { "type": "string", "minLength": 1 },
|
|
46
|
-
"inputHashes": { "$ref": "#/$defs/hashMap" }
|
|
46
|
+
"inputHashes": { "$ref": "#/$defs/hashMap" },
|
|
47
|
+
"authorResultPaths": {
|
|
48
|
+
"type": "array",
|
|
49
|
+
"items": { "$ref": "#/$defs/safeRelativePath" },
|
|
50
|
+
"minItems": 1,
|
|
51
|
+
"uniqueItems": true
|
|
52
|
+
}
|
|
47
53
|
}
|
|
48
54
|
},
|
|
49
55
|
"theme": {
|
|
@@ -115,6 +115,14 @@
|
|
|
115
115
|
"type": "object",
|
|
116
116
|
"additionalProperties": false,
|
|
117
117
|
"properties": {
|
|
118
|
+
"style": {
|
|
119
|
+
"enum": [
|
|
120
|
+
"clean-neutral",
|
|
121
|
+
"business-corporate",
|
|
122
|
+
"navy-ocean",
|
|
123
|
+
"dark-edgy"
|
|
124
|
+
]
|
|
125
|
+
},
|
|
118
126
|
"palette": { "type": "string", "minLength": 1 },
|
|
119
127
|
"visualProfile": { "type": "string", "minLength": 1 },
|
|
120
128
|
"suppliedBundlePath": {
|
|
@@ -178,6 +178,14 @@
|
|
|
178
178
|
"additionalProperties": false,
|
|
179
179
|
"required": ["derived"],
|
|
180
180
|
"properties": {
|
|
181
|
+
"style": {
|
|
182
|
+
"enum": [
|
|
183
|
+
"clean-neutral",
|
|
184
|
+
"business-corporate",
|
|
185
|
+
"navy-ocean",
|
|
186
|
+
"dark-edgy"
|
|
187
|
+
]
|
|
188
|
+
},
|
|
181
189
|
"palette": { "type": "string", "minLength": 1 },
|
|
182
190
|
"visualProfile": { "type": "string", "minLength": 1 },
|
|
183
191
|
"derived": { "type": "boolean" },
|
|
@@ -12,7 +12,12 @@ const DECISIONS = new Map([
|
|
|
12
12
|
['rejected', 'rejected'],
|
|
13
13
|
]);
|
|
14
14
|
|
|
15
|
-
export async function resolveContentApproval(
|
|
15
|
+
export async function resolveContentApproval(
|
|
16
|
+
run,
|
|
17
|
+
mode,
|
|
18
|
+
reviewedSource,
|
|
19
|
+
authorResultPaths,
|
|
20
|
+
) {
|
|
16
21
|
assertRun(run);
|
|
17
22
|
if (!MODES.has(mode)) {
|
|
18
23
|
throw new Error('Content approval mode must be interactive or unattended.');
|
|
@@ -21,6 +26,7 @@ export async function resolveContentApproval(run, mode, reviewedSource) {
|
|
|
21
26
|
const previous = await readPrevious(run);
|
|
22
27
|
let record;
|
|
23
28
|
if (mode === 'unattended') {
|
|
29
|
+
assertAuthorResultPaths(authorResultPaths);
|
|
24
30
|
const provenance =
|
|
25
31
|
reviewedSource ?? approvedSourceProvenance(run.request.factBase);
|
|
26
32
|
assertProvenance(provenance);
|
|
@@ -30,6 +36,7 @@ export async function resolveContentApproval(run, mode, reviewedSource) {
|
|
|
30
36
|
mode,
|
|
31
37
|
status: 'approved',
|
|
32
38
|
reviewedSource: structuredClone(provenance),
|
|
39
|
+
authorResultPaths: [...authorResultPaths],
|
|
33
40
|
attempts: previous?.attempts ?? [],
|
|
34
41
|
};
|
|
35
42
|
} else if (reviewedSource === undefined) {
|
|
@@ -164,6 +171,24 @@ function assertProvenance(value) {
|
|
|
164
171
|
}
|
|
165
172
|
}
|
|
166
173
|
|
|
174
|
+
function assertAuthorResultPaths(value) {
|
|
175
|
+
if (
|
|
176
|
+
!Array.isArray(value) ||
|
|
177
|
+
value.length === 0 ||
|
|
178
|
+
new Set(value).size !== value.length ||
|
|
179
|
+
value.some(
|
|
180
|
+
(path) =>
|
|
181
|
+
typeof path !== 'string' ||
|
|
182
|
+
!/^source\/author\/[^/]+\.json$/.test(path) ||
|
|
183
|
+
path.includes('..'),
|
|
184
|
+
)
|
|
185
|
+
) {
|
|
186
|
+
throw new Error(
|
|
187
|
+
'Unattended content approval requires unique source/author result paths.',
|
|
188
|
+
);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
167
192
|
function assertRun(run) {
|
|
168
193
|
if (
|
|
169
194
|
!isObject(run) ||
|