@n8r/surface 0.0.0-stage → 0.1.0-experimental.2

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 (96) hide show
  1. package/LICENSE +202 -0
  2. package/LICENSE-DOCS +395 -0
  3. package/LICENSING.md +36 -0
  4. package/README.md +181 -2
  5. package/dist/activity.d.ts +16 -0
  6. package/dist/activity.js +44 -0
  7. package/dist/cli.d.ts +2 -0
  8. package/dist/cli.js +260 -0
  9. package/dist/codec.d.ts +4 -0
  10. package/dist/codec.js +41 -0
  11. package/dist/codex.d.ts +72 -0
  12. package/dist/codex.js +510 -0
  13. package/dist/contracts.d.ts +129 -0
  14. package/dist/contracts.js +1 -0
  15. package/dist/html.d.ts +5 -0
  16. package/dist/html.js +50 -0
  17. package/dist/index.d.ts +7 -0
  18. package/dist/index.js +5 -0
  19. package/dist/notes.d.ts +52 -0
  20. package/dist/notes.js +184 -0
  21. package/dist/portable.d.ts +10 -0
  22. package/dist/portable.js +71 -0
  23. package/dist/revisions.d.ts +2 -0
  24. package/dist/revisions.js +18 -0
  25. package/dist/settings.d.ts +23 -0
  26. package/dist/settings.js +100 -0
  27. package/dist/setup.d.ts +9 -0
  28. package/dist/setup.js +161 -0
  29. package/dist/source-tools.d.ts +102 -0
  30. package/dist/source-tools.js +201 -0
  31. package/dist/startup.d.ts +7 -0
  32. package/dist/startup.js +74 -0
  33. package/dist/surface-draft.d.ts +19 -0
  34. package/dist/surface-draft.js +95 -0
  35. package/dist/surface-instructions.d.ts +2 -0
  36. package/dist/surface-instructions.js +23 -0
  37. package/dist/surface-store.d.ts +36 -0
  38. package/dist/surface-store.js +181 -0
  39. package/dist/validate.d.ts +4 -0
  40. package/dist/validate.js +184 -0
  41. package/docs/n8r-surface/README.md +133 -0
  42. package/docs/n8r-surface/codex-research-transcript.md +51 -0
  43. package/docs/n8r-surface/codex-research-verification.md +176 -0
  44. package/docs/n8r-surface/command-outcomes.md +564 -0
  45. package/docs/n8r-surface/contracts.md +210 -0
  46. package/docs/n8r-surface/critical-path.md +163 -0
  47. package/docs/n8r-surface/design.md +289 -0
  48. package/docs/n8r-surface/getting-started.md +107 -0
  49. package/docs/n8r-surface/host-contract.md +176 -0
  50. package/docs/n8r-surface/implementation-decisions.md +96 -0
  51. package/docs/n8r-surface/npm-distribution.md +137 -0
  52. package/docs/n8r-surface/npm-release.md +188 -0
  53. package/docs/n8r-surface/recreation-handoff.md +117 -0
  54. package/docs/n8r-surface/researcher-discovery.md +157 -0
  55. package/docs/n8r-surface/researcher-prepared-check.md +117 -0
  56. package/docs/n8r-surface/researcher-reconciliation-trial.md +149 -0
  57. package/docs/n8r-surface/researcher-repository-check.md +95 -0
  58. package/docs/n8r-surface/researcher-skeleton-check.md +84 -0
  59. package/docs/n8r-surface/researcher-skill-verification.md +725 -0
  60. package/docs/n8r-surface/researcher-skill.md +255 -0
  61. package/docs/n8r-surface/researcher-vault.md +134 -0
  62. package/docs/n8r-surface/save-reopen-transcript.md +211 -0
  63. package/docs/n8r-surface/save-reopen-verification.md +152 -0
  64. package/docs/n8r-surface/startup-human-check.md +172 -0
  65. package/docs/n8r-surface/startup-verification.md +161 -0
  66. package/docs/n8r-surface/startup.md +151 -0
  67. package/docs/n8r-surface/surface-revisions-transcript.md +552 -0
  68. package/docs/n8r-surface/surface-revisions-verification.md +161 -0
  69. package/docs/n8r-surface/vault-setup-verification.md +210 -0
  70. package/docs/n8r-surface/verification.md +117 -0
  71. package/docs/n8r-surface/versioning.md +183 -0
  72. package/examples/researcher/README.md +92 -0
  73. package/examples/researcher/composed.surface.json +430 -0
  74. package/examples/researcher/composed.surface.yaml +283 -0
  75. package/examples/researcher/harbor-r1.research.html +193 -0
  76. package/examples/researcher/harbor-r2.research.html +226 -0
  77. package/examples/researcher/lumen-manual-edit.pending.html +271 -0
  78. package/examples/researcher/lumen-r1.research.html +271 -0
  79. package/examples/researcher/lumen-r2.research.html +280 -0
  80. package/examples/researcher/sources/harbor-api.md +16 -0
  81. package/examples/researcher/sources/harbor-auth.md +8 -0
  82. package/examples/researcher/sources/lumen-guide.md +28 -0
  83. package/examples/researcher/sources/lumen-settings.md +9 -0
  84. package/package.json +45 -4
  85. package/plugins/n8r-surface/.codex-plugin/plugin.json +31 -0
  86. package/plugins/n8r-surface/LICENSE +202 -0
  87. package/plugins/n8r-surface/LICENSE-DOCS +395 -0
  88. package/plugins/n8r-surface/LICENSING.md +36 -0
  89. package/plugins/n8r-surface/assets/icon.svg +5 -0
  90. package/plugins/n8r-surface/plugin.json +27 -0
  91. package/plugins/n8r-surface/skills/research/SKILL.md +122 -0
  92. package/plugins/n8r-surface/skills/research/agents/openai.yaml +4 -0
  93. package/plugins/n8r-surface/skills/research/references/discovery-map.md +160 -0
  94. package/plugins/n8r-surface/skills/research/references/model-meanings.md +55 -0
  95. package/plugins/n8r-surface/skills/research/references/skeleton-surface.md +105 -0
  96. package/plugins/n8r-surface/skills/research/references/working-notes.md +116 -0
@@ -0,0 +1,152 @@
1
+ # Saved continuation: evidence and limits
2
+
3
+ Related to [#17](https://github.com/injectionator/n8r-surface/issues/17).
4
+ Use [the short human check](getting-started.md). This increment implements
5
+ SAVE-01 in numbered Markdown; it does not complete structured HTML/JSON/YAML,
6
+ broader host/live trials, Lab integration or registry distribution.
7
+
8
+ ## Current verification
9
+
10
+ **Pass (agent rehearsal), 5 November 2026. Human acceptance remains pending.**
11
+ The prior conversation increment was user-reported Pass and PR #33 merged at
12
+ `b186050`; the new saved-continuation evidence is recorded separately here.
13
+
14
+ - Implementation: [`447f440`](https://github.com/injectionator/n8r-surface/commit/447f44058c142d3a49ed827298d922a6458fbcb1).
15
+ Rehearsal completed while repository HEAD was `b4407aa`, which changes only the
16
+ offline test driver's prompt matching and plan notes, not product code.
17
+ - Installed tarball SHA-256:
18
+ `926823a95209ace0183875b2aaa2a3423f46671ad423f38e2b1fcdf885ef9b2d`.
19
+ - Environment: macOS arm64, Node 26.13.0, Codex CLI 0.166.0, existing ChatGPT
20
+ sign-in, explicit `gpt-6-astra`. A private run under the selected vault held the
21
+ isolated install, n8r HOME/settings and copied synthetic source. Existing Codex
22
+ sign-in was reused through CODEX_HOME without copying credentials.
23
+ - Loaded Researcher 0.1.8, combined instruction SHA-256
24
+ `8af29c3073df9b8210a7dd94ced9700379b0a98f76bd3a2902f9430b93c98a2a`.
25
+ - [Actual sanitized terminal transcripts](save-reopen-transcript.md) retain model
26
+ messages and source-read activity. Findings and note prose were produced by
27
+ real Codex, not prewritten by the developing agent.
28
+
29
+ ### Exercised interaction and independent readback
30
+
31
+ Starting state: copied `lumen-guide.md`, complete configured test vault, no saved
32
+ notes and unchanged version-1 settings. The installed command performed the short
33
+ human walkthrough's source investigation and OIDC decision, `/save`, `/exit`,
34
+ explicit-note reopen with renewed transmission consent, authentication follow-up,
35
+ `/save`, `/exit`. Both processes exited **0**. The original first note remained
36
+ byte-identical after its successor was saved.
37
+
38
+ A third process tested the user's additional request: append a human edit to the
39
+ older first note, prioritizing session-expiry evidence while retaining the OIDC
40
+ non-selection, then run `reopen --source SOURCE --model gpt-6-astra` without NOTE.
41
+ It suggested the edited `research-001.md`, showed its edit time, and waited for
42
+ selection and transmission consent. The conversation retained that edit and saved
43
+ `research-003.md`, linking the edited first note. It did not overwrite 002 or edit
44
+ 001 again. This process also exited **0**.
45
+
46
+ Independent file reads found all five stable IDs in every note:
47
+ `component:lumen`, `component:inference`, `component:archive`,
48
+ `component:callback`, `component:oidc`. All retained the OIDC decision separately
49
+ from source claims, cited the actual guide, preserved unknowns and included
50
+ recommended next steps. The third retained the session-expiry priority. The first
51
+ note explicitly explains that source references require the accompanying guide.
52
+ No runtime connection or alternative authentication mechanism was invented as fact.
53
+
54
+ | Readback | SHA-256 / result |
55
+ | --- | --- |
56
+ | Source before and after all processes | `98d3374c79c166b37f0debb4ffb5e457eda1385dd7847b042cbad674cac98693` |
57
+ | Original 001, preserved after saving 002 and referenced by 002 | `9910959c740959e943e7d6cf4e81b1d365468ab33576fb9c83aa9ce25dc054e7` |
58
+ | Deliberately edited 001, preserved after saving 003 and referenced by 003 | `76b6abe6d616b903f641f2b8d52f06777ad5383060701ce49a314d3ff68eca52` |
59
+ | Saved 002 | `927a6a84a810d518b5e7bc8f37df3f29916e353a3bb6817ccf21b2cc36aee265` |
60
+ | Saved 003 | `56f317af8dfd30ea76cbfe0318bf74b226cc3be0ef851e0edc67bcd120d029d6` |
61
+ | n8r settings | Unchanged bytes |
62
+
63
+ Raw transcripts, saved files and readback report remain under the selected vault's
64
+ runs/ convention. No local vault path or private infrastructure data is published.
65
+ These are agent rehearsals using supplied synthetic human input, not human acceptance.
66
+
67
+ ### Automated verification and review
68
+
69
+ - 97 Node tests passed on each of Node 22.23.2, 24.22.2 and 26.13.0.
70
+ - Installed-package checks passed on all three runtimes, including 20 offline
71
+ discovery/save/reopen terminal scenarios. They cover no premature writes,
72
+ failed and cancelled staged drafts, source scope, latest selection/refusal,
73
+ changed-source comparisons, preserved predecessors and process cleanup.
74
+ - Storage tests cover edit-time ranking, occupied names, changed predecessors,
75
+ symlink/replaced-folder refusal, bounded UTF-8 and human edits after metadata.
76
+ - Fresh review found missing historical evidence and incompatible reopen-size
77
+ limits. Regression tests failed first, then passed after preserving unavailable
78
+ evidence and using bounded comparison summaries rather than embedded source text.
79
+ - Linux CI exposed a test-driver race: a generic `[y/N]` matcher reused the first
80
+ prompt's suffix. The driver now waits for the complete transmission prompt.
81
+ Product code was unchanged; the initial failed CI run remains visible.
82
+ - Python fixture/workflow suite: 24 passed. Shell syntax, Markdownlint 0.24.0,
83
+ offline Lychee 0.24.2 with fragments, cffconvert 2.0.0 and whitespace passed.
84
+
85
+ Scripted protocol tests are not AI evidence; fixture integrity is not model
86
+ conformance. The real rehearsal used one synthetic source and unchanged source
87
+ bytes. Broader products, live observations, second-source integration, structured
88
+ HTML/JSON/YAML, named Lab consumers and npm distribution remain open in #17/#27.
89
+
90
+ ## Storage and continuation boundary
91
+
92
+ `/save` authorizes one numbered Markdown output. A dynamic `research_note` call
93
+ stages a draft in memory only during that host-authorized turn. The host writes
94
+ only after successful turn completion; ordinary conversation and unsolicited tool
95
+ calls cannot write. Natural-language save requests receive `/save` guidance.
96
+ The host shows the destination, appends current source-tool evidence and identified
97
+ Researcher/model metadata, writes a temporary file, publishes by exclusive hard
98
+ link, independently reads it back and prints the saved path and byte digest.
99
+ Predecessors retain their bytes; successors link their name and exact digest.
100
+ A changed predecessor requires reopening its edited version before another save.
101
+
102
+ Notes have a 256 KiB total limit, with at most 192 KiB of model prose and 1,000
103
+ source evidence entries. They use an experimental host metadata envelope, not
104
+ an AI Surface interchange schema. Model-authored prose and IDs are checked in the
105
+ rehearsal, not mechanically validated for truth. Metadata and human-edited prose
106
+ are untrusted input on reopening; hashes identify bytes, not authenticity.
107
+
108
+ `reopen [NOTE] --source SOURCE` requires explicit current source selection and
109
+ renewed note/source transmission permission. It starts a new ephemeral Codex
110
+ thread, compares saved evidence hashes with the selected source, reports changed
111
+ or unavailable evidence, and supplies the note plus comparisons as untrusted
112
+ research context. Reopening compares the saved evidence paths, retaining unavailable prior evidence
113
+ for subsequent attempts. Compact comparisons sent to the model are bounded to
114
+ 128 KiB with an explicit omitted count; full source text is read on demand through
115
+ the normal tools. Combined context is bounded to 512 KiB. Current source reads retain their normal limits;
116
+ no shell, broad filesystem write or extra execution environment is granted.
117
+
118
+ Without NOTE, the command suggests the latest filesystem-edited numbered note in
119
+ that source's research folder, showing UTC edit time and requiring acceptance.
120
+ A tied time sorts by filename; an invalid newest note is reported, not skipped.
121
+ Folder naming and edit time do not establish source identity. Explicit NOTE can
122
+ select another folder, and successors remain there. Only this command's metadata
123
+ notes are supported; generic Markdown import is later work.
124
+
125
+ Destination ancestor identities and predecessor bytes are checked again before
126
+ publishing. Existing names are never replaced. Directory topology must remain
127
+ stable during synchronous filesystem operations; this is not protection against
128
+ an adversarial concurrent directory replacement. An interrupted process can leave
129
+ an unreferenced hidden temporary file; it does not overwrite an earlier note.
130
+ Local storage does not provide backup, encryption or publication.
131
+
132
+ ## Pending-operation indicator follow-up
133
+
134
+ The user reported long silent waits during `/save` and after questions. Commit
135
+ `a6d11ad` adds a terminal-only spinner with elapsed seconds for connecting,
136
+ answering, reopening and preparing a note. It clears around normal output and
137
+ stops before returning to the prompt, including errors/cancellation. It reports a
138
+ pending request, not known server-side progress; nonterminal output never animates.
139
+
140
+ An isolated installed candidate was rehearsed with real Codex 0.166.0,
141
+ `gpt-6-astra`, ChatGPT sign-in and Node 26.13.0 on macOS. The same synthetic Lumen
142
+ question/OIDC choice was followed by `/save` and `/exit`. The spinner produced
143
+ 162 preparation frames over approximately 40 seconds, cleared before
144
+ **Saved and read back**, and produced no activity after the final `You>` prompt.
145
+ One note was saved, exit was 0, and source/settings bytes remained unchanged.
146
+ Raw terminal output and independent readback remain in the selected vault's runs/.
147
+ Tarball SHA-256: `d90df87bc3f1db05a5de01ee0080d88a599ca4050e63473e548907f53b6dfe3a`.
148
+
149
+ 99 Node tests and the installed-package check passed. Terminal scenarios still
150
+ cover cancellation/failure; focused tests verify repeated activity, clearing around
151
+ output, timer cleanup and nonterminal silence. The six GitHub checks passed on
152
+ `a6d11ad`. The short walkthrough now names the visible labels and expected stop.
@@ -0,0 +1,172 @@
1
+ # Human verification: bare startup (STARTUP-01)
2
+
3
+ Use a macOS or Linux terminal with Bash or zsh, Node.js **22, 24 or 26**, npm,
4
+ Python **3.9+**, Git and an authenticated GitHub CLI (`gh`). The recorded run used
5
+ macOS; this human procedure has not been rehearsed on Linux. No AI or Lab
6
+ credentials are needed.
7
+
8
+ Run the blocks below **in order, in the same terminal**, starting anywhere inside
9
+ an existing `injectionator/n8r-surface` checkout. Stop if a preparation command
10
+ fails. Installation downloads npm dependencies and creates ignored build files in
11
+ the checkout. The installed package, synthetic home, captured output and snapshot
12
+ all go in one temporary folder. Only the command under test receives that home.
13
+
14
+ ## 1. Select PR #25 and run the automated checks
15
+
16
+ First run `git status --short`. **Expected: no output.** If it lists changes, keep
17
+ those changes and use your normal process to finish that work before switching.
18
+ Then run:
19
+
20
+ ```sh
21
+ cd "$(git rev-parse --show-toplevel)"
22
+ gh pr checkout 25
23
+ git branch --show-current
24
+ git rev-parse HEAD
25
+ node --version
26
+ npm ci && npm cache add yaml@2.9.1 && npm test && npm run check:package
27
+ ```
28
+
29
+ **Expected:** branch `feat/16-bare-startup`; record the printed commit for your
30
+ review. `node --version` must start with `v22.`, `v24.` or `v26.`. The final command
31
+ must exit **0**. Its output must show **43 tests passed, 0 failed, 0 skipped** for
32
+ `npm test`, then **20 tests passed, 0 failed, 0 skipped** for the installed startup
33
+ checks, plus these messages (Node's summary formatting varies by version):
34
+
35
+ ```text
36
+ Installed package passed on Node v…; 4 nodes, 6 relationships, exact research references.
37
+ Installed PTY startup passed: overview before question, y and EOF, unchanged files.
38
+ ```
39
+
40
+ Those checks drive a terminal automatically. Continue below to see and answer the
41
+ installed command yourself.
42
+
43
+ ## 2. Install a disposable copy and prepare the starting state
44
+
45
+ ```sh
46
+ n8r_verify=$(mktemp -d "${TMPDIR:-/tmp}/n8r-startup-review.XXXXXX")
47
+ n8r_verify=$(cd "$n8r_verify" && pwd -P)
48
+ npm pack --ignore-scripts --pack-destination "$n8r_verify"
49
+ npm install --prefix "$n8r_verify/install" --offline --ignore-scripts --no-audit --no-fund "$n8r_verify/n8r-surface-0.0.0-experimental.1.tgz"
50
+ mkdir -p "$n8r_verify/home/.n8r" "$n8r_verify/home/n8r/artifacts"
51
+ cat > "$n8r_verify/home/.n8r/n8r-surface.json" <<'JSON'
52
+ {
53
+ "version": 1,
54
+ "artefactRoot": "~/n8r/artifacts",
55
+ "surfaceFormat": "json",
56
+ "private": "PRIVATE_VALUE_MUST_NOT_APPEAR"
57
+ }
58
+ JSON
59
+ cat > "$n8r_verify/home/n8r/artifacts/librechat-uniqueid.json" <<'JSON'
60
+ {
61
+ "contract": "n8r.surface/0.1",
62
+ "id": "urn:surface:librechat-uniqueid",
63
+ "title": "LibreChat",
64
+ "scope": "Synthetic startup input; no research performed",
65
+ "revision": {
66
+ "id": "r1", "parent": null, "createdAt": "2026-11-04T00:00:00Z",
67
+ "author": "Synthetic author", "reason": "Human startup verification"
68
+ },
69
+ "extensions": {}, "kind": "definition", "records": [], "vocabularies": [],
70
+ "nodes": [], "relationships": [], "requirements": [], "coverage": [], "gaps": []
71
+ }
72
+ JSON
73
+ cp -R "$n8r_verify/home" "$n8r_verify/before"
74
+ printf 'Test home: %s\n' "$n8r_verify/home"
75
+ ```
76
+
77
+ **Expected:** every preparation command exits **0**. The last line identifies the
78
+ home to expect in the overview. Your real `~/.n8r` and `~/n8r` are not used.
79
+
80
+ ## 3. Run with closed input
81
+
82
+ ```sh
83
+ n8r_exit=0
84
+ (cd "$n8r_verify" && env HOME="$n8r_verify/home" "$n8r_verify/install/node_modules/.bin/n8r-surface" </dev/null) >"$n8r_verify/closed.txt" 2>"$n8r_verify/stderr.txt" || n8r_exit=$?
85
+ cat "$n8r_verify/closed.txt"
86
+ printf 'Exit code: %s (expected 1)\n' "$n8r_exit"
87
+ ```
88
+
89
+ **Expected:** return to the shell within **five seconds**, with no question or input
90
+ needed. If it is still waiting, press Ctrl-C and report a failed check. Output must
91
+ match the following; `<test-home>` is the path printed in step 2, and the positive
92
+ PID and UTC timestamp vary each run. Do not type the angle-bracket placeholders.
93
+
94
+ ```text
95
+ Configuration
96
+ File: <test-home>/.n8r/n8r-surface.json
97
+ Settings version: 1
98
+ Artefact folder: <test-home>/n8r/artifacts
99
+ Surface output: JSON
100
+ AI runner: Not configured
101
+ Lab connection: Not configured
102
+
103
+ Processes
104
+ n8r-surface overview: running (PID <number>); observed <UTC timestamp>
105
+ Runner/Lab processes: Status unknown (no live status source)
106
+
107
+ Local artefacts (1)
108
+ LibreChat | Surface definition | <test-home>/n8r/artifacts/librechat-uniqueid.json
109
+
110
+ Setup and AI conversation are not implemented in this build. Research needs a supported AI runner.
111
+ Run in an interactive terminal for read-only setup guidance.
112
+ Exit code: 1 (expected 1)
113
+ ```
114
+
115
+ There must be exactly one artefact row. **Exit 1 is expected** because setup and
116
+ conversation are unavailable in this increment; exit 0 or 2 fails this prepared
117
+ case. Check private-value omission and stderr with:
118
+
119
+ ```sh
120
+ if grep -Fq 'PRIVATE_VALUE_MUST_NOT_APPEAR' "$n8r_verify/closed.txt" "$n8r_verify/stderr.txt"; then printf 'FAIL: private value leaked\n'; else printf 'PASS: private value absent\n'; fi
121
+ if test -s "$n8r_verify/stderr.txt"; then printf 'FAIL: unexpected stderr\n'; cat "$n8r_verify/stderr.txt"; else printf 'PASS: stderr empty\n'; fi
122
+ ```
123
+
124
+ **Expected:** `PASS: private value absent` and `PASS: stderr empty`.
125
+
126
+ ## 4. Answer the real terminal question
127
+
128
+ Paste this block, then wait for the question. Do not pipe it through `tee` or
129
+ redirect its input/output: the command must see a terminal.
130
+
131
+ ```sh
132
+ n8r_exit=0; (cd "$n8r_verify" && env HOME="$n8r_verify/home" "$n8r_verify/install/node_modules/.bin/n8r-surface") || n8r_exit=$?; printf '\nExit code: %s (expected 1)\n' "$n8r_exit"
133
+ ```
134
+
135
+ **Before typing anything**, confirm that the configuration, processes and the one
136
+ LibreChat row have appeared, followed by the unavailable-setup message and then
137
+ `Show setup requirements? [y/N]`. The private marker must be absent. The closed-input
138
+ message about running in an interactive terminal must not appear here.
139
+
140
+ Type **`y` and Enter**. Expect:
141
+
142
+ ```text
143
+ Research will require an explicitly selected runner, model and external credential reference. A Lab connection is optional. No settings have been changed.
144
+
145
+ Exit code: 1 (expected 1)
146
+ ```
147
+
148
+ Run the same block again. This time press **Ctrl-D at the empty question**. Expect
149
+ an immediate return to the shell, `Exit code: 1 (expected 1)`, and no guidance answer
150
+ or error stack. No setup or conversation is expected to start in either case.
151
+
152
+ ## 5. Confirm unchanged files and clean up
153
+
154
+ ```sh
155
+ if diff -r "$n8r_verify/before" "$n8r_verify/home"; then printf 'PASS: fixture files and directory contents unchanged\n'; else printf 'FAIL: startup changed the fixture\n'; fi
156
+ ```
157
+
158
+ **Expected:** only `PASS: fixture files and directory contents unchanged`, with no
159
+ diff. If any step differs from its expectation, retain the temporary folder while
160
+ you investigate and report the step, commit and Node version; do not call it a pass.
161
+ After inspection, remove only the temporary verification folder:
162
+
163
+ ```sh
164
+ rm -r -- "${n8r_verify:?}"
165
+ unset n8r_verify n8r_exit
166
+ git status --short
167
+ ```
168
+
169
+ **Expected:** no output. The temporary installation, synthetic home, snapshot and
170
+ captured output are gone. Ignored `node_modules/` and `dist/` from the build remain
171
+ in the checkout. This procedure verifies bare startup only; it does not complete
172
+ \#16 or verify AI-driven research.
@@ -0,0 +1,161 @@
1
+ # STARTUP-01 verification record
2
+
3
+ **Result:** specified, implemented and verified for the read-only bare-startup
4
+ increment. This does not complete #16 or verify setup, status, discovery or an AI
5
+ conversation. [Settings, parser decisions and limits](startup.md) define the
6
+ implemented boundary. [PR #25](https://github.com/injectionator/n8r-surface/pull/25)
7
+ carries the increment originally developed on #15. This record preserves the
8
+ pre-integration verification revision and does not claim a release.
9
+
10
+ ## Human verification
11
+
12
+ Follow the [copy-and-paste human check](startup-human-check.md) for prerequisites,
13
+ PR checkout, a disposable installation and synthetic home, exact expected output,
14
+ interactive `y`/EOF steps, private-value checks and cleanup. Its expected exit 1
15
+ is explained explicitly. The automated commands later in this record support
16
+ that hands-on check.
17
+
18
+ On 4 November 2026, Codex rehearsed the guide's disposable installation, closed
19
+ input, terminal `y` and Ctrl-D, private-value/stderr checks and unchanged-file
20
+ comparison on Node 22.23.2, npm 11.5.2 and macOS ARM64. The expected output and
21
+ exit codes matched; all 43 tests and 20 installed startup checks also passed.
22
+ This is an agent rehearsal, not recorded human acceptance.
23
+
24
+ ## Revision and environment
25
+
26
+ - Date: 4 November 2026. Implementer/verifier: Codex; separate read-only agent
27
+ review found no important issues in the startup implementation.
28
+ - Baseline: `5f67dbea2be93a6ee6bedb9a029bc79be4b3997d`.
29
+ - Implementation and retained test revision:
30
+ `b90358aaf22fead155081bb00f6d837a0f8f59e7`. The matrix below was repeated from
31
+ this committed revision with a clean working tree before writing this record.
32
+ - macOS ARM64; Node.js **22.23.2, 24.22.2 and 26.13.0**; npm **11.5.2**;
33
+ Python **3.13.1** for the terminal rehearsal.
34
+ - Private package `n8r-surface@0.0.0-experimental.1`, built and packed locally,
35
+ then installed outside the checkout using `--offline --ignore-scripts`.
36
+ `npm ci` populated the dependency cache; no registry publication occurred.
37
+ Each matrix executable was the `node` binary in its own runtime directory.
38
+
39
+ ## Baseline and prepared state
40
+
41
+ At the baseline, `command -v n8r-surface` returned no path (exit 1) and the package
42
+ manifest contained no `bin` entry. The installed product interaction was therefore
43
+ **blocked by an absent executable**, not an observed failed startup. No research
44
+ or setup result was invented. After adding the process tests, 16 startup checks
45
+ failed on the missing built entry point while the existing 23 library tests passed.
46
+
47
+ The repeatable check creates a temporary home containing:
48
+
49
+ - `~/.n8r/n8r-surface.json`: version 1, `artefactRoot: "~/n8r/artifacts"`,
50
+ `surfaceFormat: "json"`, and synthetic private markers in ignored settings.
51
+ - `~/n8r/artifacts/librechat-uniqueid.json`: a valid synthetic `n8r.surface/0.1`
52
+ definition titled **LibreChat**. It is a prepared input, not Researcher output.
53
+ - No runner or Lab configuration. A synthetic credential marker in the process
54
+ environment must also be absent from output. A saved PID in ignored settings
55
+ must not imply runner liveness.
56
+
57
+ **Interaction:** invoke installed `n8r-surface` with no arguments from the
58
+ isolated home. First close stdin and capture output/exit. Then run the same
59
+ installed bin in a real POSIX terminal, wait for the guidance question, check the
60
+ already-received overview, and answer `y`. Repeat with terminal EOF (Ctrl-D).
61
+ No credentials or running Lab are required.
62
+
63
+ ## Observed terminal output
64
+
65
+ This is the installed PTY readback, with only the temporary home replaced by `~`,
66
+ PID/time represented by labelled placeholders, and readline cursor escapes removed.
67
+ The assertions use the real paths, compare the child PID with its process result,
68
+ and check the timestamp is present. File contents are independently reread.
69
+
70
+ ```text
71
+ Configuration
72
+ File: ~/.n8r/n8r-surface.json
73
+ Settings version: 1
74
+ Artefact folder: ~/n8r/artifacts
75
+ Surface output: JSON
76
+ AI runner: Not configured
77
+ Lab connection: Not configured
78
+
79
+ Processes
80
+ n8r-surface overview: running (PID <observed PID>); observed <UTC timestamp>
81
+ Runner/Lab processes: Status unknown (no live status source)
82
+
83
+ Local artefacts (1)
84
+ LibreChat | Surface definition | ~/n8r/artifacts/librechat-uniqueid.json
85
+
86
+ Setup and AI conversation are not implemented in this build. Research needs a supported AI runner.
87
+ Show setup requirements? [y/N] y
88
+ Research will require an explicitly selected runner, model and external credential reference. A Lab connection is optional. No settings have been changed.
89
+ ```
90
+
91
+ With closed input, the same overview appears, followed by the unavailable-capability
92
+ message and `Run in an interactive terminal for read-only setup guidance.` No
93
+ question appears and the process exits within the five-second test deadline.
94
+ Valid startup exits **1**, explicitly indicating unavailable setup/conversation;
95
+ inspection errors and arguments exit **2**. This is not research success.
96
+
97
+ ## Independent readback and repeatable evidence
98
+
99
+ | Expected outcome | Observed check |
100
+ | --- | --- |
101
+ | Readable settings and actual configured location | Output matches the prepared configuration path, `artifacts` override, JSON format and unconfigured runner/Lab. Defaults separately resolve to `artefacts`; relative paths resolve against the settings directory. |
102
+ | One logical row per entry | The supplied LibreChat definition appears exactly once with its title, type and filename. Two-entry cases also list HTML research metadata; YAML definitions are read. Controls in titles are escaped. |
103
+ | Private values stay private | Markers in nested/unknown settings, URL credentials, malformed input, artefact bodies and the credential environment are absent. Parser errors never echo source content. |
104
+ | Reliable status only | The displayed live overview PID equals the spawned child PID. Runner/Lab status remains unknown, including with a saved PID or declared runner/Lab configuration. |
105
+ | Read-only startup | Before/after bytes, modes and modification times match; the snapshot also checks the directory inventory. PTY `y` and EOF preserve the files and directories. |
106
+ | Empty differs from unavailable | Empty folders say empty; missing/unreadable folders report the path/problem. Invalid or unreadable configuration prevents corpus inspection and remains intact. |
107
+ | Unsupported entries do not disappear or hang | Unsupported, invalid, oversized, unreadable, symlink and directory entries retain a row with a limitation. FIFO configuration and entries finish without blocking. |
108
+ | Overview precedes interaction | PTY checks see configuration, processes and the artefact row before the live guidance question, then supply `y` or EOF. |
109
+ | Installed consumer needs no checkout | The tarball supplies the executable, library and assets. The same startup assertions invoke `n8r-surface` from its installed bin directory under a temporary home. |
110
+
111
+ All **43 tests** (23 existing library checks plus 20 startup checks) passed with
112
+ `npm test` on each supported Node major above, with no skips. The installed-package
113
+ matrix passed the library consumer check, all **20 startup checks**, and both PTY
114
+ interactions on each runtime. A separate reviewer also exercised terminal `n`,
115
+ Ctrl-D and Ctrl-C on Node 22 without raw diagnostics or a hang.
116
+
117
+ A validation regression found during implementation treated explicit null settings
118
+ as defaults. Two new checks failed before the fix; null folder/format values now
119
+ report invalid configuration without inspecting a fallback folder.
120
+
121
+ Reproduce from the repository:
122
+
123
+ ```sh
124
+ npm ci
125
+ npm test
126
+ npm run check:package
127
+ ```
128
+
129
+ For the supported runtime matrix, run `npm test` with each runtime on PATH, then:
130
+
131
+ ```sh
132
+ node scripts/check-package.mjs /path/to/node22/bin/node /path/to/node24/bin/node /path/to/node26/bin/node
133
+ ```
134
+
135
+ The paths above are placeholders. Use binaries named `node` in separate runtime
136
+ directories: the installed shebang resolves `node` from that directory on PATH.
137
+ A custom-named executable beside a different `node` would not establish the same
138
+ matrix. Retained evidence is ordinary code in
139
+ [startup.test.mjs](../../tests/startup.test.mjs),
140
+ [startup-pty.py](../../tests/startup-pty.py) and
141
+ [check-package.mjs](../../scripts/check-package.mjs), plus the observed readback
142
+ above. The checks remove their temporary installations/homes. No raw machine
143
+ paths or private logs are retained in the repository.
144
+
145
+ ## Remaining limits
146
+
147
+ Only the command's own process is directly known; there is no process registry or
148
+ proof of a live AI runner or Lab. Configured runner/Lab objects are declarations
149
+ whose contents are withheld. Missing setup is explained, not repaired.
150
+
151
+ The listing recognizes the experimental #15 profile. Older illustrative LibreChat
152
+ JSON, manually edited HTML, unknown formats and unsupported versions get a
153
+ limitation row; there is no universal Surface conformance claim. Files are bounded
154
+ per entry, but this increment does not provide a large-corpus index or total scan
155
+ time limit. Network-mounted folders were not exercised. Linux and Windows were
156
+ not exercised; PTY verification requires POSIX and Python. No inference, source
157
+ research, Lab compatibility, registry/npx download or release claim is made.
158
+
159
+ Next in #16: separately specify and verify `status`, then real setup, help/version,
160
+ source selection, guarded storage and unavailable-discovery handling. Actual
161
+ Researcher instructions and AI-driven repository research remain #17.
@@ -0,0 +1,151 @@
1
+ # Bare startup and local vault setup (#16)
2
+
3
+ Bare `n8r-surface` displays readable non-private configuration, legacy saved
4
+ artefacts and known own-process status. It then offers first-use vault setup or
5
+ reuses the configured vault. Setup does not start research, scan source contents,
6
+ use a network, launch a runner or require an account. Bare startup is unchanged by the separate [Codex discovery increment](codex-research-verification.md).
7
+ SOURCE-01 remains paused; the new discovery path does not incorporate that checkpoint. This increment does not complete #16 or #30.
8
+
9
+ The earlier read-only overview and guidance question were delivered by
10
+ [PR #25](https://github.com/injectionator/n8r-surface/pull/25).
11
+ [Historical STARTUP-01 evidence](startup-verification.md) applies to that revision.
12
+ The setup increment replaces its guidance question and exit behavior; see the
13
+ [current setup rehearsal and human tasks](vault-setup-verification.md).
14
+
15
+ ## Settings and parser decisions
16
+
17
+ One settings file: `~/.n8r/n8r-surface.json`, version 1, limited to 64 KiB.
18
+ The process home directory selects `~`, allowing an isolated verification home.
19
+ There are no project settings, command-line overrides or credential environment
20
+ reads. The repository's `.local/vault-path` remains an agent convention and is
21
+ not read by this command.
22
+
23
+ ```json
24
+ {
25
+ "version": 1,
26
+ "vaultRoot": "~/n8r/",
27
+ "artefactRoot": "~/n8r/artefacts",
28
+ "surfaceFormat": "json"
29
+ }
30
+ ```
31
+
32
+ `vaultRoot` is optional; absence means setup is pending. It stores the vault for
33
+ future research, containing `research/`, `artifacts/` and `surfaces/`.
34
+ `artefactRoot` remains the separate legacy structured-artefact location and defaults
35
+ to `~/n8r/artefacts`. No migration, renaming or inference from its parent occurs.
36
+ Both locations are displayed. Existing legacy content and every unknown settings
37
+ value are preserved. `surfaceFormat` defaults to `json` and also accepts `yaml`.
38
+ Optional `runner` and `lab` objects (or null) remain independent declarations;
39
+ only configuration presence is shown, never their private contents.
40
+
41
+ Expand `~/` against home. Stored relative paths resolve against the settings
42
+ folder. Newly entered relative vault paths resolve against invocation cwd;
43
+ first setup saves an absolute path. Validate the fully expanded/resolved path as
44
+ well as the input so that neither can introduce forbidden control characters.
45
+ Resolve pre-existing ancestors and an
46
+ explicitly selected vault-root symlink before showing the destination. Reject
47
+ empty custom paths, control characters, URL forms, non-directory collisions,
48
+ settings symlinks/special files and symlinked required vault children. Invalid
49
+ settings are retained for repair, never replaced with defaults.
50
+
51
+ Only zero arguments launches startup. Discovery, reopening and local help/version
52
+ have separate paths described in [the command inventory](command-outcomes.md#initial-public-command-inventory).
53
+ Unknown arguments exit 2 without echoing them or inspecting settings. No `setup`,
54
+ `--vault`, `--path` or `status` command is added.
55
+
56
+ ## First use, reuse and repair
57
+
58
+ The read-only overview precedes all questions. With both input and output attached
59
+ to terminals, first use asks:
60
+
61
+ ```text
62
+ Vault directory [~/n8r/]:
63
+ Vault directory: <resolved absolute path>
64
+ Create vault folders and save this location? [y/N]
65
+ ```
66
+
67
+ Enter at the location question chooses `~/n8r/`. Only `y` or `yes` (case insensitive)
68
+ at confirmation permits writes. Refusal, EOF and interruption before acceptance
69
+ exit 1 without writes. Acceptance creates only missing directories, then adds
70
+ `vaultRoot` to settings and prints `Vault ready: <resolved absolute path>`.
71
+ Existing JSON member bytes are retained when inserting the new field, including
72
+ unknown numeric literals outside JavaScript precision/range.
73
+ No source files are read or written. Reject writes to settings/vault paths inside
74
+ the invocation directory, including symlink aliases and missing descendants.
75
+ Also reject vault folders inside the legacy corpus: adding directories there
76
+ would break its next inspection. Running setup from home can therefore be refused; run from a separate source
77
+ folder. Complete configured reuse is read-only even from such a directory.
78
+
79
+ A complete configured vault exits 0 without questions, locks or settings rewrites.
80
+ Missing required folders need repair confirmation; repair creates folders without
81
+ rewriting settings. An occupied child path or inaccessible vault exits 2. Existing
82
+ vault files are never removed. A failed confirmed setup may leave empty folders;
83
+ retry reuses them. Setup does not create the legacy corpus when it is absent.
84
+
85
+ | Outcome | Exit | Writes |
86
+ | --- | --- | --- |
87
+ | Successful accepted setup/repair | 0 | Missing folders; settings only on first setup |
88
+ | Complete configured reuse | 0 | None |
89
+ | Decline, EOF or interrupt before confirmation | 1 | None |
90
+ | Setup/repair needed with nonterminal input or output | 1 | None |
91
+ | Invalid settings/arguments, filesystem or conflict error | 2 | No successful setup claim; partial confirmed folders may remain |
92
+ | Legacy inspection error except absent corpus | 2 | None; takes precedence before any setup question |
93
+
94
+ Closed-input setup/repair prints exactly:
95
+
96
+ ```text
97
+ Vault setup required; run n8r-surface in an interactive terminal.
98
+ ```
99
+
100
+ It finishes promptly without waiting. Missing legacy corpus is reported as
101
+ unavailable/absent (`ENOENT`) and permits setup/reuse; it is not reported empty.
102
+ Other legacy errors remain visible even when a complete vault exists.
103
+
104
+ ## Concurrency and recovery boundary
105
+
106
+ The user approved this cooperating-writer boundary on 5 November 2026. Other
107
+ editors must not write settings during confirmed setup. Directory/symlink topology
108
+ must stay stable while setup runs. This is not an adversarial filesystem or
109
+ power-loss durability guarantee, nor protection against arbitrary external writers.
110
+
111
+ After confirmation, exclusively create `~/.n8r/n8r-surface.json.lock`. Other setup
112
+ processes fail with exit 2 rather than wait or steal the lock. Compare the original
113
+ settings bytes under the lock before folder creation and again before publication.
114
+ Detected edits fail and retain the competing values. Write an exclusive temporary
115
+ sibling and close it only after all required folders are available. For absent
116
+ settings, publish with an exclusive hard link: a competing creator is preserved
117
+ even after the final byte check. For existing settings, atomically rename under
118
+ the lock. A writer ignoring that lock can still race the final check/rename;
119
+ no stronger guarantee is claimed.
120
+
121
+ Normal completion/failure removes only this invocation's temporary sibling and
122
+ lock. A killed process may leave these and empty folders. If a lock remains,
123
+ first establish that no setup process is active, inspect the saved settings and
124
+ vault, then remove the stale `n8r-surface.json.lock` manually and retry. Never
125
+ remove a lock while another setup may be running. Abandoned `.tmp` siblings may
126
+ be inspected and removed manually after establishing ownership; automatic setup
127
+ does not delete another invocation's files. No automatic age/PID-based lock theft.
128
+
129
+ ## Local inspection boundary
130
+
131
+ List direct legacy folder entries in filename order, one terminal-safe line each.
132
+ Read JSON/YAML definitions and HTML research records with existing bounded readers;
133
+ use title/type metadata, never source or extension contents. Unsupported, invalid,
134
+ oversized, unreadable, symlink and non-regular entries remain visible as errors.
135
+ Do not recurse, open source locations or execute HTML. Reads are bounded to 2 MiB
136
+ per artefact. Terminal controls, line separators and bidi characters are escaped.
137
+
138
+ The process identifies only its own PID and observation time. Runner/Lab process
139
+ status remains unknown; configured settings do not establish a live process.
140
+ There is no daemon, PID registry, source scan, network probe or inference.
141
+
142
+ ## Verification boundary
143
+
144
+ Transaction tests cover preserved values/bytes, malformed and oversized settings,
145
+ source overlap and symlinks, deterministic conflicting writes, a second real
146
+ process under a held lock, partial filesystem/publication failure and retry.
147
+ Process and PTY checks exercise the real command with independent filesystem
148
+ readback; the package check repeats them outside the checkout. See
149
+ [the verification record](vault-setup-verification.md) for exact revisions,
150
+ runtimes, human tasks and remaining limits. Automated rehearsal is not human
151
+ acceptance or proof of research, save/continue, or consumer compatibility.