@n8r/surface 0.1.0-experimental.2 → 0.1.0-experimental.5
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 +30 -4
- package/dist/cli.js +174 -22
- package/dist/codec.d.ts +2 -0
- package/dist/codec.js +22 -7
- package/dist/codex.d.ts +1 -1
- package/dist/codex.js +26 -10
- package/dist/contracts.d.ts +108 -2
- package/dist/cyclonedx-schemas/bom-1.7.schema.json +6700 -0
- package/dist/cyclonedx-schemas/cryptography-defs.schema.json +576 -0
- package/dist/cyclonedx-schemas/jsf-0.82.schema.json +240 -0
- package/dist/cyclonedx-schemas/spdx.schema.json +786 -0
- package/dist/cyclonedx-validation.d.ts +1 -0
- package/dist/cyclonedx-validation.js +45 -0
- package/dist/html.js +27 -3
- package/dist/recent.d.ts +9 -0
- package/dist/recent.js +71 -0
- package/dist/revisions.js +42 -0
- package/dist/skill-artifacts-cli.d.ts +1 -0
- package/dist/skill-artifacts-cli.js +13 -0
- package/dist/skill-artifacts.d.ts +15 -0
- package/dist/skill-artifacts.js +184 -0
- package/dist/skill-cyclonedx.d.ts +26 -0
- package/dist/skill-cyclonedx.js +214 -0
- package/dist/skill-presentation.d.ts +10 -0
- package/dist/skill-presentation.js +108 -0
- package/dist/skill-surface-cli.d.ts +1 -0
- package/dist/skill-surface-cli.js +37 -0
- package/dist/skill-surface-store.d.ts +7 -0
- package/dist/skill-surface-store.js +126 -0
- package/dist/surface-bom.d.ts +73 -0
- package/dist/surface-bom.js +139 -0
- package/dist/surface-draft.d.ts +6 -3
- package/dist/surface-draft.js +20 -3
- package/dist/surface-instructions.d.ts +2 -1
- package/dist/surface-instructions.js +10 -1
- package/dist/surface-overview.d.ts +15 -0
- package/dist/surface-overview.js +86 -0
- package/dist/surface-store.d.ts +5 -7
- package/dist/surface-store.js +34 -2
- package/dist/surface-view.d.ts +3 -0
- package/dist/surface-view.js +50 -0
- package/dist/validate.js +298 -0
- package/docs/n8r-surface/cli-bundles.md +72 -0
- package/docs/n8r-surface/command-outcomes.md +151 -4
- package/docs/n8r-surface/contracts.md +10 -0
- package/docs/n8r-surface/critical-path.md +21 -0
- package/docs/n8r-surface/first-use-access.md +143 -0
- package/docs/n8r-surface/first-use-overview.md +262 -0
- package/docs/n8r-surface/getting-started.md +55 -88
- package/docs/n8r-surface/guided-journey-verification.md +137 -0
- package/docs/n8r-surface/implementation-decisions.md +14 -14
- package/docs/n8r-surface/instance-first-research.md +209 -0
- package/docs/n8r-surface/npm-distribution.md +39 -69
- package/docs/n8r-surface/npm-release.md +141 -14
- package/docs/n8r-surface/product-direction.md +327 -0
- package/docs/n8r-surface/researcher-skill.md +105 -51
- package/docs/n8r-surface/security-assurance-strategy.md +267 -0
- package/docs/n8r-surface/skill-bom-verification.md +142 -0
- package/docs/n8r-surface/skill-cyclonedx-verification.md +144 -0
- package/docs/n8r-surface/skill-cyclonedx.md +85 -0
- package/docs/n8r-surface/skill-manual.md +129 -0
- package/docs/n8r-surface/skill-surface-artifacts.md +234 -0
- package/docs/n8r-surface/skill-usefulness-verification.md +135 -0
- package/docs/n8r-surface/skill-workspace-automation.md +359 -0
- package/docs/n8r-surface/surface-description-contract.md +224 -0
- package/docs/n8r-surface/surface-descriptions.md +173 -0
- package/docs/n8r-surface/surface-relationships.md +231 -0
- package/docs/n8r-surface/tester-candidate.md +158 -0
- package/docs/n8r-surface/versioning.md +55 -66
- package/docs/n8r-surface/workspace-human-check.md +101 -0
- package/docs/n8r-surface/workspace-installation.md +68 -0
- package/docs/n8r-surface/workspace-verification.md +350 -0
- package/docs/n8r-surface/workspace.md +83 -0
- package/examples/researcher/README.md +8 -0
- package/examples/researcher/cyclonedx/configured/README.md +7 -0
- package/examples/researcher/cyclonedx/configured/manifest.json +10 -0
- package/examples/researcher/cyclonedx/configured/mapping.json +323 -0
- package/examples/researcher/cyclonedx/configured/surface-records.json +1275 -0
- package/examples/researcher/cyclonedx/configured/surface.cdx.json +79 -0
- package/examples/researcher/descriptions/README.md +29 -0
- package/examples/researcher/descriptions/bound-r1.json +141 -0
- package/examples/researcher/descriptions/bound-r2.json +153 -0
- package/examples/researcher/descriptions/capability.json +167 -0
- package/examples/researcher/descriptions/research-r1.json +153 -0
- package/examples/researcher/descriptions/research-r2.json +157 -0
- package/examples/researcher/descriptions/sources.md +24 -0
- package/examples/researcher/relationships/README.md +34 -0
- package/examples/researcher/relationships/bound-r1.json +346 -0
- package/examples/researcher/relationships/bound-r2.json +358 -0
- package/examples/researcher/relationships/capability.json +325 -0
- package/examples/researcher/relationships/config/assistant.env.example +4 -0
- package/examples/researcher/relationships/research-r1.json +300 -0
- package/examples/researcher/relationships/research-r2.json +304 -0
- package/examples/researcher/relationships/sources.md +38 -0
- package/examples/researcher/surface-bom/README.md +17 -0
- package/examples/researcher/surface-bom/initial.cdx.json +188 -0
- package/package.json +1 -1
- package/plugins/n8r-surface/.codex-plugin/plugin.json +2 -2
- package/plugins/n8r-surface/LICENSING.md +3 -0
- package/plugins/n8r-surface/plugin.json +2 -2
- package/plugins/n8r-surface/skills/research/SKILL.md +79 -38
- package/plugins/n8r-surface/skills/research/references/artifacts.md +152 -0
- package/plugins/n8r-surface/skills/research/references/cyclonedx.md +207 -0
- package/plugins/n8r-surface/skills/research/references/discovery-map.md +20 -2
- package/plugins/n8r-surface/skills/research/references/examples/bound-r1.json +346 -0
- package/plugins/n8r-surface/skills/research/references/examples/capability.json +325 -0
- package/plugins/n8r-surface/skills/research/references/examples/research-r1.json +300 -0
- package/plugins/n8r-surface/skills/research/references/examples/surface.cdx.json +188 -0
- package/plugins/n8r-surface/skills/research/references/first-use-access.md +97 -0
- package/plugins/n8r-surface/skills/research/references/first-use-overview.md +101 -0
- package/plugins/n8r-surface/skills/research/references/instance-first.md +125 -0
- package/plugins/n8r-surface/skills/research/references/working-notes.md +6 -1
- package/plugins/n8r-surface/skills/research/references/workspace.md +89 -0
- package/plugins/n8r-surface/skills/research/scripts/THIRD-PARTY-NOTICES.txt +273 -0
- package/plugins/n8r-surface/skills/research/scripts/artifacts.mjs +8348 -0
- package/plugins/n8r-surface/skills/research/scripts/cyclonedx.mjs +28113 -0
- package/plugins/n8r-surface/skills/research/scripts/surface.mjs +27800 -0
- package/plugins/n8r-surface/skills/research/scripts/workspace.mjs +120 -0
|
@@ -0,0 +1,359 @@
|
|
|
1
|
+
# Installed Researcher workspace acceptance
|
|
2
|
+
|
|
3
|
+
Issue [#43](https://github.com/injectionator/n8r-surface/issues/43) binds only the
|
|
4
|
+
first three [canonical scenarios](../../tests/acceptance/skill-workspace.feature)
|
|
5
|
+
to Cucumber: create, repeat setup and fresh-session reopen. The other scenarios
|
|
6
|
+
remain manual. Ordinary `npm test` is offline and never starts inference.
|
|
7
|
+
|
|
8
|
+
## Scope and interface
|
|
9
|
+
|
|
10
|
+
The runner uses **Codex CLI 0.166.0 app-server over stdio**, not the desktop UI
|
|
11
|
+
and not the standalone n8r command. It requires an enabled installed Researcher
|
|
12
|
+
**0.1.9**, byte-identical to source commit
|
|
13
|
+
`3cb08f59a4a932121bdd1c742fbac724d12a6d74`. The default installation is the normal
|
|
14
|
+
Codex plugin cache. `--installed PATH --revision FULL_COMMIT` can select another
|
|
15
|
+
already-installed, byte-verified 0.1.9 candidate. The runner never installs or
|
|
16
|
+
replaces a plugin. See the [installation procedure](workspace-installation.md).
|
|
17
|
+
|
|
18
|
+
The [documented skill input](https://developers.openai.com/codex/app-server#skills)
|
|
19
|
+
loads the discovered installed SKILL.md. The harness supplies only the selected
|
|
20
|
+
folder and scenario request. The model reads the skill reference and chooses the
|
|
21
|
+
installed helper invocation; the harness never invokes the helper or writes
|
|
22
|
+
workspace identity metadata. Its sole content write is the synthetic user note
|
|
23
|
+
between create and repeat.
|
|
24
|
+
|
|
25
|
+
One ephemeral thread holds create and repeat. Reopen starts another app-server
|
|
26
|
+
process and empty ephemeral thread, with no copied transcript, expected identity
|
|
27
|
+
or answer. The first process is closed; the second must fail to read the old
|
|
28
|
+
thread through `thread/read`. The
|
|
29
|
+
[permission profile](https://learn.chatgpt.com/docs/permissions) grants writes only
|
|
30
|
+
to the disposable workspace and reads to the installed plugin and runtime paths.
|
|
31
|
+
It denies access to retained evidence; a sandbox command checks allowed skill
|
|
32
|
+
reads and denied evidence reads before each session, including the actual setup
|
|
33
|
+
receipt before reopen. This technical probe never invokes the workspace helper.
|
|
34
|
+
|
|
35
|
+
Memories, project instructions, apps, configured MCP servers, browser/computer
|
|
36
|
+
access, remote control, multi-agent/history features and web search are disabled.
|
|
37
|
+
The normal sign-in is used by the host, never copied into fixtures or receipts.
|
|
38
|
+
Local commands receive a restricted environment. Command network access is off;
|
|
39
|
+
Codex authentication and model service traffic still need network access.
|
|
40
|
+
|
|
41
|
+
These controls establish the tested CLI boundary, not a general sandbox security
|
|
42
|
+
certification. Runtime paths remain readable. The Codex service processes the
|
|
43
|
+
conversation. No claim is made about desktop behavior, other hosts, or complete
|
|
44
|
+
system-wide file auditing.
|
|
45
|
+
|
|
46
|
+
## Run the three scenarios
|
|
47
|
+
|
|
48
|
+
Maintainer prerequisites: Node.js 22, 24 or 26; Git; `npm ci`; Codex CLI 0.166.0
|
|
49
|
+
signed in with ChatGPT; the identified plugin installed/enabled; a configured
|
|
50
|
+
available OpenAI model. The runner records the selected model and refuses a
|
|
51
|
+
provider fallback. A live run consumes account inference allowance and may incur
|
|
52
|
+
cost under the account's terms. It is opt-in and is not scheduled in CI.
|
|
53
|
+
|
|
54
|
+
From the repository root, on the branch under test:
|
|
55
|
+
|
|
56
|
+
```sh
|
|
57
|
+
npm run acceptance:skill -- --live --evidence .local/skill-acceptance/run-1
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
The evidence directory must not already exist. Create its parent first if needed:
|
|
61
|
+
`mkdir -p .local/skill-acceptance`. Keep it private and ignored. A second run uses
|
|
62
|
+
a new evidence directory and automatically creates a new disposable workspace:
|
|
63
|
+
|
|
64
|
+
```sh
|
|
65
|
+
npm run acceptance:skill -- --live --evidence .local/skill-acceptance/run-2
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
There are at most three user turns, one per scenario, each limited to 120 seconds,
|
|
69
|
+
and a 600-second suite limit. No simulated user, retries or automatic conversation
|
|
70
|
+
repair are used. A missing capability, unexpected host question or unanswered
|
|
71
|
+
setup question is a failure/blocker; dependent scenarios cannot pass.
|
|
72
|
+
|
|
73
|
+
The runner reports **automated** results separately from full Gherkin acceptance.
|
|
74
|
+
Independent checks compare the saved format, UUID, folder-derived name, supplied
|
|
75
|
+
purpose, complete entry lists, hashes and file timestamps. They compare helper
|
|
76
|
+
receipts and assistant identity/location claims with filesystem readback. This
|
|
77
|
+
detects changed-note and wrong-identity evidence without a model grader.
|
|
78
|
+
|
|
79
|
+
Semantic criteria, such as useful continuation, accurate attachment claims and
|
|
80
|
+
absence of unnecessary questions, remain **pending human review**. Each scenario
|
|
81
|
+
runs its automated checks before an After hook marks it pending. Cucumber's
|
|
82
|
+
passing intermediate steps are not full scenario acceptance. No pending criterion
|
|
83
|
+
is counted as passed by default.
|
|
84
|
+
|
|
85
|
+
Exit codes:
|
|
86
|
+
|
|
87
|
+
- **1:** at least one automated scenario or final installation check failed.
|
|
88
|
+
- **2:** blocked prerequisites, or automated checks passed but human review is
|
|
89
|
+
pending. Inspect `results.json` and `blocked.json` to distinguish these cases.
|
|
90
|
+
- **0:** successful owned-fixture cleanup. Offline report and review modes have
|
|
91
|
+
their own exit meanings below. A live run does not claim full human
|
|
92
|
+
acceptance and therefore does not return 0 in this increment.
|
|
93
|
+
|
|
94
|
+
## Evidence and human verification
|
|
95
|
+
|
|
96
|
+
The evidence directory contains run/install identity once (`metadata.json`), raw
|
|
97
|
+
app-server requests/events, each turn, before/after inventories, final metadata,
|
|
98
|
+
Cucumber JSON and individual results with outstanding review criteria. Failed
|
|
99
|
+
attempts get their own directory; rerunning never overwrites them. Paths, model
|
|
100
|
+
responses and tool receipts are private: do not commit these files or paste raw
|
|
101
|
+
receipts into public issues/PRs. Review and sanitize any published summary.
|
|
102
|
+
|
|
103
|
+
Tester steps, after the maintainer has prepared the prerequisites above:
|
|
104
|
+
|
|
105
|
+
- [ ] Run the first command from the repository root. Expect three automated
|
|
106
|
+
results and exit 2 when all automated checks pass with human review pending.
|
|
107
|
+
An automated failure, skipped prerequisite or `blocked.json` is not a pass.
|
|
108
|
+
- [ ] Open `results.json`, `1-turn.json`, `2-turn.json` and `3-turn.json` in the
|
|
109
|
+
selected private evidence directory. For each result, inspect the listed
|
|
110
|
+
`reviewRequired` criteria against actual responses and tool activity.
|
|
111
|
+
Expect creation only, recognition on repeat, and useful readiness orientation
|
|
112
|
+
on reopen. No research, credentials request, attachment claim or repeated
|
|
113
|
+
setup permission question should occur. Use the
|
|
114
|
+
[existing experience rubric](workspace-human-check.md#independent-evidence-and-report).
|
|
115
|
+
- [ ] Open the inventory files and `final-record.json`. Expect only identity
|
|
116
|
+
metadata after create, then that metadata plus the synthetic note, unchanged
|
|
117
|
+
through repeat/reopen. Inspect `setup.jsonl` and `reopen.jsonl` for the installed
|
|
118
|
+
helper path, denied-evidence probes and distinct empty ephemeral sessions.
|
|
119
|
+
- [ ] Run again with `run-2`. Expect the same observable outcomes with a different
|
|
120
|
+
disposable destination, UUID, session IDs and timings. These values may vary;
|
|
121
|
+
preservation within one journey must not vary.
|
|
122
|
+
- [ ] Report **Pass / Fail / Blocked** per scenario, including the reviewed run
|
|
123
|
+
directory and criterion, without publishing private transcripts. An automated
|
|
124
|
+
pass with unreviewed criteria is **Pending**, not human acceptance.
|
|
125
|
+
|
|
126
|
+
After preserving/reviewing evidence, clean only the owned disposable fixture:
|
|
127
|
+
|
|
128
|
+
```sh
|
|
129
|
+
npm run acceptance:skill -- --cleanup --evidence .local/skill-acceptance/run-1
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
Expected: exit 0 and “Removed owned fixture only; evidence retained.” Cleanup
|
|
133
|
+
requires the recorded ownership token and final inventory, refuses other roots,
|
|
134
|
+
and leaves the evidence, normal installation and earlier trials untouched.
|
|
135
|
+
|
|
136
|
+
## Offline checker tests
|
|
137
|
+
|
|
138
|
+
```sh
|
|
139
|
+
node --test tests/skill-acceptance.test.mjs
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
These tests deliberately substitute an incorrect identity, alter a synthetic note
|
|
143
|
+
and timestamp, add a file, remove/fail the installed helper receipt, and fail a
|
|
144
|
+
scenario prerequisite. They validate the assertions; they are not installed-skill
|
|
145
|
+
acceptance runs. They also run in the normal offline `npm test` suite.
|
|
146
|
+
|
|
147
|
+
## Development evidence — 8 November 2026
|
|
148
|
+
|
|
149
|
+
Initial live rehearsals used macOS, Node 26.13.0, Codex CLI 0.166.0 and the
|
|
150
|
+
configured `gpt-6-astra` model (medium effort). The normal installed Researcher
|
|
151
|
+
0.1.9 matched all 14 files at the pinned revision before use. No installation
|
|
152
|
+
replacement, desktop claim, merge or release was involved.
|
|
153
|
+
|
|
154
|
+
Failed attempts are retained privately:
|
|
155
|
+
|
|
156
|
+
| Attempt | Observed result |
|
|
157
|
+
| --- | --- |
|
|
158
|
+
| Initial interface probe | Installed skill selected its helper; Node could not read its system OpenSSL configuration. Destination remained empty. |
|
|
159
|
+
| Permission probe launch | Nested config was incorrectly serialized as JSON rather than TOML; server did not start. |
|
|
160
|
+
| First runner preflight | The harness incorrectly rejected the standard configured endpoint; no inference. An offline regression test now covers it. |
|
|
161
|
+
| First full journey | Create passed. Repeat preserved files/identity but the checker wrongly demanded the absolute path again rather than allowing “selected folder.” Reopen was blocked by that failed prerequisite. The corrected assertion retains the create location requirement. |
|
|
162
|
+
|
|
163
|
+
Two later fresh-fixture journeys passed all three automated scenarios:
|
|
164
|
+
|
|
165
|
+
| Private run label | Create | Repeat | Fresh reopen | Full Gherkin result |
|
|
166
|
+
| --- | --- | --- | --- | --- |
|
|
167
|
+
| run-3 | 17.842 s | 11.881 s | 16.574 s | Pending human review |
|
|
168
|
+
| run-4 | 21.449 s | 12.872 s | 18.257 s | Pending human review |
|
|
169
|
+
|
|
170
|
+
These are developing-agent rehearsals, not PM acceptance. They used a dirty
|
|
171
|
+
checkout during implementation; run-4 records complete harness file digests.
|
|
172
|
+
A subsequent startup-deadline fix has an offline regression test; the committed
|
|
173
|
+
rehearsals below include that fix. The maintained feature text is
|
|
174
|
+
unchanged apart from selection tags. Checker tests demonstrate rejection of
|
|
175
|
+
incorrect identity, altered notes, ambiguous isolation failures, malformed output
|
|
176
|
+
and unsafe cleanup. The runner leaves human criteria pending instead of treating
|
|
177
|
+
these tests or filesystem results as full conversational acceptance.
|
|
178
|
+
|
|
179
|
+
### Committed-code repetitions
|
|
180
|
+
|
|
181
|
+
Both runs below exercised clean commit
|
|
182
|
+
`d9c99c4e9853ca407264f126a9dd2aa6b8599df4`, with identical harness digests and
|
|
183
|
+
the environment/installed revision above. Each used a fresh disposable fixture,
|
|
184
|
+
a different generated identity, and separate setup/reopen processes. Both exited
|
|
185
|
+
2 with all automated checks passed and all full scenarios pending human review.
|
|
186
|
+
|
|
187
|
+
| Private run label | Create | Repeat | Fresh reopen |
|
|
188
|
+
| --- | --- | --- | --- |
|
|
189
|
+
| run-5 | 18.251 s | 8.713 s | 17.801 s |
|
|
190
|
+
| run-6 | 17.966 s | 8.431 s | 14.814 s |
|
|
191
|
+
|
|
192
|
+
Independent readback confirmed unchanged repeat/reopen inventories, global
|
|
193
|
+
settings fingerprints and installed bytes. Both reopen receipts retain the exact
|
|
194
|
+
missing-thread error and denied evidence reads. Agent inspection of the messages
|
|
195
|
+
found orientation, no repeated initialization question, honest attachment/access
|
|
196
|
+
boundaries and no research activity. This is an agent assessment, not PM acceptance;
|
|
197
|
+
the runner correctly leaves those human criteria pending. The documented cleanup
|
|
198
|
+
command then removed both owned fixtures, exited 0 and retained all evidence.
|
|
199
|
+
|
|
200
|
+
A deliberately missing installation exited 2 before inference and marked all
|
|
201
|
+
three scenarios blocked. All 153 offline tests passed, including 14 acceptance
|
|
202
|
+
checker/adapter tests. The package check passed locally on Node 26.13.0. CI for
|
|
203
|
+
`d9c99c4` passed Node 22/24/26, fixtures/tooling, Markdown and local links. Local
|
|
204
|
+
Markdown lint, lychee 0.24.2 offline links/anchors, citation validation and diff
|
|
205
|
+
checks also passed. No live inference was run by CI.
|
|
206
|
+
|
|
207
|
+
### Human acceptance — 8 November 2026
|
|
208
|
+
|
|
209
|
+
The user ran the documented command from clean commit
|
|
210
|
+
`77b1bc49108c2741e012cf1d6b5ca43e3cee97ab` on macOS with Node 22.23.2,
|
|
211
|
+
Codex CLI 0.166.0 and `gpt-6-astra`. The installed Researcher remained 0.1.9
|
|
212
|
+
at the pinned revision above. All three automated scenarios passed.
|
|
213
|
+
|
|
214
|
+
After reviewing the actual final responses and relevant tool activity presented
|
|
215
|
+
from that run, the user explicitly accepted **create, repeat setup and
|
|
216
|
+
fresh-session reopen: Pass**. The user also accepted the reopen turn's denied
|
|
217
|
+
attempt to read the unrelated Superpowers skill; its read returned exit 1 and
|
|
218
|
+
the Researcher inspection subsequently succeeded. Recorded metadata/note
|
|
219
|
+
inventories and global-settings fingerprints were unchanged through the
|
|
220
|
+
applicable checks. Scenario durations were 16.998, 10.737 and 19.492 seconds.
|
|
221
|
+
|
|
222
|
+
This is human acceptance of the reviewed run, separate from the earlier agent
|
|
223
|
+
rehearsals. A private acceptance receipt accompanies the original run evidence;
|
|
224
|
+
the raw Cucumber pending results remain unchanged as the historical automated
|
|
225
|
+
output. Future runs still require their own human review. The user authorized
|
|
226
|
+
PR #44 to become ready for review, not merge or release.
|
|
227
|
+
|
|
228
|
+
## Readable reports and recorded human verdicts
|
|
229
|
+
|
|
230
|
+
The follow-up in [#45](https://github.com/injectionator/n8r-surface/issues/45)
|
|
231
|
+
adds a private `review.md` after live-run finalization. It contains each actual
|
|
232
|
+
final response, user input, commentary, tool commands and results, including
|
|
233
|
+
failed or denied operations. Successful tool outputs and technical session
|
|
234
|
+
receipts are expandable in Markdown viewers supporting HTML details; their full
|
|
235
|
+
text remains in the file. Failed outputs remain visible. Missing evidence is
|
|
236
|
+
explicit. No model generates the report or judges the interaction.
|
|
237
|
+
|
|
238
|
+
The runner prints the report path and a SHA-256 **run fingerprint**. The companion
|
|
239
|
+
`review-manifest.json` binds the evidence file names/bytes and the report bytes.
|
|
240
|
+
These files contain private machine paths and transcripts: retain them with the
|
|
241
|
+
ignored run directory, not in public commits. Existing reports are verified,
|
|
242
|
+
never silently regenerated over different evidence.
|
|
243
|
+
|
|
244
|
+
To generate or verify a report for a retained run without inference:
|
|
245
|
+
|
|
246
|
+
```sh
|
|
247
|
+
npm run acceptance:skill -- --report --evidence .local/skill-acceptance/run-1
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
Expected: exit 0 when the report is successfully generated or verified, with the
|
|
251
|
+
report path, fingerprint and automated status. Exit 0 here means reporting worked,
|
|
252
|
+
not that the scenario passed. A blocked run can have a valid readable report.
|
|
253
|
+
Missing required evidence prevents an overall Pass. Once a verdict receipt exists,
|
|
254
|
+
this command also shows the three human verdicts and combined overall status.
|
|
255
|
+
|
|
256
|
+
### Human review task list
|
|
257
|
+
|
|
258
|
+
Prerequisite: a completed run from the command above or the live command. No new
|
|
259
|
+
Codex sign-in, network access or inference is needed for report/review commands.
|
|
260
|
+
From the repository root:
|
|
261
|
+
|
|
262
|
+
- [ ] Run `--report` as shown above and open the printed `review.md` path. Read
|
|
263
|
+
each scenario's human criteria, actual final response and tool activity.
|
|
264
|
+
Inspect any failed commands and preservation warnings. Expect the same actual
|
|
265
|
+
responses as the retained turn receipts; there are no invented summaries.
|
|
266
|
+
- [ ] Copy the report's run fingerprint. Choose **Pass**, **Fail** or **Blocked**
|
|
267
|
+
independently for create, repeat and reopen. The command below shows all Pass
|
|
268
|
+
only as an example; replace each verdict with your actual judgment, replace
|
|
269
|
+
the fingerprint and reviewer, and use the optional comment for any caveats:
|
|
270
|
+
|
|
271
|
+
```sh
|
|
272
|
+
npm run acceptance:skill -- --review \
|
|
273
|
+
--evidence .local/skill-acceptance/run-1 \
|
|
274
|
+
--run COPY_THE_64_CHARACTER_RUN_FINGERPRINT \
|
|
275
|
+
--reviewer 'Your name' \
|
|
276
|
+
--create Pass --repeat Pass --reopen Pass \
|
|
277
|
+
--comment 'Reviewed the actual responses and tool activity.'
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
Expect a separate `human-review.json` containing the run fingerprint, report
|
|
281
|
+
digest, reviewer, date/time, each verdict and comment. The terminal shows
|
|
282
|
+
automated status, human verdicts and overall status together. **Pass → exit 0;
|
|
283
|
+
Fail → exit 1; Blocked → exit 2.** A human Pass cannot override an automated
|
|
284
|
+
failure, final preservation error, missing evidence or blocked prerequisite.
|
|
285
|
+
- [ ] Run `--report` again. Expect verification of the unchanged evidence/report
|
|
286
|
+
and the recorded human verdicts. Original Cucumber JSON and pending results
|
|
287
|
+
remain untouched; a verdict receipt does not retroactively alter execution.
|
|
288
|
+
- [ ] Report **Pass / Fail / Blocked** for this review workflow with the private
|
|
289
|
+
run reference and any failed step. If commands refuse modified evidence, an
|
|
290
|
+
incorrect fingerprint or a duplicate review, that is the expected protection;
|
|
291
|
+
retain the refusal when reporting a problem. Do not publish raw private files.
|
|
292
|
+
|
|
293
|
+
Only one review receipt is supported per run in this increment. Duplicate
|
|
294
|
+
submissions refuse to overwrite it. A correction workflow, reviewer identity
|
|
295
|
+
verification and signed audit records are out of scope. A reviewer name is a
|
|
296
|
+
self-attribution, not authentication. Fingerprints detect drift relative to the
|
|
297
|
+
retained manifest; they do not make files tamper-proof against someone able to
|
|
298
|
+
rewrite both evidence and manifest. Evidence must be quiescent while reporting
|
|
299
|
+
and reviewing; concurrent writers are unsupported.
|
|
300
|
+
|
|
301
|
+
Owned-fixture cleanup still uses `--cleanup`. It retains reports and verdicts;
|
|
302
|
+
its later `cleanup.json` receipt is excluded from the evidence fingerprint. The
|
|
303
|
+
three generated review files are also excluded from that fingerprint, with
|
|
304
|
+
report bytes bound separately. All other evidence files are included. Symlinks,
|
|
305
|
+
nested entries and files over 64 MiB are refused. Historical manually written
|
|
306
|
+
acceptance receipts are preserved, not automatically imported as new approval.
|
|
307
|
+
|
|
308
|
+
Offline report/review checks:
|
|
309
|
+
|
|
310
|
+
```sh
|
|
311
|
+
node --test tests/skill-review.test.mjs
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
These tests use synthetic reviewer names and verdicts. They do not establish
|
|
315
|
+
human acceptance of any real run. Live execution retains its existing pending
|
|
316
|
+
exit behavior; `--review` is the separate acceptance step.
|
|
317
|
+
|
|
318
|
+
### Report/review development evidence — 8 November 2026
|
|
319
|
+
|
|
320
|
+
The observed baseline was the user's accepted #43 run: an agent had to extract
|
|
321
|
+
responses/tools from JSON for human review. The new offline report command was
|
|
322
|
+
exercised against that retained real run and a retained missing-installation run;
|
|
323
|
+
they reported automated Pass and Blocked respectively without new inference or
|
|
324
|
+
rewriting raw evidence. The earlier manual acceptance receipt was preserved and
|
|
325
|
+
was not imported as a new command-recorded review.
|
|
326
|
+
|
|
327
|
+
A fresh installed-skill run on macOS, Node 26.13.0, Codex CLI 0.166.0 and the
|
|
328
|
+
configured `gpt-6-astra` model passed all three automated scenarios and generated
|
|
329
|
+
the report automatically. The installed 0.1.9 plugin matched the same pinned
|
|
330
|
+
revision before and after. This was a development checkout with harness file
|
|
331
|
+
hashes retained privately, not a clean-commit or human acceptance claim.
|
|
332
|
+
|
|
333
|
+
The agent checked every final response and command against the readable report,
|
|
334
|
+
then exercised the documented review command using reviewer name
|
|
335
|
+
“Codex agent rehearsal (not human acceptance)” and an explicit rehearsal comment.
|
|
336
|
+
It recorded three Pass verdicts, exited 0 and displayed separate automated/human
|
|
337
|
+
results. Offline report verification still succeeded after owned-fixture cleanup;
|
|
338
|
+
raw results and all evidence remained retained. These verdicts test the recording
|
|
339
|
+
workflow; they are not the user's acceptance of this increment.
|
|
340
|
+
|
|
341
|
+
Focused offline checks cover changed/missing evidence, wrong fingerprints,
|
|
342
|
+
modified reports, invalid/duplicate reviews, blocked/failing aggregation, null or
|
|
343
|
+
empty required evidence, and interrupted-turn tool recovery from session receipts.
|
|
344
|
+
The latter two cases were found in fresh review, corrected and regression-tested.
|
|
345
|
+
All 171 offline tests passed, including 18 report/review cases; the installed
|
|
346
|
+
package check also passed on Node 26.13.0. No new dependencies or live CI were added.
|
|
347
|
+
|
|
348
|
+
A second fresh run exercised clean commit `1eb4cae` with the same environment
|
|
349
|
+
and installed skill. All three automated scenarios passed in 52.7 seconds;
|
|
350
|
+
live execution retained its pending-human status. The agent inspected the actual
|
|
351
|
+
responses, tool activity, preservation and isolation receipts, then recorded an
|
|
352
|
+
explicitly labeled agent rehearsal with three Pass verdicts (exit 0). Cleanup
|
|
353
|
+
and offline report verification both exited 0, preserving the exact fingerprint
|
|
354
|
+
and recorded verdicts. This does not establish desktop or human acceptance.
|
|
355
|
+
|
|
356
|
+
A later offline regression caught an evidence file named `__proto__` being omitted
|
|
357
|
+
from a plain JavaScript object's hash map. Null-prototype maps now include that
|
|
358
|
+
filename; changing its contents is detected. The final narrow fix was verified
|
|
359
|
+
by the offline suite rather than another live inference run.
|
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
# Capability and Bound Surface contract 0.2
|
|
2
|
+
|
|
3
|
+
This bounded library contract implements [#50](https://github.com/injectionator/n8r-surface/issues/50)
|
|
4
|
+
within the one AI Surface Model. It supports the [agreed delivery intent](surface-descriptions.md),
|
|
5
|
+
not a universal schema or a released Researcher workflow. The standalone skill
|
|
6
|
+
must not call or depend on the `n8r-surface` CLI. Skill artifact production is #51;
|
|
7
|
+
installed-workflow and human acceptance are #52. Observed Surface remains deferred.
|
|
8
|
+
|
|
9
|
+
For the revised #50 verification, start with [shared relationships 0.3](surface-relationships.md).
|
|
10
|
+
This earlier bounded profile and its fixtures remain readable without alteration;
|
|
11
|
+
`0.3` adds consistent node/edge metadata across both descriptions.
|
|
12
|
+
|
|
13
|
+
## Versions and shared representation
|
|
14
|
+
|
|
15
|
+
`n8r.surface/0.2` requires `kind: "capability"` or `kind: "bound"`. It neither
|
|
16
|
+
reinterprets nor replaces `n8r.surface/0.1` selected definitions. Older readers
|
|
17
|
+
reject it. Do not change the version string to downgrade: doing so loses possible
|
|
18
|
+
versus configured meaning, exclusive alternatives, conflicts and instance identity.
|
|
19
|
+
There is no automatic conversion. Keep the original when making a separately
|
|
20
|
+
reviewed projection. Package versions and artifact contract versions are distinct.
|
|
21
|
+
|
|
22
|
+
Reuse the [0.1 envelope, research records and logical digests](contracts.md).
|
|
23
|
+
All fields below are required; empty arrays are permitted except where specified.
|
|
24
|
+
Objects are closed. This profile requires an empty `extensions` object and has
|
|
25
|
+
no arbitrary attributes or actual-setting fields. JSON is the only encoding;
|
|
26
|
+
`encode` and `decode` reject YAML for these descriptions. Research records retain
|
|
27
|
+
their existing JSON/YAML/HTML support. No new renderer is introduced here.
|
|
28
|
+
|
|
29
|
+
| Shared field | Meaning |
|
|
30
|
+
| --- | --- |
|
|
31
|
+
| `id`, `title`, `scope`, `revision`, `extensions` | Existing envelope; `extensions` must be `{}`. |
|
|
32
|
+
| `records` | Exact research `{id, revision, digest}` references. |
|
|
33
|
+
| `vocabularies` | Unique `{id, version}` entries; terms remain vocabulary-specific. |
|
|
34
|
+
| `nodes` | `{id, label, type: {vocabulary, term}}`; useful component/target identity only. |
|
|
35
|
+
| `coverage`, `gaps` | Explicit coverage limits, missing information and next research needs. |
|
|
36
|
+
|
|
37
|
+
A basis entry is `{record, revision, items}`. `items` is nonempty and unique,
|
|
38
|
+
referring to findings, or to decisions only in the dedicated `decisions` field.
|
|
39
|
+
Referenced research revisions must occur in `records`. Source identity, version,
|
|
40
|
+
date, locator, coverage and limitations live in the research record, not copied
|
|
41
|
+
raw configuration. All IDs are opaque, stable and case-sensitive. Labels are not
|
|
42
|
+
identity matching rules. An omitted node/edge/binding is unspecified, not absent.
|
|
43
|
+
|
|
44
|
+
## Capability Surface
|
|
45
|
+
|
|
46
|
+
`kind: "capability"` adds `capabilities` and `exclusiveGroups`.
|
|
47
|
+
|
|
48
|
+
Each capability is `{id, from, to, type, state, basis, conditions, note}`. Endpoints
|
|
49
|
+
resolve to local nodes and type vocabulary resolves locally. Shared components,
|
|
50
|
+
parallel edges, cycles and self-loops are allowed. Each edge is a possible
|
|
51
|
+
relationship, never a selected composition. `conditions` lists material conditions
|
|
52
|
+
and `note` explains applicability and uncertainty. Empty conditions do not prove
|
|
53
|
+
unconditional support outside the stated scope.
|
|
54
|
+
|
|
55
|
+
| State | Evidence check |
|
|
56
|
+
| --- | --- |
|
|
57
|
+
| `possible` | Nonempty basis; all cited findings are `known`, subject equals `from`, property is `supports`, and every claim value equals the `to` node ID. |
|
|
58
|
+
| `absent` | Nonempty basis; all findings are `absent` with the same subject/property/target rule. This is scoped absence of support, not an unbound instance. |
|
|
59
|
+
| `conflicting` | Nonempty basis containing a conflicting finding; subject/property still match. Inspect all competing values in research. No target is selected. |
|
|
60
|
+
| `unknown`, `omitted`, `redacted`, `out-of-scope` | No support assertion. Any basis resolves to findings about that subject/property; notes explain the state. |
|
|
61
|
+
|
|
62
|
+
Each exclusive group is `{id, members}` with at least two distinct capability
|
|
63
|
+
IDs. It means **at most one** member may be configured in this bounded instance.
|
|
64
|
+
It does not require a selection, claim exhaustive alternatives, or resolve a
|
|
65
|
+
conflict. The synthetic authentication group is a fixture constraint, not a general
|
|
66
|
+
claim that every product makes OIDC and SAML mutually exclusive. Conditions and
|
|
67
|
+
other constraints remain human-readable; the checker does not execute them.
|
|
68
|
+
|
|
69
|
+
## Bound Surface
|
|
70
|
+
|
|
71
|
+
`kind: "bound"` adds `capability`, `instance` and `bindings`:
|
|
72
|
+
|
|
73
|
+
- `capability` pins one Capability Surface `{id, revision, digest}`.
|
|
74
|
+
- `instance` is `{id, label}` with an opaque identity distinct from the capability
|
|
75
|
+
artifact and its components. It contains no location or credentials.
|
|
76
|
+
- Each binding is `{id, capability, state, claims, decisions, note}`. The inner
|
|
77
|
+
`capability` is an edge ID in the pinned Capability Surface. One entry per
|
|
78
|
+
capability is permitted in this bounded profile.
|
|
79
|
+
- Each claim is `{target, basis}`. `target` resolves to a local Bound node; basis
|
|
80
|
+
is nonempty. A useful target label may be `MongoDB Atlas` or `OIDC service`.
|
|
81
|
+
A target need not have the same ID as the product-level capability target.
|
|
82
|
+
|
|
83
|
+
| State | Required claims |
|
|
84
|
+
| --- | --- |
|
|
85
|
+
| `configured` | Exactly one target with known configuration evidence; capability state must be `possible`. |
|
|
86
|
+
| `conflicting` | At least two distinct targets, each evidenced; no selected target. |
|
|
87
|
+
| `unknown`, `omitted`, `redacted`, `out-of-scope` | No claims; the note explains why. |
|
|
88
|
+
|
|
89
|
+
A configuration finding has `subject` equal to the opaque instance ID, `property`
|
|
90
|
+
equal to the capability edge ID and claim values equal to target node IDs. It is
|
|
91
|
+
`known` or `conflicting`. Each cited finding must include the target it supports;
|
|
92
|
+
all of that finding's competing targets must be retained in the binding. All
|
|
93
|
+
known/conflicting findings for that same instance and capability in the Bound
|
|
94
|
+
description's referenced research are checked, including uncited basis items.
|
|
95
|
+
Multiple known findings supporting different targets also form a conflict. A configured
|
|
96
|
+
binding cannot cite a conflicting finding. Missing evidence cannot become an
|
|
97
|
+
unbound assertion. Explicit unbound/absence and multi-target configured slots are
|
|
98
|
+
outside this initial binding profile; preserve such source findings in research
|
|
99
|
+
and describe the coverage limit rather than forcing them into a supported state.
|
|
100
|
+
|
|
101
|
+
`decisions` refers only to research decisions, independently of source findings.
|
|
102
|
+
A human preference is not configuration evidence and cannot resolve a source
|
|
103
|
+
conflict by itself. Corrected source evidence belongs in a new research revision.
|
|
104
|
+
Configuration suffices; no reachability, runtime use or successful deployment is
|
|
105
|
+
asserted or checked. Target suitability and the truth/coverage of source prose
|
|
106
|
+
require inspection; matching references alone do not establish those facts.
|
|
107
|
+
|
|
108
|
+
## Verification and revisions
|
|
109
|
+
|
|
110
|
+
The existing public APIs accept the new types:
|
|
111
|
+
|
|
112
|
+
- `validateArtefact(value)` checks closed shape, states, identity uniqueness,
|
|
113
|
+
local targets/vocabularies and declared research references.
|
|
114
|
+
- `verifyReferences(value, context)` additionally requires exact research and
|
|
115
|
+
Capability revisions/digests, checks evidence roles, subject/property/target
|
|
116
|
+
correspondence and exclusive groups. Include the Capability's research context
|
|
117
|
+
even when the Bound description cites a later research revision.
|
|
118
|
+
- `encode(value, 'json')` and `decode(text, 'json')` check structure and preserve
|
|
119
|
+
data. They do not imply that external references were checked.
|
|
120
|
+
- `verifySuccessor(previous, next)` checks parent revision/digest and retained
|
|
121
|
+
identities. Description kind cannot change. A retained node cannot change its
|
|
122
|
+
type; a retained capability cannot change endpoints/type. A retained binding
|
|
123
|
+
slot cannot change its capability ID, instance or capability-artifact identity.
|
|
124
|
+
A successor may pin a newer revision of the same Capability artifact and change
|
|
125
|
+
a binding target with new evidence. Check both references and succession.
|
|
126
|
+
|
|
127
|
+
A binding ID denotes the instance's slot for that capability, not an immutable
|
|
128
|
+
edge to one target. Target changes retain the slot ID and component IDs where
|
|
129
|
+
those components are the same. A different connection/capability needs a new ID.
|
|
130
|
+
Old bytes and old references stay unchanged; these pure library functions do not
|
|
131
|
+
write files or enforce history-wide ID reuse, atomic persistence or retention.
|
|
132
|
+
Cross-revision vocabulary changes and newly supplied source meaning still need
|
|
133
|
+
human review. Size/depth limits are the existing 2 MiB / 64-level codec limits,
|
|
134
|
+
not graph hop limits.
|
|
135
|
+
|
|
136
|
+
## Privacy boundary
|
|
137
|
+
|
|
138
|
+
Supply only permitted, sanitized research. Do not copy actual URLs, IP addresses,
|
|
139
|
+
usernames, passwords, keys or raw settings into any note, label, identifier,
|
|
140
|
+
source locator, filename, HTML, JSON or retained evidence. Use opaque source
|
|
141
|
+
identifiers or sanitized snapshots whose digest describes those actual sanitized
|
|
142
|
+
bytes; never invent a digest of unseen raw material. A source that cannot be
|
|
143
|
+
inspected safely is a coverage limit. No raw-secret store is introduced.
|
|
144
|
+
|
|
145
|
+
Closed shapes and rejection of nonempty extensions prevent designated settings
|
|
146
|
+
fields from being stored, but **validation is not a secret detector**. A secret
|
|
147
|
+
could still be put in ordinary prose or an identifier. Producers must avoid
|
|
148
|
+
collecting it and check all output before retention; #51 owns that workflow.
|
|
149
|
+
Tests use synthetic sentinels, never real secrets. New-description validation and
|
|
150
|
+
reference errors omit input values/keys; parser syntax errors also omit source
|
|
151
|
+
snippets. Do not log raw rejected input or legacy research-validation exceptions.
|
|
152
|
+
Old research records allow arbitrary claim values and retain their existing
|
|
153
|
+
validation contract; sanitization remains essential before calling those APIs.
|
|
154
|
+
|
|
155
|
+
## Human verification task list
|
|
156
|
+
|
|
157
|
+
Prerequisite: open this branch's [synthetic examples](../../examples/researcher/descriptions/README.md).
|
|
158
|
+
No CLI, inference, credentials, real configuration or live services are needed.
|
|
159
|
+
|
|
160
|
+
- [ ] Open `capability.json`. Expect MongoDB, OIDC and SAML as **possible**, an
|
|
161
|
+
authentication exclusive group and **unknown** inference support, without
|
|
162
|
+
instance bindings.
|
|
163
|
+
- [ ] Open `bound-r1.json` beside `sources.md` and `research-r1.json`. Expect a
|
|
164
|
+
**configured** MongoDB Atlas target, **conflicting** OIDC/SAML targets and
|
|
165
|
+
**unknown** inference. Find the separate OIDC preference; it must not erase
|
|
166
|
+
either source claim. Expect role/product identities, no actual settings.
|
|
167
|
+
- [ ] Open `bound-r2.json` and `research-r2.json`. Expect the same instance and
|
|
168
|
+
database binding ID, a self-hosted MongoDB target and exact predecessor
|
|
169
|
+
references. The original files still show Atlas and the earlier evidence.
|
|
170
|
+
- [ ] Report **Pass / Fail / Blocked**, inspected filenames and any incorrect
|
|
171
|
+
state, exposed value, lost conflict or broken reference. These are developer
|
|
172
|
+
fixtures; passing inspection is not installed Researcher acceptance.
|
|
173
|
+
|
|
174
|
+
### Maintainer preparation and technical readback
|
|
175
|
+
|
|
176
|
+
From the repository root, use Node.js 22, 24 or 26. Run `npm ci` then
|
|
177
|
+
`npm run build` (exit 0; dependency installation uses the registry). This read-only
|
|
178
|
+
example exercises the library directly, not a skill dependency on a CLI:
|
|
179
|
+
|
|
180
|
+
```sh
|
|
181
|
+
node --input-type=module <<'JS'
|
|
182
|
+
import {readFileSync} from 'node:fs';
|
|
183
|
+
import {decode, verifyReferences, verifySuccessor} from './dist/index.js';
|
|
184
|
+
const read = name => decode(readFileSync(
|
|
185
|
+
`examples/researcher/descriptions/${name}.json`, 'utf8'), 'json');
|
|
186
|
+
const context = ['research-r1', 'research-r2', 'capability'].map(read);
|
|
187
|
+
const before = read('bound-r1'), after = read('bound-r2');
|
|
188
|
+
verifyReferences(context[2], context);
|
|
189
|
+
verifyReferences(before, context);
|
|
190
|
+
verifyReferences(after, context);
|
|
191
|
+
verifySuccessor(before, after);
|
|
192
|
+
console.log(before.bindings.map(b => b.state).join(', '));
|
|
193
|
+
console.log(before.bindings[0].claims[0].target);
|
|
194
|
+
console.log(after.bindings[0].claims[0].target);
|
|
195
|
+
JS
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
Expect exit 0 and exactly:
|
|
199
|
+
|
|
200
|
+
```text
|
|
201
|
+
configured, conflicting, unknown
|
|
202
|
+
urn:target:atlas
|
|
203
|
+
urn:target:mongodb
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
The readback changes no files; no cleanup is needed. A nonzero exit or different
|
|
207
|
+
states/targets fails this check. `npm test` covers malformed data, unsupported
|
|
208
|
+
YAML, privacy sentinels, conflicting/exclusive selections and revision/reference
|
|
209
|
+
drift. The package check exercises these assets through an installed library.
|
|
210
|
+
|
|
211
|
+
## Baseline and evidence boundary
|
|
212
|
+
|
|
213
|
+
On 8 November 2026, inspection of installed Researcher skill **0.1.9** found its
|
|
214
|
+
explicit statement that it produces working notes and does not generate validated
|
|
215
|
+
research HTML or Surface definitions. This is a prerequisite blocker for the
|
|
216
|
+
requested installed-artifact journey, not an attempted AI investigation or proof
|
|
217
|
+
of generated artifacts. CLI availability is irrelevant to the standalone skill.
|
|
218
|
+
The authorized known gap is implemented here only at the contract/library layer.
|
|
219
|
+
|
|
220
|
+
The synthetic fixture journey above is the #50 agent rehearsal. It is not
|
|
221
|
+
Researcher-produced findings, an installed-skill rehearsal, human acceptance,
|
|
222
|
+
a real-instance inspection, or evidence of runtime use. #51 must package usable
|
|
223
|
+
standalone artifact production/checking resources; #52 must repeat the actual
|
|
224
|
+
installed conversation and independently read back its saved results.
|