diff --git a/BUILD-LOG.md b/BUILD-LOG.md index 2e024584..e3fdb015 100644 --- a/BUILD-LOG.md +++ b/BUILD-LOG.md @@ -1906,3 +1906,11 @@ packages/mosaic added: provider/account/profile/selection/harness schemas with s ## 2026-09-10 — #1499 increment 1 approved Round 1 REQUEST CHANGES caught uncommitted sage-agent contamination swept into 557aba0f from the dirty worktree plus a dangling package export; both fixed at e5a9a05b (sage hunks dropped, 0.85.1 kept). Clean git-archive verification: 20/20 tests across package and launcher suites, no agents/sage committed. Follow-up verdict APPROVED. Pre-existing task-suite headless failure remains baseline parity, not regression. Push follows; Jason acceptance precedes increment 2. + +## 2026-09-10 — #1500 correction ready for independent review + +D1-D10 prerequisite repairs implemented within packages/mosaic: fail-closed filesystem roots, Linux descriptor-anchored metadata reads, private modes, numeric versions, strict nested endpoint schemas, account enrollment/type checks, fixed errors and output gating. 43 package tests, 48 combined offline tests pass. Original 14/15 diagnostic-order failure retained in correction-progress record. Frozen overlay af97b5be sent to independent reviewer; no commit/push or dependent materialization before approval. + +## 2026-09-10 — #1500 prerequisite correction published + +Independent APPROVED af97b5be, source 6335342873985538da3e7dc80cf9e9505e758832 pushed and fresh remote verified. Exact candidate path/byte checks passed; committed-tree archive fixtures 48/48 pass. D1-D10 re-attacked independently, with FIFO and unreadable credential-sibling controls. Wrong-owner/non-Linux and rename-race properties remain source-reviewed only; no live credentials/services/Docker/deployment. Corrective slice complete; downstream materialization not authorized. Completion receipt preserves tested versus untested limits. diff --git a/docs/SESSIONS.md b/docs/SESSIONS.md index a10f0070..9b73114f 100644 --- a/docs/SESSIONS.md +++ b/docs/SESSIONS.md @@ -182,3 +182,9 @@ are never rewritten or removed; corrections are new entries. - 2026-09-10 — darkwing for Filbert — MOSAIC-I1-FILBERT-1 REQUEST CHANGES (sage contamination, dangling export) fixed at e5a9a05b; follow-up APPROVED after clean-archive reruns (package 15/15, launcher 5/5). I1-F3 baseUrl hardening deferred to a later increment. Push and owner acceptance next. - 2026-09-10 — darkwing — Jason accepted #1499 increment 1 after running registry validate (output valid); acceptance recorded. Increment 2 requires a new charter. Open: pre-existing headless task failure, I1-F3 baseUrl hardening, uncommitted sage agent. + +- 2026-09-10 — darkwing — #1500 next charter drafted and sent to Filbert via M20-I2-CHARTER-FILBERT-1; transport exit0/application acceptance unknown, expected charter verdict and direct reply, follow-up Darkwing. Confirmed baseline missing registry returns valid/exit0; block dependent materialization pending prerequisite correction. Synthetic probe only, no source or live-service edits. + +- 2026-09-10 — darkwing — #1500 owner approved prerequisite correction only. D1-D10 package repairs and 43 package/48 combined tests pass; M20-CORRECTION-FILBERT-1 dispatched to Filbert/default at manifest af97b5be, transport exit0/application acceptance unknown. Required return is correction verdict plus direct reply, follow-up Darkwing. No materialization/live credential/service changes. + +- 2026-09-10 — darkwing for Filbert — #1500 M20-CORRECTION-FILBERT-1 APPROVED af97b5be, exact 12 changed files committed at 63353428, source hashes verified; clean committed-tree fixtures 48/48 pass. Push and fresh remote SHA verified. Corrective slice complete; materialization/refresh needs separate owner approval. Review limitations retained. diff --git a/docs/plans/2026-09-10_m20-increment2-charter.md b/docs/plans/2026-09-10_m20-increment2-charter.md new file mode 100644 index 00000000..7f7283fe --- /dev/null +++ b/docs/plans/2026-09-10_m20-increment2-charter.md @@ -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
` 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. diff --git a/docs/plans/CURRENT.md b/docs/plans/CURRENT.md index e47dad57..5a29ef1d 100644 --- a/docs/plans/CURRENT.md +++ b/docs/plans/CURRENT.md @@ -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 diff --git a/docs/plans/reviews/2026-09-10_m20-correction-completion.md b/docs/plans/reviews/2026-09-10_m20-correction-completion.md new file mode 100644 index 00000000..ab701933 --- /dev/null +++ b/docs/plans/reviews/2026-09-10_m20-correction-completion.md @@ -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. diff --git a/docs/plans/reviews/2026-09-10_m20-correction-snapshot.json b/docs/plans/reviews/2026-09-10_m20-correction-snapshot.json new file mode 100644 index 00000000..1dec6234 --- /dev/null +++ b/docs/plans/reviews/2026-09-10_m20-correction-snapshot.json @@ -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" + ] +} diff --git a/docs/plans/reviews/2026-09-10_m20-correction-verdict.md b/docs/plans/reviews/2026-09-10_m20-correction-verdict.md new file mode 100644 index 00000000..4afe57fb --- /dev/null +++ b/docs/plans/reviews/2026-09-10_m20-correction-verdict.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. diff --git a/docs/plans/reviews/2026-09-10_m20-i2-charter-verdict.md b/docs/plans/reviews/2026-09-10_m20-i2-charter-verdict.md new file mode 100644 index 00000000..c5fd0bf7 --- /dev/null +++ b/docs/plans/reviews/2026-09-10_m20-i2-charter-verdict.md @@ -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.