Skip to content

ci(scaffold-e2e): give the image run an explicit database (Refs #30120) - #30714

Merged
os-zhuang merged 1 commit into
mainfrom
claude/issue-30120-scaffold-e2e-db-url
Nov 6, 2026
Merged

os-zhuang merged 1 commit into
mainfrom
claude/issue-30120-scaffold-e2e-db-url

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Requested by Elon · project thread

Refs #30120
Clause-②: no
Metadata-protocol: none
Skills-docs: none — CI wiring only

维护者速读

What changes

One line in .github/workflows/scaffold-e2e.yml, step "Docker build and run (scaffolded Dockerfile)": the docker run -d --name e2e ... call gains -e OS_DATABASE_URL="iframe.php?url=file%3A%2Ftmp%2Fe2e.db" before the two secret lines.

Why: ruling A3 on #30120 makes the official image refuse to start unless OS_DATABASE_URL, OS_AUTH_SECRET and OS_SECRET_KEY are all set explicitly (an explicit file: URL passes). This step sets only the two secrets, so once the #30120 main PR lands, its scaffold-e2e job goes red. The step only probes health, so an explicit SQLite file inside the container is enough. Until #30120 lands the variable is simply unused, so this PR is safe to land first; it must land before or together with the #30120 main PR.

Verification

  • Hunk located by text on origin/main @ 788715e; the patch applies cleanly at its recorded position.
  • Pins: git grep for --name e2e hits only the workflow itself. packages/create-objectstack tests that extract the workflow's real run: blocks pass on the branch head 6a8d5ba: scaffold-e2e-boot-probe.test.ts, template-ci-workflow.test.ts, runtime-image.test.ts — Test Files 3 passed, Tests 40 passed (lock VERDICT command-exit 0).
  • Derived gates (node scripts/pm/dispatch-gates.mjs --commands) on head 6a8d5ba: 38 commands, all exit 0; --ran reconciliation: 38 derived, 38 run, 0 NOT-MEASURED, 0 UNRUN.
  • No changeset: the diff publishes nothing (skip-changeset).

Generated by Claude Code

🤖 Generated with Claude Code

The "Docker build and run (scaffolded Dockerfile)" step starts the
scaffolded image with only OS_SECRET_KEY and OS_AUTH_SECRET. Once the
official image refuses to start without an explicit OS_DATABASE_URL,
this health-only probe would go red. Pass an explicit SQLite file URL;
until then the variable is simply unused.

Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016WV4cytQjG9X1CrCgytUM5
@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

domain:server#3 · os-elon-musk · session_016WV4cytQjG9X1CrCgytUM5

Contract review

Served-tier: CONTRACT_REVIEW_TIER
Head-sha: 6a8d5ba86e0572df87abc5a1dc503e5e00911ce6
Local-runs: none
Scope: .github/workflows/scaffold-e2e.yml + docker/Dockerfile (on origin/main badf24df and on claude/project-thread-dj7jk6), packages/cli/src/commands/start.ts (both trees: the durability refusal the main #30120 PR adds), packages/runtime/src/resolve-project-database.ts (resolveProjectDatabaseUrl), packages/runtime/src/standalone-stack.ts (sqliteFilenameFromUrl), .github/workflows/docker-publish.yml (the only other workflow that runs the image)

Inputs read: card #30120 body and all 11 comments (ruling A3 = 6634240777; the seat's claim 6671522963 and its amendment 6671390478 naming this one-line separate PR); PR #30714 body, file list (one file, +1/-0) and net diff vs main (merge-base 788715ef, 1 ahead / 7 behind, applies cleanly); the 60 check-runs on this head.

① Derived judgments

  • Accept-set / public surface: none. The diff is one -e OS_DATABASE_URL="iframe.php?url=file%3A%2Ftmp%2Fe2e.db" line inside the docker run of step "Docker build and run (scaffolded Dockerfile)". No package, schema, export or documented route moves. The PR body's Clause-②: no / Metadata-protocol: none lines are right; a workflow has neither face.
  • Does the value satisfy the refusal the main PR adds? Yes. On claude/project-thread-dj7jk6, start.ts reads OS_DEPLOYMENT_DURABILITY_CHECK_ENABLED (set true by that branch's docker/Dockerfile ENV) and refuses when missingDurableVariables({databaseSource, authSecretSet, secretKeySet}) is non-empty. databaseSource comes from resolveProjectDatabaseUrl: an OS_DATABASE_URL in the environment answers source: 'env' (step 1 of the resolution, before the config datasource and the two defaults), and isDefaultedDatabase is true only for 'unified-default' / 'legacy-file'. The two openssl rand -hex 32 secrets are non-empty after trim(). So missing is [] and the boot proceeds. The check runs before readOrCreateAuthSecret and before any database open, so nothing is written on a refusal either way.
  • Is /tmp writable by the image's user? Yes. The image is FROM node:22-slim with USER node; /tmp in that base is the usual mode-1777 directory, and the Dockerfile's install RUN only removes its own /tmp/os-installer-npm. sqliteFilenameFromUrl('file:/tmp/e2e.db', 'sqlite') strips file: and yields /tmp/e2e.db; the SQLite sidecars (-wal, -shm) land in the same world-writable directory. The green Scaffold with repo dist run on this head already ran this exact docker run against the image built from main and probed health, so the path is measured, not inferred.
  • Any other step that runs the image without the three variables? No. --name e2e / e2e-app occur only in this step. The two other boots in the workflow (npx os start --artifact ./dist/objectstack.json in scaffold-local and in registry-canary) run on the runner host, where the image's ENV signal is absent and the check stays off. docker-publish.yml runs the published image for os --version and a node_modules listing only, never os start.
  • "The image does not read it today, zero behaviour change" (PR body) is overstated. resolveProjectDatabaseUrl reads OS_DATABASE_URL today too: on main the step's SQLite file moves from the unified default under the node user's home to /tmp/e2e.db. The health probe is indifferent to where the file is, so the conclusion (safe to land first) holds; only the wording is wrong. Prose, not tree.
  • Ordering claim holds. Until the main PR lands the variable is harmless; once this line is on main, the main PR's pull_request run checks out the merge commit and so carries this line, which is why it must land before or with it.

② Semver level

skip-changeset is right: the PR publishes nothing from any released package (one governed workflow file). No changeset is owed. Check-runs on 6a8d5ba8: 60 runs, every one completed with success or skipped, including Scaffold with repo dist, Governed Surface Queue Guard, Check Changeset, Lint · CI, release & engine gates and PR-body guards; the commit-status API answers pending with zero statuses (no status contexts exist), which is not a red.

③ Boundary flags

  • Dev flags / open_questions: none on the PR; the card's claim 6671390478 names this line and its reason.
  • Author is objectstack-fleet[bot]; no out-of-relay login to name.
  • Governed path: .github/workflows/** is Tier H. This record is the contract-tier review; the human approval the PR body asks for (os-zhuang or hotlong) is still owed before landing, and the main [Decision] os start in production mode runs on a local SQLite file and self-generated secrets, with no warning #30120 PR must not land ahead of it.
  • Independence: rendered by an isolated contract-review subagent fed the card, the PR, the diff, the cited trees and the check-runs, not the seat's conclusions; adopted by the seat named in Reviewed-by:.
  • The PR is a draft and carries no needs:contract-review label; that is the dispatch seat's bookkeeping, not a finding.

④ Design judgment

hits = .github/workflows/scaffold-e2e.yml. The change holds against the code it cites and the scenario it is accepted against: the one leg that runs the official image gains the one variable the ruled refusal will demand that it did not already pass, with a value the resolver classifies as an explicit choice, pointing at a directory the image's non-root user can write, for a container that only has to answer /api/v1/health and is then removed. A mounted volume would add nothing to a health probe; :memory: would depend on the retired-engine refusal text and buys nothing over a file. The three names stay in step with missingDurableVariables by construction (the refusal names exactly OS_DATABASE_URL, OS_AUTH_SECRET, OS_SECRET_KEY).

Findings (none must-fix):

Implemented-by: claude/issue-30120-scaffold-e2e-db-url
Reviewed-by: session_016WV4cytQjG9X1CrCgytUM5

VERDICT: PASS

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

domain:server#3 · os-elon-musk · session_016WV4cytQjG9X1CrCgytUM5

ACCEPT · Refs #30120 · 2026-11-05T23:27Z · Head-sha: 6a8d5ba86e0572df87abc5a1dc503e5e00911ce6

维护者速读

席位意见: 建议批准。一行、可逆、已在本 head 的 CI 里实测跑通。

席位核对

  1. Shape: one file, +1/−0, .github/workflows/scaffold-e2e.yml step "Docker build and run (scaffolded Dockerfile)": -e OS_DATABASE_URL="iframe.php?url=file%3A%2Ftmp%2Fe2e.db". Diff read at this head.
  2. Premise, measured: contract review 6672153152 (PASS, CONTRACT_REVIEW_TIER, this head) traced the value through resolveProjectDatabaseUrl (source: 'env') against the main PR's refusal on claude/project-thread-dj7jk6, /tmp writable under USER node, and no other workflow step running the image without the three variables.
  3. Gates: 38 derived, 38 exit 0 (--ran reconciled). Check-runs on this head: 47 success, 15 skipped, 0 failed.
  4. Accepted deviations / corrections: PR body correction — "the image does not read it today / zero behaviour change" is overstated: the resolver reads OS_DATABASE_URL today and the step's SQLite file moves to /tmp/e2e.db; the health probe is indifferent, so the landing order holds. Review should-fix 1 (an explanatory comment on the new line) is dropped: dropping the line would turn this job red on the next run, which names the cause, and a comment-only push would move the approved head.
  5. Out of scope: none.
  6. Landing: check-governed-merges: governed (Tier H). pm:awaiting-merge added; reviewers os-zhuang and hotlong requested in this stroke. Lands before or with fix(cli, service-settings, console): the official image refuses to start without its database and secrets; administrators see what a production server keeps on its own disk #30720.

@objectstack-fleet objectstack-fleet Bot added the pm:awaiting-merge PR only: landing waits on the maintainer's own review and merge (SKILL.md 复核 ②); never on an issue label Nov 5, 2026
@os-zhuang
os-zhuang marked this pull request as ready for review November 6, 2026 00:55
@os-zhuang
os-zhuang enabled auto-merge November 6, 2026 00:56
@os-zhuang
os-zhuang added this pull request to the merge queue Nov 6, 2026
Merged via the queue into main with commit 3dcea42 Nov 6, 2026
68 checks passed
@os-zhuang
os-zhuang deleted the claude/issue-30120-scaffold-e2e-db-url branch November 6, 2026 01:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci/cd pm:awaiting-merge PR only: landing waits on the maintainer's own review and merge (SKILL.md 复核 ②); never on an issue size/xs skip-changeset PR has no user-facing published change; bypasses the changeset gate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants