Rocko-authored, Filbert-reviewed inspector (r6 manifest a4a44930...) with full review/build/verdict evidence under docs/plans/reviews. 43/0 selftests, oracle zero-disagreement, foundation checker PASS. Owner A9 acceptance recorded separately.
306 lines
22 KiB
Markdown
306 lines
22 KiB
Markdown
# Foundation inspector — rocko build report r2 (FI-ROCKO-4 dispositions)
|
||
|
||
Author: rocko (Claude Fable 5.1). Coordinator: darkwing. Task: FI-ROCKO-4.
|
||
Written 2026-09-06 18:35 UTC. Supersedes nothing: the original report
|
||
`docs/plans/reviews/2026-09-06_foundation-inspector-rocko-build.md` is preserved
|
||
unedited (sha256 `857470d97af6aeae4e7d7942c2a1d8455bfcda74ff68b8e1dc4ba8d066521fa4`,
|
||
unchanged since delivery); this revision records the admission findings, what
|
||
changed, and the new frozen candidate.
|
||
|
||
Inputs bound to this revision:
|
||
|
||
| Input | sha256 |
|
||
|---|---|
|
||
| Admission findings `2026-09-06_foundation-inspector-build-admission-findings.md` (as received, 18:04Z) | `59233c6126c2355df5a367f0e61df7798e6cccfaa682454992fcd0d0df39c82c` |
|
||
| Same file now (darkwing's "Transport (2026-09-06 18:17 UTC)" footnote appended; no other change) | `8d9f7aab3b3bdf79345a07ba3595b966982b7667714ac7e3f669d65e328ca3d5` |
|
||
| Charter candidate 3 `docs/plans/2026-09-06_foundation-inspector-charter.md` | `19b6721128a627a2032ffdb95ece2d50abe69a8f6d521e9eff8bbdaff22798b6` |
|
||
| `records.schema.json` / `check.py` / `records.fixtures.json` | `05774aaf…72af6` / `82564a7d…4607` / `d433d06d…da85` (full values re-verified by the oracle gate 1 and listed in the manifest) |
|
||
| Build request `2026-09-06_foundation-inspector-rocko-build-request.md` (now, transport footnote included) | `90a1f329e859152d4ce8e157cbd6c56e6bcced16b4ed757822d2309514fa9a15` |
|
||
| Integration HEAD (unchanged, nothing staged) | `9a5fbdbda74b16adf488fe28138b2ba69ea5e669` |
|
||
| Machine-generated manifest `2026-09-06_foundation-inspector-rocko-build-manifest-r2.json` | `2e8b5f1998a3be6cc7fcc3fba308724d2a29ca166c08f005e1bca88ddbc14196` |
|
||
|
||
Toolchain measured: Node v26.8.1, CPython 3.12.8, jsonschema 4.26.0, Linux
|
||
7.2.2-1-cachyos x86_64, glibc 2.44 (`strftime("%Y")` for year 999 → `999`).
|
||
|
||
## 1. Per-finding dispositions
|
||
|
||
### C1 — demo hash mismatch: transcription error, no drift
|
||
|
||
Disposition: **typo in the original report, not evidence drift.** Corrected;
|
||
no evidence was regenerated to make anything match.
|
||
|
||
- Advertised (report line 96): `…548fc023…`; measured then and now:
|
||
`f1c6bd523cdff161e51da156fd00cfaa652d193f41541686548cf023378fd8ab`.
|
||
The only difference is the transposition `fc`→`cf` at positions 51–52; the
|
||
other 62 hex characters are identical.
|
||
- Evidence the file never changed: my scratch hash listing taken at 18:03:52 UTC
|
||
(before the report was written) already contains the measured value for
|
||
`demo/prop-message-is-not-authority.json`; the file's mtime is 17:52:58 UTC,
|
||
earlier than that listing; the demo copy is byte-identical to
|
||
`bundles/prop-message-is-not-authority.json` (same hash, 49,975 bytes; asserted
|
||
by `fixtures.test.mjs` "demo copy drifted"); and both aggregate manifests
|
||
reproduce the original report's values with the original method:
|
||
bundles 185 files 9,235,245 bytes `a804e4ab253839ba2bb8ad7475d27512b2ef88e70a9779f9093fee5478de4823`,
|
||
raw 19 files 1,336,985 bytes `508ad85208f4b69676f3d041faa4ff4cd4a2f8de74b7bde9b0b89123a8485cc4`.
|
||
- Root cause: the original §3 tables were hand-transcribed. The r2 manifest is
|
||
written by a script (`manifest-r2.json`: path, mode, size, sha256 for all 239
|
||
candidate files, aggregates, HEAD, toolchain, pinned inputs). No hash in this
|
||
report or in the manifest is typed by hand except where a value is quoted from
|
||
the original report to show the error.
|
||
|
||
### C2 — oracle divergences were waived: waiver removed, one class remains as a spec blocker
|
||
|
||
Disposition: **fixed for the calendar class; precise blocker for the pattern
|
||
class.** The oracle no longer has a `KNOWN_DIVERGENCES` list; every
|
||
schema-column disagreement is a problem and the oracle FAILS.
|
||
|
||
Calendar class (2 cases, fixed): the pinned checker refuses years 0001–0999 on
|
||
this platform because `strftime("%Y")` is unpadded below 1000, so its
|
||
strptime/strftime round-trip fails. The inspector now refuses them identically
|
||
(`isValidTime`: year < 1000 refused; charter §8 "calendar semantics from the
|
||
pinned checker"). Witness:
|
||
`python3 -c 'from datetime import datetime; print(datetime(999,1,1).strftime("%Y"))'` → `999`.
|
||
The oracle asserts this witness as gate 3 before comparing and fails with an
|
||
explicit "platform boundary" message on a platform that pads. Cases
|
||
`calendar-year-0001`, `calendar-year-0999`, `calendar-year-0100` now agree
|
||
(both refuse). `resolve.test.mjs` adds the three boundary vectors.
|
||
|
||
Pattern class (4 cases, blocker, unchanged verdicts): the pinned checker
|
||
evaluates `pattern` through Python `re.search`, whose `$` also matches
|
||
immediately before a trailing `\n`; ECMAScript `$` does not. Consequently the
|
||
pinned checker ACCEPTS `id`, `scope.projectId`, `authorizationRef` (runtimeId
|
||
pattern) and `policyRef.digest` values that carry a trailing newline, and the
|
||
inspector REFUSES them (`shape-pattern-mismatch`). Witnesses:
|
||
|
||
```
|
||
python3 -c 'import re; print(bool(re.search(r"^[a-z0-9][a-z0-9._-]{0,63}$", "abc\n")))' # True
|
||
node -e 'console.log(/^[a-z0-9][a-z0-9._-]{0,63}$/.test("abc\n"))' # false
|
||
```
|
||
|
||
Current oracle output (verbatim, exit 1):
|
||
|
||
```
|
||
platform witness: strftime('%Y') for year 999 -> '999' (pinned checker refuses years 0001..0999)
|
||
node v26.8.1; corpus 1432 records (38 pinned fixtures, 410 unique bundle records, 984 typeCase/mutation/lexical cases)
|
||
schema column: agree-valid 476, agree-invalid 915, DISAGREEMENTS 4; strict-only (parser-bound) cases: 27; unsupported-kind records not schema-assessed by the inspector: 10
|
||
profile column (schema-valid records only): profile-valid 476, profile-invalid 0
|
||
problem: DISAGREEMENT pattern-authorization-ref-trailing-newline: pinned-checker schema True / inspector schema False (inspector profile False, rule shape-pattern-mismatch)
|
||
problem: DISAGREEMENT pattern-digest-trailing-newline: pinned-checker schema True / inspector schema False (inspector profile False, rule shape-pattern-mismatch)
|
||
problem: DISAGREEMENT pattern-id-trailing-newline: pinned-checker schema True / inspector schema False (inspector profile False, rule shape-pattern-mismatch)
|
||
problem: DISAGREEMENT pattern-scope-project-id-trailing-newline: pinned-checker schema True / inspector schema False (inspector profile False, rule shape-pattern-mismatch)
|
||
FAIL: 4 differential problems
|
||
```
|
||
|
||
Why I did not resolve it myself: the findings forbid implementing a waiver or
|
||
changing the pinned schema/checker, and the charter forbids weakening safe
|
||
input handling. Making the inspector accept an identifier with an embedded
|
||
newline would relax input handling merely to turn the count green (the newline
|
||
would then be carried into `selection.projectId` and the text rendering, and a
|
||
`scope.projectId` of `p1\n` would be a distinct identity from `p1` that renders
|
||
almost identically). The schema-column comparison is therefore left honestly
|
||
red, and the suite reports `selftest: 36 passed, 1 failed` until this is ruled.
|
||
|
||
Proposed amendment (for darkwing/Jason; I implement nothing until ruled):
|
||
|
||
- (a) **Recommended.** Add to charter §8 (or the incorporated notes) a
|
||
"checker-dialect artifact" clause: "The pinned checker's `pattern` semantics
|
||
are Python `re.search`; its `$` accepts one trailing newline. This is a
|
||
dialect artifact, not an intended grammar. The inspector applies the pattern
|
||
with anchored (ECMAScript) semantics and refuses a trailing newline. The
|
||
differential oracle records the cases in this class by name, with the two
|
||
witnesses above, and reports them as an expected artifact-class difference
|
||
separately from agreement counts; any other disagreement fails." Under (a) the
|
||
oracle would carry a named, witnessed artifact class with exact direction
|
||
(pinned True / inspector False) and fail on any other direction or any other
|
||
case. This is the amendment I would implement; it needs a coordinator ruling
|
||
because it is a policy choice about which side is authoritative.
|
||
- (b) Against: relax the inspector to Python semantics. Rejected for the input
|
||
handling reason above and because §8 keeps "record-schema verdict distinct
|
||
from … refusal"; the inspector would have to accept an identifier the runtime
|
||
would never mint.
|
||
- (c) Against: drop the four mutations from the corpus. Rejected: it hides a
|
||
real, reproducible difference between the two implementations.
|
||
|
||
Until ruled, the candidate's differential gate is **red by design**, and this
|
||
report does not claim oracle PASS.
|
||
|
||
### C3 — `exit` outside the closed §7 fields: removed from the serialized result
|
||
|
||
Disposition: **fixed; no charter amendment needed.** Exit status is process
|
||
metadata derived from the emitted result (`exitFor(result)`), never a field
|
||
of it and never a text line.
|
||
|
||
- `resolve.mjs`: `RESULT_KEYS` is exactly the 12 charter §7 names in charter
|
||
order; `buildResult` builds no `exit` member and throws if the requested exit
|
||
is inconsistent with the derived result/reason; new export `exitFor(result)`
|
||
(allowed→0; refused/unresolved→3; invalid+io-failure→4; other invalid→2).
|
||
`evaluate()` returns `{ result, exit, detail }` with `exit` outside `result`.
|
||
- `foundation-inspect.mjs`: `renderText` ends with the `diagnostic:` line (no
|
||
`exit:` line); `run()` returns `{ json, result, exit }`; `main()` writes the
|
||
rendering and sets `process.exitCode = exit`.
|
||
- Tests whose expected keys come from the approved contract, not from the
|
||
implementation: `resolve.test.mjs` "closed result fields equal the pinned
|
||
charter §7 list" reads the charter file, asserts its sha256 is
|
||
`19b67211…798b6`, parses the twelve `- name:` bullets under "Closed result
|
||
fields, emitted on every outcome:", and asserts they equal both an
|
||
independent literal copy in the test and the implementation's `RESULT_KEYS`;
|
||
it also asserts `exit` is absent, checks `exitFor` on all four classes, and
|
||
that `buildResult` throws for four exit/reason inconsistencies.
|
||
`cli.test.mjs` and `fixtures.test.mjs` assert `!("exit" in parsed)` for every
|
||
spawned run and derive the expected process status from the parsed result;
|
||
text renderings are asserted to end with the diagnostic line and to contain
|
||
no `exit` line for all 204 cases. `test-foundation.sh` asserts the `--json`
|
||
key list equals the twelve names literally.
|
||
- Consequence: **the ten demo goldens (`*.expected.txt`, `*.expected.json`) were
|
||
regenerated** with the README loop because the contract fix removed one line
|
||
/ one member from each; the five `*.expected.exit` files are byte-identical
|
||
to before (hashes `9a271f2a…86aa` for 0 and `1121cfcc…02a2` for 3, as in the
|
||
original table). `index.json` is unchanged (its `expect.exit` was always the
|
||
process status). Demo tree total bytes 249,096 → 248,991 (−105 = 5 × (8-byte
|
||
text line + 13-byte JSON member)).
|
||
|
||
### C4 — demo step 2 could not show unchanged bytes: corrected
|
||
|
||
Disposition: **fixed.** The BEFORE manifest is saved in a separate scratch
|
||
location first, the preview runs, then `sha256sum -c` verifies against that
|
||
SAME manifest (plus an inventory of path/type/size/mode/inode/mtime and a file
|
||
count). Corrected commands are in §4; the receipt from running them is in §3.
|
||
|
||
### C5 — report omitted O_NONBLOCK: prose corrected, flag kept
|
||
|
||
Disposition: **fixed in prose only; no code change.** The CLI opens the input
|
||
with `O_RDONLY | O_NOFOLLOW | O_NONBLOCK` (`REQUIRED_FLAGS` = those three
|
||
names) and refuses with `open-flags-unavailable` (exit 4) if any is not a
|
||
number on the platform. O_CLOEXEC is not used (charter §6). The original
|
||
report's lines 142 and 270 said `O_RDONLY|O_NOFOLLOW` only; that text was wrong
|
||
and is superseded by this paragraph. The FIFO test (`cli.test.mjs` "FIFO must be
|
||
refused after O_NONBLOCK open, not read") exercises the flag.
|
||
|
||
## 2. Changed files (old → new sha256; everything else byte-identical)
|
||
|
||
All under the FI-ROCKO-3 allowlist plus the two paths offered in the findings.
|
||
Nothing else in the working tree was touched; `git status` shows the same
|
||
pre-existing modified/untracked entries as before plus the two r2 documents.
|
||
|
||
| File | Lines | Original report sha256 | r2 sha256 |
|
||
|---|---|---|---|
|
||
| `scripts/foundation-inspect.mjs` | 239→244 | `bfa1b78007c772c54fe1dab90a53e19e6bce7e4888a5adb2de0b2cfe43c5cddd` | `dad369490ca8396d3b4a7bd4a1b7fa87b677a2b8cf991bf61672d446e5aa3c93` |
|
||
| `scripts/foundation/resolve.mjs` | 1625→1646 | `9ae8b4255b5dc1f1e9b0d36549865268c12dc53f010984eb1e5616b127d1d8a2` | `aa842898ebb0bb2a911406314c4c3a2c4079b46bfd674c4ffba0176a1e32766c` |
|
||
| `scripts/foundation/verify-schema.py` | 453→467 | `7e3098655b2e5f261391d788c2112a6ffb055895e357b427bc68e5f2fa7b52d7` | `b61031b6c2cea126133afda70894e7f2429b08bf2cd50fc766ec6b99f348c966` |
|
||
| `scripts/foundation/resolve.test.mjs` | 294→333 | `05f27aa6c8a1b8ff2ee45e5de03a9aea5ed13cf011b2464c5865022dc9781449` | `6bb6d40fa6ec90fb52db658f77ca9fd27cc3eb8673f040f52fc126e67983a571` |
|
||
| `scripts/foundation/cli.test.mjs` | 279→281 | `b7e9a13c11e3e6f487ada2779c892cdf848526de1ef8b21387d15d4a461ddb62` | `ccec06c266e03d878c1ecd9e8c20ee3f1fb82f478daead25efa4661b7090d83f` |
|
||
| `scripts/foundation/fixtures.test.mjs` | 93→98 | `2827de36214c8014471fed3478c42bf48eddb3fbdbff82cac9e27851646b15d2` | `94e7508717efcafd11585a288a5d791e1e48a993794e2d470c6097f904befdb3` |
|
||
| `scripts/test-foundation.sh` | 132 | `76fb7ba9da4345271b6ba93228a9da69c7e55c4e44b9f4033e84a8f4b430e8ec` | `fdfa13ce247bc9ad8f3617e248913aef384029198924685ada3431006ffdf114` |
|
||
| `fixtures/demo/demo-read-w1.expected.txt` | | `8bfff519ce8275cfe59562efd04647c242c328a09b301b91d70491f030cf1600` | `8ba4bbe92819ac8912c72e7c635730e99eac7916c0d924fc81b75115b5939b53` |
|
||
| `fixtures/demo/demo-read-w1.expected.json` | | `55e10c1693787cd8e39d3a66841d30e2336080d2ae4450a806a7ae8373db476b` | `42055bda71075ba5c710f011f83d470228f18097d93ac5585ba1b534cba0ef2a` |
|
||
| `fixtures/demo/demo-file-change-src.expected.txt` | | `f5387217ca0a41d437468af33b7d87d06c0c5535ab5490b568f9866a13b2732e` | `2cdd6d4e162fa904b03e8f8a88553a03065ac7fb646baabf21625d4f5962a79b` |
|
||
| `fixtures/demo/demo-file-change-src.expected.json` | | `88c7793c6af17ca255525451a499d9f8bb165155e50d2ee936bd68ba82a876a7` | `7ea412916404ec948c94e929cc7b2ce120b394944c66c7bfcc811d0721dd82db` |
|
||
| `fixtures/demo/demo-change-w1.expected.txt` | | `2a1090e5f5ad08e2175830943a7c81928de970470893e803b1e440843152c348` | `0e2807ab56d15670c51c8ad4a43f33b36c5672799937561f39e20c6e93be1dda` |
|
||
| `fixtures/demo/demo-change-w1.expected.json` | | `36c287cba327070f7ff3dd9846421bee3ebd0dd52e9c602b68e84fa620ef4fc5` | `ecf8313993ca27450d1753c6178be1a063fb0637f14be8f091de923b8b722516` |
|
||
| `fixtures/demo/adm-registration-revoked.expected.txt` | | `624c9e5991597d59fc3379343b16e7eab9cb6434f054da3a4df7518742e3b36c` | `c2fd118d44d21cbd709d30a2c2be2603740a81e628aa9d32f95d6eaf06d3a9a6` |
|
||
| `fixtures/demo/adm-registration-revoked.expected.json` | | `b966d939e0d2851ef731462a0fda932e75f53b9aac406216ad440f781e036d0f` | `c44b0935ed329c1a381f986997b1bc4be702fc4229166d8a0b49e4e80f9b2fa8` |
|
||
| `fixtures/demo/prop-message-is-not-authority.expected.txt` | | `e7b0e9fa64abe0c0f8c91fbc9aa565988ce76cb3967672bfacafab350e20d8be` | `388983ad6e4e31db6f5a688773ff2bf07d44d7ffe530eb7870e729a0f546278d` |
|
||
| `fixtures/demo/prop-message-is-not-authority.expected.json` | | `53884bfdea21185141b9a06d52aa1c0fe8e7bfae6627b465929403521f9bc4d8` | `742e479ddbb4cf2138d49ec0ac40cd038b6c20f8b9c0e2daffc5a859db9f4145` |
|
||
| `fixtures/demo/prop-message-is-not-authority.json` | | (report typo `…548fc023…`) | `f1c6bd523cdff161e51da156fd00cfaa652d193f41541686548cf023378fd8ab` (file unchanged) |
|
||
|
||
Unchanged (same hash as the original table): `strict-json.mjs`, `canonical.mjs`,
|
||
`validate-record.mjs`, `strict-json.test.mjs`, `canonical.test.mjs`,
|
||
`build-fixtures.mjs`, `index.json`, `fixtures/README.md`, all five
|
||
`*.expected.exit`, all five demo `*.json` bundles, all 185 bundles and 19 raw
|
||
fixtures (aggregates above). Full per-file listing with modes: `manifest-r2.json`.
|
||
|
||
Aggregates (r2 manifest method: sha256 of the LC_ALL=C sorted `sha256sum`
|
||
listing with repo-relative paths): `scripts/foundation/fixtures/` 227 files
|
||
`36d99b91065ed7af03f17b7b9cc309b3f7805ca5e3a337ddb5f3536f2ccaa563`;
|
||
`scripts/foundation/` 237 files `6c111ad1165e0da219d566f919e25005af47fa004257a11e7e2750a4010b9ecb`;
|
||
all 239 candidate files `e0fe89d9cc5245031ce484e9e0fe15b93319dd2cdf040800c52555a26fb1c1a6`.
|
||
Original-method demo aggregate (run in `scripts/foundation/fixtures/`,
|
||
`sha256sum demo/* | sha256sum`): `7000fdd9b2a5e92256429e148240541fab3f93d2ef009e47b08baddcbcef5216`.
|
||
|
||
Source changes in words: `resolve.mjs` (isValidTime year ≥ 1000; `exitFor`;
|
||
`RESULT_KEYS` without exit; `buildResult` consistency guard; `evaluate` returns
|
||
exit beside result). `foundation-inspect.mjs` (no exit line; `withExit`; exit via
|
||
`process.exitCode` only). `verify-schema.py` (waiver list and waiver comparison
|
||
deleted; gate 3 platform witness; trailing-newline cases renamed
|
||
`pattern-*-trailing-newline` and kept; calendar boundary cases; separate
|
||
schema/profile column summary; every disagreement is a problem).
|
||
`test-foundation.sh` (JSON key-list assertion; oracle summary grep lines).
|
||
Tests as described under C3 and C2. No new dependency, no new file outside the
|
||
allowlist, no `__pycache__` (verified absent after all runs).
|
||
|
||
## 3. Receipts (all run 2026-09-06 18:2x–18:30 UTC at HEAD 9a5fbdbd)
|
||
|
||
| Check | Result |
|
||
|---|---|
|
||
| `node --check` on all 10 `.mjs` files; `ast.parse` on `verify-schema.py` | OK |
|
||
| `node --test scripts/foundation/` | 58 tests, 58 pass, 0 fail (was 57; +1 charter-derived field test) |
|
||
| `python3 scripts/foundation/verify-schema.py` | **FAIL, exit 1: exactly the 4 `pattern-*-trailing-newline` disagreements** (output quoted under C2); gates 1–3 PASS; 38 pinned fixtures agree |
|
||
| `NO_COLOR=1 scripts/test-foundation.sh` | **`selftest: 36 passed, 1 failed`**; the one failure is the oracle gate above; all other checks OK (syntax, fixture regeneration equality, node tests, demo exits 0/0/3/3/3, usage 2, I/O 4 ×3, oversize 2, disclaimer, JSON key list, golden byte-match, sandboxed inventory unchanged, canaries never printed) |
|
||
| `python3 docs/plans/foundation-v1-candidate/check.py` | exit 0 |
|
||
| `scripts/test-config.sh` / `test-task.sh` / `test-release.sh` / `test-conductor.sh` / `test-auth.sh` | 24/0, 90/0, 14/0, 17/0, 15/0 passed/failed |
|
||
| `git rev-parse HEAD`; `git status` | `9a5fbdbd…`; nothing staged; only the pre-existing entries plus the two r2 documents |
|
||
| `scripts/foundation/__pycache__`, `docs/plans/foundation-v1-candidate/__pycache__` | absent |
|
||
|
||
Owner-demo receipt (corrected C4 procedure, verbatim outcome lines):
|
||
|
||
```
|
||
step 1 demo-read-w1.json → result: allowed … operation: work.read target null rc=0
|
||
step 2 before manifest: 227 files, sha256 cf2eed27c5e5b311d40e5346af89fbc5fdc7781488bf8ea9d663e66e7dd50d59
|
||
demo-file-change-src.json → result: allowed … operation: file.change target workspace:src/main.mjs rc=0
|
||
sha256sum -c against saved BEFORE manifest: all 227 OK
|
||
inventory (path/type/size/mode/inode/mtime) unchanged
|
||
file count unchanged: no file added
|
||
step 3 adm-workspace-registration-missing.json → refused / not-authorized / workspace-registration-missing, assignment null rc=3
|
||
step 4 demo-change-w1.json → unresolved / unknown-effects / runtime-reconciliation-required; selection keeps asg-a-w1 rev 1 rc=3
|
||
prop-all-pass-restricted-contexts.json → unresolved / unknown-effects / runtime-reconciliation-required rc=3
|
||
extra adm-registration-revoked → refused/registration-revoked rc=3; prop-message-is-not-authority → refused/message-is-not-authority rc=3
|
||
json keys = [disclaimer, preview, bundleVersion, authentication, declarations, result, reason, rule, selection, operation, proposal, diagnostic] rc=0
|
||
```
|
||
|
||
Every text rendering begins `SYNTHETIC PREVIEW — NO LIVE EFFECTS` and ends with
|
||
the `diagnostic:` line. These are bounded evidence (finite tests, inventory
|
||
comparison), not an OS-sandbox proof; the original report's §8 qualifications
|
||
stand.
|
||
|
||
## 4. Corrected owner-demo commands (A9; replaces original §9 step 2)
|
||
|
||
```sh
|
||
# 1. selected agent/project/workspace with a permitted read preview (exit 0)
|
||
node scripts/foundation-inspect.mjs scripts/foundation/fixtures/demo/demo-read-w1.json
|
||
|
||
# 2. assigned file.change preview (exit 0); prove no fixture file changed:
|
||
# save the BEFORE manifest elsewhere first, run, then verify against that SAME manifest
|
||
BEFORE="$(mktemp)"
|
||
( cd scripts/foundation/fixtures && find . -type f | LC_ALL=C sort | xargs sha256sum ) > "$BEFORE"
|
||
node scripts/foundation-inspect.mjs scripts/foundation/fixtures/demo/demo-file-change-src.json
|
||
( cd scripts/foundation/fixtures && sha256sum -c --quiet "$BEFORE" ) && echo "all $(wc -l < "$BEFORE") files unchanged"
|
||
[ "$(cd scripts/foundation/fixtures && find . -type f | wc -l)" = "$(wc -l < "$BEFORE")" ] && echo "no file added"
|
||
|
||
# 3. unregistered workspace selected: refusal without fallback (exit 3, assignment null)
|
||
node scripts/foundation-inspect.mjs scripts/foundation/fixtures/bundles/adm-workspace-registration-missing.json
|
||
|
||
# 4. cross-lane reassignment preview: original assignment stays selected; even fully
|
||
# supplied mock declarations cannot yield allowed (exit 3, unresolved)
|
||
node scripts/foundation-inspect.mjs scripts/foundation/fixtures/demo/demo-change-w1.json
|
||
node scripts/foundation-inspect.mjs scripts/foundation/fixtures/bundles/prop-all-pass-restricted-contexts.json
|
||
|
||
# machine-readable form; process exit status is the only exit signal
|
||
node scripts/foundation-inspect.mjs --json scripts/foundation/fixtures/demo/demo-read-w1.json; echo "exit $?"
|
||
```
|
||
|
||
Step 5 (Jason's answer on clarity and acceptance) is darkwing's to record; this
|
||
report claims no acceptance.
|
||
|
||
## 5. Open item and freeze
|
||
|
||
Open: the C2 pattern-class ruling (§1 C2, options a/b/c). Until ruled the
|
||
oracle and therefore `test-foundation.sh` are red on exactly those four named
|
||
cases; I have not weakened, waived or removed them.
|
||
|
||
Frozen at the r2 manifest (`manifest-r2.json`, sha256 `2e8b5f19…4196`; 239
|
||
files) for independent review. Rocko changes nothing under the allowlist until
|
||
darkwing returns a ruling or reconciled findings. No staging, commit,
|
||
checkout/reset, push, charter/schema/verdict/coordinator-record edit, live or
|
||
native/sync work, credential or `~/.mosaic` read, network access or engine
|
||
launch occurred. C1 (Archify rev 3) remains HELD; no lane action taken.
|