SpecsCLIM3-authenticated-distribution
Plan: M3 Authenticated Distribution
Plan: M3 Authenticated Distribution
Initial Situation
The branch team/stefan/m3-delivery-20260514 is open as draft PR #4 against 2.0.0. The worktree started detached at origin/2.0.0 commit ec62147 Refresh scaffold context, with pre-existing local .codex/config.toml drift preserved.
Linear M3 contains three parents and six children:
IP-101: childrenIP-122,IP-123IP-103: childrenIP-126,IP-127IP-102: childrenIP-124,IP-125
Solution Shape
Deliver in gates:
- CLI architecture refactor gate
- IP-101 authenticated CLI access
- IP-103 required toolchain, parallel-safe with IP-101 only if write scopes remain disjoint
- IP-102 backend-mediated baseline distribution after IP-101/IP-123 validate
- review, effect-review, validation, docs ingest, and Linear closeout
Research Synthesis
- CLI command registration should stay explicit and direct.
- Extract shared runtime helpers before feature work: baseline option mapping and required-tool checks are already duplicated or hard to test.
- Auth should be a command/config/provider boundary, not embedded in scaffold/update.
- API currently has an authenticated placeholder baseline boundary but no real registry/artifact service layer.
- Required-tool installation was previously tied to scaffold runtime and needed direct tests.
Tasks
T1: CLI architecture refactor gate
- depends_on: []
- status: Complete
- location:
apps/cli - description: Extract shared command baseline option resolution and required-tool installation/checking into testable modules. Preserve command behavior.
- validation:
bun run test --filter=@punks/clibun run check-types --filter=@punks/cli
- acceptance:
- required-tool boundary has direct tests for already-present, install, missing prerequisite, no package manager, and unknown tool
- scaffold/update no longer imports tool installation from scaffold runner
- command adapters do not duplicate baseline option conversion
- log: Added
apps/cli/src/cli/baseline-options.ts, extractedapps/cli/src/core/tools.ts, updated scaffold/update callers, and addedapps/cli/src/core/tools.test.ts.
T2: IP-101/IP-122 auth command and credential provider
- depends_on: [T1]
- status: Complete
- location:
apps/cli,apps/api,packages/contract - description: Add
dp auth login/status/logoutand a local credential provider. Keep flow Better Auth-compatible and testable without production credentials. - validation:
- focused CLI auth tests
- CLI smoke for
auth statusunauthenticated and logout idempotency
- acceptance:
dp auth loginstarts browser approval or explicit local-development substitute- credentials are stored in a clear local config location
- status and logout reflect credential state
- log: Added
punks auth login/status/logout, credential store, Better Auth device authorization client, direct-token local-development path, and auth store/device-flow tests.
T3: IP-101/IP-123 authenticated typed API calls
- depends_on: [T2]
- status: Complete
- location:
apps/cli,apps/api,packages/contract - description: Wire credential provider into typed
@punks/contractclient calls and replace placeholder auth acceptance with a testable backend auth/session boundary. - validation:
- contract/API tests for unauthorized and authorized requests
- typed client integration test
- acceptance:
- CLI attaches bearer token
- backend accepts valid token and returns
CurrentOperator - backend rejects missing/invalid baseline access with typed error
- log: Baseline resolver now reads stored CLI credentials when
DP_CONTROL_PLANE_TOKENis absent.packages/authenables Better Auth bearer/device plugins.apps/apirejects missing/invalid bearer credentials, fails closed withoutDP_API_CLI_TOKEN, mounts/api/auth/*, and accepts configured static local tokens or Better Auth bearer sessions before baseline handlers run.
T4: IP-103/IP-126 required toolchain checks
- depends_on: [T1]
- status: Complete
- location:
apps/cli,packages/scaffold, docs - description: Make
skills,opensrc,agent-browser, andportlessexplicit in setup/update and generated metadata. - validation:
- required-tool schema/roundtrip tests
- scaffold setup/update tests
- acceptance:
- all required tools are checked
- missing tools show actionable operator guidance
portlessis required, not optional
- log: Base required tools now include
agent-browser,opensrc,portless, andskills; content tests pin the base set and selected-skill additions.
T5: IP-103/IP-127 dp-cli skill provisioning
- depends_on: [T4]
- status: Complete
- location:
apps/cli, generated baseline assets, docs - description: Ensure setup/update can verify or surface the internal
dp-cliskill and generated guidance includes CLI-backed issue reporting expectations. - validation:
- generated required-tool/handoff/prompt tests
- CLI update/scaffold fixture checks
- acceptance:
skillscan verify/providedp-cli- setup/update exposes skill presence
- skill guidance covers CLI-backed issue reporting
- log: Existing startup checks verify
dp-clithrough theskillsCLI and print theskills add wearedevpunks/skills --global --skill dp-cli --yesguidance; setup/update keepskillsin base required tools and docs/runbook now make this provisioning contract explicit.
T6: IP-102/IP-124 baseline registry and resolution
- depends_on: [T3]
- status: Complete
- location:
apps/api,packages/contract,apps/cli - description: Implement backend recommended baseline metadata for authenticated operators, with compatibility/channel/provenance fields and CLI cache/apply path.
- validation:
- API service/layer tests
- CLI baseline resolver tests for control-plane success and fallback
- acceptance:
- backend returns recommended baseline metadata
- CLI resolves through
apps/api - CLI cache/apply behavior works locally
- fallback remains intact
- log: Added env-backed
BaselineRegistryLiveinapps/api, with authenticated/api/baselines/stablereturning typed control-plane baseline metadata when configured and retainingControlPlaneUnavailablewhen unconfigured.
T7: IP-102/IP-125 artifact access
- depends_on: [T6]
- status: Complete
- location:
apps/api,packages/contract, docs - description: Add backend-issued artifact access metadata, evaluate Vercel Blob, and preserve unprotected GitHub Releases during migration.
- validation:
- API artifact metadata tests
- docs decision note for Vercel Blob target/proxy behavior
- acceptance:
- signed/proxied artifact URL shape exists
- Vercel Blob decision is recorded
- migration keeps GitHub Releases usable
- log: Added authenticated artifact metadata endpoint backed by
DP_BASELINE_MANIFEST_URLandDP_BASELINE_ARCHIVE_URL. Docs record the M3 decision: artifact URLs are provider-agnostic and can point to Vercel Blob signed/proxied URLs or current GitHub Release assets during migration.
T8: Review, docs ingest, validation, PR, Linear closeout
- depends_on: [T2, T3, T4, T5, T6, T7]
- status: Complete
- location: repo-wide affected surfaces
- description: Run findings-first review, effect-review for Effect/backend/control-plane code, full validation, docs ingest, PR update, and Linear closeout.
- validation:
git diff --checkbun run checkbun run check-typesbun run test- targeted CLI smoke from built/dist entrypoint
- affected docs/wiki route/build checks
- acceptance:
- every issue/subissue has evidence
- blockers are concrete if any remain
- Linear comments/states updated after merge-ready validation
Current Validation Evidence
bun run test --filter=@punks/cli --filter=@punks/api: passed@punks/cli72 tests and@punks/api8 tests after review fixes.bun run check-types --filter=@punks/api --filter=@punks/cli --filter=@punks/auth --filter=@punks/db: passed 6 tasks after review fixes.git diff --check: passed.bun run check: passed.bun run check-types: passed 8 tasks.bun run test: passed 4 tasks.bun run build --filter=@punks/cli: passed.- Built CLI
--helpand auth status/login/status/logout smokes: passed.
Unresolved Questions
- None for M3 implementation. Final Vercel Blob signed URL versus proxy behavior remains provider deployment configuration behind the artifact URL contract.