Skip to content

feat(api): propose the v2 rule API migration and add the v2 client (0.12.0, stack 1/5) - #411

Open
thecodedrift wants to merge 3 commits into
mainfrom
openspec/cli-v2-rule-api
Open

thecodedrift wants to merge 3 commits into
mainfrom
openspec/cli-v2-rule-api

Conversation

@thecodedrift

@thecodedrift thecodedrift commented Sep 29, 2026 •

Copy link
Copy Markdown
Member

Stack (root → tip):

Bottom of a five-PR stack that moves the CLI to the Taskless v2 rule API (taskless/taskless#229) for 0.12.0. The stack merges down: each PR merges into the one below it, and this branch reaches main once, carrying all of it.

Why the stack merges down

The server's version floor treats a prerelease as the release it precedes, so any nightly stamped 0.12.0-* counts as a v2 client. If a partial slice reached main, the nightly would publish a CLI the server treats as v2 while it still calls v1 routes, which answer 410 once the floor is set. Measured: this branch stamps 0.12.0-20260929033014x86799ef.

What this PR contains

  • The OpenSpec change cli-v2-rule-api: proposal, design, tasks, and six spec deltas. Start with design.md; the decisions there drive every later slice.
  • The minor changeset. check now fails on an edited sg or vale rule, and rule create --json renames a field consumers read. A patch changeset would also stamp nightlies 0.11.3-*, below the v2 floor.
  • The vendored v2 schema (api-v2.schema.json / api-v2.d.ts), fetched from /cli/api/v2/__schema. It sits beside the frozen v1 files so every PR in the stack typechecks; v1 is deleted at the tip.
  • api/v2.ts: one typed client for all nine v2 operations. Every call sends x-taskless-cli-version and returns an outcome instead of throwing. Each operation's error codes are checked against the schema at compile time, so a schema refresh that adds a code fails typecheck until it's handled.
  • api/refusal.ts: a plan refusal (restoreRules: false) is an answer to relay, not an outage. Control characters are stripped from the server's message before it reaches a terminal.
  • parseEntitlementV2: withheld runtime rules keyed by rule id. A test pins the Fail check when the server withholds runtime rules (paid Taskless accounts only) #403 hazard: the v1 parser drops every v2 withheld entry.

Nothing calls the new client yet. Behavior is unchanged until the next slice.

The stack

  1. Contract (this PR): spec, changeset, v2 schema and client.
  2. Generation: rule create / rule improve on v2, with signature-verified delivery.
  3. Reconcile: snapshot → sign → report → run for every engine, the verdict policy, and accounting.
  4. Recovery: rule restore and rule rollback.
  5. Retire v1: delete v1 code, recipes, the production round trip, and the archive.

Size

Around 5,000 added lines. About 3,500 are the generated schema and types. The rest is mostly the OpenSpec artifacts (~1,600 lines), which describe every later slice. Splitting them off would leave reviewers judging a client with no spec, so they stay here, over the usual ~1,200-line guideline.

Checks

pnpm typecheck, pnpm lint (which rebuilds and runs cli check), and the full suite (110 files, 1,837 tests) pass. The archive was dry-run on a scratch copy of openspec/: every scenario that disappears belongs to a requirement marked REMOVED.

Refs TSKL-307

@github-actions github-actions Bot added the Open OpenSpec Contains unresolved OpenSpec changes. All openspec changes must eventually reach an archive state. label Sep 29, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Open OpenSpec Contains unresolved OpenSpec changes. All openspec changes must eventually reach an archive state.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant