Record reviewed prerequisite correction and separate next approval gate (#1500)

This commit is contained in:
2026-09-10 16:41:36 -05:00
parent 6335342873
commit 27e4873acc
8 changed files with 177 additions and 4 deletions
@@ -0,0 +1,48 @@
# Increment 2 charter (#1500)
Status: draft, independent review requested before owner implementation approval.
Baseline b3fa221060abb820cd809f15c3a54ba84518b7a1. Owner requested faster continuation of charter drafting. Author/coordinator Darkwing; independent reviewer Filbert; Jason approves implementation. No source changes are authorized by this document yet.
## Outcome and boundary
Prove that two executions of one agent can resolve different authorized accounts and generate isolated Pi inputs without sharing mutable files, emitting secrets, or silently switching identity. Exercise the owner-selected `pi auth check --provider <p>` refresh-driver contract with a fake executable and synthetic credentials only. No live secrets, OAuth traffic, timers, deployment, launcher integration, package upgrades or Ollama installation.
## Prerequisite gate: do not build on unverified safety
The first increment's fifteen tests establish their assertions, not comprehensive registry safety. Baseline source inspection raises these concrete checks before materialization may begin:
- loadRegistry's safeList catches every directory error and returns an empty list. Missing/inaccessible roots must not validate successfully.
- stat follows symlinks; metadata reads need path containment, regular-file and permission checks before reading. Credential paths must never be traversed by list/validate.
- Record versions currently use an ID-string validator despite numeric versions in the governing plan. Resolve schema/fixture consistency, unknown versions and nested unknown keys.
- Default account must be enrolled in allowedAccounts and match its provider's supported credential types. Validate every custom endpoint, not only its pi entry; reject URL credentials and unsafe protocols.
- Malformed input must yield bounded secret-free errors, not raw JSON parse excerpts or partially trusted list output.
Reviewer independently reproduces these with fixtures in a disposable copy. Any confirmed prerequisite defect blocks materialization. Return a separate narrowly chartered correction first if the repairs cannot fit a small, independently reviewable patch. Prior approval is not a waiver of a new demonstrated defect.
## Proposed stages after owner approval
1. Close verified prerequisite defects, obtain independent approval and clean-tree regression evidence before dependent work.
2. Pure resolution: explicit agent/project/workspace/session/execution and profile/account references. Enforce enrollment and fork account pins; unpinned relaunch uses the approved default. Missing or revoked pins refuse, never fall back. Exact field additions remain subject to review against #53; do not implement its full runtime object model.
3. Materialize synthetic credentials through an injected storage interface into a new execution-owned generation directory. Separate auth.json, models.json and non-secret manifest; no credential hashes in the manifest. Private directories/files, no symlink following, exclusive creation, validate full generation before making it visible. Failed generation leaves prior usable inputs unchanged. No shared mutable per-seat generated files.
4. Refresh adapter boundary: invoke the selected command with an explicitly isolated auth location and fixed arguments, excluding `--credentials` and print commands. Fake Pi simulates expired/valid credentials, rotated refresh tokens, errors and timeout. Token-bearing output must never reach logs; failures refuse and are recorded without secrets. Provider-specific refresh behavior and arbitrary code/extension loading must not be assumed safe from CLI command naming alone.
5. Independently review exact candidate, run applicable suites in an isolated committed-tree copy, selectively publish only after approval and green applicable checks. Present fixture-only demonstration to Jason before increment 3.
## Allowed implementation paths, only if approved
packages/mosaic/src/, packages/mosaic/tests/, packages/mosaic/package.json, package documentation and this assignment's task/review records. Do not silently broaden schema or dependency authority. No new dependency or root config edit without a reviewed need. Existing scripts/auth.sh, launcher scripts, native homes, dataRoot, services, images and releases remain unchanged.
## Acceptance and negative controls
- Missing/inaccessible/symlinked registry roots, metadata files and traversal attempts refuse before external reads; capture fake-marker disclosure tests for stdout/stderr/errors.
- Unsupported numeric versions, nested unknown fields, malformed/null records, cross-provider references, unenrolled defaults and credential-type mismatches refuse.
- Concurrent execution fixtures use distinct immutable generations; a fork cannot adopt a different account; no cross-execution file replacement.
- Generation failure, credential rotation, lock contention, timeout and interrupted output preserve prior good inputs or report uncertainty without blind retry.
- No network or real credentials in tests. Verify fake refresh command arguments, isolated auth location, environment allowlist and no inherited native extensions/config. If the supported Pi isolation boundary cannot be proven, stop rather than use the default auth home.
- Applicable package/config/auth/task/release/conductor/foundation/launcher suites green from clean candidate copies. Prior task-suite headless failure requires environment/root-cause reconciliation, not a permanent baseline waiver. Never stash unrelated work to create a test baseline.
- A build or release performed internally by a suite still counts as an effect; inspect tests first and use isolated state and explicit authorization rather than assuming a test name grants permission.
## Rollback and completion
Source revert restores the previous implementation; synthetic temporary directories are cleaned by tests. No runtime migration or live rollback is needed because none is performed. A production secret backend, refresh service and deployment require later explicit charters.
This draft does not certify increment 1 or infer acceptance from a `valid` smoke-test response. Previous records labeled that response acceptance more strongly than Jason's words warranted; do not use that label to skip any technical prerequisite or the owner approval requested here.
+11 -4
View File
@@ -11,10 +11,17 @@ Registry plan review is complete. All ten gates carry owner rulings
(2026-09-10, ms-grill-me + Q15); gate 7 closed via PI-REFRESH-ROCKO-1
investigation and GATE7-FINAL-FILBERT-1 APPROVED. Published: 224147ec,
b8008eda, d5307d2b, 86e009dde52bd588b4ade344bc292d5518843e1d (remote verified).
Next action: none queued. A registry implementation increment requires a
separate owner charter (author, reviewer, allowed paths, suites, rollback);
ask Jason whether to draft it. Pi pin moves to 0.85.1 as part of that
increment, not as an unprompted change.
#1500 prerequisite correction complete: independently APPROVED af97b5be,
source 6335342873985538da3e7dc80cf9e9505e758832 pushed and remote verified.
Committed-tree package/launcher fixtures passed 48/48; source and test limits:
`docs/plans/reviews/2026-09-10_m20-correction-completion.md`.
Next action: obtain owner approval for the separately drafted fixture-only
materialization/refresh increment before implementing it. Existing draft:
`docs/plans/2026-09-10_m20-increment2-charter.md`.
The corrective slice grants no materialization, live refresh, real credential,
service or deployment authority. #1500 remains open for this separate gate.
Increment 1 and pi 0.85.1 were published through b3fa2210; passing original tests
is not evidence that these newly identified prerequisites are satisfied.
Owner goal #1498 completed: independently approved skill/launcher repair published
at f3dce3208877626043c521c6ef5076f9559309b0; fresh remote identity verified and
@@ -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 D1D10; 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.
- **D1D10 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.
D1D10 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.