Skip to content

fix(gate): close five silent-pass holes in x verify, plus the CLI surface agents actually hit - #83

Merged
sebyx07 merged 1 commit into
mainfrom
fix/gate-and-cli
Aug 15, 2026
Merged

fix(gate): close five silent-pass holes in x verify, plus the CLI surface agents actually hit#83
sebyx07 merged 1 commit into
mainfrom
fix/gate-and-cli

Conversation

@sebyx07

@sebyx07 sebyx07 commented Aug 15, 2026

Copy link
Copy Markdown
Contributor

Tier 5 and the build tooling — the last of a four-PR audit sweep, and the one that matters most: several findings are holes in bun run verify itself. A gate step that silently passes is worse than no step, because it is read as coverage.

Stacked on #80 — the doctor check consumes a storage export from it, and noNonNullAssertion could only be raised once its ids.ts fix landed.

Gate holes closed

Where The hole
cli/src/cmd-verify.ts:147 The budgets step skipped its per-route JS/LCP half entirely when .x/build-stats.json was absent — and .x/ is gitignored. So it has never run, in CI or on either gated app, and reported green throughout. bunx create-ultimate myapp && x verify gives every generated route a budget: {js:'60kb', lcp:2500} and weighs none of them. budgets.ts' own docstring: "A declared budget with no measurement is a finding, never a pass … exactly the false green axiom 5 exists to prevent." An absent stats file is now X_BUDGET_UNMEASURED per budgeted route. Both gated apps go red as a result, so budgets is pinned in scripts/lib/gated-apps.ts for each, naming the x build-before-the-gate work that closes it — the honest outcome, rather than restoring the silent pass.
scripts/boundaries.ts:44 A relative cross-package import was invisible to the tier checkscopedName() only recognised @ultimat3/… specifiers. The repo already contained one, with a comment describing it as a deliberate evasion: cli/src/serve.live.test.ts imported ../../testing/src/sealed-network precisely because the package specifier would be refused. Any package could bypass its tier with ../../<pkg>/src/x. Relative specifiers now resolve back to a package before the tier check.
scripts/boundaries.ts:56 Bun.Transpiler.scanImports erases type-only imports, so a type-only upward import was not a build error — contradicting CLAUDE.md's "Enforced by bun run boundaries; a violation is a build error". packages/core could import type from packages/cli and the check would report clean. Zero live instances, so this was latent; now caught by a second pass over the source with the type keyword rewritten (not a regex, so template literals and doc blocks are not false positives).
biome.json The lint step printed "biome: no any, no default exports, no raw colours" — and enforced neither. noDefaultExport is not in Biome's recommended and was never enabled; Biome ignores .scss entirely, so all 64 stylesheets under packages/ui/src were unlinted. noDefaultExport is now error, noNonNullAssertion is raised from warn to error (biome check exits 0 on warnings, so foo! was unenforced), and the step's summary now names only what is actually enforced.
ui/src/tokens/tokens.test.ts:88 The only raw-colour enforcement in the repo checked exactly three files, none of them a component stylesheet — the 51 .module.scss files under components/ were covered by neither this test nor Biome. Now globs every .scss under packages/ui/src except the canonical token files, matches rgb(/hsl( as well as hex, and asserts it found >50 files so an empty glob cannot pass.
x.verify.json The suite floor omitted job and eval, both of which apply at the repo root — so deleting those suites turned them into silent skips and the gate stayed green at "17/17 (1 skipped)".
cli/src/test-select.ts:19 TEST_GLOB was **/*.test.ts, missing .test.tsx — a JSX test would be excluded from the gate's unit/contract/job steps while bun run test at the root still ran it.
cli/src/source-files.ts:5 packages/*/e2e/** was outside both SOURCE_GLOBS and the boundary collector, so filesize, errors and boundaries never saw three real source directories.
scripts/boundaries.ts:194 The shared/ leaf rule globbed examples/* only, so the deployed demo app — the one CI publishes an image for on every push to main — was checked by nothing blocking.
scripts/roadmap.ts:44 Milestone numbers came from a hardcoded map, so "every milestone row carries a status marker" only covered 0–11. Appending a milestone 12 with no marker passed. Now parses the table itself; a row with no artifacts entry is X_ROADMAP_MILESTONE_UNTRACKED.
scripts/release.ts:98 --bump was cast to its union with no validation: --bump majr fell through to 1.2.1, so a breaking change ships as a patch. --version 1.2 wrote "version": "1.2" into all 29 manifests. report() was also called with ok: true unconditionally, so pre-existing skew findings exited 0.
cli/src/workspace-checks.ts:97 X_RELEASE_VERSION_SKEW compared packages only to each other, so it had no anchor. Nine tags (v1.3.0v1.10.1) have been cut against 29 packages all still stamped 1.2.0 — the gate is green while the tag lies, and a real publish would die EPUBLISHCONFLICT on all 29. package-shape gains a --release <version> mode; bun run scripts/release.ts --check <version> asserts the lockstep version equals the version being published. Verified live: --check 1.2.0 passes, --check 1.10.1 reports 141 findings and exits 1. .github/workflows/release.yml still needs the call added before the publish loop — that file is outside this PR and is tracked separately.

CLI correctness — the agent-facing surface

Where Defect
cli/src/dispatch.ts:51 The parse-failure path read argv.includes('--json'), so -j was ignored and errors rendered as prose on stdout. x doctor -j --bogusflag and x nonexistentcmd -j both emit human text — exactly the two cases an agent hits while always passing -j, and JSON.parse throws on the result.
cli/src/templates/route.ts:25 x g route "posts/[slug]" silently scaffolded a static route. Every segment went through kebab(), which strips [ and ], so the agent got apps/web/app/posts/slug/page.tsx with exit 0 and no warning — and a generated test hard-coding params: {}.
cli/src/cmd-generate.ts:376 A missing <name> was reported as X_CLI_UNKNOWN_COMMAND for a command form that is known, with fix: x g route <name> — which pasted into bash is a redirect. Now a missing-positional error with a concrete runnable example. Swept the same shape across mcp-errors.ts (14 entries), errors.ts (5) and cmd-planned.ts: any <placeholder> now sits behind a #, never in the runnable half.
cli/src/templates/scaffold-repo.ts:225 x new scaffolded two house-rule violations into every generated app: a restated Money interface (CLAUDE.md: "one declaration in @ultimat3/schema … never restated") and a bare RangeError. Flagged independently by two auditors. Now re-exports MoneyValue as Money and throws a generated UltimateError subclass.
cli/src/cmd-doctor.ts:165 --port was parseInt'd unvalidated, so a bad value turned the port probe into a check that cannot failx doctor --port abc reports the environment shippable while 3000 is occupied. Same at cmd-dev.ts:268 (NaN to Bun.serve binds an arbitrary port) and cmd-test.ts (--workers 4abc accepted as 4, while cmd-verify.ts' comment claimed it was refused). One readIntFlag now serves all four.
cli/src/cmd-doctor.ts New X_STORAGE_SECRET_DEV finding mirroring the existing dev-cursor-secret check, wired to usesDevStorageSecret() from #80.
cli/src/dev-runtime.ts:150 startServices falls back to the local disk driver whenever S3_ENDPOINT/S3_BUCKET are unset, which after #80 throws at boot in production. Made that failure an instruction: it leads with the storage choice ("no S3_ENDPOINT/S3_BUCKET, so this production process fell back to the embedded disk at …") and names object storage first. Deliberately not an outright ban on the local disk in production — a single-node Compose deploy on a mounted volume with a real secret is a legitimate rung on the scale ladder, and refusing it is a deploy-shape decision, not a security fix.
cli/src/templates/action.ts:93 Every generated feature shipped code: 'X_INVOICE_NOT_FOUND' beside docs: '…/errors/X_NOT_FOUND' — following the link landed on a different code's page.
cli/src/cmd-generate.ts:400 --dry-run reported summary: "wrote 4 file(s)" while data.dryRun was true.
cli/src/cmd-errors.ts:88 x errors with no code reported a --code flag that does not exist; an agent reading the cause literally gets a second error.
scripts/new-package.ts:98 Every scaffolded package documented "may import tiers 0-5" regardless of --tier, because the allowed range was derived from the tier table the new package is not yet in. --tier abc produced "Tier NaN". The file had no test; it has one now.
scripts/lib/tiers.ts:46 create-ultimate resolved to the unlisted tier, so its declared → cli edge restricted nothing — it could import all 28 packages. Now pinned above the table with that edge as its only permitted import.
scripts/lib/run.ts:18 A bare RangeError at the scripts' single subprocess boundary, where cli/src/exec.ts does the identical guard correctly and explains why.
scripts/scaffold-smoke-overrides.ts Wrote prose to stdout, took no --json, and exited 1 with no code — and if it found no workspace manifests it wrote {}, silently making the smoke job install from the npm registry instead of the working tree. That is now a hard error.
create-ultimate/src/bin.ts:11 The only published entry point using process.stdout.write + process.exit, the combination both cli/src/bin.ts and scripts/lib/log.ts carry comments explaining truncates at 64KB under a pipe.
ui/src/components/date-time-view.ts:42 toDate fell back to new Date(value), whose parse of an offset-less datetime uses the host's zone — an ambient default in the one package that forbids them. Every formatting path was correctly zoned; only the parse was not.
scripts/help.ts:21 Claimed 16 verify steps against 17, and omitted the app gate — a headline command in CLAUDE.md — from the catalogue an agent reads to discover the repo.

Not closed, and named

An undriven e2eTest still reports green rather than skipped. The filename half is fixed (the generated assertion now lands in page.e2e.test.ts, which the e2e step actually selects on) and hasE2eDriver() is exported so the seam has one name — but the driver registers inside the bun test child and the step's only channel is an exit code, which is 0 on skips. Making it red would turn a scaffolded app's e2e step red on x g route output, and that blast radius could not be proven here. test-types.ts' docstring no longer claims behaviour nothing implements.

New error codes

X_STORAGE_SECRET_DEV, X_ROADMAP_MILESTONE_UNTRACKED, X_SCAFFOLD_OVERRIDES_EMPTY — documented, registered, in the manifest. X_BUDGET_UNMEASURED already existed and was already documented; only the code path that emits it was missing.

Behaviour changes

x doctor --port / x dev --port / x test --workers now refuse bad values with X_CLI_BAD_FLAG instead of coercing them. Same surface, stricter contract; wiki/Error-Codes.md's row for that code is widened to name positionals.

Gate

bun run verify green on this branch: 14/17, same three structural skips as main. bunx biome check . clean across 3547 files with both new rules at error.


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is disabled.

@coderabbitai

coderabbitai Bot commented Aug 15, 2026

Copy link
Copy Markdown

Warning

Review limit reached

You’ve reached a temporary PR review limit under our Fair Usage Limits Policy.

Your recent review volume is higher than typical usage, so adaptive limits are currently applied.

Next review available in: 9 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Path: .coderabbit.yml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 1693effb-62c9-4ca2-b35b-c32ea0337c77

📥 Commits

Reviewing files that changed from the base of the PR and between 9f4be65 and d9a5c8f.

📒 Files selected for processing (79)
  • CLAUDE.md
  • biome.json
  • framework.manifest.json
  • packages/cli/CLAUDE.md
  • packages/cli/README.md
  • packages/cli/src/app-manifest.test.ts
  • packages/cli/src/bin.ts
  • packages/cli/src/budgets.test.ts
  • packages/cli/src/cmd-dev.ts
  • packages/cli/src/cmd-doctor.test.ts
  • packages/cli/src/cmd-doctor.ts
  • packages/cli/src/cmd-errors.test.ts
  • packages/cli/src/cmd-errors.ts
  • packages/cli/src/cmd-generate.test.ts
  • packages/cli/src/cmd-generate.ts
  • packages/cli/src/cmd-planned.test.ts
  • packages/cli/src/cmd-planned.ts
  • packages/cli/src/cmd-test.ts
  • packages/cli/src/cmd-verify.ts
  • packages/cli/src/dev-runtime.ts
  • packages/cli/src/dispatch.test.ts
  • packages/cli/src/dispatch.ts
  • packages/cli/src/error-codes.ts
  • packages/cli/src/errors.ts
  • packages/cli/src/flag-number.test.ts
  • packages/cli/src/flag-number.ts
  • packages/cli/src/generate-catalogs.test.ts
  • packages/cli/src/generate-output.test.ts
  • packages/cli/src/index.ts
  • packages/cli/src/mcp-errors.test.ts
  • packages/cli/src/mcp-errors.ts
  • packages/cli/src/messages.ts
  • packages/cli/src/parse.ts
  • packages/cli/src/serve.live.test.ts
  • packages/cli/src/source-files.test.ts
  • packages/cli/src/source-files.ts
  • packages/cli/src/templates/action.ts
  • packages/cli/src/templates/route.test.ts
  • packages/cli/src/templates/route.ts
  • packages/cli/src/templates/scaffold-db-package.ts
  • packages/cli/src/templates/scaffold-domain-package.ts
  • packages/cli/src/templates/scaffold-mcp-package.ts
  • packages/cli/src/templates/scaffold-package-shape.ts
  • packages/cli/src/templates/scaffold-repo.ts
  • packages/cli/src/templates/scaffold-ui-package.ts
  • packages/cli/src/test-select.test.ts
  • packages/cli/src/test-select.ts
  • packages/cli/src/workspace-checks.test.ts
  • packages/cli/src/workspace-checks.ts
  • packages/cli/src/write-line.ts
  • packages/create-ultimate/src/bin.ts
  • packages/testing/CLAUDE.md
  • packages/testing/README.md
  • packages/testing/src/index.ts
  • packages/testing/src/test-types.ts
  • packages/ui/src/components/date-time-view.test.ts
  • packages/ui/src/components/date-time-view.ts
  • packages/ui/src/errors.ts
  • packages/ui/src/tokens/tokens.test.ts
  • scripts/boundaries.test.ts
  • scripts/boundaries.ts
  • scripts/help.test.ts
  • scripts/help.ts
  • scripts/lib/gated-apps.ts
  • scripts/lib/run.test.ts
  • scripts/lib/run.ts
  • scripts/lib/script-error.ts
  • scripts/lib/tiers.ts
  • scripts/new-package.test.ts
  • scripts/new-package.ts
  • scripts/release.test.ts
  • scripts/release.ts
  • scripts/roadmap.test.ts
  • scripts/roadmap.ts
  • scripts/scaffold-smoke-overrides.test.ts
  • scripts/scaffold-smoke-overrides.ts
  • scripts/verify.test.ts
  • wiki/Error-Codes.md
  • x.verify.json

Comment @coderabbitai help to get the list of available commands.

…face agents actually hit

Tier 5 and the build tooling — the last of a four-PR audit sweep, and the one that matters most: **several findings are holes in `bun run verify` itself.** A gate step that silently passes is worse than no step, because it is read as coverage.

**Stacked on #80** — the doctor check consumes a storage export from it, and `noNonNullAssertion` could only be raised once its `ids.ts` fix landed.

## Gate holes closed

| Where | The hole |
|---|---|
| `cli/src/cmd-verify.ts:147` | **The `budgets` step skipped its per-route JS/LCP half entirely when `.x/build-stats.json` was absent — and `.x/` is gitignored.** So it has never run, in CI or on either gated app, and reported green throughout. `bunx create-ultimate myapp && x verify` gives every generated route a `budget: {js:'60kb', lcp:2500}` and weighs none of them. `budgets.ts`' own docstring: "A declared budget with no measurement is a finding, never a pass … exactly the false green axiom 5 exists to prevent." An absent stats file is now `X_BUDGET_UNMEASURED` per budgeted route. **Both gated apps go red as a result**, so `budgets` is pinned in `scripts/lib/gated-apps.ts` for each, naming the `x build`-before-the-gate work that closes it — the honest outcome, rather than restoring the silent pass. |
| `scripts/boundaries.ts:44` | **A relative cross-package import was invisible to the tier check** — `scopedName()` only recognised `@ultimat3/…` specifiers. The repo already contained one, with a comment describing it as a deliberate evasion: `cli/src/serve.live.test.ts` imported `../../testing/src/sealed-network` precisely because the package specifier would be refused. Any package could bypass its tier with `../../<pkg>/src/x`. Relative specifiers now resolve back to a package before the tier check. |
| `scripts/boundaries.ts:56` | **`Bun.Transpiler.scanImports` erases type-only imports, so a type-only upward import was not a build error** — contradicting CLAUDE.md's "Enforced by `bun run boundaries`; a violation is a build error". `packages/core` could `import type` from `packages/cli` and the check would report clean. Zero live instances, so this was latent; now caught by a second pass over the source with the `type` keyword rewritten (not a regex, so template literals and doc blocks are not false positives). |
| `biome.json` | The `lint` step printed "biome: no any, **no default exports**, **no raw colours**" — and enforced neither. `noDefaultExport` is not in Biome's `recommended` and was never enabled; Biome ignores `.scss` entirely, so all 64 stylesheets under `packages/ui/src` were unlinted. `noDefaultExport` is now `error`, `noNonNullAssertion` is raised from `warn` to `error` (`biome check` exits 0 on warnings, so `foo!` was unenforced), and the step's summary now names only what is actually enforced. |
| `ui/src/tokens/tokens.test.ts:88` | The only raw-colour enforcement in the repo checked **exactly three files**, none of them a component stylesheet — the 51 `.module.scss` files under `components/` were covered by neither this test nor Biome. Now globs every `.scss` under `packages/ui/src` except the canonical token files, matches `rgb(`/`hsl(` as well as hex, and asserts it found >50 files so an empty glob cannot pass. |
| `x.verify.json` | The suite floor omitted `job` and `eval`, both of which apply at the repo root — so deleting those suites turned them into silent skips and the gate stayed green at "17/17 (1 skipped)". |
| `cli/src/test-select.ts:19` | `TEST_GLOB` was `**/*.test.ts`, missing `.test.tsx` — a JSX test would be excluded from the gate's `unit`/`contract`/`job` steps while `bun run test` at the root still ran it. |
| `cli/src/source-files.ts:5` | `packages/*/e2e/**` was outside both `SOURCE_GLOBS` and the boundary collector, so `filesize`, `errors` and `boundaries` never saw three real source directories. |
| `scripts/boundaries.ts:194` | The `shared/` leaf rule globbed `examples/*` only, so the **deployed demo app** — the one CI publishes an image for on every push to main — was checked by nothing blocking. |
| `scripts/roadmap.ts:44` | Milestone numbers came from a hardcoded map, so "every milestone row carries a status marker" only covered 0–11. Appending a milestone 12 with no marker passed. Now parses the table itself; a row with no artifacts entry is `X_ROADMAP_MILESTONE_UNTRACKED`. |
| `scripts/release.ts:98` | `--bump` was cast to its union with **no validation**: `--bump majr` fell through to `1.2.1`, so a breaking change ships as a patch. `--version 1.2` wrote `"version": "1.2"` into all 29 manifests. `report()` was also called with `ok: true` unconditionally, so pre-existing skew findings exited 0. |
| `cli/src/workspace-checks.ts:97` | **`X_RELEASE_VERSION_SKEW` compared packages only to each other, so it had no anchor.** Nine tags (`v1.3.0`…`v1.10.1`) have been cut against 29 packages all still stamped `1.2.0` — the gate is green while the tag lies, and a real publish would die `EPUBLISHCONFLICT` on all 29. `package-shape` gains a `--release <version>` mode; `bun run scripts/release.ts --check <version>` asserts the lockstep version equals the version being published. Verified live: `--check 1.2.0` passes, `--check 1.10.1` reports 141 findings and exits 1. **`.github/workflows/release.yml` still needs the call added before the publish loop — that file is outside this PR and is tracked separately.** |

## CLI correctness — the agent-facing surface

| Where | Defect |
|---|---|
| `cli/src/dispatch.ts:51` | The parse-failure path read `argv.includes('--json')`, so **`-j` was ignored and errors rendered as prose on stdout**. `x doctor -j --bogusflag` and `x nonexistentcmd -j` both emit human text — exactly the two cases an agent hits while always passing `-j`, and `JSON.parse` throws on the result. |
| `cli/src/templates/route.ts:25` | **`x g route "posts/[slug]"` silently scaffolded a static route.** Every segment went through `kebab()`, which strips `[` and `]`, so the agent got `apps/web/app/posts/slug/page.tsx` with exit 0 and no warning — and a generated test hard-coding `params: {}`. |
| `cli/src/cmd-generate.ts:376` | A missing `<name>` was reported as `X_CLI_UNKNOWN_COMMAND` for a command form that *is* known, with `fix: x g route <name>` — which pasted into bash is a **redirect**. Now a missing-positional error with a concrete runnable example. Swept the same shape across `mcp-errors.ts` (14 entries), `errors.ts` (5) and `cmd-planned.ts`: any `<placeholder>` now sits behind a `#`, never in the runnable half. |
| `cli/src/templates/scaffold-repo.ts:225` | **`x new` scaffolded two house-rule violations into every generated app**: a restated `Money` interface (CLAUDE.md: "one declaration in `@ultimat3/schema` … never restated") and a bare `RangeError`. Flagged independently by two auditors. Now re-exports `MoneyValue as Money` and throws a generated `UltimateError` subclass. |
| `cli/src/cmd-doctor.ts:165` | `--port` was `parseInt`'d unvalidated, so **a bad value turned the port probe into a check that cannot fail** — `x doctor --port abc` reports the environment shippable while 3000 is occupied. Same at `cmd-dev.ts:268` (`NaN` to `Bun.serve` binds an arbitrary port) and `cmd-test.ts` (`--workers 4abc` accepted as 4, while `cmd-verify.ts`' comment claimed it was refused). One `readIntFlag` now serves all four. |
| `cli/src/cmd-doctor.ts` | New `X_STORAGE_SECRET_DEV` finding mirroring the existing dev-cursor-secret check, wired to `usesDevStorageSecret()` from #80. |
| `cli/src/dev-runtime.ts:150` | `startServices` falls back to the local disk driver whenever `S3_ENDPOINT`/`S3_BUCKET` are unset, which after #80 throws at boot in production. Made that failure an *instruction*: it leads with the storage choice ("no S3_ENDPOINT/S3_BUCKET, so this production process fell back to the embedded disk at …") and names object storage first. Deliberately **not** an outright ban on the local disk in production — a single-node Compose deploy on a mounted volume with a real secret is a legitimate rung on the scale ladder, and refusing it is a deploy-shape decision, not a security fix. |
| `cli/src/templates/action.ts:93` | Every generated feature shipped `code: 'X_INVOICE_NOT_FOUND'` beside `docs: '…/errors/X_NOT_FOUND'` — following the link landed on a different code's page. |
| `cli/src/cmd-generate.ts:400` | `--dry-run` reported `summary: "wrote 4 file(s)"` while `data.dryRun` was true. |
| `cli/src/cmd-errors.ts:88` | `x errors` with no code reported a `--code` flag **that does not exist**; an agent reading the cause literally gets a second error. |
| `scripts/new-package.ts:98` | Every scaffolded package documented "may import tiers 0-5" regardless of `--tier`, because the allowed range was derived from the tier table the new package is not yet in. `--tier abc` produced "Tier NaN". The file had no test; it has one now. |
| `scripts/lib/tiers.ts:46` | `create-ultimate` resolved to the unlisted tier, so its declared `→ cli` edge restricted nothing — it could import all 28 packages. Now pinned above the table with that edge as its only permitted import. |
| `scripts/lib/run.ts:18` | A bare `RangeError` at the scripts' single subprocess boundary, where `cli/src/exec.ts` does the identical guard correctly and explains why. |
| `scripts/scaffold-smoke-overrides.ts` | Wrote prose to stdout, took no `--json`, and exited 1 with no code — and if it found no workspace manifests it wrote `{}`, silently making the smoke job install from **the npm registry** instead of the working tree. That is now a hard error. |
| `create-ultimate/src/bin.ts:11` | The only published entry point using `process.stdout.write` + `process.exit`, the combination both `cli/src/bin.ts` and `scripts/lib/log.ts` carry comments explaining truncates at 64KB under a pipe. |
| `ui/src/components/date-time-view.ts:42` | `toDate` fell back to `new Date(value)`, whose parse of an offset-less datetime uses the **host's** zone — an ambient default in the one package that forbids them. Every formatting path was correctly zoned; only the parse was not. |
| `scripts/help.ts:21` | Claimed 16 verify steps against 17, and omitted the app gate — a headline command in CLAUDE.md — from the catalogue an agent reads to discover the repo. |

## Not closed, and named

An undriven `e2eTest` still reports **green** rather than skipped. The filename half is fixed (the generated assertion now lands in `page.e2e.test.ts`, which the `e2e` step actually selects on) and `hasE2eDriver()` is exported so the seam has one name — but the driver registers inside the `bun test` child and the step's only channel is an exit code, which is 0 on skips. Making it red would turn a scaffolded app's `e2e` step red on `x g route` output, and that blast radius could not be proven here. `test-types.ts`' docstring no longer claims behaviour nothing implements.

## New error codes

`X_STORAGE_SECRET_DEV`, `X_ROADMAP_MILESTONE_UNTRACKED`, `X_SCAFFOLD_OVERRIDES_EMPTY` — documented, registered, in the manifest. `X_BUDGET_UNMEASURED` already existed and was already documented; only the code path that emits it was missing.

## Behaviour changes

`x doctor --port` / `x dev --port` / `x test --workers` now **refuse** bad values with `X_CLI_BAD_FLAG` instead of coercing them. Same surface, stricter contract; `wiki/Error-Codes.md`'s row for that code is widened to name positionals.

## Gate

`bun run verify` green on this branch: 14/17, same three structural skips as `main`. `bunx biome check .` clean across 3547 files with both new rules at `error`.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
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.

1 participant