kijito-tools 0.2.0
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/LICENSE +201 -0
- package/NOTICE +6 -0
- package/README.md +220 -0
- package/bin/cli.js +34 -0
- package/install.sh +161 -0
- package/package.json +50 -0
- package/providers/_shared/wake-core.mjs +358 -0
- package/providers/claude/CLAUDE.md.snippet +31 -0
- package/providers/claude/install.sh +186 -0
- package/providers/claude/scripts/arm-session.sh +66 -0
- package/providers/claude/scripts/claude-armed.sh +101 -0
- package/providers/claude/scripts/heartbeat-watchdog.sh +209 -0
- package/providers/claude/scripts/inbox-selftest.sh +277 -0
- package/providers/claude/scripts/kijito-persona-lib.sh +94 -0
- package/providers/claude/scripts/kijito-qa-pass.sh +12 -0
- package/providers/claude/scripts/lifecycle-lib.sh +167 -0
- package/providers/claude/scripts/myctx.sh +46 -0
- package/providers/claude/scripts/self-clear.sh +134 -0
- package/providers/claude/scripts/session-autosend.sh +85 -0
- package/providers/claude/scripts/session-catchup-hint.sh +330 -0
- package/providers/claude/scripts/statusline-context.sh +67 -0
- package/providers/claude/skills/kijito-qa-memory/SKILL.md +110 -0
- package/providers/claude/skills/kijito-recall/SKILL.md +53 -0
- package/providers/claude/skills/kijito-start/SKILL.md +122 -0
- package/providers/claude/wiring/README.md +93 -0
- package/providers/claude/wiring/kijito-heartbeat@.service +21 -0
- package/providers/codex/README.md +75 -0
- package/providers/codex/codex-kijito-parity-plan.md +265 -0
- package/providers/codex/docs-codex-setup.md +64 -0
- package/providers/codex/install.mjs +184 -0
- package/providers/codex/n0-capability-probe-protocol.md +472 -0
- package/providers/codex/n0-harness/README.md +57 -0
- package/providers/codex/n0-harness/cli.mjs +58 -0
- package/providers/codex/n0-harness/evidence-manifest.mjs +77 -0
- package/providers/codex/n0-harness/fixture.mjs +279 -0
- package/providers/codex/n0-harness/lib.mjs +141 -0
- package/providers/codex/n0-harness/manifest.mjs +36 -0
- package/providers/codex/n0-harness/oracle.mjs +464 -0
- package/providers/codex/n0-harness/parser.mjs +200 -0
- package/providers/codex/n0-harness/prompt.mjs +43 -0
- package/providers/codex/n0-harness/snapshot.mjs +120 -0
- package/providers/codex/n0-harness/specimen.mjs +37 -0
- package/providers/codex/notify/kijito-notify-count.mjs +117 -0
- package/providers/codex/notify/kijito-notify-count.test.mjs +76 -0
- package/providers/codex/plans/gate4-battery-log.md +184 -0
- package/providers/codex/plans/gate4-battery-protocol.md +43 -0
- package/providers/codex/plans/hive-user-first-plan-QA.md +34 -0
- package/providers/codex/plans/hive-user-first-plan.md +247 -0
- package/providers/codex/release-manifest.json +53 -0
- package/providers/codex/same-chat-continuation-plan-gate.md +235 -0
- package/providers/codex/same-chat-continuation-plan.md +458 -0
- package/providers/codex/skills/kijito-qa-memory/SKILL.md +193 -0
- package/providers/codex/skills/kijito-qa-memory/agents/openai.yaml +4 -0
- package/providers/codex/skills/kijito-recall/SKILL.md +53 -0
- package/providers/codex/skills/kijito-start/SKILL.md +173 -0
- package/providers/codex/skills/kijito-start/agents/openai.yaml +4 -0
- package/providers/codex/test/n0-cli-refusal.test.mjs +31 -0
- package/providers/codex/test/n0-counterexample-matrix.test.mjs +118 -0
- package/providers/codex/test/n0-guard-census-core.mjs +1372 -0
- package/providers/codex/test/n0-guard-census.json +35479 -0
- package/providers/codex/test/n0-guard-census.mjs +31 -0
- package/providers/codex/test/n0-guard-census.test.mjs +374 -0
- package/providers/codex/test/n0-guard-counterexamples.mjs +1068 -0
- package/providers/codex/test/n0-guard-independent-projection.mjs +70 -0
- package/providers/codex/test/n0-guard-independent-projection.test.mjs +53 -0
- package/providers/codex/test/n0-guard-manifest-author.mjs +424 -0
- package/providers/codex/test/n0-guard-mutation-operators.test.mjs +244 -0
- package/providers/codex/test/n0-guard-mutation-runner.mjs +599 -0
- package/providers/codex/test/n0-guard-remainder-classes.test.mjs +314 -0
- package/providers/codex/test/n0-guard-sanitizer-pairs.test.mjs +68 -0
- package/providers/codex/test/n0-guard-shared-context-predicates.test.mjs +84 -0
- package/providers/codex/test/n0-harness.test.mjs +553 -0
- package/providers/codex/test/n0-notable-regressions.test.mjs +70 -0
- package/providers/codex/test/n0-subject-boundary.mjs +97 -0
- package/providers/codex/test/n0-subject-boundary.test.mjs +72 -0
- package/providers/codex/test/same-chat-plan-preflight.sh +167 -0
- package/providers/codex/tools/refresh-manifest.mjs +81 -0
- package/providers/codex/wake-helper/TRANSPORT-NOTES.md +25 -0
- package/providers/codex/wake-helper/integration.test.mjs +285 -0
- package/providers/codex/wake-helper/kijito-wake-helper.mjs +488 -0
- package/providers/codex/wake-helper/kijito-wake-helper.test.mjs +128 -0
- package/providers/codex/wake-helper/mock-daemon.mjs +64 -0
- package/providers/codex/wake-helper/status-probe.mjs +45 -0
- package/providers/codex/wake-helper/ws-uds.mjs +153 -0
- package/providers/monitor/.github/workflows/publish-npm.yml +38 -0
- package/providers/monitor/.github/workflows/publish-pypi.yml +30 -0
- package/providers/monitor/CHANGELOG.md +465 -0
- package/providers/monitor/IMPORT-PROVENANCE.md +68 -0
- package/providers/monitor/LICENSE +202 -0
- package/providers/monitor/NOTICE +7 -0
- package/providers/monitor/OPAQUE-OUTPUT-ENFORCEMENT.md +45 -0
- package/providers/monitor/README.md +571 -0
- package/providers/monitor/RELEASING.md +125 -0
- package/providers/monitor/arm-hive-monitor.sh +13 -0
- package/providers/monitor/bin/cli.js +43 -0
- package/providers/monitor/com.kijito.inbox-monitor.plist.template +59 -0
- package/providers/monitor/docs/DESIGN.md +984 -0
- package/providers/monitor/kijito-inbox-monitor@.service.template +95 -0
- package/providers/monitor/kijito_inbox_monitor.py +3666 -0
- package/providers/monitor/package.json +35 -0
- package/providers/monitor/pyproject.toml +42 -0
- package/providers/monitor/scripts/mutation-check.py +399 -0
- package/providers/monitor/scripts/prepublish-gate.sh +284 -0
- package/providers/monitor/test_kijito_monitor.py +5609 -0
|
@@ -0,0 +1,472 @@
|
|
|
1
|
+
# Codex same-chat continuation N0 capability-probe protocol
|
|
2
|
+
|
|
3
|
+
Status: **PROTOCOL DRAFT — NO PROBE ACTION AUTHORIZED.**
|
|
4
|
+
|
|
5
|
+
This protocol operationalizes only N0a and N0b of
|
|
6
|
+
`same-chat-continuation-plan.md`. It is not provider code, a task prompt, a doctor implementation,
|
|
7
|
+
an installation, or permission to create a Scheduled task. Assay must complete two consecutive
|
|
8
|
+
zero-finding reviews from different angles on the exact unchanged protocol digest before Codex
|
|
9
|
+
prepares a test harness or asks Jason to perform the first attended marker action. Assay must then
|
|
10
|
+
complete the same two-consecutive-review gate on the frozen harness before any Scheduled task is
|
|
11
|
+
created.
|
|
12
|
+
|
|
13
|
+
Plan authority:
|
|
14
|
+
|
|
15
|
+
- PR #6 plan commit: `68a2ad85acac88fbfa785bd3026575a73b156f80`
|
|
16
|
+
- reviewed plan SHA-256: `3d11d5e0defd248e3a26d12ddb073fdd337acf8f38df785a204fbd2e0f22afac`
|
|
17
|
+
- Assay plan reviews: round 6 CLEAN at `0ec3f8b`, round 7 CLEAN at `247b31d`
|
|
18
|
+
- authority opened by those reviews: disposable N0a/N0b capability probes only
|
|
19
|
+
|
|
20
|
+
Current pre-probe observations, recorded 2026-07-30:
|
|
21
|
+
|
|
22
|
+
- macOS `26.4.1` (`25E253`)
|
|
23
|
+
- ChatGPT desktop `26.721.30844` build `5813`
|
|
24
|
+
- bundled `codex-cli 0.145.0`
|
|
25
|
+
- installed `0.145.0` permission branch measured before this revision: `codex sandbox -P :workspace`
|
|
26
|
+
remained able to write cwd, `/private/tmp`, and `$TMPDIR` even when legacy
|
|
27
|
+
`sandbox_workspace_write.exclude_*` overrides were supplied, so that combination is rejected;
|
|
28
|
+
a named profile extending `:workspace` with `:tmpdir = "deny"` and `:slash_tmp = "deny"` kept the
|
|
29
|
+
disposable cwd write GREEN and made both temp canaries fail `Operation not permitted` (exit 1)
|
|
30
|
+
- the CLI result proves the installed local sandbox primitive only; N0a-W must independently prove
|
|
31
|
+
that the ChatGPT Scheduled surface selects and preserves the same named profile, otherwise RED
|
|
32
|
+
- the loaded user config currently has SHA-256
|
|
33
|
+
`8bd92cc0d0305e71f81bf11ed196c3f2bd2461954260b113c4ea19fdf7f2f7fc` and contains legacy
|
|
34
|
+
`sandbox_mode = "workspace-write"`; no managed `allowed_permission_profiles` source was found
|
|
35
|
+
- official `0.145.0` documentation says any loaded `sandbox_mode` selects the legacy sandbox branch,
|
|
36
|
+
so the project-local profile is not presumed effective: if the desktop does not expose and apply
|
|
37
|
+
`n0-workspace` as a named/custom session permission, N0a-W is RED before any Scheduled task runs;
|
|
38
|
+
ordinary config is not edited to manufacture eligibility
|
|
39
|
+
- current official Codex manual SHA-256
|
|
40
|
+
`69bac3511f1d13a49b9a70bcafa9eae04e18376b65c17368e483dfc26c50e89d`
|
|
41
|
+
- the manual says an in-chat Scheduled task returns to the same chat with its existing context,
|
|
42
|
+
supports minute intervals, can use chat-available skills/plugins, and runs unattended with the
|
|
43
|
+
selected local project/worktree and default sandbox; these are claims to test, not evidence that
|
|
44
|
+
this installation satisfies N0
|
|
45
|
+
- legacy PID `38082` is alive and intentionally untouched; it is the withdrawn dedicated-thread
|
|
46
|
+
notifier and never counts as same-chat evidence
|
|
47
|
+
|
|
48
|
+
## 1. Binary verdict and stop rules
|
|
49
|
+
|
|
50
|
+
N0 has two independent verdicts, `N0A_GREEN|RED|BLOCKED` and
|
|
51
|
+
`N0B_GREEN|RED|BLOCKED`. `N0_GREEN` requires both GREEN on one frozen protocol and one frozen harness.
|
|
52
|
+
`BLOCKED` is never converted to GREEN by explanation, self-report, screenshot, or partial evidence.
|
|
53
|
+
|
|
54
|
+
A mandatory case is RED when the installed product behaves contrary to the reviewed plan. It is
|
|
55
|
+
BLOCKED only when an attended prerequisite was not performed or an external outage prevents a
|
|
56
|
+
measurement. A procedural defect in the harness invalidates the affected run, changes the harness
|
|
57
|
+
digest, and returns to Assay review before a fresh nonce and retry. Product RED is not retried under a
|
|
58
|
+
different prompt until a new reviewed protocol explains why the changed prompt still tests the same
|
|
59
|
+
property.
|
|
60
|
+
|
|
61
|
+
Stop immediately and preserve read-only evidence if any of these occurs:
|
|
62
|
+
|
|
63
|
+
- a task or run cannot be tied to the marker-pinned exact chat `T` by an app-owned artifact outside
|
|
64
|
+
the run;
|
|
65
|
+
- the verifier finds zero or multiple marker matches;
|
|
66
|
+
- a run starts in a new, standalone, newest, visually similar, or controller-owned chat;
|
|
67
|
+
- task creation, inspection, pause, resume, or deletion would require UI/accessibility automation,
|
|
68
|
+
a private protocol, transcript mtime guessing, `thread/resume`, `thread/injectItems`, or steering;
|
|
69
|
+
- the effective cwd, project/worktree, model, sandbox, approval mode, permission profile, skill/plugin,
|
|
70
|
+
or MCP availability differs from the pre-registered specimen;
|
|
71
|
+
- a scheduled run mutates hive unread state, uses persona `codex` for anything except the one allowed
|
|
72
|
+
`mark_read=false` capability peek, or reads a mail body into the task prompt;
|
|
73
|
+
- the exact Scheduled run record, run/turn ID, or independent rollout evidence required by the plan
|
|
74
|
+
is unavailable;
|
|
75
|
+
- the legacy controller, its lock, ordinary Codex config/auth, production Kijito state, or a
|
|
76
|
+
non-disposable workspace would be changed.
|
|
77
|
+
|
|
78
|
+
No result from this protocol authorizes provider/server implementation, N1-N3, merge, install,
|
|
79
|
+
migration, River's provider-neutral API work, legacy-controller restart, or production cutover.
|
|
80
|
+
|
|
81
|
+
## 2. Roles, isolation, and evidence custody
|
|
82
|
+
|
|
83
|
+
The attended operator performs only documented ChatGPT desktop controls and explicitly identified
|
|
84
|
+
screen-lock/sleep actions. Codex prepares prompts and read-only verifier commands but never drives the
|
|
85
|
+
UI. The outside verifier is a separate local process that is not a Scheduled run and does not use the
|
|
86
|
+
run's prose as evidence.
|
|
87
|
+
|
|
88
|
+
The PR review worktree is never the Scheduled task's project and is never inside that task's intended
|
|
89
|
+
writable scope. A newly created specimen has two separated roots:
|
|
90
|
+
|
|
91
|
+
- `/Users/jason/N0-Probes/<probe-id>/project/` is a dedicated detached disposable git worktree
|
|
92
|
+
created from the reviewed commit solely for N0; its whole
|
|
93
|
+
`/Users/jason/N0-Probes/<probe-id>/` tree is treated as disposable, contains no user work, and the
|
|
94
|
+
exact `project/` path is selected for every task;
|
|
95
|
+
- `/Users/jason/.local/state/codex-n0/<probe-id>/` is an owner-only outside-verifier control root,
|
|
96
|
+
created specifically for this probe, outside the task's selected project and ordinary temporary
|
|
97
|
+
writable roots, and holds the frozen specimen and evidence.
|
|
98
|
+
|
|
99
|
+
Owner-only mode is not treated as separation because the Scheduled process runs as the same OS user.
|
|
100
|
+
Across every eligible run the outside verifier seals the control directory non-traversable (`000`),
|
|
101
|
+
keeps comparison state in memory or through already-open descriptors, and restores access only after
|
|
102
|
+
the run is terminal. No secret-readable window may overlap task eligibility. N0a-W must prove the
|
|
103
|
+
Scheduled run cannot read a named control canary or chmod, replace, rename, delete, or create anything
|
|
104
|
+
in the sealed root. Any read or metadata/write success is RED.
|
|
105
|
+
|
|
106
|
+
Before relying on this separation, a negative preflight must prove that a run with the exact selected
|
|
107
|
+
project and sandbox can read the registered fixture in the disposable project but cannot read or
|
|
108
|
+
change the sealed control canary and cannot create a randomized canary in the control root or PR
|
|
109
|
+
review worktree. It must also prove every pre-existing file there, the ordinary Codex config/auth
|
|
110
|
+
hashes, and the original
|
|
111
|
+
`/Users/jason/Code/SideProjects/Codex/.codex/` tree remained unchanged. Any write to a non-disposable
|
|
112
|
+
path succeeds => RED and all later cases stop. Prompt text and what the run happened to touch are not
|
|
113
|
+
the boundary: verdicts use the effective granted profile plus denial probes. Any granted writable
|
|
114
|
+
root other than the exact disposable `project/` is RED.
|
|
115
|
+
|
|
116
|
+
The disposable project contains a pre-registered named permission profile `n0-workspace` that extends
|
|
117
|
+
`:workspace`, grants no additional workspace root, and sets both `:tmpdir` and `:slash_tmp` to `deny`.
|
|
118
|
+
The attended operator must be able to select that exact named/custom profile in the desktop
|
|
119
|
+
permissions control before task creation. The profile lives only in the trusted disposable project's
|
|
120
|
+
`.codex/config.toml`; ordinary Codex configuration is not changed. Because the current user config
|
|
121
|
+
selects the mutually exclusive legacy sandbox branch, merely defining the project profile is not
|
|
122
|
+
evidence that it is active. Absence of the named/custom selection, a warning that it was ignored, or
|
|
123
|
+
effective evidence that remains on legacy `workspace-write` is an immediate N0a-W RED and no
|
|
124
|
+
Scheduled task is created. If selection is available, N0a-W must still prove the effective run names
|
|
125
|
+
that exact profile, keeps the exact cwd writable, and denies randomized canaries in both
|
|
126
|
+
`/private/tmp` and the host `$TMPDIR`. Ignoring either deny, adding another writable root, or making
|
|
127
|
+
the cwd unwritable is RED.
|
|
128
|
+
|
|
129
|
+
The successful installed-CLI primitive measurement used these exact UTF-8 `config.toml` bytes
|
|
130
|
+
(including the final newline), SHA-256
|
|
131
|
+
`a3546800038c3c90a69ea7c45926cc9f12739e66fcf05f97feaf3a03299b54b8`:
|
|
132
|
+
|
|
133
|
+
```toml
|
|
134
|
+
default_permissions = "n0-workspace"
|
|
135
|
+
|
|
136
|
+
[permissions.n0-workspace]
|
|
137
|
+
extends = ":workspace"
|
|
138
|
+
|
|
139
|
+
[permissions.n0-workspace.filesystem]
|
|
140
|
+
":tmpdir" = "deny"
|
|
141
|
+
":slash_tmp" = "deny"
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
The isolated layout placed that file at
|
|
145
|
+
`/Users/jason/Code/SideProjects/Codex/.qa-tmp/n0-advp-round4/codex-home/config.toml` and used the
|
|
146
|
+
separate non-temp workspace
|
|
147
|
+
`/Users/jason/Code/SideProjects/Codex/.qa-tmp/n0-advp-round4/project/`. The tested binary was
|
|
148
|
+
`/Users/jason/.codex/packages/standalone/releases/0.145.0-aarch64-apple-darwin/bin/codex`, reported
|
|
149
|
+
`codex-cli 0.145.0`, and had SHA-256
|
|
150
|
+
`1da3f4e0e96028b8a771814293c3033dafd1971f943f6c7e79b0897fe705f590`. The exact three commands were:
|
|
151
|
+
|
|
152
|
+
```sh
|
|
153
|
+
/usr/bin/env CODEX_HOME=/Users/jason/Code/SideProjects/Codex/.qa-tmp/n0-advp-round4/codex-home /Users/jason/.codex/packages/standalone/releases/0.145.0-aarch64-apple-darwin/bin/codex sandbox -P n0-workspace -C /Users/jason/Code/SideProjects/Codex/.qa-tmp/n0-advp-round4/project -- /usr/bin/touch /Users/jason/Code/SideProjects/Codex/.qa-tmp/n0-advp-round4/project/inside
|
|
154
|
+
/usr/bin/env CODEX_HOME=/Users/jason/Code/SideProjects/Codex/.qa-tmp/n0-advp-round4/codex-home /Users/jason/.codex/packages/standalone/releases/0.145.0-aarch64-apple-darwin/bin/codex sandbox -P n0-workspace -C /Users/jason/Code/SideProjects/Codex/.qa-tmp/n0-advp-round4/project -- /usr/bin/touch /private/tmp/n0-advp-round4-slash-tmp
|
|
155
|
+
/usr/bin/env CODEX_HOME=/Users/jason/Code/SideProjects/Codex/.qa-tmp/n0-advp-round4/codex-home /Users/jason/.codex/packages/standalone/releases/0.145.0-aarch64-apple-darwin/bin/codex sandbox -P n0-workspace -C /Users/jason/Code/SideProjects/Codex/.qa-tmp/n0-advp-round4/project -- /usr/bin/touch /var/folders/z2/qvgc70gs2sl87pkrd4fffnk40000gn/T/n0-advp-round4-envtmp
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
The cwd command exited `0`; the `/private/tmp` and resolved `$TMPDIR` commands each exited `1` with
|
|
159
|
+
`Operation not permitted`, and neither outside canary existed afterward. Both `CODEX_HOME` and `-C`
|
|
160
|
+
were outside the two special temp roots; implementations with either root inside a temp grant are not
|
|
161
|
+
equivalent reproductions. These commands prove only the isolated CLI primitive. The current desktop
|
|
162
|
+
and Scheduled path remains subject to the separate effective-profile RED gates above.
|
|
163
|
+
|
|
164
|
+
Both roots must contain no symlink except normal Git-managed worktree metadata, and the disposable
|
|
165
|
+
worktree must be removed from every project/task selector after the probe. No real auth file, API
|
|
166
|
+
token, production mailbox body, whole transcript, or ordinary Codex configuration is copied into
|
|
167
|
+
either root. The evidence pack may retain only:
|
|
168
|
+
|
|
169
|
+
- file identity and bounded structural metadata for rollout candidates;
|
|
170
|
+
- the exact matching marker and run nonces;
|
|
171
|
+
- parsed `session_meta.payload.id`, run/turn/task IDs, timestamps, and environment/permission fields;
|
|
172
|
+
- prompt and artifact digests;
|
|
173
|
+
- bounded receipts created inside the disposable `project/` root;
|
|
174
|
+
- redacted screenshots of attended Scheduled controls when no machine-readable management artifact
|
|
175
|
+
exists, labeled `SETUP_EVIDENCE_ONLY`;
|
|
176
|
+
- command/version output and the verifier's deterministic verdicts.
|
|
177
|
+
|
|
178
|
+
Every evidence record contains `probe_id`, protocol digest, harness commit/digest, UTC time, host time,
|
|
179
|
+
the app and CLI versions, the target path, and the evidence producer. Hashes are computed only after
|
|
180
|
+
files stop changing. A manifest records each evidence file's relative path, size, and SHA-256. The
|
|
181
|
+
Scheduled principal cannot write the manifest or verifier verdicts. Assay receives the manifest plus
|
|
182
|
+
the minimal evidence needed to reproduce verdicts, never secrets.
|
|
183
|
+
|
|
184
|
+
The probe uses the stable dedicated test persona `codex-n0`; it does not create a new persona for each
|
|
185
|
+
run. It never creates or changes a memory, claim, checkpoint, or mail row owned by persona `codex`.
|
|
186
|
+
N0a-K may use persona `codex` only for the plan-authorized current-pointer/tool-reachability peek with
|
|
187
|
+
`mark_read=false`; any returned body remains untrusted data, the run takes no action from it, and that
|
|
188
|
+
peek is not the unread-mutation proof or dependent on unread state.
|
|
189
|
+
The mutation proof uses an exact synthetic unread row self-sent by and owned by `codex-n0`, so legacy
|
|
190
|
+
persona-`codex` consumers cannot alter it. If the hosted surface cannot create that isolated fixture
|
|
191
|
+
without another production persona, the case is BLOCKED rather than weakening attribution.
|
|
192
|
+
|
|
193
|
+
The outside verifier, not this chat or the Scheduled run, generates the test row's 128-bit body nonce
|
|
194
|
+
in process memory and sends the fixture without emitting that nonce to stdout, model context, the
|
|
195
|
+
task prompt, the disposable project, or pre-run evidence shown in the chat. Only its SHA-256 is
|
|
196
|
+
persisted in the sealed control root; the raw nonce is never written locally before the run. The body
|
|
197
|
+
nonce is distinct from the case/run nonce. The expected current pointer is selected immediately
|
|
198
|
+
before N0a-K by running the installed skill's exact sentinel recall outside the Scheduled run:
|
|
199
|
+
`kijito_recall(query="CODEX_CURRENT_STATE_POINTER_V1 RESUME NOW", scope="project", project="Codex",
|
|
200
|
+
full=true)`. The same query is pinned in `providers/codex/skills/kijito-start/SKILL.md` line 19 of the
|
|
201
|
+
frozen commit. The verifier requires one unambiguous top live result, freezes that exact memory ID,
|
|
202
|
+
and hashes the canonical UTF-8 content returned by `kijito_get(id)`. The parser ignores edge-preview
|
|
203
|
+
blocks and requires the final main `UNTRUSTED` block to name that exact requested ID and
|
|
204
|
+
`persona:codex`; it hashes only the body bytes between that block's fences, excluding the per-response
|
|
205
|
+
fence nonce. Zero or multiple main matches invalidates the snapshot. The ID and digest live only in
|
|
206
|
+
the sealed control root; neither is written into this protocol, prompt, project, or chat before the
|
|
207
|
+
run. The outside verifier re-fetches that exact ID after the run and requires the same digest. A
|
|
208
|
+
pre/post mismatch invalidates the case and requires a fresh snapshot; this protocol claims no Kijito
|
|
209
|
+
lease primitive.
|
|
210
|
+
|
|
211
|
+
## 3. Frozen specimen and outside-verifier contract
|
|
212
|
+
|
|
213
|
+
Before the first attended action, the reviewed harness must generate and freeze `specimen.json` in
|
|
214
|
+
the outside-verifier control root with:
|
|
215
|
+
|
|
216
|
+
- a random 128-bit `probe_id` and separate verifier-generated 128-bit nonces for every case;
|
|
217
|
+
- exact disposable target worktree path, device/inode, git HEAD, clean status, and permission profile;
|
|
218
|
+
- exact PR review-worktree and verifier-control paths that must remain outside the task's writable
|
|
219
|
+
roots, plus the named write-denial canaries used to prove the separation;
|
|
220
|
+
- model and reasoning selection, sandbox mode, approval mode, network allowance, and permitted tools;
|
|
221
|
+
- exact `n0-workspace` profile bytes/digest, resolved `:slash_tmp` and `:tmpdir` paths, zero additional
|
|
222
|
+
workspace roots, and the registered cwd/temp/sibling denial canaries;
|
|
223
|
+
- the full candidate task prompt bytes and SHA-256 for every scheduled case;
|
|
224
|
+
- the intended minute boundary and acceptable host/server skew;
|
|
225
|
+
- the pre-action rollout snapshot and the bounded parser version/digest;
|
|
226
|
+
- explicit expected IDs that are known before each run; a run may fill only fields that cannot exist
|
|
227
|
+
before scheduling, and the attended operator must record those through documented controls before
|
|
228
|
+
the first eligible run.
|
|
229
|
+
|
|
230
|
+
The rollout snapshot walks only real, owner-matching files beneath the documented app-owned Codex
|
|
231
|
+
session root. It records path, device, inode, size, and first-record structural type without treating
|
|
232
|
+
mtime or newest-path order as identity. After Jason submits a marker, the verifier searches only files
|
|
233
|
+
created or advanced beyond the frozen snapshot, within a bounded byte range. Exactly one candidate
|
|
234
|
+
must contain the exact marker nonce in a user turn and must begin with a valid
|
|
235
|
+
`session_meta.payload.id`. That ID is `T`. The marker proves only `T`; it does not prove a scheduled
|
|
236
|
+
run belongs to `T`.
|
|
237
|
+
|
|
238
|
+
For every scheduled run, the outside verifier independently requires all of:
|
|
239
|
+
|
|
240
|
+
1. the Scheduled control record captured by the attended operator identifies the pre-registered task
|
|
241
|
+
and run;
|
|
242
|
+
2. one app-owned rollout beginning with `session_meta.payload.id == T` contains the corresponding
|
|
243
|
+
Scheduled run/turn identity and pre-registered run nonce;
|
|
244
|
+
3. the rollout's cwd/project/worktree, model, sandbox, approval, and permission evidence equals the
|
|
245
|
+
frozen specimen;
|
|
246
|
+
4. any disposable receipt is attributable to the same run/turn ID and nonce;
|
|
247
|
+
5. the run neither steered an active turn nor relied on its own statement that it was in the right
|
|
248
|
+
chat.
|
|
249
|
+
|
|
250
|
+
If the installed build exposes no machine-readable Scheduled run record or no independent binding
|
|
251
|
+
between that record and the app-owned rollout, the case is RED. A screenshot can establish what the
|
|
252
|
+
operator selected, but cannot replace the run binding.
|
|
253
|
+
|
|
254
|
+
## 4. N0a case matrix
|
|
255
|
+
|
|
256
|
+
Each case uses a fresh nonce. A prior run, duplicate Scheduled firing, or late completion bearing an
|
|
257
|
+
old nonce cannot satisfy a later case.
|
|
258
|
+
|
|
259
|
+
### N0a-M — marker pins the exact chat
|
|
260
|
+
|
|
261
|
+
1. Freeze the rollout snapshot and marker nonce outside ChatGPT.
|
|
262
|
+
2. Ask Jason to submit exactly one attended marker turn in the intended existing chat.
|
|
263
|
+
3. Resolve `T` with the outside-verifier contract above.
|
|
264
|
+
|
|
265
|
+
GREEN requires exactly one matching rollout and one `session_meta.payload.id`. This is the first user
|
|
266
|
+
action and is requested only after protocol and harness QA are CLEAN.
|
|
267
|
+
|
|
268
|
+
### N0a-W — disposable write-boundary proof
|
|
269
|
+
|
|
270
|
+
Before trusting any later case, a scheduled run bound to `T` reads the registered fixture in
|
|
271
|
+
disposable project, attempts to read and chmod one named sealed-control canary, and attempts only
|
|
272
|
+
randomized, previously nonexistent canary paths in the control root, PR review worktree, a sibling of
|
|
273
|
+
the exact disposable project, `/private/tmp`, and the resolved host `$TMPDIR`. Every control
|
|
274
|
+
read/metadata/write attempt and every out-of-project create must be denied while one registered cwd
|
|
275
|
+
receipt succeeds. The outside verifier hashes all pre-existing config/auth, original-workspace
|
|
276
|
+
`.codex`, and review-worktree files before and after and requires them unchanged; no write is attempted
|
|
277
|
+
against a real config/auth path. Verdict is based on the granted `n0-workspace` profile and every
|
|
278
|
+
canary, not on a claim that an untested broad root happened to remain untouched. If an out-of-project
|
|
279
|
+
canary is unexpectedly created, the outside verifier records RED, removes only that exact randomized
|
|
280
|
+
canary after ownership/path verification, and stops N0. The probe never attempts to replace, rename,
|
|
281
|
+
or delete a real config, auth, source, or evidence file.
|
|
282
|
+
|
|
283
|
+
### N0a-B — baseline after a completed manual turn
|
|
284
|
+
|
|
285
|
+
Create a disposable one-minute in-chat task through documented controls. Its frozen prompt returns
|
|
286
|
+
the case nonce and reads only structural evidence needed to prove the specimen environment. It makes
|
|
287
|
+
no file, mailbox, configuration, or external-state mutation. Run identity and every environment field
|
|
288
|
+
must match `T` and the specimen. Any standalone/new chat or unavailable run binding is RED.
|
|
289
|
+
|
|
290
|
+
### N0a-Q — scheduled input during an active manual turn
|
|
291
|
+
|
|
292
|
+
Jason starts a bounded manual turn in `T` so it spans the next registered minute boundary. The
|
|
293
|
+
scheduled task becomes eligible during that turn. GREEN requires the scheduled input to queue, start
|
|
294
|
+
only after the manual turn releases ownership, retain its own registered run identity, and show no
|
|
295
|
+
`turn/steer` or merged disposition. Overlap, steering, lost run, or wrong chat is RED.
|
|
296
|
+
|
|
297
|
+
### N0a-O — two tasks forced to overlap
|
|
298
|
+
|
|
299
|
+
Two disposable in-chat tasks target the same registered minute. Task A owns a pre-created disposable
|
|
300
|
+
75-second barrier; task B becomes eligible while A is active. The barrier and atomic collision receipt
|
|
301
|
+
are test fixtures, not provider code, and the 75-second duration is the plan's explicit synthetic
|
|
302
|
+
exception to the 45-second production slice cap.
|
|
303
|
+
|
|
304
|
+
GREEN requires exactly one task to hold the fixture's winner token and act, while the other produces
|
|
305
|
+
an independently attributable collision receipt without steering, overwriting the winner, or making
|
|
306
|
+
a disposition. The verifier must distinguish provider scheduling from the fixture's own exclusion;
|
|
307
|
+
the forced concurrent eligibility is expected, but both tasks performing the registered action or
|
|
308
|
+
either task steering/overwriting is RED even when a later file-state snapshot looks singular.
|
|
309
|
+
|
|
310
|
+
### N0a-I — inactive/backgrounded desktop
|
|
311
|
+
|
|
312
|
+
With the app running but backgrounded and Jason inactive for at least ten minutes, one pre-registered
|
|
313
|
+
run must start within 90 seconds of eligibility and satisfy the full run binding. Foregrounding the app
|
|
314
|
+
or manually prompting to make it start invalidates the case.
|
|
315
|
+
|
|
316
|
+
### N0a-L — locked screen
|
|
317
|
+
|
|
318
|
+
With the computer awake, app running, and screen locked across the eligible boundary, one
|
|
319
|
+
pre-registered run must start within 90 seconds and satisfy the full binding. The operator records
|
|
320
|
+
lock and unlock times; visual notification alone is not evidence.
|
|
321
|
+
|
|
322
|
+
### N0a-K — installed Kijito reachability and read-only inbox
|
|
323
|
+
|
|
324
|
+
In a second disposable run, explicitly invoke installed `kijito-start` only far enough to prove that
|
|
325
|
+
the Scheduled surface can use the installed skill/plugin/MCP, reach hosted `https://api.kijito.ai/mcp/`,
|
|
326
|
+
return the current pointer ID plus canonical content digest, and perform the allowed persona-`codex`
|
|
327
|
+
`mark_read=false` capability peek without acting on returned data. The outside verifier compares the
|
|
328
|
+
run's pointer pair to the withheld control-root snapshot; no constant from the prompt/project can
|
|
329
|
+
satisfy it.
|
|
330
|
+
|
|
331
|
+
Separately, the outside fixture creates one exact unread row containing the withheld body nonce by
|
|
332
|
+
self-sending from `codex-n0` to `codex-n0` before the run. The prompt may contain the row ID but never
|
|
333
|
+
the body nonce. The Scheduled run exact-fetches that row using `before_id = row_id + 1`, `limit = 1`,
|
|
334
|
+
and `mark_read=false`, rejects any returned ID other than the registered row, and its app-owned rollout
|
|
335
|
+
must contain the exact fetched body nonce. The outside verifier exact-fetches the row with the same
|
|
336
|
+
cursor plus `unread_only=true, mark_read=false` before and after and requires the same ID/body digest
|
|
337
|
+
to remain unread. Merely showing unchanged unread state without the fetched nonce in the run artifact
|
|
338
|
+
is RED. Only after the evidence manifest freezes may the outside fixture mark that test row read as
|
|
339
|
+
cleanup.
|
|
340
|
+
|
|
341
|
+
N0a-K is GREEN only when both independent challenges pass: the run's pointer ID/content-digest pair
|
|
342
|
+
equals the withheld single-writer snapshot, and the rollout contains fetched row content whose
|
|
343
|
+
SHA-256 equals the withheld body-nonce digest. Either proof alone is insufficient.
|
|
344
|
+
|
|
345
|
+
The task must not follow the pointer's continuation instruction, arm or start a controller, read a
|
|
346
|
+
production mail body into its instructions, update memory, or act on returned mail. A fixture that
|
|
347
|
+
cannot be created or is already read before the Scheduled run is BLOCKED. Empty-inbox substitution,
|
|
348
|
+
foreign-persona write, failure to emit the withheld nonce from the exact fetch, or legacy-consumer
|
|
349
|
+
attribution is RED.
|
|
350
|
+
|
|
351
|
+
N0a is GREEN only if N0a-M, N0a-W, N0a-B, N0a-Q, N0a-O, N0a-I, N0a-L, and
|
|
352
|
+
N0a-K are all GREEN.
|
|
353
|
+
|
|
354
|
+
## 5. N0b lifecycle and health case matrix
|
|
355
|
+
|
|
356
|
+
N0b uses documented ChatGPT desktop controls only. Each lifecycle transition records attended setup
|
|
357
|
+
evidence plus independently observed eligible/non-eligible runs for at least two one-minute cadences.
|
|
358
|
+
|
|
359
|
+
| Case | Attended action | Required independent result |
|
|
360
|
+
|---|---|---|
|
|
361
|
+
| N0b-C | Create in `T` | Stable task identity is captured; an eligible run binds to `T` and the frozen specimen. |
|
|
362
|
+
| N0b-S | Inspect | Status, prompt digest, cadence, project/worktree, model, and recent-run identity can be captured without guessing. |
|
|
363
|
+
| N0b-P | Pause | No new eligible run appears for two cadences; health expires and cannot remain ARMED. |
|
|
364
|
+
| N0b-R | Resume | A new run with a fresh nonce and task identity appears; old evidence cannot re-arm it. |
|
|
365
|
+
| N0b-D | Delete | No run appears for two cadences; stale rollout or screenshot evidence cannot imply enabled state. |
|
|
366
|
+
| N0b-X | App exit | Project-scoped run behavior is measured; no unsupported claim is substituted for observation. |
|
|
367
|
+
| N0b-W | Sleep/wake | Missed and resumed cadence behavior is measured without changing the legacy controller. |
|
|
368
|
+
| N0b-L | Screen lock | Locked/background behavior is measured and correlated with the N0a-L run evidence. |
|
|
369
|
+
| N0b-J | Project removal | Temporarily select a disposable renamed/missing project path; the task must fail closed and health becomes RED. |
|
|
370
|
+
| N0b-F | Permission drift | Use only a per-task/per-disposable-project permission change exposed by documented controls; mismatched effective evidence makes health RED. If the product offers only a global/default change, do not change it and mark the capability RED. |
|
|
371
|
+
|
|
372
|
+
The protocol records discovered cadence, quota/rate, retention/expiry, recent-run, and notification
|
|
373
|
+
limits rather than assuming them. Host/server skew is measured at the beginning and end of each
|
|
374
|
+
lifecycle sequence and must not exceed 15 seconds. If the product provides no trustworthy server
|
|
375
|
+
timestamp, this requirement is RED, not estimated from prose.
|
|
376
|
+
|
|
377
|
+
### N0b doctor oracle
|
|
378
|
+
|
|
379
|
+
N0 may build only a disposable, non-installable, read-only oracle that consumes the frozen evidence
|
|
380
|
+
schema. It cannot invoke ChatGPT, Kijito mutations, or provider code and must refuse evidence outside
|
|
381
|
+
the specimen root. It is labeled `N0_TEST_ORACLE` and never reports production `ARMED`.
|
|
382
|
+
|
|
383
|
+
The oracle's healthy test verdict requires current exact-chat run evidence, a heartbeat no older than
|
|
384
|
+
135 seconds by server time, matching task/prompt/environment/permission identity, and all synthetic
|
|
385
|
+
claim/checkpoint/operator-journal fixtures valid. Pause, delete, app-down behavior, project removal,
|
|
386
|
+
permission drift, stale evidence, wrong task/chat, or excess clock skew is RED within two cadences.
|
|
387
|
+
|
|
388
|
+
ADV-A is load-bearing before N0b:
|
|
389
|
+
|
|
390
|
+
- missing/unreachable operator-decision journal produces explicit `JOURNAL_UNREACHABLE`, RED;
|
|
391
|
+
- missing arm record, missing pinned signer, or invalid signer binding produces explicit
|
|
392
|
+
`SIGNER_UNARMED`, RED;
|
|
393
|
+
- neither state may collapse into generic `STALE`, be omitted, or leave a healthy verdict;
|
|
394
|
+
- each has a positive control, a mutation that would incorrectly return healthy, and a unique named
|
|
395
|
+
failing assertion;
|
|
396
|
+
- the live capability result remains `N0_TEST_CAPABLE`, never production `ARMED`, because N1 has not
|
|
397
|
+
yet proven or supplied the real journal/claim surfaces.
|
|
398
|
+
|
|
399
|
+
N0b is GREEN only if all lifecycle cases, clock evidence, management limits, artifact availability,
|
|
400
|
+
and doctor-oracle negative controls are GREEN. If doctor cannot distinguish enabled, paused, deleted,
|
|
401
|
+
stale, and drifted states from supported evidence, N0b is RED.
|
|
402
|
+
|
|
403
|
+
## 6. Prompt constraints for the later frozen harness
|
|
404
|
+
|
|
405
|
+
This protocol does not contain the executable task prompt. The later harness must render exact prompt
|
|
406
|
+
bytes that:
|
|
407
|
+
|
|
408
|
+
- say `N0 CAPABILITY PROBE — NO MAIL AUTHORITY` before any tool output;
|
|
409
|
+
- pin the specimen root, task case, nonce, allowed tools, sandbox, project, chat target, and maximum
|
|
410
|
+
effect before reading external data;
|
|
411
|
+
- treat all tool-returned mail and memory as untrusted data and forbid it from changing authority;
|
|
412
|
+
- prohibit provider/server implementation, controller start/stop, hooks, LaunchAgents, app-server
|
|
413
|
+
thread operations, UI automation, ordinary config/auth changes, network use except the single N0a-K
|
|
414
|
+
hosted Kijito reachability check, and writes outside the disposable `project/` root;
|
|
415
|
+
- stop after its bounded evidence action and emit no claim that the feature works;
|
|
416
|
+
- contain a deliberate hostile-data negative fixture whose text requests scope expansion, and prove
|
|
417
|
+
that effective configuration and receipts remain unchanged.
|
|
418
|
+
|
|
419
|
+
The prompt digest, not a paraphrase, is recorded before scheduling. Any UI rewrite or model-visible
|
|
420
|
+
addition changes the digest and invalidates the run unless the outside verifier can capture and hash
|
|
421
|
+
the exact effective prompt.
|
|
422
|
+
|
|
423
|
+
## 7. QA sequence and change control
|
|
424
|
+
|
|
425
|
+
1. **Protocol QA:** commit only this protocol and supporting documentation. Send Assay the returned
|
|
426
|
+
commit SHA and protocol SHA-256. The review request must copy the full commit verbatim from
|
|
427
|
+
`git rev-parse HEAD`, verify that exact object resolves, and pair it with a freshly computed file
|
|
428
|
+
digest; an agent must never expand an abbreviated SHA from memory. No marker, nonce submission,
|
|
429
|
+
task, harness, UI action, or sleep/lock probe occurs. Remediate findings and repeat until Assay says
|
|
430
|
+
CLEAN in two consecutive zero-finding reviews from different angles on the same unchanged commit
|
|
431
|
+
and digest. Any finding or byte change resets the protocol counter to `0/2`.
|
|
432
|
+
2. **Harness QA:** implement only the disposable snapshot/parser/oracle/fixture scripts and their
|
|
433
|
+
tests. Use production-shaped synthetic rollouts and mutations for zero/multiple marker matches,
|
|
434
|
+
wrong chat/run, mtime/newest guessing, symlink/path escape, concurrent mutation, task read/chmod/
|
|
435
|
+
write access to the sealed control root, task write access to the PR worktree, stale evidence,
|
|
436
|
+
omitted `:tmpdir`/`:slash_tmp` deny, an extra writable root, wrong/unselected permission profile,
|
|
437
|
+
a missing out-of-tree temp canary, and legacy `sandbox_workspace_write` flags falsely accepted as
|
|
438
|
+
proof for the installed named-profile branch,
|
|
439
|
+
false healthy after pause/delete, live-brain checks that omit the withheld pointer digest or
|
|
440
|
+
fetched body-nonce digest, and specimens that leak an expected pointer ID/digest or raw body nonce
|
|
441
|
+
into the protocol, prompt, project, chat, or pre-run logs. Also mutate `JOURNAL_UNREACHABLE`,
|
|
442
|
+
`SIGNER_UNARMED`, absent test mail, already-read test mail, and concurrent
|
|
443
|
+
persona-`codex` mail mutation that must not affect the `codex-n0` oracle. Freeze one commit and
|
|
444
|
+
digest; Assay must complete two consecutive zero-finding reviews from different angles on those
|
|
445
|
+
exact unchanged bytes before the first attended action. Any finding or byte change resets the
|
|
446
|
+
harness counter to `0/2`.
|
|
447
|
+
3. **Attended marker:** generate the one-use marker nonce, freeze the pre-snapshot, and ask Jason for
|
|
448
|
+
exactly one marker turn. If the attended marker is not submitted, N0a-M is BLOCKED; after one
|
|
449
|
+
confirmed submission, zero or multiple rollout matches is RED.
|
|
450
|
+
4. **N0 execution:** perform cases in order N0a-M, N0a-W, N0a-B, N0a-Q, N0a-O,
|
|
451
|
+
N0a-I, N0a-L, N0a-K, then N0b-C, N0b-S, N0b-P, N0b-R, N0b-D, N0b-X, N0b-W,
|
|
452
|
+
N0b-L, N0b-J, N0b-F.
|
|
453
|
+
Check inbox between cases, update the current-state pointer after every terminal case, and do not
|
|
454
|
+
continue after a RED without Assay reviewing the evidence and ruling whether it is product RED or
|
|
455
|
+
harness invalidation.
|
|
456
|
+
5. **Evidence QA:** freeze the manifest and results. Assay independently recomputes verdicts from the
|
|
457
|
+
evidence. Only an Assay-confirmed `N0A_GREEN` plus `N0B_GREEN` becomes `N0_GREEN`.
|
|
458
|
+
|
|
459
|
+
Any change to a binary pass condition, identity source, prompt authority, evidence channel, test
|
|
460
|
+
persona, lifecycle matrix, or RED threshold changes this protocol digest and returns to step 1.
|
|
461
|
+
Formatting-only changes after protocol CLEAN are deferred until N0 evidence QA is complete.
|
|
462
|
+
|
|
463
|
+
## 8. End state
|
|
464
|
+
|
|
465
|
+
On GREEN, record only that the installed Scheduled surface is capable of supporting later N1-N3
|
|
466
|
+
probes under the measured constraints. On RED, record the exact unsupported property and reject the
|
|
467
|
+
candidate without implementing around it. On BLOCKED, record the missing attended/external
|
|
468
|
+
prerequisite and preserve the unchanged authority boundary.
|
|
469
|
+
|
|
470
|
+
In all three cases, delete the disposable Scheduled tasks through documented controls, verify two
|
|
471
|
+
cadences without runs, retain the minimal redacted evidence manifest, leave legacy PID `38082`
|
|
472
|
+
untouched, and update memory and River/Assay mail with the exact verdict and remaining authorization.
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# N0 disposable evidence harness
|
|
2
|
+
|
|
3
|
+
Status: **TEST-ONLY, NON-INSTALLABLE, NO LIVE PROBE AUTHORITY.**
|
|
4
|
+
|
|
5
|
+
This directory implements only step 2 of
|
|
6
|
+
[`../n0-capability-probe-protocol.md`](../n0-capability-probe-protocol.md): bounded rollout snapshots,
|
|
7
|
+
strict parsers, synthetic fixtures, and the `N0_TEST_ORACLE`. It cannot create or manage a Scheduled
|
|
8
|
+
task, drive the ChatGPT UI, start or stop a controller, contact Kijito, send mail, mark mail read,
|
|
9
|
+
generate a live marker, or report production `ARMED`.
|
|
10
|
+
|
|
11
|
+
The modules are deliberately separated:
|
|
12
|
+
|
|
13
|
+
- `snapshot.mjs` walks one caller-supplied app-owned root without symlinks, newest/mtime selection,
|
|
14
|
+
or path escape and records stable file identity before comparing growth;
|
|
15
|
+
- `parser.mjs` requires `session_meta.payload.id`, attributes marker and run nonces only inside one
|
|
16
|
+
user-turn span, binds exact task/run/turn/environment evidence, rejects structural steering, parses
|
|
17
|
+
only the final exact-ID/persona Kijito main block, and verifies the exact non-mutating test-mail
|
|
18
|
+
fetch artifact;
|
|
19
|
+
- `oracle.mjs` validates the frozen specimen, write-boundary canaries, lifecycle evidence, live-brain
|
|
20
|
+
challenges, exact prompt bytes, project/rollout/parser provenance, journal/signer negatives, and
|
|
21
|
+
every per-case nonce/run/receipt binding. Its sole positive value is `N0_TEST_CAPABLE`;
|
|
22
|
+
- `fixture.mjs` contains deterministic synthetic data only. Its fixed hexadecimal strings are not
|
|
23
|
+
live nonces and must never be copied into a real probe;
|
|
24
|
+
- `prompt.mjs` renders exact per-case prompt bytes, including the fixed hostile-data negative fixture,
|
|
25
|
+
and `specimen.mjs` computes every prompt digest plus inert Kijito request packets without sending;
|
|
26
|
+
- `evidence-manifest.mjs` reads stable owner-matching files beneath one explicit control root and
|
|
27
|
+
produces or validates a relative-path/size/SHA-256 evidence manifest without writing it;
|
|
28
|
+
- `cli.mjs` is a read-only convenience wrapper. It accepts evidence files only beneath an explicit
|
|
29
|
+
root, rejects symlinks and concurrent mutation, and has no mutation or network subcommand.
|
|
30
|
+
|
|
31
|
+
Run the adversarial suite with a healthy Node 18+ runtime:
|
|
32
|
+
|
|
33
|
+
```sh
|
|
34
|
+
node --test providers/codex/test/n0-harness.test.mjs
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
The fail-open completeness gate uses an Acorn AST census, exact-source ownership, and one named
|
|
38
|
+
counterexample per executable rejection atom or rejecting-helper call site. Install the pinned
|
|
39
|
+
development dependency and run all three layers:
|
|
40
|
+
|
|
41
|
+
```sh
|
|
42
|
+
npm ci
|
|
43
|
+
npm run test:n0-census-self
|
|
44
|
+
npm run test:n0-census
|
|
45
|
+
node providers/codex/test/n0-guard-mutation-runner.mjs
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
The mutation runner copies the harness to an isolated temporary tree, recomputes its aggregate,
|
|
49
|
+
asserts the 27/27 baseline before and after, and requires every pristine counterexample to reject
|
|
50
|
+
with its exact code while only its isolated fail-open mutant accepts. It also verifies that the
|
|
51
|
+
origin HEAD, index, and worktree remain unchanged. Partial census runs are authoring diagnostics,
|
|
52
|
+
never an acceptance gate.
|
|
53
|
+
|
|
54
|
+
The suite includes every mutation floor in protocol section 7, isolated counterexamples for every
|
|
55
|
+
oracle guard binding, and Assay round-5 hostile fence and run-nonce user-span controls. Passing this
|
|
56
|
+
local suite is author evidence only. The exact unchanged harness commit and manifest digest still
|
|
57
|
+
require two consecutive zero-finding Assay reviews before any attended marker or Scheduled action.
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { evaluateOracle } from "./oracle.mjs";
|
|
4
|
+
import { parseJsonBuffer, readOwnedRegularFile } from "./lib.mjs";
|
|
5
|
+
import { snapshotTree } from "./snapshot.mjs";
|
|
6
|
+
|
|
7
|
+
function usage() {
|
|
8
|
+
process.stderr.write("N0_TEST_ORACLE — non-installable, read-only\nusage: cli.mjs snapshot --root DIR | oracle --root DIR --specimen FILE --evidence FILE [--now-ms N]\n");
|
|
9
|
+
process.exitCode = 64;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
function args(argv) {
|
|
13
|
+
const [command, ...rest] = argv;
|
|
14
|
+
const options = {};
|
|
15
|
+
for (let index = 0; index < rest.length; index += 2) {
|
|
16
|
+
const key = rest[index];
|
|
17
|
+
const value = rest[index + 1];
|
|
18
|
+
if (!key?.startsWith("--") || value === undefined) {
|
|
19
|
+
usage();
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
options[key.slice(2)] = value;
|
|
23
|
+
}
|
|
24
|
+
return { command, options };
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function main(argv) {
|
|
28
|
+
const parsed = args(argv);
|
|
29
|
+
if (!parsed) return;
|
|
30
|
+
const { command, options } = parsed;
|
|
31
|
+
if (!options.root || !path.isAbsolute(options.root)) {
|
|
32
|
+
usage();
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
if (command === "snapshot") {
|
|
36
|
+
process.stdout.write(`${JSON.stringify(snapshotTree(options.root))}\n`);
|
|
37
|
+
} else if (command === "oracle") {
|
|
38
|
+
if (!options.specimen || !options.evidence) {
|
|
39
|
+
usage();
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
const specimen = parseJsonBuffer(readOwnedRegularFile(options.root, options.specimen).data);
|
|
43
|
+
const evidence = parseJsonBuffer(readOwnedRegularFile(options.root, options.evidence).data);
|
|
44
|
+
const nowMs = options["now-ms"] === undefined ? Date.now() : Number(options["now-ms"]);
|
|
45
|
+
const result = evaluateOracle(specimen, evidence, nowMs);
|
|
46
|
+
process.stdout.write(`${JSON.stringify(result)}\n`);
|
|
47
|
+
if (result.status !== "N0_TEST_CAPABLE") process.exitCode = 1;
|
|
48
|
+
} else {
|
|
49
|
+
usage();
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
try {
|
|
54
|
+
main(process.argv.slice(2));
|
|
55
|
+
} catch (error) {
|
|
56
|
+
process.stderr.write(`${error?.code ?? "N0_CLI_ERROR"}: ${error?.message ?? String(error)}\n`);
|
|
57
|
+
process.exitCode = 1;
|
|
58
|
+
}
|