Record reviewed prerequisite correction and separate next approval gate (#1500)
This commit is contained in:
@@ -0,0 +1,11 @@
|
||||
# #1500 prerequisite correction delivered
|
||||
|
||||
Source commit 6335342873985538da3e7dc80cf9e9505e758832 on refactor. Independent APPROVED M20-CORRECTION-FILBERT-1 at manifest af97b5be51760f9075e6df859fee8cedf068fbb6b8464f208b48c129f1f99991. Coordinator verified all fourteen snapshot/live hashes, staged exactly twelve changed files with no unrelated paths, then verified the committed bytes against the same snapshot. Two contextual files remained unchanged.
|
||||
|
||||
Fresh git-archive committed-tree execution of package and Pi/Rocko launcher suites: 48 tests, 48 pass, zero fail, exit 0; /tmp/m20-correction-committed.log. Reviewer independently passed package 43/43 and launcher 5/5, re-attacked D1-D10 plus additional FIFO/directory/credential-sibling cases. Initial failing diagnostic-order test remains disclosed, not erased.
|
||||
|
||||
Push succeeded. Fresh git ls-remote origin refs/heads/refactor returned 6335342873985538da3e7dc80cf9e9505e758832. No live credentials, materialization, refresh, timers, Docker, services or deployment performed. Other work remains excluded.
|
||||
|
||||
Limits retained: Linux/procfs only; wrong-owner and non-Linux refusals are source-reviewed, not independently exercised on other users/platforms. Rename-race defense is source-reviewed, not race-tested. Hardlink provenance and transactional multi-record consistency are not provided. Error reporting now fails on the first error. No broad security certification inferred.
|
||||
|
||||
The authorized corrective slice is complete. #1500 remains open for the separately gated materialization/refresh charter; completing prerequisite repair does not authorize that implementation. No new technical acceptance burden is assigned to Jason merely because the repair tests are green.
|
||||
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"baseline": "b3fa221060abb820cd809f15c3a54ba84518b7a1",
|
||||
"snapshot": "/tmp/m20-correction-review-5ffad9u7",
|
||||
"manifestSha256": "af97b5be51760f9075e6df859fee8cedf068fbb6b8464f208b48c129f1f99991",
|
||||
"files": [
|
||||
"packages/mosaic/README.md",
|
||||
"packages/mosaic/package.json",
|
||||
"packages/mosaic/src/cli/main.mjs",
|
||||
"packages/mosaic/src/index.mjs",
|
||||
"packages/mosaic/src/records.mjs",
|
||||
"packages/mosaic/src/registry.mjs",
|
||||
"packages/mosaic/tests/fixtures/valid/auth/accounts/openai-codex/homelab-openai/account.json",
|
||||
"packages/mosaic/tests/fixtures/valid/auth/providers/ollama-remote.json",
|
||||
"packages/mosaic/tests/fixtures/valid/auth/providers/openai-codex.json",
|
||||
"packages/mosaic/tests/fixtures/valid/auth/settings/research-default.json",
|
||||
"packages/mosaic/tests/fixtures/valid/harnesses/pi.json",
|
||||
"packages/mosaic/tests/registry.test.mjs",
|
||||
"packages/mosaic/tests/safety.test.mjs",
|
||||
"docs/plans/reviews/2026-09-10_m20-i2-correction-progress.md"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
# M20-CORRECTION-FILBERT-1 (#1500) — corrective-slice verdict
|
||||
|
||||
Reviewer: Filbert. Role disclosure: I was the I1 reviewer and the reviewer who reproduced D1–D10; this verdict relies on fresh evidence against the corrected code, not inherited approval. Frozen snapshot `/tmp/m20-correction-review-5ffad9u7` at manifest SHA-256 `af97b5be51760f9075e6df859fee8cedf068fbb6b8464f208b48c129f1f99991` (14 files verified before and after; snapshot unchanged). Baseline `b3fa2210…`; the two contextual files (`packages/mosaic/package.json`, `src/index.mjs`) are byte-identical to the baseline, so exactly 12 files carry the correction. All work in a disposable baseline-plus-overlay tree; no live commands, Docker, secrets, or shared-log edits.
|
||||
|
||||
## Verdict: APPROVED for the exact corrective slice
|
||||
|
||||
## Tested observations
|
||||
|
||||
- **Suites:** 43/43 package tests (loop-expanded safety suite plus schema suite) and 5/5 combined launcher fixtures in my overlay tree — matching the coordinator's 43 and 48/48. The 30 source-level `test(` occurrences expand to 43 at runtime via the parameterized D1/D2/private-mode loops.
|
||||
- **D1–D10 independently reproduced as fixed.** Beyond the author's suite, I reran my own charter-review attacks against the corrected code: missing root → `missing-path`; the matching-id symlinked provider that previously returned `valid` exit 0 → `symlink-forbidden`; `https://user:secret@…` → `url-credentials-forbidden` with path+code only; malformed JSON → fixed `invalid-json` code with zero marker echo; the restored fixture returns `valid`.
|
||||
- **Extra hostile controls (mine, beyond the suite):** FIFO as a provider file → `not-a-regular-file` with no hang; a stray file where an account directory is expected → `not-a-directory`; an unreadable mode-000 regular `credential.json` sibling leaves validation green and list clean (never opened); a chmod-000 directory inside the root refuses; usage errors still exit 2.
|
||||
- **FD-anchored containment, as reviewed in source:** Linux/procfs gate first (explicit `unsupported-platform` refusal, no silent fallback); `..` in the root string rejected; the root path walked from `/` through per-component `directory()` opens with `O_DIRECTORY|O_NOFOLLOW`; lstat-then-open with inode/device recheck (`path-changed`); `jsonFile` rechecks inode/device/mode after `O_NOFOLLOW|O_NONBLOCK` open, caps reads at 1 MiB with a bounded buffer loop, and discards the parser message entirely. Directory FDs anchor child traversal. Errors map to distinct codes (`missing-path`, `inaccessible-path`, `not-a-directory`, `symlink-forbidden`), and `loadRegistry` returns empty entries on any refusal — the CLI checks errors before printing, so no partial list output.
|
||||
- **Private-mode contract:** every traversed directory 0700 and every metadata file 0600, owned by the invoking uid, enforced at both lstat and post-open fstat. The README states the contract accurately, including that public Git fixtures cannot preserve modes and the tests re-chmod temporary copies.
|
||||
- **Schema corrections verified:** numeric version exactly 1 (fuzzed with 2, `"1"`, `"banana-schema"`, null, true across all five record kinds); per-kind nested shapes with unknown-field checks for every harness entry, not only pi; URL userinfo/protocol/hash/whitespace rejection with http requiring `allowInsecureTransport`; default-account enrollment; provider credential-type membership; harness reference existence. Diagnostics carry paths and codes only — no input values, no unknown-key names, no stack spew.
|
||||
- **Disclosed 14/15 history:** consistent with the code (cross-reference validation now precedes the final emptiness check) and honestly recorded with logs; the failing control never accepted a missing registry in either version.
|
||||
|
||||
## Untested assumptions (design-verified only)
|
||||
|
||||
- Rename-race protection: the inode/device recheck and FD anchoring are statically reviewed, not race-tested. The README disclaims transactional multi-record consistency, which is the right scope.
|
||||
- Non-Linux refusal: read in source (`rootDirectory` platform gate); not executed on another platform here.
|
||||
- Wrong-owner refusal: untestable on this single-uid host.
|
||||
|
||||
## Residuals (documented, not defects)
|
||||
|
||||
- Hardlinks: a hardlink placed inside the 0700 tree with content matching its filename would validate; containment is by inode checks, not provenance. Creating one already requires write access to the tree, so it sits outside this slice's threat model. Worth a README sentence in a future touch.
|
||||
- Reporting is fail-fast (first error only) rather than the accumulated error list of increment 1; a behavior change, acceptable for a validator, noted for the record.
|
||||
|
||||
## Effect and remaining gates
|
||||
|
||||
Approval covers committing exactly the 12 changed files (14-file snapshot including the two identical contextual files) at manifest `af97b5be…`. Materialization remains blocked pending its own chartered increment and review; nothing here authorizes live activation, refresh execution, or service work. Host-wide suites with image/state effects were not rerun, per the request's constraint; the package and launcher fixtures are the applicable green evidence for this package-only change.
|
||||
@@ -0,0 +1,42 @@
|
||||
# M20-I2-CHARTER-FILBERT-1 (#1500) — charter and prerequisite verdict
|
||||
|
||||
Reviewer: Filbert. Role disclosure: I was the increment 1 independent reviewer; that approval covered the fifteen tests' assertions, not comprehensive registry safety, and this review relies on fresh reproduction only. Baseline `b3fa2210…`; frozen draft `/tmp/m20-i2-charter-review-fga9lki3` at manifest SHA-256 `78981e71521e5df2b62649fe11eda6c241029c4fe41ef5dfe06fff3776f44401` (both hashes verified). All reproduction used a disposable `git archive` tree and synthetic fixtures; no real credentials, Pi, timers, Docker, packages, source edits, or shared logs.
|
||||
|
||||
## Verdict: APPROVED (charter), with prerequisite correction confirmed as mandatory stage 1
|
||||
|
||||
The charter is well-formed and its dependency ordering is right: nothing may build on the validator until the reproduced defects are closed and independently verified. The factual findings below are separately recorded from the proposed design, per the request.
|
||||
|
||||
## Factual prerequisite findings (all reproduced on the clean baseline)
|
||||
|
||||
- **D1 — fail-open root (the coordinator's defect, independently reproduced):** a nonexistent registry root and an empty root both return `valid`, exit 0; `list` exits 0 with an empty projection. `safeList` converts every directory error into an absent directory.
|
||||
- **D2 — symlink/containment failure:** a provider file symlinked from outside the root with a matching id returns `valid` exit 0; an account directory symlinked from outside the root is followed, its records validated and listed. The loader uses `stat`/`readFile`, both of which follow symlinks; there is no containment check anywhere.
|
||||
- **D3 — version schema inconsistency:** numeric `providerVersion: 2` is rejected (`invalid-id`) while the governing plan's examples use numeric `1`; arbitrary strings such as `"banana-schema"` are accepted. Wrong in both directions.
|
||||
- **D4 — nested unknown keys pass:** unknown fields inside `harnesses.pi` (e.g. injected `secretExfil`) validate clean; harness entries are only checked to be objects.
|
||||
- **D5 — enrollment not enforced:** a profile default account absent from `allowedAccounts` validates clean.
|
||||
- **D6 — credential-type match not enforced:** an `oauth` account under a provider whose `credentialTypes` is `["api_key"]` validates clean.
|
||||
- **D7 — non-pi endpoints unvalidated:** a `custom-endpoint` provider carrying a plain-`http` baseUrl on a non-pi harness produces no insecure-transport error (I1-F3, now confirmed as a prerequisite defect rather than later hardening).
|
||||
- **D8 — URL credentials accepted:** `https://user:secret@host/v1` as a pi baseUrl returns `valid`.
|
||||
- **D9 — bounded content echo in errors:** malformed JSON surfaces V8's parse message including a truncated excerpt of the file's first bytes (`"FIXTURE-MA"...`). Bounded to a short prefix, but a credential-shaped file misnamed `.json` would leak its opening characters.
|
||||
- **D10 — partial trusted output:** `list` prints its projection even when validation errors exist (exit 1, output still emitted). Also observed in passing: a missing `account.json` inside a listed account directory reports as `invalid-json: ENOENT`, a code mislabel.
|
||||
|
||||
D1–D10 confirm every concern in the charter's prerequisite gate. None were covered by the increment 1 suite's assertions; two (D7, partially D4) were flagged in my I1 notes as hardening and now stand as blocking prerequisites.
|
||||
|
||||
## Charter assessment
|
||||
|
||||
- **Dependency ordering:** correct. Stage 1 (close verified defects, independent approval, clean-tree regression) precedes resolution, materialization, and the refresh adapter. Given D1/D2, building a materializer on this validator would generate inputs from absent or out-of-root sources while reporting success.
|
||||
- **Scope:** confined to `packages/mosaic` plus assignment records; `scripts/auth.sh`, launchers, native homes, dataRoot, services, images, releases untouched; no new dependencies without reviewed need. The stage-2 boundary against implementing #53's full runtime model is stated.
|
||||
- **No-secret guarantees:** fake-marker disclosure tests for stdout/stderr/errors, no credential hashes in manifests, token-bearing output never logged, fake-Pi refresh simulation with isolated auth location, `--credentials`/print-* exclusion. Adequate, and now demonstrably necessary (D9).
|
||||
- **Rollback:** source-level revert; tests clean synthetic temp directories; no runtime migration performed. Consistent.
|
||||
- The closing self-correction (prior `valid` responses were labeled acceptance too strongly) is accurate and appropriately does not waive anything.
|
||||
|
||||
## Recommended corrective scope (the separate narrow prerequisite increment)
|
||||
|
||||
1. Fail-closed roots: refuse missing, inaccessible, or non-directory registry roots and required subdirectories before any record processing.
|
||||
2. Containment: `lstat`-based regular-file checks and no symlink following for files or directories anywhere under the supplied root.
|
||||
3. Version fields: numeric versions per the governing plan, with unknown-version refusal; migrate fixtures accordingly in the same patch.
|
||||
4. Nested shape validation for every harness entry (unknown keys, per-kind requireds), applied to all harnesses, not only `pi`; reject URLs carrying `user:pass@` and confine `http` to `allowInsecureTransport`.
|
||||
5. Cross-record enforcement: default accounts enrolled in `allowedAccounts`; account `type` within the provider's `credentialTypes`.
|
||||
6. Bounded secret-free errors: fixed invalid-JSON code without parse-message excerpts; correct the ENOENT mislabel; `list` must not emit trusted projections on an invalid tree.
|
||||
7. Negative controls in the package suite for each item above, including fake-marker disclosure assertions.
|
||||
|
||||
This correction is small, independently reviewable, and should land before any stage-2 work. The charter already mandates exactly that ordering; approving the charter does not approve any implementation.
|
||||
Reference in New Issue
Block a user