Registry metadata validation
Read-only metadata CLI plus fixture-only resolution, generation and refresh APIs. No live credential handling or refresh service.
node packages/mosaic/src/cli/main.mjs validate --registry-root /absolute/fixture-root
node packages/mosaic/src/cli/main.mjs list --registry-root /absolute/fixture-root
node --test packages/mosaic/tests/
Filesystem contract
The reader currently supports Linux with procfs and descriptor-relative paths. Other platforms refuse explicitly rather than falling back to unsafe traversal. Root and all traversed registry directories must belong to the invoking user and have mode 0700. Metadata files must be regular, owned by that user and mode 0600. Symlinks are rejected in the root path, directories and metadata files. Required directories are auth/providers, auth/accounts, auth/settings and harnesses. A missing or empty registry is invalid, not an empty successful listing.
Metadata is limited to 1 MiB per file. Directory handles anchor child access while paths are being checked, preventing a renamed ancestor from redirecting later opens. Files are opened without following symlinks and checked against their prior inode/device and permissions. This is not a claim of transactionally consistent multi-record snapshots under concurrent writers; registry mutation and production materialization remain outside this package slice.
Account metadata lives at auth/accounts///account.json. The credential.json sibling is never opened or inspected. No real credentials are needed for tests. Public Git fixtures do not preserve private modes: the tests copy them into temporary directories and set 0700/0600 before invoking the reader. Do not run the CLI against your real credential stores for a smoke test.
Validation contract
Record version fields are numeric 1. Unknown versions, top-level/nested unknown fields and malformed records refuse. Every custom-endpoint harness entry uses the declared api/baseUrl/models metadata shape; an unknown adapter shape requires a reviewed schema extension. URL userinfo and non-HTTP(S) protocols refuse; plain HTTP requires allowInsecureTransport: true. No secret-valued apiKey field is accepted in provider metadata.
Profiles may only default to an enrolled account. Account types must be supported by their providers, and references must resolve. Failed validation returns no partial entries or CLI listing. Diagnostics use fixed paths/codes, never input values, unknown keys or JSON parser excerpts. Invalid input exits 1; command usage errors exit 2.
The safety regression suite covers independently reproduced findings D1-D10 from issue #1500. Passing it establishes those tested properties, not a production security certification.
Fixture-only execution and refresh
resolveFixtureExecution, createFixtureCredentialStore and createFixtureWorkspace are exported from src/index.mjs. Supply a validated registry snapshot, explicit scope and marker-only synthetic credentials. Scope is fixture input, not proof of actual project membership. Fork pins and enrollment constrain selection; native model ceilings that cannot be enforced are refused.
workspace.generate(registry, request, store, options) creates distinct private execution generations in a dedicated /tmp root. It accepts only the branded in-memory store. No production backend or output directory can be injected. Call workspace.close() when done. Published files are never rewritten by this API. Exclusive claims survive failures and prohibit retrying the same execution ID.
Expired or near-expiry OAuth fixtures automatically run the fixed fake refresh program under the store transaction. Each invocation has isolated PI_CODING_AGENT_DIR, HOME and cwd, with no inherited environment. No real Pi executable, shell, print command or network client is used. Both credential fields rotate together; successful generation commits the in-memory draft. Child output is discarded, the child is killed on timeout, and cleanup waits for child closure. Output size, type, mode and fixture markers are validated before use.
Tests can supply refresh: { mode, timeoutMs }. Modes are rotate, unchanged, failure, timeout and malformed. Timeout is 10–10000 ms, default 2000. Supplying refresh forces the fake check even for currently valid credentials. Generation fault hooks are after-auth, before-publish and after-publish. No arbitrary executable, environment or callback can be supplied.
Limits: store locks are in-process, not a production distributed lock. Credential-store commit and filesystem publication are not crash-atomic together. A post-publication failure records uncertainty, retains the generation and rolls back the in-memory draft; this simulator has no external token issuer to reconcile. A real refresh backend would need a separate reconciliation protocol before reuse. Filesystem ownership does not defend against arbitrary same-UID tampering or establish hardlink provenance.
Exact Pi 0.85.1 isolation is static-source evidence only. Its model-catalog network flag does NOT suppress OAuth refresh networking. Never substitute real Pi in these tests, even with expired synthetic OAuth tokens. Final whole-increment review is required before publication.