Skip to content

chore(dev): add reproducible Node development bootstrap - #1337

Merged
joryirving merged 4 commits into
mainfrom
courier/misospace/dispatch/issue-1291
Oct 22, 2026
Merged

joryirving merged 4 commits into
mainfrom
courier/misospace/dispatch/issue-1291

Conversation

@itsmiso-ai

Copy link
Copy Markdown
Contributor

What

Implements the repository-side development bootstrap per the shared Courier #414 contract (now merged via courier#446), which unblocked this issue per the 2026-10-20 grooming refresh.

  • .mise/config.toml — min_version = "2026.10.13", [settings] locked = true, [tools] node = "24", and the shared task names:
    • bootstrap — npm ci --include=dev + npx prisma generate (mirrors .github/actions/setup-node/action.yml exactly).
    • check — npm run lint + npm run typecheck (mirrors the CI lint/typecheck jobs).
    • test — npm run test (vitest).
  • .mise/mise.lock — committed lockfile pinning node 24.22.1 with sha256 + URL for 5 platforms (linux-arm64, linux-x64, macos-arm64, macos-x64, windows-x64). Generated with digest-verified mise 2026.10.13.
  • README + AGENTS.md: documented the noninteractive setup and targeted verification commands without duplicating version claims (exact pin lives in the lockfile only).

Contract fit (Courier #414 shipped behavior, read from misospace/courier main)

  • Contract is exactly .mise/config.toml + .mise/mise.lock as regular files; Courier executes only mise run bootstrap in the materialized approved base revision and captures the environment via mise x -- env -0. Verified here: mise x -- env -0 exposes the mise-managed node (.../installs/node/24.22.1/bin/node, v24.22.1, npm 11.19.1), so the PATH delta reaches later tasks.
  • check/test are human/CI-facing; Courier never runs them. Both delegate to the authoritative npm run commands, preserving "existing repo validation commands remain authoritative."
  • Repo carries no git-hook installation, no global config mutation, and nothing interactive anywhere in the new tasks.

Invariants kept, and how each related path enforces the same rule

  1. Bootstrap needs no DATABASE_URL and connects to no database — kept: tasks invoke only npm ci and prisma generate; prisma.config.ts already tolerates an unset URL (verified by inspection, and bootstrap ran with DATABASE_URL unset in this lane). No migration/db push/groomer invocation anywhere in the new config.
  2. No Git-hook installation — kept: unlike the joryirving/containers reference (whose postinstall mutates git hooks), nothing here touches .git/hooks; package.json postinstall is unchanged and only runs prisma generate.
  3. Lockfile is never mutated by setup — kept: npm ci refuses lockfile changes (unlike npm install), and [settings] locked = true stops mise from implicitly rewriting .mise/mise.lock; after three bootstrap runs git status showed zero tracked-source or lockfile mutation.
  4. Downloads are pinned/locked — kept: every lockfile entry carries sha256 + URL; the two checksum-less musl entries emitted by mise lock (no upstream SHASUMS exist for v24.22.1 unofficial builds) were removed, and with locked = true an unlisted platform fails closed instead of downloading unpinned. The repo's own image is glibc (node:24-bookworm-slim), unaffected.
  5. Idempotency / no test/format side effects — kept: bootstrap runs no tests and no formatter; three consecutive runs exited 0.
  6. CI equivalence — check = the CI lint + typecheck job commands; test = the CI test job command; .github/actions/setup-node/action.yml unchanged and still authoritative in CI.

Local validation receipts (lane: linux-x64, mise 2026.10.13, node 24.22.1)

  • mise binary downloaded and SHA256-verified against the release SHASUMS256.txt (b775d3fe…).
  • mise lock generated the lockfile; mise lock --dry-run re-validates all 5 platform entries cleanly and does not re-add musl.
  • mise run bootstrap ×3 → exit 0 (run 1 installed node from the locked URL+checksum; postinstall + explicit prisma generate both succeeded with DATABASE_URL unset).
  • mise run check (final head) → exit 0 (lint + typecheck).
  • mise run test (final head) → exit 0 — 202 files / 5085 tests passed, 24 skipped.
  • git status after all runs: only the intended files; no tracked-source mutation.

Limitations: not re-run on macOS/Windows/arm64 (lock entries were generated, not exercised); musl behavior (fail-closed) is by configuration, not empirically exercised. CI, Docker image build, and human/AI review remain pending — left to the operator.

Closes #1291

Courier added 2 commits October 21, 2026 11:53
Add the .mise/config.toml + .mise/mise.lock development-bootstrap contract
(Courier #414): Node pinned with locked checksums, idempotent bootstrap
(npm ci + Prisma client generation), and check/test tasks delegating to the
authoritative npm scripts. No DATABASE_URL, migrations, git hooks, global
config mutation, tests, or formatting during bootstrap.
…ding

Add [settings] locked = true so mise fails closed on platforms absent from
the lockfile (musl has no upstream checksums for the pinned Node) and never
implicitly rewrites .mise/mise.lock, keeping the committed lock byte-stable
against the bootstrap contract's approval check. Point the README at
mise.lock for the exact pin.
its-saffron[bot]

This comment was marked as outdated.

@joryirving joryirving left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Secondary review on exact head 6b62a212454d135365ca0e7b1453170d2102bb7d: REQUEST CHANGES for the legitimate primary-review documentation finding. README says the non-mise commands are the equivalent manual steps, but then uses npm install; that can resolve/update dependencies and rewrite the lockfile, unlike the shipped bootstrap contract's lockfile-backed npm ci --include=dev. Please change the manual path to npm ci --include=dev (and keep Prisma generation as documented) so the fallback actually preserves the reproducible contract. I found no independent hard blocker. All exact-head CI is green.

Courier added 2 commits October 21, 2026 19:39
The no-mise fallback claimed to be equivalent to the bootstrap but used
'npm install', which can rewrite package-lock.json. Use the same
lockfile-backed install the bootstrap runs (addresses PR #1337 review).
@itsmiso-ai

Copy link
Copy Markdown
Contributor Author

Addressed the review finding on head 6b62a21 (both the AI review nit and the REQUEST-CHANGES): the "Without mise, equivalent manual steps" block in README now uses npm ci --include=dev (9c1a102), matching what .mise/config.toml's bootstrap actually runs, so the fallback can no longer rewrite package-lock.json. Prisma generation step unchanged.

This head also merges current main (includes #1333, #1336, #1339).

Local validation on 9c1a102 (linux-x64, node v24.22.0 lane):

  • npm ci --include=dev → exit 0 (empirically exercises the corrected documented path)
  • npm run lint → 0 errors (1 pre-existing warning in src/app/login/page.tsx, untouched by this PR)
  • npm run typecheck → exit 0
  • npm run test → exit 0, 202 files / 5095 tests passed, 24 skipped

CI on the new head is pending; re-review left to the operator/reviewers.

@itsmiso-ai
itsmiso-ai requested a review from joryirving October 21, 2026 19:48

@its-saffron its-saffron Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AI Automated Review

Full PR review.

Analysis engine: MiniMax-M3.1-Flash (anthropic) — primary route · pr-reviewer-action v3.7.0

Recommendation: Approve—the current head addresses the outstanding review and implements issue PR 1291 without an identified blocker or major issue.

Linked Issue Fit

  • The configuration provides noninteractive bootstrap, check, and test tasks; uses lockfile-backed npm ci --include=dev; generates the Prisma client locally; and avoids DATABASE_URL, migrations, Git hooks, formatting, and implicit tests as required by issue PR 1291.
  • The README and AGENTS.md document setup and targeted verification while leaving the exact Node version in .mise/mise.lock.

PR Claims

  • Claim 1: Unverified—12/12 cited locations are consistent with the local bootstrap commands, but the claimed exact equivalence with .github/actions/setup-node/action.yml cannot be independently checked because that file's contents are absent from the corpus.
  • Claim 2: Unverified—8/8 cited locations describe the intended regular-file contract, but Courier's external execution and environment-capture behavior is outside the supplied evidence.
  • Claim 3: Unverified—6/6 local task-definition locations match the claim, but whether Courier never runs check or test cannot be proven from this repository corpus.
  • Claim 4: Held: 5/5—both tasks delegate directly to the authoritative npm run lint, npm run typecheck, and npm run test commands.
  • Claim 5: Unverified—7/7 local references avoid an explicit database operation, but the unset-DATABASE_URL runtime claim lacks independently reproducible tool evidence; no contradictory defect was found.

Outstanding Human Review

  • Review 5601289523 is addressed: README.md:406 now uses npm ci --include=dev in the equivalent manual path, preserving the lockfile-backed contract.

Requirement Ledger

  • req-e589bfe1ad7c is satisfied by successful Lint and Typecheck CI checks on head 9c1a102.

Tool Harness Findings

  • No native tool calls were made; this review relies on the supplied PR corpus.

Unknowns or Needs Verification

  • The skipped external sources and absent setup-action/Courier source prevent independent confirmation of the external equivalence and non-execution claims; these do not show a defect in this PR.

Outstanding Human Change Requests

  • @​joryirving's change request (6b62a21, head moved since) judged addressed at this head: README.md:406 now specifies `npm ci --include=dev` instead of `npm install`, matching `.mise/config.toml:14` and preventing the documented fallback from rewriting `package-lock.json`.

@itsmiso-ai

Copy link
Copy Markdown
Contributor Author

Courier: already addressed (run courier-d0c108861b87dcf59c1bbf6ac2515001)

PR #1337 (misospace/dispatch) is already complete on the run branch courier/misospace/dispatch/issue-1291 at head 9c1a102, which matches local HEAD, origin remote, and the PR head exactly. (1) All existing review feedback is addressed on this head: joryirving's CHANGES_REQUESTED (review 5601289523, on 6b62a21) and the AI-review minor nit both asked for README's 'equivalent manual steps' to use npm ci --include=dev instead of npm install; README.md:407 now contains npm ci --include=dev, and the follow-up AI review on 9c1a102 (review 5605493705) is APPROVED with review_result 'clean', explicitly judging the change request addressed. No unresolved review threads exist (0 review comments). (2) CI on the exact head 9c1a102 is fully green: all 13 check runs succeeded (Lint, Typecheck, Tests, Build, Docker Build, Docker Build (MCP), smoke, review, npm audit, Coverage, Database migrations, Database integration, Workflow lint). (3) Local validation receipts for this exact head were recorded on the PR (comment 6325049816): npm ci --include=dev exit 0, npm run lint 0 errors, npm run typecheck exit 0, npm run test exit 0 (202 files / 5095 tests passed, 24 skipped); the working tree is unchanged since those receipts, so they remain valid and were reused. Remaining items are external only: joryirving's re-review (human) and operator verification; the 'blocked' mergeable_state reflects the pending human re-review, not any unfinished work. PR is open and non-draft.

@its-saffron

its-saffron Bot commented Oct 21, 2026

Copy link
Copy Markdown
Contributor

⏸️ This PR fix item reported an external wait without a verifiable dependency, so it was parked fail-closed (#1250). An operator can requeue it once a concrete dependency is identified.

Reason: PR review: CHANGES_REQUESTED

Outcome: invalid_wait

Worker executions: 2

Enqueue rows: 24

Enqueues by lane:

  • NORMAL: 24

Final failure: Fail-closed park: external wait without a verifiable dependency (externalWait must be an object); operator requeue required (#1250). no changes pushed; queued feedback resolution is not verified

Last attempt: Secondary review on exact head 6b62a212454d135365ca0e7b1453170d2102bb7d: REQUEST CHANGES for the legitimate primary-review documentation finding. README says the non-mise commands are the equivalent manual steps, but then uses npm install; that can resolve/update dependencies and rewrite the lockfile, unlike the shipped bootstrap contract's lockfile-backed npm ci --include=dev. Please change the manual path to npm ci --include=dev (and keep Prisma generation as documented) so the fallback actually preserves the reproducible contract. I found no independent hard blocker. All exact-head CI is green.

Latest note: no changes pushed; queued feedback resolution is not verified

Posted automatically by Dispatch on 2026-10-21T20:07:49.675Z

@joryirving joryirving left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Secondary re-review on exact head 9c1a102b93b73b9877a0d7b59463f442b9728329: APPROVE. The one legitimate prior finding is fixed: README's manual equivalent now uses npm ci --include=dev, matching the locked bootstrap contract rather than permitting lockfile mutation. The mise tasks themselves remain noninteractive and narrowly scoped; no independent hard blocker found. Exact-head CI, image build, smoke, and security checks are green.

@joryirving
joryirving merged commit c69e53e into main Oct 22, 2026
13 checks passed
@joryirving
joryirving deleted the courier/misospace/dispatch/issue-1291 branch October 22, 2026 02:15
@its-miso its-miso Bot mentioned this pull request Oct 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

chore(dev): add reproducible Node development bootstrap

2 participants