Skip to content

feat: derive the batch command union from the as-const registry (simplify #909) — Phase 1 step 7#912

Merged
thymikee merged 1 commit into
mainfrom
feat/derive-batch-command-union
Jun 27, 2026
Merged

feat: derive the batch command union from the as-const registry (simplify #909) — Phase 1 step 7#912
thymikee merged 1 commit into
mainfrom
feat/derive-batch-command-union

Conversation

@thymikee

Copy link
Copy Markdown
Member

Phase 1 step 7 of the command-descriptor migration (ADR 0008)

Stacked on #911.

What

The command-descriptor registry became as const and started exporting type Command in #910. With literal name and literal batchable preserved per entry, the batch command-name union can now derive from the registry instead of being hand-authored.

This PR:

  • Replaces the 43-member hand-authored StructuredBatchCommandName union (introduced in feat: build batch allowlist from descriptors, delete the hand list — Phase 1 step 4 #909, when the registry was not yet as const) with a derivation from the registry:
    export type StructuredBatchCommandName = Extract<
      (typeof commandDescriptors)[number],
      { batchable: true }
    >['name'];
  • Deletes the now-tautological exhaustive Record<StructuredBatchCommandName, true> membership assertion in parity.test.ts — the type and the runtime value now derive from the same batchable: true entries, so the exhaustive cross-check is a tautology. tsc enforces the type; the kept invariant guards the runtime value (exported allowlist === derived fold, no dupes, all public, control-plane stays out).

Why it is strictly behaviorless

  • Identical 43-member set. Confirmed the derived union is bidirectionally assignable to feat: build batch allowlist from descriptors, delete the hand list — Phase 1 step 4 #909's hand union and that both have exactly 43 members (type-level count check) — no member added or removed.
  • Runtime allowlist unchanged. STRUCTURED_BATCH_COMMAND_NAMES still folds the registry via deriveStructuredBatchCommandNames; only the narrowing cast's source-of-truth comment changed.
  • Public BatchCommandName structurally identical. The re-export through command-surface.ts resolves to the same union; a consumer switching on specific batch command names still typechecks (tsc green across the project, including the satisfies readonly DaemonCommandName[] guard in commands/batch/projection.ts).

Verification

  • tsc -p tsconfig.json --noEmit — exit 0
  • oxfmt --write + oxlint --deny-warnings on changed files — exit 0
  • vitest run batch core/command-descriptor command-surface-metadata projection — all pass
  • Layering Guard grep — empty

@github-actions

github-actions Bot commented Jun 27, 2026

Copy link
Copy Markdown

Size Report

Metric Base Current Diff
JS raw 1.4 MB 1.4 MB 0 B
JS gzip 445.5 kB 445.5 kB 0 B
npm tarball 584.7 kB 584.7 kB 0 B
npm unpacked 2.0 MB 2.0 MB 0 B

Startup median (7 runs, lower is better):

Scenario Base Current Diff
CLI --version 27.3 ms 27.6 ms +0.3 ms
CLI --help 48.6 ms 47.0 ms -1.6 ms

Top changed chunks: no changes in the largest emitted chunks.

@thymikee thymikee force-pushed the feat/command-result-spine branch from 3dca1c8 to f938536 Compare June 27, 2026 16:25
@thymikee thymikee force-pushed the feat/derive-batch-command-union branch from d5bc90f to f322cb0 Compare June 27, 2026 16:26
@thymikee thymikee force-pushed the feat/command-result-spine branch from f938536 to e8e4a81 Compare June 27, 2026 18:07
@thymikee thymikee force-pushed the feat/derive-batch-command-union branch from f322cb0 to 0a488e8 Compare June 27, 2026 18:08
@thymikee thymikee force-pushed the feat/command-result-spine branch from e8e4a81 to ef61c90 Compare June 27, 2026 18:24
@thymikee thymikee force-pushed the feat/derive-batch-command-union branch from 0a488e8 to 537a9d6 Compare June 27, 2026 18:24
@thymikee thymikee force-pushed the feat/command-result-spine branch from ef61c90 to 3d4fcb2 Compare June 27, 2026 18:54
@thymikee thymikee force-pushed the feat/derive-batch-command-union branch from 537a9d6 to 30798a9 Compare June 27, 2026 18:54
Base automatically changed from feat/command-result-spine to main June 27, 2026 19:02
…lify #909) — Phase 1 step 7

The command-descriptor registry is now `as const` (#910), so each entry keeps
its literal `name` and literal `batchable`. Derive StructuredBatchCommandName
from it via `Extract<…, { batchable: true }>['name']` instead of the 43-member
hand-authored union from #909, and delete the now-tautological exhaustive Record
membership assertion in parity.test.ts (type and value now derive from the same
`batchable: true` entries).

Strictly behaviorless: the derived union is the identical 43-member set
(confirmed bidirectionally assignable to the old hand union, member count
unchanged), the runtime allowlist value is unchanged, and the public
BatchCommandName re-export is structurally identical (consumer switches on
specific batch command names still typecheck).
@thymikee thymikee force-pushed the feat/derive-batch-command-union branch from 30798a9 to 167cf6d Compare June 27, 2026 19:09
@thymikee thymikee merged commit 9422881 into main Jun 27, 2026
20 checks passed
@thymikee thymikee deleted the feat/derive-batch-command-union branch June 27, 2026 19:23
@github-actions

Copy link
Copy Markdown
PR Preview Action v1.8.1
Preview removed because the pull request was closed.
2026-06-27 19:24 UTC

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