This document records the current local verification contract and the known environment-specific gotchas that contributors have already hit.
The baseline sprint closeout command is:
./scripts/verify-local.shSprint 77 also makes the browser-shell smoke a CI-owned gate. Run it locally with:
pnpm run test:e2ePlaywright starts and stops Vite through webServer; no separately running dev server is required. The smoke deliberately asserts that native Tauri IPC is absent, so it proves only the limited browser shell. Native workspace, asset-protocol, CSP enforcement, and PDF-preview behavior require a desktop smoke.
When the host disk is near capacity, fresh Rust target directories under /var/folders/.../T can fail with No space left on device even when the repo itself is healthy. If a rerun fails that way after frontend or docs-only changes, inspect df -h, clean stale verifier target dirs, and prefer reusing a previously successful CARGO_TARGET_DIR before treating the failure as a product regression.
Use npm run maintainer:temp-hygiene before ad hoc shell cleanup when the likely problem is stale 900project-* verifier or sprint artifacts under the temp roots. That command reports and can remove only repo-prefixed temp artifacts; it is the reviewed repo-owned path for this class of disk-pressure triage.
Use npm run maintainer:artifact-hygiene before manual repo-root cleanup when the likely problem is generated evidence or release directories inside the checkout. That command reports and can remove only managed repo-local artifact paths; it does not touch tracked content or workspace-state directories.
Use npm run maintainer:duplicate-copy-hygiene before deleting suspicious untracked * 2.* or * 3.* files when stale duplicate snapshots may be shadowing tracked repo content inside the checkout.
Fresh clones need dependencies installed before this script can work because it calls the local node_modules/.bin tools directly. In a new healthy clone, run:
npx pnpm install --frozen-lockfileThe repo tracks pnpm-workspace.yaml with allowBuilds.esbuild: true because the reviewed Vite/Svelte toolchain needs the esbuild postinstall step. If that file is missing or reverted to a placeholder, pnpm install --frozen-lockfile will stop at pnpm's build-approval gate before ./scripts/verify-local.sh can run.
If you validate from a secondary git worktree, that worktree also needs access to the dependency tree. The simplest options are:
npx pnpm install --frozen-lockfileor, when a healthy sibling checkout already has a complete install:
ln -s /path/to/healthy-clone/node_modules node_modulesThe script runs frontend tools through local node_modules/.bin binaries by default. That keeps local closeout focused on the actual compiler, linter, test runner, and bundler instead of the package-runner layer that can stall in this Codex desktop environment.
When ./scripts/verify-local.sh has to create its own 900project-verify-* Cargo target, it now removes that auto-created target on exit by default. To keep the auto-created target for one deliberate rerun, set:
VERIFY_KEEP_CARGO_TARGET_DIR=1 ./scripts/verify-local.shThe repo contract remains pnpm for dependency installation and lockfile policy. If a contributor needs to validate through package scripts, use:
VERIFY_FRONTEND_RUNNER=pnpm ./scripts/verify-local.shThat runner reads package.json and tries to run the repository-pinned pnpm version from the local pnpm store before falling back to PATH-level pnpm or npm. To force a specific pnpm script path, use:
VERIFY_FRONTEND_RUNNER=pnpm VERIFY_PNPM_SCRIPT=/absolute/path/to/pnpm.cjs ./scripts/verify-local.shIf the Codex desktop environment stalls on the default local-binary path without diagnostics, the script also supports npm runners:
VERIFY_FRONTEND_RUNNER=npm-exec ./scripts/verify-local.shThe default script path runs:
./node_modules/.bin/svelte-check --tsconfig ./tsconfig.json./node_modules/.bin/eslint src/lib src/main.ts vite.config.ts vitest.config.ts playwright.config.ts eslint.config.js scripts/*.js scripts/release/*.js scripts/maintainers/*.js scripts/contributors/*.js./node_modules/.bin/vitest runnode --test scripts/e2e-config.test.js scripts/public-safe-artifacts.test.js scripts/release/native-bundle-identity.test.js ...plus the maintained release, maintainer, and contributor Node suites frompackage.json./node_modules/.bin/vite buildcargo fmt --check --manifest-path src-tauri/Cargo.tomlcargo check --manifest-path src-tauri/Cargo.tomlcargo test --lib --bins --tests --manifest-path src-tauri/Cargo.toml
After portability, CSP, release-boundary, or native packaging changes, also run the relevant focused gates:
npm run test:release
npm run test:maintainers
npm run release:boundary
cargo audit --file src-tauri/Cargo.lock
pnpm run test:e2eOn macOS, after producing an app bundle, verify that Tauri selected the desktop executable rather than an auxiliary Cargo binary:
npm run release:verify:native-bundleThe command skips clean checkouts with no built app, but fails a present bundle unless both Info.plist and Contents/MacOS/ identify nine-hundred-project.
The Sprint 77 audit closed RUSTSEC-2026-0190, RUSTSEC-2026-0194, and RUSTSEC-2026-0195 with lock-only updates. Cargo audit may still report informational unmaintained/unsound warnings; record them separately rather than calling the vulnerability gate clean without qualification.
Vitest now resolves the browser condition in vitest.config.ts so Svelte component tests can use the public mount(...) API under jsdom. If App-level component tests start failing with mount(...) is not available on the server, check the Vitest resolve conditions before changing the application code.
With VERIFY_FRONTEND_RUNNER=pnpm, the frontend half uses:
- repository-pinned
pnpm run checkwhen available, otherwise PATHpnpm run check, otherwisenpm run check - repository-pinned
pnpm run lintwhen available, otherwise PATHpnpm run lint, otherwisenpm run lint - repository-pinned
pnpm run testwhen available, otherwise PATHpnpm run test, otherwisenpm run test - repository-pinned
pnpm run buildwhen available, otherwise PATHpnpm run build, otherwisenpm run build
With VERIFY_FRONTEND_RUNNER=npm-exec, the frontend half uses:
npm exec -- svelte-check --tsconfig ./tsconfig.jsonnpm exec -- eslint src/lib src/main.ts vite.config.ts vitest.config.ts playwright.config.ts eslint.config.js scripts/*.js scripts/release/*.js scripts/maintainers/*.js scripts/contributors/*.jsnpm exec -- vitest runnode --test scripts/release/release-artifacts.test.js scripts/release/release-verification.test.js scripts/release/release-evidence-ledger.test.js scripts/release/release-publish-assets.test.js scripts/release/release-boundary-regressions.test.js scripts/release/release-witness-pack.test.js scripts/release/release-candidate-preflight.test.js scripts/maintainers/rotation-drill.test.js scripts/maintainers/issue-reproduction-kit.test.js scripts/maintainers/evidence-freshness.test.js scripts/maintainers/durability-stewardship.test.js scripts/maintainers/temp-artifact-hygiene.test.js scripts/maintainers/repo-artifact-hygiene.test.js scripts/maintainers/recovery-incident-fixtures.test.js scripts/maintainers/validation-receipts.test.js scripts/maintainers/fixture-provenance-ledger.test.js scripts/maintainers/review-dossier-pack.test.js scripts/contributors/starter-kit.test.js scripts/contributors/validation-sandbox.test.jsnpm exec -- vite build
Sprint 40 adds a public transfer-fixture library with its own maintainer smoke path:
pnpm run fixtures:transfer:refresh
pnpm run fixtures:transfer:smokeIf package-runner behavior is noisy in the current environment, the direct Rust fallback is:
cargo run --manifest-path src-tauri/Cargo.toml --bin transfer-fixtures -- refresh --force
cargo run --manifest-path src-tauri/Cargo.toml --bin transfer-fixtures -- smokeThe generated artifacts land in artifacts/transfer-fixtures/ and are intentionally not committed.
Sprint 42 adds a repo-owned performance harness with explicit fixture refresh and gate-run commands:
npm run performance:gates:refresh
npm run performance:gates:runThe direct Rust fallback is:
cargo run --manifest-path src-tauri/Cargo.toml --bin performance-gates -- refresh --force
cargo run --manifest-path src-tauri/Cargo.toml --bin performance-gates -- runThe harness writes ignored artifacts under artifacts/performance-gates/:
catalog.json- fixture inventory and scenario metadata
report.json- machine-readable pass/fail output with actual timings and threshold values
- generated fixture directories for:
workspace-scaleimport-conflict-scaleattachment-preview-scaleexport-scale
These gates are intentionally not part of the baseline ./scripts/verify-local.sh contract yet. They are heavier than routine sprint closeout checks and should stay opt-in until maintainers decide they belong in a broader local or CI budget.
Sprint 41 adds a repo-owned release evidence ledger:
pnpm run release:ledger -- \
--downloads-root release-downloads \
--asset-directory release-publish \
--release-tag v0.1.0 \
--repo 900Labs/900Project \
--sign-updater trueIn normal release recovery flows, pnpm run release:publish:assets ... rewrites the same release-publish/release-evidence-ledger.json automatically after verification.
Sprint 44 adds a Rust-owned support-bundle contract with focused local coverage:
CARGO_TARGET_DIR=/tmp/900project-sprint44-cargo cargo test --manifest-path src-tauri/Cargo.toml support_bundle -- --nocaptureThat target currently covers:
- deterministic JSON output from the same input state
- settings redaction, including the
app_lock.pin_hashcase that lives insideapp_settings - missing and unparseable repo-evidence diagnostics
The current bundle button and save-path wiring ride on the normal shell validation path (svelte-check, vite build, and baseline app smoke). Sprint 44 does not yet add a dedicated frontend test for that button flow.
Sprint 45 adds a backend-owned integrity report plus one explicit repair action for orphaned attachment blobs:
CARGO_TARGET_DIR=/tmp/900project-sprint45-cargo cargo test --manifest-path src-tauri/Cargo.toml audits_ -- --nocaptureThat target currently covers:
- a healthy workspace returning a clean audit
- a deliberately corrupted workspace surfacing graph, attachment, timer, and time-entry findings
- deterministic orphan-blob cleanup removing only the repairable blob finding
The current shell surface for the audit is maintainer-facing and rides on the normal Svelte typecheck and build path. Sprint 45 does not yet add a dedicated frontend test for the audit panel.
Sprint 46 adds a repo-owned compatibility matrix with one maintainer rerun command:
npm run compatibility:matrix:runThe direct Rust fallback is:
cargo run --manifest-path src-tauri/Cargo.toml --bin compatibility-matrix -- run --forceThe command writes ignored artifacts under artifacts/compatibility-matrix/:
report.json- supported workspace schema upgrade results for schema versions 1 through current schema 6
- supported
.900projimport results for bundle schema versions 1 through 6 - explicit expected-failure output for the unsupported schema-1 placeholder recurring-rule case
- generated case directories for:
workspace-schema-v1workspace-schema-v2workspace-schema-v3workspace-schema-v4workspace-schema-v5workspace-schema-v6workspace-schema-v1-legacy-recurring-rulesbundle-schema-v1bundle-schema-v2bundle-schema-v3bundle-schema-v4bundle-schema-v5bundle-schema-v6
Sprint 46 also adds focused Rust coverage under the compatibility_matrix test target, but the maintainer-facing command is the source of truth for the compatibility report artifact.
Sprint 66 keeps the focused validation path narrow and backend-heavy:
- run
cargo fmt --manifest-path src-tauri/Cargo.tomlplusCARGO_TARGET_DIR=/tmp/900project-sprint66-cargo cargo test --lib --bins --tests --manifest-path src-tauri/Cargo.tomlplusnpm run checkfor Sprint 66
cargo fmt --manifest-path src-tauri/Cargo.toml
CARGO_TARGET_DIR=/tmp/900project-sprint66-cargo cargo test --lib --bins --tests --manifest-path src-tauri/Cargo.toml
npm run check
git diff --checkThis lane upgrades the Rust PDF exporter and the shell copy around it. If the host disk is nearly full, prefer reusing an existing successful CARGO_TARGET_DIR instead of creating a fresh verifier target for every rerun.
Sprint 67 keeps the focused validation path narrow and maintainer-surface-only:
- run
git ls-files --error-unmatch docs/sprints/sprint-67-final-closeout.mdplusnode --test scripts/maintainers/evidence-freshness.test.jsplusnpm run maintainer:evidence:freshnessplusgit diff --checkfor Sprint 67
git ls-files --error-unmatch docs/sprints/sprint-67-final-closeout.md
node --test scripts/maintainers/evidence-freshness.test.js
npm run maintainer:evidence:freshness
git diff --checkThis lane changes status and drift-guard files only. The Sprint 67 note must be tracked before the focused guard can pass. If a branch updates closeout wording again, keep README.md, the roadmap set, maintainer docs, the Sprint 67 note, and the guard in the same patch set instead of carrying partial status updates across branches.
Sprint 68 adds one standalone maintainer-operability follow-on for repo-prefixed temp cleanup:
- run
node --test scripts/maintainers/temp-artifact-hygiene.test.jsplusnpm run maintainer:temp-hygieneplusgit diff --checkfor Sprint 68
node --test scripts/maintainers/temp-artifact-hygiene.test.js
npm run maintainer:temp-hygiene
git diff --check- focused command contract:
npm run maintainer:temp-hygiene
Use this route when the maintainer question is "are stale 900project-* temp artifacts the real cause of the failure?" rather than "did the product or portable workspace state regress?"
Sprint 69 adds one standalone maintainer-operability follow-on for generated repo-local evidence and release cleanup:
- run
node --test scripts/maintainers/repo-artifact-hygiene.test.jsplusnpm run maintainer:artifact-hygieneplusgit diff --checkfor Sprint 69
node --test scripts/maintainers/repo-artifact-hygiene.test.js
npm run maintainer:artifact-hygiene
git diff --checkSprint 70 adds one standalone maintainer-operability follow-on for the remaining attachment-preview iframe warnings in src/App.svelte:
- run
./node_modules/.bin/svelte-check --tsconfig ./tsconfig.jsonplus./node_modules/.bin/vite buildplus./node_modules/.bin/vitest run src/App.test.ts src/lib/attachments.test.tsplusgit diff --checkfor Sprint 70
./node_modules/.bin/svelte-check --tsconfig ./tsconfig.json
./node_modules/.bin/vite build
./node_modules/.bin/vitest run src/App.test.ts src/lib/attachments.test.ts
git diff --check- focused command contract:
npm run maintainer:artifact-hygiene
Use this route when the maintainer question is "did generated evidence or release directories inside the repo root build up?" rather than "did system temp roots fill up?" or "did portable workspace state regress?"
Sprint 71 adds one standalone maintainer-operability follow-on for suspicious untracked duplicate-copy shadows of tracked repo files:
- run
node --test scripts/maintainers/duplicate-copy-hygiene.test.jsplusnpm run maintainer:duplicate-copy-hygieneplusgit diff --checkfor Sprint 71
node --test scripts/maintainers/duplicate-copy-hygiene.test.js
npm run maintainer:duplicate-copy-hygiene
git diff --check- focused command contract:
npm run maintainer:duplicate-copy-hygiene
Use this route when the maintainer question is "did stale untracked duplicate copies shadow tracked repo content?" rather than "did generated artifacts build up?" or "did temp roots fill up?"
Sprint 47 adds a repo-owned boundary regression command:
npm run release:boundaryFocused command-level coverage lives in:
node --test scripts/release/release-boundary-regressions.test.jsThe broader validation path is:
- focused command contract:
node --test scripts/release/release-boundary-regressions.test.js - release-script suite:
npm run test:release - baseline repo verifier:
./scripts/verify-local.sh
Sprint 72 adds public repository licensing, governance, support, security, package metadata, and release workflow script-path validation:
- run
node --test scripts/release/release-boundary-regressions.test.jsplusnpm run release:boundaryplusgit diff --checkfor Sprint 72
node --test scripts/release/release-boundary-regressions.test.js
npm run release:boundary
git diff --check- focused command contract:
npm run release:boundary
Use this route when the maintainer question is "does the public release metadata stay aligned with the release workflow script surface?" rather than "did product runtime behavior change?"
The command prints one machine-readable JSON report to stdout on both success and failure. Maintainer tooling and review notes should treat that JSON plus the process exit status as the source of truth for Sprint 47 boundary status rather than paraphrasing the command from memory.
This boundary pack proves:
- the capability baseline across
src-tauri/capabilities/default.json,src-tauri/tauri.conf.json,src-tauri/src/lib.rs, and the reviewed Tauri dependency surface - updater build gating for unsigned/dev-style builds, signed builds with no endpoint source, and the
windows-offlinevariant through the real build invocation path - workflow-step and child-build env scoping for updater signing/runtime env and Apple notarization inputs
- the continued absence of generic Tauri shell/filesystem/process/opener/store/CLI plugin surfaces the repo does not need
Runtime-side updater disabled reasons are still covered by the Rust updater tests and the broader baseline verifier. The Sprint 47 command itself is the build-path and release-boundary check.
Expected fail conditions include:
- capability permissions widening past
core:defaultplusdialog:default - generic Tauri shell/filesystem/process/open/reveal style plugins being added
- updater signing env leaking into standard or offline child builds
- Apple signing env leaking into non-notarized workflow steps or child builds
- signed updater builds no longer failing when neither explicit endpoints nor
GITHUB_REPOSITORYis configured
Sprint 74 adds a repo-owned release candidate preflight for the first public v0.1.0 tag:
npm run release:candidate -- --release-tag v0.1.0 --allow-private true --check-remote-tags false --repo-visibility privateFocused command-level coverage lives in:
node --test scripts/release/release-candidate-preflight.test.jsThe broader validation path is:
- focused command contract:
node --test scripts/release/release-candidate-preflight.test.js - release-script suite:
npm run test:release - baseline repo verifier:
./scripts/verify-local.sh
Use --allow-private true only for pre-tag dry runs while the GitHub repository is intentionally still private. The focused local dry-run command injects --repo-visibility private and disables only the remote tag lookup so local validation does not depend on gh or network access. The JSON report should show repo visibility as action_required with the action to make the repo public before creating or pushing the release tag. The final pre-tag run should omit --allow-private true, --repo-visibility private, and --check-remote-tags false after maintainer approval makes the repo public.
Sprint 48 adds a repo-owned maintainer continuity command:
npm run maintainer:rotation:drillFocused command-level coverage lives in:
node --test scripts/maintainers/rotation-drill.test.jsThe broader validation path is:
- focused command contract:
node --test scripts/maintainers/rotation-drill.test.js - maintainer drill suite:
npm run test:maintainers - baseline repo verifier:
./scripts/verify-local.sh
The command prints one machine-readable JSON report to stdout on both success and failure. Maintainer continuity notes should treat that JSON report plus the process exit status as the source of truth for whether the repo still exposes the required drill surface.
This drill proves:
- the required maintainer docs and shell/package entrypoints still exist together
- issue intake, fixture selection, validation entrypoints, release lookup, rollback choice, and support interpretation still route through repo-owned docs and commands
- the current maintainer surface still points at the active Sprint 65 post-polish continuation lane instead of private handoff context
Sprint 49 adds a repo-owned issue handoff command:
npm run maintainer:issue-kit -- \
--support-bundle /path/to/exported.support-bundle.json \
--output-dir /path/to/issue-kitFocused command-level coverage lives in:
node --test scripts/maintainers/issue-reproduction-kit.test.jsThe broader validation path is:
- focused command contract:
node --test scripts/maintainers/issue-reproduction-kit.test.js - maintainer suite:
npm run test:maintainers - baseline repo verifier:
./scripts/verify-local.sh
The command prints one machine-readable JSON report to stdout on both success and failure. Treat that JSON plus the process exit status as the source of truth for whether the issue-kit contract succeeded. Focused coverage now also proves that malformed support-bundle JSON is rejected, same-directory reruns do not leak stale broader evidence, and the manifest stays deterministic for the same input state.
Sprint 50 adds a repo-owned release provenance command:
npm run release:witness -- \
--ledger-path release-publish/release-evidence-ledger.json \
--output-dir release-witnessFocused command-level coverage lives in:
node --test scripts/release/release-witness-pack.test.jsThe broader validation path is:
- focused command contract:
node --test scripts/release/release-witness-pack.test.js - release-script suite:
npm run test:release - baseline repo verifier:
./scripts/verify-local.sh
Focused coverage now also proves that witness output cannot be written into the publish directory and that reruns clear stale managed optional evidence before rewriting the witness pack.
Sprint 53 adds a repo-owned maintainer evidence checker:
npm run maintainer:evidence:freshnessFocused command-level coverage lives in:
node --test scripts/maintainers/evidence-freshness.test.jsThe broader validation path is:
- focused command contract:
npm run maintainer:evidence:freshness - focused test coverage:
node --test scripts/maintainers/evidence-freshness.test.js - baseline repo verifier:
./scripts/verify-local.sh
The checker prints one machine-readable JSON report to stdout on both success and failure. Treat that JSON plus the process exit status as the source of truth for whether the current maintainer docs, evidence names, and continuation-status contract still match the repo-owned contract.
Sprint 54 adds a repo-owned replay-pack command for drill-derived recovery incidents:
npm run maintainer:recovery:fixturesFocused command-level coverage lives in:
node --test scripts/maintainers/recovery-incident-fixtures.test.jsThe broader validation path is:
- focused command contract:
npm run maintainer:recovery:fixtures - focused test coverage:
node --test scripts/maintainers/recovery-incident-fixtures.test.js - maintainer suite:
npm run test:maintainers - baseline repo verifier:
./scripts/verify-local.sh
The command prints one machine-readable JSON report to stdout and writes artifacts/recovery-incident-fixtures/report.json. Treat that JSON plus the process exit status as the source of truth for whether the repo can still publish public-safe recoverable, blocked, and manual-intervention replay cases from the maintained drill output.
Sprint 52 adds a repo-owned contributor starter checker:
npm run contributor:starter:checkFocused command-level coverage lives in:
node --test scripts/contributors/starter-kit.test.jsThe broader validation path is:
- focused command contract:
npm run contributor:starter:check - focused test coverage:
node --test scripts/contributors/starter-kit.test.js - baseline repo verifier:
./scripts/verify-local.sh
The checker prints one machine-readable JSON report to stdout on both success and failure. Treat that JSON plus the process exit status as the source of truth for whether the contributor-safe command and guardrail surface still matches the documented first-contribution lane.
Sprint 55 adds one repo-owned contributor validation sandbox checker:
npm run contributor:validation:sandboxFocused command-level coverage lives in:
node --test scripts/contributors/validation-sandbox.test.jsThe broader validation path is:
- focused command contract:
npm run contributor:validation:sandbox - focused test coverage:
node --test scripts/contributors/validation-sandbox.test.js - contributor starter boundary:
npm run contributor:starter:check - baseline repo verifier:
./scripts/verify-local.sh
The checker prints one machine-readable JSON report to stdout on both success and failure. Treat that JSON plus the process exit status as the source of truth for whether the contributor-safe validation profiles, evidence paths, and maintainer-only stop boundaries still match the documented sandbox.
Sprint 57 adds one repo-owned validation handoff command:
npm run maintainer:validation:receipt -- \
--profile closeout \
--output-path artifacts/validation-receipts/closeout.jsonIf GitHub Actions failed before runner startup for billing reasons, rerun the same closeout receipt path with the documented caveat:
npm run maintainer:validation:receipt -- \
--profile closeout \
--caveat ci-billing-blocked \
--output-path artifacts/validation-receipts/closeout.jsonFocused command-level coverage lives in:
node --test scripts/maintainers/validation-receipts.test.jsThe broader validation path is:
- focused command contract:
npm run maintainer:validation:receipt -- --profile <id> --output-path <path> - focused test coverage:
node --test scripts/maintainers/validation-receipts.test.js - contributor profile owner:
npm run contributor:validation:sandbox - maintainer route owners:
npm run maintainer:evidence:freshness,npm run maintainer:durability:check, andnpm run maintainer:rotation:drill - baseline repo verifier:
./scripts/verify-local.sh
Use this route when the question is "what exactly did we run, what artifact proves it, and what environment caveat still matters?" The receipt is a local declaration over the maintained command surface, not another validation runner and not execution telemetry.
Sprint 58 adds one repo-owned artifact-ownership command:
npm run maintainer:provenance:ledgerThat command writes artifacts/fixture-provenance-ledger/report.json by default. To redirect it elsewhere:
npm run maintainer:provenance:ledger -- \
--output-path /tmp/900project-fixture-provenance.jsonFocused command-level coverage lives in:
node --test scripts/maintainers/fixture-provenance-ledger.test.jsThe broader validation path is:
- focused command contract:
npm run maintainer:provenance:ledger - focused test coverage:
node --test scripts/maintainers/fixture-provenance-ledger.test.js - maintainer routing owners:
npm run maintainer:evidence:freshnessandnpm run maintainer:rotation:drill - baseline repo verifier:
./scripts/verify-local.sh
Use this route when the real question is "which repo-owned family owns this public-safe artifact, how do I rerun it, and is the missing artifact expected?" The ledger documents ownership and retention; it does not replace the underlying fixture, release, recovery, or validation command.
Sprint 59 adds one repo-owned cross-surface reviewer handoff command:
npm run maintainer:review:dossier -- \
--validation-receipt artifacts/validation-receipts/closeout.json \
--issue-kit-dir /tmp/900project-issue-kit \
--output-dir /tmp/900project-review-dossierFocused command-level coverage lives in:
node --test scripts/maintainers/review-dossier-pack.test.jsThe broader validation path is:
- focused command contract:
npm run maintainer:review:dossier -- --validation-receipt <path> --issue-kit-dir <dir> --output-dir <dir> - focused test coverage:
node --test scripts/maintainers/review-dossier-pack.test.js - maintainer routing owners:
npm run maintainer:evidence:freshnessandnpm run maintainer:rotation:drill - baseline repo verifier:
./scripts/verify-local.sh
Use this route when one reviewer handoff needs validation receipts, issue or fixture context, and multiple repo-owned evidence families in one public-safe folder. The dossier is a composition layer over reviewed evidence, not a generic archive builder.
Sprint 51 adds a repo-owned recovery composition command:
npm run maintainer:recovery:drillFocused Rust coverage lives in:
CARGO_TARGET_DIR=/tmp/900project-sprint51-cargo cargo test --manifest-path src-tauri/Cargo.toml recovery_drill -- --nocapture
CARGO_TARGET_DIR=/tmp/900project-sprint51-cargo cargo test --manifest-path src-tauri/Cargo.toml --bin recovery-drill -- --nocaptureThe broader validation path is:
- focused core coverage:
cargo test --manifest-path src-tauri/Cargo.toml recovery_drill -- --nocapture - focused CLI coverage:
cargo test --manifest-path src-tauri/Cargo.toml --bin recovery-drill -- --nocapture - command contract:
npm run maintainer:recovery:drill - baseline repo verifier:
./scripts/verify-local.sh
The command prints one machine-readable JSON report to stdout and writes artifacts/recovery-drill/report.json. That report should point at:
compatibility-matrix/report.jsonunder the drill root- one recoverable round-trip scenario
- one recoverable repair-bounded orphan-blob scenario
- one blocked newer-bundle scenario
- one manual-intervention checksum-mismatch scenario
Focused coverage now also proves that the recoverable backup path stays inside SQLite-backed workspace durability, while attachment durability remains validated through bundle import and integrity-audit artifacts instead of pretending the backup alone preserved attachment blobs.
Sprint 56 adds one repo-owned durability stewardship checker:
npm run maintainer:durability:checkFocused command-level coverage lives in:
node --test scripts/maintainers/durability-stewardship.test.jsThe broader validation path is:
- focused command contract:
npm run maintainer:durability:check - focused test coverage:
node --test scripts/maintainers/durability-stewardship.test.js - recovery evidence anchor:
npm run maintainer:recovery:drill - compatibility evidence anchor:
npm run compatibility:matrix:run - baseline repo verifier:
./scripts/verify-local.sh
Use this route when the question is about backup rotation, restore-verification cadence, .900proj retention, or issue-safe recovery evidence retention for long-lived offline workspaces.
Do not use it as a substitute for local machine troubleshooting. If the real problem is disk pressure, temp-directory cleanup, placeholder checkout hydration, or a stalled local toolchain, stay in the environment-specific guidance in this file and the maintainer issue-triage path.
Sprint 61 adds focused frontend regression coverage for the maintainer-facing transfer and integrity surfaces:
./node_modules/.bin/vitest run src/lib/maintainer-panel.test.ts src/lib/file-dialog.test.ts
./node_modules/.bin/svelte-check --tsconfig ./tsconfig.json
./node_modules/.bin/eslint src/lib/maintainer-panel.ts src/lib/maintainer-panel.test.ts src/lib/file-dialog.test.tsFocused coverage now proves:
- support-bundle output-path validation and save-filter wiring stay explicit
- import-review handoff output-path derivation stays deterministic and user overrides are preserved
- workspace-integrity audit finding formatting, evidence summarization, and orphan-blob repair availability stay testable through pure helpers rather than ad hoc component-only assertions
The broader validation path is:
- focused command contract:
./node_modules/.bin/vitest run src/lib/maintainer-panel.test.ts src/lib/file-dialog.test.ts - shell typecheck:
./node_modules/.bin/svelte-check --tsconfig ./tsconfig.json - focused lint coverage:
./node_modules/.bin/eslint src/lib/maintainer-panel.ts src/lib/maintainer-panel.test.ts src/lib/file-dialog.test.ts - baseline repo verifier:
./scripts/verify-local.sh
Sprint 63 adds one portable schedule contract for reports, utilization, and calendar highlighting:
CARGO_TARGET_DIR=/tmp/900project-sprint63-cargo cargo test --manifest-path src-tauri/Cargo.toml --lib --bins --tests
./node_modules/.bin/vitest run src/lib/schedule.test.ts src/lib/calendar.test.ts
./node_modules/.bin/svelte-check --tsconfig ./tsconfig.jsonFocused coverage now proves:
- work calendars and per-member capacity overrides persist through the backend schema and command surface
- report snapshots, CSV output, and utilization summaries explain their working-day and holiday basis from local data
- the month calendar highlights non-working days and configured holidays from the same project-local schedule contract
The broader validation path is:
- focused Rust contract:
CARGO_TARGET_DIR=/tmp/900project-sprint63-cargo cargo test --manifest-path src-tauri/Cargo.toml --lib --bins --tests - focused frontend coverage:
./node_modules/.bin/vitest run src/lib/schedule.test.ts src/lib/calendar.test.ts - shell typecheck:
./node_modules/.bin/svelte-check --tsconfig ./tsconfig.json - baseline repo verifier:
./scripts/verify-local.sh
Sprint 64 extends the portable budget model with expense entries, actual-versus-plan report fields, and bundle-portable budget actuals:
CARGO_TARGET_DIR=/tmp/900project-sprint64-cargo cargo test --manifest-path src-tauri/Cargo.toml --lib --bins --tests
./node_modules/.bin/vitest run src/lib/budget.test.ts
./node_modules/.bin/svelte-check --tsconfig ./tsconfig.jsonFocused coverage now proves:
- expense entries persist through the backend schema, command surface, and change-log-aware bundle contract
- project, category, and donor-linked budget actuals stay integer-exact in report snapshots and export artifacts
- the shell keeps budget planning and expense-entry UX aligned with the same portable budget snapshot
The broader validation path is:
- focused Rust contract:
CARGO_TARGET_DIR=/tmp/900project-sprint64-cargo cargo test --manifest-path src-tauri/Cargo.toml --lib --bins --tests - focused frontend coverage:
./node_modules/.bin/vitest run src/lib/budget.test.ts - shell typecheck:
./node_modules/.bin/svelte-check --tsconfig ./tsconfig.json - baseline repo verifier:
./scripts/verify-local.sh
Sprint 65 adds pointer-first board ergonomics and richer Gantt dependency cues without changing the backend mutation contract:
./node_modules/.bin/vitest run src/App.test.ts src/lib/task-board.test.ts src/lib/gantt.test.ts
./node_modules/.bin/svelte-check --tsconfig ./tsconfig.jsonFocused coverage now proves:
- Kanban pointer-drop planning still reuses the deterministic ordering model instead of inventing a second task-move API
- pointer drag is withheld when filtered board state would hide project tasks from persisted ordering decisions
- Gantt dependency visuals derive from existing dependency type, lag, and critical-path facts without widening backend contracts
The broader validation path is:
- focused frontend coverage:
./node_modules/.bin/vitest run src/App.test.ts src/lib/task-board.test.ts src/lib/gantt.test.ts - shell typecheck:
./node_modules/.bin/svelte-check --tsconfig ./tsconfig.json - evidence drift guard:
npm run maintainer:evidence:freshness - evidence drift tests:
node --test scripts/maintainers/evidence-freshness.test.js - baseline repo verifier:
./scripts/verify-local.sh
The focused App test stubs document.elementFromPoint directly because jsdom does not provide browser hit-testing. Keep that stub in pointer-drop component tests instead of weakening the application code.
- Rust validation can block on stale Cargo build-directory locks in this environment.
- The verification script now forces Rust checks into an isolated
CARGO_TARGET_DIRper run to avoid unrelated lock contention. - If you need to run commands manually, prefer setting
CARGO_TARGET_DIRexplicitly when there are othercargosessions on the machine.
Example:
CARGO_TARGET_DIR=/tmp/900project-manual-check cargo check --manifest-path src-tauri/Cargo.toml
CARGO_TARGET_DIR=/tmp/900project-manual-check cargo test --lib --bins --tests --manifest-path src-tauri/Cargo.toml- In this environment, plain
cargo test --manifest-path src-tauri/Cargo.tomlreached a quietrustdoc --testphase after the unit-test banner and did not return promptly. Use the explicit--lib --bins --testsform for reliable sprint closeout unless you are intentionally validating doc tests.
- The repo contract remains
pnpm, and the repo now carries a committedpnpm-lock.yamlso CI and release workflows can use--frozen-lockfile. - Local validation defaults to local tool binaries because package runners have repeatedly stalled in this Codex desktop environment even when the underlying tools return cleanly.
- When a package-runner validation is needed, prefer the
packageManager-pinned pnpm script over a global Homebrew/Corepack shim. A broken global shim should not make the repository look broken. - A local pnpm store can have metadata for the pinned version while still missing tarballs needed by
node_modules. In that case, rerun the pinned install path with network access rather than editing package policy. - After any dependency-specifier change in
package.json, rerun a frozen install path before pushing.pnpm install --frozen-lockfilewill fail if the importerspecifier:values inpnpm-lock.yamlstill reflect the old range or pin, even when the resolved package version did not change. - This machine did not initially have
pnpminstalled. Early bootstrap validation usednpmwithout changing repo policy. - If frontend validation appears to hang in the Codex desktop execution environment, rerun the same commands in a normal terminal session before treating the result as a code failure. This has occurred intermittently even for simple Node-based commands.
compressed,datalessplaceholders can exist insidenode_modulesas well as repo source files on this Mac. Ifsvelte-check,eslint,vitest,vite build, or evennode -e "import('./vite.config.ts')"idles with no diagnostics, inspect both the repo tree and the dependency tree:
ls -lO src/App.svelte src/lib/i18n.ts
find node_modules -flags +dataless | head- If placeholders are present, hydrate them before retrying the same validation command:
brctl download src
find node_modules -flags +dataless -print0 | xargs -0 brctl download- Sprint 3 repeated the same behavior for
npm run build,npm run lint, andnpm run test, with timed subprocess runs printing only the command banner before stalling. Record that exact outcome in sprint notes when it happens. - Sprint 8 repeated the pattern for
npm run test,npm run check, Node-20npm run check, targetednpx eslint, and single-filenpx vitest. At that point the issue is broader than one script or one Node major version, so do not waste sprint closeout time pretending a local green run is available in this execution environment. - Sprint 9 repeated the pattern again for
npm run check, which printed only thesvelte-check --tsconfig ./tsconfig.jsonstartup banner before manual interruption. Treat that as the same known environment limitation, not as a new repo-specific failure, unless a normal terminal reproduces it. - Sprint 10 repeated the same behavior for
npm exec tsc -- -p tsconfig.json --noEmit, which stayed attached with no diagnostics until manual interruption. Record it as the same Codex-local Node stall family unless a normal terminal reproduces the hang. - Sprint 11 repeated the same behavior for
npm run check,npm run test -- src/lib/i18n.test.ts, andnpm exec prettier -- --write ..., all of which printed their startup banner and then remained attached without diagnostics. Treat that as the same Codex-local Node stall family unless a normal terminal reproduces it. - Sprint 12 confirmed a more reliable local fallback in the same environment:
npm exec -- svelte-check --tsconfig ./tsconfig.json,npm exec -- eslint ...,npm exec -- vitest run, andnpm exec -- vite buildall returned cleanly whilepnpm run ...still behaved inconsistently. UseVERIFY_FRONTEND_RUNNER=npm-execinstead of pretending thepnpm runpath is the only local workflow. - Sprint 13 hit a different post-repair variant: after replacing broken git metadata,
./scripts/verify-local.shstalled in thepnpm run check->svelte-check --tsconfig ./tsconfig.jsonphase without diagnostics,npm exec -- svelte-check --tsconfig ./tsconfig.jsonfailed withERR_INVALID_PACKAGE_CONFIGinside the localsvelte-checkpackage, and bothnpm exec -- vitest run src/lib/i18n.test.tsandnpm exec -- vite buildhung again without diagnostics. Treat that as another local toolchain integrity problem first; rerun from a normal terminal and prefer CI before assuming the repo change itself is broken. - Sprint 20 showed the stall pattern again on both fallback paths:
./node_modules/.bin/vitest run src/lib/i18n.test.tsstayed attached with no output, andnpm exec -- eslint src/App.svelte src/lib/i18n.ts src/lib/i18n.test.tsdid the same until manual interruption. When both local-bin and npm-exec stall silently, stop spending sprint time on local frontend retries and use CI or a normal terminal instead. - Sprint 24 exposed a second local-binary failure mode on this machine:
./node_modules/.bin/svelte-check,./node_modules/.bin/eslint, and./node_modules/.bin/tsccan fail immediately under Node 22 withERR_INVALID_PACKAGE_CONFIGwhile resolving pnpm-installed tool packages. Treat that as local toolchain integrity noise first, then retry through a normal terminal or CI instead of attributing it to the repo change by default. - Do not quietly remove or skip frontend validation from sprint closeout; record the behavior and keep the docs current if the environment constraint changes.
Before merging a sprint branch:
- Run the baseline verification script.
- Run the sprint-specific checks introduced by the sprint; keep the newest additions explicit below so closeout remains auditable without copying stale local paths.
- Keep the newest merge-closeout additions explicit in the checklist:
- run
npm run contributor:starter:checkfor Sprint 52 - run
npm run contributor:validation:sandboxfor Sprint 55 - run
npm run maintainer:durability:checkfor Sprint 56 - run
npm run maintainer:validation:receipt -- --profile closeout --output-path artifacts/validation-receipts/closeout.jsonfor Sprint 57 - run
npm run maintainer:provenance:ledgerfor Sprint 58 - run
npm run maintainer:review:dossier -- --validation-receipt <path> --issue-kit-dir <dir> --output-dir <dir>for Sprint 59 - run
npm run maintainer:evidence:freshnessplusnode --test scripts/maintainers/evidence-freshness.test.jsfor Sprint 60 - run
./node_modules/.bin/vitest run src/lib/maintainer-panel.test.ts src/lib/file-dialog.test.tsfor Sprint 61 - run
node --test scripts/release/release-artifacts.test.js scripts/release/release-verification.test.js scripts/release/release-evidence-ledger.test.js scripts/release/release-publish-assets.test.js scripts/release/release-boundary-regressions.test.js scripts/release/release-witness-pack.test.jsplusnpm run release:boundaryfor Sprint 62 - run
CARGO_TARGET_DIR=/tmp/900project-sprint63-cargo cargo test --manifest-path src-tauri/Cargo.toml --lib --bins --testsplus./node_modules/.bin/vitest run src/lib/schedule.test.ts src/lib/calendar.test.tsfor Sprint 63 - run
CARGO_TARGET_DIR=/tmp/900project-sprint64-cargo cargo test --manifest-path src-tauri/Cargo.toml --lib --bins --testsplus./node_modules/.bin/vitest run src/lib/budget.test.tsplus./node_modules/.bin/svelte-check --tsconfig ./tsconfig.jsonfor Sprint 64 - run
./node_modules/.bin/vitest run src/App.test.ts src/lib/task-board.test.ts src/lib/gantt.test.tsplus./node_modules/.bin/svelte-check --tsconfig ./tsconfig.jsonplusnpm run maintainer:evidence:freshnessplusnode --test scripts/maintainers/evidence-freshness.test.jsfor Sprint 65 - run
cargo fmt --manifest-path src-tauri/Cargo.tomlplusCARGO_TARGET_DIR=/tmp/900project-sprint66-cargo cargo test --lib --bins --tests --manifest-path src-tauri/Cargo.tomlplusnpm run checkfor Sprint 66 - run
git ls-files --error-unmatch docs/sprints/sprint-67-final-closeout.mdplusnode --test scripts/maintainers/evidence-freshness.test.jsplusnpm run maintainer:evidence:freshnessplusgit diff --checkfor Sprint 67 - run
node --test scripts/maintainers/temp-artifact-hygiene.test.jsplusnpm run maintainer:temp-hygieneplusgit diff --checkfor Sprint 68 - run
node --test scripts/maintainers/repo-artifact-hygiene.test.jsplusnpm run maintainer:artifact-hygieneplusgit diff --checkfor Sprint 69 - run
./node_modules/.bin/svelte-check --tsconfig ./tsconfig.jsonplus./node_modules/.bin/vite buildplus./node_modules/.bin/vitest run src/App.test.ts src/lib/attachments.test.tsplusgit diff --checkfor Sprint 70 - run
node --test scripts/maintainers/duplicate-copy-hygiene.test.jsplusnpm run maintainer:duplicate-copy-hygieneplusgit diff --checkfor Sprint 71 - run
node --test scripts/release/release-boundary-regressions.test.jsplusnpm run release:boundaryplusgit diff --checkfor Sprint 72 - run
npm run checkplusnpm test -- --runplusnpm run buildplusgit diff --checkfor Sprint 73 - run
node --test scripts/release/release-candidate-preflight.test.jsplusnpm run release:candidate -- --release-tag v0.1.0 --allow-private true --check-remote-tags false --repo-visibility privateplusgit diff --checkfor Sprint 74 - run
./node_modules/.bin/vitest run src/App.test.tsplusnpm run checkplusnpm run buildplusgit diff --checkfor Sprint 75 - add
--caveat ci-billing-blockedwhen GitHub Actions failed before runner startup for billing reasons and local closeout proof surfaces carry the merge handoff
- run
- Update the relevant docs.
- Add new learnings to
LEARNINGS.md. - Record any validation exceptions explicitly in the sprint notes.