version: 1
updated_at: '2026-05-07'
states:
- todo
- in_progress
- blocked
- done
roles:
- A-backend
- B-ui
- C-ops
tasks:
- id: B-V3-ACK-SUPPRESS-CONTROL-001
  title: Add V3 platform AckSuppressControl and wire action queues
  role: B-ui
  status: done
  priority: 1
  owner: B-ui
  branch: agent/B-ui
  completed_at: '2026-05-04'
  commit: 3993e614
  depends_on: []
  acceptance_checks:
  - pnpm --dir packages/web exec vitest run AckSuppressControl
  - pnpm --dir packages/web typecheck
  - ruby scripts/ops/agent_queue_store.rb --queue-file doc/governance/Agent_Work_Queue.yaml
    validate
  - make queue-git-check
  notes: |
    Context:
    V3 platform queues currently accumulate action noise from known test debris and operator-reviewed issues. Backend support for signal acknowledge/suppress is available and verified; the UI needs a bounded primitive to prove the workflow on existing pages before any larger admin workbench refactor.

    Pre-read (required):
    - doc/product/V3_Admin_Workbench_Model_v1.md
    - doc/api/openapi/domains/v3-read-models.yaml
    - packages/web/src/lib/v3/api.ts
    - packages/web/src/components/v3/v3-platform-pages.tsx
    - packages/web/src/lib/session/platform-access.ts

    Invariants (must not break):
    - Use backend-provided `signal_key` and `ack_fingerprint`; never derive fingerprints client-side.
    - Mutation visibility must require `platform.ops.write`.
    - Suppression requires `reason` and a future `expires_at`.
    - Current backend supports only `scope: "item"`.
    - Render ack state badges only for `acknowledged`, `suppressed`, `expired`, and `resurfaced`; do not badge `none`.
    - Suppressed items are hidden by default by the backend; do not add a full history/suppressed view in this task.
    - Do not start the broader admin workbench, table, drawer, or IA refactor in this task.

    Scope:
    - In: Add an `AckSuppressControl` UI primitive for V3 platform action items.
    - In: Use `acknowledgeV3PlatformSignal`, `suppressV3PlatformSignal`, and `clearV3PlatformSignalAcknowledgement`.
    - In: Wire the primitive into existing V3 platform action queues on Ops, Lifecycle, and Finance.
    - In: Add focused component/page tests covering ack, suppress, clear, permission-gated visibility, and resurfaced/expired badge rendering.
    - Out: New backend work, new API fields, show-suppressed/history mode, and broad admin workbench layout refactors.

    Deliverables:
    - `packages/web/src/components/v3/` component or equivalent existing V3 component location for `AckSuppressControl`.
    - Updates to V3 platform Ops/Lifecycle/Finance action queue rendering.
    - Focused Vitest coverage for the primitive and first wiring.

    Evidence required in handoff:
    - files changed
    - commit SHA
    - exact acceptance commands run
    - pass/fail status by command
- id: B-V3-ACK-ACTIONBAND-CLEANUP-001
  title: Normalize V3 action-band ack suppression wiring
  role: B-ui
  status: done
  priority: 1
  owner: B-ui
  branch: agent/B-ui
  completed_at: '2026-05-04'
  commit: ac667030
  depends_on:
  - B-V3-ACK-SUPPRESS-CONTROL-001
  acceptance_checks:
  - pnpm --dir packages/web exec vitest run AckSuppressControl
  - pnpm --dir packages/web typecheck
  - ruby scripts/ops/agent_queue_store.rb --queue-file doc/governance/Agent_Work_Queue.yaml
    validate
  - make queue-git-check
  notes: |
    Context:
    The first AckSuppressControl task proved the workflow, but it embedded the control by rebuilding `ActionBandFromItems` row rendering in `v3-platform-pages.tsx`. That is acceptable for the prototype, but it creates drift from the shared action-band primitive.

    Required outcome:
    - Refactor the V3 action-band rendering so acknowledgement/suppression is a formal extension point instead of one-off inline row duplication.
    - Prefer a small trailing/action slot or V3-specific action-band variant with a clear prop contract.
    - Preserve existing rendering on Ops, Lifecycle, and Finance.
    - Preserve backend-owned `signal_key` and `ack_fingerprint` semantics; do not derive fingerprints client-side.
    - Preserve permission-gated mutation visibility and existing `AckSuppressControl` tests.

    Scope:
    - In: frontend component cleanup and focused tests/typecheck.
    - Out: new backend fields, show-suppressed history mode, and broad workbench layout changes.
- id: B-V3-PLATFORM-PROSE-TRIM-001
  title: Trim reviewer-facing prose from V3 platform pages
  role: B-ui
  status: done
  priority: 1
  owner: B-ui
  branch: agent/B-ui
  completed_at: '2026-05-04'
  commit: 4500b1ce
  depends_on:
  - B-V3-ACK-ACTIONBAND-CLEANUP-001
  acceptance_checks:
  - pnpm --dir packages/web typecheck
  - pnpm --dir packages/web test
  - rg -q "ContextHelp" packages/web/src/components/v3/v3-platform-pages.tsx
  - ruby scripts/ops/agent_queue_store.rb --queue-file doc/governance/Agent_Work_Queue.yaml
    validate
  - make queue-git-check
  notes: |
    Context:
    `doc/product/V3_Admin_Workbench_Model_v1.md` defines where prose belongs: empty states, confirmations, runbooks, or `ContextHelp`. Current platform pages still carry permanent mock/spec copy in section descriptions and workflow cards, which makes the UI read like a document with data.

    Required outcome:
    - Audit `/v3-prod/platform/*` rendering in `packages/web/src/components/v3/v3-platform-pages.tsx`.
    - Remove descriptions that restate the title or explain design rationale.
    - Move genuinely non-obvious operational context into `ContextHelp` where the page already supports it.
    - Keep empty-state guidance where it helps the operator decide what to do next.
    - Do not change backend contracts or page IA in this task.

    Scope:
    - In: Platform Ops, Lifecycle, Config, Evidence, Finance, IAM prose trim.
    - Out: user workload/storage/app pages, table/drawer redesign, and new finance backend work.
- id: B-V3-ADMIN-WORKBENCH-PRIMITIVES-001
  title: Add shared V3 admin workbench and operation drawer primitives
  role: B-ui
  status: done
  priority: 1
  owner: B-ui
  branch: agent/B-ui
  completed_at: '2026-05-04'
  commit: 92382da0
  depends_on:
  - B-V3-PLATFORM-PROSE-TRIM-001
  acceptance_checks:
  - pnpm --dir packages/web typecheck
  - pnpm --dir packages/web test
  - rg -q "AdminWorkbench|OperationsDrawer|AdminFamilyLanding" packages/web/src/components/v3
  - ruby scripts/ops/agent_queue_store.rb --queue-file doc/governance/Agent_Work_Queue.yaml
    validate
  - make queue-git-check
  notes: |
    Context:
    Before converting Lifecycle Nodes or Finance Sessions, add the shared primitive foundation from `doc/product/V3_Admin_Workbench_Model_v1.md` so future pages do not each invent their own table, selected-detail panel, operation drawer, URL state, and responsive fallback.

    Required outcome:
    - Add lightweight shared primitives or component contracts for:
      - `AdminFamilyLanding`
      - `AdminWorkbench`
      - `OperationsDrawer`
    - Include URL-state behavior for filters/selection where practical, or document a narrow placeholder prop contract if full URL persistence would force a page migration.
    - Implement drawer width and right-edge overlay behavior from the spec.
    - Add focused tests for open/close behavior, selected-row focus return if practical, and narrow/full-screen fallback if covered by existing test utilities.
    - Do not migrate Lifecycle, Finance, IAM, or Evidence pages in this task unless needed for a minimal example.

    Scope:
    - In: shared frontend primitives and tests.
    - Out: Finance sessions backend, broad page migrations, and visual redesign beyond the primitive contract.
- id: B-WEB-VITEST-JSX-RUNTIME-001
  title: Normalize Vitest JSX runtime for product primitives
  role: B-ui
  status: done
  priority: 1
  owner: B-ui
  branch: agent/B-ui
  completed_at: '2026-05-04'
  commit: 4053eec8
  depends_on:
  - B-V3-ADMIN-WORKBENCH-PRIMITIVES-001
  acceptance_checks:
  - pnpm --dir packages/web exec vitest run src/components/product src/components/v3/admin
  - pnpm --dir packages/web typecheck
  - ruby scripts/ops/agent_queue_store.rb --queue-file doc/governance/Agent_Work_Queue.yaml
    validate
  - make queue-git-check
  notes: |
    Context:
    Multiple recent B UI tasks hit the same Vitest/classic JSX runtime failure: isolated component tests compile JSX to `React.createElement`, but several product primitives did not import React explicitly. Fix the test/runtime footing before more admin workbench pages are migrated.

    Required outcome:
    - Choose the lowest-risk repo-consistent fix:
      - either configure Vitest/Vite test JSX transform to automatic runtime if compatible with the existing app build, or
      - audit `packages/web/src/components/product/**` and V3 shared primitives for classic-runtime-safe explicit React imports.
    - Add or adjust focused tests so at least `action-band`, `section-card`, `kpi-tile`, `status-chip`, and the V3 admin primitives render in isolation.
    - Do not do broad visual refactors in this task.

    Scope:
    - In: Vitest config/test harness or explicit React imports for shared frontend primitives; focused tests.
    - Out: Finance workbench implementation, backend changes, Playwright/e2e changes, and full-suite timeout triage unless directly caused by this task.

    Evidence required in handoff:
    - chosen approach and why
    - files changed
    - exact acceptance commands run
    - pass/fail status by command
- id: B-V3-FINANCE-SESSIONS-WORKBENCH-001
  title: Implement V3 Finance Sessions workbench
  role: B-ui
  status: done
  priority: 1
  owner: B-ui
  branch: agent/B-ui
  completed_at: '2026-05-04'
  commit: 5c81d190
  depends_on:
  - B-WEB-VITEST-JSX-RUNTIME-001
  acceptance_checks:
  - pnpm --dir packages/web exec vitest run src/components/v3 src/lib/v3
  - pnpm --dir packages/web typecheck
  - rg -q "getV3PlatformFinanceSessions|getV3PlatformFinanceSessionDetail" packages/web/src/components/v3
  - ruby scripts/ops/agent_queue_store.rb --queue-file doc/governance/Agent_Work_Queue.yaml
    validate
  - make queue-git-check
  notes: |
    Context:
    Backend V3 finance session read models are available on master:
    - `GET /api/v1/v3/platform/finance/sessions`
    - `GET /api/v1/v3/platform/finance/sessions/{payment_session_id}`
    API helpers exist in `packages/web/src/lib/v3/api.ts`. Shared primitives exist under `packages/web/src/components/v3/admin/`.

    Pre-read (required):
    - doc/product/V3_Admin_Workbench_Model_v1.md
    - doc/architecture/Billing_Platform_Overhaul_v1.md
    - doc/api/openapi/domains/v3-read-models.yaml
    - packages/web/src/lib/v3/api.ts
    - packages/web/src/components/v3/admin/*
    - packages/web/src/components/v3/v3-platform-pages.tsx

    Required outcome:
    - Add a V3 Finance Sessions workbench route/surface reachable from `/v3-prod/platform/finance`.
    - Use `AdminWorkbench` for list + selected detail, not another long stacked page.
    - Use backend-provided `signal_key` and `ack_fingerprint` for AckSuppressControl; never derive them client-side.
    - Support filters from the backend list endpoint: `status`, `user_id`, `correlation_id`, cursor/page size where practical.
    - Detail panel must show summary, diagnostics, activity, recovery policy, and operation targets from the detail endpoint.
    - Use `OperationsDrawer` for manual recovery actions/links; do not implement new mutation flows unless they already exist as stable helpers.
    - Explicitly display that provider replay is not supported by this slice; label recovery as auditable manual recovery.
    - Preserve responsive fallback from the shared primitive; do not force a cramped split pane below the primitive breakpoint.

    Scope:
    - In: frontend route/page/component implementation, API helper usage, focused tests.
    - Out: new backend endpoints, provider replay mutation, rating/budgets/invoices, broad Lifecycle/Nodes workbench migration.

    Evidence required in handoff:
    - files changed
    - route(s) added/updated
    - exact acceptance commands run
    - pass/fail status by command
- id: B-V3-FINANCE-LANDING-COMPACT-001
  title: Compact V3 Finance landing around queues and pivots
  role: B-ui
  status: done
  priority: 1
  owner: B-ui
  branch: agent/B-ui
  completed_at: '2026-05-04'
  commit: 18ca1769
  depends_on:
  - B-V3-FINANCE-SESSIONS-WORKBENCH-001
  acceptance_checks:
  - pnpm --dir packages/web exec vitest run src/components/v3
  - pnpm --dir packages/web typecheck
  - ruby scripts/ops/agent_queue_store.rb --queue-file doc/governance/Agent_Work_Queue.yaml
    validate
  - make queue-git-check
  notes: |
    Context:
    `doc/product/V3_Admin_Workbench_Model_v1.md` says family landings should stay compact: KPI strip, action queue, and pivots into workbenches. Finance should not become a full payment-session/ledger/reconciliation long page now that a Sessions workbench exists.

    Required outcome:
    - Keep `/v3-prod/platform/finance` as a compact family landing.
    - Lead with KPIs and actionable finance queue.
    - Add clear pivots to Sessions workbench, diagnostics/evidence, refunds/user finance, and reconciliation posture.
    - Remove or relocate any permanent reviewer-facing prose that explains the design rather than helping an operator act.
    - Do not duplicate the full Sessions list or detail panel on the landing.

    Scope:
    - In: V3 Finance landing layout/content trim and focused tests.
    - Out: backend changes, new billing domains, and broad platform IA redesign.

    Evidence required in handoff:
    - before/after summary
    - files changed
    - exact acceptance commands run
    - pass/fail status by command
- id: A-V3-FINANCE-ACK-FIELDS-REQUIRED-001
  title: Require ack fields on V3 payment session rows
  role: A-backend
  status: done
  priority: 1
  owner: Codex
  branch: agent/A-backend
  completed_at: '2026-05-04'
  commit: 766e2c87
  depends_on:
  - B-V3-FINANCE-SESSIONS-WORKBENCH-001
  acceptance_checks:
  - sh -lc 'rg -n "V3PlatformPaymentSessionRow:" doc/api/openapi/domains/v3-read-models.yaml && rg -n "signal_key|ack_fingerprint|ack_state" packages/web/src/lib/v3/api.ts packages/web/src/components/v3'
  - pnpm --dir packages/web exec vitest run src/components/v3/v3-platform-finance-sessions-page.test.tsx src/components/v3/AckSuppressControl.test.tsx
  - pnpm --dir packages/web typecheck
  - ruby scripts/ops/agent_queue_store.rb --queue-file doc/governance/Agent_Work_Queue.yaml
    validate
  - make queue-git-check
  notes: |
    Context:
    B's Finance Sessions workbench exposed a contract gap: ack-able payment session rows include `signal_key`, `ack_fingerprint`, `ack_state`, `ack_reason`, `ack_expires_at`, `ack_actor`, and `ack_updated_at`, but `V3PlatformPaymentSessionRow.required` does not currently require those fields. That forces the UI to narrow before rendering `AckSuppressControl`, which conflicts with the admin workbench model's backend-owned signal/fingerprint rule.

    Required outcome:
    - Update `doc/api/openapi/domains/v3-read-models.yaml` so every ack field on `V3PlatformPaymentSessionRow` is required.
    - Regenerate or update generated web API types as needed.
    - Keep `signal_key` and `ack_fingerprint` documented as backend-owned opaque values; clients must never derive them.
    - Preserve nullable semantics for optional ack metadata (`ack_reason`, `ack_expires_at`, `ack_actor`, `ack_updated_at`) while still requiring the keys in the row shape.

    Scope:
    - In: OpenAPI contract and generated/client type fallout.
    - Out: new ack/suppression mutation semantics, provider replay, finance UI layout redesign.
- id: B-V3-FINANCE-DEAD-HELPER-CLEANUP-001
  title: Remove dead V3 finance landing helpers after workbench split
  role: B-ui
  status: done
  priority: 1
  owner: B-ui
  branch: agent/B-ui
  completed_at: '2026-05-04'
  commit: 00e09b5d
  depends_on:
  - B-V3-FINANCE-LANDING-COMPACT-001
  acceptance_checks:
  - pnpm --dir packages/web exec vitest run src/components/v3
  - pnpm --dir packages/web typecheck
  - sh -lc '! rg -n "function (PaymentSessionRow|PaymentRecoveryPanel|PaymentDiagnosticsCard|PaymentSessionReconcileCard|financeStuckFirst|paymentRank)" packages/web/src/components/v3/v3-platform-pages.tsx'
  - ruby scripts/ops/agent_queue_store.rb --queue-file doc/governance/Agent_Work_Queue.yaml
    validate
  - make queue-git-check
  notes: |
    Context:
    After `B-V3-FINANCE-SESSIONS-WORKBENCH-001` and `B-V3-FINANCE-LANDING-COMPACT-001`, the Finance landing should no longer own full payment-session detail/recovery rendering. Several old helpers appear to remain in `packages/web/src/components/v3/v3-platform-pages.tsx`, including `PaymentSessionRow`, `PaymentRecoveryPanel`, `PaymentDiagnosticsCard`, `PaymentSessionReconcileCard`, `financeStuckFirst`, and `paymentRank`.

    Required outcome:
    - Remove unused Finance helper components/functions and any imports/types that are only retained for those helpers.
    - Preserve current Finance landing behavior and `/v3-prod/platform/finance/sessions` workbench behavior.
    - Do not reintroduce the full sessions table/detail stack onto the landing page.
    - Keep the patch mechanical; no broad IA redesign in this cleanup task.

    Before claiming:
    - `git fetch origin`
    - `git switch agent/B-ui`
    - `git reset --hard origin/master`
    - then claim this task from the queue.

    Evidence required in handoff:
    - helper names removed
    - files changed
    - exact acceptance commands run
    - pass/fail status by command
- id: B-V3-FINANCE-WORKBENCH-POLISH-001
  title: Harden V3 Finance Sessions workbench operator states
  role: B-ui
  status: done
  priority: 2
  owner: B-ui
  branch: agent/B-ui
  completed_at: '2026-05-04'
  commit: 9e351446
  depends_on:
  - A-V3-FINANCE-ACK-FIELDS-REQUIRED-001
  - B-V3-FINANCE-DEAD-HELPER-CLEANUP-001
  acceptance_checks:
  - pnpm --dir packages/web exec vitest run src/components/v3/v3-platform-finance-sessions-page.test.tsx src/components/v3/AckSuppressControl.test.tsx
  - pnpm --dir packages/web typecheck
  - ruby scripts/ops/agent_queue_store.rb --queue-file doc/governance/Agent_Work_Queue.yaml
    validate
  - make queue-git-check
  notes: |
    Context:
    Once the payment session ack fields are required in the contract, the workbench can stop treating ack support as optional and can focus on operator states instead of defensive type narrowing.

    Required outcome:
    - Remove any client-side optional ack-field narrowing that exists only because generated types made ack fields optional.
    - Tighten empty, loading, error, filter, and selected-row states in the Sessions workbench.
    - Keep `AckSuppressControl` visible for ack-able rows using backend-provided `signal_key` and `ack_fingerprint`.
    - Ensure the operations drawer remains recovery/evidence oriented; do not add provider replay mutations unless backend helpers already exist.
    - Add or update tests for empty/error state, row selection, and ack control rendering.

    Before claiming:
    - `git fetch origin`
    - `git switch agent/B-ui`
    - `git reset --hard origin/master`
    - confirm `A-V3-FINANCE-ACK-FIELDS-REQUIRED-001` is done.

    Scope:
    - In: Finance Sessions workbench polish and tests.
    - Out: rating, budgets, invoices, provider replay API, broad admin workbench redesign.
- id: B-V3-FINANCE-KIND-SMOKE-POLISH-001
  title: Smoke test and polish V3 Finance workbench in kind
  role: B-ui
  status: done
  priority: 1
  owner: B-ui
  branch: agent/B-ui
  completed_at: '2026-05-04'
  commit: 499e0bc2
  depends_on:
  - B-V3-FINANCE-WORKBENCH-POLISH-001
  acceptance_checks:
  - pnpm --dir packages/web exec vitest run src/components/v3/v3-platform-finance-sessions-page.test.tsx src/components/v3/AckSuppressControl.test.tsx
  - pnpm --dir packages/web typecheck
  - sh -lc 'rg -q "platform/finance/sessions|Finance Sessions|AckSuppressControl" packages/web/src/components/v3 packages/web/app/v3-prod/platform/finance'
  - ruby scripts/ops/agent_queue_store.rb --queue-file doc/governance/Agent_Work_Queue.yaml
    validate
  - make queue-git-check
  notes: |
    Context:
    The V3 Finance landing and Sessions workbench are now split and polished, but they need a narrow kind-environment pass before we use the pattern as the example for other admin workbenches.

    Required outcome:
    - Run the Finance landing and `/v3-prod/platform/finance/sessions` workbench against the kind app/read models.
    - Fix only focused UI/runtime issues found during smoke testing: broken links, missing empty/error states, stale selection behavior, drawer open/close regressions, ack/suppress rendering regressions, or obvious responsive breakage.
    - Keep this as a polish task, not a new Finance feature task.
    - Record the exact kind URL(s), browser path(s), and manual observations in the handoff.

    Before claiming:
    - `git fetch origin`
    - `git switch agent/B-ui`
    - `git reset --hard origin/master`

    Scope:
    - In: V3 Finance landing and Sessions workbench smoke/polish in kind.
    - Out: backend mutations, provider replay/reconcile semantics, invoices, budgets, rating, broad admin IA changes, and deploy automation.
- id: B-V3-ADMIN-WORKBENCH-CONSISTENCY-PLAN-001
  title: Define focused V3 admin workbench consistency plan
  role: B-ui
  status: done
  priority: 2
  owner: B-ui
  branch: agent/B-ui
  completed_at: '2026-05-04'
  commit: ea8398cf
  depends_on:
  - B-V3-ADMIN-WORKBENCH-PRIMITIVES-001
  - B-V3-FINANCE-KIND-SMOKE-POLISH-001
  acceptance_checks:
  - sh -lc 'test -f doc/product/V3_Admin_Workbench_Consistency_Plan_v1.md'
  - sh -lc 'rg -q "Finance Sessions|Lifecycle|IAM|Evidence|page family|workbench" doc/product/V3_Admin_Workbench_Consistency_Plan_v1.md'
  - ruby scripts/ops/agent_queue_store.rb --queue-file doc/governance/Agent_Work_Queue.yaml
    validate
  - make queue-git-check
  notes: |
    Context:
    We should not start another one-off admin page refactor. Finance Sessions proved the workbench primitives, while Lifecycle, IAM, Evidence, and future Billing surfaces still need a consistent migration order and editorial rules.

    Required outcome:
    - Create `doc/product/V3_Admin_Workbench_Consistency_Plan_v1.md`.
    - Use `doc/product/V3_Admin_Workbench_Model_v1.md` as the governing model.
    - Compare current V3 Platform Finance, Lifecycle, Ops, Evidence, and IAM pages against the model.
    - Identify which surfaces should remain family landings, which should become workbenches, and which should become focused detail pages.
    - Produce a sequenced implementation plan with small PR-sized slices and explicit non-goals.
    - Include deletion/trim candidates where pages still read like document-with-data.
    - Keep this as a plan/spec task; do not implement broad UI migrations in this task.

    Before claiming:
    - `git fetch origin`
    - `git switch agent/B-ui`
    - `git reset --hard origin/master`

    Scope:
    - In: product/UX plan for V3 admin workbench consistency, using Finance Sessions as the first validation surface.
    - Out: code migrations, backend contracts, visual redesign beyond documentation, and V1 retirement.
- id: B-V3-PROVISIONING-ATTENTION-REVIEW-UX-001
  title: Wire V3 provisioning attention review controls
  role: B-ui
  status: done
  priority: 2
  owner: B-ui
  branch: agent/B-ui
  completed_at: '2026-05-04'
  commit: a24253ca
  depends_on:
  - A-V3-PROVISIONING-ATTENTION-REVIEW-001
  - B-V3-ACK-SUPPRESS-CONTROL-001
  acceptance_checks:
  - pnpm --dir packages/web exec vitest run src/components/v3
  - pnpm --dir packages/web typecheck
  - sh -lc 'rg -q "review_state|taken_care_of|ignored|superseded_by_workflow_id" packages/web/src/components/v3 packages/web/src/lib/gen'
  - ruby scripts/ops/agent_queue_store.rb --queue-file doc/governance/Agent_Work_Queue.yaml
    validate
  - make queue-git-check
  notes: |
    Context:
    Operators need stale provisioning failures to stop polluting live attention queues after a newer workflow resolves the same target. Backend task `A-V3-PROVISIONING-ATTENTION-REVIEW-001` will add review state, supersession, and privileged review mutations.

    Required outcome:
    - Once the backend contract lands, wire review controls into the V3 Lifecycle/Provisioning attention surfaces.
    - Show review state clearly for open, taken care of, ignored, and superseded items.
    - Add operator actions for marking attention items `taken_care_of` or `ignored` with a required note, using generated API helpers or a narrow helper added from the contract.
    - Keep reviewed/superseded items out of default live queues when the backend filters them, but make the state understandable in history/evidence surfaces when present.
    - Reuse existing V3 action/ack patterns where possible; do not invent a second suppression model.

    Before claiming:
    - Confirm `A-V3-PROVISIONING-ATTENTION-REVIEW-001` is done on master.
    - `git fetch origin`
    - `git switch agent/B-ui`
    - `git reset --hard origin/master`

    Scope:
    - In: V3 Lifecycle/Provisioning attention review UI after backend support lands.
    - Out: backend review mutations, MAAS workflow semantics, Finance ack/suppress, and broad admin workbench migration.
- id: A-IAM-TOKEN-ISSUER-EXTRACT-ISSUERS-001
  title: Extract current machine-token issuers behind IAM Token Issuer
  role: A-backend
  status: done
  priority: 1
  owner: Codex
  branch: agent/A-backend
  completed_at: '2026-05-04'
  commit: f7b91144
  depends_on: []
  acceptance_checks:
  - go test ./packages/services/auth ./packages/shared/middleware
  - go test ./cmd/api -run 'Test.*ServiceAccountToken|Test.*SharedRuntimeOperator'
  - ruby scripts/ops/agent_queue_store.rb --queue-file doc/governance/Agent_Work_Queue.yaml
    validate
  - make queue-git-check
  notes: |
    Context:
    `doc/architecture/IAM_Token_Issuer_v1.md` defines the consolidation path for machine-token issuance. Current code has two working but duplicated issuer paths:
    - `packages/services/auth/service_accounts.go`
    - `packages/services/auth/shared_runtime_operator_tokens.go`

    Required outcome:
    - Extract common issuer logic behind an IAM token issuer package/service or internal auth service component.
    - Preserve existing public contracts and endpoints:
      - `POST /api/v1/auth/service-account/token`
      - `POST /api/v1/auth/shared-runtime-operator/token`
    - Preserve current claim shapes, TTL policy behavior, issuer/audience defaults, and sentinel errors.
    - Keep actor-specific validation explicit; do not weaken service-account/project scope or shared-runtime/org scope checks.
    - Do not add storage/WEKA provider credentials in this task.

    Scope:
    - In: backend extraction, unit tests, handler regression tests if behavior can drift.
    - Out: OpenAPI changes, new public endpoints, provider credential issuance, token signing-key migration, broad auth middleware rewrite.

    Evidence required in handoff:
    - files changed
    - exact acceptance commands run
    - pass/fail status by command
- id: A-IAM-TOKEN-ISSUER-ISSUANCE-AUDIT-001
  title: Add audit coverage for machine-token issuance
  role: A-backend
  status: done
  priority: 1
  owner: Codex
  branch: agent/A-backend
  completed_at: '2026-05-04'
  commit: 7d6afceb
  depends_on:
  - A-IAM-TOKEN-ISSUER-EXTRACT-ISSUERS-001
  acceptance_checks:
  - go test ./packages/services/auth ./cmd/api -run 'Test.*Token'
  - sh -lc 'rg -q "auth.token.issue|auth.token.deny" packages/services/auth cmd/api doc/architecture/IAM_Token_Issuer_v1.md'
  - ruby scripts/ops/agent_queue_store.rb --queue-file doc/governance/Agent_Work_Queue.yaml
    validate
  - make queue-git-check
  notes: |
    Context:
    IAM Token Issuer v1 reserves audit actions `auth.token.issue` and `auth.token.deny`. Current token endpoints return credential material and should have consistent issuance/denial audit semantics before adding more machine actor classes.

    Required outcome:
    - Add audit rows for successful current machine-token issuance.
    - Add denial audit where the caller has supplied a reusable credential identity that can be attributed safely without logging secrets.
    - Include actor/request metadata without raw tokens, client secrets, private keys, wrapped tokens, or provider credential material.
    - Classify any local 5xx path as `internal_error` and add regression coverage if new error paths are introduced.

    Scope:
    - In: audit rows for existing service-account and shared-runtime operator token endpoints.
    - Out: provider credential sessions, new token actor classes, token revocation UI.

    Evidence required in handoff:
    - audit actions implemented
    - tests proving audit row content excludes credential material
    - exact acceptance commands run
- id: A-IAM-TOKEN-ISSUER-STORAGE-PROVIDER-SESSIONS-001
  title: Define storage provider credential session evidence
  role: A-backend
  status: done
  priority: 2
  owner: Codex
  branch: agent/A-backend
  completed_at: '2026-05-04'
  commit: 697b37a2
  depends_on:
  - A-IAM-TOKEN-ISSUER-ISSUANCE-AUDIT-001
  - A-STORAGE-WEKA-IAM-SHARING-CONTRACT-001
  acceptance_checks:
  - sh -lc 'rg -q "storage_credential_sessions|credential_session_id" doc/architecture doc/api/openapi.draft.yaml'
  - ruby scripts/ops/agent_queue_store.rb --queue-file doc/governance/Agent_Work_Queue.yaml
    validate
  - make queue-git-check
  notes: |
    Context:
    Storage and WEKA need short-lived provider credentials without leaking raw keys into read models. `doc/architecture/Storage_Sharing_and_IAM_Model_v1.md` and `doc/architecture/IAM_Token_Issuer_v1.md` both call out provider credential sessions as evidence, not durable secrets.

    Required outcome:
    - Define the provider credential session schema and OpenAPI response/read-model fields needed by `POST /api/v1/v3/storage/{bucket_id}/credentials`.
    - Keep provider secrets out of durable read models; responses containing credential material are one-time only.
    - Reserve audit actions for storage/provider credential issue/deny/revoke behavior.
    - Do not enable WEKA S3 issuance until capability validation is unblocked.

    Scope:
    - In: contract/schema/design slice for provider credential session evidence.
    - Out: live WEKA S3 credential issuance, provider adapter implementation, UI.
- id: C-CLI-MACOS-SIGNING-HOMEBREW-001
  title: Add macOS CLI signing notarization and Homebrew tap distribution plan
  role: C-ops
  status: todo
  priority: 3
  owner: ''
  branch: agent/C-ops
  completed_at: ''
  commit: ''
  depends_on: []
  acceptance_checks:
  - sh -lc 'test -f doc/operations/CLI_MacOS_Signing_Notarization_and_Homebrew_v1.md'
  - ruby scripts/ops/agent_queue_store.rb --queue-file doc/governance/Agent_Work_Queue.yaml
    validate
  - make queue-git-check
  notes: 'Context:

    macOS users will hit Gatekeeper/quarantine friction with unsigned downloaded CLI
    binaries. Homebrew improves installation UX but does not fully replace signing/notarization
    when distributing prebuilt binaries.

    Required design/runbook:

    - `doc/operations/CLI_MacOS_Signing_Notarization_and_Homebrew_v1.md`

    Required content:

    - compare distribution options: direct release binary, Homebrew formula installing
    prebuilt artifacts, and Homebrew formula building from source

    - use the created distribution repo `git@github.com:core42-us/GPUaaS-cli.git`
    as the initial Homebrew/release publishing target unless product naming changes
    before implementation

    - define target product-grade path: signed and notarized `darwin/amd64` and `darwin/arm64`
    release artifacts plus a Homebrew tap formula with SHA256 verification

    - define demo/internal fallback: direct binary with documented quarantine removal
    only when necessary, clearly marked non-product-grade

    - specify CI secret requirements for Apple Developer ID certificate/keychain and
    notary credentials; no secrets committed

    - specify release artifact names, checksum generation, formula update flow, and
    verification commands on clean macOS

    - decide whether the Homebrew formula should install prebuilt binaries or build
    from source for early releases

    Acceptance for later implementation:

    - `dist/gpuaas-cli-darwin-amd64` and `dist/gpuaas-cli-darwin-arm64` can be signed/notarized
    in release CI or a documented manual release step

    - Homebrew install path works without requiring users to bypass security settings
    for normal product releases

    '
- id: A-CLI-BROWSER-OIDC-PKCE-LOGIN-001
  title: Replace primary CLI login with browser-based OIDC PKCE flow and provider
    hints
  role: A-backend
  status: done
  priority: 3
  owner: Codex
  branch: agent/A-backend
  completed_at: '2026-04-26'
  commit: 01836fda
  depends_on: []
  acceptance_checks:
  - sh -lc 'test -f doc/architecture/CLI_Browser_OIDC_PKCE_Login_v1.md'
  - sh -lc 'go test ./cmd/gpuaas-cli ./pkg/sdk'
  - ruby scripts/ops/agent_queue_store.rb --queue-file doc/governance/Agent_Work_Queue.yaml
    validate
  - make queue-git-check
  notes: 'Context:

    The current CLI demo path uses `auth keycloak-login`, which is Keycloak password
    grant. That is acceptable for local/dev and breakglass-style seeded users, but
    it is not the right primary user model for a cloud provider CLI. Brokered identities
    such as Hugging Face and GitHub cannot use this path cleanly.

    Target product model:

    - `gpuaas auth login` opens a browser to the GPUaaS/Keycloak authorize flow.

    - Use OIDC Authorization Code + PKCE, with a localhost callback when possible
    and a device-code/manual-code fallback for headless terminals.

    - Support provider hints such as `--provider huggingface`, `--provider github`,
    and `--provider sso` by passing the correct Keycloak IdP hint without bypassing
    the normal auth server.

    - Store resulting access/refresh tokens in the CLI config using the existing SDK
    config path initially; document any future OS keychain work separately.

    - Keep service-account auth as the automation path.

    - Keep password grant available only as an explicitly dev/breakglass command,
    e.g. renamed or documented as `auth dev-login`; do not present it as the normal
    user login path.

    Required design doc:

    - `doc/architecture/CLI_Browser_OIDC_PKCE_Login_v1.md`

    Required implementation:

    - CLI command behavior and help text updated.

    - SDK helpers for PKCE verifier/challenge, callback listener or device-code polling
    path, and token exchange.

    - Tests cover PKCE generation, provider hint construction, callback exchange success/failure,
    and no token-in-query leakage.

    Security constraints:

    - Do not pass access tokens, refresh tokens, or app-local tokens in URL query
    parameters.

    - Do not log auth codes, access tokens, refresh tokens, or provider secrets.

    - Preserve service-account token flow for CI/automation.

    '
- id: A-V3-TASK-READMODEL-HANDLERS-001
  title: Add v3 task read-model handlers for routed launch progress
  role: A-backend
  status: done
  priority: 1
  owner: Codex
  branch: agent/A-backend
  completed_at: '2026-04-26'
  commit: 515f5e6f
  depends_on: []
  acceptance_checks:
  - sh -lc 'rg -q "V3TaskListResponse|/api/v1/v3/tasks" doc/api/openapi.draft.yaml
    doc/api/openapi/domains/v3-read-models.yaml'
  - sh -lc 'rg -q "listV3TasksHandler|getV3TaskDetailHandler" cmd/api/routes_v3_tasks.go
    cmd/api/routes_v3_readmodels.go'
  - go test ./cmd/api -run 'TestV3Tasks'
  - pnpm --dir packages/web typecheck
  - ruby scripts/api/bundle_contracts.rb --check
  - ruby scripts/ops/agent_queue_store.rb --queue-file doc/governance/Agent_Work_Queue.yaml
    validate
  - make queue-git-check
  notes: 'Context:

    V3 launch flows route to a durable task view after submit, but production v3
    only had workload/detail read models and the older allocation timeline. The
    UI needs one task shape for compute launch, app launch, release/restart, and
    later app operations.

    Completed work:

    - added contract-first `GET /api/v1/v3/tasks` and `GET /api/v1/v3/tasks/{task_id}`

    - implemented allocation-backed task summaries and task details in modular
    v3 route code, with existing allocation timeline enrichment when a DB pool is
    available and synthetic lifecycle fallback otherwise

    - added generated Go/TS types plus web client helpers `listV3Tasks` and `getV3Task`

    - mirrored the task contract into the v3 OpenAPI fragment and updated the read-model
    endpoint map

    '
- id: B-UX-REDESIGN-BASELINE-PLAN-001
  title: Productize the Core42 AI Cloud UX redesign baseline and phased implementation
    plan
  role: B-ui
  status: todo
  priority: 4
  owner: ''
  branch: agent/B-ui
  completed_at: ''
  commit: ''
  depends_on: []
  acceptance_checks:
  - sh -lc 'test -f doc/product/UX_Redesign_Implementation_Plan.md'
  - sh -lc '! find doc/product/ux-mocks -name .DS_Store -type f | grep .'
  - ruby scripts/ops/agent_queue_store.rb --queue-file doc/governance/Agent_Work_Queue.yaml
    validate
  - make queue-git-check
  notes: 'Context:

    The product UI has grown inconsistently across allocation, catalog, launch, admin,
    billing, access, audit, and task/provisioning pages. We now have multiple UX mock
    directions under `doc/product/ux-mocks/` and need one product baseline before
    starting another broad UI implementation pass.

    B should refresh or recreate the `agent/B-ui` worktree from current `master` before
    claiming this task:

    - `git fetch origin`

    - `git switch agent/B-ui`

    - `git rebase origin/master`

    - then `make queue-claim ROLE=B-ui OWNER=B TASK_ID=B-UX-REDESIGN-BASELINE-PLAN-001
    BRANCH=agent/B-ui`

    Review inputs:

    - `doc/product/ux-mocks/product-redesign-v1/README.md`

    - `doc/product/ux-mocks/product-redesign-v1/index.html`

    - `doc/product/ux-mocks/product-redesign-option2/`

    - `doc/product/ux-mocks/product-redesign-v3/README.md`

    - `doc/product/ux-mocks/product-redesign-v3/index.html`

    Primary deliverable:

    - Create `doc/product/UX_Redesign_Implementation_Plan.md`.

    Required doc content:

    - Decision summary: identify the adopted mock direction. The current working assumption
    is `product-redesign-v3` as the baseline, `product-redesign-option2` as visual/reference
    material, and `product-redesign-v1` as the source of the intent-based page-family
    taxonomy.

    - Product information architecture: standardize pages by user intent, not backend
    entity type. Cover Operate, Choose, Async, Detail, Config, Access, Money, Evidence,
    and Triage/Ops.

    - Route model: propose target routes for Control Room, catalog, allocations/workloads,
    task view, billing, access, ops, admin, and MAAS decommission visibility.

    - Shell/navigation model: top context bar with workspace/project, region selector,
    balance/spend, notifications, and account menu; sidebar groups and role-gating;
    count/attention-dot behavior.

    - Shared component inventory: define `AppShell`, `TopContextBar`, `PageHeader`,
    `Card`, `KPI`, `StatusChip`, `DataTable`, `MoreActions`, `Tabs`, `FactsRow`, `CopyableValue`,
    `Timeline`, `TaskTimeline`, `TaskPanel`, `WorkbenchPage`, `DetailPage`, `LaunchWizard`,
    `CatalogCard`, `EmptyState`, and `AlertBanner`.

    - Table/action standard: one primary row action, usually `Open`; secondary actions
    under `MoreActions`; dangerous actions separated; menus must not be clipped by
    table scroll containers.

    - Detail page standard: common detail header, copyable IDs/resource names, facts
    row, tabs, and optional right-side task/event panel.

    - Task/async operation standard: one model for allocation provisioning, slice
    VM provisioning, app deploy, MAAS decommission, node bootstrap/reimage, image
    builds, long-running states, retries, resume/cancel, and event pagination.

    - Launch/catalog flow: catalog card into unified launch wizard, baremetal vs GPU
    slice branching, global/wizard region selection, image/storage/network/access/review
    steps, and at least base Ubuntu plus CUDA/NVIDIA developer image support as product
    direction.

    - Admin page classification: config setup, workflow/lifecycle, evidence, finance/admin,
    IAM/admin, and triage. Explicitly avoid raw entity-dump admin pages.

    - API/read-model gaps: shell summary, task list/detail, timeline pagination/sorting,
    MAAS decommission timeline coverage, fleet health summary, per-device GPU telemetry,
    image catalog, and action availability rules. Mark each as first-pass required
    or future.

    - Phased implementation plan: avoid a rewrite-everything-at-once approach. Include
    pages touched, components introduced, API dependencies, e2e tests to update/add,
    and risks for each phase.

    - Playwright/e2e strategy: stable `data-testid` usage, user-intent assertions,
    shared helpers for login/context selection/MoreActions/launch/task navigation,
    and critical smoke coverage.

    - What not to do yet: no spot pricing, idle suspend lifecycle, savings recommendation
    apply actions, per-GPU telemetry UI without API, fleet heatmap without read model,
    route deletion before redirects, all-pages rewrite in one commit, or backend/OpenAPI
    changes without a follow-up contract task.

    Scope:

    - In: docs under `doc/product/`, cleanup of `.DS_Store` files under `doc/product/ux-mocks/`,
    and a clear implementation plan.

    - Out: `packages/web/**`, backend/runtime/node-agent code, OpenAPI/AsyncAPI changes,
    platform-control/release branch work, or implementing the redesign itself.

    '
- id: B-UI-NIGHT-PASS-001
  title: Execute the overnight v3 workflow UX pass across launch allocations workloads
    and evidence surfaces
  role: B-ui
  status: done
  priority: 3
  owner: B
  branch: agent/B-ui
  completed_at: '2026-04-22'
  commit: f8b4fea8
  depends_on: []
  acceptance_checks:
  - sh -lc 'test -f doc/product/UI_Night_Pass_B_Handoff.md'
  - sh -lc 'test -f doc/product/UX_Implementation_Spec.md'
  - sh -lc 'test -f doc/product/UX_Journeys.md'
  - sh -lc 'test -f doc/product/Admin_Ops_and_User_IA_v1.md'
  - sh -lc 'test -f doc/product/ux-mocks/product-redesign-v3/index.html'
  - ruby scripts/ops/agent_queue_store.rb --queue-file doc/governance/Agent_Work_Queue.yaml
    validate
  - make queue-git-check
  notes: 'Context:

    B should use this task as the authoritative overnight UI implementation pass.
    The scope is not a one-page polish pass; it is a workflow/system cleanup aligned
    to the adopted v3 hybrid redesign and the updated UX contracts.

    Before claiming, refresh the role worktree from current `master`:

    - `git fetch origin`

    - `git switch agent/B-ui`

    - `git rebase origin/master`

    - then `make queue-claim ROLE=B-ui OWNER=B TASK_ID=B-UI-NIGHT-PASS-001 BRANCH=agent/B-ui`

    Primary execution brief:

    - `doc/product/UI_Night_Pass_B_Handoff.md`

    Normative references:

    - `doc/product/ux-mocks/product-redesign-v3/README.md`

    - `doc/product/ux-mocks/product-redesign-v3/index.html`

    - `doc/product/UX_Redesign_Implementation_Plan.md`

    - `doc/product/UX_Implementation_Spec.md`

    - `doc/product/UX_Journeys.md`

    - `doc/product/Admin_Ops_and_User_IA_v1.md`

    - `doc/product/IAM_UX_Information_Architecture_v1.md`

    - `doc/architecture/App_UI_Extension_Model_v1.md`

    Required product outcomes:

    - make the launch flow a real step-by-step wizard with consistent controls and
    review/progress treatment

    - make `/allocations` and `/workloads` follow one shared workbench behavior model

    - keep search/filter/status/view controls visible even when the current result
    set is empty

    - make rows sortable/paginatable with consistent header behavior where the contract
    expects it

    - prevent rows from appearing to vanish after mutation without a visible status
    bucket/path to find them

    - add or reuse a row-detail drilldown pattern for audit/evidence style tables
    instead of truncation-only tables

    - keep detail pages, task/provisioning views, and back behavior consistent across
    these flows

    Implementation order:

    - shared workbench/table/detail/task primitives first

    - launch wizard

    - allocations list/detail

    - workloads list/detail

    - audit/evidence drilldown

    - nearby consistency cleanup only where it supports those flows

    Key starting files:

    - `packages/web/app/allocations/page.tsx`

    - `packages/web/app/workloads/page.tsx`

    - `packages/web/app/apps/instances/[instanceId]/page.tsx`

    - `packages/web/app/admin/allocations/page.tsx`

    - `packages/web/src/lib/api/client.ts`

    - `packages/web/src/lib/apps/workloads.ts`

    Deliverable by morning:

    - working code, not just updated mocks

    - a short summary of changed pages/components, remaining gaps, and any UX-contract
    conflicts found during implementation

    Out of scope for this task:

    - backend/runtime/node-agent changes unless strictly required to unblock the UX
    contract

    - unrelated visual rewrites outside the documented workflow surfaces

    - release branch edits or platform-control promotion work

    '
- id: B-UI-E2E-STABILIZE-001
  title: Replace fragile UI E2E patterns with stable workflow-level validation after
    the v3 UI pass
  role: B-ui
  status: done
  priority: 5
  owner: B
  branch: agent/B-ui
  completed_at: '2026-04-22'
  commit: 1b448b52
  depends_on:
  - B-UI-NIGHT-PASS-001
  acceptance_checks:
  - sh -lc 'test -f doc/product/UI_Night_Pass_B_Handoff.md'
  - sh -lc 'test -f doc/product/UX_Implementation_Spec.md'
  - sh -lc 'test -f doc/product/UX_Journeys.md'
  - sh -lc 'test -f doc/governance/Testing_Standards.md'
  - ruby scripts/ops/agent_queue_store.rb --queue-file doc/governance/Agent_Work_Queue.yaml
    validate
  - make queue-git-check
  notes: 'Context:

    Once the overnight UI pass is validated, B should take a second pass on the web
    E2E/UI test strategy. The current browser tests are too fragile in places: they
    overfit DOM structure, break on harmless UI refactors, and are not consistently
    aligned to workflow-level product behavior.

    This task should only be claimed after `B-UI-NIGHT-PASS-001` is done and the updated
    UX flows are available to validate against.

    Before claiming:

    - `git fetch origin`

    - `git switch agent/B-ui`

    - `git rebase origin/master`

    - then `make queue-claim ROLE=B-ui OWNER=B TASK_ID=B-UI-E2E-STABILIZE-001 BRANCH=agent/B-ui`

    Reference docs:

    - `doc/product/UI_Night_Pass_B_Handoff.md`

    - `doc/product/UX_Implementation_Spec.md`

    - `doc/product/UX_Journeys.md`

    - `doc/governance/Testing_Standards.md`

    Required outcomes:

    - review the current Playwright/UI test suite and identify brittle selectors,
    structure-coupled assertions, and duplicated login/context setup

    - replace fragile patterns with stable workflow-oriented helpers and `data-testid`
    usage where the UX contract requires stable automation hooks

    - prefer user-intent assertions over brittle markup assertions

    - align critical coverage around launch, allocations, workloads, audit/evidence
    drilldown, project/workspace context, and task/provisioning navigation

    - remove or rewrite tests that are only preserving accidental layout details rather
    than product behavior

    - document any remaining backend/read-model gaps that still make stable E2E coverage
    hard

    Guidance:

    - do not paper over bad UX or race conditions only by increasing sleeps/timeouts

    - if a test is unstable because the product lacks a stable state boundary, fix
    the product/test hook at the owning layer where reasonable

    - favor shared test helpers for login, workspace/project switching, launch flow,
    MoreActions access, and row/detail navigation

    Deliverable:

    - improved E2E/UI automation that survives the v3 workflow refactor

    - concise summary of what was deleted, rewritten, or newly stabilized

    Out of scope:

    - broad backend/runtime refactors unrelated to enabling stable UX validation

    - adding coverage for unfinished product flows whose UX contract is still unsettled

    '
- id: B-UI-V3-CONSISTENCY-FIRST-PASS-001
  title: Apply the v3 shared-component consistency pass across user admin launch catalog
    and evidence surfaces
  role: B-ui
  status: done
  priority: 2
  owner: B
  branch: agent/B-ui
  completed_at: '2026-04-22'
  commit: 2a98f87b
  depends_on:
  - B-UI-NIGHT-PASS-001
  acceptance_checks:
  - sh -lc 'test -f doc/product/UX_Consistency_First_Pass_Handoff.md'
  - sh -lc 'test -f doc/product/UX_Redesign_Implementation_Plan.md'
  - sh -lc 'test -f doc/product/UX_Implementation_Spec.md'
  - pnpm --dir packages/web typecheck
  - make verify-web
  - ruby scripts/ops/agent_queue_store.rb --queue-file doc/governance/Agent_Work_Queue.yaml
    validate
  - make queue-git-check
  notes: 'Context:

    The shared v3 component foundation has landed, but the product still has inconsistent
    behavior across user and admin surfaces. Some fixes exist in one role surface
    but not the matching user/admin surface; for example audit-log detail/copy behavior
    is present in admin but not consistently in user audit surfaces. The new `/launch`
    wizard exists, but catalog-driven launch still uses the older path and does not
    share the same availability-first decision model. The goal of this task is a broad
    first pass to make the product feel cohesive before the demo, not a final pixel-perfect
    rewrite.

    Before claiming, refresh the role worktree from current `master`:

    - `git fetch origin`

    - `git switch agent/B-ui`

    - `git rebase origin/master`

    - then `make queue-claim ROLE=B-ui OWNER=B TASK_ID=B-UI-V3-CONSISTENCY-FIRST-PASS-001
    BRANCH=agent/B-ui`

    Primary references:

    - `doc/product/ux-mocks/product-redesign-v3/README.md`

    - `doc/product/ux-mocks/product-redesign-v3/index.html`

    - `doc/product/UX_Redesign_Implementation_Plan.md`

    - `doc/product/UX_Implementation_Spec.md`

    - `doc/product/UX_Journeys.md`

    - `doc/product/Admin_Ops_and_User_IA_v1.md`

    - `doc/product/E2E_Selector_Contract.md`

    Use the shared components already available from `packages/web/src/components/product/`:

    - `ProductPage`, `ProductPageHeader`, `ProductSummaryStrip`, `ProductToolbar`

    - `StatusTabs`, `DataTable`, `DetailDrawer`, `Timeline`, `TaskTimeline`, `AlertBanner`,
    `MoreActions`

    Required first-pass outcomes:

    - Make catalog launch and sidebar `/launch` converge on one launch model. Catalog
    cards may still be the entry point, but they should route into the same wizard
    behavior and preserve the useful catalog-card context. `/launch` must show availability/status
    before the user commits to a product selection.

    - Apply one table/workbench behavior contract across user and admin pages: consistent
    search/filter/status controls, sortable headers where tables use `DataTable`,
    pagination/empty states, one primary row action, secondary actions under `MoreActions`,
    and controls remaining visible when a result set is empty.

    - Remove raw resource-name/entity-dump presentation from primary columns where
    possible. Show human names/status in the row, keep full resource IDs in detail
    drawers with copy affordances.

    - Normalize evidence/audit surfaces for both user and admin views. Detail drawers
    should expose full target/action/result/correlation data, raw JSON where useful,
    copy affordances, and redaction of obvious sensitive values before display (`kubeconfig`,
    tokens, passwords, private keys, access credentials).

    - Normalize workload/app presentation. Healthy state should not render as error
    red text. Fast refresh should not flicker or make rows appear to vanish without
    an obvious status bucket/path. Failed/stopped/released resources should remain
    discoverable through filters.

    - Take a first pass across all Admin pages using the new IA model. Admin should
    read as operator workflows and triage surfaces, not raw entity dumps. Group setup/config,
    lifecycle operations, evidence, IAM/user/project management, finance, and MAAS/fleet
    operations consistently. If a page cannot be fully converted tonight, at least
    wrap it in the shared product shell, normalize its toolbar/table/detail behavior,
    and document the remaining workflow gap.

    - Add metrics/graph placeholders only where they are backed by current API data
    or a clearly documented empty/loading state. Existing Netdata backed allocation/node
    metrics may be used where already exposed by the API. Do not render fake fleet
    heatmaps, per-GPU tables, spend charts, or sparklines as if they are live. Instead,
    document the exact read-model/API gaps for: fleet health summary, per-GPU telemetry
    (utilization/VRAM/power/temp/ECC), allocation-list sparkline summaries, and billing
    daily spend aggregates.

    - Make project lifecycle visible if the existing API/client already supports it:
    create, manage, default/switch, and delete/leave semantics. If an API or read
    model is missing, document the exact gap instead of faking behavior.

    - Improve developer docs/API docs integration so docs feel in-product. Avoid opening
    API docs in a disconnected new-window experience when an embedded route can provide
    the same value.

    - Keep the work demo-oriented: polish the flows an executive/user will actually
    touch, then document remaining consistency gaps.

    Scope:

    - In: `packages/web/**` UI code, web tests, docs/handoff under `doc/product/`,
    route/link cleanup needed for consistency, and UI-only graph component placeholders
    wired only to existing real data or explicit unavailable states.

    - Out: backend Go code, OpenAPI/AsyncAPI changes, platform-proxy runtime work,
    MAAS/slice runtime work, platform-control release branch work, or broad visual
    redesign beyond the v3 shared-component system.

    Deliverable:

    - Working code pushed to `agent/B-ui`.

    - `doc/product/UX_Consistency_First_Pass_Handoff.md` summarizing changed pages,
    remaining inconsistencies, screenshots or concise visual notes, API/read-model
    gaps, and exact validation commands/results.

    - Preserve or extend the `data-testid` selector contract for changed pages and
    controls.

    '
- id: A-NODE-AGENT-RUNTIME-OPERATOR-PRIMITIVES-001
  title: Add bounded node-agent runtime operator primitives for artifact fetch install
    and service lifecycle work
  role: A-backend
  status: done
  priority: 994
  owner: Codex
  branch: agent/A-backend
  completed_at: '2026-03-10'
  commit: ec67382
  depends_on:
  - A-APP-RUNTIME-SECRET-DELIVERY-001
  acceptance_checks:
  - make test-integration-selected
  - make queue-git-check
  notes: 'Context:

    Before Slurm or any other platform app can be usable without manual host intervention,
    node-agent needs typed runtime operator primitives for artifact fetch, staged
    install/update, and service lifecycle work.


    Scope:

    - In: bounded typed operator primitives, audit/result reporting, and no arbitrary
    remote-shell semantics.

    - Out: scheduler-specific adapter logic.

    '
- id: A-CONTRACT-001
  title: Remove OpenAPI 3.1 to 3.0 codegen downgrade once Go toolchain supports 3.1
    end-to-end
  role: A-backend
  status: blocked
  priority: 32
  owner: agent-a
  branch: agent/A-backend
  completed_at: ''
  commit: ''
  depends_on:
  - A-TENANT-IMPL-002
  acceptance_checks:
  - make codegen | tee /tmp/codegen.log
  - sh -lc 'rg -q "^openapi" doc/api/openapi.draft.yaml && rg -q "3.1.0" doc/api/openapi.draft.yaml'
  - sh -lc '! rg -q \"3.1.x specification.*not yet supported|recommended to downgrade\"
    /tmp/codegen.log'
  notes: 'Context:

    The canonical API contract remains a single generated OpenAPI artifact today because
    that keeps codegen and review simple while the platform is still consolidating.
    This task should only be reopened when the toolchain fully supports the target
    OpenAPI version without downgrade workarounds.

    Keep 3.1 as source-of-truth. Remove build-time conversion only when codegen and
    contract validation/tests pass directly from 3.1 without compatibility warnings.

    Reopen trigger: upstream oapi-codegen supports OpenAPI 3.1 end-to-end without
    downgrade warning output.

    '
- id: A-API-DOMAIN-AUTHORING-SPLIT-001
  title: Split OpenAPI and AsyncAPI authoring by domain while preserving one canonical
    generated contract
  role: A-backend
  status: done
  priority: 140
  owner: Codex
  branch: agent/A-backend
  completed_at: '2026-04-26'
  commit: 6b1c7a3b
  depends_on: []
  acceptance_checks:
  - make codegen
  - bash scripts/ci/contracts_validate.sh
  - make queue-git-check
  notes: 'Context:

    The current single-file `doc/api/openapi.draft.yaml` and `doc/api/asyncapi.draft.yaml`
    remain acceptable for now, but the platform is converging on explicit domains
    (`IAM`, `Billing`, `Provisioning.Allocation`, `Provisioning.BareMetal.MAAS`, `Inventory.Catalog`,
    `App Platform`, `UX`, `Operations`). Once contract churn and review ownership
    follow those domains more strongly, authoring should move to domain-scoped fragments
    while still producing one canonical generated contract for codegen and external
    consumers.

    Trigger:

    - Reopen when at least two of these hold: 1. multiple domains are editing the
    same top-level contract file in parallel often enough to create review noise,
    2. one contract review regularly mixes unrelated domain changes, 3. a new domain
    such as `Provisioning.BareMetal.MAAS` or `App Platform` adds enough surface that
    ownership in one file is no longer clear, 4. codegen/bundling can preserve one
    canonical generated artifact without weakening contract-first workflow.

    Scope:

    - In: domain-scoped authoring layout for OpenAPI and AsyncAPI contracts, bundling/generation
    into canonical published specs, ownership notes per fragment, # gitleaks:allow
    and unchanged client/server codegen inputs.

    - Out: splitting the public API into multiple externally versioned APIs or changing
    runtime deployment boundaries.

    Delivered:

    - added OpenAPI and AsyncAPI domain-authoring manifests in canonical mode - added
    `scripts/api/bundle_contracts.rb --check|--write` so CI/codegen can validate canonical
    mode now and fragment bundle drift later - documented the long-term authoring
    model in `doc/architecture/API_Domain_Authoring_Model_v1.md` - wired the authoring
    check into `make codegen` and `scripts/ci/contracts_validate.sh` - split v3 read-model
    route registration and handlers into `cmd/api/routes_v3_readmodels.go` as the
    first route-domain module

    '
- id: A-APP-RUNTIME-EXTERNAL-WORKER-CONTRACT-001
  title: Define and implement the external app-worker runtime contract so app lifecycle
    logic can move out of platform-core switches
  role: A-backend
  status: done
  priority: 143
  owner: codex
  branch: agent/A-backend
  completed_at: '2026-04-28'
  commit: 3456f8f5
  depends_on: []
  acceptance_checks:
  - make codegen
  - bash scripts/ci/contracts_validate.sh
  - make queue-git-check
  notes: 'Context:

    The long-term app platform boundary should be a narrow runtime API plus scoped
    machine identity for app-owned workers. Internal reference apps such as Slurm
    have proven many of the needed primitives, but some lifecycle logic still lives
    in platform-core code paths.

    Requirements:

    - define the public runtime report/query API boundary for app-owned workers

    - define the app-worker auth/identity model and route allowlist

    - define whether the first public delivery mechanism is slug-scoped NATS, polling,
    or both

    - define manifest/schema registration direction for app onboarding

    - extract at least one reference-app lifecycle path to use the external-style
    contract instead of platform-core switch logic

    Scope:

    - In: contract design and first extraction slice for the external worker model

    - Out: forcing Temporal or NATS as the only internal orchestration style for all
    apps

    '
- id: A-APP-RUNTIME-K8S-RECONCILE-REPAIR-001
  title: Define Kubernetes runtime reconcile and repair lifecycle semantics
  role: A-backend
  status: done
  priority: 144
  owner: codex
  branch: agent/A-backend
  completed_at: '2026-04-28'
  commit: 28ccd4a2
  depends_on:
  - A-APP-RUNTIME-EXTERNAL-WORKER-CONTRACT-001
  acceptance_checks:
  - make codegen
  - bash scripts/ci/contracts_validate.sh
  - make queue-git-check
  notes: 'Context:

    RKE2 stop and start have clear service lifecycle semantics, but "restart" can
    mean different things across single-node and multi-node Kubernetes clusters. We
    should not expose a dummy status-only restart because it gives users a false sense
    that the cluster was reconciled.

    Requirements:

    - define whether Kubernetes restart should exist as a user action or be replaced
    by reconcile/repair

    - define single-node versus multi-node behavior for control-plane, agent, and
    whole-cluster repair

    - define progress and activity events for repair steps so long-running actions
    do not look stuck

    - define safe failure behavior and rollback expectations when a repair partially
    succeeds

    Scope:

    - In: product semantics, API contract, controller behavior, and UI action naming
    for RKE2 repair/reconcile.

    - Out: adding status-only lifecycle completion for Kubernetes restart.

    '
- id: A-PLATFORM-PROXY-FIRST-SLICE-001
  title: Define and implement the first platform-proxy control-plane slice for workload
    HTTP and WebSocket access
  role: A-backend
  status: done
  priority: 145
  owner: Codex
  branch: agent/A-backend
  completed_at: '2026-04-27'
  commit: 9b17d96d
  depends_on: []
  acceptance_checks:
  - sh -lc 'test -f doc/architecture/Platform_Proxy_Implementation_Checklist_v1.md'
  - sh -lc 'test -f doc/architecture/Embedded_UI_Gateway_Contract_v1.md'
  - sh -lc 'test -f doc/architecture/Launchable_OCI_Workload_Profile_Contract_v1.md'
  - make codegen
  - bash scripts/ci/contracts_validate.sh
  - make queue-git-check
  notes: 'Context:

    The repo already accepts `exposure_mode: platform_proxy` in launchable OCI profile
    metadata and app-runtime validation, but there is no real route lifecycle, API
    surface, or browser-facing gateway for those routes yet. The workload detail UI
    currently shows a placeholder that the proxy-managed URL is not wired.

    This task should produce the first control-plane slice for platform proxy without
    coupling it to broad public IP/BGP/NAT work and without depending on the B-ui
    overnight refactor lane.

    Primary references:

    - `doc/architecture/Platform_Proxy_Implementation_Checklist_v1.md`

    - `doc/architecture/Embedded_UI_Gateway_Contract_v1.md`

    - `doc/architecture/Launchable_OCI_Workload_Profile_Contract_v1.md`

    - `doc/architecture/Public_Endpoint_IP_Assignment_Model_v1.md`

    Required outcomes:

    - define the first route/read-model contract for proxy-backed workload endpoints

    - update OpenAPI first for any route/status fields or new proxy lifecycle endpoints

    - add backend persistence/read-model support for route allocation state

    - add lifecycle hooks so app/workload status can drive proxy route create/remove
    intent

    - keep the first slice scoped to HTTP/HTTPS/WebSocket-aware workload routes

    - keep public IP assignment, BGP, and general NAT automation out of scope

    Guidance:

    - prefer a route/status/read-model foundation first, not UI polish first

    - do not make the API/control plane the general tenant data path

    - preserve the embedded-vs-link_out boundary from the gateway contract

    - avoid touching broad shared UI files owned by the B-ui overnight lane unless
    a narrow contract hook is required

    Deliverable:

    - contract-first backend/control-plane groundwork for a first platform-proxy slice

    - concise summary of remaining gateway/runtime pieces after the control-plane
    model lands

    '
- id: A-ALLOCATION-GROUP-MODEL-001
  title: Define allocation-group or cluster model separately from single-node allocations
  role: A-backend
  status: done
  priority: 144
  owner: codex
  branch: agent/A-backend
  completed_at: '2026-04-28'
  commit: 463d3b0d
  depends_on: []
  acceptance_checks:
  - make codegen
  - bash scripts/ci/contracts_validate.sh
  - make queue-git-check
  notes: 'Context:

    Users may need one action that provisions many nodes, but the current `allocation`
    object is intentionally single-node: one node, one connection target, one release
    lifecycle, one billing lifecycle. Batch-create can satisfy immediate UX needs
    while preserving that invariant.

    This future task exists to prevent overloading `allocation` itself with mutable
    multi-node membership. If users later need named groups, dynamic add/remove of
    members, aggregate status, or group-level release semantics, introduce an explicit
    parent object such as `allocation_group` or `cluster` that owns many normal allocations.

    Scope:

    - In: contract and lifecycle design for group/cluster semantics on top of independent
    member allocations

    - Out: changing the meaning of the existing single-node allocation object

    '
- id: A-ALLOCATION-POLICY-ADMIN-SURFACE-001
  title: Add admin API and UI for policy values and overrides affecting allocation
    quotas
  role: A-backend
  status: done
  priority: 145
  owner: Codex
  branch: agent/A-backend
  completed_at: '2026-04-06'
  commit: 4212d111
  depends_on: []
  acceptance_checks:
  - make codegen
  - go test ./cmd/api ./packages/shared/policy
  - make verify-web
  - make queue-git-check
  notes: 'Context:

    Allocation concurrency and other quota-like behavior are currently driven by `policy_values`,
    but operators cannot inspect or modify those values through a supported admin
    surface. That leaves live quota management dependent on direct DB operations,
    which is not acceptable for normal admin workflows.

    Required outcome:

    - add an admin read API for effective policy values and scoped overrides relevant
    to allocation/quota behavior - add an admin mutation API and UI for updating those
    values with audit logging - surface effective scope/source so operators can distinguish
    global defaults from org/project overrides - include allocation-relevant defaults
    now visible in the user marketplace such as `allocation.max_concurrent_per_user`,
    so admin changes can be verified without direct DB inspection

    Delivered slice:

    - added global admin API + UI for `allocation.max_concurrent_per_user` - updates
    append new `policy_values` rows, write `policy_change_events`, write `audit_logs`,
    and invalidate policy cache - added `/admin/quotas` as the first operator-facing
    quota control surface - remaining follow-up is broader scoped override management
    (org/project) and additional quota-like policies beyond this first allocation
    limit

    Scope:

    - In: policy read/update surface for allocation-relevant limits and overrides,
    with auditability - Out: a full generic rules engine or arbitrary tenant self-service
    policy editing in the same slice

    '
- id: B-USER-QUOTA-LIMITS-PAGE-001
  title: Add a user-visible quota and limits page for effective allocation headroom
    and other provisioning restrictions
  role: B-ui
  status: todo
  priority: 146
  owner: ''
  branch: agent/B-ui
  completed_at: ''
  commit: ''
  depends_on: []
  acceptance_checks:
  - make codegen
  - make verify-web
  - make queue-git-check
  notes: 'Context:

    Users currently need a clear explanation of how many allocations they can hold,
    how much headroom remains, and which platform-side restrictions will block provisioning.
    The short-term limit summary near marketplace/allocations helps, but the product
    still lacks a dedicated quota/limits surface.

    Required outcome:

    - add a user-facing quota/limits page or panel that shows effective concurrent
    allocation limit, current usage, remaining headroom, and other provisioning-relevant
    restrictions - distinguish quota from capacity so users can tell "policy blocked"
    apart from "no nodes available" - reuse the new allocation limits API/read-model
    as the baseline and extend it deliberately - cover both the passive summary now
    shown on marketplace/allocations and the active provisioning path where quantity
    selection is bounded by quota headroom and free-node capacity

    Scope:

    - In: user-visible limits/quota UX and supporting API consumption - Out: admin
    policy editing workflows, which belong to the separate admin policy task

    '
- id: A-ALLOCATION-STORAGE-MODEL-001
  title: Define storage attachment and persistence model for allocations before exposing
    shared storage UX
  role: A-backend
  status: done
  priority: 147
  owner: Codex
  branch: agent/A-backend
  completed_at: '2026-04-10'
  commit: 3dfd8073
  depends_on: []
  acceptance_checks:
  - make queue-git-check
  notes: 'Context:

    Storage is the largest remaining product gap for serious allocation users. Before
    implementing user-facing attach flows, the platform needs a clear model for per-allocation
    versus shared storage, multi-attach semantics, detach/release behavior, and persistence
    guarantees.

    Required outcome:

    - document storage object types and attachment semantics - define whether attach
    is allowed only during allocation create or also after create - define lifecycle
    after allocation release - clarify whether the first storage backend can be shared
    across many allocations safely and under what read/write guarantees

    Inputs:

    - doc/product/Allocation_Experience_Gaps_v1.md

    '
- id: A-K8S-RKE2-STORAGE-INTEGRATION-DESIGN-001
  title: Define RKE2 external storage and exposure model before adding Kubernetes
    storage UX
  role: A-backend
  status: done
  priority: 148
  owner: codex
  branch: agent/A-backend
  completed_at: '2026-04-28'
  commit: 93649007
  depends_on:
  - A-ALLOCATION-STORAGE-MODEL-001
  acceptance_checks:
  - rg -q "RKE2 external storage" doc
  - rg -q "StorageClass" doc
  - bash scripts/ci/agent_queue_validate.sh
  - make queue-git-check
  notes: 'Context:

    The current self-managed RKE2 app uses the default RKE2 Canal CNI with VXLAN pod
    overlay and does not install a StorageClass. Storage should not be exposed as
    a guess in the app UI until infra confirms the backend and external exposure model.

    Required outcome:

    - document the storage backend choice for RKE2 clusters, including whether WEKA
    or another CSI-backed backend is the first supported target - define the StorageClass
    and CSI installation/configuration contract owned by GPUaaS versus tenant workloads
    - define how storage attachments map from GPUaaS allocation/app intent into Kubernetes
    PVCs and mount paths - clarify multi-allocation and multi-app attach semantics,
    including RWO/RWX behavior, detach behavior, and release/decommission cleanup
    - define the data path and exposure model so high-throughput storage traffic uses
    the intended host/storage network rather than relying on pod VXLAN - document
    what, if anything, should be externally exposed for storage access outside the
    RKE2 cluster

    Inputs needed:

    - infra decision on first storage backend and CSI support - infra decision on
    external storage access/exposure boundaries - confirmation of WEKA multi-attach
    semantics if WEKA is selected

    Scope:

    - In: design/spec task for RKE2 storage integration, StorageClass/CSI contract,
    GPUaaS attachment mapping, and exposure boundaries - Out: implementing CSI installation,
    storage UI attach flows, or app bundle PVC generation before the infra answers
    are available

    '
- id: A-ALLOCATION-RESTART-001
  title: Add self-service allocation restart lifecycle for active allocations
  role: A-backend
  status: done
  priority: 148
  owner: Codex
  branch: agent/A-backend
  completed_at: '2026-04-10'
  commit: 3dfd8073
  depends_on: []
  acceptance_checks:
  - make codegen
  - go test ./cmd/api ./packages/services/inventory
  - make verify-web
  - make queue-git-check
  notes: 'Context:

    GPU users expect reboot without releasing the allocation. Restart should preserve
    allocation identity while interrupting sessions and workloads intentionally, then
    returning the allocation to active or an explicit restart-failed state.

    Required outcome:

    - add allocation restart API and UI - route restart through the normal async control-plane
    / node-agent path - preserve SSH access metadata across reboot - surface restart
    progress and failure states to the user

    Inputs:

    - doc/product/Allocation_Experience_Gaps_v1.md

    '
- id: A-ALLOCATION-PROJECT-SSH-ACCESS-001
  title: Define and implement project-scoped SSH access sharing for live allocations
  role: A-backend
  status: done
  priority: 149
  owner: A
  branch: agent/A-backend
  completed_at: '2026-04-28'
  commit: 821be254
  depends_on: []
  acceptance_checks:
  - make codegen
  - go test ./cmd/api ./packages/services/inventory ./packages/services/auth
  - make verify-web
  - make queue-git-check
  notes: 'Context:

    Personal SSH-key management and allocation-level key swapping are useful, but
    they do not solve team handoff. Another project member should be able to gain
    SSH access to a live allocation with their own public key without requiring the
    original owner to share a private key.

    Required outcome:

    - define project/member authz model for allocation access grants - define who
    may add/remove project-member access - ensure the granted user supplies their
    own public key material - audit every access-change mutation

    Inputs:

    - doc/product/Allocation_Experience_Gaps_v1.md

    '
- id: A-MANAGED-RUNTIME-BUNDLES-001
  title: Define and implement managed runtime bundles layered on top of allocations
  role: A-backend
  status: done
  priority: 150
  owner: A
  branch: agent/A-backend
  completed_at: '2026-04-28'
  commit: 1675985c
  depends_on: []
  acceptance_checks:
  - make codegen
  - go test ./cmd/api ./packages/services/appruntime ./packages/services/inventory
  - make verify-web
  - make queue-git-check
  notes: 'Context:

    Users need framework choice such as PyTorch, but that choice should not turn raw
    allocation provisioning into a slow image matrix. Managed runtime bundles are
    the product layer above driver-ready compute.

    Required outcome:

    - define bundle model, ownership boundary, and platform-owned install paths -
    support optional initial runtime choice during allocation create - support later
    apply/change of a managed runtime bundle on an existing allocation - keep arbitrary
    user SSH-installed state outside platform ownership

    Inputs:

    - doc/product/Managed_Runtime_Bundles_v1.md - doc/product/Allocation_Experience_Gaps_v1.md

    '
- id: A-LAUNCHABLE-OCI-WORKLOAD-IMAGES-001
  title: Define OCI-based launchable workload images such as JupyterLab and vLLM as
    a separate app class
  role: A-backend
  status: done
  priority: 151
  owner: agent-a
  branch: agent/A-backend
  completed_at: '2026-04-12'
  commit: 19f682bf
  depends_on: []
  acceptance_checks:
  - make queue-git-check
  notes: 'Context:

    Some user experiences are better modeled as launchable OCI images than as raw
    compute or node-local managed runtimes. Examples include JupyterLab and vLLM.
    The platform should use OCI as the first canonical packaging format and pre-seed
    supported images in the platform registry.

    Required outcome:

    - document this app class separately from managed runtime bundles - define launch-on-existing-allocation
    as the first operating mode - define workspace/storage mount expectations - keep
    Apptainer or other adapters as future extensions rather than first-format requirements

    Inputs:

    - doc/product/Launchable_OCI_Workload_Images_v1.md - doc/architecture/Launchable_OCI_Workload_Profile_Contract_v1.md

    '
- id: A-LOCAL-API-BOOTSTRAP-SHIFT-001
  title: Shift suitable local bootstrap from direct SQL seed to API-driven domain
    bootstrap helpers
  role: A-backend
  status: done
  priority: 141
  owner: codex
  branch: agent/A-backend
  completed_at: '2026-04-28'
  commit: e73e1678
  depends_on: []
  acceptance_checks:
  - make queue-git-check
  notes: 'Context:

    `scripts/seed.sql` bootstraps local development quickly, but it bypasses the CRUD,
    validation, defaulting, and audit paths that domain-owned admin APIs are meant
    to exercise. The new local MAAS helper showed that API-backed bootstrap can both
    populate local fixtures and validate the real control-plane surface.

    Requirements:

    - inventory current seed rows and classify them as foundational SQL seed vs product-managed
    runtime objects

    - define a rule for what stays in SQL (`policy_values`, static catalogs, foundational
    reference data) vs what should move to API-backed helpers once the owning domain
    CRUD exists

    - convert at least one additional suitable local bootstrap path from direct SQL
    to an API helper with a local-dev make/script entrypoint

    - document that API-backed bootstrap helpers are intended to validate domain CRUD/probe
    flows locally, not just insert fixtures

    Scope:

    - In: local-dev bootstrap path review, API-backed helper additions, docs/make
    target updates

    - Out: removal of foundational SQL seed for static policy/catalog/reference data

    '
- id: A-SKU-RESOURCE-MODEL-EXPANSION-001
  title: Revisit SKU model to support GPU and CPU node flavors with explicit CPU memory
    and storage resources
  role: A-backend
  status: done
  priority: 142
  owner: codex
  branch: agent/A-backend
  completed_at: '2026-04-28'
  commit: 4a68b713
  depends_on: []
  acceptance_checks:
  - make codegen
  - bash scripts/ci/contracts_validate.sh
  - make queue-git-check
  notes: 'Context:

    The current SKU model is intentionally GPU-shaped: `gpus_total` is required and
    billing/placement assume GPU-hour semantics. As the platform expands into CPU-only
    compute and richer hardware classes, the SKU/resource contract will need a broader
    model rather than overloading `gpus_total=0`.


    Scope:

    - In: future resource-model redesign for GPU and CPU node flavors, including explicit
    CPU, memory, and storage dimensions and the resulting contract/schema implications.

    - Out: weakening the current GPU-only SKU invariants before the replacement model
    exists.

    '
- id: A-CONTROL-PLANE-K8S-POSTGRES-MIGRATION-001
  title: Migrate Postgres last into gpuaas-infra with explicit persistence backup
    and rollback plan
  role: A-backend
  status: todo
  priority: 935
  owner: ''
  branch: ''
  completed_at: ''
  commit: ''
  depends_on:
  - A-CONTROL-PLANE-K8S-KEYCLOAK-MIGRATION-001
  acceptance_checks:
  - rg -q "Postgres|backup|rollback|persistence" doc/operations/Control_Plane_K8s_Migration_v1.md
  - make queue-git-check
  notes: 'Context:

    Postgres is intentionally last because it is the highest blast-radius infra dependency.
    This migration requires explicit persistence, backup, restore, and rollback handling
    rather than a simple manifest move.


    Invariants (must not break):

    - immutable ledger and audit data remain intact

    - schema/seed/bootstrap paths remain automation-owned

    - rollback does not rely on manual reconstruction


    Scope:

    - In: Postgres migration planning and execution baseline in `gpuaas-infra`.

    - Out: broader production HA/postgres operator adoption.


    Evidence required in handoff:

    - files changed

    - commit SHA

    - exact acceptance commands run

    - pass/fail status by command

    '
- id: A-ADMIN-OPS-SUMMARY-CONTRACT-001
  title: Add additive admin ops summary fields only if UI restructure needs backend
    simplification
  role: A-backend
  status: todo
  priority: 927
  owner: agent-a
  branch: agent/A-backend
  completed_at: ''
  commit: ''
  depends_on:
  - B-ADMIN-OPS-UX-REDESIGN-001
  acceptance_checks:
  - bash scripts/ci/contracts_validate.sh
  - go test ./cmd/api
  notes: 'Context:

    The preferred path is UI restructuring without backend churn. This task exists
    only if the redesigned admin ops page proves that current `/api/v1/admin/ops/overview`
    fields force too much client-side interpretation.


    Pre-read (required):

    - doc/product/Admin_Ops_and_User_IA_v1.md

    - doc/api/openapi.draft.yaml

    - packages/web/app/admin/ops/page.tsx


    Invariants (must not break):

    - additive contract change only.

    - no observability signal reclassification without review.

    - do not push presentation-only concerns into the backend unless they materially
    simplify operator correctness.


    Scope:

    - In: optional summary-field additions for auth/release/action-required rollups.

    - Out: full admin ops contract redesign.

    '
- id: A-APP-OCI-REGISTRY-IMPLEMENTATION-001
  title: Run a real OCI registry on platform_control and point app artifact registry
    info at it
  role: A-backend
  status: done
  priority: 926
  owner: agent-a
  branch: agent/A-backend
  completed_at: '2026-03-10'
  commit: 8a702ee
  depends_on:
  - A-APP-OCI-REGISTRY-BASELINE-001
  acceptance_checks:
  - sh -lc 'PLATFORM_CONTROL_REGISTRY_BASE_URL=https://registry.100-90-157-34.sslip.io
    PLATFORM_CONTROL_API_URL=https://api.100-90-157-34.sslip.io PLATFORM_CONTROL_WEB_URL=https://app.100-90-157-34.sslip.io
    PLATFORM_CONTROL_KEYCLOAK_URL=https://auth.100-90-157-34.sslip.io PLATFORM_CONTROL_GRAFANA_BASE_URL=https://grafana.100-90-157-34.sslip.io
    PLATFORM_CONTROL_PROMETHEUS_BASE_URL=https://prometheus.100-90-157-34.sslip.io
    PLATFORM_CONTROL_LOKI_BASE_URL=https://loki.100-90-157-34.sslip.io PLATFORM_CONTROL_TEMPO_BASE_URL=https://tempo.100-90-157-34.sslip.io
    PLATFORM_CONTROL_NODE_API_URL=http://100.90.157.34:18081 PLATFORM_CONTROL_WEBHOOK_BASE_URL=skip
    PLATFORM_CONTROL_SSH_HOST=hpcadmin@100.90.157.34 bash scripts/ci/platform_control_remote_validation.sh'
  notes: 'Context:

    Move the app artifact registry from a declarative placeholder to a real platform-owned
    service in `gpuaas-infra`. The API already exposes registry info and artifact
    lifecycle metadata; this task makes the advertised registry endpoint real.


    Scope:

    - In: k8s registry deployment, ingress exposure, core config wiring, remote validation.

    - Out: authenticated publish credentials, registry replication/HA, promotion enforcement
    against registry state.

    '
- id: A-APP-RUNTIME-ADAPTER-SLURM-001
  title: Implement first real app runtime adapter using the scheduler-as-platform-app
    Slurm path
  role: A-backend
  status: todo
  priority: 924
  owner: ''
  branch: ''
  completed_at: ''
  commit: ''
  depends_on:
  - A-APP-OCI-REGISTRY-IMPLEMENTATION-001
  - A-APP-RUNTIME-SECRET-DELIVERY-001
  - A-NODE-AGENT-RUNTIME-OPERATOR-PRIMITIVES-001
  - A-NODE-LIFECYCLE-RETIRE-DRAIN-001
  acceptance_checks:
  - bash scripts/ci/contracts_validate.sh
  - make test-integration-selected
  - make queue-git-check
  notes: 'Context:

    The app control plane now has artifact metadata, trust enforcement, and a real
    OCI registry endpoint. The next runtime step should be narrow and concrete: use
    the Slurm reference path as the first adapter instead of inventing a universal
    runtime abstraction.


    Scope:

    - In: first executable app runtime adapter against the documented Slurm reference
    model.

    - Out: multi-backend abstraction fantasy, generic managed scheduler service.

    '
- id: A-SLURM-ADAPTER-CONTRACT-AND-MANIFEST-001
  title: Define the first Slurm app runtime adapter contract and manifest boundary
  role: A-backend
  status: todo
  priority: 923
  owner: ''
  branch: agent/A-backend
  completed_at: ''
  commit: ''
  depends_on:
  - A-APP-RUNTIME-ADAPTER-SLURM-001
  acceptance_checks:
  - make codegen
  - bash scripts/ci/contracts_validate.sh
  - make queue-git-check
  notes: 'Context:

    Slurm is already the chosen first runtime adapter, but the adapter-owned contract
    boundary still needs to be sharpened before host execution starts. This slice
    should define what the Slurm app version manifest must contain and what generic
    app-instance lifecycle fields remain unchanged.


    Scope:

    - In: Slurm adapter manifest shape, app-instance/runtime metadata expectations,
    and doc/api changes required for the first adapter slice.

    - Out: real controller/worker execution.

    '
- id: A-SLURM-CONTROLLER-BOOTSTRAP-001
  title: Implement first Slurm controller bootstrap path through node operations
  role: A-backend
  status: todo
  priority: 922
  owner: ''
  branch: agent/A-backend
  completed_at: ''
  commit: ''
  depends_on:
  - A-SLURM-ADAPTER-CONTRACT-AND-MANIFEST-001
  - A-APP-RUNTIME-SECRET-DELIVERY-001
  - A-NODE-AGENT-RUNTIME-OPERATOR-PRIMITIVES-001
  acceptance_checks:
  - go test ./packages/services/inventory ./cmd/api
  - make test-integration-selected
  - make queue-git-check
  notes: 'Context:

    The first executable proof should be the smallest real Slurm runtime path: stand
    up the control-plane/controller side through the existing app-instance and node-operation
    model without inventing raw SSH or special core handlers.


    Scope:

    - In: controller artifact/config delivery, service bootstrap, health verification,
    and app-instance lifecycle mapping.

    - Out: worker fleet join/drain/remove behavior.

    '
- id: A-APP-ACCESS-CREDENTIAL-CUSTODY-COMPLETION-001
  title: Complete platform access-credential custody APIs for app-managed machine
    credentials
  role: A-backend
  status: todo
  priority: 921
  owner: ''
  branch: agent/A-backend
  completed_at: ''
  commit: ''
  depends_on:
  - A-APP-RUNTIME-ADAPTER-SLURM-001
  acceptance_checks:
  - bash scripts/ci/contracts_validate.sh
  - make test-integration-selected
  - make queue-git-check
  notes: 'Context:

    Local parity validation proved a viable bootstrap path using public SSH-key registration,
    allocation SSH-key attachment, and direct SSH login to a real allocated node.
    That is sufficient for the first Slurm proof, but it also exposed a reusable core
    gap: the admin access-credential APIs currently manage metadata references only.
    They do not yet let an app or platform workflow complete the custody lifecycle
    by writing app-managed machine credential material through the public platform
    contract.


    Required outcome:

    - keep the platform contract generic: this is about app-managed access credentials,
    not a special-case private-key API - extend the platform-owned access-credential
    model so secret material can be written through approved APIs into Vault-backed
    custody - support later retrieval or delivery through platform-owned references
    or wrapping semantics without making raw secret reveal the normal read path -
    preserve the boundary that GPUaaS owns custody and delivery primitives while app
    teams own the meaning and runtime use of the credential


    Scope:

    - In: Vault-backed write and rotate completion for access credentials, contract
    updates, audit, and regression tests - Out: making this a blocker for the first
    Slurm bootstrap proof or turning it into an app-specific secret API

    '
- id: A-SLURM-WORKER-LIFECYCLE-001
  title: Add Slurm worker join drain and remove behavior through the node lifecycle
    model
  role: A-backend
  status: todo
  priority: 921
  owner: ''
  branch: agent/A-backend
  completed_at: ''
  commit: ''
  depends_on:
  - A-SLURM-CONTROLLER-BOOTSTRAP-001
  - A-NODE-LIFECYCLE-RETIRE-DRAIN-001
  acceptance_checks:
  - make test-integration-selected
  - make queue-git-check
  notes: 'Context:

    Slurm support is only credible if worker membership and drain/remove behavior
    compose cleanly with the node lifecycle you already implemented. This slice should
    map worker join, scheduler drain, and scheduler-safe remove into the existing
    node lifecycle primitives.


    Scope:

    - In: worker bootstrap/join path, Slurm-aware drain/remove sequencing, and runtime-state/status
    reporting.

    - Out: HA/multi-controller or shared managed Slurm service.

    '
- id: A-SLURM-MULTI-NODE-PLACEMENT-UX-001
  title: Productize multi-node Slurm deploy and worker placement UX on allocation-based
    primitives
  role: B-ui
  status: todo
  priority: 920
  owner: ''
  branch: agent/B-ui
  completed_at: ''
  commit: ''
  depends_on:
  - A-SLURM-WORKER-LIFECYCLE-001
  acceptance_checks:
  - pnpm --dir packages/web exec vitest run
  - pnpm --dir packages/web exec tsc --noEmit
  - make queue-git-check
  notes: 'Context:

    The current Slurm UI is now honest for the supported single-node reference path:
    deploy chooses a controller allocation and bootstrap SSH credential, and worker
    add chooses an explicit allocation. That is not sufficient for the final example-app
    workflow because a real clustered Slurm product must support choosing one or many
    worker allocations intentionally rather than treating same-node as the only first-class
    operator path.


    Required outcome:

    - make deploy semantics explicit for: - single-node Slurm - split controller/worker
    Slurm - one-or-many worker allocations - make add-worker selection clearly allocation-based
    with support for multiple targets where the product allows it - keep the UI aligned
    with platform-owned `placement_intent` and `allocation_intent` primitives rather
    than inventing Slurm-only placement contracts


    Scope:

    - In: deploy/add-worker UX, operator-visible placement semantics, and supporting
    web tests - Out: tenant-scope multi-project Slurm policy semantics

    '
- id: A-SLURM-TENANT-SCOPE-SEMANTICS-001
  title: Define and implement tenant-scope Slurm semantics for cross-project scheduler
    instances
  role: A-backend
  status: todo
  priority: 919
  owner: ''
  branch: agent/A-backend
  completed_at: ''
  commit: ''
  depends_on:
  - A-SLURM-WORKER-LIFECYCLE-001
  acceptance_checks:
  - bash scripts/ci/contracts_validate.sh
  - make test-integration-selected
  - make queue-git-check
  notes: 'Context:

    The current Slurm example is project-scoped. That is the right first productized
    path, but the architecture docs already call out a future tenant-scoped Slurm
    shape where one scheduler instance can span projects within a tenant and allow
    cross-project job submission by policy.


    Required outcome:

    - define the product semantics for project-scope vs tenant-scope Slurm clearly
    - decide which parts are platform-owned: - tenant/project membership and policy
    - placement and app-instance ownership - decide which parts are app-owned: - queue/account/QoS
    mapping - scheduler-native authorization and routing - implement only the reusable
    core and app-contract changes needed for that model


    Scope:

    - In: contract/doc/service changes required for tenant-scope Slurm support - Out:
    broad platform-managed shared Slurm service beyond the defined tenant-scope model

    '
- id: B-APP-UI-EXTENSION-MODEL-001
  title: Define and implement reusable platform shell extension points for app-owned
    UI panels and deploy forms
  role: B-ui
  status: todo
  priority: 918
  owner: ''
  branch: agent/B-ui
  completed_at: ''
  commit: ''
  depends_on:
  - A-SLURM-MULTI-NODE-PLACEMENT-UX-001
  acceptance_checks:
  - pnpm --dir packages/web exec vitest run
  - pnpm --dir packages/web exec tsc --noEmit
  - make queue-git-check
  notes: 'Context:

    The Slurm example now proves that app-specific UI can live inside the platform
    shell, but the implementation is still Slurm-specific in the catalog and instance
    pages. If Slurm is the example app for external app developers, the platform needs
    a reusable extension model rather than one-off page logic per app.


    Required outcome:

    - define platform-owned extension points for: - deploy form sections - app-instance
    detail panels - app-specific actions and status cards - keep the public API authoritative
    and treat any UI helper layer as convenience - use the Slurm example as the first
    consumer of that reusable model


    Scope:

    - In: UI extension contracts, shared helpers/components, and migration of the
    Slurm UI to that model - Out: a plugin execution system or remote code-loading
    scheme

    '
- id: A-TENANT-SHARED-RUNTIME-ATTACHMENT-CONTRACT-001
  title: Define the first tenant-shared runtime and project-attachment control-plane
    contract
  role: A-backend
  status: todo
  priority: 917
  owner: ''
  branch: agent/A-backend
  completed_at: ''
  commit: ''
  depends_on:
  - A-SLURM-TENANT-SCOPE-SEMANTICS-001
  acceptance_checks:
  - make codegen
  - bash scripts/ci/contracts_validate.sh
  - make queue-git-check
  notes: 'Context:

    The docs now explicitly choose the tenant-owned shared runtime model with attached
    consumer projects for apps such as Slurm. That decision is not real until the
    platform has a first-class control-plane contract for the shared runtime object
    and its project attachments.


    Required outcome:

    - define the first API/schema shape for a tenant-owned shared runtime control-plane
    object - define the first API/schema shape for attached consumer projects and
    their lifecycle - keep project-owned app instances intact for project-scoped mode
    instead of overloading them to mean tenant ownership - make audit, correlation,
    and read-model expectations explicit


    Scope:

    - In: contract/doc/schema direction for tenant-shared runtime ownership and attachments
    - Out: implementing tenant-shared scheduler behavior before the contract exists

    '
- id: A-TENANT-SCOPED-APP-MACHINE-IDENTITY-001
  title: Define tenant-scoped machine identity for tenant-owned shared app controllers
  role: A-backend
  status: todo
  priority: 916
  owner: ''
  branch: agent/A-backend
  completed_at: ''
  commit: ''
  depends_on:
  - A-TENANT-SHARED-RUNTIME-ATTACHMENT-CONTRACT-001
  acceptance_checks:
  - bash scripts/ci/contracts_validate.sh
  - make test-integration-selected
  - make queue-git-check
  notes: 'Context:

    Project-scoped service accounts are now real and are sufficient for project-scoped
    app controllers. Tenant-owned shared runtimes need a machine identity that is
    explicitly tenant-bounded without becoming platform-global. This is now the real
    blocker for honest tenant-shared app implementation.


    Required outcome:

    - define how a tenant-owned shared app controller authenticates - keep authority
    tenant-bounded and auditable - define how identity interacts with attached-project
    read surfaces and shared runtime mutations - avoid weakening the existing project-scoped
    service-account model


    Scope:

    - In: tenant-scoped service-account or delegated machine-identity model, docs,
    and resulting contract/service implications - Out: platform-global break-glass
    or undocumented privilege broadening

    '
- id: A-NODE-LIFECYCLE-RETIRE-DRAIN-001
  title: Implement node draining lifecycle before retire/remove
  role: A-backend
  status: done
  priority: 923
  owner: agent-a
  branch: agent/A-backend
  completed_at: '2026-03-11'
  commit: ea83f4f
  depends_on:
  - A-NODE-AGENT-RUNTIME-OPERATOR-PRIMITIVES-001
  acceptance_checks:
  - go test ./packages/services/inventory ./cmd/api ./cmd/node-agent
  - go test -tags integration ./packages/services/inventory ./cmd/api -run 'Test(NodeReactivateAndRemoveLifecycleIntegration|InternalNodeDrainTaskLifecycleIntegration)'
    -count=1
  - bash scripts/ci/agent_queue_validate.sh
  - make queue-git-check
  notes: 'Context:

    Retire/remove semantics still jump from active/offline straight to retired, but
    internal node runtime explicitly denies retired nodes. Add a draining lifecycle
    with a typed node.drain task so the node can acknowledge drain before final retire/remove
    semantics.

    Scope:

    - In: draining status in schema/contracts/runtime allowlist, signed node.drain
    task, task-result-driven draining -> retired|offline transition. - Out: full uninstall/reimage
    workflow; that comes later.

    '
- id: A-APP-RUNTIME-SECRET-DELIVERY-001
  title: Implement generalized app runtime secret delivery for verified artifacts
  role: A-backend
  status: done
  priority: 923
  owner: agent-a
  branch: agent/A-backend
  completed_at: '2026-03-10'
  commit: cba1897
  depends_on:
  - A-VAULT-PLATFORM-SECRETS-IMPLEMENTATION-001
  - A-APP-OCI-REGISTRY-IMPLEMENTATION-001
  - A-APP-NON-OCI-BLOB-BACKEND-001
  acceptance_checks:
  - bash scripts/ci/contracts_validate.sh
  - make test-integration-selected
  - make queue-git-check
  notes: 'Context:

    Artifact publication and verification are now real, but runtimes still need a
    single control-plane path to fetch verified OCI and blob artifacts without inventing
    per-adapter secret handling. This slice adds project-scoped runtime secret delivery
    for app instances.


    Scope:

    - In: app-instance runtime secret issuance, Vault-wrapped registry pull credentials,
    artifact-store pull metadata, service-account access, audit, and platform-control
    Vault seeding.

    - Out: workload-specific secret injection beyond artifact pull.

    '
- id: A-TENANT-IMPL-002
  title: Implement policy scope resolution chain with deterministic precedence
  role: A-backend
  status: done
  priority: 30
  owner: agent-a
  branch: agent/A-backend
  completed_at: '2026-03-02'
  commit: de549bb
  depends_on:
  - A-TENANT-IMPL-001
  acceptance_checks:
  - go test ./packages/shared/policy ./cmd/api
  - make test-integration-selected
  - rg -q "global.*org.*project" packages/shared/policy
  notes: 'Implement MVP policy precedence chain global->org->project (most-specific
    wins), explicitly excluding user/plan from MVP evaluation path. Required pre-read:
    doc/architecture/Tenant_Project_Ownership_Baseline.md, doc/architecture/ERD.md,
    doc/architecture/db_schema_v1.sql, doc/api/openapi.draft.yaml. Invariants: deterministic
    precedence only (no fallback ambiguity), and no contract-field drift.'
- id: A-CONTROL-PLANE-K8S-KEYCLOAK-MIGRATION-001
  title: Migrate Keycloak from host-managed external infra into gpuaas-infra with
    stable ingress and realm import
  role: A-backend
  status: done
  priority: 934
  owner: agent-a
  branch: agent/A-backend
  completed_at: '2026-03-08'
  commit: 9629e6d
  depends_on:
  - A-CONTROL-PLANE-K8S-INFRA-MIGRATION-001
  acceptance_checks:
  - rg -q "Keycloak|realm import|ingress|issuer" doc/operations/Control_Plane_K8s_Migration_v1.md
  - make queue-git-check
  notes: 'Context:

    Redis, NATS, and Temporal are migrated into `gpuaas-infra`. Keycloak remains external
    and is the next identity-critical infra migration. This move must preserve issuer
    stability, realm import behavior, and redirect URI handling.


    Invariants (must not break):

    - public issuer remains stable

    - seeded/local dev login flows keep working

    - realm import stays automation-owned

    - ingress and service-link collisions are explicitly handled


    Scope:

    - In: Keycloak runtime move into `gpuaas-infra`, ingress/service config, automation-owned
    realm import path.

    - Out: Postgres migration.


    Evidence required in handoff:

    - files changed

    - commit SHA

    - exact acceptance commands run

    - pass/fail status by command

    '
- id: B-ADMIN-OPS-UX-REDESIGN-001
  title: Redesign admin ops page around action-first triage flow
  role: B-ui
  status: done
  priority: 924
  owner: agent-b
  branch: agent/B-ui
  completed_at: '2026-03-09'
  commit: 4602a0d
  depends_on: []
  acceptance_checks:
  - make verify-web
  - pnpm --dir packages/web test app/admin/ops
  notes: 'Context:

    `/admin/ops` has accumulated useful telemetry and debug pivots, but the page is
    too busy and does not guide operator triage well. Active incident signals, health
    summary, query packs, and fleet detail currently compete on one screen.


    Pre-read (required):

    - doc/product/Admin_Ops_and_User_IA_v1.md

    - doc/operations/Ops_Runbook_Architecture.md

    - packages/web/app/admin/ops/page.tsx


    Invariants (must not break):

    - correlation-first debugging path remains available.

    - runbook links remain discoverable for degraded states.

    - no backend contract drift; prefer additive UI restructuring.


    Scope:

    - In: IA/layout rewrite for `/admin/ops`.

    - In: clearer separation of summary, action-required, and debug sections.

    - In: first-class auth failure visibility if current API fields allow it.

    - Out: unrelated visual theme redesign.


    Deliverables:

    - action-first `/admin/ops` layout.

    - reduced above-the-fold noise.

    - tests covering key degraded-state sections and links.


    Evidence required in handoff:

    - files changed

    - commit SHA

    - exact acceptance commands run

    - pass/fail status by command

    '
- id: A-MAAS-DOMAIN-FOUNDATION-001
  title: Establish Provisioning.BareMetal.MAAS domain foundation in the monorepo
  role: A-backend
  status: done
  priority: 914
  owner: A
  branch: agent/A-backend
  completed_at: '2026-03-12'
  commit: 226343f
  depends_on: []
  acceptance_checks:
  - rg -q "Provisioning.BareMetal.MAAS" doc/architecture/Domain_Ownership_Map.md
  - rg -q "packages/services/maas" doc/architecture/Provisioning_BareMetal_MAAS_API_Boundary_v1.md
  - make queue-git-check
  notes: 'Context:

    The MAAS work now has a reviewed architecture baseline, but implementation will
    drift immediately if the domain does not get an explicit home and boundary first.
    This task is the packaging/foundation slice before any workflow coding.

    Scope:

    - In: establish the domain/package home and implementation boundary for MAAS-specific
    logic.

    - Out: workflow execution logic, schema changes, or UX.

    '
- id: A-MAAS-SITE-CONTRACT-001
  title: Define MAAS site management and probe API contract
  role: A-backend
  status: done
  priority: 913
  owner: A
  branch: agent/A-backend
  completed_at: '2026-03-12'
  commit: 226343f
  depends_on:
  - A-MAAS-DOMAIN-FOUNDATION-001
  acceptance_checks:
  - make codegen
  - bash scripts/ci/contracts_validate.sh
  - make queue-git-check
  notes: 'Context:

    Before any onboarding workflow exists, operators need a real control-plane surface
    for MAAS site CRUD, credentials, policy, and connectivity probing. This contract
    slice is the foundation for both backend implementation and admin UX.

    Scope:

    - In: OpenAPI for site create/list/get/update/disable, credentials write/rotate,
    and probe.

    - Out: onboarding/decommission workflow APIs.

    '
- id: A-MAAS-SITE-SCHEMA-AND-CLIENT-001
  title: Implement MAAS site schema and typed client/probe primitives
  role: A-backend
  status: done
  priority: 912
  owner: A
  branch: agent/A-backend
  completed_at: '2026-03-12'
  commit: 226343f
  depends_on:
  - A-MAAS-SITE-CONTRACT-001
  acceptance_checks:
  - go test ./packages/services/maas ./cmd/api
  - make queue-git-check
  notes: 'Context:

    The first concrete backend slice should lock down the stable site foundation:
    MAAS site records, policies, credential paths, and a typed MAAS probe/client.
    This is intentionally lower risk than starting with long-running workflows.

    Scope:

    - In: `maas_sites`, `maas_site_policies`, `maas_power_credential_overrides`, `maas_roce_assignments`,
    Vault-backed credential flows, and MAAS version/connectivity probe primitives.

    - Out: onboarding/decommission workflow execution.

    '
- id: B-MAAS-SITE-ADMIN-UX-001
  title: Build admin UX for MAAS site configuration, credentials, policy, and probe
  role: B-ui
  status: done
  priority: 911
  owner: B
  branch: agent/B-ui
  completed_at: '2026-03-12'
  commit: fe29542
  depends_on:
  - A-MAAS-SITE-CONTRACT-001
  - A-MAAS-SITE-SCHEMA-AND-CLIENT-001
  acceptance_checks:
  - make verify-web
  - make queue-git-check
  notes: 'Context:

    MAAS site management needs to be usable by operators before any onboarding workflow
    exists. This UX slice should let infra/admin users configure sites, rotate credentials,
    edit policy, and probe live MAAS connectivity from the control plane.

    '
- id: A-MAAS-WORKFLOW-READMODEL-FOUNDATION-001
  title: Add draft MAAS workflow read-model schema and query contract foundation
  role: A-backend
  status: done
  priority: 910
  owner: A
  branch: agent/A-backend
  completed_at: '2026-03-12'
  commit: a4fbdac
  depends_on:
  - A-MAAS-SITE-SCHEMA-AND-CLIENT-001
  acceptance_checks:
  - make codegen
  - go test ./cmd/api
  - make queue-git-check
  notes: 'Context:

    The onboarding/decommission state model and recovery semantics are reviewed, but
    the workflow read model should be introduced conservatively before full Temporal
    implementation so the UI and operators have somewhere to read state.

    Important caution:

    - Treat this as a draft/foundation schema. - The final event/detail columns should
    be refined when the first real MAAS workflow slice lands, especially around `maas_system_id`,
    stage details, and upstream diagnostic payloads.

    Scope:

    - In: initial `node_onboardings`, `node_onboarding_events`, `node_decommissions`,
    `node_decommission_events`, `node_maas_state`, and read/query contract baseline.

    - Out: running onboarding/decommission workflows.

    '
- id: B-MAAS-WORKFLOW-VISIBILITY-UX-001
  title: Build admin UX for MAAS onboarding and decommission visibility before workflow
    execution lands
  role: B-ui
  status: done
  priority: 909
  owner: B
  branch: agent/B-ui
  completed_at: '2026-03-14'
  commit: a948465
  depends_on:
  - A-MAAS-WORKFLOW-READMODEL-FOUNDATION-001
  acceptance_checks:
  - make verify-web
  - make queue-git-check
  notes: 'Context:

    The operator experience should exist before the first live workflow writes into
    it. This slice should provide status, stage, failure-class, and recovery-action
    presentation for onboarding/decommission read models, even if the first pass is
    read-only or fixture-backed.

    '
- id: B-MAAS-CURRENT-VS-HISTORY-UX-001
  title: Separate current MAAS node state from historical onboarding and decommission
    attempts
  role: B-ui
  status: done
  priority: 913
  owner: B
  branch: agent/B-ui
  completed_at: '2026-03-17'
  commit: ffcbdc4
  depends_on: []
  acceptance_checks:
  - make verify-web
  - make queue-git-check
  notes: 'Context:

    Live MAAS validation now shows the admin UI can render both current node truth
    and historical workflow attempts for the same reused test node, but the presentation
    still makes old completed onboarding rows look like the current lifecycle state.
    Inventory state (`nodes.status`), workflow status (`node_onboardings.status` /
    `node_decommissions.status`), and workflow history need explicit separation in
    the UI.


    Scope:

    - In: distinguish current node state from historical onboarding/decommission attempts,
    label history as history, avoid implying that the latest visible workflow row
    is the current node lifecycle truth, and clean up MAAS summary/detail layout issues
    such as long decommission IDs, badge stacks, and action buttons overflowing or
    colliding inside summary cards.

    - In: improve operator visibility on active workflow detail pages so the current
    attempt and current stage are obvious at a glance, and add a direct MAAS-status
    shortcut/panel when backend/API support is available (for example current MAAS
    machine state during `deploy_node` or other long-running upstream stages).

    - Out: backend workflow semantics, reconciliation correctness, or new MAAS workflow
    actions.

    '
- id: A-MAAS-ONBOARDING-WORKFLOW-EXECUTION-001
  title: Implement first real MAAS onboarding workflow execution slice against the
    reviewed execution baseline
  role: A-backend
  status: todo
  priority: 909
  owner: ''
  branch: agent/A-backend
  completed_at: ''
  commit: ''
  depends_on:
  - A-MAAS-WORKFLOW-READMODEL-FOUNDATION-001
  - A-MAAS-SITE-PROFILES-001
  acceptance_checks:
  - go test ./packages/services/maas ./cmd/api
  - make test-integration
  - bash scripts/ci/contracts_validate.sh
  - make queue-git-check
  notes: 'Context:

    The control plane now accepts MAAS onboarding requests and persists read-model
    rows, but it does not yet execute the real MAAS workflow. The first live execution
    slice must be built against `doc/architecture/MAAS_Execution_Readiness_v1.md`,
    preserving the proven prototype intent where it matters before broader automation
    or batch execution is introduced.


    Scope:

    - In: first real single-node onboarding execution path, deterministic create/find
    behavior, commissioning, PXE preflight, composed first-boot payload, deploy, and
    bounded classified retry semantics.

    - Out: batch execution, broad decommission automation, and multi-site rollout
    beyond the approved first fixture.

    '
- id: A-MAAS-INSTALL-OUTPUT-RETRIEVAL-001
  title: Retrieve MAAS install output through the API and surface it in onboarding
    diagnostics
  role: A-backend
  status: todo
  priority: 910
  owner: ''
  branch: agent/A-backend
  completed_at: ''
  commit: ''
  depends_on:
  - A-MAAS-ONBOARDING-WORKFLOW-EXECUTION-001
  acceptance_checks:
  - go test ./packages/services/maas ./cmd/api
  - make test-integration
  - make queue-git-check
  notes: 'Context:

    Real MAAS deploy debugging is already surfacing in operator workflows, and relying
    on the MAAS UI for install-output inspection weakens the control-plane experience.
    GPUaaS should be able to fetch install output through the MAAS API, surface it
    on onboarding detail, and later forward it into Loki with onboarding/site/system
    identifiers.


    Scope:

    - In: MAAS install-output retrieval, onboarding detail/timeline enrichment, and
    a clean extension point for later Loki export.

    - Out: full centralized log shipping implementation in the same slice.

    '
- id: A-MAAS-DIAGNOSTICS-REMOTE-SMOKE-001
  title: Add remote platform-control smoke for MAAS diagnostics routes after rollout
  role: A-backend
  status: todo
  priority: 910
  owner: ''
  branch: agent/A-backend
  completed_at: ''
  commit: ''
  depends_on:
  - A-MAAS-INSTALL-OUTPUT-RETRIEVAL-001
  acceptance_checks:
  - bash scripts/ci/platform_control_remote_validation.sh
  - make queue-git-check
  notes: 'Context:

    The first live rollout of MAAS diagnostics looked healthy at the deployment level,
    but the new `install-output` and `maas-events` routes still returned 500 until
    a MAAS-specific auth bug was found in the running platform-control API. Health
    checks and generic smoke were not enough to catch that failure.


    Scope:

    - In: post-deploy remote validation that exercises real MAAS onboarding diagnostics
    routes against a known onboarding fixture, verifies non-empty install output,
    verifies MAAS event payload retrieval, and fails the rollout when those routes
    regress.

    - Out: broad UI verification or full MAAS workflow replay in the same slice.

    '
- id: A-MAAS-BOOTSTRAP-PROGRESS-VISIBILITY-001
  title: Surface live MAAS bootstrap and node-enrollment progress during onboarding
    without requiring SSH
  role: A-backend
  status: todo
  priority: 909
  owner: ''
  branch: agent/A-backend
  completed_at: ''
  commit: ''
  depends_on:
  - A-MAAS-ONBOARDING-WORKFLOW-EXECUTION-001
  acceptance_checks:
  - go test ./packages/services/maas ./cmd/api
  - make test-integration
  - make queue-git-check
  notes: 'Context:

    The first live H200/IB onboarding runs proved a major visibility gap after MAAS
    reports `Deployed`: operators still cannot tell from GPUaaS or MAAS-facing diagnostics
    whether cloud-init is still progressing normally, site bootstrap is running, node
    bootstrap failed, or node-agent enrollment is stuck. We had to SSH into the node
    to classify healthy long-running package installs versus real failure.


    Required outcome:

    - emit explicit first-boot progress markers for site bootstrap, node bootstrap,
    and node-agent enrollment - surface those markers through MAAS-visible status/events
    when reachable - also surface the same progress in GPUaaS onboarding detail/events
    so operators can distinguish slow package installs from actual bootstrap or enrollment
    failure without SSH - preserve local node logs as the detailed source, but make
    the control-plane summary good enough for routine operator diagnosis


    Scope:

    - In: phase markers, MAAS event/status posting when reachable, onboarding detail/timeline
    enrichment, and operator-visible progress semantics for the provisioning window
    between `deploy_node` and final activation - In: short term, keep MAAS event ingestion
    inside existing workflow wait loops, but poll only curated `INFO` events and only
    within the active workflow/stage time window so the timeline shows current-run
    progress instead of stale machine history - In: treat this as part of the current
    MAAS release-candidate quality bar because live validation already exposed it
    as an operator gap - Out: full centralized log shipping or a generic host-observability
    platform in the same slice

    Long term:

    - if concurrent MAAS activity grows, replace per-workflow polling with a site-level/shared
    MAAS event refresher that batches active systems and fans events back into the
    owning onboarding/decommission streams

    '
- id: A-MAAS-WORKFLOW-TIMELINE-ORDERING-001
  title: Make MAAS workflow stage progress and attempt timelines use stable lifecycle
    ordering
  role: B-ui
  status: todo
  priority: 909
  owner: ''
  branch: agent/B-ui
  completed_at: ''
  commit: ''
  depends_on:
  - A-MAAS-WORKFLOW-READMODEL-FOUNDATION-001
  acceptance_checks:
  - pnpm exec vitest run app/admin/nodes/decommissions/[decommissionId]/page.test.tsx
    app/admin/nodes/onboardings/[onboardingId]/page.test.tsx
  - make verify-web
  - make queue-git-check
  notes: 'Context:

    Live MAAS decommission validation on 2026-04-05 showed that the admin detail page
    does not present workflow order reliably. Temporal showed the expected execution
    order (`deploy_node` -> `reactivate_node` -> `wait_node_enrollment`), but the
    GPUaaS "Stage Progress" cards and "Current Attempt" table were derived from event
    timestamps alone. When multiple stage events land within the same second, the
    page can present confusing or unstable ordering that does not match the real workflow
    path.


    Required outcome:

    - make "Stage Progress" use an explicit stage sequence for each MAAS workflow
    type instead of first-seen event order - make attempt/timeline tables use stable
    ordering with a deterministic tiebreaker for same-second events - keep the page
    aligned with Temporal execution order so operators can trust the UI during incident
    handling - preserve bootstrap breadcrumb detail once it exists, without letting
    timestamp ties scramble the lifecycle presentation

    Follow-up note:

    - 2026-04-05 live validation showed the broader ordering fix was necessary but
    not sufficient; decommission tail ordering and stage-summary status/message semantics
    needed an additional refinement after MAAS deploy progress began streaming into
    `deploy_node`

    Scope:

    - In: explicit ordered stage lists for MAAS onboarding and MAAS decommission,
    stable event ordering semantics, and regression tests covering same-second stage/event
    collisions - Out: changing Temporal execution order, changing backend workflow
    semantics, or redesigning the whole MAAS admin information architecture

    '
- id: A-MAAS-SITE-BOOTSTRAP-MIDPHASE-PROGRESS-001
  title: Surface long-running mid-phase site bootstrap progress during MAAS first
    boot
  role: A-backend
  status: todo
  priority: 909
  owner: ''
  branch: agent/A-backend
  completed_at: ''
  commit: ''
  depends_on:
  - A-MAAS-BOOTSTRAP-PROGRESS-VISIBILITY-001
  acceptance_checks:
  - go test ./packages/services/maas ./cmd/api
  - make test-integration
  - make queue-git-check
  notes: 'Context:

    By 2026-04-05 we proved that MAAS deploy progress is visible and that late guest-side
    callbacks (`site bootstrap completed`, `starting GPUaaS node bootstrap`, `waiting
    for gpuaas node enrollment`, `node enrollment completed`) are stored and rendered.
    The remaining operational blind spot is the long middle of `site_bootstrap`: package
    install / Lambda stack / DOCA-OFED work can run for 10+ minutes with no visible
    updates, then all guest callbacks arrive near completion.


    Required outcome:

    - emit visible progress markers during the long-running interior of `site_bootstrap`,
    not only at completion - ensure those markers land in the owning onboarding/decommission
    workflow event stream during the wait-node-enrollment window - make operators
    able to distinguish "still installing Lambda stack" from "stuck or failed" without
    SSH


    Scope:

    - In: additional callback checkpoints inside the site bootstrap script before/around
    long-running install sections - In: if needed, coarse heartbeat-style markers
    during especially long package-install sections - In: validation that the updated
    site bootstrap OCI bundle is what the live MAAS profile actually delivers - Out:
    separate admin lifecycle/progress API design - Out: generalized OCI bundle release
    discipline/process design

    '
- id: A-MAAS-SITE-BOOTSTRAP-BUNDLE-RELEASE-DISCIPLINE-001
  title: Formalize MAAS site bootstrap OCI publish and live profile reference discipline
  role: C-ops
  status: todo
  priority: 908
  owner: ''
  branch: agent/C-ops
  completed_at: ''
  commit: ''
  depends_on:
  - A-MAAS-SITE-BOOTSTRAP-MIDPHASE-PROGRESS-001
  acceptance_checks:
  - make queue-git-check
  notes: 'Context:

    We already hit a real failure mode where platform-control code had the updated
    site bootstrap logic, but the live MAAS profile still pointed at an older OCI
    digest, so nodes kept receiving the stale script. That makes visibility fixes
    look broken even when the control-plane code is correct.


    Required outcome:

    - define and document the release path from updated site bootstrap script -> OCI
    artifact publish -> live MAAS profile reference update - make the resolved digest/profile
    binding easy to verify during incident handling and release validation - prevent
    future "code deployed but old site bundle still running" confusion

    '
- id: A-MAAS-ADMIN-LIFECYCLE-PROGRESS-SURFACE-001
  title: Add a dedicated admin lifecycle progress surface for MAAS onboarding and
    reimage flows
  role: A-backend
  status: todo
  priority: 908
  owner: ''
  branch: agent/A-backend
  completed_at: ''
  commit: ''
  depends_on:
  - A-MAAS-BOOTSTRAP-PROGRESS-VISIBILITY-001
  acceptance_checks:
  - make codegen
  - go test ./cmd/api ./packages/services/maas
  - make queue-git-check
  notes: 'Context:

    The workflow detail page is now useful, but it still mixes workflow stages, MAAS
    progress events, and bootstrap callbacks into one view. Operators would benefit
    from a dedicated lifecycle/progress surface that answers "what phase is this node
    in right now?" without needing to infer state from mixed event rows.


    Required outcome:

    - define an admin read-model/API focused on MAAS lifecycle progress - expose current
    phase, last update, and source (`maas_event` vs `bootstrap_progress`) cleanly
    - make onboarding and reimage diagnosis easier without reading raw workflow event
    history

    '
- id: A-MAAS-UPSTREAM-PAYLOAD-REALITY-CHECK-001
  title: Capture real MAAS auth and payload fixtures for client-method regression
    tests
  role: A-backend
  status: todo
  priority: 910
  owner: ''
  branch: agent/A-backend
  completed_at: ''
  commit: ''
  depends_on:
  - A-MAAS-INSTALL-OUTPUT-RETRIEVAL-001
  acceptance_checks:
  - go test ./packages/services/maas
  - make queue-git-check
  notes: 'Context:

    The MAAS diagnostics regression came from two assumptions that unit tests did
    not pin tightly enough: the new client methods sent a raw `Authorization: OAuth
    <token>` header instead of the signed MAAS OAuth1 header, and the MAAS `events.created`
    timestamp format was not RFC3339. Both bugs only became obvious after probing
    the real MAAS API from a live pod.


    Scope:

    - In: tighter client-method tests that assert signed MAAS OAuth header shape,
    real MAAS URL/query behavior, and parser coverage for upstream timestamp/payload
    formats observed from the live MAAS API.

    - Out: replacing integration tests with recorded fixtures or introducing a separate
    MAAS mock framework.

    '
- id: A-PLATFORM-CONTROL-DEPLOY-IMAGE-FRESHNESS-001
  title: Fail platform-control deploy when runtime images are stale relative to promoted
    commit
  role: A-backend
  status: todo
  priority: 909
  owner: ''
  branch: agent/A-backend
  completed_at: ''
  commit: ''
  depends_on:
  - A-MAAS-DIAGNOSTICS-REMOTE-SMOKE-001
  acceptance_checks:
  - bash scripts/ci/platform_control_deploy.sh
  - bash scripts/ci/platform_control_release_conformance.sh
  - make queue-git-check
  notes: 'Context:

    A platform-control rollout applied cleanly at the Kubernetes level, but the running
    API and web pods were still serving older runtime images because the newest digests
    had not been published yet. That left newly promoted routes unavailable until
    the images were rebuilt and patched manually.


    Scope:

    - In: a freshness assertion between promoted git SHA and runtime image/build metadata,
    and a deploy-time failure path when the cluster would otherwise roll forward using
    stale published images.

    - Out: replacing the existing release pipeline architecture in the same slice.

    '
- id: A-MAAS-DISCOVER-MANAGEMENT-IP-001
  title: Discover MAAS-provided management IP after deploy and surface it through
    GPUaaS
  role: A-backend
  status: todo
  priority: 908
  owner: ''
  branch: agent/A-backend
  completed_at: ''
  commit: ''
  depends_on:
  - A-MAAS-UPSTREAM-PAYLOAD-REALITY-CHECK-001
  acceptance_checks:
  - make codegen
  - bash scripts/ci/contracts_validate.sh
  - go test ./packages/services/maas ./cmd/api
  - go test -count=1 -tags integration ./packages/services/maas -run 'TestExecuteOnboardingPreflightIntegration|TestExecuteReimageDecommissionIntegration'
  - make queue-git-check
  notes: 'Context:

    Live MAAS validation showed that manual host verification can drift because operators
    may guess the wrong IP after a deploy or reimage. MAAS already knows the machine
    interface state and the MAAS-provided management address (for example `enp8303`
    on `10.176.46.0/24` for `c07u31`). GPUaaS should use the MAAS API as the source
    of truth instead of relying on remembered or guessed IPs.

    Requirements:

    - use the MAAS machine/interface API after deploy and reimage to discover the
    current management or boot interface and its MAAS-provided address

    - define a deterministic selection rule for the management IP rather than relying
    on interface order

    - store or surface the discovered value through GPUaaS read models/APIs so operators
    can see the actual reachable host address on onboarding/decommission detail and
    related node surfaces

    - use this discovered address in workflow diagnostics and verification where appropriate

    - document fallback behavior if MAAS has no clear management IP for the machine

    Scope:

    - In: MAAS interface inspection, management-IP selection logic, additive API/read-model
    exposure, tests

    - Out: changing MAAS networking semantics or replacing RoCE or management network
    ownership rules

    '
- id: A-MAAS-PREDEPLOY-PREFLIGHT-HARDENING-001
  title: Add MAAS onboarding predeploy guards for bootstrap route trust and token
    persistence
  role: A-backend
  status: todo
  priority: 910
  owner: ''
  branch: agent/A-backend
  completed_at: ''
  commit: ''
  depends_on:
  - A-MAAS-ONBOARDING-WORKFLOW-EXECUTION-001
  acceptance_checks:
  - go test ./packages/services/maas ./cmd/provisioning-worker
  - make test-integration
  - make queue-git-check
  notes: 'Context:

    The first full MAAS lifecycle run exposed repeatable predeploy failures that should
    be caught before MAAS deploy begins: wrong bootstrap route selection, placeholder
    CA material, unresolved bootstrap package/script URLs, and token persistence gaps.


    Scope:

    - In: workflow-owned guards for bootstrap endpoint reachability from the MAAS
    subnet, fetchability of the exact rendered bootstrap URL, bootstrap CA validation,
    and bootstrap/enrollment-token persistence checks before deploy starts.

    - Out: post-deploy enrollment retries or centralized diagnostics export.

    '
- id: A-MAAS-ENROLLMENT-TOKEN-CONSISTENCY-001
  title: Fix MAAS onboarding enrollment-token and completion consistency
  role: A-backend
  status: todo
  priority: 911
  owner: ''
  branch: agent/A-backend
  completed_at: ''
  commit: ''
  depends_on:
  - A-MAAS-ONBOARDING-WORKFLOW-EXECUTION-001
  acceptance_checks:
  - go test ./packages/services/maas ./cmd/api ./cmd/node-agent
  - make test-integration
  - make queue-git-check
  notes: 'Context:

    The first full platform-control MAAS onboarding run reached an active node, but
    only after manual recovery of a missing `node_enroll_token:*` Redis key and observation
    of stale attempt/completion state in onboarding read models. The current workflow
    can therefore report confusing attempt/current-stage data and may leave a running
    node-agent holding an enrollment token that the control plane no longer recognizes.


    Scope:

    - In: guarantee that bootstrap-token generation and enrollment-token storage stay
    consistent across reruns, preserve attempt numbering and completion semantics
    correctly in onboarding read models, and remove the need for direct Redis recovery
    during node enrollment.

    - Out: broad redesign of node-agent PKI or MAAS workflow stages beyond this consistency
    fix.

    '
- id: A-MAAS-POSTDEPLOY-COMPLETION-GUARDS-001
  title: Require deployed node-agent-started active-node state before MAAS onboarding
    completion
  role: A-backend
  status: todo
  priority: 912
  owner: ''
  branch: agent/A-backend
  completed_at: ''
  commit: ''
  depends_on:
  - A-MAAS-ONBOARDING-WORKFLOW-EXECUTION-001
  acceptance_checks:
  - go test ./packages/services/maas ./cmd/provisioning-worker
  - make test-integration
  - make queue-git-check
  notes: 'Context:

    The first successful live onboarding showed that MAAS `Deployed` and GPUaaS onboarding
    `completed` are not the same boundary. Node-agent start, first enrollment success,
    and final node activation must be explicit completion gates.


    Scope:

    - In: post-deploy guards that require MAAS `Deployed`, node-agent install/start
    success, first enrollment success, active node state, and attempt-state consistency
    before onboarding is marked complete.

    - Out: generalized node health monitoring beyond onboarding completion.

    '
- id: A-MAAS-RECONCILIATION-DRIFT-TRUTH-001
  title: Make MAAS reconciliation and drift summary reflect live node truth
  role: A-backend
  status: todo
  priority: 913
  owner: ''
  branch: agent/A-backend
  completed_at: ''
  commit: ''
  depends_on:
  - A-MAAS-ONBOARDING-WORKFLOW-EXECUTION-001
  acceptance_checks:
  - go test ./packages/services/maas ./cmd/api
  - make test-integration
  - make queue-git-check
  notes: 'Context:

    Live MAAS validation now shows the summary surface loading again, but reconciliation
    truth is still wrong: active MAAS-managed nodes can show `Total nodes: 0`, and
    flaky network behavior can push a node from healthy/active into broken or drifted
    state without the control-plane reconciliation summary reflecting that change
    clearly.


    Scope:

    - In: make MAAS reconciliation summary and drift read models reflect real MAAS-managed
    node population and drifted/broken state, including cases where transient network
    issues or MAAS/node-agent reachability problems move a node away from its expected
    active baseline.

    - Out: UI presentation cleanup, generalized non-MAAS heartbeat redesign, or speculative
    auto-remediation policy beyond accurate reconciliation/drift truth.

    '
- id: A-MAAS-DRIFT-RECONCILIATION-SCHEDULER-001
  title: Add periodic MAAS drift detection and lifecycle-trigger scheduling
  role: A-backend
  status: todo
  priority: 914
  owner: ''
  branch: ''
  completed_at: ''
  commit: ''
  depends_on:
  - A-MAAS-RECONCILIATION-DRIFT-TRUTH-001
  - A-NODE-AGENT-RELEASE-UPDATE-PATH-001
  acceptance_checks:
  - go test ./packages/services/maas ./packages/services/admin ./cmd/provisioning-worker
    ./cmd/api
  - make test-integration
  - make queue-git-check
  notes: 'Context:

    Drift is currently modeled but not actively driven. MAAS reconciliation/drift
    endpoints can report current truth, and node-agent lifecycle has a Temporal workflow
    surface, but no periodic scheduler actually scans for drift or starts reconcile
    work. That leaves drift detection and correction as operator-driven actions instead
    of a real control-plane loop.


    Required outcome:

    - add a periodic control-plane scan for MAAS-managed nodes that refreshes reconciliation
    truth on a schedule - classify actionable drift states clearly enough to decide
    whether they are report-only or eligible for automated follow-up - start bounded
    reconcile work only when a safe execution path exists, instead of treating drift
    purely as a read-model concept - record each scan cycle and any triggered reconcile
    attempt in operator-visible events/read models


    Scope:

    - In: periodic drift scan/scheduling, safe eligibility rules, Temporal/work-queue
    handoff for reconcileable nodes, and operator-visible scan evidence - Out: speculative
    self-healing for every drift class before the owning lifecycle execution path
    exists

    Progress:

    - first slice implemented on 2026-04-04: provisioning-worker now ensures a Temporal
    schedule that runs a MAAS reconciliation workflow/activity, and the MAAS service
    scan refreshes `node_maas_state` plus classifies drift (ip drift, released outside
    workflow, missing machine, MAAS read failure, agent offline, retired still deployed,
    etc.) - current periodic scan is intentionally scoped to MAAS-managed nodes already
    `active`; non-active MAAS states should be reconciled by the owning lifecycle
    workflows/events rather than broad periodic fleet scan - current scan intentionally
    records `report_only` / candidate actions because node-agent lifecycle execution
    is still operator-required or unimplemented; safe automatic lifecycle trigger
    handoff remains follow-up work under `A-NODE-AGENT-RELEASE-UPDATE-PATH-001` -
    discovery of MAAS machines unknown to GPUaaS, candidate listing, and operator-reviewed
    adoption stay out of scope here and are tracked separately under `A-MAAS-DISCOVERY-CANDIDATE-LIST-001`

    '
- id: A-MAAS-DISCOVERY-CANDIDATE-LIST-001
  title: Discover MAAS machines as operator-reviewed onboarding candidates with first-pass
    SKU inference
  role: A-backend
  status: todo
  priority: 913
  owner: ''
  branch: agent/A-backend
  completed_at: ''
  commit: ''
  depends_on:
  - A-MAAS-SITE-SCHEMA-AND-CLIENT-001
  - A-MAAS-ONBOARDING-WORKFLOW-EXECUTION-001
  acceptance_checks:
  - go test ./packages/services/maas ./cmd/api
  - make test-integration
  - make queue-git-check
  notes: 'Context:

    Today GPUaaS only manages MAAS nodes that are explicitly introduced through onboarding.
    That is acceptable for the first proven MAAS slice, but it forces admins to type
    hostname and IPMI details even when MAAS already knows the machine inventory.
    Discovery should be a separate operator-safe surface, not a hidden side effect
    of reconciliation or auto-adoption.


    Required outcome:

    - phase 1: let an operator explicitly trigger discovery for a MAAS site and return/store
    machines that are not already known as GPUaaS-managed nodes - phase 1: present
    them as discovery candidates rather than auto-managed nodes - phase 1: attach
    first-pass SKU inference plus confidence/reason metadata so the list is useful
    for operators - phase 1: let operators suppress, ignore, or choose a candidate
    for onboarding without forcing the reconciler to claim unknown hardware - long
    term: once the candidate model is trusted, allow Temporal-scheduled refresh of
    the discovery list while still keeping adoption operator-reviewed by default


    Scope:

    - In: phase-1 manual discovery trigger, MAAS discovery candidate read model/API,
    operator-safe list semantics, first-pass SKU inference from MAAS-visible inventory,
    and explicit suppression/ignore state for known exceptions - In: design/contract
    room for later Temporal-scheduled candidate refresh once the manual discovery
    model is proven - Out: automatic adoption of unknown MAAS machines, broad auto-claim
    heuristics, or folding discovery into the steady-state drift scheduler

    '
- id: C-MAAS-DIAGNOSTICS-LOKI-EXPORT-001
  title: Export MAAS onboarding diagnostics to Loki after control-plane retrieval
    exists
  role: C-ops
  status: todo
  priority: 913
  owner: ''
  branch: agent/C-ops
  completed_at: ''
  commit: ''
  depends_on:
  - A-MAAS-INSTALL-OUTPUT-RETRIEVAL-001
  acceptance_checks:
  - make queue-git-check
  notes: 'Context:

    MAAS install output and machine events should first be available through GPUaaS
    APIs and onboarding detail views. After that exists, Loki export becomes an operational
    extension for centralized analysis instead of the only way to inspect diagnostics.


    Scope:

    - In: operational design and rollout for exporting MAAS onboarding diagnostics
    to Loki with `site_id`, `onboarding_id`, `node_id`, `maas_system_id`, `hostname`,
    and `correlation_id`.

    - Out: replacing the control-plane diagnostics surface with Loki-only access.

    '
- id: C-OPS-LOKI-CORRELATION-COVERAGE-001
  title: Audit platform-control observability label model and correlation-first Loki
    workflow
  role: C-ops
  status: done
  priority: 913
  owner: Codex
  branch: agent/C-ops
  completed_at: '2026-05-03'
  commit: 19bcee48
  depends_on: []
  acceptance_checks:
  - rg -q "namespace=\\\"gpuaas-core\\\"|service=~\\\"gpuaas-api" infra/k8s/base/observability/config/grafana/dashboards/gpuaas-incident-correlation.json
    infra/k8s/base/observability/config/grafana/dashboards/gpuaas-control-plane-overview.json
  - rg -q "platform-control Kubernetes logs|compose_service label" doc/operations/Observability_Baseline.md
    doc/operations/Control_Plane_K8s_Migration_v1.md
  - make queue-git-check
  notes: 'Context:

    During live MAAS lifecycle testing, a failed retired-node remove request returned
    correlation ID `984c057f-2d0c-49a0-8aaa-edb26d76a8ef`. The event was present in
    the live `gpuaas-api` pod logs but absent from Loki when queried through the existing
    Grafana incident workflow. Follow-up investigation proved the event is in Loki,
    but the platform-control dashboards and saved queries were still using the local-dev
    `compose_service` label model, while live Kubernetes logs expose labels like `namespace`,
    `job`, `host_role`, and JSON payload fields such as `service`, `correlation_id`,
    and `trace_id`.

    This means the real gap is broader than one MAAS request: platform-control observability
    assumptions are drifting from the actual live label model, and operators can get
    false negatives unless dashboards, runbooks, and environment setup docs are audited
    together.


    Scope:

    - In: audit the full platform-control observability path for logs: - promtail
    collection labels in Kubernetes - OTEL/Loki JSON field usage - Grafana dashboards
    and saved Loki queries - docs/runbooks that still assume local-dev labels

    - In: document the actual label/query model for platform-control and what must
    be configured or verified in any new environment before operators rely on correlation-first
    Loki triage.

    - In: update platform-control dashboards/runbooks so incident workflows use the
    live Kubernetes label model, then note how local-dev should later converge or
    intentionally differ.

    - Out: redesigning all observability pipelines or replacing direct pod log access
    entirely.

    Required outcome:

    - confirm what labels and JSON fields are actually available in live platform-control
    Loki - ensure correlation-ID and trace-ID lookup works from Grafana/Explore using
    those live fields - document the platform-control observability contract in: -
    `doc/operations/Observability_Baseline.md` - `doc/operations/Control_Plane_K8s_Migration_v1.md`
    - any runbook or dashboard note that currently assumes `compose_service` - record
    what new environments must set up/verify so this does not regress on the next
    cluster

    '
- id: C-OPS-NODE-AGENT-LOG-PIPELINE-001
  title: Design and implement collector-backed node-agent and metrics-helper log shipping
    to Loki
  role: C-ops
  status: done
  priority: 914
  owner: C
  branch: agent/C-ops
  completed_at: '2026-05-03'
  commit: ed08d4d3
  depends_on:
  - C-OPS-LOKI-CORRELATION-COVERAGE-001
  acceptance_checks:
  - rg -q "collector-backed node-agent logs" doc/operations/Observability_Baseline.md
  - rg -q "gpuaas-node-agent|gpuaas-metrics-helper" infra/ansible infra/k8s doc/operations
  - make queue-git-check
  notes: 'Context:

    Node-agent and guest metrics-helper diagnostics are still primarily inspected
    through host-local journald. The durable direction is not for each service to
    push directly to Loki. At a few hundred worker nodes, direct per-agent Loki writes
    create avoidable coupling, burst risk, and credential sprawl. `gpuaas-node-agent`
    and `gpuaas-metrics-helper` should keep emitting structured JSON to stdout/journald,
    and a host-local or site-local collector pipeline should batch, label, buffer,
    and forward logs into the platform observability backend.


    Required outcome:

    - define the scalable log path: journald for `gpuaas-node-agent.service`, `gpuaas-metrics-helper.service`,
    and `gpuaas-metrics-helper.timer` -> host collector or site collector -> platform
    OTel/Loki gateway -> Loki - preserve query fields and labels for `service=gpuaas-node-agent|gpuaas-metrics-helper`,
    `systemd_unit`, `host_role=worker_compute`, `host_name`, `node_id`, `node_instance_id`,
    `agent_version`, `correlation_id`, and `allocation_id` when present - avoid direct
    service-to-Loki writes and avoid per-node long-lived Loki credentials where a
    collector/gateway can own that boundary - support batching/backpressure and bounded
    local buffering so temporary platform-control or network outages do not hot-loop
    node-agent logging - add a worker_compute rollout path through bootstrap/Ansible
    and a smoke query proving node-agent and metrics-helper logs are visible in Loki
    by node id or allocation id


    Scope:

    - In: operational design, bootstrap/Ansible collector configuration, label/query
    contract, and smoke validation for dev/platform-control. - Out: replacing Loki,
    building a generic fleet telemetry product, or streaming application workload
    logs in the same slice.

    '
- id: C-OPS-NODE-RUNTIME-RESIDUE-CLEANUP-001
  title: Define and implement deallocation cleanup policy for node-local runtime residue
    across k8s, Slurm, and Docker-backed app paths
  role: C-ops
  status: todo
  priority: 915
  owner: ''
  branch: agent/C-ops
  completed_at: ''
  commit: ''
  depends_on: []
  acceptance_checks:
  - rg -q "node-local runtime residue" doc/operations doc/architecture doc/governance
  - rg -q "k8s|slurm|docker" doc/operations doc/architecture doc/governance
  - make queue-git-check
  notes: 'Context:

    Repeated test and deallocation cycles are leaving behind node-local runtime state.
    The cleanup problem is not uniform: Slurm and k8s land directly on the node and
    can accumulate images, snapshots, kubelet/containerd state, mounts, and scheduler/runtime
    artifacts, while some application paths are primarily Docker-backed and have different
    teardown semantics. We need an explicit platform policy for what must be deleted
    during deallocation, what is retained briefly for rewind/debug, and what must
    move into platform-owned audit/history instead of lingering indefinitely on worker
    disks.


    Required outcome:

    - inventory node-local residue by runtime class: k8s, Slurm, Docker-backed apps,
    logs, and temporary workload artifacts - define deallocation/release cleanup policy
    for each class, including what is deleted immediately, what is retained briefly
    for rewind, and what must be captured in platform audit/history instead of preserved
    locally - identify the owning layer for each cleanup path: node-agent, provisioning
    worker, runtime-specific controller, or infra baseline - add reconciliation/garbage-collection
    follow-up for leaked residue from failed or interrupted releases - produce an
    operator validation path proving repeated test churn does not cause unbounded
    node growth


    Scope:

    - In: node-local runtime residue policy, deallocation cleanup ownership, runtime-by-runtime
    inventory, and follow-up implementation planning. - Out: unrelated control-plane
    log shipping, MAAS full-reimage semantics, or generic host hardening outside cleanup/deallocation
    behavior.

    '
- id: A-MAAS-SITE-BOOTSTRAP-BUNDLE-MODEL-001
  title: Replace extra cloud-init path semantics with versioned MAAS site bootstrap
    bundle references
  role: A-backend
  status: todo
  priority: 914
  owner: ''
  branch: agent/A-backend
  completed_at: ''
  commit: ''
  depends_on:
  - A-MAAS-ONBOARDING-WORKFLOW-EXECUTION-001
  acceptance_checks:
  - make codegen
  - bash scripts/ci/contracts_validate.sh
  - make queue-git-check
  notes: 'Context:

    The current MAAS policy still talks about `extra_cloud_init_bundle_path`, but
    the real abstraction from `../maas` is an infra-owned first-boot bootstrap bundle
    that runs before GPUaaS node bootstrap. That bundle should be versioned and tracked
    as its own managed reference rather than treated as an arbitrary YAML append.


    Scope:

    - In: rename and reframe the policy/contract around `site_bootstrap_bundle_ref`,
    preserve ordered two-stage bootstrap semantics, and make site bootstrap failures
    distinguishable from GPUaaS bootstrap failures in workflow state and diagnostics.

    - Out: the full artifact upload UI or OCI distribution implementation in the same
    slice.

    '
- id: B-MAAS-SITE-BOOTSTRAP-BUNDLE-UX-001
  title: Add admin UI and API flow for MAAS site bootstrap bundle upload versioning
    and selection
  role: B-ui
  status: todo
  priority: 915
  owner: ''
  branch: agent/B-ui
  completed_at: ''
  commit: ''
  depends_on:
  - A-MAAS-SITE-BOOTSTRAP-BUNDLE-MODEL-001
  acceptance_checks:
  - pnpm --dir packages/web typecheck
  - make verify-web
  - make queue-git-check
  notes: 'Context:

    Infra should eventually be able to upload and version the site bootstrap bundle
    through the control plane instead of relying on a local file path convention.
    That makes the bundle auditable and aligns it with other deployment-package flows.


    Scope:

    - In: admin/API UX for upload or registration, bundle version selection, and site/profile
    binding to the chosen site bootstrap bundle reference.

    - Out: provider-specific execution semantics beyond the reference and selection
    flow.

    '
- id: A-MAAS-TEMPORAL-RECOVERY-SEMANTICS-001
  title: Make MAAS resume and rerun semantics match Temporal workflow recovery intent
  role: A-backend
  status: todo
  priority: 916
  owner: Codex
  branch: agent/A-backend
  completed_at: ''
  commit: ''
  depends_on:
  - A-MAAS-ONBOARDING-WORKFLOW-EXECUTION-001
  acceptance_checks:
  - go test ./packages/services/maas ./cmd/provisioning-worker
  - go test -tags integration ./packages/services/maas
  - make queue-git-check
  notes: 'Context:

    Live decommission testing on 2026-03-18 for decommission `502d470e-3692-459a-a1a0-e868063db0fc`
    showed that MAAS recovery semantics still do not line up cleanly with operator
    expectations or the documented recovery matrix.

    Observed workflow chain: - original workflow id `maas-decommission:502d470e-3692-459a-a1a0-e868063db0fc`
    / run `f710deb4-492e-4bc3-97db-102908b4954a` failed on `node_completion_guard_failed`
    - rerun created fresh workflow identities `...:2` and `...:3`, which is the expected
    top-level rerun model - resume, however, did not behave like a clear checkpoint
    continuation from the failed stage and operator readback was confusing enough
    that the next live error appeared to come from an earlier MAAS release stage even
    though the original interest was the post-MAAS node boundary

    The Temporal UI and backend behavior together suggest: - `rerun` semantics are
    closer to the intended model (fresh workflow execution identity) - `resume` semantics
    are still ambiguous or incomplete at the workflow/runtime boundary - workflow
    detail/readmodel/UI do not separate current run vs prior failed run strongly enough
    for repeated-node operator use

    This should be treated as a Temporal recovery semantics slice, not just a UI wording
    problem.


    Scope:

    - In: define and implement exact backend/Temporal behavior for `resume` vs `rerun`
    on MAAS onboarding and decommission workflows, including what happens to workflow
    IDs, run IDs, attempt counters, and current-stage recovery after manual prerequisite
    fixes.

    - In: make service/readmodel state and workflow execution state agree on the active
    attempt/run so workflow detail pages can present current vs prior attempts correctly.

    - In: regression coverage based on the concrete decommission chain above so `resume`
    and `rerun` each prove the intended execution model.

    - Out: general workflow UI redesign beyond the semantics/data needed for correct
    current-attempt presentation.

    '
- id: A-MAAS-DISCOVERY-CREATE-FALLBACK-001
  title: Implement MAAS machine discovery and create fallback when hostname and IPMI
    match do not resolve an existing machine
  role: A-backend
  status: todo
  priority: 916
  owner: ''
  branch: agent/A-backend
  completed_at: ''
  commit: ''
  depends_on:
  - A-MAAS-ONBOARDING-WORKFLOW-EXECUTION-001
  acceptance_checks:
  - go test ./packages/services/maas ./cmd/provisioning-worker
  - make test-integration
  - make queue-git-check
  notes: 'Context:

    The current live workflow only succeeds when MAAS already has a resolvable machine
    by hostname or IPMI power address. The original `../maas` behavior also covers
    create/discovery fallback and controlled acceptance of newly discovered machines.


    Scope:

    - In: create/discovery fallback path, deterministic ambiguity handling, and policy-controlled
    acceptance of newly discovered MAAS machines when no direct match exists.

    - Out: broad multi-candidate auto-claim or batch discovery heuristics.

    '
- id: A-MAAS-DEPLOY-FAILURE-CLASSIFICATION-RETRY-001
  title: Classify MAAS deploy datasource failures and implement bounded release to
    Ready retry
  role: A-backend
  status: todo
  priority: 917
  owner: ''
  branch: agent/A-backend
  completed_at: ''
  commit: ''
  depends_on:
  - A-MAAS-ONBOARDING-WORKFLOW-EXECUTION-001
  acceptance_checks:
  - go test ./packages/services/maas ./cmd/provisioning-worker
  - make test-integration
  - make queue-git-check
  notes: 'Context:

    The MAAS lifecycle docs preserve a bounded classified retry model for datasource/cloud-init
    failures, but the live workflow does not yet implement the full classify -> release
    to Ready -> retry path.


    Scope:

    - In: deploy failure classification, bounded retry policy enforcement, release
    back to `Ready` before retry, and operator-visible failure/retry evidence in the
    workflow timeline.

    - Out: unbounded retries or provider-agnostic retry abstractions.

    '
- id: A-MAAS-HW-SYNC-COMPLETION-GATE-001
  title: Require healthy MAAS hardware sync before onboarding is considered fully
    complete
  role: A-backend
  status: todo
  priority: 918
  owner: ''
  branch: agent/A-backend
  completed_at: ''
  commit: ''
  depends_on:
  - A-MAAS-POSTDEPLOY-COMPLETION-GUARDS-001
  acceptance_checks:
  - go test ./packages/services/maas ./cmd/provisioning-worker
  - make test-integration
  - make queue-git-check
  notes: 'Context:

    The docs treat MAAS hardware sync as a required invariant for MAAS-managed nodes,
    but the current live success path proves active node enrollment more strongly
    than verified MAAS hardware-sync health.


    Scope:

    - In: explicit hardware-sync seed or verification stage, healthy sync checks in
    onboarding completion logic, and operator-visible failure state when MAAS sync
    is not healthy after deploy.

    - Out: unrelated host telemetry or generic node-health monitoring.

    '
- id: A-MAAS-DECOMMISSION-PARITY-001
  title: Bring MAAS decommission and release fallback behavior to the same proven
    level as onboarding
  role: A-backend
  status: todo
  priority: 919
  owner: ''
  branch: agent/A-backend
  completed_at: ''
  commit: ''
  depends_on:
  - A-MAAS-ONBOARDING-WORKFLOW-EXECUTION-001
  acceptance_checks:
  - go test ./packages/services/maas ./cmd/provisioning-worker
  - make test-integration
  - make queue-git-check
  notes: 'Context:

    Onboarding is now live-proven, but decommission and release fallback semantics
    from the MAAS design are not yet proven to the same standard. The documented `abort
    -> mark-fixed -> forced no-erase release` behavior still needs real workflow parity.


    Scope:

    - In: decommission execution parity, release fallback behavior, and matching workflow
    diagnostics/recovery actions.

    - Out: unrelated inventory retirement work outside the MAAS ownership boundary.

    '
- id: A-NODEAGENT-CLEANUP-TASK-CONTRACTS-001
  title: Define typed node-agent cleanup task contracts for GPU scrub, storage cleanup,
    and cleanliness validation
  role: A-backend
  status: todo
  priority: 919
  owner: ''
  branch: agent/A-backend
  completed_at: ''
  commit: ''
  depends_on:
  - A-MAAS-DECOMMISSION-PARITY-001
  acceptance_checks:
  - rg -q "node.gpu_scrub" doc/api/asyncapi.draft.yaml cmd/node-agent/catalog.go
  - rg -q "node.storage_cleanup" doc/api/asyncapi.draft.yaml cmd/node-agent/catalog.go
  - rg -q "node.validate_clean" doc/api/asyncapi.draft.yaml cmd/node-agent/catalog.go
  - make queue-git-check
  notes: 'Context:

    `soft_reset` and `storage_cleanup` cannot be implemented honestly until the platform
    has explicit typed cleanup tasks instead of vague operator assumptions. The missing
    host-side capabilities are GPU/runtime scrub, storage cleanup, and a final cleanliness
    verification step.


    Scope:

    - In: contract-first task definitions, payload/response semantics, task-catalog
    registration, and explicit success/failure semantics for cleanup and validation.

    - Out: task execution logic itself.

    '
- id: A-NODEAGENT-CLEANUP-TASK-IMPLEMENTATION-001
  title: Implement node-agent cleanup tasks for GPU scrub, storage cleanup, and validate-clean
  role: A-backend
  status: todo
  priority: 920
  owner: ''
  branch: agent/A-backend
  completed_at: ''
  commit: ''
  depends_on:
  - A-NODEAGENT-CLEANUP-TASK-CONTRACTS-001
  acceptance_checks:
  - go test ./cmd/node-agent
  - go test ./packages/services/provisioning/worker
  - make queue-git-check
  notes: 'Context:

    Once the cleanup task contracts exist, the node-agent still needs real implementations
    that can scrub runtime/GPU residue, clean approved storage locations, and verify
    the machine is safe to return to service.


    Scope:

    - In: node-agent task handlers, cleanup command execution, validation logic, logging/audit
    metadata, and failure classification.

    - Out: MAAS workflow orchestration that uses these tasks.

    '
- id: A-WORKER-CLEANUP-ORCHESTRATION-001
  title: Add provisioning-worker orchestration for node cleanup tasks and cleanliness
    gating
  role: A-backend
  status: todo
  priority: 921
  owner: ''
  branch: agent/A-backend
  completed_at: ''
  commit: ''
  depends_on:
  - A-NODEAGENT-CLEANUP-TASK-IMPLEMENTATION-001
  acceptance_checks:
  - go test ./packages/services/provisioning/worker ./cmd/provisioning-worker
  - make test-integration
  - make queue-git-check
  notes: 'Context:

    The node-agent cleanup tasks are only useful once the provisioning worker can
    dispatch them, wait for completion, classify cleanup failures, and gate subsequent
    lifecycle transitions on validated clean state.


    Scope:

    - In: Temporal activities, task dispatch/wait logic, timeout/retry rules, compensation
    boundaries, and operator-visible cleanup stage transitions.

    - Out: MAAS-specific reimage/release orchestration beyond consuming these cleanup
    results.

    '
- id: A-MAAS-SOFT-RESET-MODE-001
  title: Implement honest MAAS soft_reset mode using cleanup tasks without full redeploy
  role: A-backend
  status: todo
  priority: 922
  owner: ''
  branch: agent/A-backend
  completed_at: ''
  commit: ''
  depends_on:
  - A-WORKER-CLEANUP-ORCHESTRATION-001
  acceptance_checks:
  - go test ./packages/services/maas ./cmd/provisioning-worker
  - make test-integration
  - make queue-git-check
  notes: 'Context:

    `soft_reset` should mean drain, scrub, validate clean, and return the node to
    service without a full MAAS redeploy. That requires the cleanup path to be real
    first; otherwise the mode name overpromises isolation.


    Scope:

    - In: MAAS decommission workflow support for `soft_reset`, cleanup-task orchestration,
    reactivation logic, and clear workflow diagnostics.

    - Out: full redeploy/reimage behavior, which belongs to `reimage`.

    '
- id: A-MAAS-STORAGE-CLEANUP-MODE-001
  title: Implement honest MAAS storage_cleanup mode with validated host cleanup semantics
  role: A-backend
  status: todo
  priority: 923
  owner: ''
  branch: agent/A-backend
  completed_at: ''
  commit: ''
  depends_on:
  - A-WORKER-CLEANUP-ORCHESTRATION-001
  acceptance_checks:
  - go test ./packages/services/maas ./cmd/provisioning-worker
  - make test-integration
  - make queue-git-check
  notes: 'Context:

    `storage_cleanup` needs a narrower but still provable cleanup path that can remove
    workload data and verify cleanliness without pretending a full redeploy occurred.


    Scope:

    - In: MAAS decommission workflow support for `storage_cleanup`, storage-focused
    cleanup task usage, validate-clean gating, and operator-visible failure/recovery
    surfaces.

    - Out: full OS redeploy or generic host teardown outside the mode contract.

    '
- id: A-MAAS-TEMPORAL-ACTIVITY-PARITY-001
  title: Continue splitting MAAS workflow behavior into Temporal-native stage activities
    and compensation boundaries
  role: A-backend
  status: todo
  priority: 920
  owner: ''
  branch: agent/A-backend
  completed_at: ''
  commit: ''
  depends_on:
  - A-MAAS-ONBOARDING-WORKFLOW-EXECUTION-001
  acceptance_checks:
  - go test ./packages/services/maas ./cmd/provisioning-worker
  - make test-integration
  - make queue-git-check
  notes: 'Context:

    The workflow is already much closer to proper Temporal stage ownership, but a
    few recovery and compensation semantics are still more workflow-managed than fully
    activity-native. Continuing that split will make targeted retry and future compensation
    cleaner.


    Scope:

    - In: stage-level Temporal ownership, clearer activity retry/timeout boundaries,
    and cleaner compensation hooks for MAAS workflow stages.

    - Out: rebuilding the MAAS workflow from scratch or collapsing domain state back
    into Temporal history alone.

    '
- id: A-MAAS-SITE-PROFILES-001
  title: Introduce MAAS site profile model for per-site operational policy bundles
  role: A-backend
  status: done
  priority: 908
  owner: A
  branch: agent/A-backend
  completed_at: '2026-03-12'
  commit: 99d5d9f
  depends_on:
  - A-MAAS-SITE-SCHEMA-AND-CLIENT-001
  acceptance_checks:
  - make codegen
  - go test ./packages/services/maas ./cmd/api
  - make queue-git-check
  notes: 'Context:

    The current MAAS site implementation stores operational policy directly at the
    site level so the first admin and workflow slices can land quickly. That is acceptable
    for the bootstrap phase, but it will become limiting once one MAAS site needs
    multiple operational modes or host classes.

    Scope:

    - In: `maas_site_profiles` schema, profile CRUD contract, default profile selection,
    and workflow inputs carrying both `site_id` and `profile_id`.

    - Out: profile-aware workflow execution changes beyond wiring the new identifiers
    through contracts and storage.

    '
- id: A-MAAS-SITE-PROFILE-SCOPE-CORRECTION-001
  title: Move MAAS deploy user from profile policy to site scope only
  role: A-backend
  status: todo
  priority: 266
  owner: ''
  branch: agent/A-backend
  completed_at: ''
  commit: ''
  depends_on:
  - A-MAAS-SITE-PROFILES-001
  acceptance_checks:
  - make codegen
  - go test ./packages/services/maas ./cmd/api
  - make queue-git-check
  notes: 'Context:

    The initial site/profile implementation still allows `deploy_user` inside MAAS
    profile policy because it inherited the prototype''s flatter environment model.
    The intended operating model is one deploy user per MAAS site, with profiles only
    varying operational behavior. Leaving `deploy_user` profile-scoped will create
    avoidable ambiguity and invalid profile combinations on the same site.

    Scope:

    - In: move `deploy_user` to site scope, remove profile-level override semantics,
    keep `deploy_password` in the site credentials path, and adjust UX/docs/contracts
    accordingly.

    - Out: broader MAAS credential-model redesign beyond this site-vs-profile ownership
    correction.

    '
- id: B-MAAS-SITE-PROFILES-UX-001
  title: Add MAAS admin UX for site profile management and selection
  role: B-ui
  status: done
  priority: 907
  owner: B
  branch: agent/B-ui
  completed_at: '2026-03-14'
  commit: 64cd39b
  depends_on:
  - A-MAAS-SITE-PROFILES-001
  acceptance_checks:
  - make verify-web
  - make queue-git-check
  notes: 'Context:

    Operators should be able to manage multiple policy bundles per MAAS site once
    profiles exist in the control plane. This UX should extend site management with
    profile list/detail/create/edit flows and make the default profile visible.

    Scope:

    - In: profile CRUD UX, default-profile presentation, and profile selection in
    future onboarding entry points.

    - Out: executing full onboarding/decommission workflows.

    '
- id: B-MAAS-ADMIN-IA-REFRESH-001
  title: Restructure MAAS admin UX into summary, create, and site-detail pages
  role: B-ui
  status: done
  priority: 286
  owner: B
  branch: agent/B-ui
  completed_at: '2026-03-14'
  commit: 81e275c
  depends_on:
  - B-MAAS-SITE-ADMIN-UX-001
  - B-MAAS-SITE-PROFILES-UX-001
  acceptance_checks:
  - make verify-web
  - make queue-git-check
  notes: 'Context:

    The current `/admin/maas` page was a useful bootstrap UX, but it now mixes summary,
    create-site, selected-site edit, selected-site credentials/connectivity, profiles,
    and workflow summaries into one overloaded screen. That makes site-scoped sections
    look ambiguous and will only get worse as workflow actions land.

    Scope:

    - In: `/admin/maas` as summary/hub, `/admin/maas/new` as create-site, and `/admin/maas/[siteId]`
    as site detail/edit, credentials/connectivity, profiles, and linked lifecycle
    views.

    - Out: backend contract redesign; keep current MAAS backend APIs and improve information
    architecture/routing only.

    '
- id: B-ADMIN-ACTIONABLE-ERROR-MESSAGES-001
  title: Replace generic admin load failures with actionable section-level errors
  role: B-ui
  status: done
  priority: 285
  owner: B
  branch: agent/B-ui
  completed_at: '2026-03-14'
  commit: 6a05e13
  depends_on:
  - B-MAAS-ADMIN-IA-REFRESH-001
  acceptance_checks:
  - make verify-web
  - make queue-git-check
  notes: 'Context:

    Several admin surfaces still collapse read-model or backend failures into generic
    messages like "Check the backend and retry."

    That slows down operators even though the platform already carries correlation
    IDs and section-level fetch boundaries.


    Scope:

    - In: section-scoped actionable errors for admin pages, starting with MAAS and
    node/operator surfaces.

    - Out: redesign of the shared API error envelope.


    Required behavior:

    - identify which section failed instead of failing the whole page generically

    - preserve successful sections when one section load fails

    - surface correlation ID when the backend returns one

    - use clearer operator language than "check backend"

    '
- id: B-ADMIN-FOUNDATION-AND-HYBRID-IA-001
  title: Establish shared admin UI foundation and hybrid summary-detail information
    architecture
  role: B-ui
  status: done
  priority: 284
  owner: B
  branch: agent/B-ui
  completed_at: '2026-03-14'
  commit: b065081
  depends_on: []
  acceptance_checks:
  - make verify-web
  - make queue-git-check
  notes: "Context:\nThe admin/operator surfaces are now useful but still inconsistent.\
    \ Pages repeatedly mix fetch logic, polling, tables, forms, and workflow-specific\
    \ rendering in one file. The MAAS and node workflow pages proved the control-plane\
    \ model, but they also exposed the need for a cleaner admin foundation and a more\
    \ intentional information architecture.\n\nDirection:\n- Keep: Next.js, React,\
    \ TypeScript, Tailwind, Lucide, xterm.\n- Adopt for admin surfaces: TanStack Query\
    \ for server state, react-hook-form + zod for forms, TanStack Table for admin\
    \ list views, and shared page primitives built on the existing UI layer.\n- Do\
    \ not add Redux/Zustand, GraphQL, CSS-in-JS, or a separate design-system package.\n\
    \nHybrid IA rule:\n- Use summary -> detail everywhere.\n- Use drawers/slide-overs\
    \ for quick record inspection and lightweight edits.\n- Keep dedicated pages for\
    \ workflow detail, timelines, recovery actions, and observability-heavy views\
    \ (for example MAAS onboarding and decommission workflows).\n\nRequired foundation\
    \ work:\n- add shared admin query patterns so list/detail polling and auto-refresh\
    \ stop being reimplemented page by page\n- add shared admin form patterns so large\
    \ operator forms stop using many ad hoc `useState` fields\n- add a reusable admin\
    \ table wrapper with sorting/filtering/column-visibility/pagination support\n\
    - add shared KPI/status-strip, filter-bar, empty-state, and drawer primitives\
    \ for admin pages\n- standardize page anatomy across admin views:\n  1. page title\
    \ / breadcrumb\n  2. KPI or status strip\n  3. filters/search\n  4. main content\
    \ area\n  5. optional drawer for quick detail\n\nMigration scope:\n- start with\
    \ MAAS and Nodes admin surfaces because they are highest churn and already expose\
    \ the current UX pain\n- treat onboarding/decommission detail pages as the reference\
    \ pattern for \"dedicated workflow page\"\n- do not attempt a big-bang rewrite\
    \ of all admin/user pages in one task\n\nDeliverables:\n- architecture note or\
    \ implementation spec for the admin UI foundation\n- shared primitives/hooks/components\
    \ landed in `packages/web`\n- at least one admin list page and one admin form\
    \ page migrated to the new patterns\n- clear follow-up slicing for remaining admin\
    \ pages\n\nOut:\n- visual redesign for its own sake\n- rewriting low-churn user-facing\
    \ pages unless touched by adjacent work\n"
- id: B-ADMIN-DEBUG-DUMP-CLEANUP-001
  title: Sweep stale-token admin pages and redesign remaining debug-dump admin surfaces
  role: B-ui
  status: done
  priority: 283
  owner: B
  branch: agent/B-ui
  completed_at: '2026-03-14'
  commit: d2ef644
  depends_on:
  - B-ADMIN-FOUNDATION-AND-HYBRID-IA-001
  - B-ADMIN-ACTIONABLE-ERROR-MESSAGES-001
  acceptance_checks:
  - make verify-web
  - make queue-git-check
  notes: 'Context:

    A review of the remaining admin/operator surfaces found two related problems:

    1. correctness: several pages still capture a stale access token once at mount
    and do not react to session refresh or identity change.

    2. presentation: several pages still read like debug dumps instead of operator-facing
    admin views.


    Required sequencing:

    - First: do the stale-token sweep as a mechanical correctness pass.

    - Second: redesign the identified debug-dump pages using the new admin foundation
    primitives rather than ad hoc tables.

    Do not do both as one giant refactor commit. Keep the token sweep and the page
    redesigns reviewable.


    Stale-token sweep scope:

    - remove remaining `useMemo(() => getAccessToken(), [])` and equivalent one-time
    token capture patterns from the affected admin pages

    - use the same reactive token/session pattern already adopted in the newer MAAS
    pages

    - preserve session-refresh correctness across background refetch and mutation
    paths


    Debug-dump redesign scope:

    - `/admin/audit-logs` - `/admin/allocations` - `/admin/payments/sessions` - notifications
    surface still showing inline `type={...}` style raw presentation

    Target pattern:

    - proper table columns with operator labels instead of raw field dumps

    - expandable row or detail panel for raw metadata/correlation ID

    - status/result badges where appropriate

    - linked user/node/allocation identifiers instead of opaque inline UUID dumps
    when navigable


    Reference pattern:

    - use `/admin/skus` as the reference for list ergonomics and admin foundation
    usage

    - keep workflow-heavy pages on dedicated detail pages rather than forcing everything
    into a drawer


    Out:

    - backend contract churn unless a real missing read-model/API surface is discovered

    - redesigning already-good pages only for visual consistency

    '
- id: A-ADMIN-ALLOCATIONS-DISPLAY-ENRICHMENT-001
  title: Enrich admin allocation read models with human display fields and UUID copy
    affordances
  role: A-backend
  status: done
  priority: 282
  owner: A
  branch: agent/A-backend
  completed_at: '2026-04-28'
  commit: ceddcb7a
  depends_on: []
  acceptance_checks:
  - make codegen
  - bash scripts/ci/contracts_validate.sh
  - go test ./cmd/api ./packages/services/admin ./packages/services/provisioning/...
  - pnpm --dir packages/web exec vitest run app/admin/allocations/page.test.tsx app/allocations/page.test.tsx
  - pnpm --dir packages/web typecheck
  - make queue-git-check
  notes: 'Context:

    `/admin/allocations` currently exposes raw UUIDs (`requested_by_user_id`, `node_id`)
    as the primary operator-facing labels. That is operationally weak: operators need
    human-readable names first and still need one-click access to the canonical IDs.
    The user-facing `/allocations` page may also need a lighter pass if raw IDs remain
    exposed awkwardly there.

    Requirements:

    - update the admin allocation contract first so list/detail responses can include
    additive display fields such as: - `requested_by_username` - `requested_by_display_name`
    if available - `node_hostname` - optional `project_name` if the page needs it

    - keep canonical IDs in the contract; do not replace IDs with labels

    - update backend read models/services/handlers to populate the additive display
    fields from owning domain sources

    - update `/admin/allocations` to show human-readable labels first and UUIDs as
    secondary copyable values

    - add one-click copy affordances for allocation, user, and node IDs where operators
    still need the canonical identifier

    - review `/allocations` and apply only the minimal corresponding UI cleanup if
    raw UUID exposure there is still operator/user-hostile

    Decision:

    - `/admin/allocations` and `/allocations` stay separate pages because they serve
    different audiences and actions

    Scope:

    - In: additive OpenAPI change, backend read-model enrichment, admin allocation
    UI cleanup, UUID copy affordances, optional minimal user-page polish

    '
- id: A-ADMIN-AUDIT-PRESENTATION-MODEL-001
  title: Add backend-owned audit presentation model and action registry for operator
    audit surfaces
  role: A-backend
  status: done
  priority: 281
  owner: codex
  branch: agent/A-backend
  completed_at: '2026-04-26'
  commit: 04b202cb
  depends_on: []
  acceptance_checks:
  - make codegen
  - bash scripts/ci/contracts_validate.sh
  - go test ./cmd/api ./packages/services/admin/...
  - make queue-git-check
  notes: 'Context:

    The current audit log surface is closer to a raw debug stream than an operator-grade
    audit product. It exposes raw action strings, UUID-heavy actor/target fields,
    and ad hoc metadata that would force the UI to special-case each new action if
    we tried to solve this only in the page layer.

    Goal:

    - move audit presentation ownership to the backend so new privileged actions scale
    without requiring page-specific UI logic

    Requirements:

    - define a backend-owned audit action registry/catalog that maps raw action identifiers
    to stable presentation metadata such as: - category/domain - operator-facing summary
    template - target type label - default severity/outcome semantics - safe detail
    fields to surface in the UI

    - extend the audit read model/API additively so audit rows can return normalized
    presentation data, including: - actor display label - target display label - action
    category/family - human-readable summary - result severity / outcome classification
    - correlation/debug affordances

    - keep raw audit fields and immutable audit semantics intact; this is a presentation-model
    enrichment, not an audit rewrite

    - ensure new actions can be onboarded by updating the backend registry rather
    than editing the audit page itself

    Scope:

    - In: additive contract/read-model enrichment, backend registry/catalog, handler/service
    updates, tests for known action families

    - Out: page-specific visual redesign without the enriched backend model, or changing
    immutable audit row semantics

    '
- id: B-ADMIN-AUDIT-LOGS-OPERATOR-UX-001
  title: Rebuild admin audit logs on top of the backend audit presentation model
  role: B-ui
  status: todo
  priority: 280
  owner: ''
  branch: agent/B-ui
  completed_at: ''
  commit: ''
  depends_on:
  - A-ADMIN-AUDIT-PRESENTATION-MODEL-001
  acceptance_checks:
  - pnpm --dir packages/web exec vitest run app/admin/audit-logs/page*.test.tsx
  - pnpm --dir packages/web typecheck
  - make verify-web
  - make queue-git-check
  notes: 'Context:

    Do not keep patching `/admin/audit-logs` as a raw-field dump. Once the backend
    audit presentation model exists, the UI should become a stable operator surface
    that renders the enriched API generically instead of special-casing each action.

    Requirements:

    - consume backend-provided audit presentation fields as the primary display surface

    - show human-readable action summaries, actor/target labels, category, result
    severity, and correlation affordances

    - keep raw metadata/details available behind an expandable row or detail panel
    for debugging

    - avoid per-action UI branching unless a true interaction difference exists

    - use the shared admin foundation patterns already established (`DataTable`, filters,
    detail panel/expandable rows, empty/error states)

    Scope:

    - In: admin audit logs page redesign on top of the enriched backend model

    - Out: inventing presentation logic in the page that belongs in the backend action
    registry

    '
- id: B-E2E-FAIL-CLOSED-BACKEND-MOCKING-001
  title: Make persona E2E backend mocking fail closed on unmocked routes
  role: B-ui
  status: done
  priority: 279
  owner: B-ui
  branch: agent/B-ui
  completed_at: '2026-03-15'
  commit: 30f4d5c
  depends_on: []
  acceptance_checks:
  - pnpm --dir packages/web exec playwright test packages/web/e2e/persona-admin.spec.ts
  - make verify-web
  - make queue-git-check
  notes: 'Context:

    The recent persona-admin test fix added a `**/backend/**` catch-all that returns
    `200` for any unmocked backend request. That prevents auth redirect loops, but
    it also hides new backend dependencies and contract drift by turning unexpected
    requests into false-green test passes.

    Requirements:

    - replace permissive catch-all backend mocking with a fail-closed pattern

    - unmocked `**/backend/**` requests must fail the test loudly with a clear error
    that identifies the unexpected route

    - keep explicit mocks for known routes such as `/api/v1/projects`

    - preserve the original goal of preventing accidental calls to the real backend
    during E2E tests

    Scope:

    - In: Playwright persona/admin/backend route mocking harness and related tests

    - Out: backend API changes or production client behavior changes

    '
- id: B-TERMINAL-TEST-HARNESS-STABILIZATION-001
  title: Stabilize terminal UI tests by centralizing xterm and browser-environment
    shims
  role: B-ui
  status: done
  priority: 280
  owner: B
  branch: agent/B-ui
  completed_at: '2026-03-17'
  commit: cb95e2d
  depends_on: []
  acceptance_checks:
  - pnpm --dir packages/web exec vitest run src/components/terminal/TerminalPanel.test.tsx
  - make verify-web
  - make queue-git-check
  notes: 'Context:

    The terminal UI test suite has produced repeated latent failures as xterm internals
    touched more real browser APIs during Vitest/jsdom runs. Recent fixes had to patch
    missing pieces incrementally (`FitAddon.activate/dispose`, then `window.matchMedia`),
    which indicates the terminal test boundary is too leaky.

    Required outcome:

    - centralize the browser/xterm shims needed by terminal component tests

    - stop relying on one-off per-failure patches when xterm touches another browser
    primitive

    - decide whether terminal Vitest coverage should: - fully mock xterm at the module
    boundary, or - use one shared test setup for the minimum browser APIs xterm needs

    - keep Playwright responsible for real browser integration, while Vitest stays
    deterministic and fail-fast

    Scope:

    - In: terminal UI Vitest harness, shared test setup utilities, and related documentation/comments

    - Out: changing the production terminal behavior or removing browser-level E2E
    coverage

    '
- id: B-SEC-FRONTEND-SAST-TRIAGE-001
  title: Triage frontend-owned SAST and Semgrep findings
  role: B-ui
  status: done
  priority: 281
  owner: B
  branch: agent/B-ui
  completed_at: '2026-03-17'
  commit: 2eda01f
  depends_on: []
  acceptance_checks:
  - make queue-git-check
  - make verify-web
  - pnpm --dir packages/web typecheck
  - pnpm --dir packages/web exec vitest run
  notes: 'Context:

    Recent SAST/Semgrep review found a mix of real backend issues, infra policy findings,
    and UI/test-tooling noise. The frontend-owned portion should be handled explicitly
    by B-ui instead of leaving the report as a shared ambiguous backlog.

    Required outcome:

    - review current findings that map to `packages/web/**` or frontend test/tooling

    - classify each item as: - immediate fix - backlog hardening - documented false
    positive / accepted pattern

    - land straightforward UI-owned fixes where the scope is clear

    - document rationale for frontend findings that should not be treated as defects

    Scope:

    - In: `packages/web/**`, frontend test/tooling, and UI-owned Semgrep/SAST findings

    - Out: backend/API/worker findings and CI/report-pipeline ownership changes

    '
- id: B-OPS-RUNTIME-METADATA-VISIBILITY-001
  title: Surface live service runtime image and commit metadata in admin UI
  role: B-ui
  status: todo
  priority: 282
  owner: ''
  branch: agent/B-ui
  completed_at: ''
  commit: ''
  depends_on:
  - A-OPS-RUNTIME-METADATA-ENDPOINT-001
  acceptance_checks:
  - make queue-git-check
  - make verify-web
  - pnpm --dir packages/web typecheck
  - pnpm --dir packages/web exec vitest run
  notes: 'Context:

    Recent platform-control rollout/debug work repeatedly needed direct cluster inspection
    to answer a simple ops question: what code and image is actually running right
    now? This is especially important for environment-bound work such as MAAS where
    local validation is not enough and stale deploy state can masquerade as application
    defects.

    Required outcome:

    - add an admin-visible runtime metadata panel for platform-control services

    - surface at least: - deployed commit / git sha - image ref or digest - pipeline
    id - deploy timestamp when available

    - make the first version useful for control-plane debugging even if it starts
    with `gpuaas-api` only

    Scope:

    - In: admin UI/runtime metadata presentation, frontend contract consumption, and
    tests

    - Out: backend collection/storage design changes beyond what is necessary to expose
    existing runtime annotations

    '
- id: A-OPS-RUNTIME-METADATA-ENDPOINT-001
  title: Add admin runtime metadata endpoint for live service image and commit visibility
  role: A-backend
  status: done
  priority: 282
  owner: Codex
  branch: agent/A-backend
  completed_at: '2026-04-27'
  commit: 04935166
  depends_on: []
  acceptance_checks:
  - bash scripts/ci/contracts_validate.sh
  - go test ./cmd/api
  - make queue-git-check
  notes: 'Context:

    Recent platform-control rollout/debug work repeatedly needed direct cluster inspection
    to answer a simple ops question: what code and image is actually running right
    now? The UI should surface this, but it needs a contract-backed admin API first.

    Required outcome:

    - define the contract-first admin API for runtime metadata visibility

    - implement an admin-only endpoint that returns live runtime metadata for platform-control
    services

    - source at least: - deployed commit / git sha - image ref or digest - pipeline
    id - deploy timestamp when available

    - keep the first version useful even if it starts with `gpuaas-api` only

    Scope:

    - In: `doc/api/openapi.draft.yaml`, admin API handler/service wiring, tests, and
    sourcing existing runtime annotations

    - Out: the frontend/admin UI presentation layer

    '
- id: C-PLATFORM-CONTROL-GITOPS-EVALUATION-001
  title: Evaluate ArgoCD or Flux adoption after rollout-hardening invariants are encoded
  role: C-ops
  status: todo
  priority: 210
  owner: ''
  branch: agent/C-ops
  completed_at: ''
  commit: ''
  depends_on:
  - A-PLATFORM-CONTROL-DEPLOY-IMAGE-FRESHNESS-001
  acceptance_checks:
  - make queue-git-check
  notes: 'Context:

    Platform-control rollout is currently script-driven. GitOps may reduce custom
    deploy orchestration and improve drift visibility, but adopting ArgoCD or Flux
    before rollout-hardening invariants are explicit would only move fragile logic
    into a different tool.

    Goal:

    - evaluate GitOps adoption only after image identity, rendered config/secret validation,
    and remote validation gates are already encoded

    Requirements:

    - compare ArgoCD and Flux specifically for platform-control needs: - desired-state
    reconciliation - drift visibility - rollout history - pre/post-sync validation
    hooks - operational UX for the team

    - document how current release-hardening checks would map into a GitOps model:
    - image freshness verification - rendered secret/config validation - remote validation
    as release criteria

    - recommend one concrete direction (or justify staying script-driven longer)

    Scope:

    - In: evaluation, migration outline, and fit analysis for platform-control rollout

    - Out: immediate GitOps migration before current rollout-hardening tasks are complete

    '
- id: C-CI-RUNNER-TOPOLOGY-PLANNING-001
  title: Plan CI runner classes and capacity for fast checks build scans and deploy
    validation
  role: C-ops
  status: todo
  priority: 209
  owner: ''
  branch: agent/C-ops
  completed_at: ''
  commit: ''
  depends_on:
  - A-SEC-SAST-REPORT-001
  - A-SEC-IMAGE-SCAN-REPORT-001
  - A-CONTRACT-SCHEMATHESIS-RUNTIME-CONFORMANCE-001
  acceptance_checks:
  - make queue-git-check
  notes: 'Context:

    The pipeline is accumulating heavier checks: browser/E2E, image build + scan,
    platform-control deploy + remote validation, and upcoming runtime conformance
    / DAST. Runner capacity should be planned by workload class instead of growing
    one generic pool blindly.

    Requirements:

    - define recommended runner classes such as: - fast CI for contracts/unit/codegen/lint
    - build/image runner for Docker build + image scans - deploy runner for platform-control
    deploy/remote validation - optional browser runner for Playwright

    - estimate which current and near-term jobs belong to each class

    - document the trigger for adding more runners vs rebalancing existing ones

    - include isolation/security considerations for deploy-capable runners

    Scope:

    - In: runner topology recommendation and capacity plan

    - Out: immediate runner procurement or a broad CI platform migration in the same
    slice

    - Out: collapsing admin and user allocation pages into one surface, or removing
    canonical IDs from the system

    '
- id: A-NODE-BOOTSTRAP-SCRIPT-ENDPOINT-001
  title: Implement bootstrap-script issuance and brokered bootstrap-token endpoint
    so node onboarding can run as one command instead of exposing raw OCI/Vault metadata
  role: A-backend
  status: done
  priority: 4
  owner: A-backend
  branch: agent/A-backend
  completed_at: '2026-03-10'
  commit: e0bf99f
  depends_on:
  - A-NODE-AGENT-OCI-BOOTSTRAP-001
  - A-VAULT-PLATFORM-SECRETS-IMPLEMENTATION-001
  - A-NODE-BOOTSTRAP-TRUST-DELIVERY-001
  acceptance_checks:
  - rg -q "bootstrap-script|bootstrap token|cloud-init" doc/architecture/Node_Bootstrap_Script_and_Token_v1.md
  - go test ./cmd/api ./cmd/node-agent
  - bash scripts/ci/agent_queue_validate.sh
  - make queue-git-check
  notes: Add a control-plane-brokered bootstrap-script flow for nodes. The script
    must write trust material, resolve short-lived package pull credentials, pull
    the bootstrap OCI package by digest, install the node agent, and optionally enable/start
    the systemd unit. Do not use a general service account for first bootstrap; use
    a node-bound short-lived bootstrap token.
- id: A-PLATFORM-ACCESS-CREDENTIALS-API-001
  title: Define and implement admin-scoped platform access-credential APIs and custody
    references for machine and registry access workflows
  role: A-backend
  status: done
  priority: 4
  owner: Codex
  branch: agent/A-backend
  completed_at: '2026-04-26'
  commit: cbba0787
  depends_on:
  - A-VAULT-PLATFORM-SECRETS-IMPLEMENTATION-001
  acceptance_checks:
  - rg -q "Initial Acceptance Criteria" doc/architecture/Platform_Access_Credential_Model_v1.md
  - bash scripts/ci/contracts_validate.sh
  - go test ./cmd/api ./packages/services/admin
  - bash scripts/ci/agent_queue_validate.sh
  - make queue-git-check
  notes: 'Context:

    The queue had a live dependency on this task from bootstrap-script issuance work,
    but the task itself was never represented in the active backlog even though the
    architecture and acceptance criteria are already documented in `Platform_Access_Credential_Model_v1.md`.

    Scope:

    - In: admin-scoped APIs to create/list/get/rotate/disable platform access-credential
    references, Vault-backed custody metadata, and attachment/reference model for
    machine and registry workflows.

    - In: stable credential metadata/read model and workflow-facing reference consumption
    so host/runtime flows can consume managed references without logging or returning
    raw secrets by default.

    - Out: forcing node-agent lifecycle onto platform-managed SSH execution; reimage
    and manual-install remain valid alternatives.

    - Out: full tenant-facing runtime credential UX in the same slice.

    '
- id: A-PLATFORM-CONTROL-LOCAL-PREFLIGHT-HARDENING-001
  title: Harden the platform-control local preflight so release promotion catches
    admin route-guard, role-authz, audit export, and local e2e startup regressions
    before deploy
  role: A-backend
  status: done
  priority: 3
  owner: Codex
  branch: agent/A-backend
  completed_at: '2026-03-26'
  commit: 66afcb3
  depends_on: []
  acceptance_checks:
  - bash scripts/ci/platform_control_local_preflight.sh
  - go test ./cmd/api -tags integration -run TestAdminPaymentsAndAuditEndpointsIntegration
    -count=1
  - bash scripts/ci/agent_queue_validate.sh
  - make queue-git-check
  notes: Record the rollout hardening slice that made local preflight mandatory, stabilized
    local frontend e2e startup/reset behavior, and added regression coverage for audit-log
    export filtering.
- id: A-TEST-LIFECYCLE-CLEANUP-001
  title: Add reusable cleanup helpers for lifecycle-bearing test resources so validation
    tears down allocations, nodes, app instances, artifacts, service accounts, and
    storage instead of accumulating junk state
  role: A-backend
  status: done
  priority: 3
  owner: Codex
  branch: agent/A-backend
  completed_at: '2026-03-11'
  commit: db746bd
  depends_on: []
  acceptance_checks:
  - bash -n scripts/ops/disposable_project_scope.sh
  - bash scripts/ci/agent_queue_validate.sh
  - make queue-git-check
  notes: Implement a reusable disposable-scope helper for create/cleanup so teardown
    becomes part of validation instead of an optional manual step.
- id: B-QA-TEST-SESSION-GUIDE-001
  title: Write the manual QA guide for disposable test sessions so operators and QA
    use temporary projects and treat teardown failures as lifecycle bugs
  role: B-ui
  status: done
  priority: 4
  owner: Codex
  branch: agent/B-ui
  completed_at: '2026-03-11'
  commit: db746bd
  depends_on:
  - A-TEST-LIFECYCLE-CLEANUP-001
  acceptance_checks:
  - rg -q "Disposable Test Session|historical allocations" doc/operations/QA_Disposable_Test_Session_Guide.md
  - bash scripts/ci/agent_queue_validate.sh
  - make queue-git-check
  notes: Manual QA should use disposable project scope and include cleanup as part
    of the test definition, not as best-effort hygiene after the main flow.
- id: A-NODE-LIFECYCLE-UNINSTALL-001
  title: Implement host-side uninstall and cleanup semantics for removed nodes so
    node-agent service, env, and local identity material do not linger indefinitely
    after remove
  role: A-backend
  status: todo
  priority: 6
  owner: ''
  branch: ''
  completed_at: ''
  commit: ''
  depends_on:
  - A-NODE-LIFECYCLE-RETIRE-DRAIN-001
  - A-NODE-BOOTSTRAP-SCRIPT-ENDPOINT-001
  acceptance_checks:
  - go test ./cmd/api ./cmd/node-agent
  - bash scripts/ci/agent_queue_validate.sh
  - make queue-git-check
  notes: 'Context:

    The validated lifecycle now reaches add -> bootstrap -> allocate -> terminal ->
    release -> retire -> remove. What still remains incomplete is host-side post-remove
    behavior: the installed systemd unit, env file, and local cert material remain
    on the node until the next bootstrap/reinstall.


    Scope:

    - In: typed host cleanup/uninstall semantics for removed nodes, with explicit
    policy for what is deleted versus preserved.

    - Out: MaaS reimage handoff; that is a separate lifecycle step.'
- id: A-NODE-LIFECYCLE-REACTIVATE-REUSE-001
  title: Define and implement explicit reactivate and host-reuse semantics so re-adding
    a machine does not rely only on implicit identity mismatch handling
  role: A-backend
  status: todo
  priority: 6
  owner: ''
  branch: ''
  completed_at: ''
  commit: ''
  depends_on:
  - A-NODE-LIFECYCLE-UNINSTALL-001
  acceptance_checks:
  - go test ./cmd/api ./cmd/node-agent
  - bash scripts/ci/agent_queue_validate.sh
  - make queue-git-check
  notes: 'Context:

    Re-adding the same host currently works because bootstrap rewrites env and the
    node-agent re-enrolls under a new node_id. That is correct enough for now, but
    it is still implicit behavior. We need an explicit host-reuse model so reactivation,
    reinstall, and reuse semantics are deliberate and testable.


    Scope:

    - In: explicit host reuse/reactivation semantics, tests, and operator-facing expectations.

    - Out: scheduler/runtime-specific reuse behavior.'
- id: A-NODE-REENROLLMENT-RECOVERY-HARDENING-001
  title: Harden node re-enrollment recovery so admin repair updates endpoint drift,
    defines auto-recovery boundaries, and aligns with node-agent lifecycle state
  role: A-backend
  status: todo
  priority: 5
  owner: ''
  branch: ''
  completed_at: ''
  commit: ''
  depends_on:
  - A-NODE-LIFECYCLE-UNINSTALL-001
  acceptance_checks:
  - make codegen
  - go test ./cmd/api ./cmd/node-agent ./packages/services/admin
  - bash scripts/ci/agent_queue_validate.sh
  - make queue-git-check
  notes: 'Context:

    We now have an admin-scoped `reissue-enrollment` recovery API and UI, but the
    current recovery command only rotates the enrollment token and forces fresh cert
    issuance. It does not reconcile stale node-agent endpoint configuration such as
    `GPUAAS_API_URL` or `GPUAAS_TERMINAL_API_URL`, and the longer-term self-heal /
    auto-reenrollment model is still undefined.

    2026-05-03 partial hardening: node-agent task polling now detects a locally
    expired node certificate before opening the task wait request and attempts recovery
    enrollment immediately when a current `GPUAAS_ENROLLMENT_TOKEN` is present. Poll
    and maintenance retry backoffs now saturate instead of overflowing after very large
    failure counters observed on disconnected nodes. Remaining work is the contract/UI
    model for endpoint drift, missing token recovery, and operator-visible lifecycle
    reasons.

    Scope:

    - In: patch recovery command generation so it rewrites node-agent endpoint fields
    when the recovery bundle provides canonical values.

    - In: document and implement the explicit boundary between manual re-enrollment,
    automatic re-enrollment, and node-agent lifecycle-driven repair.

    - In: define operator-visible lifecycle/state reasons for cert drift, endpoint
    drift, and recovery-required nodes so recovery does not rely on journal inspection
    alone.

    - In: edge-case coverage for CA rotation, stale hostnames, lost cert/key, cloned
    images, and node records that exist while local identity material does not.

    - Out: full MaaS reimage semantics; that remains a separate lifecycle path.

    '
- id: A-SLURM-REFERENCE-CONTROLLER-HARDENING-001
  title: Harden Slurm reference controller runtime identity, SSH credential cache
    handling, and bootstrap state transitions for local parity
  role: A-backend
  status: todo
  priority: 6
  owner: ''
  branch: ''
  completed_at: ''
  commit: ''
  depends_on: []
  acceptance_checks:
  - go test ./cmd/slurm-reference-controller -count=1
  - bash infra/env/dev-gpu/slurm-reference/deploy-kind.sh
  - bash scripts/ci/agent_queue_validate.sh
  - make queue-git-check
  notes: 'Context:

    The Slurm reference app instance `1032e3ba-2bb5-4ef5-94fa-a7e175058614` was stuck
    in `deploying`, but the owning fault was not Slurm controller reachability. First,
    local parity had no running `slurm-reference-controller` deployment for the seeded
    app instance. After deploying it, the controller still failed before bootstrap
    because the pod forced `runAsUser=10001`/`runAsGroup=10001` even though the image
    only defined the `gpuaas` user at uid/gid `100/101`, which caused SSH to emit
    `No user exists for uid 10001`. Second, the controller cached delivered SSH private
    keys directly to `/tmp/slurm-reference-<credential>.key` with mode `0400` and
    then attempted to overwrite the same read-only file on the next reconcile, causing
    `open ... permission denied`.

    Delivered slice:

    - aligned the image passwd entry, Dockerfile `USER`, kind manifest, and platform-control
    manifest on uid/gid `10001:10001` - added `scripts/ci/runtime_uid_parity_guard.sh`
    to catch Dockerfile-backed app runtime UID drift before platform-control deploy
    - changed the SSH key cache write path to `/tmp/slurm-reference/<credential>.key`
    - switched cache refresh to atomic temp-file replace so repeated reconciles do
    not fail on a read-only cached key - verified the controller progressed from `allocation_bound`
    to a complete reconcile and the node returned to `State=IDLE`

    Remaining follow-up:

    - document the platform-control deployment dependency for the Slurm reference
    controller explicitly in the operator runbook - clean up bootstrap-script behavior
    around `slurm_update error: Invalid node state specified` - tighten lifecycle/reporting
    so member-operation progress is visible without relying on pod logs or direct
    DB inspection

    Scope:

    - In: controller runtime hardening, bootstrap-state visibility, and follow-up
    cleanup for the remaining Slurm bootstrap warning - Out: redesigning the whole
    reference-app execution model or replacing the app-owned controller pattern

    '
- id: A-APP-RUNTIME-MEMBER-INVENTORY-001
  title: Add app-runtime member inventory read model with member role, node binding,
    endpoint, and health fields for distributed workloads
  role: A-backend
  status: done
  priority: 5
  owner: Codex
  branch: agent/A-backend
  completed_at: '2026-04-10'
  commit: 69bc9c42
  depends_on: []
  acceptance_checks:
  - make codegen
  - go test ./cmd/api ./packages/services/appruntime ./packages/services/admin
  - bash scripts/ci/agent_queue_validate.sh
  - make queue-git-check
  notes: 'Context:

    The Kubernetes design now depends on a first-class distributed workload read model.
    The platform cannot keep treating app instances as a single opaque status row
    if Kubernetes, Slurm HA, Ray, or Spark are expected to work cleanly.

    Scope:

    - In: add a member inventory/read-model surface for app-runtime instances with
    component key, member role, bound node/allocation identity, resolved endpoint
    or node-reachable address where appropriate, health, and current operation summary.

    - In: make the shape generic for any distributed workload rather than Kubernetes-only.

    - Out: embedded UI proxying or workload-specific dashboards; those build on top
    of this read model.

    '
- id: A-APP-RUNTIME-PHASE-PROGRESS-001
  title: Add app-runtime phase, progress, and member-health reporting primitives for
    distributed workload lifecycle
  role: A-backend
  status: done
  priority: 5
  owner: Codex
  branch: agent/A-backend
  completed_at: '2026-04-10'
  commit: 69bc9c42
  depends_on:
  - A-APP-RUNTIME-MEMBER-INVENTORY-001
  acceptance_checks:
  - make codegen
  - go test ./cmd/api ./packages/services/appruntime
  - bash scripts/ci/agent_queue_validate.sh
  - make queue-git-check
  notes: 'Context:

    Kubernetes and other multi-member apps need more than a single coarse instance
    status. The platform should support explicit phase reporting, progress counters,
    and member- level health so ordered bootstrap, upgrades, and degraded states are
    representable.

    Scope:

    - In: generic app-runtime APIs/contracts for instance phase reporting, progress
    summaries, and member health updates.

    - In: regression coverage for partial progress and degraded-member semantics.

    - Out: workload-specific health logic for Kubernetes or Slurm; only the platform
    primitive belongs here.

    '
- id: A-WORKLOADS-READ-MODEL-SHELL-001
  title: Add workload-first shell read model so navigation can show Active and Needs-attention
    workloads instead of only healthy running instances
  role: B-ui
  status: done
  priority: 5
  owner: Codex
  branch: agent/B-ui
  completed_at: '2026-04-10'
  commit: 69bc9c42
  depends_on:
  - A-APP-RUNTIME-MEMBER-INVENTORY-001
  - A-APP-RUNTIME-PHASE-PROGRESS-001
  acceptance_checks:
  - make codegen
  - pnpm vitest run app
  - pnpm exec tsc --noEmit --pretty false
  - bash scripts/ci/agent_queue_validate.sh
  - make queue-git-check
  notes: 'Context:

    The rewritten navigation design requires the shell to surface workloads as primary
    navigation objects and to keep deploying/degraded/manual-intervention states visible.

    Scope:

    - In: workload summary/read-model API and shell consumption for `Active` and `Needs
    attention` groupings.

    - In: route and data requirements for `/workloads/{instance_id}` as a stable workload
    detail shell.

    - Out: embedded UI tabs themselves; this task only establishes workload-first
    nav and read models.

    '
- id: A-AUDIT-SCOPED-SURFACES-001
  title: Add scoped audit log surfaces for user, project, tenant, and platform contexts
  role: A-backend
  status: done
  priority: 6
  owner: Codex
  branch: agent/A-backend
  completed_at: '2026-04-10'
  commit: b8547632
  depends_on:
  - A-WORKLOADS-READ-MODEL-SHELL-001
  acceptance_checks:
  - make codegen
  - go test ./cmd/api ./packages/services/inventory
  - make verify-web
  - bash scripts/ci/agent_queue_validate.sh
  - make queue-git-check
  notes: 'Context:

    As the shell shifts to workload-first and app-platform product surfaces, audit
    access should no longer exist only as a platform-admin debug page. Users need
    audit visibility appropriate to their scope without exposing platform-global events.

    Required outcome:

    - add API-enforced scoped audit reads for: - personal/user-visible audit - project-admin
    audit - tenant-admin audit - platform-admin global audit - keep `/admin/audit-logs`
    as the platform-global surface - add user-facing and scoped UI entry points later
    without requiring direct SQL or admin escalation for common audit questions -
    ensure logs carry enough tenant/project/user linkage for safe filtering

    Scope:

    - In: scoped audit read model, authz rules, contract updates, and UI surfaces
    - Out: audit event schema rewrite or immutable audit storage changes

    Sequencing:

    - do this after the current Kubernetes first-slice work, not in the middle of
    it

    '
- id: B-APP-PLATFORM-WORKLOAD-SHELL-UX-001
  title: Stabilize the workload detail shell UI with generic Overview, Members, Events,
    Config, and Access tabs before expanding Kubernetes depth
  role: B-ui
  status: done
  priority: 5
  owner: Codex
  branch: agent/B-ui
  completed_at: '2026-04-10'
  commit: 601ade86
  depends_on:
  - A-WORKLOADS-READ-MODEL-SHELL-001
  - A-APP-RUNTIME-MEMBER-INVENTORY-001
  - A-APP-RUNTIME-PHASE-PROGRESS-001
  acceptance_checks:
  - make codegen
  - pnpm --dir packages/web exec tsc --noEmit --pretty false
  - bash scripts/ci/frontend_e2e.sh full
  - bash scripts/ci/agent_queue_validate.sh
  - make queue-git-check
  notes: 'Context:

    The first self-managed RKE2 implementation is intentionally basic, but the current
    app-instance detail surfaces are still too bespoke. Before adding more Kubernetes
    depth, the UI should expose the generic workload shell contract used by RKE2,
    Slurm, and future app/execution-engine profiles.

    Required outcome:

    - workload detail uses stable generic tabs: - Overview - Members - Events - Config
    - Access - lifecycle phase/progress and recent activity are visible without relying
    on direct DB inspection or pod logs - member inventory is readable for distributed
    workloads such as RKE2 server and agent members - Access can host kubeconfig/endpoints
    for RKE2 without embedding a cluster UI - the shell preserves native-only, embedded,
    and link-out app UI modes from the embedded UI gateway contract

    Scope:

    - In: workload shell UI layout, generic app-instance detail surfaces, and e2e
    coverage for attention/active workload visibility - Out: implementing Rancher,
    managed Kubernetes, dstack, Helm execution, or arbitrary app-specific dashboards

    Sequencing:

    - do this before expanding Kubernetes beyond the current self-managed RKE2 validation
    slice

    '
- id: A-EMBEDDED-UI-GATEWAY-CONTRACT-001
  title: Define embedded app UI gateway contract for reverse proxy, auth, cookies,
    WebSockets, and fallback-to-link-out behavior
  role: A-backend
  status: done
  priority: 5
  owner: Codex
  branch: agent/A-backend
  completed_at: '2026-04-10'
  commit: 71cfa510
  depends_on: []
  acceptance_checks:
  - rg -q "Embedded UI Gateway" doc/architecture
  - bash scripts/ci/agent_queue_validate.sh
  - make queue-git-check
  notes: 'Context:

    Kubernetes and Slurm product designs both now depend on a platform-owned embedded
    UI contract. Without it, Rancher, Grafana, and Open OnDemand remain speculative
    or unsafe to embed.

    Scope:

    - In: architecture/spec coverage for reverse-proxy route shape, auth strategies,
    cookie and session ownership, WebSocket upgrades, CSP/frame policy, logout/session
    expiry propagation, and the explicit criteria for link-out fallback.

    - In: clear ownership boundary between the app manifest capability declaration
    and the platform decision to enable embedding.

    - Out: implementation of the gateway itself; this task is the design/spec baseline.

    '
- id: A-APP-RUNTIME-RECOVERY-MODEL-001
  title: Define app-runtime recovery, intervention, and repair semantics for distributed
    workloads before Kubernetes lifecycle work starts
  role: A-backend
  status: done
  priority: 5
  owner: Codex
  branch: agent/A-backend
  completed_at: '2026-04-10'
  commit: 71cfa510
  depends_on:
  - A-APP-RUNTIME-MEMBER-INVENTORY-001
  - A-APP-RUNTIME-PHASE-PROGRESS-001
  acceptance_checks:
  - rg -q "distributed workload" doc/architecture
  - bash scripts/ci/agent_queue_validate.sh
  - make queue-git-check
  notes: 'Context:

    The platform already has partial recovery gaps in onboarding and app-runtime flows.
    Kubernetes will amplify those weaknesses because multi-member bootstrap and repair
    are normal, not exceptional.

    Scope:

    - In: explicit runtime semantics for retry, intervention-required, reconcile,
    repair, and operator-visible recovery actions for distributed workloads.

    - In: clarify what belongs to generic runtime state versus workload-specific logic.

    - Out: the Kubernetes implementation itself; this is the prerequisite recovery
    model.

    '
- id: A-K8S-RKE2-FIRST-SLICE-DESIGN-001
  title: Define the first self-managed RKE2 product slice with placement, member topology,
    bootstrap ordering, and kubeconfig delivery boundaries
  role: A-backend
  status: done
  priority: 5
  owner: Codex
  branch: agent/A-backend
  completed_at: '2026-04-10'
  commit: 19dc8829
  depends_on:
  - A-APP-RUNTIME-MEMBER-INVENTORY-001
  - A-APP-RUNTIME-PHASE-PROGRESS-001
  - A-APP-RUNTIME-RECOVERY-MODEL-001
  acceptance_checks:
  - rg -q "Self-Managed RKE2 First Slice" doc/architecture
  - bash scripts/ci/agent_queue_validate.sh
  - make queue-git-check
  notes: 'Context:

    The Kubernetes platform direction is chosen, but implementation will sprawl if
    the first slice remains described only as "self-managed RKE2". The platform needs
    a narrower product and runtime definition that keeps this validation slice inside
    existing control boundaries.

    Scope:

    - In: first-slice product statement, placement schema direction, runtime member
    roles, ordered bootstrap, kubeconfig delivery boundary, and workload-shell expectations.

    - Out: Rancher, HA managed Kubernetes, and full day-2 operations.

    '
- id: A-K8S-RKE2-CATALOG-PLACEMENT-001
  title: Add self-managed RKE2 catalog and placement contract so app instances can
    declare server and agent allocations explicitly
  role: A-backend
  status: done
  priority: 5
  owner: Codex
  branch: agent/A-backend
  completed_at: '2026-04-10'
  commit: e0cfe60
  depends_on:
  - A-K8S-RKE2-FIRST-SLICE-DESIGN-001
  acceptance_checks:
  - make codegen
  - go test ./cmd/api ./packages/services/inventory
  - bash scripts/ci/agent_queue_validate.sh
  - make queue-git-check
  notes: 'Context:

    The first self-managed RKE2 slice needs an explicit placement contract, not an
    overloaded free-form config blob. The platform should validate one required server
    allocation and optional agent allocations before bootstrap begins.

    Scope:

    - In: OpenAPI/catalog metadata and service validation for the RKE2 placement contract.

    - Out: actual bootstrap execution.

    '
- id: A-K8S-RKE2-BOOTSTRAP-ADAPTER-001
  title: Implement self-managed RKE2 app-runtime adapter path for ordered server bootstrap
    and agent joins through platform-owned execution
  role: A-backend
  status: done
  priority: 5
  owner: Codex
  branch: agent/A-backend
  completed_at: '2026-04-10'
  commit: 3dfd8073
  depends_on:
  - A-K8S-RKE2-CATALOG-PLACEMENT-001
  acceptance_checks:
  - go test ./packages/services/appruntime ./cmd/api
  - bash scripts/ci/agent_queue_validate.sh
  - make queue-git-check
  notes: 'Context:

    The first Kubernetes implementation should validate ordered distributed bootstrap
    through the existing platform runtime model. That means one server member first,
    then agent joins, with visible member and phase reporting.

    Scope:

    - In: app-runtime adapter logic, member operations, ordered bootstrap semantics,
    and progress reporting.

    - Out: managed Kubernetes and Rancher.

    '
- id: A-K8S-RKE2-KUBECONFIG-ACCESS-001
  title: Add workload access delivery for self-managed RKE2 so users can retrieve
    kubeconfig from the workload shell
  role: B-ui
  status: done
  priority: 5
  owner: Codex
  branch: agent/B-ui
  completed_at: '2026-04-10'
  commit: ee0f47d
  depends_on:
  - A-K8S-RKE2-BOOTSTRAP-ADAPTER-001
  - A-WORKLOADS-READ-MODEL-SHELL-001
  acceptance_checks:
  - make codegen
  - pnpm vitest run app
  - pnpm exec tsc --noEmit --pretty false
  - bash scripts/ci/agent_queue_validate.sh
  - make queue-git-check
  notes: 'Context:

    The first self-managed cluster slice is not usable unless the workload shell can
    expose kubeconfig and endpoint information without forcing operators to SSH into
    the server node manually.

    Scope:

    - In: access/read-model and workload-shell delivery for kubeconfig and cluster
    endpoint details.

    - Out: embedded dashboards.

    '
- id: A-PLATFORM-RELEASE-DOWNLOAD-API-001
  title: Add control-plane platform release catalog and download APIs so developer
    downloads and future CLI flows use real release metadata instead of placeholders
  role: A-backend
  status: done
  priority: 925
  owner: A
  branch: agent/A-backend
  completed_at: '2026-03-11'
  commit: 135d2ea
  depends_on:
  - A-CLI-SDK-OCI-RELEASE-FLOW-001
  acceptance_checks:
  - make codegen
  - go test ./cmd/api ./packages/services/releases
  - make queue-git-check
  notes: 'Context:


    The current developer downloads UI is placeholder-backed: it renders hardcoded
    artifact cards and env-derived `oras pull` snippets, but there is no control-plane
    API that exposes platform release manifests or downloadable developer artifacts.
    The release build/publish scripts already produce OCI artifacts and metadata;
    the missing layer is runtime API ownership.


    Required backend direction:


    - add platform release catalog/discovery endpoints for version + artifact metadata

    - add convenience download endpoints for small developer-facing platform artifacts
    (`cli`, `go-sdk`, `python-sdk`)

    - use the same release metadata model for future `ops releases list|get|download`
    CLI commands

    - do not make the public downloads UX depend on frontend env vars or hardcoded
    registry paths


    Scope:


    - In: OpenAPI contract, backend release read-model, download proxy for small platform
    artifacts

    - Out: release publishing pipeline changes, generalized pull-intent APIs, large
    app-artifact byte proxying through `cmd/api`

    '
- id: A-ARTIFACT-PULL-INTENT-API-001
  title: Add pull-intent APIs for platform release and project app artifact registry-native
    pulls
  role: A-backend
  status: done
  priority: 924
  owner: A
  branch: agent/A-backend
  completed_at: '2026-04-28'
  commit: 5f9802e4
  depends_on:
  - A-PLATFORM-RELEASE-DOWNLOAD-API-001
  acceptance_checks:
  - bash scripts/ci/contracts_validate.sh
  - go test ./cmd/api ./packages/services/inventory ./packages/services/releases
  - make queue-git-check
  notes: 'Context:


    Platform release catalog/discovery and control-plane download endpoints are now
    implemented, but the foundational pull-intent primitive is still missing. Registry-native
    pulls for app artifacts, CI, and future power-user release flows need an authenticated,
    short-lived credential issuance path owned by the control plane.


    Required backend direction:


    - add pull-intent endpoints for platform release artifacts

    - add pull-intent endpoints for project app artifacts

    - return canonical repository/ref/digest metadata plus wrapped short-lived credentials

    - keep large artifact bytes on the registry path rather than proxying them through
    `cmd/api`


    Scope:


    - In: OpenAPI contract, Vault-backed credential delivery, release/app artifact
    pull-intent handlers and service logic

    - Out: release publishing pipeline changes, public downloads page UX changes

    '
- id: A-LIFECYCLE-CLEANUP-AS-TEST-CONTRACT-001
  title: Make cleanup and teardown a required success condition for lifecycle-bearing
    automated tests
  role: A-backend
  status: todo
  priority: 924
  owner: ''
  branch: ''
  completed_at: ''
  commit: ''
  depends_on:
  - A-TEST-LIFECYCLE-CLEANUP-001
  acceptance_checks:
  - bash scripts/ci/agent_queue_validate.sh
  - make queue-git-check
  notes: 'Context:


    Disposable scope helpers now exist, but cleanup is not yet a universal test contract.
    Lifecycle-bearing tests still risk leaving allocations, nodes, app instances,
    artifacts, and related state behind unless the caller remembers to clean up.


    Requirements:


    - teardown/cleanup must be part of the success criteria for lifecycle-bearing
    tests

    - tests should fail when cleanup fails

    - extend the reusable cleanup pattern beyond artifact checks to allocation, node,
    and app-instance validation flows

    - document cleanup failure as a lifecycle defect, not leftover test noise


    Scope:


    - In: shared cleanup contract/helpers and test harness behavior for lifecycle-bearing
    automation

    - Out: unrelated unit tests that do not create real resources

    '
- id: C-LIFECYCLE-TEST-CLEANUP-POLICY-001
  title: Document cleanup as part of lifecycle test policy for remote validation and
    manual QA
  role: C-ops
  status: todo
  priority: 923
  owner: ''
  branch: ''
  completed_at: ''
  commit: ''
  depends_on:
  - A-LIFECYCLE-CLEANUP-AS-TEST-CONTRACT-001
  - B-QA-TEST-SESSION-GUIDE-001
  acceptance_checks:
  - make queue-git-check
  notes: 'Context:


    The team repeatedly found lifecycle bugs only after shared test resources accumulated.
    The operational/testing policy now needs to state explicitly that cleanup is part
    of a successful test run.


    Requirements:


    - remote validation docs must treat teardown as part of pass/fail criteria

    - manual QA guidance must call out cleanup failures as lifecycle defects

    - runbook/test guidance should make it clear when disposable scope is required


    Scope:


    - In: governance/ops guidance updates

    - Out: backend helper implementation

    '
- id: A-QUEUE-SQLITE-SOURCE-OF-TRUTH-001
  title: Move mutable queue graph data to SQLite while keeping stable task intent
    text in files
  role: A-backend
  status: todo
  priority: 922
  owner: ''
  branch: agent/A-backend
  completed_at: ''
  commit: ''
  depends_on: []
  acceptance_checks:
  - make queue-git-check
  notes: 'Context:


    The active queue YAML keeps failing under scale: syntax fragility, large merge
    surfaces, and cross-task dependency edits are now recurring operational problems.
    The task graph data is mutable and structured, while much of the prose is stable
    briefing text keyed by task id.


    Requirements:


    - move mutable task graph fields to a structured SQLite source of truth

    - preserve task ids as the stable join key

    - keep stable task instructions/notes in file-backed sidecars or equivalent human-reviewable
    text

    - support dependency validation across the full task graph

    - generate human-readable active/archive exports as needed


    Scope:


    - In: SQLite schema/tooling for task rows and dependencies, plus export/validation
    strategy

    - Out: full replacement of all human-readable queue docs in the same task

    '
- id: C-QUEUE-ACTIVE-ARCHIVE-001
  title: Keep active queue YAML limited to actionable items and archive done history
  role: C-ops
  status: todo
  priority: 921
  owner: ''
  branch: agent/C-ops
  completed_at: ''
  commit: ''
  depends_on: []
  acceptance_checks:
  - make queue-git-check
  notes: 'Context:


    Until the queue graph moves to a structured store, the practical way to reduce
    breakage is to keep the live YAML small. Done items should be preserved in archive
    snapshots, not left to accumulate indefinitely in the active execution file.


    Requirements:


    - define and execute an archive sweep for completed queue items

    - keep the active queue focused on `todo`, `in_progress`, and `blocked` work

    - preserve completion metadata in archive files

    - update governance docs so this stays an operating rule rather than a one-off
    cleanup


    Scope:


    - In: active/archive queue hygiene policy and archive execution plan

    - Out: the SQLite queue-system refactor itself

    '
- id: A-PLATFORM-OCI-RELEASE-ARTIFACTS-001
  title: Publish platform-controlled release artifacts to OCI registries for local-dev
    and platform-control
  role: A-backend
  status: done
  priority: 993
  owner: Codex
  branch: agent/A-backend
  completed_at: '2026-03-10'
  commit: 36580b1
  depends_on:
  - A-NODE-AGENT-OCI-BOOTSTRAP-001
  - A-VAULT-PLATFORM-SECRETS-IMPLEMENTATION-001
  acceptance_checks:
  - bash scripts/release/build_platform_release_artifacts.sh
  - bash scripts/release/publish_platform_release_artifacts.sh
  - make queue-git-check
  notes: 'Context:

    Node-agent bootstrap metadata was available, but the actual release artifacts
    were still distributed out-of-band. This task publishes platform-owned OCI release
    artifacts for node-agent bootstrap, node-agent, CLI, Go SDK, and Python SDK into
    both local-dev and platform-control registries so the bootstrap and developer
    flows use the same distribution model.

    '
- id: A-CLI-SDK-OCI-RELEASE-FLOW-001
  title: Publish CLI, Go SDK, and Python SDK through the same OCI release flow as
    node-agent artifacts
  role: A-backend
  status: done
  priority: 992
  owner: Codex
  branch: agent/A-backend
  completed_at: '2026-03-10'
  commit: 36580b1
  depends_on:
  - A-PLATFORM-OCI-RELEASE-ARTIFACTS-001
  acceptance_checks:
  - bash scripts/release/build_platform_release_artifacts.sh
  - bash scripts/release/publish_platform_release_artifacts.sh
  - make queue-git-check
  notes: 'Context:

    The Go SDK is the basis for the CLI, and all developer-facing release artifacts
    should follow the same supply-chain path. This task extends the OCI release flow
    to the CLI, Go SDK, and Python SDK so app developers can consume them from the
    platform registries instead of ad hoc distribution.

    '
- id: A-NODE-AGENT-TERMINAL-SPLIT-REVIEW-001
  title: Review node-agent split seam between lifecycle tasks and interactive terminal
    relay
  role: A-backend
  status: done
  priority: 999
  depends_on: []
  acceptance_checks:
  - make queue-git-check
  notes: Design review only. Revisit doc/architecture/Node_Operations_and_Agent_Lifecycle_v1.md,
    document lifecycle-vs-terminal seam, and seed follow-ons only if concrete execution
    work is exposed.
  owner: agent-a
  branch: agent/A-backend
  completed_at: '2026-03-09'
  commit: 7c166cc
- id: A-NODE-AGENT-DELIVERY-AND-BOOTSTRAP-001
  title: Make node bootstrap authoritative from the control plane and remove browser-derived
    onboarding assembly
  role: A-backend
  status: done
  priority: 998
  owner: agent-a
  branch: agent/A-backend
  completed_at: '2026-03-10'
  commit: ecd50cf
  depends_on:
  - A-NODE-AGENT-TERMINAL-SPLIT-REVIEW-001
  acceptance_checks:
  - make codegen
  - go test ./cmd/api
  - pnpm --dir packages/web test app/admin/nodes/page.lifecycle.test.tsx
  - make queue-git-check
  notes: 'Context:

    Node onboarding was still assembled in the admin UI from frontend env and stale
    operator assumptions. This task makes the enrollment-token response return the
    authoritative bootstrap bundle so operators and future CLI/bootstrap tooling consume
    the same control-plane output.

    Scope:

    - In: API bootstrap bundle contract, admin nodes page consumption, local-dev/platform_control
    config wiring, onboarding runbook alignment.

    - Out: binary delivery automation and live remote terminal smoke.

    '
- id: A-NODE-AGENT-REMOTE-TERMINAL-SMOKE-001
  title: Add a real remote terminal smoke for browser to gateway to API to node-agent
    to PTY path
  role: A-backend
  status: done
  priority: 997
  owner: agent-a
  branch: agent/A-backend
  completed_at: '2026-03-10'
  commit: 8ab23e8
  depends_on:
  - A-NODE-AGENT-DELIVERY-AND-BOOTSTRAP-001
  acceptance_checks:
  - bash scripts/ops/terminal_remote_smoke.sh
  - make queue-git-check
  notes: 'Context:

    The deployed websocket host regression was caught only after adding runtime bundle
    validation, but the deeper node-agent stream path is still not covered by an automated
    remote smoke. This task should validate browser -> terminal-gateway -> API internal
    stream -> node-agent -> PTY against a live active allocation.

    '
- id: A-NODE-AGENT-OCI-BOOTSTRAP-001
  title: Deliver node-agent bootstrap as a digest-pinned OCI package with control-plane-issued
    pull instructions
  role: A-backend
  status: done
  priority: 996
  owner: Codex
  branch: agent/A-backend
  completed_at: '2026-03-10'
  commit: ec67382
  depends_on:
  - A-NODE-AGENT-DELIVERY-AND-BOOTSTRAP-001
  - A-NODE-AGENT-REMOTE-TERMINAL-SMOKE-001
  acceptance_checks:
  - bash scripts/ci/contracts_validate.sh
  - make queue-git-check
  notes: 'Context:

    Node onboarding no longer invents bootstrap values in the browser, but binary/package
    delivery is still manual. The next step is to publish a node bootstrap package
    as an OCI artifact and return that package reference plus pull instructions from
    the control plane.


    Scope:

    - In: OCI bootstrap package contract, bootstrap package reference in onboarding,
    digest-pinned artifact reference, and short-lived pull-instruction delivery.

    - Out: full runtime adapter behavior.

    '
- id: A-NODE-AGENT-RELEASE-UPDATE-PATH-001
  title: Implement secure node-agent release/update path around rebootstrap, manual
    install, and reimage
  role: A-backend
  status: todo
  priority: 995
  owner: Codex
  branch: agent/A-backend
  completed_at: ''
  commit: ''
  depends_on:
  - A-NODE-AGENT-OCI-BOOTSTRAP-001
  - A-NODE-AGENT-RUNTIME-OPERATOR-PRIMITIVES-001
  acceptance_checks:
  - go test ./cmd/node-agent ./packages/services/maas
  - go test -tags integration ./packages/services/maas -run 'Test(ExecuteDecommissionReimageIntegration|ExecuteDecommissionWaitNodeEnrollmentRejectsCertRenewOnlyTransition)$'
  - make queue-git-check
  notes: 'Context:

    This task was marked done too early. Live MAAS reruns on 2026-03-18 showed that
    node `1429d5d0-7877-4cca-a44b-e4782261f5dc` (`c07u31`) was repeatedly reimaged
    with stale bootstrap content because platform-control was still advertising old
    `NODE_BOOTSTRAP_PACKAGE_TAG` metadata, and the installed node-agent binary on
    the node remained at `5b82c78` even after a fresh MAAS deploy.

    After the release pipeline was corrected and `NODE_BOOTSTRAP_PACKAGE_TAG` moved
    forward, the node finally reimaged onto newer builds (`0081f66`, later `0c7cea7`),
    which proved the current delivery path still depends on MAAS redeploy timing and
    release-config propagation rather than a first-class live node-agent update model.

    2026-05-03 status: the non-reimage `rebootstrap` path is now implemented for
    healthy enrolled nodes through `node.self_update`; the provisioning worker builds
    a digest-pinned bootstrap package plan, enqueues a signed task, and waits for the
    node-agent task result. The node-agent finalizer validates `package_sha256`, carries
    the configured container runtime package into `install-node-agent.sh`, and writes
    installer output to `/var/log/gpuaas-node-agent-self-update.log` when possible.
    Remaining work in this task is broader release/update hardening across manual
    install and reimage modes, plus fleet-level version conformance after deploy.

    The same live run also showed installer/runtime noise that still needs hardening:
    - `install-node-agent.sh` does `systemctl enable --now` and then `systemctl restart`,
    causing a first start to be cancelled immediately with `node enrollment attempt
    failed ... context canceled` - the node-agent then enrolls and immediately renews
    its certificate because `GPUAAS_CERT_RENEW_BEFORE_SECONDS` defaults to 24h, which
    matches the issued cert TTL closely enough to trigger immediate renewal on first
    boot

    The real missing capability is therefore broader than SCP replacement: the platform
    still lacks a reliable, observable, and non-reimage-only update path for already-enrolled
    nodes, and the install/runtime handoff is noisier than it should be. A short-lived
    SSH detour was explored during this incident and then removed; the intended product
    direction is explicitly non-SSH.


    Scope:

    - In: make the execution modes explicit instead of assuming every node-agent lifecycle
    action is a reimage: `reimage`, `manual_install`, and `rebootstrap`.

    - In: verified bootstrap artifact/version propagation from release metadata into
    live node bootstrap package selection, explicit validation against the node''s
    observed version, and a safe runtime handoff that does not self-cancel on first
    install.

    - In: release/update path design and implementation that can handle manual install,
    rebootstrap, and reimage without requiring SSH as the long-term product model.

    - Out: reintroducing ad hoc SCP/SSH as the supported update path.

    '
- id: A-NODE-BOOTSTRAP-DNS-PREP-CONTRACT-001
  title: Separate environment DNS and hosts preparation from node bootstrap and cloud-init
    rendering
  role: A-backend
  status: todo
  priority: 994
  owner: ''
  branch: agent/A-backend
  completed_at: ''
  commit: ''
  depends_on:
  - A-NODE-AGENT-DELIVERY-AND-BOOTSTRAP-001
  - A-PLATFORM-DNS-CERT-ENDPOINT-001
  acceptance_checks:
  - rg -q "DNS|hosts|bootstrap|cloud-init" doc/architecture/Node_Bootstrap_Script_and_Token_v1.md
  - bash scripts/ci/agent_queue_validate.sh
  - make queue-git-check
  notes: 'Context:

    The current brokered bootstrap script still mutates `/etc/hosts` as part of node-agent
    bootstrap, and the same coupling is inherited by the cloud-init rendering path.
    That mixes environment preparation with GPUaaS bootstrap and makes local/manual
    VM onboarding look like one opaque step when it is really two concerns: name-resolution/connectivity
    prep and node-agent install/enroll.

    Requirements:

    - define the supported contract for environments where public/stable DNS is already
    correct vs environments that require explicit hostname-resolution prep

    - make `/etc/hosts` manipulation, if supported at all, an explicit optional prep
    layer rather than an implicit bootstrap side effect

    - define how cloud-init composes an optional environment-prep stage with the GPUaaS
    bootstrap stage, including a switch that can be enabled or disabled based on DNS
    policy

    - keep operator-visible output clear enough that manual flows can inspect, modify,
    or skip host-manipulation steps without patching the bootstrap payload itself

    Scope:

    - In: bootstrap/env-prep contract design, rendering boundary definition for manual
    and cloud-init modes, and operator workflow/readme expectations

    - Out: immediate implementation of the split or automatic `/etc/hosts` editing
    behavior changes in the same slice

    '
- id: A-NODE-AGENT-TERMINAL-ERROR-PROPAGATION-001
  title: Propagate node-agent terminal startup failures to control-plane logs and
    UI
  role: A-backend
  status: todo
  priority: 996
  owner: Codex
  branch: agent/A-backend
  completed_at: ''
  commit: ''
  depends_on: []
  acceptance_checks:
  - go test ./cmd/node-agent ./packages/services/terminal ./cmd/api
  - make queue-git-check
  notes: 'Context:

    Live allocation/terminal testing on 2026-03-18 for allocation `7fa81cc4-a0c5-43d7-bd2b-6064fd4c66f8`
    on node `1429d5d0-7877-4cca-a44b-e4782261f5dc` showed the control plane accepted
    terminal setup while the browser remained stuck on `Connecting...`. Central control-plane
    evidence showed:

    - terminal gateway accepted the websocket - session binding was created - `terminal.open`
    completed successfully

    The actual root cause was only visible by SSHing to the node and reading `journalctl`:

    - node-agent logged `terminal stream connected` - then immediately logged `terminal
    session ended with error` - exact error: `lookup terminal user: user: unknown
    user u_adda9308def04a2f`

    This exposed two observability gaps: - terminal startup failure on the node was
    not propagated back to the control plane as a structured failure reason - the
    UI treated websocket connection as effectively "connected" even though the shell
    never became usable

    The node-agent logging slice added on 2026-03-18 improved task-level visibility,
    but terminal startup failure propagation still needs an explicit end-to-end fix.


    Scope:

    - In: propagate terminal startup failures from node-agent back through the terminal/control-plane
    path with structured reason codes and correlation/session context, and make those
    failures visible in control-plane logs so SSH-to-node is not required for first
    diagnosis.

    - In: preserve safe redaction while logging enough context for `allocation_id`,
    `session_id`, `node_id`, and the failing runtime user.

    - Out: broader terminal UI redesign beyond surfacing the true startup failure
    state.

    '
- id: A-NODE-AGENT-RETRY-LOG-THROTTLING-001
  title: Throttle and coalesce repeated node-agent connectivity retry logs
  role: A-backend
  status: todo
  priority: 995
  owner: ''
  branch: agent/A-backend
  completed_at: ''
  commit: ''
  depends_on: []
  acceptance_checks:
  - go test ./cmd/node-agent
  - make queue-git-check
  notes: 'Context:

    Local parity bootstrap validation on 2026-03-26 showed that a misconfigured runtime
    control-plane URL caused the node-agent to emit repeated warning lines on every
    failed enroll and task-poll retry. The resulting journal growth on the VM was
    large enough that `journalctl --vacuum-time=1d` freed about 1.7G of archived logs.

    This is an owning-layer issue in node-agent retry/error logging, not just an operator
    cleanup concern.


    Scope:

    - In: keep first failure visible, coalesce repeated identical connectivity errors,
    emit periodic summarized warnings during sustained failure, and emit explicit
    recovery logs when connectivity resumes.

    - In: cover enrollment retry and task-poll retry loops.

    - Out: redesign of retry backoff policy, journald retention policy, or broader
    observability changes outside node-agent retry logging.

    '
- id: A-VAULT-PLATFORM-SECRETS-IMPLEMENTATION-001
  title: Implement Vault-backed secret delivery for platform runtime and app artifact
    flows
  role: A-backend
  status: done
  priority: 925
  owner: agent-a
  branch: agent/A-backend
  completed_at: '2026-03-10'
  commit: 36580b1
  depends_on:
  - A-VAULT-PLATFORM-SECRETS-001
  - A-APP-OCI-REGISTRY-IMPLEMENTATION-001
  acceptance_checks:
  - bash scripts/ci/contracts_validate.sh
  - make queue-git-check
  notes: 'Context:

    The registry is now real on `platform_control`, and this slice implements the
    first Vault-backed runtime secret delivery path for artifact publication.


    Scope:

    - In: running Vault baseline, registry credential custody, wrapped credential
    delivery for OCI publish intents, and live remote validation.

    - Out: full production HA Vault topology.

    '
- id: A-APP-NON-OCI-BLOB-BACKEND-001
  title: Implement non-OCI blob artifact backend and delivery path
  role: A-backend
  status: done
  priority: 923
  owner: agent-a
  branch: agent/A-backend
  completed_at: '2026-03-10'
  commit: 36580b1
  depends_on:
  - A-APP-NON-OCI-ARTIFACT-LIFECYCLE-001
  - A-VAULT-PLATFORM-SECRETS-IMPLEMENTATION-001
  acceptance_checks:
  - bash scripts/ci/contracts_validate.sh
  - make test-integration-selected
  - make queue-git-check
  notes: 'Context:

    Blob/object artifact support is now modeled and this slice implements the first
    real backend using project storage plus upload intents and registration/verification
    checks.


    Scope:

    - In: real blob upload intent, artifact-store registration linkage, storage metadata
    persistence, and runtime resolution baseline.

    - Out: every possible third-party storage backend in one slice.

    '
- id: A-APP-OCI-REGISTRY-BASELINE-001
  title: Define and implement platform OCI registry baseline for app-runtime artifacts
  role: A-backend
  status: done
  priority: 930
  owner: agent-a
  branch: agent/A-backend
  completed_at: '2026-03-09'
  commit: 2d2816d
  depends_on: []
  acceptance_checks:
  - bash scripts/ci/contracts_validate.sh
  - make queue-git-check
  notes: 'Context:


    The app-platform quickstart and gap tracker now make the missing artifact path
    explicit: app teams need a first-class platform OCI registry instead of hidden
    per-app artifact handling.


    Pre-read (required):


    - doc/architecture/App_Platform_Quickstart_v1.md

    - doc/architecture/App_Platform_Gap_Tracker_v1.md

    - doc/architecture/Node_Operations_and_Agent_Lifecycle_v1.md

    - doc/architecture/App_Control_Plane_v1.md


    Invariants (must not break):


    - digest-pinned artifact model only.

    - do not hardcode a single global registry forever; reserve tenant/project extension
    path.

    - do not bypass policy allowlists or audit model.


    Scope:


    - In: platform-owned OCI registry model, API/contract direction, lifecycle baseline
    for publish/promote/deprecate/retire.

    - Out: full non-OCI artifact implementation.

    '
- id: A-VAULT-PLATFORM-SECRETS-001
  title: Define Vault-backed secrets baseline for registry, signing, and app operator
    credentials
  role: A-backend
  status: done
  priority: 931
  owner: agent-a
  branch: agent/A-backend
  completed_at: '2026-03-09'
  commit: aa53555
  depends_on:
  - A-APP-OCI-REGISTRY-BASELINE-001
  acceptance_checks:
  - bash scripts/ci/contracts_validate.sh
  - make queue-git-check
  notes: 'Context:


    Registry and artifact trust require a real secret-custody model. The current platform
    needs a Vault-first baseline for runtime and operator credentials before app teams
    build around host-local secrets.


    Pre-read (required):


    - doc/architecture/App_Platform_Gap_Tracker_v1.md

    - doc/architecture/Service_Account_Model.md

    - doc/operations/Control_Plane_K8s_Migration_v1.md


    Invariants (must not break):


    - no long-lived bearer secrets in app configs.

    - clear separation between CI secrets, runtime secrets, and operator credentials.

    - preserve future KMS evolution path.


    Scope:


    - In: Vault baseline, secret classes, delivery model, control-plane integration
    direction.

    - Out: full production hardening for every secret path.

    '
- id: A-NODE-BOOTSTRAP-TRUST-DELIVERY-001
  title: Define automated bootstrap trust delivery for node-agent control-plane HTTPS
  role: A-backend
  status: done
  priority: 934
  owner: agent-a
  branch: agent/A-backend
  completed_at: '2026-03-09'
  commit: 6c5f0d8
  depends_on:
  - A-VAULT-PLATFORM-SECRETS-001
  - A-PLATFORM-DNS-CERT-ENDPOINT-001
  acceptance_checks:
  - bash scripts/ci/contracts_validate.sh
  - make queue-git-check
  notes: 'Context:


    Real node onboarding on platform_control required manual CA copy to establish
    HTTPS trust. That is acceptable for a bootstrap test, but not as a platform baseline.


    Pre-read (required):


    - doc/architecture/PKI_Spec.md

    - doc/architecture/Node_Agent_Spec.md

    - doc/architecture/Platform_Signing_and_Bootstrap_Trust_v1.md


    Invariants (must not break):


    - node agents still talk only to platform-controlled endpoints.

    - public HTTPS trust and node-cert lifecycle trust remain distinct.

    - trust updates must be auditable and reversible.


    Scope:


    - In: bootstrap trust bundle model, delivery/update direction, CA rotation handling.

    - Out: full implementation of every provider-specific bootstrap path.

    '
- id: A-PLATFORM-DNS-CERT-ENDPOINT-001
  title: Define DNS, cert-manager, and stable platform control endpoint model
  role: A-backend
  status: done
  priority: 932
  owner: agent-a
  branch: agent/A-backend
  completed_at: '2026-03-09'
  commit: 068bb54
  depends_on:
  - A-CONTROL-PLANE-K8S-CD-001
  acceptance_checks:
  - bash scripts/ci/agent_queue_validate.sh
  - make queue-git-check
  notes: 'Context:


    The control plane now runs behind ingress and TLS, but environment creation must
    not depend on one node IP or ad hoc cert handling forever.


    Pre-read (required):


    - doc/operations/Control_Plane_K8s_Migration_v1.md

    - doc/architecture/App_Platform_Gap_Tracker_v1.md


    Invariants (must not break):


    - environment creation must remain config-driven.

    - adding platform_control-2 later must not require deployment-logic rewrites.

    - public endpoints must stay stable for CI and app teams.


    Scope:


    - In: stable endpoint model, DNS plan, cert-manager direction, LB/ingress follow-on
    design.

    - Out: immediate HA rollout across multiple control nodes.

    '
- id: A-APP-NON-OCI-ARTIFACT-LIFECYCLE-001
  title: Define non-OCI artifact lifecycle baseline for app-platform workloads
  role: A-backend
  status: done
  priority: 936
  owner: agent-a
  branch: agent/A-backend
  completed_at: '2026-03-09'
  commit: 64849e3
  depends_on:
  - A-APP-OCI-REGISTRY-BASELINE-001
  - A-VAULT-PLATFORM-SECRETS-001
  acceptance_checks:
  - bash scripts/ci/contracts_validate.sh
  - make queue-git-check
  notes: 'Context:


    OCI is not enough for many ML and scheduler-adjacent workloads. The platform already
    reserves blob-style artifact pulls in node operations, but app teams do not yet
    have a productized end-to-end non-OCI path.


    Pre-read (required):


    - doc/architecture/Node_Operations_and_Agent_Lifecycle_v1.md

    - doc/architecture/App_Platform_Gap_Tracker_v1.md

    - doc/architecture/App_Platform_OCI_Registry_Baseline_v1.md


    Invariants (must not break):


    - digest verification remains mandatory.

    - source allowlists and credential scoping remain policy-governed.

    - non-OCI support must not fork the IAM or audit model.


    Scope:


    - In: canonical blob-source model, lifecycle baseline, credential direction, verification
    rules.

    - Out: full runtime implementation across every provider.

    '
- id: A-TENANT-IMPL-001
  title: Implement tenant/project ownership enforcement in API/service authz paths
  role: A-backend
  status: done
  priority: 29
  owner: agent-a
  branch: agent/A-backend
  completed_at: '2026-03-02'
  commit: 63a1b0e
  depends_on:
  - A-CLEAN-001
  acceptance_checks:
  - go test ./cmd/api ./packages/services/auth ./packages/services/admin ./packages/services/storage
  - make test-integration-selected
  - rg -q "tenant_memberships" packages/services
  - rg -q "project_memberships" packages/services
  notes: Replace user-owned access checks with tenant/project membership checks for
    project-scoped endpoints; enforce missing project context as invalid_request (400)
    per baseline.
- id: A-CONTROL-PLANE-K8S-CD-001
  title: Nightly build and deploy automation for dev-control-1 Kubernetes
  role: A-backend
  status: done
  priority: 932
  owner: agent-a
  branch: agent/A-backend
  completed_at: '2026-03-08'
  commit: e3e5e15
  depends_on:
  - A-CONTROL-PLANE-K8S-BASELINE-001
  - A-CI-BASE-IMAGE-001
  acceptance_checks:
  - rg -q "nightly|digest|rollback|publish" doc/operations/Control_Plane_K8s_Migration_v1.md
  - make queue-git-check
  notes: 'Context:

    The move to Kubernetes is also a CD lifecycle change. The lab should gain nightly
    build/deploy automation and a reproducible rollback path instead of relying on
    manual deployment steps.


    Pre-read (required):

    - doc/operations/Control_Plane_K8s_Migration_v1.md

    - build/ci-image/README.md

    - .gitlab-ci.yml


    Invariants (must not break):

    - Build/publish/deploy steps remain traceable to immutable image digests.

    - Nightly automation must not blur host-role boundaries.

    - Rollback must remain explicit and reproducible.


    Scope:

    - In: nightly build/publish/deploy baseline for dev-control-1 Kubernetes.

    - Out: full production promotion pipeline.


    Deliverables:

    - CD/nightly deployment model.

    - registry/image/digest deployment evidence path.

    - rollback and smoke validation baseline.


    Evidence required in handoff:

    - files changed

    - commit SHA

    - exact acceptance commands run

    - pass/fail status by command

    '
- id: A-CLEAN-001
  title: Cleanup sprint - backend single-path enforcement and legacy removal
  role: A-backend
  status: done
  priority: 17
  owner: agent-a
  branch: agent/A-backend
  completed_at: '2026-02-28'
  commit: 14cc349
  depends_on:
  - A-SSH-003
  - B-TERM-002
  - C-SSH-001
  - A-PROV-REMOVE-SSH
  - A-TERM-STREAM-COMPLETE
  - A-ERR-SWEEP-001
  acceptance_checks:
  - go test ./...
  - make test-integration-selected
  - make lint
  notes: mode=single-path. Remove deprecated fallbacks, eliminate magic sentinels,
    and align all terminal/ssh runtime paths to current contracts only.
- id: A-CONTROL-PLANE-K8S-INFRA-MIGRATION-001
  title: Phase selected infra services into dev-control-1 Kubernetes one service at
    a time
  role: A-backend
  status: done
  priority: 933
  owner: agent-a
  branch: agent/A-backend
  completed_at: '2026-03-08'
  commit: f10389f
  depends_on:
  - A-CONTROL-PLANE-K8S-CORE-DEPLOY-001
  acceptance_checks:
  - rg -q "Redis|NATS|Temporal|Keycloak|Postgres" doc/operations/Control_Plane_K8s_Migration_v1.md
  - make queue-git-check
  notes: 'Context:

    Once the platform core is stable in Kubernetes, selected infra services can move
    into the cluster one service at a time. This is intentionally phased so operational
    lessons from the core deployment inform the infra move.


    Pre-read (required):

    - doc/operations/Control_Plane_K8s_Migration_v1.md

    - doc/operations/Three_Host_Dev_CI_MaaS_Lab_Plan.md


    Invariants (must not break):

    - Postgres is not the first stateful migration.

    - Each infra migration is independently observable and rollbackable.

    - Identity-critical and data-critical services move only after config, ingress,
    persistence, and secret handling are stable.


    Scope:

    - In: phased infra migration model and execution path.

    - Out: one-shot all-in migration.


    Deliverables:

    - phased service order and migration criteria.

    - rollback-aware infra move baseline.

    - cluster-placement rationale for each migrated service.


    Evidence required in handoff:

    - files changed

    - commit SHA

    - exact acceptance commands run

    - pass/fail status by command

    '
- id: A-CONTROL-PLANE-K8S-BASELINE-001
  title: K3s baseline and namespace/config model for dev-control-1 platform core
  role: A-backend
  status: done
  priority: 930
  owner: agent-a
  branch: agent/A-backend
  completed_at: '2026-03-08'
  commit: 3bdf965
  depends_on:
  - A-LAB-AUTOMATION-001
  - A-CI-BASE-IMAGE-001
  acceptance_checks:
  - rg -q "k3s|namespace|dev-control-1|platform core|nightly" doc/operations/Control_Plane_K8s_Migration_v1.md
  - make queue-git-check
  notes: 'Context:

    The three-host lab baseline is in place, but dev-control-1 is still only described
    as a control host. The next phase is to move the GPUaaS platform core to Kubernetes
    so deployment, rollout, namespace, and config automation become explicit.


    Pre-read (required):

    - doc/operations/Control_Plane_K8s_Migration_v1.md

    - doc/operations/Three_Host_Dev_CI_MaaS_Lab_Plan.md

    - build/ci-image/README.md


    Invariants (must not break):

    - Platform-app control stacks remain off dev-control-1.

    - Stateful infra is not all migrated at once.

    - The cluster model must preserve host-role boundaries and support nightly deployment
    automation.

    - Environment creation must remain config-driven and reusable for future test/staging/prod
    environments.

    - Multi-server control-plane expansion must be reserved now, not retrofitted later.


    Scope:

    - In: k3s install baseline, namespace model, config/secrets baseline, ingress
    baseline.

    - In: reusable environment blueprint model and multi-server control-plane design.

    - Out: full service deployment and stateful infra migration.


    Deliverables:

    - k3s baseline execution plan and automation hooks.

    - explicit namespace/config model for dev-control-1.

    - environment blueprint direction for test/staging/prod reuse.

    - multi-server control-plane expansion model for future `dev-control-2`.

    - follow-on seeds for core deploy, CD automation, and infra migration.


    Evidence required in handoff:

    - files changed

    - commit SHA

    - exact acceptance commands run

    - pass/fail status by command

    '
- id: A-CI-BASE-IMAGE-001
  title: Reusable CI base image for Go, Node, codegen, and contract tooling
  role: A-backend
  status: done
  priority: 917
  owner: agent-a
  branch: agent/A-backend
  completed_at: '2026-03-08'
  commit: 3d57a15
  depends_on:
  - A-THREE-HOST-DEV-CI-MAAS-LAB-001
  acceptance_checks:
  - rg -q "build/ci-image|runner|registry" doc/operations/Three_Host_Dev_CI_MaaS_Lab_Plan.md
  - make queue-git-check
  notes: 'Context:

    CI drift is currently absorbed at job runtime through package installs and toolchain
    mismatch handling. The lab baseline assumes a reusable CI image published from
    the control host and consumed by tagged runners.


    Pre-read (required):

    - doc/operations/Three_Host_Dev_CI_MaaS_Lab_Plan.md

    - .gitlab-ci.yml

    - scripts/ci/


    Invariants (must not break):

    - CI logic remains host-agnostic and lives in reusable scripts.

    - The CI image is a dependency carrier, not a place to encode project logic.

    - The image must be consumable by digest.


    Scope:

    - In: CI image baseline and pipeline consumption model.

    - Out: full self-hosted registry HA.

    - Out: non-CI runtime images.


    Deliverables:

    - `build/ci-image/` baseline.

    - documented image build/publish/update trigger model.

    - follow-up path for runner adoption.


    Evidence required in handoff:

    - files changed

    - commit SHA

    - exact acceptance commands run

    - pass/fail status by command

    '
- id: A-SSH-003
  title: Update node-agent task validation/execution for multi-key provision payload
  role: A-backend
  status: done
  priority: 16
  owner: agent-a
  branch: agent/A-backend
  completed_at: '2026-02-27'
  commit: 391e4f4
  depends_on:
  - A-SSH-001
  acceptance_checks:
  - go test ./cmd/node-agent
  - make test-integration-selected
  notes: Enforce username regex + uid/gid bounds, process ssh_public_keys[] (1..20),
    create group/user deterministically, and write authorized_keys set idempotently.
- id: B-TERM-002
  title: Terminal reconnect/release e2e correctness
  role: B-ui
  status: done
  priority: 8
  owner: agent-b
  branch: agent/B-ui
  completed_at: '2026-02-27'
  commit: 540bc0c
  depends_on:
  - A-TERM-002
  - B-TERM-001
  acceptance_checks:
  - pnpm --dir packages/web e2e -- e2e/provisioning.spec.ts --grep reconnect
  - pnpm --dir packages/web e2e -- e2e/provisioning.spec.ts --grep release
  notes: Verify reconnect performs full reopen (new token), and release mid-session
    shows deterministic close reason with clean UI recovery.
- id: C-SSH-001
  title: SSH key management operational controls and runbook coverage
  role: C-ops
  status: done
  priority: 9
  owner: agent-c
  branch: agent/C-ops
  completed_at: '2026-02-27'
  commit: e63c22d
  depends_on:
  - A-SSH-002
  acceptance_checks:
  - make ops-observability-smoke
  - rg -q "SSH key" doc/operations/runbooks/Node_Onboarding_Runbook.md
  notes: Capture key-rotation/rollback guidance, audit evidence expectations, and
    alert/runbook mapping for SSH key management paths.
- id: A-PROV-REMOVE-SSH
  title: Remove SSH provisioning runtime path and enforce agent-only provisioning
    mode
  role: A-backend
  status: done
  priority: 17
  owner: agent-a
  branch: agent/A-backend
  completed_at: '2026-02-28'
  commit: 3208c1d
  depends_on:
  - A-SSH-003
  - C-OPS-002
  acceptance_checks:
  - go test ./cmd/provisioning-worker ./packages/services/provisioning/worker
  - make test-integration-selected
  - sh -lc '! rg -q "NewSSHRuntimeFromEnv" cmd/provisioning-worker/main.go'
  - rg -q "NewAgentTaskRuntime" cmd/provisioning-worker/main.go
  notes: Remove ssh runtime branch from provisioning worker/runtime config; keep noop
    for test-only harness but production/dev path must be agent runtime only.
- id: A-TERM-STREAM-COMPLETE
  title: Complete stream-only terminal backend path and deprecate ssh_legacy mode
  role: A-backend
  status: done
  priority: 18
  owner: agent-a
  branch: agent/A-backend
  completed_at: '2026-02-28'
  commit: 2c29edf
  depends_on:
  - A-TERM-003
  - A-PROV-REMOVE-SSH
  acceptance_checks:
  - go test ./cmd/terminal-gateway ./packages/services/terminal ./cmd/api
  - make test-integration-selected
  - rg -q "terminal.open" cmd/node-agent/catalog.go
  - sh -lc '! rg -q "terminal mode not yet supported" cmd/terminal-gateway/routes.go'
  notes: Keep ssh_legacy behind explicit temporary flag only; set node_agent_stream
    as default runtime mode and remove legacy-only dependencies from active path.
- id: A-ERR-SWEEP-001
  title: Backend error-handling sweep for canonical envelope and non-silent failures
  role: A-backend
  status: done
  priority: 19
  owner: agent-a
  branch: agent/A-backend
  completed_at: '2026-02-28'
  commit: 0571f93
  depends_on:
  - A-TERM-STREAM-COMPLETE
  acceptance_checks:
  - go test ./cmd/api ./cmd/terminal-gateway ./packages/services/terminal
  - make test-integration-selected
  - rg -q "correlation_id" cmd/terminal-gateway/routes.go
  - rg -q "code\\\":\\\".*\\\"" packages/web/src/lib/errors.ts
  notes: Ensure pre-upgrade terminal failures, auth failures, and provisioning failures
    consistently return code/message/correlation_id with actionable log context.
- id: A-CONTROL-PLANE-K8S-CORE-DEPLOY-001
  title: Deploy GPUaaS platform core services to dev-control-1 Kubernetes
  role: A-backend
  status: done
  priority: 931
  owner: agent-a
  branch: agent/A-backend
  completed_at: '2026-03-08'
  commit: 488d834
  depends_on:
  - A-CONTROL-PLANE-K8S-BASELINE-001
  acceptance_checks:
  - rg -q "api|web|terminal-gateway|outbox-relay|app-runtime-worker|provisioning-worker"
    doc/operations/Control_Plane_K8s_Migration_v1.md
  - make queue-git-check
  notes: 'Context:

    After the cluster baseline is established, the next step is to deploy the GPUaaS
    platform core itself to dev-control-1 in Kubernetes rather than relying on host-level
    compose assumptions.


    Pre-read (required):

    - doc/operations/Control_Plane_K8s_Migration_v1.md

    - doc/operations/Three_Host_Dev_CI_MaaS_Lab_Plan.md


    Invariants (must not break):

    - Platform-app control stacks remain on dev-lab-1.

    - External infra remains stable while the first core wave moves.

    - Readiness, liveness, ingress, and scaling boundaries must become explicit.


    Scope:

    - In: first-wave and follow-on GPUaaS core service deployment to Kubernetes.

    - Out: stateful infra migration.


    Deliverables:

    - deployable Kubernetes artifacts for the platform core.

    - documented rollout order and health validation.

    - follow-on gaps captured if service assumptions leak from compose/local-dev.


    Evidence required in handoff:

    - files changed

    - commit SHA

    - exact acceptance commands run

    - pass/fail status by command

    '
- id: A-LAB-AUTOMATION-001
  title: Three-host lab automation baseline with inventory and common convergence
    roles
  role: A-backend
  status: done
  priority: 916
  owner: agent-a
  branch: agent/A-backend
  completed_at: '2026-03-08'
  commit: f6be511
  depends_on:
  - A-THREE-HOST-DEV-CI-MAAS-LAB-001
  acceptance_checks:
  - rg -q "infra/ansible|dev-control|dev-lab|dev-gpu" doc/operations/Three_Host_Dev_CI_MaaS_Lab_Plan.md
  - make queue-git-check
  notes: 'Context:

    The 3-host lab baseline is documented, but the hosts remain pets until automation
    owns their baseline. This task converts the lab plan into inventory, common roles,
    and repeatable host convergence.


    Pre-read (required):

    - doc/operations/Three_Host_Dev_CI_MaaS_Lab_Plan.md

    - doc/operations/Production_Platform_Baseline.md

    - doc/operations/Environment_Promotion_Policy.md


    Invariants (must not break):

    - Real GPU workers are not treated as generic CI hosts.

    - Host role separation stays explicit in automation.

    - Manual shell history is not treated as desired state.


    Scope:

    - In: automation skeleton, inventory, and common host convergence.

    - Out: full HA production deployment automation.

    - Out: scheduler/runtime-specific stack deployment.


    Deliverables:

    - `infra/ansible/` baseline and host inventory.

    - common role and host-role separation for control/lab/gpu.

    - documented converge path.


    Evidence required in handoff:

    - files changed

    - commit SHA

    - exact acceptance commands run

    - pass/fail status by command

    '
- id: A-THREE-HOST-DEV-CI-MAAS-LAB-001
  title: Three-host dev, CI, platform-app, and MaaS lab execution baseline
  role: A-backend
  status: done
  priority: 915
  owner: agent-a
  branch: agent/A-backend
  completed_at: '2026-03-07'
  commit: c00a9aa
  depends_on: []
  acceptance_checks:
  - rg -q "100.90.157.34|100.69.173.30|100.88.227.60|dev-control-1|dev-lab-1|dev-gpu-1"
    doc/operations/Three_Host_Dev_CI_MaaS_Lab_Plan.md
  - rg -q "Slurm|Ray|K8s|node-shim|MaaS" doc/operations/Three_Host_Dev_CI_MaaS_Lab_Plan.md
  - make queue-git-check
  notes: 'Context:

    We now have distinct control, lab, and real GPU hosts available. Without an explicit
    baseline, CI, platform-app testing, and MaaS evidence collection will drift into
    ad hoc host usage and unclear responsibility boundaries.


    Pre-read (required):

    - doc/operations/Three_Host_Dev_CI_MaaS_Lab_Plan.md

    - doc/architecture/Scheduler_as_Platform_App_v1.md

    - doc/architecture/App_Runtime_Operating_Modes_v1.md

    - doc/operations/Observability_Baseline.md


    Invariants (must not break):

    - Real GPU workers are not treated as generic CI hosts.

    - Platform-app control planes run off the GPU worker host.

    - The lab layout must support future tenant-dedicated app backends and MaaS evidence
    gathering.

    - Automation remains the target operating model, not manual shell history.

    Scope:

    - In: host role baseline, runner model, automation layout, and day 0-7 execution
    plan.

    - In: separation of control-plane, lab-control, and real GPU worker responsibilities.

    - Out: full Ansible or systemd implementation in this task.

    - Out: production HA deployment guide.


    Deliverables:

    - 3-host lab execution plan.

    - explicit host-role and CI-tag model.

    - follow-up execution seeds for automation and deployment if needed.


    Evidence required in handoff:

    - files changed

    - commit SHA

    - exact acceptance commands run

    - pass/fail status by command.

    '
- id: A-SSH-001
  title: Implement per-user POSIX identity + effective SSH key-set resolution in provisioning
    runtime
  role: A-backend
  status: done
  priority: 14
  owner: agent-a
  branch: agent/A-backend
  completed_at: '2026-02-27'
  commit: 66cbf0b
  depends_on:
  - A-TERM-003
  acceptance_checks:
  - go test ./packages/services/provisioning/worker
  - make test-integration-selected
  notes: Resolve user_posix_identities and allocation_ssh_public_keys/default key
    fallback, then pass username/uid/gid/supplemental_gids/ssh_public_keys[] to agent
    runtime.
- id: A-TERM-002
  title: Terminal close sequencing and reconnect semantics
  role: A-backend
  status: done
  priority: 12
  owner: agent-a
  branch: agent/A-backend
  completed_at: '2026-02-27'
  commit: 052144a
  depends_on:
  - A-TERM-001
  acceptance_checks:
  - go test ./packages/services/terminal ./cmd/provisioning-worker
  - make test-integration-selected
  notes: Release wins with deterministic ordering (close session, then revoke user);
    reconnect must use full reopen flow with a new token.
- id: B-TERM-001
  title: Terminal UX lifecycle and close-reason rendering
  role: B-ui
  status: done
  priority: 7
  owner: agent-b
  branch: agent/B-ui
  completed_at: '2026-02-27'
  commit: 64d3b5e
  depends_on:
  - A-TERM-001
  acceptance_checks:
  - pnpm --dir packages/web test src/components/terminal/TerminalPanel.test.tsx
  - pnpm --dir packages/web e2e -- e2e/provisioning.spec.ts --grep terminal
  notes: Render stable states (connecting/connected/disconnected/closed) and deterministic
    close reasons from control payloads.
- id: A-SSH-002
  title: Implement SSH key management APIs for default key and allocation key set
    override
  role: A-backend
  status: done
  priority: 15
  owner: agent-a
  branch: agent/A-backend
  completed_at: '2026-02-27'
  commit: 9f07f5f
  depends_on:
  - A-SSH-001
  acceptance_checks:
  - go test ./cmd/api ./packages/services/auth ./packages/services/provisioning/worker
  - make test-integration-selected
  notes: Implement PUT /api/v1/ssh-keys/{key_id}/default and PUT /api/v1/allocations/{allocation_id}/ssh-keys
    with ownership/auth/audit and contract-compliant error handling.
- id: C-OPS-002
  title: PKI/step-ca staging readiness evidence
  role: C-ops
  status: done
  priority: 2
  owner: agent-c
  branch: agent/C-ops
  completed_at: '2026-02-26'
  commit: a8b6131
  depends_on:
  - A-P7-002
  acceptance_checks:
  - make ops-parallel-evidence-check
  - rg -q "Phase" doc/Phase_Readiness_Tracker.md
  notes: Track cert lifecycle, rotation procedure, and trust bootstrap evidence.
- id: A-TERM-003
  title: Terminal mode gate and legacy path hardening
  role: A-backend
  status: done
  priority: 13
  owner: agent-a
  branch: agent/A-backend
  completed_at: '2026-02-27'
  commit: 368933e
  depends_on:
  - A-TERM-001
  acceptance_checks:
  - go test ./cmd/terminal-gateway ./cmd/api
  - make test-integration-selected
  notes: Keep TERMINAL_MODE=ssh_legacy fallback, default to node_agent_stream in dev
    docs once relay path is stable, expose explicit metrics per mode.
- id: A-TERM-001
  title: Terminal sprint MVP-secure stream relay via api.internal (Option-A)
  role: A-backend
  status: done
  priority: 11
  owner: agent-a
  branch: agent/A-backend
  completed_at: '2026-02-27'
  commit: 48b9969
  depends_on:
  - A-P9C-001
  - A-P9C-002
  acceptance_checks:
  - go test ./packages/services/terminal ./cmd/api ./cmd/terminal-gateway
  - make test-integration-selected
  notes: Implement terminal.open task + internal stream relay path; enforce single
    active session per allocation and terminal.session_max_ttl_seconds.
- id: A-P7-002
  title: Internal node mTLS identity binding and auth hardening
  role: A-backend
  status: done
  priority: 2
  owner: agent-a
  branch: agent/A-backend
  completed_at: '2026-02-26'
  commit: cc3af8e
  depends_on:
  - A-P7-001
  acceptance_checks:
  - go test ./cmd/api
  - make test-integration-selected
  notes: Bind cert identity to node_id authorization.
- id: A-P9C-001
  title: Extract terminal WS runtime into dedicated cmd/terminal-gateway
  role: A-backend
  status: done
  priority: 6
  owner: agent-a
  branch: agent/A-backend
  completed_at: '2026-02-26'
  commit: a050e34
  depends_on:
  - A-P7-005
  acceptance_checks:
  - go test ./packages/services/terminal ./cmd/terminal-gateway
  - make test-integration-selected
  notes: 'Option C path: keep contracts unchanged, move WS handling out of cmd/api.'
- id: A-P9C-002
  title: Terminal gateway security/telemetry hardening
  role: A-backend
  status: done
  priority: 7
  owner: agent-a
  branch: agent/A-backend
  completed_at: '2026-02-26'
  commit: 1bd75ff
  depends_on:
  - A-P9C-001
  acceptance_checks:
  - go test ./cmd/terminal-gateway
  - make test-integration-selected
  notes: Enforce strict token consume/validation and gateway-specific health metrics.
- id: A-P7-001
  title: 'Provisioning agent runtime: wait for node task completion'
  role: A-backend
  status: done
  priority: 1
  owner: agent-a
  branch: agent/A-backend
  completed_at: '2026-02-26'
  commit: 4dca85d
  depends_on: []
  acceptance_checks:
  - go test ./packages/services/provisioning/worker
  - make test-integration-selected
  notes: Enqueue is not terminal success; map timeout/failure to failed/release_failed.
- id: A-P7-005
  title: Remove persistent user private-key dependency from provisioning/terminal
  role: A-backend
  status: done
  priority: 5
  owner: agent-a
  branch: agent/A-backend
  completed_at: '2026-02-26'
  commit: 05f2ddc
  depends_on:
  - A-P7-001
  - A-P7-003
  acceptance_checks:
  - go test ./packages/services/provisioning/worker ./packages/services/terminal
  - make test-integration-selected
  notes: 'Decision finalized: remove /api/v1/allocations/{id}/ssh-key and move to
    user-managed public key model as pre-launch cutover (no compatibility window).'
- id: A-P7-003
  title: Temporal provisioning workflow compensation and duplicate-event safety
  role: A-backend
  status: done
  priority: 3
  owner: agent-a
  branch: agent/A-backend
  completed_at: '2026-02-26'
  commit: cdac6ed
  depends_on:
  - A-P7-001
  acceptance_checks:
  - go test ./cmd/provisioning-worker
  - make test-integration-selected
  notes: Deterministic behavior for retries and duplicate envelopes.
- id: A-SEC-SAST-REPORT-001
  title: Add report-only SAST and secret scanning to every push
  role: A-backend
  status: todo
  priority: 930
  owner: ''
  branch: agent/A-backend
  completed_at: ''
  commit: ''
  depends_on:
  - A-PLATFORM-CONTROL-DEPLOY-IMAGE-FRESHNESS-001
  acceptance_checks:
  - bash scripts/ci/security_sast_report.sh
  - make queue-git-check
  notes: 'Context:

    The codebase is large enough now that security findings should be surfaced continuously
    instead of discovered ad hoc later. Start with report-only scans so the team can
    baseline noise and fix real issues before introducing blocking gates.


    Scope:

    - In: `gitleaks`, `gosec`, and `semgrep` wired into reusable CI scripts with machine-readable
    output artifacts and a clear summary. - In: guidance for local/pre-commit secret
    scanning where practical. - Out: blocking merge/promotion enforcement in the same
    slice.

    '
- id: A-SEC-IMAGE-SCAN-REPORT-001
  title: Add report-only OCI/runtime image vulnerability scanning before promotion
  role: A-backend
  status: todo
  priority: 931
  owner: ''
  branch: agent/A-backend
  completed_at: ''
  commit: ''
  depends_on:
  - A-SEC-SAST-REPORT-001
  - A-PLATFORM-CONTROL-DEPLOY-IMAGE-FRESHNESS-001
  acceptance_checks:
  - bash scripts/ci/security_image_scan_report.sh
  - make queue-git-check
  notes: 'Context:

    GPUaaS publishes runtime images and OCI artifacts as first-class release units.
    Those artifacts should carry vulnerability scan evidence before they are promoted
    further in the lifecycle.


    Scope:

    - In: `trivy` scanning for runtime images and relevant OCI artifacts with report
    output persisted in CI artifacts. - In: digest-based scanning tied to the published
    image/artifact ref. - Out: blocking promotion enforcement in the same slice.

    '
- id: A-SEC-DAST-REPORT-001
  title: Add report-only API DAST against platform-control or staging
  role: A-backend
  status: todo
  priority: 932
  owner: ''
  branch: agent/A-backend
  completed_at: ''
  commit: ''
  depends_on:
  - A-SEC-SAST-REPORT-001
  - A-SEC-IMAGE-SCAN-REPORT-001
  acceptance_checks:
  - bash scripts/ci/security_dast_report.sh
  - make queue-git-check
  notes: 'Context:

    Static scanning is not enough for API auth, header, and exposed-surface regressions.
    A deployed environment should be exercised with an OpenAPI-driven DAST pass before
    the platform begins enforcing promotion gates.


    Scope:

    - In: report-only `OWASP ZAP` API scan against a live environment using the published
    OpenAPI contract. - In: CI artifact/report output and a short summary in the deploy/validation
    stage. - Out: immediate blocking of deploys or promotions on DAST findings.

    '
- id: A-SEC-SCAN-PROMOTION-GATES-001
  title: Turn security scan reports into artifact promotion and rollout gates
  role: A-backend
  status: todo
  priority: 933
  owner: ''
  branch: agent/A-backend
  completed_at: ''
  commit: ''
  depends_on:
  - A-SEC-SAST-REPORT-001
  - A-SEC-IMAGE-SCAN-REPORT-001
  - A-SEC-DAST-REPORT-001
  acceptance_checks:
  - bash scripts/ci/security_promotion_gate.sh
  - make queue-git-check
  notes: 'Context:

    Scan results should not remain loose CI artifacts forever. GPUaaS already has
    an artifact lifecycle and promotion model, so verified scan outcomes should become
    part of the release decision boundary.


    Scope:

    - In: promotion rules for clean or explicitly-accepted scan outcomes, initially
    blocking on the highest-severity image findings only. - In: a path for baselining/suppressing
    accepted findings with reviewable ownership. - Out: broad policy exceptions without
    artifact-state visibility.

    '
- id: A-CONTRACT-SCHEMATHESIS-RUNTIME-CONFORMANCE-001
  title: Add report-only Schemathesis runtime conformance checks against the OpenAPI
    contract
  role: A-backend
  status: todo
  priority: 934
  owner: ''
  branch: agent/A-backend
  completed_at: ''
  commit: ''
  depends_on:
  - A-PLATFORM-CONTROL-DEPLOY-IMAGE-FRESHNESS-001
  acceptance_checks:
  - rg -q "schemathesis" scripts/ci
  - bash scripts/ci/contracts_validate.sh
  - make queue-git-check
  notes: 'Context:

    The repo is already strongly contract-first:

    - OpenAPI / AsyncAPI as source of truth - generated Go and TypeScript types -
    breaking-change gates - invariant gates - UX/contract parity checks

    The remaining gap is runtime conformance: proving that the running API actually
    behaves according to the OpenAPI contract.


    Scope:

    - In: add a report-only Schemathesis stage that exercises a running API against
    `doc/api/openapi.draft.yaml` - In: start with a scoped, stable set of endpoints
    rather than fuzzing the whole product surface on day one - Out: immediate hard
    CI gating before the report-only baseline is understood

    '
- id: A-CONTRACT-OASDIFF-TOOLING-REFRESH-001
  title: Replace or compare legacy openapi-diff usage with oasdiff for breaking-change
    classification
  role: A-backend
  status: todo
  priority: 935
  owner: ''
  branch: agent/A-backend
  completed_at: ''
  commit: ''
  depends_on:
  - A-CONTRACT-SCHEMATHESIS-RUNTIME-CONFORMANCE-001
  acceptance_checks:
  - rg -q "oasdiff|openapi-diff" scripts/ci
  - bash scripts/ci/contracts_breaking_change.sh
  - make queue-git-check
  notes: 'Context:

    The current contract governance already includes a breaking-change stage, but
    the underlying `openapi-diff` tooling is less attractive than `oasdiff` for long-term
    maintenance and classification quality.


    Scope:

    - In: evaluate `oasdiff` against the current breaking-change workflow and either
    replace the existing tool or run both side by side during a migration window -
    Out: changing the contract versioning policy itself in the same slice

    '
- id: A-PLATFORM-RUNTIME-IDENTITY-INFO-001
  title: Add runtime build identity logging and `/info` endpoints across platform
    binaries
  role: A-backend
  status: todo
  priority: 936
  owner: ''
  branch: agent/A-backend
  completed_at: ''
  commit: ''
  depends_on:
  - A-PLATFORM-CONTROL-DEPLOY-IMAGE-FRESHNESS-001
  acceptance_checks:
  - rg -q "/info|buildinfo|git_sha|build_timestamp" cmd packages scripts/ci
  - go test ./cmd/... ./packages/...
  - make queue-git-check
  notes: 'Context:

    Release hardening now has better artifact and digest checks, but runtime verification
    is still weaker than it should be. Every deployable binary should make its build
    identity obvious both in startup logs and over an operator-readable HTTP endpoint
    so release conformance can compare intended vs actual runtime state directly.


    Scope:

    - In: add startup log fields for service name, version, git SHA, build timestamp,
    and any available image/config revision metadata - In: add lightweight `/info`
    identity endpoints for HTTP-serving binaries, including API, web-facing gateways,
    docs containers, and node-agent where applicable - In: standardize toward `/livez`
    and `/readyz` semantics instead of overloading `/healthz` for every purpose -
    In: ensure release validation can consume this identity data during deploy checks
    - Out: broad `/env` dumps, secret-bearing config endpoints, or turning `/healthz`
    into a verbose diagnostic surface

    Relevant platform stance:

    - `/metrics`: internal/scraper only - `/livez`: cheap process-alive only - `/readyz`:
    minimal dependency readiness for serving traffic - `/info`: build/runtime identity,
    operator-readable, not public by default - `/env`: not a normal public feature;
    if ever added later, it must be admin/internal only with an explicit redaction
    allowlist

    '
- id: A-OPS-MACHINE-READABLE-INTENT-001
  title: Enrich operational APIs and read models with machine-readable intent recovery
    hints and semantic explanations
  role: A-backend
  status: todo
  priority: 936
  owner: ''
  branch: agent/A-backend
  completed_at: ''
  commit: ''
  depends_on:
  - A-PLATFORM-RUNTIME-IDENTITY-INFO-001
  - A-ADMIN-AUDIT-PRESENTATION-MODEL-001
  acceptance_checks:
  - make codegen
  - bash scripts/ci/contracts_validate.sh
  - go test ./cmd/api ./packages/services/maas ./packages/services/admin/...
  - make queue-git-check
  notes: 'Context:

    The platform already has strong contract-first discipline, but many operational
    surfaces still behave like programmer-facing debug APIs rather than agent/operator-friendly
    control-plane APIs. The next maturity step is to make failures, workflow states,
    and privileged audit surfaces more self-describing without weakening security
    or inventing AI-only protocol changes.


    Requirements:

    - keep the canonical error envelope and enrich `details` additively where the
    owning domain can provide useful machine-readable intent such as failing resource
    identifiers, failure class, retryability, and suggested next action

    - extend operational read models with semantic explanation fields such as current
    blocker, recovery action, and next safe operator step instead of exposing only
    raw state strings

    - ensure privileged admin/audit APIs return backend-owned presentation metadata
    rather than forcing UIs or agents to hardcode per-action interpretation

    - preserve source-of-truth boundaries: GPUaaS should expose operationally necessary
    and diagnostically useful context, not become a general CMDB or raw environment/config
    dump

    Scope:

    - In: additive contract/read-model improvements for errors, workflow visibility,
    audit presentation, and runtime identity surfaces

    - Out: broad debug endpoints, raw `/env` dumps, or speculative agent-only transport
    changes

    '
- id: A-PLATFORM-MANAGEMENT-ENDPOINT-SEPARATION-001
  title: Separate operational endpoints onto a dedicated management listener where
    appropriate
  role: A-backend
  status: todo
  priority: 937
  owner: ''
  branch: agent/A-backend
  completed_at: ''
  commit: ''
  depends_on:
  - A-PLATFORM-RUNTIME-IDENTITY-INFO-001
  acceptance_checks:
  - rg -q "livez|readyz|metrics|management" cmd packages scripts
  - go test ./cmd/... ./packages/...
  - make queue-git-check
  notes: 'Context:

    Once runtime identity and health endpoint semantics are standardized, the next
    hardening step is to stop serving operational endpoints from the same listener
    as public business traffic where that separation is practical.


    Scope:

    - In: evaluate and implement dedicated management listeners/ports for core HTTP-serving
    binaries where it materially improves safety and operational clarity - In: keep
    `/metrics`, `/livez`, `/readyz`, and `/info` on the management side where possible
    - Out: blocking the runtime identity work on a full listener refactor, or exposing
    broad debug/config payloads without access controls

    '
- id: C-PLATFORM-POSTGRES-IN-K8S-001
  title: Move platform-control Postgres into Kubernetes with PgBouncer and recovery
    requirements
  role: C-ops
  status: todo
  priority: 938
  owner: ''
  branch: agent/C-ops
  completed_at: ''
  commit: ''
  depends_on:
  - A-PLATFORM-CONTROL-DEPLOY-IMAGE-FRESHNESS-001
  acceptance_checks:
  - rg -q "postgres|pgbouncer" infra/k8s scripts doc/architecture
  - bash scripts/ci/platform_control_remote_validation.sh
  - make queue-git-check
  notes: 'Context:

    Platform-control is becoming the integrated pre-production environment, and the
    database should eventually stop being an out-of-band special case. But moving
    Postgres into Kubernetes only helps if pooling, persistence, backup, restore,
    and recovery are treated as first-class requirements from day one.


    Scope:

    - In: choose and implement the platform-control Postgres-on-Kubernetes shape (operator/stateful
    deployment as appropriate) - In: add PgBouncer for connection pooling in front
    of the database - In: define and test backup/restore expectations, storage layout,
    and operational runbooks - In: ensure application connection settings and validation
    scripts work with the new topology - Out: broad multi-region HA ambitions or production-grade
    cross-cluster failover in the same slice

    Preferred direction:

    - Postgres in Kubernetes with durable storage and explicit restore testing - PgBouncer
    for pooling - no broad `/env` style operational shortcuts instead of real runbooks
    and validation

    '
- id: C-PLATFORM-CONTROL-DOCKER-DATAROOT-MOVE-001
  title: Move platform-control Docker data root onto `/ai-cloud-data`
  role: C-ops
  status: todo
  priority: 939
  owner: ''
  branch: agent/C-ops
  completed_at: ''
  commit: ''
  depends_on:
  - A-PLATFORM-CONTROL-DEPLOY-IMAGE-FRESHNESS-001
  acceptance_checks:
  - ssh hpcadmin@100.90.157.34 'sudo docker info --format ''{{.DockerRootDir}}'''
  - ssh hpcadmin@100.90.157.34 'df -h / /ai-cloud-data'
  - bash scripts/ci/platform_control_remote_validation.sh
  - make queue-git-check
  notes: 'Context:

    The new 1.6T disk is mounted at `/ai-cloud-data`, but the actual pressure path
    that caused rollout failures was Docker storage on the root filesystem. Move Docker
    first because it offers the highest benefit with the lowest operational risk.


    Scope:

    - In: move Docker data root from the root filesystem to `/ai-cloud-data/docker`
    - In: preserve build/import/deploy workflows and validate platform-control after
    the change - Out: moving k3s/containerd or database state in the same slice

    '
- id: C-PLATFORM-CONTROL-STORAGE-REVALIDATION-001
  title: Revalidate platform-control build and deploy behavior after Docker storage
    migration
  role: C-ops
  status: todo
  priority: 940
  owner: ''
  branch: agent/C-ops
  completed_at: ''
  commit: ''
  depends_on:
  - C-PLATFORM-CONTROL-DOCKER-DATAROOT-MOVE-001
  acceptance_checks:
  - bash scripts/ci/platform_control_deploy.sh
  - bash scripts/ci/platform_control_remote_validation.sh
  - bash scripts/ci/platform_control_hardening_report.sh
  - make queue-git-check
  notes: 'Context:

    Moving Docker storage should reduce disk pressure, but the value only counts if
    the full build/import/deploy/validation path stays healthy afterward. This is
    a validation slice, not just an infra tweak.


    Scope:

    - In: rerun the standard platform-control rollout and validation path after the
    Docker move - In: confirm the node no longer hits disk pressure during normal
    release activity - Out: broader k3s or database storage moves

    '
- id: C-PLATFORM-CONTROL-STATEFUL-STORAGE-PLAN-001
  title: Plan relocation of platform-control stateful data onto `/ai-cloud-data`
  role: C-ops
  status: todo
  priority: 941
  owner: ''
  branch: agent/C-ops
  completed_at: ''
  commit: ''
  depends_on:
  - C-PLATFORM-CONTROL-STORAGE-REVALIDATION-001
  acceptance_checks:
  - rg -q "/ai-cloud-data|/var/lib/rancher|postgres|stateful" doc infra scripts
  - make queue-git-check
  notes: 'Context:

    Docker is the first, low-risk storage move. Stateful data such as k3s/containerd
    paths and any future database storage should be planned separately with backup,
    restore, and rollback in mind rather than folded into the same operational change.


    Scope:

    - In: assess which remaining stateful paths should live on `/ai-cloud-data` and
    what migration/recovery mechanics they need - In: treat k3s/containerd and database
    storage as deliberate migrations with maintenance windows - Out: making those
    moves immediately without the necessary recovery plan

    '
- id: C-PLATFORM-CONTROL-CAPACITY-REBOOT-001
  title: Reboot platform-control to realize allocated CPU and memory expansion
  role: C-ops
  status: todo
  priority: 942
  owner: ''
  branch: agent/C-ops
  completed_at: ''
  commit: ''
  depends_on:
  - C-PLATFORM-CONTROL-STORAGE-REVALIDATION-001
  acceptance_checks:
  - ssh hpcadmin@100.90.157.34 'nproc && free -h'
  - ssh hpcadmin@100.90.157.34 'sudo k3s kubectl get node -o wide'
  - bash scripts/ci/platform_control_remote_validation.sh
  - make queue-git-check
  notes: 'Context:

    The platform-control node has been allocated additional CPU and memory, but a
    reboot is still required for the guest to realize the new capacity. Track this
    as an explicit infrastructure step rather than an informal note.


    Scope:

    - In: perform the reboot when the environment can absorb it and re-measure CPU/memory
    afterward - In: validate that k3s and the platform services recover cleanly -
    Out: mixing this reboot into the Docker storage migration without a clear rollback
    point

    '
- id: C-PLATFORM-PRODUCTION-SHAPED-AUTOMATION-001
  title: Make platform-control and future production environments one-button, production-shaped
    deployments
  role: C-ops
  status: todo
  priority: 943
  owner: ''
  branch: agent/C-ops
  completed_at: ''
  commit: ''
  depends_on:
  - A-PLATFORM-CONTROL-DEPLOY-IMAGE-FRESHNESS-001
  - C-PLATFORM-CONTROL-GITOPS-EVALUATION-001
  acceptance_checks:
  - rg -q "platform-control|GitOps|remote validation|release candidate|runbook" doc
    infra scripts/ci
  - make queue-git-check
  notes: 'Context:

    The target operating model is not a special-case lab environment. Platform-control
    should be a smaller but production-shaped deployment, and a new environment should
    be bring-up-able from a box with declarative automation rather than manual setup
    knowledge.


    Target outcome:

    - A new environment can be brought up from infrastructure + secrets prerequisites
    with a standard automated path - The deployment model, storage model, validation
    model, and release model match production shape as closely as possible - Manual
    patching and tribal-knowledge recovery steps are driven toward zero


    Scope:

    - In: define the phased path from current platform-control to production-shaped
    automation - In: use platform-control as the proving ground for GitOps/release
    discipline, storage topology, runtime identity, validation, and recovery automation
    - In: make the end state explicit enough that work can be delegated across lanes,
    including C-ops - Out: pretending the entire end state lands in one slice without
    intermediate milestones

    '
- id: C-PLATFORM-CI-RUNTIME-IMAGE-MODEL-DOCS-001
  title: Document platform-control pipeline image model runner lanes and release checks
  role: C-ops
  status: done
  priority: 944
  owner: agent-c
  branch: agent/C-ops
  completed_at: '2026-03-17'
  commit: 13078ab
  depends_on: []
  acceptance_checks:
  - rg -q "Mermaid|runner lanes|blocking|report-only|CI base image|distroless|scratch"
    doc/operations/Platform_Control_Release_Pipeline_Model.md
  - make queue-git-check
  notes: 'Context:

    Platform-control now has a real release pipeline, multiple runner lanes, a reusable
    CI base image model, report-only security/runtime checks, and a planned move of
    Go runtime images toward distroless or `scratch`. That operating model needs one
    clear document so later changes do not recreate hidden assumptions.


    Required content:

    - Mermaid or equivalent pipeline diagram showing release stages and main job dependencies

    - runner-lane map (`ci-fast`, `ci-build`, `ci-release`, `ci-report`, `ci-frontend`)
    and which job classes run on each

    - check inventory covering: - contracts - build/tests - SAST (`gosec`, `gitleaks`,
    `govulncheck`, `semgrep`) - image scan (`trivy`) - runtime contract conformance
    (`Schemathesis`) - API DAST - deploy / remote validation / hardening aggregation

    - explicit blocking vs report-only status for each check

    - CI base image model: - explicit hash inputs - when the CI image rebuilds - how
    `GPUAAS_CI_JOB_IMAGE` is rolled out - why normal jobs should consume, not build,
    the CI environment

    - runtime image model: - runtime images stay fixed unless their service/runtime
    inputs change - Go services target distroless or `scratch` - web remains the Node/dependency-heavy
    exception

    - release candidate model: - frozen SHA as deployment unit - relationship between
    release candidate, runtime image digests, and live conformance checks


    Scope:

    - In: platform-control release/CI/runtime-image operating model documentation

    - Out: rewriting the pipeline itself as part of the documentation task

    '
- id: C-PLATFORM-CI-LOG-REVIEW-ACTIONS-001
  title: Review platform-control CI logs and artifacts and turn findings into fixes
    backlog or documented exceptions
  role: C-ops
  status: todo
  priority: 945
  owner: ''
  branch: agent/C-ops
  completed_at: ''
  commit: ''
  depends_on:
  - C-PLATFORM-CI-RUNTIME-IMAGE-MODEL-DOCS-001
  acceptance_checks:
  - rg -q "CI log review|pipeline artifact review|action items|false positives|follow-up
    owner" doc/operations/Platform_Control_CI_Log_Review.md
  - make queue-git-check
  notes: 'Context:

    The platform-control pipeline is now in a usable fast-iteration state, but recent
    work exposed several classes of hidden issues only after reading full job logs
    and report artifacts closely: stale/full-mode CI graph mismatches, frontend e2e
    environment readiness problems, cache warnings, scanner false positives, and report-only
    jobs that still need explicit disposition.


    Required outcome:

    - review current platform-control pipeline logs across the main lanes (`ci-fast`,
    `ci-build`, `ci-release`, `ci-report`, `ci-frontend`) and classify recurring warnings/failures/noise
    as: - immediate fix - backlog follow-up - accepted/documented exception

    - review generated report artifacts and summaries for: - SAST - image scan - DAST
    - Schemathesis - hardening aggregation

    - record concrete follow-up actions with owner and next step rather than leaving
    findings in raw logs only


    Scope:

    - In: end-to-end log reading, artifact review, warning/noise classification, and
    backlog/doc follow-up creation

    - In: identifying cache-path cleanup, scanner suppression candidates, flaky-job
    hardening, and stale summary/report issues

    - Out: implementing every resulting fix in one slice; this task is to review,
    classify, and create the actionable queue

    '
- id: C-PLATFORM-CI-FRONTEND-E2E-STACK-REVAMP-001
  title: Rework frontend_e2e CI stack to remove brittle local-dev compose assumptions
  role: C-ops
  status: done
  priority: 946
  owner: Codex
  branch: agent/C-ops
  completed_at: '2026-04-27'
  commit: 3c3c37e8
  depends_on:
  - C-PLATFORM-CI-RUNTIME-IMAGE-MODEL-DOCS-001
  acceptance_checks:
  - rg -q "frontend_e2e|GPUAAS_WORKSPACE_DIR|compose config|CI-specific stack|workspace
    mount" scripts/ci doc/operations
  - make queue-git-check
  notes: 'Context:

    `frontend_e2e` is still repeatedly failing on `master` because the CI job is reusing
    the local-dev compose stack too literally. The recurring failure mode is that
    app containers come up with an empty `/workspace`, then `go run` fails with `go.mod
    file not found`, and the job surfaces later as an opaque Keycloak/app readiness
    timeout.


    Why this is now a revamp task:

    - repeated one-off fixes have not removed the underlying coupling between CI and
    local-dev compose assumptions - environment resolution is still split across shell
    exports, `.env.local`, compose interpolation, and `make` wrappers - the failure
    should become impossible or at least fail immediately with explicit configuration
    diagnostics


    Required outcome:

    - define a CI-specific frontend e2e stack model instead of depending on ambiguous
    local-dev mount/env behavior - make workspace resolution explicit and deterministic
    for all app containers - add early config/render validation so bad mounts fail
    before startup waits - document what should be shared with local-dev and what
    should intentionally differ in CI


    Scope:

    - In: frontend e2e stack/environment model, compose/env resolution cleanup, fast-fail
    diagnostics, and any needed CI-specific compose/script path changes - Out: unrelated
    Playwright test-content changes or UI feature work

    '
- id: C-PLATFORM-CONTROL-VAULT-OPS-HARDENING-001
  title: Harden persistent platform-control Vault operations and replace root-token
    runtime usage
  role: C-ops
  status: todo
  priority: 946
  owner: ''
  branch: agent/C-ops
  completed_at: ''
  commit: ''
  depends_on: []
  acceptance_checks:
  - rg -q "root token|unseal key|operational token|kv/" doc/operations/runbooks/Vault_Bootstrap_and_Root_Token_Runbook.md
  - rg -q "Vault bootstrap|operational-token evidence|root-token" doc/operations/evidence/secrets_key_ops.md
  - make queue-git-check
  notes: 'Context:

    The platform-control Vault migration from dev-mode to persistent file-backed storage
    required manual init/unseal and exposed that the generated root token was temporarily
    used to complete runtime bootstrap. That is acceptable as break-glass/bootstrap
    material, but it should not remain the normal runtime credential model.


    Required outcome:

    - document and validate the persistent Vault bootstrap/unseal flow - escrow unseal/root
    material in the intended operator path - replace routine runtime/root-token usage
    with the intended limited-scope operational token or policy - verify restart recovery,
    `kv/` mount availability, and baseline secret readability after the cutover


    Scope:

    - In: Vault bootstrap/unseal/root-token operational policy, runbook hardening,
    operational-token replacement, and evidence capture - In: platform-control-specific
    validation that persistent Vault survives restart and still serves registry/MAAS
    secret paths - Out: general secret-manager redesign beyond platform-control Vault
    operations

    '
- id: C-LOCAL-DEV-KIND-PARITY-001
  title: Add local kind parity path alongside compose development flow
  role: C-ops
  status: done
  priority: 947
  owner: Codex
  branch: agent/C-ops
  completed_at: '2026-04-27'
  commit: 25a12fd5
  depends_on: []
  acceptance_checks:
  - rg -q "kind|compose|parity|local developer parity" doc/operations/local-dev/README.md
    doc/operations/Local_Parity_Mode_Inventory_v1.md
  - make queue-git-check
  notes: 'Context:

    Local development is currently strongest at the docker-compose layer, but recent
    rollout and runtime failures repeatedly proved that platform-control correctness
    depends on Kubernetes-shaped behavior: ingress/routing, config injection, health/readiness
    boundaries, rollout sequencing, and runtime topology. Compose should remain the
    fast inner loop, but it should stop being the only supported local model for parity-sensitive
    work.


    Required outcome:

    - define two explicit local modes: fast compose development and local kind parity
    - document what parity-sensitive checks must run on kind before platform-control
    deploy work - provide reproducible scripts/manifests to stand up, validate, tear
    down, and rebuild the kind environment - make the intended relationship between
    local-dev, kind parity, and shared platform-control explicit


    Scope:

    - In: kind-based local parity model, scripts/runbooks, validation path, and documented
    boundary versus compose - In: enough automation that operators and developers
    can rebuild the kind environment without hidden manual repair steps - Out: replacing
    compose as the default feature-development loop - Out: vm-105 environment-factory
    automation, GitOps redesign, or remote rebuild automation - Out: fully solving
    production environment factory work in the same slice

    '
- id: C-FRONTEND-E2E-MODEL-REDESIGN-001
  title: Redesign frontend e2e validation model after kind parity to reduce harness
    brittleness
  role: C-ops
  status: done
  priority: 947
  owner: Codex
  branch: agent/C-ops
  completed_at: '2026-04-27'
  commit: 74e11c72
  depends_on:
  - C-LOCAL-DEV-KIND-PARITY-001
  - C-PLATFORM-CI-FRONTEND-E2E-STACK-REVAMP-001
  acceptance_checks:
  - rg -q "frontend e2e|Playwright|kind parity|harness failures|product failures"
    doc/operations/Local_Parity_Mode_Inventory_v1.md doc/governance
  - make queue-git-check
  notes: 'Context:

    Recent frontend e2e work fixed several concrete owners, but the lane is still
    too brittle because it is trying to prove too many things at once: browser workflows,
    auth/session behavior, local-dev/CI stack wiring, compose versus deploy topology
    assumptions, and runtime readiness. Even after stack hardening, failures can still
    oscillate between harness drift and real product regressions, which makes the
    lane expensive to trust and maintain.


    Why this is a separate follow-up after kind parity:

    - local kind parity should first make the environment model explicit instead of
    leaving Playwright to discover environment drift indirectly - once parity-sensitive
    runtime checks have a clearer home, frontend e2e can be narrowed to the browser
    flows that actually require it - continued one-off Playwright fixes without rethinking
    lane boundaries are likely to repeat the same instability under new symptoms


    Required outcome:

    - define what frontend e2e is supposed to prove versus what should move to Vitest,
    parity checks, or release validation - separate harness failures from product
    failures in scripts, logs, and artifacts so the owner is obvious - reduce Playwright
    coverage to intentional browser/runtime workflows instead of using it as a catch-all
    integration lane - document the execution model for local runs, CI runs, and release
    validation so new tests land in the right layer by default


    Scope:

    - In: frontend e2e ownership model, lane boundaries, harness/product failure separation,
    and follow-on queue/doc updates - Out: solving all individual app/UI regressions
    in the same slice

    '
- id: C-AGENT-QUEUE-STRUCTURED-STORE-001
  title: Replace fragile YAML queue editing with a structured local queue store and
    archive bridge
  role: C-ops
  status: todo
  priority: 947
  owner: ''
  branch: agent/C-ops
  completed_at: ''
  commit: ''
  depends_on: []
  acceptance_checks:
  - rg -q "structured store|SQLite|archive bridge|Agent_Work_Queue" doc/governance
  - make queue-git-check
  notes: 'Context:

    Recent queue maintenance exposed the limits of the live YAML queue as an execution
    surface: missing metadata fields, stale dependency references, validator friction,
    and increasing risk when multiple planning updates touch the same file. The archive
    README already says the long-term answer is a structured task store, but there
    is no explicit task yet to define or implement that move.


    Required outcome:

    - define the target structured queue model, with SQLite as the default local implementation
    unless a stronger alternative is justified - preserve git-reviewable export and
    archive snapshots so queue history remains repo-visible - define how current tools
    (`agent_queue_validate.sh`, `agent_queue_git_consistency.sh`, `agent_queue.sh`,
    orchestrator commands) map to the new store - define migration and rollback rules
    so the queue authority does not become ambiguous during transition


    Scope:

    - In: design and follow-on implementation plan for a structured queue source of
    truth plus YAML/archive interoperability - Out: rebuilding the entire agent orchestration
    model in the same slice

    '
- id: C-AGENT-ORCHESTRATOR-V2-COORDINATED-EXECUTION-001
  title: Define coordinated multi-agent orchestrator v2 execution model
  role: C-ops
  status: done
  priority: 948
  owner: C
  branch: agent/C-ops
  completed_at: '2026-05-05'
  commit: 55a6e67f
  depends_on: []
  acceptance_checks:
  - test -f doc/governance/Agent_Orchestrator_v2_Coordinated_Execution.md
  - rg -q "ready -> claimed|needs_review|merge-ready|human-gated|handoff|review routing|session adapter" doc/governance/Agent_Orchestrator_v2_Coordinated_Execution.md
  - rg -q "C-AGENT-ORCHESTRATOR-V2" doc/governance/Agent_Work_Queue.yaml
  - bash scripts/ci/agent_queue_validate.sh
  - make queue-git-check
  notes: 'Context:

    GPUaaS is now running repeated A-backend/B-ui/C-ops/D-arch/E-governance
    coordination manually: humans approve architecture, agents work in role
    worktrees, handoffs are prose, reviews are manual overlays, and merges depend
    on a human remembering each branch/task state. Existing docs already define
    the queue store, lane worktrees, review lanes, and orchestrator v1 status/tick
    model, but there is no single v2 execution contract that turns those pieces
    into a dependency-aware coordinator loop.


    Required outcome:

    - create doc/governance/Agent_Orchestrator_v2_Coordinated_Execution.md that
    defines the post-human-signoff operating model: task pack decomposition,
    coordinator authority boundaries, role/lane assignment, agent launch/resume,
    evidence capture, review routing, merge-ready gates, and human-gated release
    promotion.
    - define the coordinator state machine explicitly, including ready -> claimed
    -> running -> needs_review -> changes_requested -> verified -> merged -> done,
    with blocked and failed escape paths.
    - specify how the v2 model builds on Agent_Queue_Structured_Store_v1.md,
    Multi_Agent_Lane_Worktrees_v1.md, Multi_Agent_Review_Model.md, and existing
    orchestrator commands without making live SQLite/git authority ambiguous.
    - split implementation into follow-on queue tasks small enough to delegate:
    queue state hardening, handoff/review/evidence tables, dispatch/session
    adapter, review router, merge-ready command, and operator runbook.
    - call out extraction boundaries so the repo-local implementation can later
    become a reusable product/CLI without baking GPUaaS-specific roles into core
    logic.


    Scope:

    - In: governance/design spec, executable follow-on task breakdown, acceptance
    gates, product extraction boundaries, and risk controls.
    - Out: implementing auto-dispatch, unattended merge, or release promotion in
    this slice. Implementation tasks should depend on the queue structured-store
    foundation where appropriate.

    '
- id: C-AGENT-QUEUE-STATE-HARDENING-001
  title: Harden queue SQLite state path and validation layers for orchestrator v2
  role: C-ops
  status: done
  priority: 947
  owner: codex
  branch: agent/C-ops
  completed_at: '2026-05-05'
  commit: 7d5c06a9
  depends_on:
  - C-AGENT-ORCHESTRATOR-V2-COORDINATED-EXECUTION-001
  acceptance_checks:
  - bash scripts/ci/agent_queue_validate.sh
  - make orchestrator-status
  - make queue-git-check
  notes: 'Context:

    Agent_Orchestrator_v2_Coordinated_Execution.md identifies queue state hardening
    as the first implementation slice. Current queue commands can still fail from
    stale local SQLite state, read-only/default DB path drift, and mixed definition
    vs execution-state validation. The coordinator cannot own dispatch or merge
    gates until the queue store has deterministic local behavior.


    Required outcome:

    - make the default queue DB path writable and deterministic across coordinator
    and lane worktrees.
    - split queue validation behavior into definition validation, state validation,
    and YAML/SQLite cross-reference validation, matching
    Agent_Queue_Structured_Store_v1.md.
    - add a cleanup/prune path for stale state rows that reference removed task ids
    without requiring manual SQLite edits.
    - document rollback guidance for YAML-only recovery if the SQLite state store
    is corrupt or unavailable.


    Scope:

    - In: queue/orchestrator scripts, local queue DB path handling, validation
    behavior, stale-state cleanup, and governance docs.
    - Out: auto-dispatch, review enforcement, and merge-ready automation.

    '
- id: A-AGENT-QUEUE-EVIDENCE-TABLES-001
  title: Add structured handoff review and evidence records to the agent queue store
  role: A-backend
  status: done
  priority: 946
  owner: codex
  branch: agent/A-backend
  completed_at: '2026-05-05'
  commit: 7d5c06a9
  depends_on:
  - C-AGENT-QUEUE-STATE-HARDENING-001
  acceptance_checks:
  - ruby scripts/ops/agent_queue_store.rb --queue-file doc/governance/Agent_Work_Queue.yaml validate
  - ruby scripts/ops/agent_queue_store.rb --queue-file doc/governance/Agent_Work_Queue.yaml status-report
  - rg -q "handoff|review|evidence" scripts/ops doc/governance
  - make queue-git-check
  notes: 'Context:

    Orchestrator v2 requires agents to hand off structured evidence before review
    or merge. Today evidence is prose in chat handoffs and queue notes, so the
    coordinator cannot reliably tell which commands passed, which files changed,
    which review findings were resolved, or what residual risk remains.


    Required outcome:

    - add SQLite schema and queue-store commands for handoff, review, and evidence
    records.
    - preserve existing queue commands and YAML task definitions.
    - support exact command/result capture, changed-file lists, commit SHA,
    residual risk, blocker, and next-slice fields.
    - export readable handoff snapshots for archive/review boundaries.


    Scope:

    - In: queue-store schema/tooling and docs for handoff/review/evidence records.
    - Out: launching agents, enforcing review routing, or merging branches.

    '
- id: C-AGENT-DISPATCH-SESSION-ADAPTER-001
  title: Add non-destructive session adapter for orchestrator v2 role lanes
  role: C-ops
  status: done
  priority: 945
  owner: codex
  branch: agent/C-ops
  completed_at: '2026-05-05'
  commit: 7d5c06a9
  depends_on:
  - A-AGENT-QUEUE-EVIDENCE-TABLES-001
  acceptance_checks:
  - bash scripts/ops/setup_agent_lanes.sh --help
  - bash scripts/ops/launch_agent_lanes.sh --help
  - rg -q "session adapter" doc/governance/Agent_Orchestrator_v2_Coordinated_Execution.md scripts/ops
  - make queue-git-check
  notes: 'Context:

    The coordinator needs a safe way to start or resume agents in the correct
    worktree without relying on ad hoc terminal memory. Orchestrator v2 treats
    tmux, Zellij, or shell execution as replaceable session adapters, with role
    names and lane paths coming from repository configuration rather than hardcoded
    product logic.


    Required outcome:

    - add a session adapter interface or command contract for create/resume/status
    operations.
    - implement launch/resume/status for existing lane worktrees using the repository
    current shell/Zellij/tmux preference.
    - capture transcript/log pointers where practical.
    - preflight branch, directory, dependency, and unrelated-modification checks
    before launching work.
    - keep all launch/interrupt behavior non-destructive by default.


    Scope:

    - In: scripts/ops session adapter commands, help text, preflight checks, and
    docs.
    - Out: automatic merge, release promotion, and unattended infinite loops.

    '
- id: C-AGENT-REVIEW-ROUTER-001
  title: Route required D-arch and E-governance reviews from changed-file scope
  role: C-ops
  status: done
  priority: 944
  owner: codex
  branch: agent/C-ops
  completed_at: '2026-05-05'
  commit: 7d5c06a9
  depends_on:
  - A-AGENT-QUEUE-EVIDENCE-TABLES-001
  acceptance_checks:
  - bash scripts/ci/agent_queue_validate.sh
  - rg -q "review routing|D-arch|E-governance|no self-approval" scripts/ops doc/governance
  - make queue-git-check
  notes: 'Context:

    Multi_Agent_Review_Model.md defines D/E review lanes, and orchestrator v2
    makes review routing a merge gate for critical scopes. The rule is still
    mostly manual: contributors know when a change is sensitive, but the queue
    store does not consistently populate review metadata or block done when
    critical reviews are missing.


    Required outcome:

    - implement changed-file based review routing for doc/api, doc/architecture,
    doc/governance, scripts/ci, security/auth/billing/provisioning/terminal,
    node-agent, and release-runtime paths.
    - populate review-required metadata in the queue store.
    - enforce no-self-approval for critical scopes, with explicit exception notes
    when review diversity is unavailable.
    - block done/merge-ready when required review evidence is missing.


    Scope:

    - In: review routing policy, queue-store validation, and docs.
    - Out: implementing the full merge-ready command or dispatch session adapter.

    '
- id: C-AGENT-MERGE-READY-COMMAND-001
  title: Add explicit merge-ready gate for orchestrator v2 coordinator merges
  role: C-ops
  status: done
  priority: 943
  owner: codex
  branch: agent/C-ops
  completed_at: '2026-05-05'
  commit: 7d5c06a9
  depends_on:
  - C-AGENT-REVIEW-ROUTER-001
  - C-AGENT-DISPATCH-SESSION-ADAPTER-001
  acceptance_checks:
  - make queue-git-check
  - rg -q "merge-ready" scripts/ops doc/governance
  - rg -q "fast-forward|origin/master|acceptance" scripts/ops doc/governance
  notes: 'Context:

    Manual coordinator merges are currently effective but fragile: the human must
    remember branch freshness, exact acceptance checks, queue state, generated
    artifacts, review evidence, and merge ordering. Orchestrator v2 needs a
    command that verifies all of that before a coordinator merge to master.


    Required outcome:

    - add an explicit merge-ready command that verifies acceptance checks,
    evidence records, required reviews, branch freshness, generated artifacts,
    scope fit, and queue/git consistency.
    - require fast-forward-safe merge semantics or a documented blocked state when
    conflicts/dependency order prevent safe merge.
    - record merged commit and done metadata only after the commit is reachable
    from origin/master.
    - keep release/platform-control promotion out of this command.


    Scope:

    - In: merge-ready verification command, queue-store integration, docs.
    - Out: automatic release promotion and unattended continuous dispatch loops.

    '
- id: C-AGENT-ORCHESTRATOR-V2-RUNBOOK-001
  title: Write the operator runbook for orchestrator v2 coordinated execution
  role: C-ops
  status: done
  priority: 942
  owner: codex
  branch: agent/C-ops
  completed_at: '2026-05-05'
  commit: 7d5c06a9
  depends_on:
  - C-AGENT-MERGE-READY-COMMAND-001
  acceptance_checks:
  - test -f doc/operations/runbooks/Agent_Orchestrator_v2_Runbook.md
  - rg -q "human-gated|blocked path|review path|merge-ready|release promotion" doc/operations/runbooks/Agent_Orchestrator_v2_Runbook.md
  - make queue-git-check
  notes: 'Context:

    Once queue hardening, evidence records, review routing, session dispatch, and
    merge-ready gates exist, operators need one runbook for using the coordinated
    execution loop safely. The runbook must keep release promotion human-gated
    and make blocked/recovery paths explicit.


    Required outcome:

    - add doc/operations/runbooks/Agent_Orchestrator_v2_Runbook.md.
    - cover normal post-signoff task-pack flow, blocked path, failed-agent path,
    review path, merge-ready path, and release-promotion handoff.
    - include rollback guidance for queue DB failure and role worktree drift.
    - call out which steps remain human-authority decisions.


    Scope:

    - In: operator runbook and references to the v2 spec/tooling.
    - Out: new automation beyond documenting the implemented flow.

    '
- id: A-APP-PLATFORM-IAM-COMPLETION-001
  title: Complete backend IAM and authz path required for app platform operator use
  role: A-backend
  status: done
  priority: 947
  owner: A
  branch: agent/A-backend
  completed_at: '2026-04-28'
  commit: 7aad1c9e
  depends_on: []
  acceptance_checks:
  - bash scripts/ci/contracts_validate.sh
  - go test ./cmd/api ./packages/services/auth ./packages/services/admin ./packages/services/provisioning/worker
  - make queue-git-check
  notes: 'Context:

    App-platform capabilities now have enough real surface area that other developers
    want to use them, but IAM/authz completion is still uneven across membership,
    entitlement, service-account, and project-scoped access paths. The risk is not
    only missing screens; it is backend drift where app-platform flows work only for
    one bootstrap role shape or bypass the intended IAM model under pressure.


    Required outcome:

    - inventory the current app-platform IAM path end-to-end: project membership,
    tenant membership, app entitlements, service-account access, and audit coverage
    - close backend authz and contract gaps that prevent normal operator/dev use of
    the app platform - make app-platform routes and runtime flows rely on the intended
    IAM model rather than bootstrap shortcuts or implicit admin assumptions - document
    the remaining explicit out-of-scope IAM gaps rather than leaving them as accidental
    behavior


    Scope:

    - In: backend IAM/authz enforcement, contract additions if needed, audit coverage,
    and regression tests for app-platform flows - Out: broad UI information architecture
    redesign in the same slice

    '
- id: B-APP-PLATFORM-IAM-UX-COMPLETION-001
  title: Complete IAM and entitlement UX needed to operate the app platform
  role: B-ui
  status: todo
  priority: 947
  owner: ''
  branch: agent/B-ui
  completed_at: ''
  commit: ''
  depends_on:
  - A-APP-PLATFORM-IAM-COMPLETION-001
  acceptance_checks:
  - make verify-web
  - make queue-git-check
  notes: 'Context:

    The platform already has IAM and app-platform architecture direction, but developers
    trying to use the app platform should not need deep backend knowledge to discover
    who can do what, where entitlements are managed, or why an action is denied. The
    UI needs to make the intended IAM model usable, not merely documented.


    Required outcome:

    - align app-platform operator flows with the reviewed IAM information architecture
    - make entitlement, membership, and service-account surfaces discoverable enough
    for real app-platform use - remove or clearly label bootstrap/debug-only affordances
    that look like supported operator workflows - add UI/e2e coverage for the intended
    role-based app-platform flows


    Scope:

    - In: IAM/app-platform UI completion, discoverability, actionable errors, and
    test coverage - Out: unrelated visual redesign or non-IAM app runtime feature
    expansion

    '
- id: A-APP-PLATFORM-DSTACK-CONTRACT-VALIDATION-001
  title: Validate dstack-style scheduler integration against App Platform contracts
    and capture the required core gaps
  role: A-backend
  status: todo
  priority: 948
  owner: ''
  branch: agent/A-backend
  completed_at: ''
  commit: ''
  depends_on:
  - A-APP-PLATFORM-IAM-COMPLETION-001
  - A-APP-RUNTIME-ADAPTER-SLURM-001
  acceptance_checks:
  - rg -q "dstack|scheduler app|internal and external apps use the same contracts|allocation-group|gang
    scheduling" doc/architecture
  - make queue-git-check
  notes: 'Context:

    A recent readiness assessment concluded that dstack can likely operate as a first-class
    app on GPUaaS because the platform already treats internal and external apps through
    the same App Platform contracts. That needs to be validated explicitly against
    the reviewed contracts and current implementation slices rather than left as a
    one-off report.


    Required outcome:

    - validate that a dstack-style scheduler can use the App Platform APIs and service-account
    model without hidden internal-app bypasses - separate what is already covered
    by the existing Slurm reference-adapter work from what is truly dstack-specific
    - capture the remaining platform-owned missing primitives as explicit follow-on
    tasks rather than letting them stay implicit in an assessment - document the recommended
    boundary: platform owns lifecycle/IAM/billing/audit, scheduler app owns job orchestration
    and runner management


    Scope:

    - In: contract and implementation-gap review for dstack-style integration, explicit
    gap capture, and architecture/backlog updates - Out: implementing a full dstack
    adapter in the same slice

    '
- id: A-ALLOCATION-GROUP-GANG-SCHEDULING-001
  title: Define allocation-group and gang-scheduling primitive for multi-node scheduler
    workloads
  role: A-backend
  status: todo
  priority: 949
  owner: ''
  branch: agent/A-backend
  completed_at: ''
  commit: ''
  depends_on: []
  acceptance_checks:
  - make codegen
  - bash scripts/ci/contracts_validate.sh
  - make queue-git-check
  notes: 'Context:

    The current allocation model is node-at-a-time. That is sufficient for single-node
    app and user flows, but scheduler-style workloads such as distributed training
    need an explicit multi-node primitive with all-or-nothing semantics rather than
    an application stitching together unrelated single allocations with partial-failure
    ambiguity.


    Required outcome:

    - define whether the platform should expose an allocation-group resource or another
    equivalent gang-scheduling primitive - make the all-or-nothing semantics, partial-failure
    behavior, billing anchor, and lifecycle states explicit - define the boundary
    between platform placement guarantees and scheduler-app orchestration responsibilities
    - capture how cross-node identity, audit, and observability should work for grouped
    allocations


    Scope:

    - In: contract and lifecycle design for multi-node allocation groups and gang
    scheduling - Out: implementing a production distributed-training scheduler in
    the same slice

    '
- id: A-GPU-PARTITION-MODEL-001
  title: Define GPU partition and MIG-style allocation model without weakening whole-node
    baseline
  role: A-backend
  status: todo
  priority: 950
  owner: ''
  branch: agent/A-backend
  completed_at: ''
  commit: ''
  depends_on: []
  acceptance_checks:
  - make codegen
  - bash scripts/ci/contracts_validate.sh
  - make queue-git-check
  notes: 'Context:

    Scheduler and app-platform workloads may need to place multiple jobs on one GPU
    host through MIG or similar partitioning. The current platform contract is whole-node
    oriented. Before any implementation work, the platform needs an explicit resource
    and billing model for partitioned GPU capacity so later support does not arrive
    as ad hoc exceptions.


    Required outcome:

    - define how GPU partitions map into catalog, placement, identity, and billing
    contracts - preserve the existing whole-node allocation baseline until the partition
    model is reviewed and explicit - document what runtime backends may assume about
    partition discoverability and isolation


    Scope:

    - In: contract/schema/design baseline for GPU partitions or MIG-like slices -
    Out: immediate runtime implementation for every GPU vendor

    '
- id: A-ALLOCATION-PREEMPTION-MODEL-001
  title: Define spot and preemption semantics for allocations and scheduler-backed
    workloads
  role: A-backend
  status: todo
  priority: 951
  owner: ''
  branch: agent/A-backend
  completed_at: ''
  commit: ''
  depends_on: []
  acceptance_checks:
  - make codegen
  - bash scripts/ci/contracts_validate.sh
  - make queue-git-check
  notes: 'Context:

    Some scheduler and app-platform use cases assume spot/preemptible capacity and
    explicit eviction behavior. The current platform does not model priority, eviction,
    or preemption semantics. Those behaviors need a reviewed lifecycle and billing
    model before any app integration depends on them.


    Required outcome:

    - define whether allocations can be preemptible, what events or warning windows
    are required, and how billing reconciles after eviction - define the boundary
    between platform-owned preemption semantics and scheduler-app retry/recovery semantics
    - capture required observability and audit signals for preempted workloads


    Scope:

    - In: platform-level preemption/spot model and follow-on contract gaps - Out:
    implementing a market/pricing engine for spot capacity in the same slice

    '
- id: B-ADMIN-NODE-REMOVE-TASK-VISIBILITY-001
  title: Expose remove-node lifecycle task progress and details in the admin UI
  role: B-ui
  status: todo
  priority: 952
  owner: ''
  branch: agent/B-ui
  completed_at: ''
  commit: ''
  depends_on: []
  acceptance_checks:
  - rg -q "removing|node.uninstall|recovery_action|task" packages/web/app/admin/nodes
  - make verify-web
  - make queue-git-check
  notes: 'Context:

    Removing a retired node is asynchronous and currently leaves the operator with
    very little visibility after clicking remove. During the recent production incident,
    the node moved into `removing` and only backend logs or direct task inspection
    explained whether uninstall had started, failed, or was still waiting on the node
    agent. That makes normal operator triage slower than it should be.


    Required outcome:

    - show the current remove/uninstall lifecycle state in the admin nodes experience
    once remove is requested - expose enough task detail for operators to distinguish
    queued, dispatched, completed, failed, and retry/requeue states - surface correlation/task
    identifiers or a direct drill-down path so operators can move from UI to logs
    without guessing


    Scope:

    - In: admin UI/read-model support for remove-node task visibility and operator
    drill-down - Out: redesigning the full node lifecycle UX in the same slice

    '
- id: A-SLURM-REFERENCE-PLATFORM-CONTROL-DEPLOYMENT-001
  title: Add durable platform-control deployment and validation path for slurm-reference-controller
  role: A-backend
  status: todo
  priority: 953
  owner: ''
  branch: agent/A-backend
  completed_at: ''
  commit: ''
  depends_on: []
  acceptance_checks:
  - rg -q "slurm-reference-controller" infra/k8s
  - rg -q "slurm-reference-controller|deploying" doc/operations/runbooks/Slurm_Reference_Deploying_Stuck_Runbook.md
  - make queue-git-check
  notes: 'Context:

    The first platform-control Slurm instance bound its controller allocation successfully
    but stayed in `deploying` because no durable `slurm-reference-controller` was
    running in that environment. Manual controller execution then exposed that controller
    SSH transport was also preferring `hostname` over the reachable `host`, but the
    owning control-plane gap was still the missing deployment path.


    Required outcome:

    - add platform-control deployment wiring for `slurm-reference-controller` - define
    how project/app-instance scope is supplied to the controller in platform-control
    without ad hoc shell steps - add validation so platform-control cannot claim Slurm
    readiness unless the controller is deployed and reconciling


    Scope:

    - In: platform-control runtime deployment shape, env/secret contract, and environment
    validation for the Slurm reference controller - Out: redesigning the clustered
    Slurm runtime model in the same slice

    '
- id: B-IMAGE-LAUNCH-UX-ALIGNMENT-001
  title: Align launch and admin image UX with curated MAAS host and slice guest image
    model
  role: B-ui
  status: todo
  priority: 954
  owner: ''
  branch: agent/B-ui
  completed_at: ''
  commit: ''
  depends_on:
  - B-UI-NIGHT-PASS-001
  acceptance_checks:
  - rg -q "image|driver strategy|preinstalled|cloud-init|CUDA" packages/web/app/launch
    packages/web/src/components/launch
  - rg -q "compatible SKUs|source URI|digest|validation" packages/web/app/admin/os-images
  - pnpm --dir packages/web exec vitest run src/components/launch/launch-wizard.test.tsx
    app/admin/os-images/page.test.tsx app/allocations/page.test.tsx app/workloads/page.test.tsx
  - make verify-web
  - ruby scripts/ops/agent_queue_store.rb --queue-file doc/governance/Agent_Work_Queue.yaml
    validate
  - make queue-git-check
  notes: 'Context:

    The platform is moving from heavy first-boot package installs toward curated images.
    Users need the launch flow and admin surfaces to explain the difference between
    a MAAS host image, a slice guest image, and driver strategy (`preinstalled` versus
    `cloud-init`) without exposing raw backend rows. If the UI stays ambiguous, users
    will not know why a launch is fast or slow, and admins will not know which images
    are safe to make active.


    Pre-read (required):

    - doc/product/UX_Redesign_Implementation_Plan.md

    - doc/product/UI_Night_Pass_B_Handoff.md

    - doc/architecture/MAAS_Provisioning_Time_Optimization_v1.md

    - doc/architecture/Allocation_Capacity_Shapes_and_GPU_Slices_v1.md

    - doc/operations/runbooks/GPU_Slice_Image_Pipeline_Runbook.md

    - packages/web/app/launch/page.tsx

    - packages/web/src/components/launch/launch-wizard.tsx

    - packages/web/app/admin/os-images/page.tsx

    - packages/web/app/allocations/page.tsx

    - packages/web/app/workloads/page.tsx


    Invariants (must not break):

    - Rebase `agent/B-ui` from `origin/master` before starting; do not work from the
    pre-merge night-pass branch.

    - Do not change OpenAPI, backend Go code, MAAS scripts, image build scripts, or
    seed data in this task.

    - Keep launch wizard behavior consistent with the v3 flow and existing tests.

    - Treat MAAS host image selection as profile/admin infrastructure state, not a
    user launch-time field.

    - Treat slice guest image selection as a launch/product choice, with clear `preinstalled`
    versus `cloud-init` copy.

    - Keep controls uniform with `StatusTabs`, `FilterBar`, `ProductPage`, and existing
    workbench patterns.


    Scope:

    - In: improve `/launch` copy/step state for image choices and future curated image
    selection.

    - In: make admin OS Images more product-oriented: status, compatible SKUs, source
    URI/digest, driver strategy, validation/readiness state, and clear active/disabled
    semantics.

    - In: surface selected image/provisioning mode in allocation/workload list/detail
    where the current API data already provides it or where a safe placeholder is
    needed.

    - In: add UX copy that distinguishes MAAS host image from slice guest image.

    - Out: backend contract changes, MAAS image build/upload automation, direct DB
    work, changing provisioning semantics, or adding new API fields.


    Deliverables:

    - packages/web/app/launch/page.tsx and/or packages/web/src/components/launch/launch-wizard.tsx
    updated with image/provisioning-mode UX.

    - packages/web/app/admin/os-images/page.tsx updated to present curated image lifecycle/readiness
    clearly.

    - Relevant tests updated or added for launch image copy, admin OS image fields,
    and no-regression allocation/workload rendering.

    - Short handoff note in `doc/product/` or task handoff explaining remaining backend/API
    gaps for full image selection if any are discovered.


    Evidence required in handoff:

    - files changed

    - commit SHA

    - exact acceptance commands run

    - pass/fail status by command

    - screenshots or concise text summary of launch wizard and admin OS Images behavior
    after the change

    '
- id: B-SHARED-COMPONENT-FOUNDATION-001
  title: Build shared v3 component foundation — unify product and admin component
    systems
  role: B-ui
  status: done
  priority: 3
  owner: B
  branch: agent/B-ui
  completed_at: '2026-04-21'
  commit: 76478a5f
  depends_on:
  - B-UI-NIGHT-PASS-001
  acceptance_checks:
  - sh -lc 'test -f packages/web/src/components/product/timeline.tsx'
  - sh -lc 'test -f packages/web/src/components/product/alert-banner.tsx'
  - rg -q "DataTable" packages/web/app/allocations/page.tsx packages/web/app/workloads/page.tsx
  - pnpm --dir packages/web test --no-coverage
  - make verify-web
  - ruby scripts/ops/agent_queue_store.rb --queue-file doc/governance/Agent_Work_Queue.yaml
    validate
  - make queue-git-check
  notes: "Context:\nThe product and admin page systems use parallel component families\
    \ that do the same thing differently. Product pages use hand-coded raw tables,\n\
    ProductSummaryStrip for KPIs, and no drawers. Admin pages use DataTable (TanStack\
    \ Table), KpiStrip, and DetailDrawer. The v3 redesign requires\nthese to converge\
    \ so all workbench pages share one table, one KPI strip, one drawer, and one timeline\
    \ pattern.\n\nScope — 5 shared components to build or unify:\n\n1. Promote DataTable\
    \ from components/admin/ to components/product/ (or a shared location). Update\
    \ allocations and workloads pages to use\n   DataTable instead of hand-coded raw\
    \ tables. Keep TanStack Table underneath.\n\n2. Merge KpiStrip and ProductSummaryStrip\
    \ into one component. Both show label+value tiles with tone colors. Pick one API\
    \ shape, deprecate\n   the other, update all consumers.\n\n3. Build Timeline component\
    \ at components/product/timeline.tsx. Vertical event list with dot status indicators\
    \ (done/active/pending/failed).\n   Used by allocation events, app deploy progress,\
    \ node onboarding, MAAS decommission.\n\n4. Build AlertBanner component at components/product/alert-banner.tsx.\
    \ Top-of-page alert with variant (warning/danger/info), message, and\n   actions\
    \ slot. Used by control room budget alerts, allocation degradation warnings, billing\
    \ overspend.\n\n5. Promote DetailDrawer from components/admin/ to shared. Make\
    \ it available for product detail pages (allocation detail, workload detail).\n\
    \nOut of scope: Sparkline, AreaChart, BudgetBar, Heatmap, DeviceTable, SpendChart\
    \ (those need API data that doesn't exist yet). No backend changes.\n\nDeliverables:\n\
    - New or promoted shared components with tests\n- Allocations and workloads pages\
    \ migrated to shared DataTable\n- KPI strip unified across product and admin pages\n\
    - Short handoff note listing what changed and what remains\n"
- id: A-SLICE-GUEST-GPU-METRICS-NETDATA-001
  title: Add slice guest GPU metrics path mediated by node-agent
  role: A-backend
  status: todo
  priority: 955
  owner: ''
  branch: agent/A-backend
  completed_at: ''
  commit: ''
  depends_on: []
  acceptance_checks:
  - rg -q "slice guest GPU metrics|vfio-pci|guest telemetry" doc/architecture doc/operations
  - rg -q "guest_metrics|metrics source|node-agent" doc/api/openapi.draft.yaml cmd/api
    packages/services cmd/node-agent
  - go test ./cmd/api ./cmd/node-agent ./packages/services/provisioning/...
  - ruby scripts/ops/agent_queue_store.rb --queue-file doc/governance/Agent_Work_Queue.yaml
    validate
  - make queue-git-check
  notes: "Context:\nHost Netdata is now standardized in the MAAS H200 host image and\
    \ works for bare-metal nodes where GPUs remain bound to the NVIDIA driver. On\n\
    slice hosts, GPUs are intentionally bound to `vfio-pci` for passthrough, so host\
    \ `nvidia-smi`/NVML cannot report tenant GPU utilization. The\nmetrics API currently\
    \ probes host Netdata directly and therefore cannot show live per-GPU utilization\
    \ for slice allocations.\n\nRequired outcome:\n- keep host Netdata as the source\
    \ for node health, CPU, memory, Docker/cgroup, and bare-metal GPU metrics\n- add\
    \ a slice allocation metrics path that gets guest GPU telemetry through node-agent\
    \ instead of exposing guest Netdata directly\n- return a clear source/status in\
    \ the metrics response so the UI can distinguish `host_netdata`, `slice_guest`,\
    \ and `unavailable`\n- document that direct API-to-guest Netdata proxying is not\
    \ the preferred path because it expands tenant VM network exposure\n\nRecommended\
    \ design:\n- Bare-metal allocation: API continues to read host Netdata.\n- Slice\
    \ allocation: API asks node-agent for guest metrics; node-agent reaches the VM\
    \ over the controlled management path and normalizes GPU\n  utilization, memory\
    \ utilization, and health.\n- Slice guest image: include NVIDIA driver, `nvidia-smi`,\
    \ and either Netdata `nvidia_smi` collector or a small guest-side helper. Keep\
    \ collection\n  bounded and avoid fake graph data.\n- If guest telemetry is not\
    \ installed or unreachable, return `null` metric values with an explicit reason\
    \ instead of falling back to misleading\n  host GPU metrics.\n\nScope:\n- In:\
    \ contract/read-model design, node-agent task or runtime endpoint, API source\
    \ selection, tests, and operational docs.\n- Out: UI graph redesign, direct guest\
    \ network exposure, broad observability stack replacement, or demo-only synthetic\
    \ metrics.\n"
- id: A-OPENCLAW-DEMO-SMOKE-001
  title: Add OpenClaw composed-app demo smoke path using existing OCI and platform-proxy
    primitives
  role: A-backend
  status: todo
  priority: 956
  owner: ''
  branch: agent/A-backend
  completed_at: ''
  commit: ''
  depends_on: []
  acceptance_checks:
  - rg -q "openclaw" scripts/seed.sql packages/web/src/lib/apps doc/architecture/OpenClaw_App_Integration_and_Platform_Composition_v1.md
  - rg -q "platform_proxy" scripts/seed.sql packages/services/appruntime cmd/api/routes.go
  - go test ./packages/services/appruntime ./packages/services/inventory ./cmd/api
  - pnpm --dir packages/web exec vitest run app/apps/instances/'[instanceId]'/page.test.tsx
  - ruby scripts/ops/agent_queue_store.rb --queue-file doc/governance/Agent_Work_Queue.yaml
    validate
  - make queue-git-check
  notes: "Context:\nOpenClaw is already documented as the reference composed app in\
    \ `doc/architecture/OpenClaw_App_Integration_and_Platform_Composition_v1.md`,\n\
    but it is not yet present in seed/catalog data or app UI metadata. The demo needs\
    \ one concrete path that proves app composition intent without\ninventing OpenClaw-specific\
    \ platform code.\n\nRequired outcome:\n- add an `openclaw` or `openclaw-local-llm`\
    \ catalog entry/version backed by the existing launchable OCI manifest model\n\
    - prefer the same-allocation OpenClaw + vLLM compose smoke from the architecture\
    \ doc if the current compose renderer can support it safely\n- otherwise add a\
    \ clearly labeled external-LLM lab smoke entry that can run as a normal OCI workload\
    \ and document why it is not the product\n  milestone\n- expose the OpenClaw web\
    \ endpoint through `platform_proxy` where route reporting is available, and keep\
    \ private/tunnel fallback honest\n- add/adjust web app product metadata so the\
    \ workload detail page names OpenClaw clearly and uses the generic proxy access\
    \ card\n\nScope:\n- In: seed/catalog data, app product metadata, manifest validation\
    \ tests, and a concise demo runbook/handoff.\n- Out: OpenClaw-specific API routes,\
    \ custom scheduler logic, webhook ingress signing, cross-allocation dependency\
    \ picker, or synthetic demo data.\n"
- id: B-DEMO-APP-WORKBENCH-V3-001
  title: Make demo-critical app workbench pages match v3 product table and action
    patterns
  role: B-ui
  status: todo
  priority: 957
  owner: ''
  branch: agent/B-ui
  completed_at: ''
  commit: ''
  depends_on:
  - B-SHARED-COMPONENT-FOUNDATION-001
  acceptance_checks:
  - rg -q "DataTable" packages/web/app/apps/instances/page.tsx packages/web/app/apps/artifacts/page.tsx
  - rg -q "StatusTabs|FilterBar|MoreActions" packages/web/app/apps/instances/page.tsx
    packages/web/app/apps/artifacts/page.tsx
  - rg -q "data-testid=.apps-instances-page|data-testid=.apps-artifacts-page" packages/web/app/apps/instances/page.tsx
    packages/web/app/apps/artifacts/page.tsx
  - pnpm --dir packages/web exec vitest run app/apps/instances/page.test.tsx app/apps/artifacts/page.test.tsx
  - pnpm --dir packages/web typecheck
  - ruby scripts/ops/agent_queue_store.rb --queue-file doc/governance/Agent_Work_Queue.yaml
    validate
  - make queue-git-check
  notes: "Context:\nThe demo story needs the app/workload surfaces to feel like the\
    \ same product as allocations and workloads. `/apps/instances` and\n`/apps/artifacts`\
    \ still look like raw list pages compared with the v3-compliant `/allocations`,\
    \ `/workloads`, `/audit-logs`, `/billing`,\n`/access/quotas`, and `/launch` pages.\n\
    \nBefore claiming:\n- `git fetch origin`\n- `git switch agent/B-ui`\n- `git rebase\
    \ origin/master`\n- then claim this task from the queue.\n\nNormative references:\n\
    - `doc/product/UX_Redesign_Implementation_Plan.md`\n- `doc/product/UX_Implementation_Spec.md`\n\
    - `doc/product/UX_Journeys.md`\n- `doc/product/E2E_Selector_Contract.md`\n- `doc/product/ux-mocks/product-redesign-v3/README.md`\n\
    - `doc/product/ux-mocks/product-redesign-v3/index.html`\n\nRequired outcome:\n\
    - `/apps/instances` uses the shared v3 workbench pattern: `ProductPage`, `ProductPageHeader`,\
    \ KPI/summary strip if useful, `FilterBar`,\n  `StatusTabs`, `DataTable`, and\
    \ `MoreActions`.\n- `/apps/artifacts` uses the same table/filter/action pattern\
    \ where appropriate.\n- Toolbars remain visible when the current filter result\
    \ is empty.\n- Rows have one primary action (`Open` or `View`) and secondary actions\
    \ under `MoreActions`; no clipped menus inside table scroll containers.\n- Status\
    \ filtering behavior is consistent with `/allocations` and `/workloads`.\n- Add\
    \ or preserve stable page-root test IDs and use intent-level assertions in tests.\n\
    \nScope:\n- In: `packages/web/app/apps/instances/page.tsx`, `packages/web/app/apps/artifacts/page.tsx`,\
    \ nearby page tests, shared component usage.\n- Out: app instance detail/proxy\
    \ backend changes, catalog deploy flow rewrites, OpenAPI changes, release branch\
    \ work, and fake/demo-only data.\n\nHandoff required:\n- files changed\n- screenshots\
    \ or concise text summary of `/apps/instances` and `/apps/artifacts`\n- exact\
    \ validation commands and pass/fail status\n- remaining visual/product gaps, if\
    \ any\n"
- id: B-DEMO-CONTEXT-RESOURCE-CLI-UX-001
  title: Add demo-ready context hierarchy and CLI quickstart surfaces using existing
    data
  role: B-ui
  status: todo
  priority: 958
  owner: ''
  branch: agent/B-ui
  completed_at: ''
  commit: ''
  depends_on:
  - B-SHARED-COMPONENT-FOUNDATION-001
  acceptance_checks:
  - rg -q "Current context|Resource hierarchy|Org|Project|Region|CLI" packages/web/app/settings/profile
    packages/web/app/developer packages/web/src/components
  - rg -q "gpuaas auth login|gpuaas projects list|gpuaas allocations" packages/web/app/developer
    packages/web/app/docs packages/web/src/components
  - pnpm --dir packages/web typecheck
  - pnpm --dir packages/web test --no-coverage
  - ruby scripts/ops/agent_queue_store.rb --queue-file doc/governance/Agent_Work_Queue.yaml
    validate
  - make queue-git-check
  notes: "Context:\nThe platform has a real hierarchy (user, org/workspace, project,\
    \ region, resources, canonical resource names), but the demo currently exposes\
    \ it\ninconsistently. We also need a lightweight CLI story to show that GPUaaS\
    \ is API-first and automatable, not only a web UI.\n\nBefore claiming:\n- `git\
    \ fetch origin`\n- `git switch agent/B-ui`\n- `git rebase origin/master`\n- then\
    \ claim this task from the queue.\n\nNormative references:\n- `doc/product/UX_Redesign_Implementation_Plan.md`\
    \ detail-page and shell/context sections\n- `doc/product/E2E_Selector_Contract.md`\n\
    - `doc/architecture/App_UI_Extension_Model_v1.md`\n- `cmd/gpuaas-cli/` for existing\
    \ CLI capabilities and command naming\n- `doc/api/openapi.draft.yaml` only as\
    \ reference; do not change API contracts in this task\n\nRequired outcome:\n-\
    \ Add a v3-consistent \"Current context\" or \"Resource hierarchy\" card/surface\
    \ on an existing appropriate page such as `/settings/profile`,\n  `/access/quotas`,\
    \ or `/docs`.\n- Show org/workspace, project, region, user role, and how canonical\
    \ resource names fit into that hierarchy using existing session/API data.\n- Add\
    \ copyable values for canonical IDs/resource names where already present; do not\
    \ render long resource names as primary row text on list pages.\n- Add a demo-ready\
    \ CLI quickstart surface on an existing developer/docs/downloads page. Include\
    \ commands that match the existing CLI shape, e.g.\n  auth/login, projects list,\
    \ catalog list, allocations create/list, apps list if available.\n- Make the CLI\
    \ section honest: mark commands as quickstart/examples and avoid claiming unsupported\
    \ features.\n- Keep styling aligned to v3 product pages and add stable test IDs.\n\
    \nScope:\n- In: frontend-only context/CLI explanatory surfaces using existing\
    \ data and static docs copy.\n- Out: adding new CLI commands, changing CLI behavior,\
    \ backend contract changes, project lifecycle implementation, or new API fields.\n\
    \nHandoff required:\n- chosen route(s) and why\n- exact CLI commands shown\n-\
    \ unsupported CLI gaps found, if any\n- validation commands and pass/fail status\n"
- id: B-DEMO-ADMIN-LIGHT-CONSISTENCY-001
  title: Apply low-risk v3 controls to admin evidence and configuration pages for
    demo consistency
  role: B-ui
  status: todo
  priority: 959
  owner: ''
  branch: agent/B-ui
  completed_at: ''
  commit: ''
  depends_on:
  - B-SHARED-COMPONENT-FOUNDATION-001
  acceptance_checks:
  - rg -q "StatusTabs|FilterBar" packages/web/app/admin/allocations/page.tsx packages/web/app/admin/audit-logs/page.tsx
    packages/web/app/admin/payments/sessions/page.tsx packages/web/app/admin/skus/page.tsx
  - rg -q "Timeline|TaskTimeline" packages/web/app/admin/nodes/onboardings/'[onboardingId]'/page.tsx
    packages/web/app/admin/nodes/decommissions/'[decommissionId]'/page.tsx
  - pnpm --dir packages/web exec vitest run app/admin/allocations/page.test.tsx app/admin/audit-logs/page.test.tsx
    app/admin/payments/sessions/page.test.tsx app/admin/skus/page.test.tsx app/admin/nodes/onboardings/'[onboardingId]'/page.test.tsx
    app/admin/nodes/decommissions/'[decommissionId]'/page.test.tsx
  - pnpm --dir packages/web typecheck
  - ruby scripts/ops/agent_queue_store.rb --queue-file doc/governance/Agent_Work_Queue.yaml
    validate
  - make queue-git-check
  notes: "Context:\nAdmin pages do not need a full redesign before the demo, but obvious\
    \ raw-select/table inconsistencies weaken the product impression. Apply a\nlow-risk\
    \ controls pass where the page already has table/drawer structure, and avoid restructuring\
    \ `/admin/nodes` broadly.\n\nBefore claiming:\n- `git fetch origin`\n- `git switch\
    \ agent/B-ui`\n- `git rebase origin/master`\n- then claim this task from the queue.\n\
    \nNormative references:\n- `doc/product/UX_Redesign_Implementation_Plan.md`\n\
    - `doc/product/Admin_Ops_and_User_IA_v1.md`\n- `doc/product/E2E_Selector_Contract.md`\n\
    - shared components under `packages/web/src/components/product/`\n\nRequired outcome:\n\
    - Replace raw status/action selects with `StatusTabs` and/or `FilterBar` where\
    \ the page already has a simple list/table:\n  `/admin/allocations`, `/admin/audit-logs`,\
    \ `/admin/payments/sessions`, `/admin/skus`.\n- Keep table actions consistent\
    \ with `Open` as primary and `MoreActions` for secondary actions where low risk.\n\
    - Convert MAAS onboarding/decommission detail timeline rendering to shared `Timeline`\
    \ or `TaskTimeline` if the data shape fits cleanly.\n- Preserve all existing admin\
    \ mutations and guardrails; do not move or rename destructive actions without\
    \ tests.\n- Do not attempt a full `/admin/nodes` redesign in this task. Only small\
    \ polish or links to existing detail/task state are allowed.\n\nScope:\n- In:\
    \ low-risk admin UI consistency and tests.\n- Out: backend changes, new admin\
    \ APIs, broad node lifecycle redesign, release branch work, or risky action-flow\
    \ rewrites.\n\nHandoff required:\n- pages updated\n- screenshots or concise text\
    \ summary\n- exact validation commands and pass/fail status\n- list of admin pages\
    \ intentionally deferred\n"
- id: A-CAPACITY-BM-SLICE-CONVERSION-BACKLOG-001
  title: Design explicit bare-metal to slice-host conversion and slice-host to bare-metal
    reclassification workflow
  role: A-backend
  status: todo
  priority: 1200
  owner: ''
  branch: agent/A-backend
  completed_at: ''
  commit: ''
  depends_on: []
  acceptance_checks:
  - sh -lc 'test -f doc/architecture/Baremetal_Slice_Conversion_Workflow_v1.md'
  - rg -q "conversion is explicit" doc/architecture/Baremetal_Slice_Conversion_Workflow_v1.md
  - rg -q "no implicit scheduler conversion" doc/architecture/Baremetal_Slice_Conversion_Workflow_v1.md
  - ruby scripts/ops/agent_queue_store.rb --queue-file doc/governance/Agent_Work_Queue.yaml
    validate
  - make queue-git-check
  notes: "Context:\nCurrent scheduling intentionally keeps bare-metal and GPU slice\
    \ capacity exclusive. A full BM allocation uses a bare-metal SKU such as `h200`\n\
    on an available full node. Slice allocations use approved `node_resource_slots`\
    \ under a GPU slice SKU such as `h200-sxm-slice`. A node must\nnot silently switch\
    \ between these modes during allocation placement.\n\nProduct/backlog decision:\n\
    If resources are available, add an explicit operator workflow to convert a host\
    \ between BM and slice modes. This is backlog work, not demo-critical.\n\nRequired\
    \ design outcome:\n- Document the conversion state machine for BM -> slice-host\
    \ and slice-host -> BM.\n- State clearly that conversion is explicit and there\
    \ is no implicit scheduler conversion.\n- Define preconditions: no active/releasing/release_failed\
    \ allocation, no active/reserved/provisioning/releasing slice claims, no cleanup-blocked\n\
    \  slots, node drained, audit/log evidence present.\n- Define whether conversion\
    \ requires MAAS reimage, node-agent bootstrap, slot discovery/approval, BIOS/firmware\
    \ checks, and netdata/node-agent\n  health checks.\n- Define what happens to `nodes.sku`,\
    \ `node_resource_slots`, slot approval state, OS image/profile compatibility,\
    \ and scheduler availability.\n- Define admin UX/API surfaces needed: action availability,\
    \ confirmation, task timeline, rollback/failure states, and audit entries.\n-\
    \ Include the alternative \"8-GPU slice VM\" option as distinct from true bare-metal;\
    \ it can use all slots but remains a VM/slice product.\n\nScope:\n- In: architecture/product\
    \ design doc and follow-up implementation tasks if needed.\n- Out: changing allocator\
    \ behavior, changing existing SKU semantics, running MAAS reimages, or enabling\
    \ implicit BM/slice fallback.\n\nHandoff required:\n- recommended first implementation\
    \ slice\n- risks and demo impact\n- required API/schema changes, if any\n"
- id: B-DEMO-MARKETPLACE-LAUNCH-REGION-POLISH-001
  title: Polish marketplace to launch path with region-aware availability and clear
    BM versus GPU VM semantics
  role: B-ui
  status: todo
  priority: 940
  owner: ''
  branch: agent/B-ui
  completed_at: ''
  commit: ''
  depends_on: []
  acceptance_checks:
  - rg -q "US Buffalo|region" packages/web/app/marketplace packages/web/app/launch
    packages/web/src/components/marketplace packages/web/src/lib/region
  - rg -q "GPU VM|Bare-metal|bare-metal|slice" packages/web/app/marketplace packages/web/app/launch
    packages/web/src/components/marketplace
  - pnpm --dir packages/web exec vitest run src/components/marketplace/MarketplaceView.test.tsx
    src/components/launch/launch-wizard.test.tsx
  - pnpm --dir packages/web typecheck
  - ruby scripts/ops/agent_queue_store.rb --queue-file doc/governance/Agent_Work_Queue.yaml
    validate
  - make queue-git-check
  notes: "Context:\nThe demo launch path must make capacity intent obvious: true bare\
    \ metal is different from GPU VM/slice. The region selector should show\n`US Buffalo\
    \ / us-buffalo-1`, while current backend requests map that selection to the platform-control\
    \ API region `region-maas-1` through\nthe shared region helper. A separate A-side\
    \ patch is already adding `packages/web/src/lib/region/regions.ts` and fixing\
    \ launch submit to send\nthe selected GPU count instead of the SKU total.\n\n\
    Before claiming:\n- Wait until the current A-side launch/region patch is merged\
    \ to `master`.\n- `git fetch origin`\n- `git switch agent/B-ui`\n- `git rebase\
    \ origin/master`\n- then claim this task.\n\nRequired outcome:\n- Marketplace\
    \ cards and launch review clearly distinguish `Bare-metal host` from `GPU VM`/slice\
    \ products.\n- Availability copy is region-aware and references the selected region\
    \ label/code consistently.\n- Launch review shows the selected GPU count, selected\
    \ region, selected image, and SSH keys without implying that a slice VM is bare\
    \ metal.\n- Sold-out/insufficient-capacity messaging should say what is unavailable\
    \ in the selected region and suggest another SKU/count, not a generic\n  SKU error.\n\
    - Preserve the fixed submit behavior: slice launch must send selected `gpuCount`\
    \ and selected active API region.\n\nScope:\n- In: marketplace/launch UI copy,\
    \ tests, small helper usage.\n- Out: backend allocation changes, adding new region\
    \ APIs, BM/slice conversion, or fake capacity data.\n\nHandoff required:\n- screenshots\
    \ or concise text summary for marketplace card and launch review\n- exact validation\
    \ commands and pass/fail status\n- any remaining backend/read-model gaps\n"
- id: B-DEMO-SENSITIVE-DETAIL-REDACTION-001
  title: Centralize UI sensitive-field redaction for audit details app access payloads
    and raw JSON drawers
  role: B-ui
  status: todo
  priority: 941
  owner: ''
  branch: agent/B-ui
  completed_at: ''
  commit: ''
  depends_on:
  - B-SHARED-COMPONENT-FOUNDATION-001
  acceptance_checks:
  - rg -q "redact|REDACTED|kubeconfig|client-key-data" packages/web/src packages/web/app
  - pnpm --dir packages/web test --no-coverage
  - pnpm --dir packages/web typecheck
  - ruby scripts/ops/agent_queue_store.rb --queue-file doc/governance/Agent_Work_Queue.yaml
    validate
  - make queue-git-check
  notes: "Context:\nPlatform-control currently returns sensitive nested values in\
    \ some detail payloads, especially RKE2 kubeconfig material inside app-instance\n\
    reports/audit metadata. Backend/API sanitization remains an A-side task, but the\
    \ demo UI must not display secrets in detail drawers, raw JSON,\naudit details,\
    \ copy buttons, or app access panels.\n\nBefore claiming:\n- Rebase `agent/B-ui`\
    \ from current `origin/master`.\n\nRequired outcome:\n- Add or reuse a shared\
    \ frontend redaction helper for nested objects/JSON.\n- Redact sensitive keys\
    \ and values including `kubeconfig`, `client-key-data`, `client-certificate-data`,\
    \ `certificate-authority-data`,\n  `token`, `access_token`, `refresh_token`, `id_token`,\
    \ `password`, `secret`, `ssh_private_key`, and similar credential names.\n- Apply\
    \ the helper to user/admin audit detail drawers, app instance access/detail surfaces,\
    \ and any raw JSON drawer/view that can show API payloads.\n- Preserve useful\
    \ non-sensitive structure so operators can still debug.\n- Add tests that prove\
    \ nested kubeconfig/client-key data is redacted and copy actions do not copy raw\
    \ secret material.\n\nScope:\n- In: frontend redaction and tests.\n- Out: backend\
    \ API sanitization, audit schema changes, or deleting fields from stored records.\n\
    \nHandoff required:\n- helper path and call sites\n- redaction key list\n- validation\
    \ commands and pass/fail status\n- backend sanitization gaps still remaining\n"
- id: B-DEMO-APP-DETAIL-PROXY-ACCESS-UX-001
  title: Make app instance detail and workload access demo-ready for platform proxy
    and fallback access paths
  role: B-ui
  status: todo
  priority: 942
  owner: ''
  branch: agent/B-ui
  completed_at: ''
  commit: ''
  depends_on:
  - B-DEMO-APP-WORKBENCH-V3-001
  acceptance_checks:
  - rg -q "proxy|Platform proxy|SSH tunnel|Access" packages/web/app/apps/instances/'[instanceId]'
    packages/web/app/workloads
  - pnpm --dir packages/web exec vitest run app/apps/instances/'[instanceId]'/page.test.tsx
    app/workloads/page.test.tsx
  - pnpm --dir packages/web typecheck
  - ruby scripts/ops/agent_queue_store.rb --queue-file doc/governance/Agent_Work_Queue.yaml
    validate
  - make queue-git-check
  notes: 'Context:

    Demo app instances are running, but `proxy_routes` may be empty until backend/platform-proxy
    wiring is complete. The UI should still be honest

    and useful: show proxy route access when present, show fallback/private access
    instructions when present, and show a clear "proxy route not

    published yet" state when absent.


    Before claiming:

    - Rebase `agent/B-ui` from current `origin/master`.


    Required outcome:

    - App instance detail has a v3-consistent Access section with primary path, status,
    copyable URL/command, and fallback notes.

    - If `proxy_routes` exists, render a clear platform-proxy route with copy/open
    affordance.

    - If only private host/port or runtime access metadata exists, render an honest
    fallback such as SSH tunnel/private endpoint guidance.

    - If no route exists, show a non-error empty state that explains platform proxy
    is not published yet and links back to workloads/app events.

    - Keep workloads page row text concise; long resource names stay in detail/copy
    surfaces, not as primary table text.


    Scope:

    - In: app instance detail/workload UI, tests, copy polish.

    - Out: backend proxy route generation, deploying platform proxy, fake URLs, or
    changing app runtime APIs.


    Handoff required:

    - screenshots or concise text summary for route-present and route-missing states

    - exact validation commands and pass/fail status

    - backend/platform-proxy gaps that block a live URL

    '
- id: B-DEMO-EXEC-SMOKE-E2E-001
  title: Add a stable demo smoke e2e suite for the executive walkthrough path
  role: B-ui
  status: todo
  priority: 943
  owner: ''
  branch: agent/B-ui
  completed_at: ''
  commit: ''
  depends_on:
  - B-DEMO-APP-WORKBENCH-V3-001
  - B-DEMO-CONTEXT-RESOURCE-CLI-UX-001
  - B-DEMO-ADMIN-LIGHT-CONSISTENCY-001
  acceptance_checks:
  - rg -q "demo|executive|gotoProductPage|expectPageLoaded" packages/web/e2e packages/web/e2e/helpers.ts
  - pnpm --dir packages/web typecheck
  - ruby scripts/ops/agent_queue_store.rb --queue-file doc/governance/Agent_Work_Queue.yaml
    validate
  - make queue-git-check
  notes: "Context:\nWe need a stable smoke suite for the demo route sequence that\
    \ uses the new `data-testid` contract and avoids brittle text/heading assertions.\n\
    This task should not try to make every e2e test perfect; it should create one\
    \ high-signal walkthrough that tells us whether the demo can load.\n\nBefore claiming:\n\
    - Rebase `agent/B-ui` from current `origin/master`.\n\nRequired outcome:\n- Add\
    \ or update an e2e spec for the demo walkthrough: login/session seed, marketplace\
    \ or launch entry, allocations, workloads, app instances,\n  audit logs detail,\
    \ quotas/context, and one admin evidence page if admin session is available.\n\
    - Use shared helpers and `data-testid` selectors for page roots and key controls.\n\
    - Assert no generic failure/error state is visible after each navigation.\n- Keep\
    \ the suite resilient to empty data by asserting the correct empty/detail/control\
    \ surfaces, not fixed resource names.\n- Document how to run this smoke locally/kind/platform-control\
    \ if commands differ.\n\nScope:\n- In: e2e tests/helpers/docs only.\n- Out: product\
    \ UI rewrites, backend changes, fixing unrelated flaky tests by weakening assertions.\n\
    \nHandoff required:\n- e2e file paths\n- run command(s)\n- known environment assumptions\n\
    - any remaining brittle selectors found\n"
- id: A-AUTH-MULTI-PROVIDER-ACCOUNT-LINKING-001
  title: Define and implement explicit account linking for GitHub, Hugging Face, and
    SSO identities
  role: A-backend
  status: done
  priority: 650
  owner: codex
  branch: agent/A-backend
  completed_at: '2026-04-28'
  commit: 7f418dbe
  depends_on: []
  acceptance_checks:
  - rg -q "user_identity_links|account linking|duplicate-email" doc/product doc/api
    doc/architecture packages/services/auth
  - go test ./packages/services/auth ./cmd/api
  - ruby scripts/ops/agent_queue_store.rb --queue-file doc/governance/Agent_Work_Queue.yaml
    validate
  - make queue-git-check
  notes: 'Context:

    Users can authenticate through multiple social providers such as Hugging Face
    and GitHub. If the same human uses the same email address across

    providers, Keycloak currently rejects the second first-login path with a duplicate
    user/account conflict. This is expected with the secure

    current configuration (`trustEmail=false`) and should not be "fixed" by silently
    merging accounts by email.


    Product/security decision:

    - Do not auto-link identities by email alone.

    - A GPUaaS account should support multiple explicit identity links.

    - Linking a second provider must require proof of current session, an approved
    invite, or an admin-approved/account-recovery flow.

    - Every link/create/fail decision should be auditable.


    Required outcome:

    - Extend the auth/account model from `doc/product/Login_UX_and_Identity_Provider_Gap_v1.md`
    into a concrete contract and data model.

    - Add or finalize a `user_identity_links` style model with unique active `(provider_name,
    subject)` and no silent duplicate-email merge.

    - Define user-facing duplicate-email and "link provider" behavior for Keycloak-brokered
    providers.

    - Add API/read-model support only after updating `doc/api/openapi.draft.yaml`.

    - Add tests for provider already linked, duplicate email without link proof, successful
    explicit link, and audit logging.


    Scope:

    - In: auth contracts, schema/model, service logic, account-linking UX/API handoff,
    tests.

    - Out: demo-week workaround, global `trustEmail=true`, silent account takeover
    by matching email, provider-specific org/team authorization.


    Interim demo guidance:

    - Use one provider consistently for the demo account, or manually link the identity
    in Keycloak for a specific demo user.

    - Do not change platform-control provider config to auto-link by email.

    '
- id: A-SLICE-VM-RUNTIME-HEALTH-RECOVERY-001
  title: Detect stopped slice VMs and recover them without rebooting the physical
    node
  role: A-backend
  status: todo
  priority: 880
  owner: ''
  branch: agent/A-backend
  completed_at: ''
  commit: ''
  depends_on: []
  acceptance_checks:
  - rg -q "slice.vm_start|slice.vm_restart|runtime_health|domstate|autostart" cmd/node-agent
    packages/services/provisioning cmd/api doc/api/openapi.draft.yaml packages/web/app/allocations
  - go test ./cmd/node-agent ./packages/services/provisioning/orchestrator ./cmd/api
  - pnpm --dir packages/web typecheck
  - ruby scripts/ops/agent_queue_store.rb --queue-file doc/governance/Agent_Work_Queue.yaml
    validate
  - make queue-git-check
  notes: "Context:\nOn 2026-04-22, allocation `072dc1af-1834-471a-8125-8ebce4260bf0`\
    \ was still `active` in the control plane, but its libvirt domain\n`slice-j22u15-1g-s01-072dc1af`\
    \ on `j22u15` was `shut off` after the host rebooted at `2026-04-22 16:49:09`.\n\
    The browser terminal path was healthy, but node-agent SSH to the slice guest failed\
    \ with:\n`ssh: connect to host 10.100.0.11 port 22: No route to host`.\n\nRoot\
    \ cause:\n- The slice VM was persistent but `virsh autostart` was disabled.\n\
    - The control plane tracked allocation lifecycle, not continuous slice VM runtime\
    \ state.\n- The existing user Restart action queues `node.reboot`, which is too\
    \ coarse for `capacity_shape=gpu_slice`.\n\nRequired outcome:\n- Set or reconcile\
    \ libvirt autostart for active slice VMs during provisioning and after node-agent\
    \ restart.\n- Add node-agent runtime health reporting for active slice allocations:\
    \ libvirt `domstate`, guest SSH reachability, private IP, and last probe error.\n\
    - Expose allocation runtime health through an API/read-model surface after updating\
    \ `doc/api/openapi.draft.yaml`.\n- Add slice-specific recovery task(s), for example\
    \ `slice.vm_start` and/or `slice.vm_restart`, that operate on the VM only and\
    \ do not reboot the physical node.\n- In the allocation detail UI, show a clear\
    \ banner when a slice VM is stopped or SSH-unreachable and offer `Start slice`\
    \ / `Recover console`.\n- Ensure the existing Restart button does not reboot the\
    \ whole physical node for slice allocations; either route it to slice VM recovery\
    \ or label it explicitly.\n\nScope:\n- In: node-agent slice VM task catalog, provisioning/orchestrator\
    \ task enqueue path, API runtime health read model, allocation detail UI affordance,\
    \ tests.\n- Out: full BM <-> slice conversion, generic fleet heatmap, replacing\
    \ all node lifecycle UI.\n\nDemo/interim operations:\n- If this recurs before\
    \ the fix lands, recover manually on the host with:\n  `sudo virsh start <slice-vm-name>`\n\
    - For currently active demo slices, enable autostart manually:\n  `sudo virsh\
    \ autostart <slice-vm-name>`\n"
- id: A-PLATFORM-PROXY-BROWSER-SESSION-001
  title: Add browser-session bridge for platform-proxied web apps such as Jupyter
  role: A-backend
  status: done
  priority: 879
  owner: codex
  branch: agent/A-backend
  completed_at: '2026-04-28'
  commit: 957f7f66
  depends_on: []
  acceptance_checks:
  - rg -q "browser session|app proxy session|platform proxy.*cookie|workloads/.*/ui"
    doc/api/openapi.draft.yaml cmd/api packages/web/app
  - go test ./cmd/api ./packages/services/inventory
  - pnpm --dir packages/web typecheck
  - ruby scripts/ops/agent_queue_store.rb --queue-file doc/governance/Agent_Work_Queue.yaml
    validate
  - make queue-git-check
  notes: "Context:\nOn 2026-04-22, Jupyter platform proxy routes were visible in the\
    \ workload access card, but clicking a direct gateway URL opened the app login\n\
    path because a normal browser link cannot attach the bearer token stored in web\
    \ sessionStorage. The API proxy endpoint correctly requires\nplatform auth. vLLM\
    \ chat works because the web UI calls the proxy through the authenticated API\
    \ client; full web apps like Jupyter need a\nbrowser navigation/session mechanism.\n\
    \nRequired outcome:\n- Keep platform auth off URL query strings.\n- Add a short-lived,\
    \ auditable browser-session bridge for app proxy navigation, likely a same-site\
    \ cookie or one-time opener session minted by an\n  authenticated API call.\n\
    - Preserve current Authorization-header behavior for API clients and vLLM chat.\n\
    - Support proxied HTML assets and websocket upgrade paths needed by JupyterLab.\n\
    - Update `doc/api/openapi.draft.yaml` before adding any new endpoint or request/response\
    \ shape.\n- Add tests for unauthenticated browser navigation, authenticated session\
    \ minting, route ownership checks, expiry, and cookie/header cleanup.\n\nScope:\n\
    - In: app proxy auth contract, API gateway auth/session handling, web access button\
    \ UX, Jupyter browser-open validation.\n- Out: passing app-local Jupyter tokens\
    \ in URLs, unauthenticated public proxy access, general service mesh ingress.\n\
    \nDemo/interim operations:\n- Use private SSH tunnel access for Jupyter and paste\
    \ the app-local token shown in the workload access card.\n- Use the platform proxy\
    \ path for authenticated API-style calls such as vLLM chat until the browser bridge\
    \ lands.\n"
- id: C-NODE-AGENT-PLATFORM-PROXY-ROLLOUT-001
  title: Make platform-proxy node-agent bind behavior durable across demo nodes
  role: C-ops
  status: todo
  priority: 878
  owner: ''
  branch: agent/C-ops
  completed_at: ''
  commit: ''
  depends_on: []
  acceptance_checks:
  - rg -q "platform_proxy.*0.0.0.0|ociWorkloadEndpointPublishSpec" cmd/node-agent
  - go test ./cmd/node-agent
  - rg -q "node-agent.*rollout|lifecycle.*node-agent" doc/operations scripts doc/governance/Agent_Work_Queue.yaml
  - ruby scripts/ops/agent_queue_store.rb --queue-file doc/governance/Agent_Work_Queue.yaml
    validate
  - make queue-git-check
  notes: 'Context:

    The source fix for platform-proxy OCI workloads binds host ports on `0.0.0.0`,
    but j27u15 was still running an older node-agent and created

    Jupyter as `127.0.0.1:8888->8888/tcp`, making the platform target `10.177.36.198:8888`
    unreachable. The node was manually updated on

    2026-04-22 for demo recovery, but this must be made durable.


    Required outcome:

    - Ensure all demo GPU nodes run a node-agent build that publishes `exposure_mode=platform_proxy`
    endpoints on the node interface.

    - Add or document the safe node-agent rollout command/path for j22u05, j22u11,
    j22u15, and j27u15.

    - Verify newly created Jupyter/vLLM workloads publish `0.0.0.0:<port>` or equivalent
    reachable host binding.

    - Capture rollback steps and evidence in the operations runbook.


    Scope:

    - In: node-agent rollout/runbook, demo node validation, port binding evidence.

    - Out: changing existing running containers in place; recreate workloads after
    rollout.

    '
- id: C-DEV-CONTROL-FUNNEL-CANONICALIZATION-001
  title: Remove remaining sslip.io public-path drift from dev-control and node bootstrap
    flows
  role: C-ops
  status: todo
  priority: 877
  owner: ''
  branch: agent/C-ops
  completed_at: ''
  commit: ''
  depends_on: []
  acceptance_checks:
  - rg -n "sslip.io|100-90-157-34\\.sslip" infra/k8s/overlays/dev-control scripts/ops
    scripts/ci doc/operations doc/architecture
  - rg -q "configure_platform_control_dev_auth_urls|platform_control_tailscale_funnel_edges|NODE_BOOTSTRAP_PUBLIC_API_BASE_URL|NODE_BOOTSTRAP_REGISTRY_API_BASE_URL"
    scripts/ops infra/k8s/overlays/dev-control
  - ruby scripts/ops/agent_queue_store.rb --queue-file doc/governance/Agent_Work_Queue.yaml
    validate
  - make queue-git-check
  notes: "Context:\nThe live dev-control environment now uses Funnel/Tailscale public\
    \ hosts as the canonical browser entrypoints:\n- `gpuaas-dev-app.tailfe39f5.ts.net`\n\
    - `gpuaas-dev-api.tailfe39f5.ts.net`\n- `gpuaas-dev-auth.tailfe39f5.ts.net`\n\
    - `gpuaas-dev-term.tailfe39f5.ts.net`\n\nHowever, `sslip.io` still exists in several\
    \ dev-control configs, scripts, and docs. During the 2026-04-24 proxy/Jupyter/Grafana\
    \ recovery,\nthis mixed public-host model created misleading failures even when\
    \ the code was correct. Browser-facing paths should be Funnel-hosted;\ninternal-only\
    \ traffic should use internal service names or explicit node/bootstrap names.\
    \ We should not keep dual public models alive longer\nthan necessary.\n\nRequired\
    \ outcome:\n- Inventory all remaining `sslip.io` references used by active dev-control\
    \ flows and classify them as:\n  1. browser/public entrypoint\n  2. node bootstrap/runtime\
    \ dependency\n  3. internal-only service reference\n  4. historical/docs-only\n\
    - Remove `sslip.io` from active browser/public dev-control config and smoke defaults\
    \ where Funnel has replaced it.\n- Keep internal-only traffic on cluster/internal\
    \ names instead of public `sslip.io` names where possible.\n- Update node bootstrap/reconcile\
    \ flow so enrolled nodes receive the correct host/config updates automatically;\
    \ do not rely on one-off manual\n  `/etc/hosts` edits on nodes.\n- Preserve explicit\
    \ node-facing names only where node bootstrap/runtime genuinely requires them,\
    \ and document why.\n- Update release/recreation docs and smoke commands so a\
    \ fresh dev-control rebuild does not drift back to `sslip.io`.\n\nScope:\n- In:\
    \ dev-control public config canonicalization, node bootstrap/reconcile host updates,\
    \ docs/runbooks/smoke defaults, Funnel-first public\n  environment model.\n- Out:\
    \ removing `sslip.io` from historical incident docs/evidence that intentionally\
    \ record old behavior, changing unrelated production DNS\n  architecture, or rewriting\
    \ all internal ingress topology in one slice.\n\nKey caution:\n- Changing this\
    \ later will affect enrolled nodes. Plan an explicit node update/reconcile step\
    \ as part of the cleanup so a recreated\n  environment does not leave nodes pointing\
    \ at stale public hosts.\n"
- id: A-REGION-READ-MODEL-001
  title: Expose region read model for product shell region selection and remove placeholder-only
    UX
  role: A-backend
  status: done
  priority: 880
  owner: Codex
  branch: agent/A-backend
  completed_at: '2026-04-27'
  commit: bcd3ed8e
  depends_on: []
  acceptance_checks:
  - rg -q "region" doc/api/openapi.draft.yaml packages/web/src/components/layout/AppShell.tsx
  - go test ./cmd/api ./packages/services/inventory/...
  - pnpm --dir packages/web exec tsc --noEmit
  - ruby scripts/ops/agent_queue_store.rb --queue-file doc/governance/Agent_Work_Queue.yaml
    validate
  - make queue-git-check
  notes: 'Context:

    The current product shell exposes a Region menu, but additional regions are not
    backed by a read model yet. The placeholder message was removed

    from the UI because it is not a useful operator/user affordance, but the missing
    backend capability remains.


    Required outcome:

    - Define and expose a region read model that the product shell can consume.

    - Make region availability and disabled reasons data-driven instead of hardcoded
    placeholder copy.

    - Preserve the existing current-region UX while allowing additional environments/regions
    to appear cleanly when they are actually available.


    Scope:

    - In: contract/read-model/API/web wiring for regions.

    - Out: unrelated tenancy redesign, full geo-routing automation, or speculative
    region UX that is not backed by live data.

    '
- id: C-NODE-PROVISIONING-METRICS-PARITY-001
  title: Make node provisioning/bootstrap the source of truth for metrics and slice-network
    fixes, then prove it with BM and slice reimage
  role: C-ops
  status: todo
  priority: 881
  owner: ''
  branch: agent/C-ops
  completed_at: ''
  commit: ''
  depends_on:
  - C-NODE-AGENT-PLATFORM-PROXY-ROLLOUT-001
  - C-DEV-CONTROL-FUNNEL-CANONICALIZATION-001
  acceptance_checks:
  - rg -q "GPUAAS_TELEMETRY_ADDR=0.0.0.0:9110" cmd/api/routes.go build/node-agent-bootstrap/config
    infra/env/maas scripts/ops
  - rg -q "gpuaas-slice-network-baseline.service|GPUAAS_SLICE_RUNTIME_VFIO_BIND|MASQUERADE|ip_forward"
    infra/env/maas scripts/ops doc/operations
  - rg -q "Open Netdata" packages/web/app/admin/nodes/page.tsx
  - go test ./cmd/api ./cmd/node-agent ./packages/services/provisioning/...
  - pnpm --dir packages/web exec vitest run 'app/admin/nodes/page.list.test.tsx'
  - ruby scripts/ops/agent_queue_store.rb --queue-file doc/governance/Agent_Work_Queue.yaml
    validate
  - make queue-git-check
  notes: "Context:\nThe 2026-04-24 and 2026-04-25 metrics rollout added a platform-owned\
    \ allocation telemetry path, admin-only Netdata on `/admin/nodes`,\nslice-network\
    \ repair, and a node-agent telemetry listener on `:9110`. During live validation\
    \ we also found that some of these fixes still\ndepended on manual host repair\
    \ or manual node-agent bootstrap, especially:\n- slice host network/NAT/ip_forward\
    \ baseline drift;\n- node-agent env drift where manual bootstrap overwrote `/etc/gpuaas/node-agent.env`\
    \ without `GPUAAS_TELEMETRY_ADDR`;\n- mixed Netdata behavior across BM hosts until\
    \ updated node-agent/collector rollout lands.\n\nRequired outcome:\n- Move every\
    \ required node-side metrics/network fix into the owned provisioning/bootstrap\
    \ path so a freshly provisioned node gets the same\n  behavior without manual\
    \ repair.\n- Ensure the node bootstrap package, rendered bootstrap script, and\
    \ MAAS/site bootstrap path all agree on the node-agent telemetry listener\n  and\
    \ current slice-network baseline.\n- Keep Netdata as an admin/operator surface\
    \ only, with allocation/user metrics coming from the first-party telemetry path.\n\
    - Reimage one bare-metal node and one slice host and prove they converge automatically\
    \ to the expected state:\n  - node-agent enrolled and reporting;\n  - `:9110`\
    \ listener present;\n  - slice network baseline/NAT present where required;\n\
    \  - BM and slice metrics usable without ad hoc host repair.\n- Capture the evidence\
    \ and any remaining manual exceptions in the runbook.\n\nScope:\n- In: provisioning/bootstrap\
    \ parity, node-agent env/render parity, slice-network baseline parity, admin Netdata\
    \ surface, BM+slice reimage proof.\n- Out: long-term metrics retention/history\
    \ redesign, central telemetry backend, or unrelated node lifecycle UX changes.\n"
- id: A-AUTH-BROKER-IDENTITY-LINKING-001
  title: Investigate and fix brokered identity duplicate-account behavior for repeated
    Hugging Face logins
  role: A-backend
  status: done
  priority: 3
  owner: Codex
  branch: agent/A-backend
  completed_at: '2026-04-26'
  commit: e7b89ccc
  depends_on: []
  acceptance_checks:
  - sh -lc 'test -f doc/architecture/Brokered_Identity_Linking_and_Dedup_v1.md'
  - sh -lc 'go test ./cmd/api ./packages/services/auth/...'
  - ruby scripts/ops/agent_queue_store.rb --queue-file doc/governance/Agent_Work_Queue.yaml
    validate
  - make queue-git-check
  notes: 'Context:

    Repeated Hugging Face logins during fresh-session/incognito testing appear to
    create a new login/user footprint instead of resolving to the same logical identity.
    Investigate whether this is broker-sub handling, account linking policy, user
    provisioning drift, or duplicate-identity creation in our auth layer.

    Required output:

    - document current brokered-identity linking behavior and desired product model
    - define expected behavior for first login, returning login, conflict, and manual/admin
    linking cases - implement fix or bounded owner-layer change so repeated Hugging
    Face login resolves to one intended account identity

    '
- id: B-UI-AUDIT-LOGS-V3-PARITY-001
  title: Bring user and admin audit log surfaces onto one v3 evidence-page model
  role: B-ui
  status: done
  priority: 2
  owner: Codex
  branch: agent/B-ui
  completed_at: '2026-04-28'
  commit: b45b439f
  depends_on: []
  acceptance_checks:
  - sh -lc 'test -f packages/web/src/components/v3/v3-audit-evidence-page.tsx
    && test -f packages/web/app/v3-prod/evidence/page.tsx'
  - rg -q "/v3-prod/evidence|v3-audit-evidence-page" packages/web/src doc/product
  - pnpm --dir packages/web exec vitest run src/lib/cutover/route-map.test.ts
  - pnpm --dir packages/web typecheck
  - pnpm --dir packages/web test
  - make queue-git-check
  notes: 'Context:

    User audit logs and admin audit logs now share a v3 evidence-page grammar while
    preserving scope differences and permissions. `/audit-logs` cuts over to
    `/v3-prod/evidence` for user/project/tenant scoped audit APIs; `/admin/audit-logs`
    cuts over to `/v3-prod/platform/evidence`, which mounts the same evidence component
    with platform admin filters.

    Implemented shared headers, scope/action filters, v3 table grammar, sanitized
    detail drawer, correlation-id copy affordances, and admin-only actor filters.

    '
- id: B-UI-LAUNCH-WIZARD-INLINE-DEPENDENCIES-001
  title: Add inline prerequisite creation and attachment to launch wizards
  role: B-ui
  status: done
  priority: 3
  owner: Codex
  branch: agent/B-ui
  completed_at: '2026-04-28'
  commit: 0de70907
  depends_on: []
  acceptance_checks:
  - sh -lc 'test -f doc/product/Launch_Wizard_Inline_Dependencies_v1.md'
  - rg -q "v3-inline-create-ssh-key|v3-inline-create-service-account|v3-inline-create-storage-bucket"
    packages/web/src/components/v3 packages/web/e2e
  - pnpm --dir packages/web typecheck
  - pnpm --dir packages/web test
  - ruby scripts/ops/agent_queue_store.rb --queue-file doc/governance/Agent_Work_Queue.yaml
    validate
  - make queue-git-check
  notes: 'Context:

    Launch flows should not force users out to separate pages when a required dependency
    is missing. SSH keys are the current example; storage, network, firewall, and
    similar inputs will follow.

    Required work:

    - define inline create/select UX inside compute and app launch flows - identify
    which dependencies can be created inline versus only attached - keep pricing/review
    and blocker language coherent after inline creation

    '
- id: B-UI-APP-LAUNCH-WIZARD-V3-001
  title: Migrate app launch flow onto the shared v3 launch wizard system
  role: B-ui
  status: done
  priority: 3
  owner: Codex
  branch: agent/B-ui
  completed_at: '2026-04-28'
  commit: af83c8a5
  depends_on:
  - B-UI-LAUNCH-WIZARD-INLINE-DEPENDENCIES-001
  acceptance_checks:
  - sh -lc 'test -f doc/product/App_Launch_Wizard_v3_Migration_v1.md'
  - rg -q "WizardShell|useWizard|submitV3AppLaunch|ServiceAccountDependencyField"
    packages/web/src/components/v3/v3-launch-app-page.tsx
  - pnpm --dir packages/web typecheck
  - pnpm --dir packages/web test
  - ruby scripts/ops/agent_queue_store.rb --queue-file doc/governance/Agent_Work_Queue.yaml
    validate
  - make queue-git-check
  notes: 'Context:

    App launch should use the same shared wizard system as compute launch rather than
    a separate page language. This is part of migrating launch flows to the v3 redesign.

    Required work:

    - define shared wizard primitives and app-specific branches - align app launch
    states, review, dependency handling, and post-submit task routing with compute
    launch

    '
- id: A-IAM-TENANT-ADMIN-QUOTA-DELEGATION-001
  title: Define tenant-admin quota delegation model for projects and users
  role: A-backend
  status: done
  priority: 3
  owner: Codex
  branch: agent/A-backend
  completed_at: '2026-04-26'
  commit: e71f4f49
  depends_on: []
  acceptance_checks:
  - sh -lc 'test -f doc/architecture/Tenant_Admin_Quota_Delegation_v1.md'
  - ruby scripts/ops/agent_queue_store.rb --queue-file doc/governance/Agent_Work_Queue.yaml
    validate
  - make queue-git-check
  notes: 'Context:

    We need a clear model for whether tenant admins can set quotas for projects and/or
    users, how that authority is scoped, and how it interacts with platform-admin
    controls and future budget/billing controls.

    Required output:

    - define supported quota scopes - define allowed actors and mutation boundaries
    - identify required API/read-model changes and UX implications

    '
- id: A-BILLING-PLATFORM-OVERHAUL-EPIC-001
  title: Redesign billing model beyond allocation-duration accounting
  role: A-backend
  status: done
  priority: 4
  owner: Codex
  branch: agent/A-backend
  completed_at: '2026-04-26'
  commit: 71234552
  depends_on: []
  acceptance_checks:
  - sh -lc 'test -f doc/architecture/Billing_Platform_Overhaul_v1.md'
  - ruby scripts/ops/agent_queue_store.rb --queue-file doc/governance/Agent_Work_Queue.yaml
    validate
  - make queue-git-check
  notes: 'Context:

    Billing needs a separate redesign/architecture effort. Current implementation
    is allocation-duration accounting, but the target scope is broader and should
    be treated as a first-class platform control plane.

    Required design scope:

    - pricing modes: on-demand, spot, reserved duration - idle policies selected at
    launch - invoice generation and payment timing - future usage models beyond simple
    allocation duration - tenant budgets and alerts - usage attribution by user, SKU,
    and app - data ingress/egress accounting - delinquency handling and standard billing
    controls

    This is an epic-sized design/input task and should not be merged into smaller
    UI polish work.

    '
- id: A-V3-READMODEL-CACHE-FOUNDATION-001
  title: Wire Redis-backed read-model cache foundation into first v3 backend endpoint
  role: A-backend
  status: done
  priority: 4
  owner: Codex
  branch: agent/A-backend
  completed_at: '2026-04-26'
  commit: a4d254b7
  depends_on: []
  acceptance_checks:
  - sh -lc 'test -f doc/architecture/UI_Read_Model_Cache_Architecture_v1.md'
  - sh -lc 'test -f packages/shared/readcache/cache.go'
  - go test ./packages/shared/readcache ./cmd/api
  - ruby scripts/ops/agent_queue_store.rb --queue-file doc/governance/Agent_Work_Queue.yaml
    validate
  - make queue-git-check
  notes: 'Context:

    The v3 UI shell/workbenches need read-heavy dashboard endpoints. We should not
    let each page fan out across multiple domain tables on every

    refresh. Redis is already in the platform stack; standardize its use for read-model
    hot caches before implementing live v3 pages.


    Required work:

    - use `packages/shared/readcache` as the shared Redis JSON cache helper

    - choose one existing read endpoint, preferably `/api/v1/admin/ops/overview`,
    and add cache-aside behavior without changing its OpenAPI shape

    - cache only sanitized response DTOs

    - include tenant/project/user/role scope in cache keys where authorization depends
    on it

    - fail open on Redis errors and recompute from source

    - add unit tests for hit, miss, Redis error, and scope isolation

    - add lightweight cache hit/miss/error counters or logs ready for OTel metrics
    follow-up


    Out of scope:

    - new v3 API contract surfaces

    - caching ledger correctness, authorization decisions, raw tokens, or secrets

    - replacing Postgres/domain services as source of truth

    '
- id: A-V3-READMODEL-ENDPOINT-MAP-001
  title: Produce v3 endpoint/read-model implementation map before page migration
  role: A-backend
  status: done
  priority: 4
  owner: Codex
  branch: agent/A-backend
  completed_at: '2026-04-26'
  commit: a4d254b7
  depends_on:
  - A-V3-READMODEL-CACHE-FOUNDATION-001
  acceptance_checks:
  - sh -lc 'test -f doc/architecture/V3_Read_Model_Endpoint_Map_v1.md'
  - rg -q "Workloads|Apps|Storage|Access|Account|Platform" doc/architecture/V3_Read_Model_Endpoint_Map_v1.md
  - ruby scripts/ops/agent_queue_store.rb --queue-file doc/governance/Agent_Work_Queue.yaml
    validate
  - make queue-git-check
  notes: 'Context:

    After the v3 mock polish, implementation should start from shared primitives and
    backend read-model/API gaps rather than wiring page-by-page

    from mock fixtures. This task produces the backend migration map that lets UI
    and backend lanes work independently.


    Required work:

    - map each v3 shell group to existing endpoints, missing endpoints, owning domain,
    cache class, and security scope

    - cover Workloads, Compute, Apps, Storage, Access, Account, and Platform

    - identify which endpoints can reuse existing OpenAPI contracts and which require
    new contract-first work

    - list kind/kind-env smoke tests for the first implementation slice

    - identify read-model tables/projections that should be event-updated instead
    of recomputed live

    - document feature-flag rollout order and old-route replacement order


    Out of scope:

    - implementing new OpenAPI endpoints in the same task

    - frontend route migration

    '
- id: B-V3-WIZARD-USABILITY-STANDARD-001
  title: Lock v3 launch wizard usability standard for inline dependencies and back
    navigation
  role: B-ui
  status: done
  priority: 4
  owner: B
  branch: agent/B-ui
  completed_at: '2026-04-26'
  commit: 258453ca
  depends_on: []
  acceptance_checks:
  - sh -lc 'test -f doc/product/Launch_Wizard_Usability_Standard_v1.md'
  - rg -q "inline dependency|clickable previous|draft persistence" doc/product/Launch_Wizard_Usability_Standard_v1.md
  - ruby scripts/ops/agent_queue_store.rb --queue-file doc/governance/Agent_Work_Queue.yaml
    validate
  - make queue-git-check
  notes: 'Context:

    Current launch flows send users away when prerequisites such as SSH keys are missing,
    forcing them to restart. v3 launch wizards should fix this

    across compute, app, and storage flows before implementation begins.


    Required rules:

    - completed previous step numbers are directly clickable from any later step

    - future steps remain locked until valid

    - wizard drafts persist while navigating backward/forward

    - changing an earlier step invalidates only dependent later choices

    - launch-blocking prerequisites support inline create/select/attach where safe:
    SSH key, bucket, service account/API key, network/firewall policy

    - if a prerequisite must be completed elsewhere, the return path resumes the same
    wizard draft and step


    Out of scope:

    - backend implementation of each prerequisite API

    - replacing all current production launch pages in this task

    '
- id: A-V3-OPENAPI-SHELL-WORKLOADS-CONTRACTS-001
  title: Define first v3 shell and workload read-model contracts
  role: A-backend
  status: done
  priority: 1
  owner: Codex
  branch: agent/A-backend
  completed_at: '2026-04-26'
  commit: 294c9df1
  depends_on:
  - A-V3-READMODEL-ENDPOINT-MAP-001
  acceptance_checks:
  - rg -q "v3.*shell|shell.*context|workload.*workbench" doc/api/openapi.draft.yaml
  - rg -q "V3 Read Model Endpoint Map" doc/architecture/V3_Read_Model_Endpoint_Map_v1.md
  - make codegen
  - go test ./cmd/api ./packages/services/inventory ./packages/services/provisioning/...
  - ruby scripts/ops/agent_queue_store.rb --queue-file doc/governance/Agent_Work_Queue.yaml
    validate
  - make queue-git-check
  notes: 'Context:

    The first real v3 migration slice should not start from page wiring. It needs
    contract-first read models for the product shell and unified

    workload workbench/detail because those are used by nearly every v3 flow.


    Required work:

    - add OpenAPI contracts for shell context summary: mode defaults, tenant/project
    picker, balance summary, region list, attention counts

    - add OpenAPI contracts for unified workload workbench rows and workload detail
    summary

    - preserve the product noun model: compute, app, notebook, endpoint, and training
    runtimes are workload kinds

    - include authz scope fields and cache/debug headers where appropriate

    - document which fields come from existing source tables versus later projection
    tables

    - add handler/service skeletons or explicit TODO stubs only if they are contract-compatible


    Out of scope:

    - replacing current `/workloads` UI

    - full storage/access/account contracts

    - changing allocation lifecycle semantics

    '
- id: A-V3-READCACHE-OBSERVABILITY-INVALIDATION-001
  title: Add read-cache observability and invalidation primitives before broad v3
    rollout
  role: A-backend
  status: done
  priority: 1
  owner: Codex
  branch: agent/A-backend
  completed_at: '2026-04-26'
  commit: f9ba2bf8
  depends_on:
  - A-V3-READMODEL-CACHE-FOUNDATION-001
  acceptance_checks:
  - rg -q "hit|miss|error|invalidate" packages/shared/readcache
  - go test ./packages/shared/readcache ./cmd/api
  - ruby scripts/ops/agent_queue_store.rb --queue-file doc/governance/Agent_Work_Queue.yaml
    validate
  - make queue-git-check
  notes: 'Context:

    The first cache-aside helper is landed. Before using it across many v3 pages,
    we need standard instrumentation and invalidation helpers so

    operators can see cache behavior and mutations can clear affected read models
    deliberately.


    Required work:

    - add a small metrics/logging interface for read-cache hit, miss, set, delete,
    and Redis error paths

    - add key-pattern deletion helpers for scoped invalidation without exposing raw
    Redis details to handlers

    - document which events should invalidate shell, workload, platform ops, catalog/config,
    and metrics-summary caches

    - wire instrumentation into the existing `/api/v1/admin/ops/overview` cache-aside
    slice

    - add unit tests for metrics calls and invalidation helpers


    Out of scope:

    - building full event consumers for every invalidation path

    - using Redis as a correctness dependency

    '
- id: A-V3-KIND-READMODEL-SMOKE-HARNESS-001
  title: Build kind smoke harness for v3 read models and cache behavior
  role: A-backend
  status: done
  priority: 2
  owner: Codex
  branch: agent/A-backend
  completed_at: '2026-04-26'
  commit: 172652eb
  depends_on:
  - A-V3-OPENAPI-SHELL-WORKLOADS-CONTRACTS-001
  - A-V3-READCACHE-OBSERVABILITY-INVALIDATION-001
  acceptance_checks:
  - rg -q "v3 read model" scripts doc/operations doc/architecture
  - ruby scripts/ops/agent_queue_store.rb --queue-file doc/governance/Agent_Work_Queue.yaml
    validate
  - make queue-git-check
  notes: 'Context:

    The v3 UI migration needs fast feedback in kind before touching production routes.
    We need deterministic seed data and smoke checks for authz,

    cache miss/hit, and representative read-model responses.


    Required work:

    - add or document a kind/local seed path with tenant, project, users, workloads,
    storage-like fixtures, access drift, one blocked node, and task history

    - add smoke commands that hit shell/workload/admin ops read models twice and verify
    cache miss then hit headers or logs

    - include negative authz checks for project scoping

    - keep the harness additive and safe for repeated local runs


    Out of scope:

    - full browser E2E migration

    - production data migration

    '
- id: A-V3-SHELL-WORKLOADS-READMODEL-HANDLERS-001
  title: Implement first temporary v3 shell and workload read-model handlers
  role: A-backend
  status: done
  priority: 1
  owner: Codex
  branch: agent/A-backend
  completed_at: '2026-04-26'
  commit: e91eeb03
  depends_on:
  - A-V3-OPENAPI-SHELL-WORKLOADS-CONTRACTS-001
  - A-V3-READCACHE-OBSERVABILITY-INVALIDATION-001
  acceptance_checks:
  - go test ./cmd/api
  - rg -q "GET /api/v1/v3/shell/context" cmd/api/routes_v3_readmodels.go
  - rg -q "GET /api/v1/v3/workloads" cmd/api/routes_v3_readmodels.go
  - ruby scripts/ops/agent_queue_store.rb --queue-file doc/governance/Agent_Work_Queue.yaml
    validate
  - make queue-git-check
  notes: 'Context:

    The `/api/v1/v3/*` routes are temporary migration read models for the v3 UI shell.
    They let the frontend bind to stable page-shaped data while

    we decide which contracts graduate into normal long-term resource paths.


    Delivered:

    - shell context route scoped by `X-Project-ID`

    - workload list route backed by existing allocation read paths

    - workload detail route backed by project allocation detail

    - scoped Redis read-cache keys and `X-Read-Model-Cache` headers


    Out of scope:

    - permanent public API naming

    - storage/access/account read models

    - app-instance kind-specific enrichment beyond allocation-backed compute workloads

    '
- id: B-V3-SHARED-PRODUCTION-PRIMITIVES-001
  title: Promote v3 mock primitives into production shared UI building blocks
  role: B-ui
  status: done
  priority: 1
  owner: B
  branch: agent/B-ui
  completed_at: '2026-04-26'
  commit: 0020b56e
  depends_on:
  - B-V3-WIZARD-USABILITY-STANDARD-001
  acceptance_checks:
  - rg -q "ResourceHeader|ContextStrip|ActionBand|Tabs" packages/web
  - pnpm --dir packages/web typecheck
  - pnpm --dir packages/web test
  - ruby scripts/ops/agent_queue_store.rb --queue-file doc/governance/Agent_Work_Queue.yaml
    validate
  - make queue-git-check
  notes: 'Context:

    The `/v3` mock proved the page grammar. Before replacing production pages, extract
    the reusable primitives into the production component system

    instead of copying mock page code route by route.


    Required work:

    - promote stable primitives such as ResourceHeader, ContextStrip, ActionBand,
    Tabs, StatusChip, KpiTile, DataTable/Toolbar patterns

    - preserve existing design-system compatibility and avoid double shell wrapping

    - add production-safe loading, empty, error, and permission-denied states

    - keep the mock routes working while introducing shared primitives

    - add tests/story-like fixture pages where useful for responsive review


    Out of scope:

    - wiring primitives to new backend endpoints

    - replacing all existing product/admin pages in this task

    '
- id: B-V3-WIZARD-PRODUCTION-FOUNDATION-001
  title: Implement production launch-wizard foundation with draft persistence and
    backward step navigation
  role: B-ui
  status: done
  priority: 2
  owner: B
  branch: agent/B-ui
  completed_at: '2026-04-26'
  commit: 2a8e55b8
  depends_on:
  - B-V3-SHARED-PRODUCTION-PRIMITIVES-001
  - B-V3-WIZARD-USABILITY-STANDARD-001
  acceptance_checks:
  - rg -q "draft|previous step|inline" packages/web
  - pnpm --dir packages/web typecheck
  - pnpm --dir packages/web test
  - ruby scripts/ops/agent_queue_store.rb --queue-file doc/governance/Agent_Work_Queue.yaml
    validate
  - make queue-git-check
  notes: 'Context:

    Launch wizards are one of the highest-friction current flows. The production foundation
    should support v3 behavior before individual compute,

    app, storage, or network launch flows are migrated.


    Required work:

    - implement shared stepper behavior where completed previous steps are clickable
    and future steps remain locked

    - add draft persistence across backward/forward navigation and temporary route
    exits

    - model inline prerequisite creation/select/attach slots without hardcoding only
    SSH keys

    - add tests for dependent-step invalidation and return-to-wizard behavior


    Out of scope:

    - implementing every prerequisite backend API

    - migrating every launch flow in the same PR

    '
- id: A-V3-STORAGE-READMODEL-CONTRACTS-001
  title: Define v3 storage workbench and bucket detail read-model contracts
  role: A-backend
  status: done
  priority: 1
  owner: Codex
  branch: agent/A-backend
  completed_at: '2026-04-26'
  commit: e3471f7a
  depends_on:
  - A-V3-SHELL-WORKLOADS-READMODEL-HANDLERS-001
  - B-V3-WIZARD-PRODUCTION-FOUNDATION-001
  acceptance_checks:
  - rg -q "V3StorageBucketListResponse|V3StorageBucketDetailResponse" doc/api/openapi.draft.yaml
  - make codegen
  - ruby scripts/ops/agent_queue_store.rb --queue-file doc/governance/Agent_Work_Queue.yaml
    validate
  - make queue-git-check
  notes: 'Context:

    Storage is now a top-level v3 shell group and appears in launch wizards, workload
    detail, and persistent data management. Before UI migration,

    define the read-model contract instead of wiring the mock table directly to ad
    hoc storage calls.


    Required work:

    - add temporary `/api/v1/v3/storage` and `/api/v1/v3/storage/{bucket_id}` read-model
    contracts

    - model bucket purpose, quota/usage, flags, workload mounts, access summary, lifecycle
    summary, and object preview fields

    - include `V3ReadModelMeta` and cache/debug-friendly metadata

    - keep secrets, provider credentials, signed URLs, and raw object-store internals
    out of the read model

    - document that these routes are temporary v3 migration read models until stable
    resource paths are chosen


    Out of scope:

    - implementing bucket creation or object mutation APIs

    - choosing the long-term storage backend

    - full RKE2 CSI/storage integration

    '
- id: A-V3-STORAGE-READMODEL-HANDLERS-001
  title: Implement temporary v3 storage read-model handlers with cache-aside behavior
  role: A-backend
  status: done
  priority: 1
  owner: Codex
  branch: agent/A-backend
  completed_at: '2026-04-26'
  commit: e3471f7a
  depends_on:
  - A-V3-STORAGE-READMODEL-CONTRACTS-001
  - A-V3-READCACHE-OBSERVABILITY-INVALIDATION-001
  acceptance_checks:
  - go test ./cmd/api ./packages/services/storage
  - rg -q "GET /api/v1/v3/storage" cmd/api/routes_v3_readmodels.go
  - rg -q "storage" scripts/ops/v3_read_model_smoke.sh
  - ruby scripts/ops/agent_queue_store.rb --queue-file doc/governance/Agent_Work_Queue.yaml
    validate
  - make queue-git-check
  notes: 'Context:

    Once the storage read-model contract exists, wire the first temporary handlers
    using existing storage/project/workload data where available and

    explicit empty/unknown fields where the source domain does not exist yet.


    Required work:

    - register authenticated `GET /api/v1/v3/storage` and `GET /api/v1/v3/storage/{bucket_id}`
    routes

    - scope cache keys by user, tenant, project, and bucket where applicable

    - fail open on Redis errors and return sanitized DTOs only

    - add smoke coverage for list/detail cache miss then hit when project context
    is available

    - avoid direct object-store credentials or signed URLs in responses


    Out of scope:

    - storage mutation handlers

    - real bucket lifecycle enforcement

    - event-updated projection tables

    '
- id: A-STORAGE-PROVIDER-CAPABILITY-MODEL-001
  title: Define provider-neutral storage backend capability model for WEKA first and
    VAST later
  role: A-backend
  status: done
  priority: 1
  owner: Codex
  branch: agent/A-backend
  completed_at: '2026-04-26'
  commit: 3fb074a5
  depends_on:
  - A-V3-STORAGE-READMODEL-CONTRACTS-001
  acceptance_checks:
  - rg -q "WEKA.*VAST|provider.*capability|storage provider" doc/architecture doc/api/openapi.draft.yaml
    packages/services/storage
  - make codegen
  - go test ./packages/services/storage ./cmd/api
  - ruby scripts/ops/agent_queue_store.rb --queue-file doc/governance/Agent_Work_Queue.yaml
    validate
  - make queue-git-check
  notes: "Context:\nStorage will likely start with WEKA, but the platform needs a\
    \ vendor-neutral model similar to GPU vendor support. VAST, DDN/NVMe pools, or\n\
    other backends should be represented through capabilities instead of forcing UI/API\
    \ semantics to become WEKA-specific.\n\nRequired work:\n- document the storage\
    \ provider capability model: backend type, mount modes, multi-attach support,\
    \ performance tier, encryption/KMS support,\n  snapshot/versioning support, retention\
    \ support, quota support, and region/fabric constraints\n- add or reserve OpenAPI\
    \ fields needed by v3 storage read models without exposing provider credentials\
    \ or raw backend internals\n- keep WEKA as the initial implementation target,\
    \ but make VAST and other backends additive\n- update storage read-model docs\
    \ so UI can show provider/tier/capability hints without vendor lock-in\n\nOut\
    \ of scope:\n- implementing the WEKA CSI/runtime integration\n- adding VAST runtime\
    \ support now\n- changing user-facing storage launch UX beyond provider-neutral\
    \ fields\n"
- id: A-V3-ACCESS-READMODEL-CONTRACTS-001
  title: Define v3 access posture read-model contracts for memberships, credentials,
    entitlements, and drift
  role: A-backend
  status: done
  priority: 2
  owner: Codex
  branch: agent/A-backend
  completed_at: '2026-04-26'
  commit: 8e06f97e
  depends_on:
  - A-V3-SHELL-WORKLOADS-READMODEL-HANDLERS-001
  - B-V3-SHARED-PRODUCTION-PRIMITIVES-001
  acceptance_checks:
  - rg -q "V3Access" doc/api/openapi.draft.yaml
  - make codegen
  - ruby scripts/ops/agent_queue_store.rb --queue-file doc/governance/Agent_Work_Queue.yaml
    validate
  - make queue-git-check
  notes: 'Context:

    The v3 Access workbench consolidates who-can-do-what across memberships, service
    accounts, credentials, entitlements, connectivity, identity,

    and audit. The backend needs page-shaped read models before UI migration.


    Required work:

    - define additive read-model contracts for access overview, memberships, service
    accounts, credentials map, entitlements, and drift flags

    - distinguish Account-owned personal credential records from Access-owned credential
    map/read posture

    - include tenant/project scope and role provenance fields

    - keep raw secrets and private key material out of every response


    Out of scope:

    - network/VRF/firewall implementation

    - full identity-provider account-linking implementation

    - billing or quota mutation APIs

    '
- id: A-V3-ACCOUNT-READMODEL-CONTRACTS-001
  title: Define v3 account read-model contracts for profile, linked identities, sessions,
    and personal security
  role: A-backend
  status: done
  priority: 2
  owner: Codex
  branch: agent/A-backend
  completed_at: '2026-04-26'
  commit: 5118a0f7
  depends_on:
  - A-V3-SHELL-WORKLOADS-READMODEL-HANDLERS-001
  - B-V3-SHARED-PRODUCTION-PRIMITIVES-001
  acceptance_checks:
  - rg -q "V3Account" doc/api/openapi.draft.yaml
  - make codegen
  - ruby scripts/ops/agent_queue_store.rb --queue-file doc/governance/Agent_Work_Queue.yaml
    validate
  - make queue-git-check
  notes: 'Context:

    The v3 Account group owns personal records: profile, linked identity providers,
    SSH/API keys, sessions, and lightweight personal billing. This

    must stay distinct from Access, which shows the permission map.


    Required work:

    - define profile and linked-provider read models without exposing provider secrets

    - define session inventory fields suitable for revoke/sign-out UX

    - define personal SSH/API key summary fields with fingerprints and last-used metadata
    only

    - include duplicate-account/account-linking hints only as safe presentation data


    Out of scope:

    - implementing account-linking mutation flows

    - full billing redesign

    - storing or returning raw tokens, private keys, or provider credentials

    '
- id: A-V3-REGION-READMODEL-CONTRACTS-001
  title: Define product-shell region read model and remove hardcoded v3 region placeholder
  role: A-backend
  status: done
  priority: 2
  owner: Codex
  branch: agent/A-backend
  completed_at: '2026-04-26'
  commit: b2dae5a1
  depends_on:
  - A-V3-SHELL-WORKLOADS-READMODEL-HANDLERS-001
  acceptance_checks:
  - rg -q "V3Region" doc/api/openapi.draft.yaml
  - make codegen
  - ruby scripts/ops/agent_queue_store.rb --queue-file doc/governance/Agent_Work_Queue.yaml
    validate
  - make queue-git-check
  notes: 'Context:

    The v3 shell currently uses `us-buffalo-1` as a placeholder. Before production
    migration, expose a region read model that can drive the shell

    selector and capacity scoping without hardcoding deployment geography in UI code.


    Required work:

    - define region list/current-region read-model fields for shell consumption

    - include display label, availability state, default marker, and optional capacity
    scope hints

    - update shell context contract or add a small companion endpoint so the UI can
    remove hardcoded region values


    Out of scope:

    - multi-region scheduler implementation

    - region billing differences

    - cross-region workload migration

    '
- id: A-V3-ACCESS-ACCOUNT-READMODEL-HANDLERS-001
  title: Implement temporary v3 Access and Account read-model handlers with cache-aside
    behavior
  role: A-backend
  status: done
  priority: 1
  owner: Codex
  branch: agent/A-backend
  completed_at: '2026-04-26'
  commit: 66d5e762
  depends_on:
  - A-V3-ACCESS-READMODEL-CONTRACTS-001
  - A-V3-ACCOUNT-READMODEL-CONTRACTS-001
  - A-V3-READCACHE-OBSERVABILITY-INVALIDATION-001
  acceptance_checks:
  - go test ./cmd/api ./packages/shared/readcache
  - rg -q "GET /api/v1/v3/access" cmd/api/routes_v3_readmodels.go
  - rg -q "GET /api/v1/v3/account" cmd/api/routes_v3_readmodels.go
  - ruby scripts/ops/agent_queue_store.rb --queue-file doc/governance/Agent_Work_Queue.yaml
    validate
  - make queue-git-check
  notes: 'Context:

    Access and Account contracts exist, but the v3 UI cannot migrate those shell groups
    until page-shaped read-model handlers exist. Keep these

    handlers temporary under `/api/v1/v3/*` until the long-term IAM/Account route
    ownership is finalized.


    Required work:

    - register authenticated Access overview, memberships, service accounts, credentials,
    entitlements, and Account profile/security/sessions routes

    - scope every response by user, tenant, project, and platform role where applicable

    - use cache-aside behavior with sanitized DTOs only and fail open on Redis errors

    - return safe empty/unknown fields where the source domain is not implemented
    yet rather than leaking raw credentials or provider internals

    - keep handler code in `cmd/api/routes_v3_readmodels.go` for now so v3 migration
    remains isolated


    Out of scope:

    - account-linking mutations

    - service-account mutation APIs

    - network/VRF/firewall implementation

    - full billing redesign

    '
- id: A-V3-COMPUTE-APPS-READMODEL-HANDLERS-001
  title: Define and implement temporary v3 Compute and Apps read-model contracts
    and handlers
  role: A-backend
  status: done
  priority: 1
  owner: Codex
  branch: agent/A-backend
  completed_at: '2026-04-26'
  commit: 72951ec8
  depends_on:
  - A-V3-SHELL-WORKLOADS-READMODEL-HANDLERS-001
  - A-V3-READCACHE-OBSERVABILITY-INVALIDATION-001
  acceptance_checks:
  - rg -q "V3ComputeCatalogResponse|V3AppCatalogResponse|V3AppDetailResponse" doc/api/openapi.draft.yaml
  - rg -q "GET /api/v1/v3/compute" cmd/api/routes_v3_readmodels.go
  - rg -q "GET /api/v1/v3/apps" cmd/api/routes_v3_readmodels.go
  - make codegen
  - go test ./cmd/api
  - pnpm --dir packages/web typecheck
  - ruby scripts/ops/agent_queue_store.rb --queue-file doc/governance/Agent_Work_Queue.yaml
    validate
  - make queue-git-check
  notes: 'Context:

    Compute and Apps are top-level v3 shell groups, but production pages need typed,
    project-scoped read models before B can migrate them from mock fixtures.


    Delivered:

    - temporary `GET /api/v1/v3/compute` read model with SKU, image, availability,
    and launch-link fields

    - temporary `GET /api/v1/v3/apps` and `GET /api/v1/v3/apps/{app_slug}` read
    models with catalog, featured rows, versions, entitlements, dependencies, and
    examples

    - generated Go and TypeScript OpenAPI artifacts

    - shared web v3 API client exports for Compute and Apps

    - targeted API tests plus full Go/web gates


    Out of scope:

    - launch readiness/precheck mutation contracts

    - compute/app launch submit handlers

    - long-term route graduation out of `/api/v1/v3/*`

    '
- id: A-V3-LAUNCH-READINESS-PRECHECK-HANDLERS-001
  title: Define and implement v3 launch readiness precheck contracts and handlers
  role: A-backend
  status: done
  priority: 1
  owner: Codex
  branch: agent/A-backend
  completed_at: '2026-04-26'
  commit: 11240c73
  depends_on:
  - A-V3-COMPUTE-APPS-READMODEL-HANDLERS-001
  acceptance_checks:
  - rg -q "V3LaunchPrecheckResponse|V3ComputeLaunchPrecheckRequest|V3AppLaunchPrecheckRequest" doc/api/openapi.draft.yaml
  - rg -q "POST /api/v1/v3/launch/compute/precheck|POST /api/v1/v3/launch/apps" cmd/api/routes_v3_readmodels.go
  - go test ./cmd/api
  - pnpm --dir packages/web typecheck
  - ruby scripts/ops/agent_queue_store.rb --queue-file doc/governance/Agent_Work_Queue.yaml
    validate
  - make queue-git-check
  notes: 'Context:

    Production v3 launch wizards need a read-only readiness surface so missing SSH,
    storage, network, service-account, entitlement, image, capacity, and quota checks
    can be rendered inline before submit.


    Delivered:

    - `POST /api/v1/v3/launch/compute/precheck`

    - `POST /api/v1/v3/launch/apps/{app_slug}/precheck`

    - generated Go and TypeScript OpenAPI artifacts

    - web v3 API client helpers for Compute/App launch prechecks

    - focused API tests for dependency blocker rows


    Out of scope:

    - creating allocations or app instances

    - implementing storage/network/service-account inline-create mutations

    - replacing the existing submit endpoints

    - long-term route graduation out of `/api/v1/v3/*`

    '
- id: A-API-ROUTE-DOMAIN-SPLIT-PILOT-001
  title: Split one stable non-v3 route family into a domain route module without behavior
    changes
  role: A-backend
  status: done
  priority: 2
  owner: Codex
  branch: agent/A-backend
  completed_at: '2026-04-26'
  commit: 1885dd9c
  depends_on:
  - A-API-DOMAIN-AUTHORING-SPLIT-001
  acceptance_checks:
  - bash scripts/ci/route_structure_guard.sh
  - go test ./cmd/api
  - rg -q "register.*Routes" cmd/api/routes_*.go
  - ruby scripts/ops/agent_queue_store.rb --queue-file doc/governance/Agent_Work_Queue.yaml
    validate
  - make queue-git-check
  notes: 'Context:

    `routes_v1_frozen.go` now preserves the frozen demo/internal v1 registration surface.
    To prove the domain route-module pattern before broad

    refactors, split one low-risk stable route family out of the legacy monolith without
    changing contracts or behavior.


    Recommended pilot:

    - choose a clear owner such as account/auth, storage, billing, or platform health

    - move only registration first if handler movement is risky

    - do not add product routes to the frozen v1 registrar

    - update route structure docs if the pilot reveals a naming improvement


    Out of scope:

    - changing endpoint paths or OpenAPI shapes

    - migrating all route families in one pass

    - deleting v1 routes before the v3 cutover

    '
- id: A-OPENAPI-V3-FRAGMENT-PILOT-001
  title: Pilot OpenAPI fragment authoring with the v3 read-model domain while preserving
    the canonical bundle
  role: A-backend
  status: done
  priority: 2
  owner: Codex
  branch: agent/A-backend
  completed_at: '2026-04-26'
  commit: 959eb1d7
  depends_on:
  - A-API-DOMAIN-AUTHORING-SPLIT-001
  - A-V3-SHELL-WORKLOADS-READMODEL-HANDLERS-001
  acceptance_checks:
  - ruby scripts/api/bundle_contracts.rb --check
  - make codegen
  - bash scripts/ci/contracts_validate.sh
  - ruby scripts/ops/agent_queue_store.rb --queue-file doc/governance/Agent_Work_Queue.yaml
    validate
  - make queue-git-check
  notes: 'Context:

    The OpenAPI domain-authoring manifests are in canonical mode. Before many teams
    edit the same 12k-line contract, prove the fragment flow with

    a narrow low-risk domain: temporary v3 read models.


    Required work:

    - create the first OpenAPI fragment layout for v3 read-model paths/components

    - keep `doc/api/openapi.draft.yaml` as the generated canonical artifact consumed
    by codegen and external docs

    - make `scripts/api/bundle_contracts.rb --check` detect drift between fragments
    and the canonical artifact

    - preserve generated Go/TypeScript types exactly except for ordering/formatting
    changes caused by bundling

    - document the fragment migration steps for the next domains


    Out of scope:

    - splitting the public API into multiple external specs

    - moving every OpenAPI path in one pass

    - changing endpoint behavior

    '
- id: A-OPENAPI-V3-FRAGMENT-COVERAGE-COMPUTE-APPS-001
  title: Add Compute Apps and launch precheck contracts to the v3 OpenAPI fragment
  role: A-backend
  status: done
  priority: 1
  owner: Codex
  branch: agent/A-backend
  completed_at: '2026-04-26'
  commit: e679cbdd
  depends_on:
  - A-OPENAPI-V3-FRAGMENT-PILOT-001
  - A-V3-LAUNCH-READINESS-PRECHECK-HANDLERS-001
  acceptance_checks:
  - rg -q "V3ComputeCatalogResponse|V3AppCatalogResponse|V3LaunchPrecheckResponse" doc/api/openapi/domains/v3-read-models.yaml
  - rg -q "/api/v1/v3/launch/compute/precheck|/api/v1/v3/launch/apps" doc/api/openapi/domains/v3-read-models.yaml
  - ruby scripts/api/bundle_contracts.rb --check
  - make codegen
  - ruby scripts/ops/agent_queue_store.rb --queue-file doc/governance/Agent_Work_Queue.yaml
    validate
  - make queue-git-check
  notes: 'Context:

    The OpenAPI fragment pilot exists so domain teams can edit focused contract
    files instead of only changing the large canonical artifact. Compute, Apps,
    and launch precheck contracts were added during v3 migration and need to be
    mirrored into the v3 read-model fragment.


    Delivered:

    - v3 Compute catalog path and schemas in `doc/api/openapi/domains/v3-read-models.yaml`

    - v3 Apps catalog/detail paths and schemas in the same fragment

    - v3 launch readiness precheck paths and schemas in the same fragment

    - bundle validation proving canonical and fragment output remain consistent

    '
- id: B-V3-SHELL-WORKLOADS-PRODUCTION-MIGRATION-001
  title: Migrate the production shell and Workloads entry flow onto v3 primitives
    and read models
  role: B-ui
  status: done
  priority: 1
  owner: B
  branch: agent/B-ui
  completed_at: '2026-04-26'
  commit: ece9f318
  depends_on:
  - B-V3-SHARED-PRODUCTION-PRIMITIVES-001
  - B-V3-WIZARD-PRODUCTION-FOUNDATION-001
  - A-V3-SHELL-WORKLOADS-READMODEL-HANDLERS-001
  - A-V3-REGION-READMODEL-CONTRACTS-001
  acceptance_checks:
  - pnpm --dir packages/web typecheck
  - pnpm --dir packages/web test
  - rg -q "v3-shell|v3-workloads|fail-closed" doc/product/V3_E2E_Testing_Contract_v1.md
    packages/web/e2e packages/web/src 2>/dev/null
  - rg -q "ResourceHeader\\|ContextStrip\\|ActionBand" packages/web
  - ruby scripts/ops/agent_queue_store.rb --queue-file doc/governance/Agent_Work_Queue.yaml
    validate
  - make queue-git-check
  notes: 'Context:

    The v3 mock and shared primitives are ready. The first production UI slice should
    be shell + Workloads because it validates mode/context,

    routing, read-model fetches, action bands, and workload detail patterns without
    waiting for every domain.


    Required work:

    - use production primitives from `packages/web/src/components/product`

    - bind shell context, regions, workload list, and workload detail to the v3 read-model
    endpoints

    - follow `doc/product/V3_E2E_Testing_Contract_v1.md` for stable selectors and
    fail-closed backend mocks

    - keep v1/demo routes available during the rollout, but do not add new v1 UI dependencies

    - preserve responsive behavior and stable test IDs

    - add loading, empty, error, and permission-denied states


    Out of scope:

    - replacing every admin page

    - implementing Access/Account UI before backend handlers exist

    - deleting v1 UI routes

    '
- id: B-V3-STORAGE-ACCESS-ACCOUNT-PRODUCTION-MIGRATION-001
  title: Migrate Storage, Access, and Account production surfaces after read-model
    handlers land
  role: B-ui
  status: done
  priority: 2
  owner: B
  branch: agent/B-ui
  completed_at: '2026-04-26'
  commit: 8c6d2d00
  depends_on:
  - B-V3-SHELL-WORKLOADS-PRODUCTION-MIGRATION-001
  - A-V3-STORAGE-READMODEL-HANDLERS-001
  - A-V3-ACCESS-ACCOUNT-READMODEL-HANDLERS-001
  - A-STORAGE-PROVIDER-CAPABILITY-MODEL-001
  acceptance_checks:
  - pnpm --dir packages/web typecheck
  - pnpm --dir packages/web test
  - rg -q "v3-storage|v3-access-account" doc/product/V3_E2E_Testing_Contract_v1.md
    packages/web/e2e packages/web/src 2>/dev/null
  - rg -q "storage\\|access\\|account" packages/web/app packages/web/src/components/product
  - ruby scripts/ops/agent_queue_store.rb --queue-file doc/governance/Agent_Work_Queue.yaml
    validate
  - make queue-git-check
  notes: 'Context:

    Storage, Access, and Account are the next high-value shell groups after Workloads.
    They validate the v3 model across persistent data,

    permission posture, and personal records.


    Required work:

    - migrate production Storage surfaces to the v3 workbench/detail patterns backed
    by read models

    - keep Storage UI provider-neutral: WEKA may appear as the first backend, but
    the page model should also fit VAST/DDN/NVMe-class providers

    - migrate Access surfaces to the v3 posture/workbench patterns backed by read
    models

    - migrate Account profile/security/sessions to the v3 account pattern

    - follow `doc/product/V3_E2E_Testing_Contract_v1.md` and retire duplicate v1 E2E
    coverage as v3 workflows replace it

    - keep inline dependency creation hooks compatible with the wizard foundation

    - avoid exposing internal roadmap or architecture-document references in user-facing
    copy


    Out of scope:

    - full billing redesign

    - network/VRF implementation

    - removing v1 routes

    '
- id: B-V3-COMPUTE-APPS-PRODUCTION-MIGRATION-001
  title: Migrate Compute and Apps production surfaces onto v3 read models
  role: B-ui
  status: done
  priority: 1
  owner: B
  branch: agent/B-ui
  completed_at: '2026-04-26'
  commit: b703753b
  depends_on:
  - B-V3-SHELL-WORKLOADS-PRODUCTION-MIGRATION-001
  - B-V3-WIZARD-PRODUCTION-FOUNDATION-001
  - A-V3-COMPUTE-APPS-READMODEL-HANDLERS-001
  - A-V3-LAUNCH-READINESS-PRECHECK-HANDLERS-001
  acceptance_checks:
  - pnpm --dir packages/web typecheck
  - pnpm --dir packages/web test
  - rg -q "getV3ComputeCatalog|listV3Apps|getV3AppDetail|precheckV3ComputeLaunch|precheckV3AppLaunch"
    packages/web/src packages/web/app/v3-prod
  - rg -q "v3-compute|v3-apps" doc/product/V3_E2E_Testing_Contract_v1.md
    packages/web/e2e packages/web/src 2>/dev/null
  - ruby scripts/ops/agent_queue_store.rb --queue-file doc/governance/Agent_Work_Queue.yaml
    validate
  - make queue-git-check
  notes: 'Context:

    Compute and Apps now have temporary backend read models under `/api/v1/v3/*`.
    The next B-ui slice should replace the remaining production placeholders/mock
    dependency for those top-level shell groups.


    Required work:

    - add or replace `/v3-prod/compute` with a production Compute catalog bound to
    `getV3ComputeCatalog`

    - add `/v3-prod/apps` and `/v3-prod/apps/[slug]` production pages bound to
    `listV3Apps` and `getV3AppDetail`

    - wire `/v3-prod/launch/compute` and `/v3-prod/launch/app/[slug]` readiness
    panels to `precheckV3ComputeLaunch` and `precheckV3AppLaunch`

    - keep the wizard flow backward-clickable and preserve draft state when inline
    dependency creation expands/collapses

    - keep app instances as Workload subtypes; Apps remains catalog/detail/launch
    entry, not a separate runtime detail surface

    - reuse production primitives and the v3 shell states

    - wire stable v3 selectors and fail-closed E2E mocks for Compute and Apps

    - keep launch submit mutations disabled or clearly staged until final submit
    integration is explicitly assigned


    Out of scope:

    - adding app launch submit backend mutations

    - replacing billing/network/storage dependency APIs

    - deleting v1/demo routes

    '
- id: A-V3-LAUNCH-SUBMIT-HANDLERS-001
  title: Add v3 launch submit handlers and production task handoff
  role: A-backend
  status: done
  priority: 1
  owner: Codex
  branch: agent/A-backend
  completed_at: '2026-04-26'
  commit: fa60c0cf
  depends_on:
  - A-V3-LAUNCH-READINESS-PRECHECK-HANDLERS-001
  - A-V3-TASK-READMODEL-HANDLERS-001
  - B-V3-COMPUTE-APPS-PRODUCTION-MIGRATION-001
  acceptance_checks:
  - rg -q "V3LaunchSubmitResponse|V3ComputeLaunchSubmitRequest|V3AppLaunchSubmitRequest"
    doc/api/openapi.draft.yaml doc/api/openapi/domains/v3-read-models.yaml
  - rg -q "submitV3ComputeLaunchHandler|submitV3AppLaunchHandler" cmd/api
  - rg -q "submitV3ComputeLaunch|submitV3AppLaunch|v3-task-detail-page" packages/web/src
    packages/web/app/v3-prod packages/web/e2e
  - ruby scripts/api/bundle_contracts.rb --check
  - make codegen
  - go test ./cmd/api
  - go test ./...
  - go vet ./...
  - make lint
  - pnpm --dir packages/web typecheck
  - pnpm --dir packages/web test
  - ruby scripts/ops/agent_queue_store.rb --queue-file doc/governance/Agent_Work_Queue.yaml
    validate
  - make queue-git-check
  notes: 'Context:

    B-V3-COMPUTE-APPS-PRODUCTION-MIGRATION-001 moved Compute and Apps launch
    wizards onto production v3 read models but intentionally left submit staged.


    Delivered:

    - contract-first submit endpoints for `POST /api/v1/v3/launch/compute`
    and `POST /api/v1/v3/launch/apps/{app_slug}`

    - idempotent compute allocation submit through the provisioning orchestrator
    domain

    - idempotent app launch submit through the inventory app-instance domain

    - normalized `V3LaunchSubmitResponse` task/workload handoff

    - app-instance fallback source in the v3 task read model

    - `/v3-prod/tasks/[id]` task detail page bound to the production task read
    model

    - production launch wizards call submit, preserve drafts on failed async
    submit, and route to task detail on success

    - fail-closed v3 E2E mocks for compute/app submit and task detail


    Out of scope:

    - implementing storage/network/service-account inline-create mutations

    - replacing app runtime workflow internals

    - graduating temporary `/api/v1/v3/*` paths into their long-term route family

    - deleting v1/demo launch routes

    '
- id: A-V3-PLATFORM-READMODEL-HANDLERS-001
  title: Define and implement temporary v3 Platform and Ops read-model handlers
  role: A-backend
  status: done
  priority: 1
  owner: Codex
  branch: agent/A-backend
  completed_at: '2026-04-27'
  commit: ae1ce1b8
  depends_on:
  - A-V3-SHELL-WORKLOADS-READMODEL-HANDLERS-001
  - A-V3-READCACHE-OBSERVABILITY-INVALIDATION-001
  - A-OPENAPI-V3-FRAGMENT-PILOT-001
  acceptance_checks:
  - rg -q "V3PlatformOverviewResponse|V3PlatformOpsResponse|V3PlatformLifecycleResponse"
    doc/api/openapi.draft.yaml doc/api/openapi/domains/v3-read-models.yaml
  - rg -q "GET /api/v1/v3/platform/overview" cmd/api/routes_v3_readmodels_domains.go
  - rg -q "getV3PlatformOverview|getV3PlatformLifecycle|getV3PlatformEvidence"
    packages/web/src/lib/v3/api.ts
  - ruby scripts/api/bundle_contracts.rb --check
  - make codegen
  - go test ./cmd/api
  - pnpm --dir packages/web typecheck
  - ruby scripts/ops/agent_queue_store.rb --queue-file doc/governance/Agent_Work_Queue.yaml
    validate
  - make queue-git-check
  notes: 'Context:

    The v3 production shell now has Workloads, Compute, Apps, Storage, Access, Account,
    launch submit, and task handoff. Platform/Ops is still mock-only, but it is the
    operator surface that will replace dense admin information dumps.


    Required work:

    - define temporary `/api/v1/v3/platform/*` read-model contracts for overview,
    ops, lifecycle, config, evidence, finance, and IAM

    - implement authenticated platform-ops read handlers with cache-aside behavior
    and sanitized DTOs only

    - keep the route registration in v3 read-model route modules, not frozen v1

    - add web v3 API client helpers so B-ui can migrate `/v3-prod/platform/*`

    - extend the v3 smoke harness to include platform family endpoints


    Out of scope:

    - replacing the platform UI pages in this A-backend task

    - full billing redesign

    - long-term route graduation out of `/api/v1/v3/*`

    '
- id: B-V3-PLATFORM-PRODUCTION-MIGRATION-001
  title: Migrate Platform and Ops production surfaces onto v3 read models
  role: B-ui
  status: done
  priority: 1
  owner: B
  branch: agent/B-ui
  completed_at: '2026-04-27'
  commit: a28214c0
  depends_on:
  - B-V3-SHELL-WORKLOADS-PRODUCTION-MIGRATION-001
  - A-V3-PLATFORM-READMODEL-HANDLERS-001
  acceptance_checks:
  - pnpm --dir packages/web typecheck
  - pnpm --dir packages/web test
  - rg -q "getV3PlatformOverview|getV3PlatformOps|getV3PlatformLifecycle"
    packages/web/src packages/web/app/v3-prod
  - rg -q "v3-platform|v3-admin-platform" doc/product/V3_E2E_Testing_Contract_v1.md
    packages/web/e2e packages/web/src 2>/dev/null
  - ruby scripts/ops/agent_queue_store.rb --queue-file doc/governance/Agent_Work_Queue.yaml
    validate
  - make queue-git-check
  notes: 'Context:

    Platform/Ops mock pages validated the operator IA, but production `/v3-prod`
    still does not have Platform family pages. The A-backend platform read models
    now provide overview, ops, lifecycle, config, evidence, finance, and IAM data
    under temporary `/api/v1/v3/platform/*` endpoints.


    Required work:

    - add `/v3-prod/platform/overview`, `/v3-prod/platform/ops`, `/v3-prod/platform/lifecycle`,
    `/v3-prod/platform/config`, `/v3-prod/platform/evidence`, `/v3-prod/platform/finance`,
    and `/v3-prod/platform/iam`

    - bind each page to the corresponding `getV3Platform*` client helper

    - reuse production v3 primitives, loading/error/permission states, and stable
    selectors

    - keep "Open Netdata" as an operator action where node context exists, but do
    not solve the Netdata edge-proxy redesign in this UI task

    - add or extend fail-closed v3 E2E coverage for the platform family navigation
    and at least overview + lifecycle + evidence


    Out of scope:

    - backend contract changes

    - full billing redesign

    - node-local Netdata/nginx edge proxy implementation

    - deleting v1 admin pages

    '
- id: C-V3-KIND-QA-VALIDATION-HARNESS-001
  title: Build v3 kind QA validation harness for shell workloads storage access account
    and route freeze
  role: C-ops
  status: done
  priority: 1
  owner: Codex
  branch: agent/C-ops
  completed_at: '2026-04-26'
  commit: 78bce27d
  depends_on:
  - A-V3-ACCESS-ACCOUNT-READMODEL-HANDLERS-001
  - B-V3-SHELL-WORKLOADS-PRODUCTION-MIGRATION-001
  acceptance_checks:
  - rg -q "v3.*kind\\|route_structure_guard\\|demo/internal" scripts doc/operations
    doc/architecture
  - bash scripts/ci/route_structure_guard.sh
  - ruby scripts/ops/agent_queue_store.rb --queue-file doc/governance/Agent_Work_Queue.yaml
    validate
  - make queue-git-check
  notes: 'Context:

    QA must be a first-class lane for the v3 migration. The fastest feedback loop
    is kind, with deterministic smoke data and route freeze checks.


    Required work:

    - document and/or script a kind smoke path for v3 shell, workloads, storage, access,
    and account read models

    - verify read-model cache miss/hit where endpoints use Redis cache

    - verify project/user authz negative cases

    - verify frozen v1 route guard remains active and no `/api/v1/v3/*` route is registered
    through v1

    - include manual QA guidance for demo/internal users during v3 cutover


    Out of scope:

    - production deployment promotion

    - full browser matrix automation

    - deleting v1 routes

    '
- id: B-V3-E2E-FOUNDATION-001
  title: Build the v3 Playwright foundation with stable selectors and fail-closed
    backend mocks
  role: B-ui
  status: done
  priority: 1
  owner: B
  branch: agent/B-ui
  completed_at: '2026-04-26'
  commit: 2e39f8db
  depends_on:
  - B-V3-SHARED-PRODUCTION-PRIMITIVES-001
  acceptance_checks:
  - sh -lc 'test -f doc/product/V3_E2E_Testing_Contract_v1.md'
  - pnpm --dir packages/web typecheck
  - pnpm --dir packages/web test
  - rg -q "fail-closed|v3-shell|v3-workloads" packages/web/e2e doc/product/V3_E2E_Testing_Contract_v1.md
  - ruby scripts/ops/agent_queue_store.rb --queue-file doc/governance/Agent_Work_Queue.yaml
    validate
  - make queue-git-check
  notes: 'Context:

    The v3 UI migration should not inherit brittle v1 E2E patterns. Build a small
    reusable Playwright harness before or alongside the first v3

    production pages.


    Required work:

    - add shared v3 E2E helpers for shell session setup, mode/project context, page
    load assertions, and backend route mocking

    - make backend mocks fail closed for unmocked `/backend/**` requests

    - add a skeleton `v3-shell.spec.ts` or equivalent that asserts the contract without
    depending on fragile heading copy

    - ensure new v3 selectors follow `doc/product/V3_E2E_Testing_Contract_v1.md`

    - document which old v1 E2E suites are candidates for retirement after v3 coverage
    lands


    Out of scope:

    - migrating every v3 page

    - deleting old v1 E2E files before replacement coverage exists

    - real kind-backed browser tests; those belong to the C-ops QA harness

    '
- id: C-MAAS-SLICE-BOOTSTRAP-FABRIC-CONVERGENCE-001
  title: Make h200-slice-vm bootstrap converge the slice fabric/IPoIB baseline
  role: C-ops
  status: done
  priority: 1
  owner: Codex
  branch: agent/C-ops
  completed_at: '2026-04-26'
  commit: 46275005
  depends_on: []
  acceptance_checks:
  - sh -lc 'rg -q "gpuaas-slice-network-baseline|60-ipoib|ibp" infra/env/maas/site-bootstrap/h200-slice-vm scripts/ops'
  - sh -lc 'rg -q "Slice Custom-Image Convergence Gap|slice baseline" doc/operations/runbooks/MAAS_H200_Host_Image_Pipeline_Runbook.md'
  - ruby scripts/ops/agent_queue_store.rb --queue-file doc/governance/Agent_Work_Queue.yaml
    validate
  - make queue-git-check
  notes: 'Context:

    2026-04-26 reimage validation showed that a custom-image slice host can enroll
    node-agent and bind VFIO while still missing the IPoIB/fabric-network baseline.
    Known-good `j22u15` had `60-ipoib.yaml`, an `ibp*` fabric address/route, OVS,
    dnsmasq, libvirt, and slice networking services. Custom-image `j22u11` had
    node-agent, Netdata, VFIO, and OVS, but did not have the IPoIB netplan/fabric
    route or `gpuaas-slice-network-baseline`.

    Required work:

    - update the `h200-slice-vm` site-bootstrap artifact so it composes the `h200-ib`
    fabric-network baseline or implements an equivalent IPoIB convergence step

    - preserve the custom-image speed goal while keeping host-specific fabric and route
    configuration in first boot/site-profile bootstrap

    - normalize the network-baseline service naming so operators do not have to reason
    about `gpuaas-slice-host-net-baseline` versus `gpuaas-slice-network-baseline`

    - update the host-image and slice bootstrap runbooks if the final service name or
    validation commands differ from the documented baseline

    '
- id: A-NODE-AGENT-SLICE-READINESS-BLOCKERS-001
  title: Block slice scheduling when fabric/IPoIB readiness evidence is missing
  role: A-backend
  status: done
  priority: 1
  owner: Codex
  branch: agent/A-backend
  completed_at: '2026-04-26'
  commit: 46275005
  depends_on:
  - C-MAAS-SLICE-BOOTSTRAP-FABRIC-CONVERGENCE-001
  acceptance_checks:
  - sh -lc 'rg -q "slice_network|cleanup_blocked|gpuaas-slice-network-baseline|60-ipoib|ibp" cmd packages doc/architecture doc/operations'
  - make test
  - ruby scripts/ops/agent_queue_store.rb --queue-file doc/governance/Agent_Work_Queue.yaml
    validate
  - make queue-git-check
  notes: 'Context:

    The scheduler/admin surfaces must not treat a slice node as schedulable only
    because node-agent is enrolled or VFIO setup completed. Slice-ready requires
    fabric/IPoIB, bridge, dnsmasq, libvirt, and node-agent topology evidence with
    no hard blockers.

    Required work:

    - ensure node-agent topology/readiness evidence detects missing IPoIB netplan,
    missing `ibp*` fabric address/route, missing OVS guest gateway, missing dnsmasq,
    and missing libvirt where applicable

    - ensure admin/read-model/scheduler paths show or honor hard blockers instead
    of presenting false-green slice capacity

    - add tests around missing fabric/IPoIB evidence and successful slice-ready evidence

    - keep Netdata presence non-gating for slice readiness

    '
- id: C-SLICE-HOST-PARITY-CHECK-SCRIPT-001
  title: Add an ops parity checker for slice-host convergence after MAAS deploy
  role: C-ops
  status: done
  priority: 2
  owner: Codex
  branch: agent/C-ops
  completed_at: '2026-04-27'
  commit: 22b8f302
  depends_on: []
  acceptance_checks:
  - sh -lc 'test -x scripts/ops/gpuaas_slice_host_parity_check.sh'
  - sh -lc 'rg -q "gpuaas_slice_host_parity_check|Automated Provisioning Parity Target" doc/operations/runbooks/GPU_Slice_Node_Manual_Bootstrap_Runbook.md'
  - ruby scripts/ops/agent_queue_store.rb --queue-file doc/governance/Agent_Work_Queue.yaml
    validate
  - make queue-git-check
  notes: 'Context:

    Operators need a repeatable API/script-level check after MAAS deploy or reimage
    so they do not manually compare hosts like `j22u15` and `j22u11`.

    Required work:

    - add a script that checks the documented slice parity target: MAAS tag intent,
    node-agent active, VFIO/slice services active, IPoIB netplan and route, OVS guest
    gateway, dnsmasq GPU subnet, libvirt active, and node-agent topology evidence
    when an API endpoint is available

    - make the script output machine-readable pass/fail lines suitable for future
    automation and human-readable remediation hints for ops

    - document how to run it against a freshly deployed slice host and how to interpret
    partial convergence

    '
- id: C-NODE-TELEMETRY-EDGE-PROXY-001
  title: Move host Netdata exposure behind node-local nginx telemetry edge
  role: C-ops
  status: done
  priority: 2
  owner: Codex
  branch: agent/C-ops
  completed_at: '2026-04-27'
  commit: ac825e30
  depends_on: []
  acceptance_checks:
  - sh -lc 'rg -q "telemetry edge|NETDATA_BIND|nginx|127.0.0.1:19999" infra/env/maas doc/operations'
  - sh -lc 'bash -n infra/env/maas/site-bootstrap/h200-ib/bootstrap.sh && bash -n infra/env/maas/site-bootstrap/h200-slice-vm/bootstrap.sh'
  - ruby scripts/ops/agent_queue_store.rb --queue-file doc/governance/Agent_Work_Queue.yaml
    validate
  - make queue-git-check
  notes: 'Context:

    Transitional control-plane Netdata launch logic now probes node Netdata routes
    because different deployed nodes expose different Netdata UI package paths. That
    solves immediate browser-launch compatibility but keeps Netdata version knowledge
    in the API and requires Netdata to bind on the node network.

    Target architecture:

    - provisioning/site-bootstrap owns host telemetry personality

    - Netdata binds only to loopback, for example `127.0.0.1:19999`

    - node-local nginx exposes a stable GPUaaS-owned telemetry path/port for control-plane
    proxying

    - bootstrap renders the nginx config after locally discovering the working Netdata
    dashboard route, such as `/v3/spaces/<host>/rooms/local/overview` or `/v2/spaces/<host>/rooms/local/overview`

    - nginx should proxy Netdata assets/API paths required by that dashboard without
    exposing arbitrary host services

    - the same pattern must be applied to `h200-ib` and `h200-slice-vm` bootstraps

    - document verification commands for active service state, bind addresses, and
    direct local edge health before using the platform proxy

    Security requirement:

    - do not leave Netdata listening directly on `0.0.0.0:19999` once nginx edge
    exposure is in place

    '
- id: A-NETDATA-PROXY-REMOVE-ROUTE-PROBES-001
  title: Simplify control-plane Netdata proxy after node telemetry edge rollout
  role: A-backend
  status: done
  priority: 2
  owner: Codex
  branch: agent/A-backend
  completed_at: '2026-04-27'
  commit: c9b44555
  depends_on:
  - C-NODE-TELEMETRY-EDGE-PROXY-001
  acceptance_checks:
  - sh -lc 'rg -q "adminNodeNetdataStableOpenURL|adminNodeNetdataVersionedOpenURL" cmd/api/routes.go cmd/api/routes_test.go'
  - go test ./cmd/api -run 'TestAdminNodeNetdataHelpers|TestPlatformProxyBrowserSessionTargetParsesAdminNodeNetdataPath'
  - ruby scripts/ops/agent_queue_store.rb --queue-file doc/governance/Agent_Work_Queue.yaml
    validate
  - make queue-git-check
  notes: 'Context:

    After `C-NODE-TELEMETRY-EDGE-PROXY-001`, the API should no longer understand
    Netdata UI versions or probe `/v2`/`/v3` dashboard paths. The node-local edge
    proxy becomes the compatibility boundary.

    Required work:

    - change admin node Netdata browser-session launch to open the stable edge path
    exposed by bootstrap

    - remove control-plane dashboard route probing and version-based Netdata UI path
    decisions for admin node launch

    - keep browser-session cookie scoping and proxy authorization unchanged

    - update tests so the control-plane contract is "open stable node telemetry edge",
    not "understand Netdata app route versions"

    '
- id: C-NETDATA-EXISTING-NODE-EDGE-CONVERGENCE-001
  title: Converge demo nodes to node-local nginx Netdata edge and remove v1 fallback
  role: C-ops
  status: blocked
  priority: 3
  owner: ''
  branch: agent/C-ops
  completed_at: ''
  commit: ''
  depends_on:
  - C-NODE-TELEMETRY-EDGE-PROXY-001
  - A-NETDATA-PROXY-REMOVE-ROUTE-PROBES-001
  acceptance_checks:
  - sh -lc 'rg -q "gpuaas/telemetry/netdata|j22u05|j22u11|j22u15|j27u15" doc/governance/Agent_Work_Queue.yaml'
  - test -x scripts/ops/gpuaas_netdata_edge_converge.sh
  - make queue-git-check
  notes: 'Deferred until after the current v3 implementation push.

    2026-05-03 update:

    - Added `scripts/ops/gpuaas_netdata_edge_converge.sh` for idempotent local or
    SSH convergence of pre-edge nodes.
    - Converged j22u05 and j22u11 to the nginx telemetry edge. From platform-control,
    both nodes return `ok` at `/gpuaas/telemetry/health` and redirect
    `/gpuaas/telemetry/netdata/` to their locally detected `/v3/spaces/<host>/rooms/local/overview`
    dashboards.
    - j22u15 and j27u15 remain blocked by SSH/access denial and still need convergence
    through MAAS, console, or another approved operator path.
    - API browser-session open URL has been restored to `/gpuaas/telemetry/netdata/`;
    old direct-Netdata nodes will not have the correct UX until they are converged.

    Interim state:

    - admin-node Netdata browser sessions now intentionally open the stable node-local
    edge path `/gpuaas/telemetry/netdata/`.
    - Example drift observed on j22u11: `nginx inactive`, Netdata directly listening
    on `0.0.0.0:19999`, and `/gpuaas/telemetry/netdata/` serving Netdata latest-UI
    bootstrap instead of a GPUaaS-owned redirect. j22u11 has since been converged;
    this drift pattern still applies to pre-edge nodes.

    Existing nodes that were bootstrapped before the nginx telemetry edge need manual
    convergence or a site-bootstrap rerun. Target demo nodes:

    - j22u05: converged 2026-05-03
    - j22u11: converged 2026-05-03
    - j22u15: blocked by SSH/access denial
    - j27u15: blocked by SSH/access denial

    Required node-side end state:

    - Netdata listens on `127.0.0.1:19998`
    - nginx listens on `0.0.0.0:19999`
    - `http://127.0.0.1:19999/gpuaas/telemetry/health` returns OK
    - `http://127.0.0.1:19999/gpuaas/telemetry/netdata/` redirects to the locally
    detected working Netdata dashboard path
    - Netdata is no longer directly exposed on `0.0.0.0:19999`

    Manual verification commands:

    - `systemctl is-active netdata`
    - `systemctl is-active nginx`
    - `ss -ltnp | grep -E "127\\.0\\.0\\.1:19998|:19999"`
    - `curl -fsS http://127.0.0.1:19999/gpuaas/telemetry/health`
    - `curl -I http://127.0.0.1:19999/gpuaas/telemetry/netdata/`

    '
- id: B-V3-PRODUCTION-SUBPAGE-COMPLETION-001
  title: Complete remaining v3-prod Account Access Storage subpages before cutover
  role: B-ui
  status: done
  priority: 1
  owner: B
  branch: agent/B-ui
  completed_at: '2026-04-27'
  commit: a91d77a5
  depends_on:
  - B-V3-STORAGE-ACCESS-ACCOUNT-PRODUCTION-MIGRATION-001
  - B-V3-COMPUTE-APPS-PRODUCTION-MIGRATION-001
  acceptance_checks:
  - sh -lc 'test -f packages/web/app/v3-prod/account/profile/page.tsx && test -f packages/web/app/v3-prod/account/security/page.tsx'
  - sh -lc 'test -f packages/web/app/v3-prod/access/memberships/page.tsx && test -f packages/web/app/v3-prod/access/service-accounts/page.tsx'
  - pnpm --dir packages/web typecheck
  - pnpm --dir packages/web test
  - make queue-git-check
  notes: 'Move the remaining real v3 mock subpages into production-backed `/v3-prod`
    routes so the shell has no meaningful dead ends before internal cutover.

    Scope:

    - Account: profile, security, billing, sessions.
    - Access: memberships, service accounts, credentials, entitlements, connectivity,
    identity, audit.
    - Storage: standalone launch route if the production storage workbench exposes
    "New bucket".
    - Keep using v3 production primitives and read-model contracts; no V1 component
    fallback.

    This is UI-heavy and can be assigned to B.

    '
- id: A-V3-PERSONA-LANDING-READMODEL-CUTOVER-001
  title: Wire v3 persona landing defaults and tenant project admin read-models for cutover
  role: A-backend
  status: done
  priority: 1
  owner: codex
  branch: agent/A-backend
  completed_at: '2026-04-27'
  commit: 1abdbcd
  depends_on:
  - A-V3-SHELL-WORKLOADS-READMODEL-HANDLERS-001
  - A-V3-ACCESS-ACCOUNT-READMODEL-HANDLERS-001
  acceptance_checks:
  - rg -q "tenant_admin|project_admin|platform_admin|ops" doc/api openapi/generated cmd/api packages/web/src/lib
  - go test ./cmd/api
  - pnpm --dir packages/web typecheck
  - make queue-git-check
  notes: 'Before v3 becomes the internal default, multi-role users need deterministic
    landing behavior and read-model coverage for the current persona modes.

    Required outcome:

    - define/currently document the v3 landing route for user, tenant admin, project
    admin, platform admin, and ops personas.
    - ensure shell context exposes enough role/mode data for the UI to land users
    correctly without hardcoded demo assumptions.
    - add or complete temporary read-model handlers where tenant/project admin landings
    still depend on mock-only data.
    - keep contracts additive and generated types current.

    '
- id: B-V3-PROD-ROUTE-CUTOVER-FLAG-001
  title: Add controlled v3 product route cutover flag and route mapping
  role: B-ui
  status: done
  priority: 1
  owner: B
  branch: agent/B-ui
  completed_at: '2026-04-27'
  commit: debf8a6b
  depends_on:
  - B-V3-PRODUCTION-SUBPAGE-COMPLETION-001
  - A-V3-PERSONA-LANDING-READMODEL-CUTOVER-001
  acceptance_checks:
  - rg -q "NEXT_PUBLIC_V3|v3-prod|V3.*default|cutover" packages/web doc/product doc/operations
  - pnpm --dir packages/web typecheck
  - pnpm --dir packages/web test
  - make queue-git-check
  notes: 'Introduce a deliberate internal cutover switch instead of leaving v3-prod
    as a separate manual URL forever.

    Required outcome:

    - route users to v3 production surfaces by default when the flag is enabled.
    - preserve a short-lived V1 fallback path for demo/internal users until V1 retirement.
    - document the route mapping from current product routes to v3-prod surfaces.
    - keep the switch environment-driven so kind and platform-control can test the
    cutover independently.

    '
- id: C-V3-CUTOVER-KIND-E2E-SMOKE-001
  title: Run v3 cutover smoke in kind with persona and Playwright coverage
  role: C-ops
  status: done
  priority: 1
  owner: Codex
  branch: agent/C-ops
  completed_at: '2026-04-28'
  commit: b9c2da01
  depends_on:
  - B-V3-PROD-ROUTE-CUTOVER-FLAG-001
  - C-V3-KIND-QA-VALIDATION-HARNESS-001
  - C-FRONTEND-E2E-MODEL-REDESIGN-001
  acceptance_checks:
  - make kind-parity-validate
  - sh -lc 'E2E_SPEC=e2e/v3-shell.spec.ts bash scripts/ci/frontend_e2e.sh full'
  - make queue-git-check
  notes: 'Validate the v3 cutover in local kind before platform-control promotion.

    Required outcome:

    - kind parity environment runs with v3 default route flag enabled.
    - all seed personas can load their default landing without hitting mock-only
    paths or V1 chrome.
    - Playwright remains scoped to the v3 shell/workflow smoke, not broad V1 coverage.
    - capture failures as product, harness, or environment issues per
    `doc/governance/Frontend_E2E_Validation_Model_v1.md`.

    '
- id: C-V3-PLATFORM-CONTROL-CUTOVER-DEPLOY-001
  title: Promote and deploy v3 default route cutover to platform-control
  role: C-ops
  status: done
  priority: 1
  owner: Codex
  branch: agent/C-ops
  completed_at: '2026-04-28'
  commit: 3e169366
  depends_on:
  - C-V3-CUTOVER-KIND-E2E-SMOKE-001
  acceptance_checks:
  - sh -lc 'test -f dist/platform-control-release-candidate.env || true'
  - make queue-git-check
  notes: 'After local kind and scoped E2E pass, promote through the documented
    platform-control release process and monitor deployment until v3 routes are
    available for internal feedback.

    Required outcome:

    - use `scripts/ci/platform_control_promote_release_branch.sh`, not manual release
    branch editing.
    - enable the v3 default route flag in the target environment.
    - run remote validation/smoke appropriate to the cutover.
    - record any follow-up issues as tasks instead of patching V1 unless it is a live
    demo blocker.

    '
- id: A-V3-WORKLOAD-STORAGE-DETAIL-RICH-READMODELS-001
  title: Enrich v3 workload and storage detail read models to match mock expectations
  role: A-backend
  status: done
  priority: 1
  owner: codex
  branch: agent/A-backend
  completed_at: '2026-04-27'
  commit: e29e868d
  depends_on:
  - A-V3-PERSONA-LANDING-READMODEL-CUTOVER-001
  acceptance_checks:
  - rg -q "V3_Mock_To_Production_Data_Parity|V3Workload.*tabs|V3Storage.*tabs|mounted_workloads|primary_action" doc/product doc/api/openapi/domains/v3-read-models.yaml cmd/api packages/web/src/lib/v3
  - make codegen
  - go test ./cmd/api ./packages/shared/readcache
  - make queue-git-check
  notes: 'Close the biggest data-depth gap between `/v3` and `/v3-prod` before
    internal cutover.

    Required outcome:

    - workload detail read model exposes enough sanitized tab data for lifecycle,
      kind-aware connect, metrics source, events/tasks, storage mounts, and effective
      config.
    - storage detail read model populates objects, mounts, access audiences,
      lifecycle, and events with real data where available and deliberate empty
      states otherwise.
    - keep the contract provider-neutral and app-kind aware, per
      `doc/product/V3_Mock_To_Production_Data_Parity_v1.md` and the external
      architectural review.
    - do not add unrelated handlers to legacy `cmd/api/routes.go`; keep the v3
      domain route structure.

    '
- id: A-STORAGE-WEKA-IAM-SHARING-CONTRACT-001
  title: Add provider-neutral storage sharing and WEKA IAM contract baseline
  role: A-backend
  status: done
  priority: 1
  owner: codex
  branch: agent/A-backend
  completed_at: '2026-04-27'
  commit: 0a7bc2c2
  depends_on:
  - A-STORAGE-PROVIDER-CAPABILITY-MODEL-001
  acceptance_checks:
  - rg -q "Storage_Sharing_and_IAM_Model|storage.grant|storage.credential|weka|STS|shared-with" doc/architecture doc/api/openapi/domains packages/services/storage
  - make codegen
  - go test ./packages/services/storage ./cmd/api
  - make queue-git-check
  notes: 'Define the first storage IAM slice before implementing WEKA.

    Required outcome:

    - OpenAPI and schema direction for project-owned buckets/namespaces,
      prefix-capable grants, shared-with audiences, and short-lived direct S3
      credentials.
    - provider-neutral storage adapter interfaces for policy compilation and
      credential issuance, with WEKA as first backend.
    - human users remain GPUaaS principals; WEKA identities are derived provider
      principals for service accounts, workloads, or short-lived user sessions.
    - no raw provider credentials in read models or frontend.

    '
- id: A-STORAGE-WEKA-CAPABILITY-VALIDATION-001
  title: Validate WEKA S3 IAM, STS, service-account, policy, quota, and audit behavior
    against target cluster
  role: A-backend
  status: blocked
  priority: 1
  owner: Codex
  branch: master
  completed_at: ''
  commit: ''
  depends_on:
  - A-STORAGE-WEKA-IAM-SHARING-CONTRACT-001
  acceptance_checks:
  - rg -q "Storage_WEKA_Capability_Assessment|active STS revocation|service-account API ownership|policy size" doc/architecture
  - rg -q "weka.*sts|storage.*credential|storage.*grant|provider.*binding" doc/api/openapi.draft.yaml packages/services/storage
  - make queue-git-check
  notes: 'Blocked until the target WEKA cluster has at least one S3 protocol
    host/container enabled. The current cluster exposes the WEKA API and
    WEKAFS/POSIX filesystems, but S3 bucket/policy/user APIs return provider
    readiness errors because no S3 host is available.

    Run the design assumptions from Storage_WEKA_Capability_Assessment_v1.md
    against the target WEKA version before relying on the S3/STS adapter in
    production.

    Required outcome:

    - verify WEKA STS with restrictive policy can scope access by bucket, prefix,
      action, and TTL.
    - verify whether active STS credentials can be revoked individually, or only
      by deleting the parent S3 user / waiting for expiry.
    - verify service-account creation/removal API ownership: cluster admin versus
      parent S3 user, REST versus CLI.
    - verify generated policy byte limits and wildcard behavior for IAM policy,
      STS session policy, and bucket policy.
    - verify bucket quota, lifecycle, and S3 audit webhook behavior.
    - record exact target WEKA version, commands/API calls, observed behavior,
    and resulting adapter constraints.

    '
- id: C-STORAGE-WEKA-WEKAFS-PREFLIGHT-001
  title: Add read-only WEKA WEKAFS provider preflight for kind and platform-control
  role: C-ops
  status: done
  priority: 1
  owner: Codex
  branch: agent/C-ops
  completed_at: '2026-04-28'
  commit: dcd2df64
  depends_on:
  - A-STORAGE-WEKAFS-PROTOCOL-CONTRACT-001
  acceptance_checks:
  - bash -n scripts/ops/weka_wekafs_probe.sh
  - sh -lc 'WEKA_SERVER=http://127.0.0.1:14000 make ops-weka-wekafs-probe'
  - make queue-git-check
  notes: 'WEKA S3 is blocked until protocol hosts are enabled, but WEKAFS/POSIX
    filesystems are available now. Add a read-only provider preflight that logs
    in through WEKA REST API v2, verifies cluster health, checks expected
    GPUaaS filesystems (`gpuaas-kind-fs`, `gpuaas-fs`), and reports S3 readiness
    without creating filesystems, buckets, users, policies, mounts, or
    credentials.

    '
- id: A-V3-STORAGE-GRANT-HANDLERS-001
  title: Implement provider-neutral v3 storage grant handlers
  role: A-backend
  status: done
  priority: 1
  owner: codex
  branch: agent/A-backend
  completed_at: '2026-04-28'
  commit: f34b1851
  depends_on:
  - A-STORAGE-WEKA-IAM-SHARING-CONTRACT-001
  acceptance_checks:
  - rg -q "storage_grants" doc/architecture/db_schema_v1.sql cmd/api
  - rg -q "listV3StorageGrants|createV3StorageGrant|revokeV3StorageGrant" cmd/api
  - go test ./cmd/api ./packages/services/storage
  - go test ./...
  notes: 'Bridge the storage IAM contract into live v3 API handlers before B
    adds storage-sharing UI parity.

    Required outcome:

    - durable provider-neutral `storage_grants` records.
    - list/create/revoke endpoints for bucket grants under `/api/v1/v3/storage`.
    - mutating paths require idempotency and write privileged audit records.
    - credential issuance route is registered but fail-closed until WEKA/VAST
      provider behavior is validated.

    '
- id: A-V3-STORAGE-ATTACHMENT-HANDLERS-001
  title: Implement provider-neutral v3 storage attachment handlers
  role: A-backend
  status: done
  priority: 1
  owner: codex
  branch: agent/A-backend
  completed_at: '2026-04-28'
  commit: 5a4d6e3d
  depends_on:
  - A-STORAGE-WEKA-IAM-SHARING-CONTRACT-001
  - A-V3-STORAGE-GRANT-HANDLERS-001
  acceptance_checks:
  - rg -q "storage_attachments|listV3StorageAttachments|createV3StorageAttachment|detachV3StorageAttachment" cmd/api packages/web/src/lib/v3/api.ts
  - rg -q "storage.attachment.detach_requested|STORAGE" doc/api/asyncapi.draft.yaml doc/architecture/NATS_Stream_Config.md packages/shared/events
  - go test ./cmd/api ./packages/shared/events ./packages/services/storage
  - pnpm --dir packages/web typecheck
  notes: 'Bridge WEKAFS/POSIX storage attachment intent into the v3 production
    API without exposing provider secrets.

    Required outcome:

    - list/create/get/detach endpoints under `/api/v1/v3/storage/{bucket_id}/attachments`.
    - mutating paths require idempotency, write audit rows, and emit outbox-backed
      storage attachment events for workers.
    - read models prefer explicit `storage_attachments` rows for bucket and
      workload mount tabs, falling back to legacy placement metadata only when
      needed for demo continuity.
    - provider backend remains per bucket/attachment, not a single global product
      backend.

    '
- id: B-V3-STORAGE-SHARING-UX-PARITY-001
  title: Add storage sharing affordances to v3-prod storage pages
  role: B-ui
  status: done
  priority: 2
  owner: B
  branch: agent/B-ui
  completed_at: '2026-04-28'
  commit: a6ce9a22
  depends_on:
  - A-STORAGE-WEKA-IAM-SHARING-CONTRACT-001
  - B-V3-WORKLOAD-STORAGE-DETAIL-PARITY-001
  acceptance_checks:
  - rg -q "shared with|owner project|grant|S3 credentials|credential TTL" packages/web/src/components/v3 packages/web/e2e doc/product
  - pnpm --dir packages/web typecheck
  - pnpm --dir packages/web test
  - make queue-git-check
  notes: 'Expose storage sharing as a first-class product model once backend
    contracts exist.

    Required outcome:

    - storage workbench differentiates owned buckets from buckets shared with
      the active project.
    - bucket detail shows owner project, access audiences/grants, and attached
      workloads without exposing provider secrets.
    - direct S3 credential action shows TTL and allowed bucket/prefix summary.
    - launch flows can choose read-only shared datasets/artifacts and writable
      output/checkpoint buckets.

    '
- id: B-V3-WORKLOAD-STORAGE-DETAIL-PARITY-001
  title: Render v3-prod workload and storage detail tabs with enriched read-model data
  role: B-ui
  status: done
  priority: 1
  owner: Codex
  branch: agent/B-ui
  completed_at: '2026-04-28'
  commit: 3645e2c5
  depends_on:
  - B-V3-PROD-ROUTE-CUTOVER-FLAG-001
  - A-V3-WORKLOAD-STORAGE-DETAIL-RICH-READMODELS-001
  acceptance_checks:
  - rg -q "V3_Mock_To_Production_Data_Parity|SectionTabs|connect|metrics|objects|mounts|lifecycle" packages/web/src/components/v3 packages/web/e2e doc/product
  - pnpm --dir packages/web typecheck
  - pnpm --dir packages/web test
  - make queue-git-check
  notes: 'Use the enriched read models to bring `/v3-prod/workloads/{id}` and
    `/v3-prod/storage/{id}` closer to the approved `/v3` mock.

    Required outcome:

    - workload detail renders kind-aware connect/action content for compute,
      Jupyter, vLLM, and training when present.
    - workload detail renders lifecycle, recent activity/events, metrics placeholder
      or source, storage mounts, and config using read-model payloads.
    - storage detail renders tabbed overview, objects, mounts, access, lifecycle,
      and events; no mock-only static payloads.
    - preserve safe empty states where backend data is not yet available.

    '
- id: A-V3-KIND-DEMO-READMODEL-RICHNESS-001
  title: Enrich kind/demo v3 read-model data so v3-prod compares fairly to approved mocks
  role: A-backend
  status: done
  priority: 1
  owner: Codex
  branch: agent/A-backend
  completed_at: '2026-04-27'
  commit: 09af9d76
  depends_on:
  - A-V3-WORKLOAD-STORAGE-DETAIL-RICH-READMODELS-001
  - A-V3-PLATFORM-READMODEL-HANDLERS-001
  acceptance_checks:
  - rg -q "v3.*demo|storage.*bucket|platform.*health|app.*example|mock-to-production" scripts
    cmd/api packages/web/e2e doc/product
  - go test ./cmd/api
  - pnpm --dir packages/web typecheck
  - ruby scripts/ops/agent_queue_store.rb --queue-file doc/governance/Agent_Work_Queue.yaml
    validate
  - make queue-git-check
  notes: 'The approved `/v3` mock is visually rich because fixtures include buckets,
    mounts, app examples, platform health/action items, and realistic workload context.
    The kind `/v3-prod` smoke currently proves route correctness but can look empty
    or thin because seed/read-model data is sparse.

    Required outcome:

    - add or extend deterministic local/kind seed/read-model fixtures so internal
    review sees representative storage buckets, mounts, access audiences, platform
    health/action items, and app/workload context without requiring live external
    providers.

    - keep demo data clearly local/dev scoped; do not hardcode production business
    policy constants in handlers.

    - prefer real schema/seed/read-model paths over frontend-only mock fallbacks so
    `/v3-prod` remains a production-path validation surface.

    - document any remaining data that must come from real providers such as WEKA,
    Netdata, MAAS, or billing systems as accepted future-product gaps.

    '
- id: B-V3-APPS-VISUAL-FIDELITY-001
  title: Bring v3-prod Apps catalog visual treatment up to approved v3 mock fidelity
  role: B-ui
  status: done
  priority: 1
  owner: B
  branch: agent/B-ui
  completed_at: '2026-04-27'
  commit: e2b2a52a
  depends_on:
  - B-V3-COMPUTE-APPS-PRODUCTION-MIGRATION-001
  acceptance_checks:
  - rg -q "hero|glyph|featured|publisher|v3-apps" packages/web/src/components/v3
    packages/web/e2e
  - pnpm --dir packages/web typecheck
  - pnpm --dir packages/web test
  - make queue-git-check
  notes: 'The approved `/v3/apps` mock uses colorful featured app cards, app glyphs,
    publisher chips, and strong launch/detail CTAs. The current `/v3-prod/apps`
    production rendering is structurally correct but too grayscale/plain for the
    expectation set by the mock.

    Required outcome:

    - preserve production read-model binding; do not import fixture data from
    `app/v3`.

    - add a small deterministic presentation mapping for known app slugs/categories
    with safe fallbacks for unknown/community apps.

    - featured cards should match the mock hierarchy: colored hero mark/glyph,
    category/kind/version/pricing, publisher tone, Launch and Details CTAs.

    - compact cards should keep the same visual language and remain responsive.

    '
- id: B-V3-COMPUTE-CATALOG-VISUAL-FIDELITY-001
  title: Replace v3-prod Compute table-first catalog with mock-aligned SKU cards
  role: B-ui
  status: done
  priority: 1
  owner: B
  branch: agent/B-ui
  completed_at: '2026-04-27'
  commit: c7253e49
  depends_on:
  - B-V3-COMPUTE-APPS-PRODUCTION-MIGRATION-001
  acceptance_checks:
  - rg -q "SkuCard|capacity|availability|v3-compute" packages/web/src/components/v3
    packages/web/e2e
  - pnpm --dir packages/web typecheck
  - pnpm --dir packages/web test
  - make queue-git-check
  notes: 'The current `/v3-prod/compute` page is functional but presents SKUs as
    an admin-like table. For internal review, Compute should feel like the approved
    product catalog: card-first, capacity-aware, and launch-oriented.

    Required outcome:

    - render a responsive SKU card or card/table hybrid using existing read-model
    fields: capacity shape, vendor, GPU count, hourly rate, availability, and launch
    href.

    - keep provider-neutral copy and styling; do not make vendor-specific behavior
    assumptions beyond displaying read-model vendor names.

    - preserve filters, empty/error/loading states, and stable v3 selectors.

    '
- id: B-V3-STORAGE-LAUNCH-PRODUCTION-001
  title: Add production v3 storage launch wizard route
  role: B-ui
  status: done
  priority: 1
  owner: B
  branch: agent/B-ui
  completed_at: '2026-04-27'
  commit: 7ce9f6a7
  depends_on:
  - B-V3-STORAGE-ACCESS-ACCOUNT-PRODUCTION-MIGRATION-001
  - B-V3-WIZARD-PRODUCTION-FOUNDATION-001
  acceptance_checks:
  - sh -lc 'test -f packages/web/app/v3-prod/launch/storage/page.tsx'
  - rg -q "v3-prod/launch/storage|createLocalDraftStore|InlineCreator|New bucket"
    packages/web/src packages/web/app/v3-prod packages/web/e2e
  - pnpm --dir packages/web typecheck
  - pnpm --dir packages/web test
  - make queue-git-check
  notes: 'The approved mock includes `/v3/launch/storage`, and `/v3-prod/storage`
    exposes the storage workbench as a real top-level group. Production still lacks
    the standalone storage launch route, so the New bucket flow is incomplete.

    Required outcome:

    - add `/v3-prod/launch/storage` using the production wizard foundation.

    - support backward clickable steps, draft persistence, review summary, and safe
    staged submit behavior until storage create mutation is assigned.

    - keep WEKA/VAST/vendor details out of the UI contract; use provider-neutral
    language such as bucket, quota, encryption, lifecycle, access, and mount intent.

    - wire the `/v3-prod/storage` New bucket CTA to the new route.

    '
- id: C-V3-MOCK-PROD-VISUAL-DATA-PARITY-001
  title: Compare approved v3 mock against v3-prod before platform-control cutover
  role: C-ops
  status: done
  priority: 1
  owner: Codex
  branch: agent/C-ops
  completed_at: '2026-04-28'
  commit: 9038e899
  depends_on:
  - B-V3-WORKLOAD-STORAGE-DETAIL-PARITY-001
  - A-V3-KIND-DEMO-READMODEL-RICHNESS-001
  - B-V3-APPS-VISUAL-FIDELITY-001
  - B-V3-COMPUTE-CATALOG-VISUAL-FIDELITY-001
  - B-V3-STORAGE-LAUNCH-PRODUCTION-001
  - C-V3-CUTOVER-KIND-E2E-SMOKE-001
  acceptance_checks:
  - rg -q "mock-to-production|visual/data parity|read-model gap|rendering gap" doc/product doc/operations
  - sh -lc 'E2E_SPEC=e2e/v3-shell.spec.ts bash scripts/ci/frontend_e2e.sh full'
  - make queue-git-check
  notes: 'Visual approval of `/v3` is not sufficient proof that `/v3-prod` is
    ready. Run a focused parity pass before promoting platform-control.

    Required outcome:

    - compare the approved mock routes against production routes listed in
      `doc/product/V3_Mock_To_Production_Data_Parity_v1.md`.
    - classify any mismatch as read-model gap, rendering gap, seed gap, or
      accepted future-product gap.
    - do not block on future billing/networking epics, but do block on thin
    workload/storage detail pages if they fail the expectation set by the mock.

    '
- id: B-V3-SCHEDULERS-GUIDANCE-CUTOVER-001
  title: Add v3 scheduler guidance route and cutover mapping
  role: B-ui
  status: done
  priority: 2
  owner: Codex
  branch: agent/B-ui
  completed_at: '2026-04-28'
  commit: aef8e611
  depends_on:
  - B-V3-PROD-ROUTE-CUTOVER-FLAG-001
  acceptance_checks:
  - sh -lc 'test -f packages/web/app/v3-prod/schedulers/page.tsx'
  - rg -q "/v3-prod/schedulers|v3-schedulers-page" packages/web/src doc/product
  - pnpm --dir packages/web exec vitest run src/lib/cutover/route-map.test.ts
  - pnpm --dir packages/web typecheck
  - make queue-git-check
  notes: 'Migrated the lightweight scheduler guidance route into v3-prod and
    mapped `/schedulers` to it. Tenant-shared scheduler remains a deliberate
    pilot exception at `/schedulers/tenant-shared` until runtime contracts
    settle. The route reinforces the v3 model: scheduler systems are app-backed
    workloads governed through Apps, Workloads, and Access rather than an eighth
    shell group.

    '
- id: B-V1-UI-RETIRE-AFTER-V3-CUTOVER-001
  title: Retire old V1 UI routes after v3 internal cutover is accepted
  role: B-ui
  status: blocked
  priority: 2
  owner: ''
  branch: agent/B-ui
  completed_at: ''
  commit: ''
  depends_on:
  - C-V3-PLATFORM-CONTROL-CUTOVER-DEPLOY-001
  acceptance_checks:
  - rg -q "V1 retired|legacy UI|v3 default" packages/web doc/product doc/operations
  - pnpm --dir packages/web typecheck
  - pnpm --dir packages/web test
  - make queue-git-check
  notes: 'Blocked until internal users have reviewed the v3 default route on platform-control.

    Required outcome:

    - remove or quarantine old V1 product/admin surfaces that are superseded by v3.
    - keep only explicit compatibility/debug routes that are still needed for demo
    continuity.
    - update docs so new work lands in v3 surfaces only.
    - reduce test scope accordingly so CI no longer carries broad V1 Playwright debt.

    '
- id: A-NODE-AGENT-STORAGE-MOUNT-TASKS-001
  title: Add fail-closed node-agent storage mount task validators
  role: A-backend
  status: done
  priority: 1
  owner: Codex
  branch: agent/A-backend
  completed_at: '2026-04-28'
  commit: cc6d3fae
  depends_on:
  - A-V3-STORAGE-ATTACHMENT-HANDLERS-001
  acceptance_checks:
  - rg -q "storage.mount_attach|storage.mount_detach|storage.mount_probe" cmd/node-agent
    doc/architecture/Node_Agent_Spec.md
  - go test ./cmd/node-agent
  - go test ./...
  - make queue-git-check
  notes: 'Node-agent now recognizes storage mount attach, detach, and probe tasks.
    Payload validation is fail-closed: UUIDs, provider backend, source roots, mount
    roots, access mode, write policy, and uid/gid are validated before any runner
    is called. Runtime mount execution remains disabled unless
    `GPUAAS_STORAGE_MOUNT_EXECUTION` is explicitly enabled, so the task catalog
    can be deployed before provider-specific WEKAFS side effects are wired.

    '
- id: A-STORAGE-ATTACHMENT-NOOP-WORKFLOW-001
  title: Add local/dev no-op storage attachment workflow
  role: A-backend
  status: done
  priority: 1
  owner: Codex
  branch: agent/A-backend
  completed_at: '2026-04-28'
  commit: 4973e551
  depends_on:
  - A-V3-STORAGE-ATTACHMENT-HANDLERS-001
  - A-NODE-AGENT-STORAGE-MOUNT-TASKS-001
  acceptance_checks:
  - rg -q "SubjectStorageAttachmentRequested|SubjectStorageAttachmentDetachRequested|HandleStorageAttachmentRequested" cmd/provisioning-worker
    packages/services/storage
  - go test ./cmd/provisioning-worker ./packages/services/storage
  - go test ./...
  - make queue-git-check
  notes: 'Provisioning worker now consumes storage attachment requested and detach
    requested events through the same Temporal lane used for allocation lifecycle
    work. The first workflow implementation records durable mounted/detached state
    transitions and outbox-backed lifecycle events without real provider side
    effects. This keeps v3 UI flows usable in local/kind while WEKAFS mount-plan
    execution is implemented separately.

    '
- id: A-STORAGE-WEKAFS-MOUNT-PLAN-COMPILER-001
  title: Add WEKAFS/local-dev storage attachment mount-plan compiler
  role: A-backend
  status: done
  priority: 1
  owner: Codex
  branch: agent/A-backend
  completed_at: '2026-04-28'
  commit: 30d02f65
  depends_on:
  - A-STORAGE-ATTACHMENT-NOOP-WORKFLOW-001
  acceptance_checks:
  - rg -q "BuildAttachmentMountPlan|gpuaas-kind-fs|ProviderFilesystem|provider_mount_ref" packages/services/storage
    cmd/api
  - go test ./packages/services/storage ./cmd/api ./cmd/provisioning-worker
  - go test ./...
  - make queue-git-check
  notes: 'Storage attachment workflows now compile provider-neutral intent into a
    sanitized local mount plan. WEKA plans resolve to
    `/mnt/weka/<filesystem>/projects/<project>/<bucket>` or the configured
    `GPUAAS_STORAGE_WEKA_MOUNT_ROOT`; local-dev plans resolve under
    `GPUAAS_STORAGE_LOCAL_MOUNT_ROOT` or `/var/lib/gpuaas/storage`. The workflow
    stores the generated source reference in `provider_mount_ref` without
    exposing raw provider commands or credentials.

    '
- id: A-STORAGE-ATTACHMENT-NODE-TASK-DISPATCH-001
  title: Add opt-in storage attachment node-task dispatch bridge
  role: A-backend
  status: done
  priority: 1
  owner: Codex
  branch: agent/A-backend
  completed_at: '2026-04-28'
  commit: 9ee06f8f
  depends_on:
  - A-STORAGE-WEKAFS-MOUNT-PLAN-COMPILER-001
  acceptance_checks:
  - rg -q "STORAGE_ATTACHMENT_NODE_TASKS_ENABLED|NewPostgresNodeTaskDispatcher|storage.mount_attach|storage.mount_detach" cmd/provisioning-worker packages/services/storage doc/architecture/Storage_Attachment_Workflow_v1.md
  - go test ./packages/services/storage ./cmd/provisioning-worker
  - go test ./...
  - make queue-git-check
  notes: 'Bridge accepted storage attachment intent into signed node-agent mount
    tasks without making real mount execution the default.

    Required outcome:

    - provisioning worker keeps local/kind no-op behavior unless
      `STORAGE_ATTACHMENT_NODE_TASKS_ENABLED=true`.
    - with the flag enabled, attach records `mounting`, dispatches
      `storage.mount_attach`, waits for node-task terminal state, then records
      `mounted`.
    - detach records `detaching`, dispatches `storage.mount_detach`, waits for
      node-task terminal state, then records `detached`.
    - node-task failure maps to `failed` or `detach_failed` with storage lifecycle
      outbox events and no provider credentials in task output/read models.

    '
- id: A-STORAGE-PROVIDER-PLACEMENT-ASSIGNMENT-001
  title: Persist per-bucket storage provider placement assignment
  role: A-backend
  status: done
  priority: 1
  owner: Codex
  branch: agent/A-backend
  completed_at: '2026-04-28'
  commit: 0ca271ef
  depends_on:
  - A-STORAGE-PROVIDER-CAPABILITY-MODEL-001
  - A-V3-STORAGE-ATTACHMENT-HANDLERS-001
  acceptance_checks:
  - rg -q "ResolveProviderAssignment|provider_instance_id|provider_filesystem" packages/services/storage
    cmd/api doc/architecture/db_schema_v1.sql
  - go test ./packages/services/storage ./cmd/api
  - go test ./...
  - make queue-git-check
  notes: 'Storage bucket creation must not assume a single region-wide provider
    backend. Persist provider backend, provider filesystem, and provider instance
    on the bucket so regions can host WEKA, VAST, local-dev, or multiple storage
    instances side by side. Attachments and grants inherit the persisted bucket
    placement instead of re-reading a global default.

    '
- id: A-STORAGE-WEKAFS-PROTOCOL-CONTRACT-001
  title: Make WEKAFS/POSIX the explicit first storage access protocol
  role: A-backend
  status: done
  priority: 1
  owner: Codex
  branch: agent/A-backend
  completed_at: '2026-04-28'
  commit: 40ba88b8
  depends_on:
  - A-STORAGE-PROVIDER-PLACEMENT-ASSIGNMENT-001
  acceptance_checks:
  - rg -q "access_protocol|V3StorageAccessProtocol|ProviderSupportsProtocol" doc/api/openapi.draft.yaml
    doc/api/openapi/domains/v3-read-models.yaml cmd/api packages/services/storage
  - make codegen
  - go test ./packages/services/storage ./cmd/api
  - pnpm --dir packages/web typecheck
  - pnpm --dir packages/web test
  - go test ./...
  - make queue-git-check
  notes: 'The target WEKA cluster currently has WEKAFS/POSIX available while S3
    protocol hosts are not enabled. Persist the selected storage access protocol
    on each storage bucket, default new v3 bucket creation to WEKAFS, expose the
    protocol in v3 read models, and reject unsupported protocol requests before
    any provider/local storage side effect.

    '
- id: B-V3-CUTOVER-ROUTE-MAP-COVERAGE-001
  title: Cover legacy app, access, settings, and admin routes in v3 cutover
  role: B-ui
  status: done
  priority: 1
  owner: Codex
  branch: agent/B-ui
  completed_at: '2026-04-28'
  commit: d1ff9847
  depends_on:
  - B-V3-PROD-ROUTE-CUTOVER-FLAG-001
  acceptance_checks:
  - pnpm --dir packages/web test -- src/lib/cutover/route-map.test.ts
  - rg -q "/apps/instances|/settings/ssh-keys|/admin/nodes|/iam/service-accounts" packages/web/src/lib/cutover/route-map.ts doc/product/V3_Cutover_Route_Map_v1.md
  - make queue-git-check
  notes: 'Expanded the explicit v3 cutover route map so legacy app catalog,
    app instances, app artifacts, settings, IAM, quotas, and admin operational
    routes land on the intended v3-prod surfaces instead of falling through or
    being interpreted as app slugs. App instances and allocation detail collapse
    into the v3 Workloads workbench by design.

    '
- id: B-V3-ACCESS-FUTURE-SURFACES-PRODUCTION-001
  title: Add production v3 Access connectivity identity and audit surfaces
  role: B-ui
  status: done
  priority: 1
  owner: Codex
  branch: agent/B-ui
  completed_at: '2026-04-28'
  commit: 2d12e677
  depends_on:
  - B-V3-PRODUCTION-SUBPAGE-COMPLETION-001
  - B-V3-CUTOVER-ROUTE-MAP-COVERAGE-001
  acceptance_checks:
  - sh -lc 'test -f packages/web/app/v3-prod/access/connectivity/page.tsx && test -f packages/web/app/v3-prod/access/identity/page.tsx && test -f packages/web/app/v3-prod/access/audit/page.tsx'
  - rg -q "v3-access-connectivity-page|v3-access-identity-page|v3-access-audit-page" packages/web/src/components/v3
  - pnpm --dir packages/web typecheck
  - pnpm --dir packages/web test
  - make queue-git-check
  notes: 'Closed the production route gap for Access sub-surfaces that were visible
    in the approved v3 mock but absent from `/v3-prod`: connectivity, identity,
    and access audit. These pages are production-safe scope surfaces that link to
    current sources of record and avoid fake provider data until network/security,
    SSO, and filtered access-audit read models are implemented.

    '
- id: B-V3-PERSONA-LANDING-PRODUCTION-001
  title: Add production v3 tenant and project persona landings
  role: B-ui
  status: done
  priority: 1
  owner: Codex
  branch: agent/B-ui
  completed_at: '2026-04-28'
  commit: e360003b
  depends_on:
  - A-V3-PERSONA-LANDING-READMODEL-CUTOVER-001
  - B-V3-ACCESS-FUTURE-SURFACES-PRODUCTION-001
  acceptance_checks:
  - sh -lc 'test -f packages/web/app/v3-prod/tenant/overview/page.tsx
    && test -f packages/web/app/v3-prod/project/overview/page.tsx'
  - rg -q "/v3-prod/tenant/overview|/v3-prod/project/overview" cmd/api packages/web/src
    doc/product
  - go test ./cmd/api -run 'TestV3ShellContext|TestV3'
  - go test ./cmd/api
  - pnpm --dir packages/web typecheck
  - pnpm --dir packages/web test
  - make queue-git-check
  notes: 'Added first-cutover production tenant and project overview routes backed
    by existing v3 shell, access, account, and workload read models. Backend-owned
    shell mode defaults now send tenant admins to `/v3-prod/tenant/overview` and
    project admins to `/v3-prod/project/overview`; richer dedicated governance and
    spend read models remain future work.

    '
- id: B-V3-DEVELOPER-API-DOCS-ELEMENTS-001
  title: Embed Stoplight Elements as the primary v3 API reference
  role: B-ui
  status: todo
  priority: 3
  owner: ''
  branch: agent/B-ui
  completed_at: ''
  commit: ''
  depends_on:
  - B-V1-UI-RETIRE-AFTER-V3-CUTOVER-001
  acceptance_checks:
  - sh -lc 'test -f packages/web/app/v3-prod/developer/api/page.tsx'
  - sh -lc 'rg -q "Stoplight|Elements|API reference|Swagger fallback" packages/web doc/product'
  - pnpm --dir packages/web typecheck
  - pnpm --dir packages/web test
  - make queue-git-check
  notes: 'Deferred until after the main v3 migration/cutover is complete.

    Goal:

    - make `/v3-prod/developer/api` the integrated API reference inside the v3
    shell using Stoplight Elements against the generated OpenAPI document
    - keep Swagger UI as a secondary raw/debug route until the developer portal
    is fully stable
    - remove or demote ReDoc after the Elements surface is accepted

    Requirements:

    - preserve the contract-first source of truth in `doc/api/openapi.draft.yaml`
    and generated artifacts
    - "Try it" must not pass tokens in query strings; use the current browser
    session or an explicit bearer-header flow only
    - no vendor lock-in to hosted Stoplight workspaces; use the embeddable
    Elements package/component
    - add a short product/developer-doc note explaining primary API reference,
    Swagger fallback, and auth behavior

    '
- id: B-V3-K8S-INTEGRATED-UI-RESEARCH-AND-IMPLEMENTATION-001
  title: Research and implement integrated Kubernetes UI for v3 workloads
  role: B-ui
  status: todo
  priority: 3
  owner: ''
  branch: agent/B-ui
  completed_at: ''
  commit: ''
  depends_on:
  - B-V1-UI-RETIRE-AFTER-V3-CUTOVER-001
  acceptance_checks:
  - sh -lc 'test -f doc/product/V3_Kubernetes_UI_Integration_Options_v1.md'
  - sh -lc 'rg -q "Headlamp|backstage-plugin|Headlamp as a Library|Kubernetes UI" doc/product packages/web'
  - pnpm --dir packages/web typecheck
  - pnpm --dir packages/web test
  - make queue-git-check
  notes: 'Deferred until after the main v3 migration/cutover is complete.

    Goal:

    - provide an integrated Kubernetes view for app/workload operators without
    forcing users into a separate dashboard unless that proves safer
    - evaluate `@headlamp-k8s/backstage-plugin`, Headlamp as a Library, a
    standalone proxied Headlamp deployment, and any viable lighter-weight
    Kubernetes UI alternative
    - decide whether the surface belongs under Workloads detail, Apps runtime
    detail, Platform/Ops, or a role-scoped Developer/Operations page

    Research requirements:

    - auth model: map GPUaaS user/project/role to Kubernetes access without
    broad cluster-admin leakage
    - multi-cluster and namespace scoping: support future tenant/project
    isolation and prevent cross-project visibility
    - proxy/session model: no query-string tokens; preserve current platform
    proxy/browser-session rules
    - operational scope: show pods, events, logs, exec, services/ingress, PVCs,
    and health in a way that does not duplicate Netdata/fleet telemetry
    - implementation recommendation with tradeoffs, security risks, and phased
    rollout plan before coding the production UI

    '
- id: A-V3-USER-RUNTIME-FLOW-CUTOVER-HARDENING-001
  title: Harden v3 user runtime flow read models and launch handoffs for V1 retirement
  role: A-backend
  status: done
  priority: 1
  owner: Codex
  branch: agent/A-backend
  completed_at: '2026-04-30'
  commit: d7ae82b4
  depends_on:
  - A-V3-LAUNCH-SUBMIT-HANDLERS-001
  - A-V3-WORKLOAD-STORAGE-DETAIL-RICH-READMODELS-001
  - A-STORAGE-WEKAFS-PROTOCOL-CONTRACT-001
  acceptance_checks:
  - rg -q "launch_dependencies|app_proxy_launch|V3_User_Workflow_Demo_Runbook" cmd/api packages/services/inventory doc/product
  - go test ./cmd/api -run 'TestV3.*(Workload|Launch|Task)|TestPlatformProxy'
  - go test ./packages/services/inventory
  - pnpm --dir packages/web exec tsc --noEmit
  - make queue-git-check
  notes: 'Focus the migration on the complete user runtime flow, not isolated demo
    patches.

    Required outcome:

    - compute launch, app launch, task detail, workload detail, app proxy launch,
    metrics links, and storage/dependency handoffs are backed by v3 read models
    and contracts.
    - no core runtime flow depends on a V1 allocation page or V1 app-instance page
    except deliberately external compatibility routes such as terminal popout or
    platform proxy.
    - app launch dependencies selected in the v3 wizard are persisted into the
    app-instance domain so runtime reconciliation, storage attachment, and recovery
    paths can use the same launch context.
    - kind verification remains the fast validation target; do not deploy
    platform-control for this task.

    '
- id: B-V3-WORKLOAD-DETAIL-USER-FLOW-POLISH-001
  title: Polish v3 workload detail connect metrics storage and runtime tabs for user cutover
  role: B-ui
  status: done
  priority: 1
  owner: B
  branch: agent/B-ui
  completed_at: '2026-04-30'
  commit: 4503a080
  depends_on:
  - A-V3-USER-RUNTIME-FLOW-CUTOVER-HARDENING-001
  - B-V3-SHELL-WORKLOADS-PRODUCTION-MIGRATION-001
  acceptance_checks:
  - rg -q "v3-workload-detail-page|Connect|Runtime metrics|Storage" packages/web/src/components/v3 packages/web/e2e
  - pnpm --dir packages/web typecheck
  - pnpm --dir packages/web test
  - make queue-git-check
  notes: 'UI-heavy follow-up for B after the backend/read-model handoffs are stable.

    Required outcome:

    - workload detail should feel as complete as the approved `/v3` mock for the
    end-user flow: resource header, context strip, connect/app-open, metrics,
    events/tasks, storage, and config.
    - render null/empty telemetry fields deliberately; never crash when GPU devices
    or network interfaces are absent or temporarily unavailable.
    - app-backed workloads should show the correct primary action and error state
    for platform proxy browser-session launch.
    - compute workloads should keep browser terminal and SSH command affordances
    clear without leaking V1 allocation-page concepts into the v3 surface.

    '
- id: C-V3-ADMIN-OPS-RETIREMENT-COVERAGE-001
  title: Close admin and ops route coverage before V1 UI retirement
  role: C-ops
  status: done
  priority: 2
  owner: codex
  branch: agent/C-ops
  completed_at: '2026-04-30'
  commit: 9d1d240d
  depends_on:
  - B-V3-PROD-ROUTE-CUTOVER-FLAG-001
  - B-V3-PLATFORM-PRODUCTION-MIGRATION-001
  acceptance_checks:
  - rg -q "admin|ops|v3-prod/platform" doc/product/V3_Cutover_Route_Map_v1.md packages/web/src/lib/cutover
  - pnpm --dir packages/web test -- src/lib/cutover/route-map.test.ts
  - make queue-git-check
  notes: 'Keep V1 available only while migration coverage is incomplete, but make
    the retirement criteria explicit.

    Required outcome:

    - enumerate remaining admin/ops V1 routes and classify them as migrated,
    deliberately deferred, or compatibility-only.
    - ensure platform overview, ops, lifecycle, config, evidence, finance, and IAM
    v3-prod pages cover the current operator workflows well enough for internal
    users to stop depending on V1.
    - replace V1-style entity dumps with intent/workflow pages: live triage,
    lifecycle intervention, configuration publishing, evidence investigation,
    finance intervention, and IAM/role governance.
    - capture any Netdata/nginx, terminal edge, MAAS, or node-agent operational
    gaps as ops/backend tasks instead of keeping V1 UI routes alive by default.

    '
- id: A-V3-PLATFORM-WORKFLOW-READMODEL-DETAILS-001
  title: Enrich platform workflow read models for admin and ops V3 cutover
  role: A-backend
  status: done
  priority: 1
  owner: Codex
  branch: agent/A-backend
  completed_at: '2026-04-30'
  commit: 98aa7b7e
  depends_on:
  - C-V3-ADMIN-OPS-RETIREMENT-COVERAGE-001
  acceptance_checks:
  - go test ./cmd/api -run 'TestV3Platform|TestV3.*ReadModel'
  - rg -q "v3.*platform.*workflow|lifecycle.*intervention|config.*publish|evidence.*pivot|finance.*intervention|iam.*governance" cmd/api doc/product
  - ruby scripts/ops/agent_queue_store.rb --queue-file doc/governance/Agent_Work_Queue.yaml validate
  - make queue-git-check
  notes: 'The remaining admin/ops migration risk is not route count; it is whether
    V3 platform pages answer operator questions without falling back to V1 entity
    dumps.

    Required outcome:

    - extend `/api/v1/v3/platform/*` read models where needed so Platform Ops,
    Lifecycle, Config, Evidence, Finance, and IAM can render workflow-first
    pages.
    - lifecycle should expose intervention queues, active onboarding/reimage/decommission
    workflow summaries, node detail links, and task/history pivots.
    - config should expose publish/draft state for SKUs, OS images, MAAS profiles,
    and policy values without sending users to V1 admin forms.
    - evidence should expose correlation-first pivots, audit detail payloads, and
    export/search affordances.
    - finance should expose payment-session intervention reasons and recovery actions
    without raw ledger dumping.
    - IAM should expose user/role governance, stale/offboarding signals, and platform
    role posture.
    - keep all links on `/v3-prod/platform/*` or explicit utility surfaces; no new
    `/admin/*` links from V3 read models.

    Out of scope:

    - visual polish; B owns UI composition after the read-model contract is stable.
    - Netdata nginx edge redesign and node-agent cert recovery; those stay separate
    ops/backend tasks.

    '
- id: B-V3-PLATFORM-WORKFLOW-POLISH-001
  title: Turn V3 platform admin and ops pages into workflow workbenches
  role: B-ui
  status: done
  priority: 1
  owner: B
  branch: agent/B-ui
  completed_at: '2026-04-30'
  commit: 01155ee1
  depends_on:
  - A-V3-PLATFORM-WORKFLOW-READMODEL-DETAILS-001
  - B-V3-PLATFORM-PRODUCTION-MIGRATION-001
  acceptance_checks:
  - pnpm --dir packages/web exec tsc --noEmit
  - pnpm --dir packages/web exec vitest run src/lib/cutover/route-map.test.ts
  - rg -q "V3PlatformOpsPage|V3PlatformLifecyclePage|V3PlatformConfigPage|V3PlatformEvidencePage|V3PlatformFinancePage|V3PlatformIAMPage" packages/web/src/components/v3/v3-platform-pages.tsx
  - ruby scripts/ops/agent_queue_store.rb --queue-file doc/governance/Agent_Work_Queue.yaml validate
  - make queue-git-check
  notes: 'B-owned UI task after A enriches the platform read models.

    Required outcome:

    - Platform Ops reads as live triage: action band, health summary, runbook/tool
    pivots, and clear severity ordering.
    - Lifecycle reads as intervention workflow: active nodes, blocked/draining/onboarding/reimage
    queues, node/task pivots, and no raw table dump as the primary experience.
    - Config reads as durable platform setup: SKU/image/MAAS/policy sections with
    publish/draft state and safe change affordances.
    - Evidence reads as investigation: filter-first audit/event rows, detail drawer,
    correlation/log/trace pivots, and export as a secondary action.
    - Finance reads as intervention: stuck/failed sessions first, reason hints and
    recovery actions before the ledger table.
    - IAM reads as governance: user/platform role posture, stale/offboarding signals,
    and privileged mutation affordances.
    - preserve the approved V3 visual language and avoid reintroducing V1 admin
    chrome, entity dumps, or `/admin/*` navigation from V3 pages.

    '
- id: C-V3-V1-RETIREMENT-GUARDRAILS-001
  title: Add V1 retirement guardrails and prune broad V1 frontend validation path
  role: C-ops
  status: done
  priority: 2
  owner: Codex
  branch: agent/C-ops
  completed_at: '2026-04-30'
  commit: 921e7e41
  depends_on:
  - B-V3-PLATFORM-WORKFLOW-POLISH-001
  - C-V3-ADMIN-OPS-RETIREMENT-COVERAGE-001
  acceptance_checks:
  - rg -q "v1 retirement|v3 cutover|compatibility-only|frontend e2e" doc/governance doc/product scripts packages/web/e2e
  - pnpm --dir packages/web exec vitest run src/lib/cutover/route-map.test.ts
  - ruby scripts/ops/agent_queue_store.rb --queue-file doc/governance/Agent_Work_Queue.yaml validate
  - make queue-git-check
  notes: 'Once the V3 user, platform, admin, and ops workflows are accepted, stop
    spending default validation time on broad V1 UI coverage.

    Required outcome:

    - document which V1 routes remain compatibility-only during the final internal
    cutover window and what condition removes each one.
    - update frontend validation guidance so V3 smoke and route-map tests are the
    primary gate; V1 tests remain only for deliberate compatibility pages or known
    demo fallbacks.
    - ensure the cutover route map does not silently redirect unknown routes, but
    does cover every V1 route intentionally retired.
    - keep `/v3` mock routes available as visual references until V3 production
    parity is accepted.

    Out of scope:

    - deleting V1 route files; that happens only after this guardrail task proves
    no internal user workflow depends on them.

    '
- id: B-V3-LIFECYCLE-OPERATION-AFFORDANCES-001
  title: Standardize V3 lifecycle operation affordances across mutable resource pages
  role: B-ui
  status: done
  priority: 1
  owner: codex
  branch: agent/B-ui
  completed_at: '2026-05-02'
  commit: 43a55d3f
  depends_on:
  - C-V3-V1-RETIREMENT-GUARDRAILS-001
  acceptance_checks:
  - pnpm --dir packages/web exec tsc --noEmit
  - pnpm --dir packages/web test
  - rg -q "Lifecycle Operation Pattern" doc/product/V3_Resource_Lifecycle_Evidence_Pattern_v1.md
  - rg -q "preconditions|progress|evidence" packages/web/src/components/v3
  - ruby scripts/ops/agent_queue_store.rb --queue-file doc/governance/Agent_Work_Queue.yaml validate
  - make queue-git-check
  notes: 'Context:

    V3 now has broad route/read parity with V1, but several mutable resource pages
    still expose setup/update/maintenance/recovery/destructive actions as page-local
    button clusters. That recreates the V1 admin "entity dump plus buttons" problem
    even when the page is visually modern.

    Required outcome:

    - introduce or reuse a shared lifecycle operation affordance pattern for V3
    resource pages.
    - apply it to the highest-risk mutable surfaces: node detail, app runtime
    detail, MAAS site/profile workflows, platform config workflows, storage lifecycle
    actions, access/service-account lifecycle actions, and finance recovery actions
    where applicable.
    - each operation should expose intent, preconditions/disabled reason, result,
    progress surface, failure path, evidence/audit/task pivot, and danger level.
    - destructive operations should use a typed confirmation pattern rather than
    browser confirm.
    - preserve existing API contracts; when a required capability/progress field
    is missing, show a safe disabled state and leave the backend gap to the A task.

    Out of scope:

    - inventing backend state that is not in the read model.
    - redesigning billing, Netdata edge routing, or Headlamp/Kubernetes embedding.

    '
- id: A-V3-RESOURCE-ACTIVITY-CAPABILITY-READMODELS-001
  title: Add V3 resource activity streams and operation capability fields for lifecycle-bearing resources
  role: A-backend
  status: done
  priority: 1
  owner: codex
  branch: agent/A-backend
  completed_at: '2026-05-02'
  commit: 31211668
  depends_on:
  - C-V3-V1-RETIREMENT-GUARDRAILS-001
  acceptance_checks:
  - make codegen
  - go test ./cmd/api ./packages/services/...
  - rg -q "activity|capabilities" doc/api/openapi.draft.yaml
  - ruby scripts/ops/agent_queue_store.rb --queue-file doc/governance/Agent_Work_Queue.yaml validate
  - make queue-git-check
  notes: 'Context:

    Several V3 pages currently derive lifecycle activity from facts, tasks, workflow
    cards, or table rows. That is acceptable during migration, but the long-term
    V3 model needs first-class read models for operation availability and durable
    activity/evidence.

    Required outcome:

    - update OpenAPI first for any new V3 read-model fields.
    - add operation capability fields where the UI currently infers action availability
    from status strings, especially node operations and app runtime operations.
    - add resource activity streams for nodes, app runtimes, platform config objects,
    storage/WEKAFS attachment lifecycle, and access/IAM mutations where repeated
    operator workflows need history.
    - include evidence pointers: task id, workflow id/run id, audit correlation id,
    runbook/log/trace/provider handoff where available.
    - keep domain boundaries intact; do not add cross-domain DB joins. Use explicit
    read models or service-owned aggregation.

    Out of scope:

    - implementing WEKA S3/STS protocol support before protocol hosts are enabled.
    - changing billing product model.

    '
- id: C-V3-LIFECYCLE-OPERATION-GUARDRAILS-001
  title: Add V3 lifecycle operation migration guardrails and coverage checks
  role: C-ops
  status: done
  priority: 2
  owner: A
  branch: agent/C-ops
  completed_at: '2026-05-02'
  commit: 160a6946
  depends_on:
  - B-V3-LIFECYCLE-OPERATION-AFFORDANCES-001
  - A-V3-RESOURCE-ACTIVITY-CAPABILITY-READMODELS-001
  acceptance_checks:
  - rg -q "Lifecycle Operation Pattern" doc/product
  - pnpm --dir packages/web exec playwright test e2e/v3-navigation-contract.spec.ts --workers=1
  - ruby scripts/ops/agent_queue_store.rb --queue-file doc/governance/Agent_Work_Queue.yaml validate
  - make queue-git-check
  notes: 'Context:

    V3 retirement should not be measured only by route inventory. Every migrated
    mutable resource should expose setup, update, maintenance, recovery, destructive,
    and evidence paths consistently enough that users and operators do not fall
    back to V1 admin pages.

    Required outcome:

    - extend the migration tracker and E2E/QA guidance so lifecycle operation
    coverage is checked alongside route-map coverage.
    - add or update smoke coverage for representative lifecycle-bearing resources:
    workload/app runtime, node detail, MAAS provisioning workflow, platform config,
    storage, access/service account, and finance recovery.
    - document remaining explicit deferrals as named tasks rather than ambiguous
    "later" notes.

    Out of scope:

    - broad V1 frontend test reactivation.
    - platform-control deployment.

    '
- id: B-V3-WORKFLOW-CONSOLIDATION-MOCKS-001
  title: Update V3 mocks for workflow-first workload node setup and recovery flows
  role: B-ui
  status: done
  priority: 1
  owner: B
  branch: agent/B-ui
  completed_at: '2026-05-01'
  commit: c723ca73
  depends_on:
  - C-V3-V1-RETIREMENT-GUARDRAILS-001
  acceptance_checks:
  - sh -lc 'test -f doc/product/V3_Workflow_Consolidation_Plan_v1.md'
  - pnpm --dir packages/web exec tsc --noEmit
  - pnpm --dir packages/web test
  - sh -lc 'rg -q "History|action_required|Node onboarding|Platform setup|Repair certs|Inline SSH" packages/web/app/v3 packages/web/src/components/v3 doc/product'
  - bash scripts/ci/agent_queue_validate.sh
  - make queue-git-check
  notes: 'Context:

    The 2026-05-01 recordings showed that V3 production has route coverage, but
    several flows still look like V1 admin/entity dumps. Before more production
    page work, update the `/v3` mock reference so B and A are implementing toward
    a shared workflow target.

    Required outcome:

    - update the mock workloads landing so it defaults to active/provisioning/recent
    actionable resources, hides released rows by default, and offers History/All
    states as an opt-in.
    - cap the default action band to the top actionable groups and show remaining
    failures behind a disclosure or secondary history view.
    - add a guidance-first node onboarding mock flow: site/profile/network/bootstrap
    token/manual command/heartbeat/ready, with automated MAAS path shown as available
    only when configured.
    - update node lifecycle detail mocks with operation groups: inspect, repair,
    scheduling, provisioning, retirement, and destructive break-glass.
    - add a platform setup checklist mock for Vault, registry, MAAS, bootstrap bundle,
    node-agent release/certs, SKUs/images, telemetry, network/security placeholders,
    and storage provider posture.
    - make launch/access mocks expose inline SSH-key add/select so users do not leave
    the wizard and restart.
    - carry app catalog visual identity into app-backed workload detail mocks.

    Scope:

    - In: `/v3` mock routes/components/fixtures and supporting mock docs.
    - Out: production `/v3-prod` wiring, backend contracts, billing redesign, Netdata
    nginx-edge routing, and Headlamp/Kubernetes embedding.

    '
- id: A-V3-WORKLOAD-ACTIONABILITY-HISTORY-READMODELS-001
  title: Add V3 server-derived workload actionability archive and history read-model semantics
  role: A-backend
  status: done
  priority: 1
  owner: Codex
  branch: agent/A-backend
  completed_at: '2026-05-01'
  commit: 72c0bc30
  depends_on:
  - C-V3-V1-RETIREMENT-GUARDRAILS-001
  acceptance_checks:
  - make codegen
  - go test ./cmd/api ./packages/services/...
  - sh -lc 'rg -q "is_actionable|action_required|actionable_until|archived_at|history" doc/api/openapi.draft.yaml doc/api/openapi/domains packages/shared/gen packages/web/src/lib/v3'
  - bash scripts/ci/agent_queue_validate.sh
  - make queue-git-check
  notes: 'Context:

    The workload landing page currently treats old release_failed/test resources
    as live triage. Released workloads are valuable for audit/history, but they
    should not dominate the runtime workbench after the user has intentionally
    released them or after the failure is no longer actionable.

    Required outcome:

    - update OpenAPI first with contract-backed workload actionability/history fields,
    or document any transitional derivation explicitly.
    - expose server-derived `is_actionable` so browsers do not compute time-bound
    actionability with local clocks.
    - expose whether a workload or operation currently requires action.
    - expose an actionability window or equivalent retention semantics as explanatory
    data so old failures can move out of the default landing page.
    - expose archive/history posture without deleting audit evidence.
    - keep released workloads queryable through History/All states but hidden from
    default runtime lists.
    - preserve evidence pointers for failures moved out of live triage.

    Scope:

    - In: v3 workload list/detail read models, contract/codegen, and tests.
    - Out: changing billing ledger retention or deleting historical records.

    '
- id: A-V3-NODE-ONBOARDING-RECOVERY-CONTRACTS-001
  title: Define V3 node onboarding and node-agent recovery contracts
  role: A-backend
  status: done
  priority: 1
  owner: codex
  branch: agent/A-backend
  completed_at: '2026-05-01'
  commit: b195afab
  depends_on:
  - C-V3-V1-RETIREMENT-GUARDRAILS-001
  acceptance_checks:
  - make codegen
  - go test ./cmd/api ./packages/services/maas ./packages/services/inventory
  - sh -lc 'rg -q "onboard|re-enroll|repair cert|node-agent" doc/api/openapi.draft.yaml doc/api/openapi/domains cmd/api packages/services'
  - bash scripts/ci/agent_queue_validate.sh
  - make queue-git-check
  notes: 'Context:

    V3 exposes node lifecycle data, but the operator cannot yet start a clear node
    onboarding workflow or recover common production failures such as node-agent
    certificate expiry after platform-control outages. These were hidden as admin
    troubleshooting in V1 and must become explicit V3 lifecycle operations.

    Required outcome:

    - define the guidance-first onboarding contract if full MAAS automation is not
    ready: selectable site/profile/network/bootstrap token/manual command/progress
    polling/ready state.
    - define the future automated MAAS mutation path without forcing the UI to wait
    for it before becoming useful.
    - define node-agent recovery operations: probe, repair certs, re-enroll, repair
    agent, refresh inventory, and restart/repair telemetry where appropriate.
    - expose operation capabilities, disabled reasons, progress task/workflow ids,
    and evidence pointers.
    - ensure privileged mutations audit actor/action/target/result/correlation id.

    Scope:

    - In: OpenAPI/read-model/mutation design and first backend handlers where the
    owning services already support the operation.
    - Out: broad MAAS batch onboarding, billing redesign, and V1 admin UI changes.

    '
- id: A-V3-PLATFORM-SETUP-CHECKLIST-READMODEL-001
  title: Add V3 platform setup checklist read model for operator first-run readiness
  role: A-backend
  status: done
  priority: 1
  owner: codex
  branch: agent/A-backend
  completed_at: '2026-05-01'
  commit: b195afab
  depends_on:
  - C-V3-V1-RETIREMENT-GUARDRAILS-001
  acceptance_checks:
  - make codegen
  - go test ./cmd/api ./packages/services/...
  - sh -lc 'rg -q "setup checklist|platform setup|Vault|registry|MAAS|node-agent|telemetry" doc/api/openapi.draft.yaml doc/api/openapi/domains cmd/api packages/services'
  - bash scripts/ci/agent_queue_validate.sh
  - make queue-git-check
  notes: 'Context:

    Operators currently have to infer platform readiness from several admin/config
    pages. V3 needs a first-login/first-run checklist that says what is configured,
    missing, stale, or unsafe before nodes and apps can work.

    Required outcome:

    - expose a platform setup checklist read model with item status, owner, next
    action, evidence, and optional config route.
    - cover Vault/registry, MAAS site/profile, bootstrap bundle digest, node-agent
    release/cert renewal posture, SKUs/images, telemetry/Netdata proxy posture,
    network/security placeholders, and storage provider posture.
    - separate product readiness from raw entity presence; for example a MAAS site
    exists but bootstrap profile digest is stale should be `stale`, not `ok`.
    - keep provider-specific details behind provider-owned fields so WEKAFS/VAST/GPU
    vendor variation can grow without redesigning the checklist.

    Scope:

    - In: read model, contract/codegen, and tests.
    - Out: implementing every setup mutation in the same task.

    '
- id: B-V3-WORKFLOW-CONSOLIDATION-PROD-IMPLEMENTATION-001
  title: Apply workflow consolidation mocks to V3 production pages
  role: B-ui
  status: done
  priority: 1
  owner: B
  branch: agent/B-ui
  completed_at: '2026-05-02'
  commit: 36bc18dc
  depends_on:
  - B-V3-WORKFLOW-CONSOLIDATION-MOCKS-001
  - A-V3-WORKLOAD-ACTIONABILITY-HISTORY-READMODELS-001
  - A-V3-NODE-ONBOARDING-RECOVERY-CONTRACTS-001
  - A-V3-PLATFORM-SETUP-CHECKLIST-READMODEL-001
  acceptance_checks:
  - pnpm --dir packages/web exec tsc --noEmit
  - pnpm --dir packages/web test
  - pnpm --dir packages/web exec playwright test e2e/v3-navigation-contract.spec.ts --workers=1
  - sh -lc 'rg -q "History|Node onboarding|Platform setup|Repair certs|Inline SSH" packages/web/src/components/v3 packages/web/app/v3-prod'
  - bash scripts/ci/agent_queue_validate.sh
  - make queue-git-check
  notes: 'Context:

    Once the mock target and backend/read-model gaps are defined, production V3
    should follow the same workflow shape instead of patching pages one at a time.

    Required outcome:

    - update `/v3-prod/workloads` with actionability/history defaults and opt-in
    released/history views.
    - add the production node onboarding route/surface using guidance-first semantics
    where automation is not yet available.
    - update node detail and platform lifecycle pages to use operation groups and
    evidence/progress affordances consistently.
    - add platform setup checklist production surface.
    - expose inline SSH-key add/select in launch flows using existing account/access
    contracts where available.
    - carry app identity from catalog to app-backed workload detail.
    - keep mock and production close enough that reviewer feedback does not depend
    on mock-only behavior.

    Scope:

    - In: V3 production UI wiring against approved read models and safe disabled
    states for unavailable operations.
    - Out: backend contract additions, billing overhaul, Netdata nginx-edge routing,
    and Headlamp/Kubernetes embedding.

    '
- id: A-V3-NODE-SCHEDULING-LIFECYCLE-MUTATIONS-001
  title: Add V3 node scheduling and inventory lifecycle mutation contracts
  role: A-backend
  status: done
  priority: 1
  owner: codex
  branch: agent/A-backend
  completed_at: '2026-05-06'
  commit: 383967c4
  depends_on:
  - A-V3-NODE-ONBOARDING-RECOVERY-CONTRACTS-001
  acceptance_checks:
  - make codegen
  - go test ./cmd/api ./packages/services/inventory ./packages/services/admin
  - sh -lc 'rg -q "cordon|drain|refresh_inventory|node scheduling" doc/api/openapi.draft.yaml cmd/api packages/services'
  - bash scripts/ci/agent_queue_validate.sh
  - make queue-git-check
  notes: 'Context:

    The V3 node operation read model exposes operator affordances for scheduling
    and inventory recovery, but not every affordance has an executable backend
    mutation. The UI must not present active-looking placeholders.

    Required outcome:

    - define contract-first V3/admin mutations for node cordon, drain, resume
      scheduling where applicable, and refresh inventory.
    - keep privileged mutations idempotent and audited with actor/action/target/
      result/correlation id.
    - return task/workflow/evidence pointers so the UI can show what happened
      after the operator clicks.
    - preserve safety gates: active allocations, MAAS enrollment, node status,
      and break-glass/destructive paths must have explicit disabled reasons.

    Scope:

    - In: OpenAPI, generated types, handlers, service logic, audit rows, tests.
    - Out: UI wiring beyond generated client affordances.

    '
- id: B-V3-NODE-OPERATIONS-UX-COMPLETE-001
  title: Complete V3 node operation UX for scheduling and inventory mutations
  role: B-ui
  status: done
  priority: 1
  owner: B-ui
  branch: agent/B-ui
  completed_at: '2026-05-06'
  commit: 1a148c18
  depends_on:
  - A-V3-NODE-SCHEDULING-LIFECYCLE-MUTATIONS-001
  acceptance_checks:
  - pnpm --dir packages/web exec vitest run src/components/v3
  - pnpm --dir packages/web typecheck
  - sh -lc 'rg -q "cordon|drain|refresh inventory|focused action flow" packages/web/src/components/v3'
  - bash scripts/ci/agent_queue_validate.sh
  - make queue-git-check
  notes: 'Context:

    Platform-control smoke found node operation affordances that looked clickable
    but either only described the operation or required the operator to know the
    focused node-detail path. Low-risk recovery operations now run from the
    compact lifecycle/nodes drawer, but scheduling/inventory actions still need
    backend mutation contracts.

    Required outcome:

    - wire node cordon, drain, scheduling resume, and refresh-inventory actions
      through the approved backend helpers.
    - keep high-risk reimage/destructive actions behind typed confirmation in
      the focused node detail operations drawer.
    - show accepted task/workflow/evidence links immediately after mutation.
    - remove or clearly disable any operation button that has no backend action.

    Scope:

    - In: `/v3-prod/platform/lifecycle/nodes`, focused node detail operations,
      tests, disabled reasons, and evidence/task pivots.
    - Out: adding backend contracts or changing node-agent task semantics.

    '
- id: C-V3-POST-DEPLOY-SMOKE-SUITE-001
  title: Build manual post-deploy V3 smoke suite for user and admin workflows
  role: C-ops
  status: done
  priority: 1
  owner: C-ops
  branch: agent/C-ops
  completed_at: '2026-05-06'
  commit: 0f321d85
  depends_on: []
  acceptance_checks:
  - sh -lc 'test -f scripts/smoke/v3_post_deploy_smoke.sh || test -f doc/operations/V3_Post_Deploy_Smoke_Runbook.md'
  - sh -lc 'rg -q "launch compute|GPU selection|node operations|storage|access|billing|evidence|platform lifecycle" scripts/smoke doc/operations'
  - bash scripts/ci/agent_queue_validate.sh
  - make queue-git-check
  notes: 'Context:

    The V3 migration now changes many user and admin surfaces at once. Unit,
    component, and CI e2e tests are not enough to catch post-deploy workflow
    regressions such as a launch wizard that cannot advance past GPU selection
    or node operation buttons without executable actions.

    Required outcome:

    - add a post-deploy smoke runbook and/or script that is run manually after
      kind/platform-control deploys, not as a blocking CD gate.
    - cover user workflows: login, compute launch BM/VM GPU selection, storage
      launch, workloads list/detail, connect/open-notebook primary actions.
    - cover admin workflows: platform lifecycle nodes, node operation drawer,
      MAAS provisioning/reimage pivots, config SKUs/images/quotas, evidence,
      access/security/sessions, billing/refunds/reconciliation.
    - capture screenshots or trace/video artifacts with stable filenames and
      a single pass/fail summary.
    - document seed-data prerequisites and known safe destructive-action skips.

    Scope:

    - In: smoke runbook/script, selectors, artifact naming, and operator steps.
    - Out: making this a required CD job until the suite has proven stable.

    '
- id: A-V3-PROVISIONING-ATTENTION-REVIEW-001
  title: Add V3 provisioning attention review and supersession model
  role: A-backend
  status: done
  priority: 1
  owner: Codex
  branch: agent/A-backend
  completed_at: '2026-05-04'
  commit: fd5ee1c6
  depends_on:
  - A-V3-NODE-ONBOARDING-RECOVERY-CONTRACTS-001
  acceptance_checks:
  - make codegen
  - go test ./cmd/api -run 'TestV3Platform|TestV3.*Provisioning|TestV3.*Attention'
  - sh -lc 'rg -q "review_required|review_state|superseded_by_workflow_id|taken_care_of|ignored" doc/api/openapi.draft.yaml doc/api/openapi/domains cmd/api packages/shared/gen packages/web/src/lib/gen'
  - bash scripts/ci/agent_queue_validate.sh
  - make queue-git-check
  notes: 'Context:

    Platform-control recordings showed stale provisioning attention after a failed
    decommission was followed by a newer workflow that completed. Operators need
    a way to mark old failures as taken care of or ignored, and the backend should
    automatically supersede old failed workflows when a newer workflow resolves the
    same target/action family.

    Required outcome:

    - extend V3 provisioning/lifecycle workflow read models with review_required,
    review_state, reviewed_at, reviewed_by, review_note, attention_reason,
    next_action, and superseded_by_workflow_id where applicable.
    - add a privileged mutation to mark an attention item taken_care_of or ignored
    with an operator note and audit log row.
    - server-derive superseded state when a newer successful workflow resolves the
    same node/site/profile/action-family target.
    - default live attention queues include open review items only; reviewed,
    ignored, and superseded workflows remain visible in History/Evidence.
    - update generated Go/TS types and add regression tests for stale failed
    workflow -> newer successful workflow -> no live attention.

    Scope:

    - In: OpenAPI contract, backend read model/mutation, audit, codegen, and tests.
    - Out: client-only dismissal state, deleting workflow history, and broad IA
    reshuffle.

    '
- id: A-V3-PROVISIONING-DETAIL-ATTENTION-CONTRACT-001
  title: Extend provisioning detail read models with backend-owned attention review state
  role: A-backend
  status: done
  priority: 1
  owner: codex
  branch: agent/A-backend
  completed_at: '2026-05-05'
  commit: 6b04505d
  depends_on:
  - A-V3-PROVISIONING-ATTENTION-REVIEW-001
  acceptance_checks:
  - make codegen
  - go test ./cmd/api -run 'TestV3Platform|TestV3.*Provisioning|TestV3.*Attention'
  - sh -lc 'rg -q "attention_key|review_required|review_state|superseded_by_workflow_id" doc/api/openapi.draft.yaml doc/api/openapi/domains cmd/api packages/shared/gen packages/web/src/lib/gen'
  - bash scripts/ci/agent_queue_validate.sh
  - make queue-git-check
  notes: 'Context:

    The lifecycle cards expose backend-owned review state and B wired the generic
    ReviewAttentionControl there. MAAS provisioning and onboarding/decommission
    detail surfaces still lack the same contract, so adding UI controls there
    would require a client-side fetch/merge by convention.

    Required outcome:

    - extend onboarding and decommission detail read models/API payloads with
    attention_key, review_required, review_state, reviewed_at, reviewed_by,
    review_note, attention_reason, next_action, and superseded_by_workflow_id.
    - reuse the same backend review identity and supersession rules as lifecycle
    workflow cards.
    - do not add UI-only joins or duplicate mutation endpoints.
    - update generated Go/TS types and regression tests.

    Scope:

    - In: OpenAPI contract, backend read-model mapping, codegen, tests.
    - Out: frontend rendering and broad page layout changes.

    '
- id: A-V3-WORKLOAD-OPERATOR-STATE-CONTRACT-001
  title: Add backend-owned operator state to V3 workloads for allocations and apps
  role: A-backend
  status: done
  priority: 1
  owner: codex
  branch: agent/A-backend
  completed_at: '2026-05-05'
  commit: 75260124
  depends_on:
  - A-V3-PROVISIONING-ATTENTION-REVIEW-001
  acceptance_checks:
  - make codegen
  - go test ./cmd/api -run 'TestV3Workload|TestV3.*OperatorState|TestV3.*Attention'
  - sh -lc 'rg -q "operator_state|signal_key|ack_fingerprint|review_required|attention_key" doc/api/openapi.draft.yaml doc/api/openapi/domains cmd/api packages/shared/gen packages/web/src/lib/gen'
  - bash scripts/ci/agent_queue_validate.sh
  - make queue-git-check
  notes: 'Context:

    Workloads already combine compute allocations and app instances, but the
    attention state is still inferred in the UI from status. Allocation/app rows
    and details need backend-owned operator state so B can render common controls
    without per-page heuristics.

    Required outcome:

    - add an operator_state block to V3 workload summaries/details covering generic
    signals and provisioning-style review fields where applicable.
    - allocations with failed/release_failed/restart_failed states expose stable
    backend-owned review identity and attention reason.
    - app instances with failed/degraded/repair-required states expose stable
    backend-owned signal/review identity based on the owning workflow/action
    family.
    - default workload attention lists stay backend-filterable; reviewed/ignored
    items remain available when history is requested.
    - update generated Go/TS types and regression tests.

    Scope:

    - In: OpenAPI contract, V3 workload read model, codegen, tests.
    - Out: frontend rendering, app runtime operation mutations, and new app
    lifecycle workflow engines.

    '
- id: B-V3-PROVISIONING-DETAIL-ATTENTION-UI-001
  title: Render review controls on provisioning detail surfaces
  role: B-ui
  status: done
  priority: 1
  owner: B-ui
  branch: agent/B-ui
  completed_at: '2026-05-04'
  commit: 171bec35
  depends_on:
  - A-V3-PROVISIONING-DETAIL-ATTENTION-CONTRACT-001
  acceptance_checks:
  - pnpm --dir packages/web exec vitest run src/components/v3/ReviewAttentionControl.test.tsx src/components/v3/v3-platform-provisioning-pages
  - pnpm --dir packages/web typecheck
  - sh -lc 'rg -q "ReviewAttentionControl|attention_key|review_required" packages/web/src/components/v3/v3-platform-provisioning-pages.tsx'
  - bash scripts/ci/agent_queue_validate.sh
  - make queue-git-check
  notes: 'Context:

    Backend will expose the same provisioning attention contract on onboarding and
    decommission detail payloads. Use that contract directly; do not fetch lifecycle
    cards and merge by attention_key in the client.

    Required outcome:

    - render ReviewAttentionControl in MAAS provisioning/detail headers or action
    bands when review_required is true.
    - show attention_reason and next_action near the existing status evidence.
    - invalidate the owning detail and lifecycle query keys after review.
    - keep reviewed/superseded items read-only in history/evidence views.

    '
- id: B-V3-WORKLOADS-OPERATOR-STATE-UI-001
  title: Render backend-owned operator state on V3 workloads for allocations and apps
  role: B-ui
  status: done
  priority: 1
  owner: B-ui
  branch: agent/B-ui
  completed_at: '2026-05-04'
  commit: f70e2b62
  depends_on:
  - A-V3-WORKLOAD-OPERATOR-STATE-CONTRACT-001
  acceptance_checks:
  - pnpm --dir packages/web exec vitest run src/components/v3 src/lib/v3
  - pnpm --dir packages/web typecheck
  - sh -lc 'rg -q "operator_state|AckSuppressControl|ReviewAttentionControl" packages/web/src/components/v3/v3-workloads-page.tsx packages/web/src/components/v3/v3-workload-detail-page.tsx packages/web/src/lib/v3/api.ts'
  - bash scripts/ci/agent_queue_validate.sh
  - make queue-git-check
  notes: 'Context:

    Workloads cover compute allocations and app instances. Once backend exposes
    operator_state, UI should stop inferring actionability from status and render
    common controls from the read model.

    Required outcome:

    - render ack/suppress or review controls based on backend-provided
    operator_state.
    - update workloads list filtering/counts to use backend state rather than local
    status heuristics where possible.
    - show operator state in workload detail header/action area for both compute
    allocations and app instances.
    - no client-side joins across lifecycle/platform endpoints.

    '
- id: B-V3-PLATFORM-SUBNAV-CONSISTENCY-001
  title: Make V3 platform submenus and workbench entry points consistent
  role: B-ui
  status: done
  priority: 2
  owner: B-ui
  branch: agent/B-ui
  completed_at: '2026-05-04'
  commit: 5fecb60d
  depends_on: []
  acceptance_checks:
  - pnpm --dir packages/web exec vitest run src/components/v3
  - pnpm --dir packages/web typecheck
  - sh -lc 'rg -q "V3PlatformNav|AdminWorkbench|OperationsDrawer" packages/web/src/components/v3'
  - bash scripts/ci/agent_queue_validate.sh
  - make queue-git-check
  notes: 'Context:

    The platform family has routes and a local nav, but second-level IA is still
    uneven. This task is UI-only and should not introduce new backend state.

    Required outcome:

    - make platform subnav labels and active states consistent across Ops,
    Lifecycle, Provisioning, Config, Setup, Evidence, Finance, and IAM pages.
    - preserve the existing routes; do not do a broad IA migration.
    - ensure entry points use the shared workbench primitives where they already
    fit.
    - remove stale reviewer prose only when it is not needed for the operator task.

    '
- id: B-V3-WORKBENCH-CONSISTENCY-AUDIT-V2-001
  title: Audit all V3 list/table/card-list surfaces and define unified workbench UX contract
  role: B-ui
  status: done
  priority: 1
  owner: B-ui
  branch: agent/B-ui
  completed_at: '2026-05-05'
  commit: 31ac9025
  depends_on: []
  acceptance_checks:
  - sh -lc 'test -f doc/product/V3_Workbench_Consistency_Plan_v2.md'
  - sh -lc 'rg -q "workloads|credentials|access audit|storage|billing|evidence|click-to-detail|filter rail" doc/product/V3_Workbench_Consistency_Plan_v2.md'
  - sh -lc 'rg -q "v3-data-table|<table|WorkbenchRow|AdminWorkbench|card-list" doc/product/V3_Workbench_Consistency_Plan_v2.md'
  - bash scripts/ci/agent_queue_validate.sh
  - make queue-git-check
  notes: 'Context:

    The admin workbench plan completed for `/v3-prod/platform/*`, but user-facing
    V3 surfaces still behave inconsistently. Workloads, storage, access
    credentials, access audit, account billing, and evidence-like lists mix card
    grids, plain tables, custom lists, disabled-row defaults, and inconsistent
    click affordances. The result still feels like several mock layouts rather
    than one product console.

    Required outcome:

    - create `doc/product/V3_Workbench_Consistency_Plan_v2.md`.
    - audit every V3 component/page that renders a table, row list, card-list used
    as a table, or workbench-like surface. Include at least:
      `/v3-prod/workloads`, `/v3-prod/workloads/[id]` tabs, `/v3-prod/storage`,
      `/v3-prod/storage/[id]`, `/v3-prod/access/credentials`,
      `/v3-prod/access/audit`, `/v3-prod/account/billing`,
      `/v3-prod/platform/evidence/audit`, `/v3-prod/evidence`, and any
      `data-testid="v3-data-table"` or raw `<table>` use under
      `packages/web/src/components/v3`.
    - define one canonical UX contract: filter rail, dense useful columns, whole
    row click behavior, selected-row detail or focused-detail rationale,
    operations drawer rule, default-hidden inactive/disabled rows with explicit
    history toggle, empty/filter states, refetch indicator, keyboard behavior,
    and stable test selectors.
    - classify each surface as: conformant, needs filter rail only, needs row
    affordance/detail, needs operations drawer, needs backend contract, or should
    intentionally remain a focused detail page.
    - produce a sequenced conversion backlog with small slices and dependencies.

    Scope:

    - In: product/UX audit and concrete task sequencing across V3 user and
    platform surfaces.
    - Out: code conversion, backend changes, and broad navigation IA changes.

    '
- id: B-V3-CREDENTIALS-WORKBENCH-STANDARDIZE-001
  title: Standardize V3 access credentials table with filter rail and inactive-row defaults
  role: B-ui
  status: done
  priority: 1
  owner: B-ui
  branch: agent/B-ui
  completed_at: '2026-05-05'
  commit: b1abf49e
  depends_on:
  - B-V3-WORKBENCH-CONSISTENCY-AUDIT-V2-001
  acceptance_checks:
  - pnpm --dir packages/web exec vitest run src/components/v3
  - pnpm --dir packages/web typecheck
  - sh -lc 'rg -q "credentials.*filter|show.*disabled|hide.*disabled|WorkbenchRow|WorkbenchFilterRail" packages/web/src/components/v3'
  - bash scripts/ci/agent_queue_validate.sh
  - make queue-git-check
  notes: 'Context:

    `/v3-prod/access/credentials` is the smallest high-confidence tactical fix:
    it currently reads like a table, lacks a filter rail, and shows disabled
    credentials by default. This should become the first implementation slice
    after the v2 audit confirms the exact contract.

    Required outcome:

    - add the canonical filter rail from the v2 plan.
    - hide disabled/revoked/inactive credentials by default, with an explicit
    "show disabled/history" affordance when the read model supports it.
    - render dense rows with useful columns only; move extra metadata into
    selected detail or an existing focused detail/drawer pattern.
    - make row interaction consistent with the v2 workbench contract.
    - preserve credential secrecy; do not expose tokens, secret material, or
    raw credential values.

    Scope:

    - In: frontend behavior and tests for the credentials surface.
    - Out: new credential backend mutations, secret reveal flows, and global nav
    changes.

    '
- id: B-V3-WORKLOADS-WORKBENCH-STANDARDIZE-001
  title: Standardize V3 workloads workbench rows, filters, and detail affordances
  role: B-ui
  status: done
  priority: 1
  owner: B-ui
  branch: agent/B-ui
  completed_at: '2026-05-05'
  commit: 47d31b80
  depends_on:
  - B-V3-WORKBENCH-CONSISTENCY-AUDIT-V2-001
  acceptance_checks:
  - pnpm --dir packages/web exec vitest run src/components/v3
  - pnpm --dir packages/web typecheck
  - sh -lc 'rg -q "v3-workloads-page|WorkbenchRow|filter|operator_state" packages/web/src/components/v3/v3-workloads-page.tsx'
  - bash scripts/ci/agent_queue_validate.sh
  - make queue-git-check
  notes: 'Context:

    Workloads is the highest-traffic V3 runtime surface, but it still uses a
    bespoke card/list shape. It has operator-state controls now, yet the list
    lacks the same filter/row/detail behavior users see on platform workbenches.

    Required outcome:

    - apply the v2 workbench contract to `/v3-prod/workloads`.
    - add a filter rail for workload kind/status/attention/search where supported
    by current client-side data or backend filters.
    - render dense rows with useful columns: status, name/id, kind, owner/project,
    runtime/sku/app, age/activity, and operator-state signal.
    - make the whole row click target consistent. If workload detail remains a
    focused page instead of selected-row detail, document and implement that as
    the explicit v2 exception: whole-row navigation, stable back link, and no
    competing inline detail affordance.
    - keep primary row actions available but avoid multi-line data dumps in the
    list.

    Scope:

    - In: frontend list/filter/row affordance standardization for workloads.
    - Out: workload detail redesign, new backend filters unless the v2 audit
    marks them as required upstream tasks.

    '
- id: B-V3-ACCESS-AUDIT-WORKBENCH-STANDARDIZE-001
  title: Align V3 access audit trail with evidence audit workbench behavior
  role: B-ui
  status: done
  priority: 2
  owner: B-ui
  branch: agent/B-ui
  completed_at: '2026-05-05'
  commit: f95ea659
  depends_on:
  - B-V3-WORKBENCH-CONSISTENCY-AUDIT-V2-001
  acceptance_checks:
  - pnpm --dir packages/web exec vitest run src/components/v3
  - pnpm --dir packages/web typecheck
  - sh -lc 'rg -q "access.*audit|WorkbenchFilterRail|WorkbenchRow|audit" packages/web/src/components/v3'
  - bash scripts/ci/agent_queue_validate.sh
  - make queue-git-check
  notes: 'Context:

    Access audit currently behaves differently from the platform Evidence Audit
    workbench, even though both are evidence/audit investigation surfaces.

    Required outcome:

    - align `/v3-prod/access/audit` with the v2 filter rail, row, empty-state,
    click-to-detail, and evidence-detail behavior.
    - reuse the Evidence Audit interaction model where contracts overlap.
    - keep the surface access-scoped; do not turn it into the platform-wide audit
    surface.

    '
- id: B-V3-STORAGE-WORKBENCH-STANDARDIZE-001
  title: Standardize V3 storage workbench row and detail behavior
  role: B-ui
  status: done
  priority: 2
  owner: B-ui
  branch: agent/B-ui
  completed_at: '2026-05-05'
  commit: aabed78c
  depends_on:
  - B-V3-WORKBENCH-CONSISTENCY-AUDIT-V2-001
  acceptance_checks:
  - pnpm --dir packages/web exec vitest run src/components/v3
  - pnpm --dir packages/web typecheck
  - sh -lc 'rg -q "v3-storage-page|WorkbenchRow|filter|storage" packages/web/src/components/v3'
  - bash scripts/ci/agent_queue_validate.sh
  - make queue-git-check
  notes: 'Context:

    Storage currently uses a custom layout and row affordances. The row model is
    less obvious than credentials or workloads, so it should follow the v2 audit
    rather than be converted ad hoc.

    Required outcome:

    - apply the v2 workbench contract to `/v3-prod/storage`.
    - define useful dense columns for bucket/name, owner/scope, region/protocol,
    mount posture, sharing posture, size/object count where available, and latest
    activity.
    - make row click behavior consistent with either selected detail or focused
    bucket detail, per the v2 plan.
    - move extra context and destructive actions into detail/drawer affordances.

    '
- id: B-V3-BILLING-WORKBENCH-ROW-INTENT-001
  title: Decide and standardize V3 account billing row behavior
  role: B-ui
  status: done
  priority: 2
  owner: B-ui
  branch: agent/B-ui
  completed_at: '2026-05-05'
  commit: d73edcd7
  depends_on:
  - B-V3-WORKBENCH-CONSISTENCY-AUDIT-V2-001
  acceptance_checks:
  - pnpm --dir packages/web exec vitest run src/components/v3
  - pnpm --dir packages/web typecheck
  - sh -lc 'rg -q "billing|usage|refund|invoice|Workbench|detail" packages/web/src/components/v3/v3-account-subpages.tsx doc/product/V3_Workbench_Consistency_Plan_v2.md'
  - bash scripts/ci/agent_queue_validate.sh
  - make queue-git-check
  notes: 'Context:

    Account billing has tables, but it is not obvious every row needs a detail
    drawer. For read-only usage/refund/ledger rows, forcing click-to-detail may
    add noise instead of usability.

    Required outcome:

    - use the v2 audit to decide row intent for account billing tables.
    - if rows have actionable or inspectable detail, add the standard click/detail
    behavior.
    - if rows are intentionally read-only summary rows, document the exception and
    still align density, columns, empty states, and filters with the v2 contract.
    - do not add finance mutations or provider recovery flows in this task.

    '
- id: A-V3-ACTION-LIFECYCLE-CONTRACT-AUDIT-001
  title: Audit V3 managed-resource lifecycle contracts and close read-only gaps
  role: A-backend
  status: done
  priority: 1
  owner: A-backend
  branch: agent/A-backend
  completed_at: '2026-05-05'
  commit: 0aa1f156
  depends_on:
  - B-V3-BILLING-WORKBENCH-ROW-INTENT-001
  acceptance_checks:
  - sh -lc 'test -f doc/product/V3_Action_Lifecycle_Closure_Plan_v1.md'
  - sh -lc 'rg -q "manageable|intentionally read-only|backend-gated|Config|Access/IAM|Account Security" doc/product/V3_Action_Lifecycle_Closure_Plan_v1.md'
  - sh -lc 'rg -q "V3.*(Config|Access|Account|Storage|Billing|Evidence)" doc/api/openapi.draft.yaml doc/product/V3_Action_Lifecycle_Closure_Plan_v1.md'
  - bash scripts/ci/agent_queue_validate.sh
  - make queue-git-check
  notes: 'Context:

    Plan v2 completed visual/workbench consistency for the highest-priority
    V3 surfaces, but the product is still incomplete if governed resources are
    only read/view models. Configuration, IAM/access, account security/sessions,
    storage, app artifacts, and finance/refund flows need explicit lifecycle
    classification before B-ui adds more controls.

    Required outcome:

    - use `doc/product/V3_Action_Lifecycle_Closure_Plan_v1.md` as the closure
      source of truth.
    - audit current OpenAPI, generated types, handlers, and existing V1/V3
      behavior for every managed V3 surface.
    - classify each resource as manageable, intentionally read-only, or
      backend-gated.
    - produce a concrete missing-contract matrix with endpoint shapes, audit
      actions, idempotency expectations, disabled reasons, evidence/progress
      fields, and UI dependency tasks.
    - do not implement mutations in this audit slice; create or update the
      downstream A/B tasks with exact contract dependencies.

    Scope:

    - In: contract/product audit across config, IAM/access, account security,
      storage, workloads/apps, billing/finance, and evidence/audit.
    - Out: backend implementation, UI wiring, and V1 route changes.

    2026-05-05 partial implementation:

    - 2420d47b added V3 lifecycle aliases for existing audited authorities instead
      of waiting for the full matrix: config SKU/OS image/quota policy, access
      service accounts/credentials/entitlements/membership bind, and account SSH-key
      create/delete/default.
    - Remaining audit gaps still need explicit contract classification: session
      revoke/revoke-others, membership removal, OS-image update/deprecate, broader
      quota/policy editor scope, storage bucket update/archive/delete, app artifact
      lifecycle, and finance refund-request boundaries.

    2026-05-05 closure:

    - 0aa1f156 added `doc/product/V3_Action_Lifecycle_Closure_Plan_v1.md` as the
      source-of-truth classification for manageable, intentionally read-only, and
      backend-gated V3 surfaces.
    - Follow-up A/B tasks were queued for the concrete backend-gated gaps instead
      of treating this audit as implementation-complete.

    '
- id: A-V3-CONFIG-MUTATION-LIFECYCLE-001
  title: Add V3 platform configuration mutation lifecycle contracts
  role: A-backend
  status: done
  priority: 1
  owner: A-backend
  branch: agent/A-backend
  completed_at: '2026-05-05'
  commit: 5f68c784
  depends_on:
  - A-V3-ACTION-LIFECYCLE-CONTRACT-AUDIT-001
  acceptance_checks:
  - sh -lc 'rg -q "platform/config|sku|os-image|quota|policy|publish|archive|disable" doc/api/openapi.draft.yaml packages/services cmd/api'
  - go test ./...
  - bash scripts/ci/agent_queue_validate.sh
  - make queue-git-check
  notes: 'Context:

    V3 platform Config now has compact workbenches for SKUs, OS images, and
    quotas, but those surfaces mostly expose read-model posture. Operators need
    contract-backed lifecycle actions instead of a console that only displays
    configuration.

    Required outcome:

    - update OpenAPI first for the config mutations confirmed by the lifecycle
      audit: create/update/disable/archive SKU, create/update/deprecate OS
      image, create/update quota or policy value, publish/revert config changes
      where applicable.
    - implement handlers/services with idempotency, typed errors, audit logs,
      and progress/evidence fields for B-ui.
    - expose disabled reasons and latest actor/timestamp in the read model.
    - add unit, handler, and DB/audit integration coverage for changed paths.

    Scope:

    - In: V3 config mutation contracts and backend implementation.
    - Out: frontend wiring; broad policy editor redesign beyond audited actions.

    2026-05-05 partial implementation:

    - 2420d47b added V3 config mutation aliases over existing admin authorities:
      create/update/activate/deactivate SKU, create/delete OS image, and get/set
      global allocation concurrency policy.
    - Remaining backend gaps: OS image update/deprecate, SKU archive semantics beyond
      deactivate, broader quota/policy editor actions, read-model actor/timestamp
      operation metadata, and DB/audit integration coverage for the new V3 aliases.

    Completed:

    - Added server-owned `V3PlatformConfigOperation` metadata to the platform config
      read model for SKU, OS image, and allocation-concurrency policy lifecycle
      actions.
    - Exposed method/href templates, disabled reasons, audit actions, evidence
      links, and latest actor/timestamp from config audit activity so B can wire
      standard operation drawers without deriving lifecycle semantics client-side.
    - Preserved existing audited/idempotent V3 config mutation aliases and avoided
      inventing a generic policy editor beyond the current allocation-concurrency
      authority.
    - Acceptance evidence: make codegen; go test ./cmd/api; go test
      ./packages/services/inventory; pnpm --dir packages/web typecheck; git diff
      --check.

    '
- id: A-V3-IAM-ACCESS-MUTATION-LIFECYCLE-001
  title: Add V3 IAM and access governance mutation lifecycle contracts
  role: A-backend
  status: done
  priority: 1
  owner: A-backend
  branch: agent/A-backend
  completed_at: '2026-05-05'
  commit: 1f4aa2df
  depends_on:
  - A-V3-ACTION-LIFECYCLE-CONTRACT-AUDIT-001
  acceptance_checks:
  - sh -lc 'rg -q "access/(memberships|service-accounts|entitlements|credentials)|invite|revoke|rotate|disable|grant" doc/api/openapi.draft.yaml packages/services cmd/api'
  - go test ./...
  - bash scripts/ci/agent_queue_validate.sh
  - make queue-git-check
  notes: 'Context:

    Access credentials have been visually standardized, but memberships,
    service accounts, entitlements, and platform IAM users are still mostly
    read/view surfaces. V3 migration is not complete until users and admins can
    perform the governed lifecycle actions with audit/evidence.

    Required outcome:

    - update OpenAPI first for audited IAM/access mutations: membership invite
      or add/remove/change role, service account create/rotate/disable/delete,
      entitlement grant/revoke, credential revoke/rotate/history where supported.
    - implement backend authority with idempotency, audit logs, typed errors,
      correlation/evidence fields, and disabled reasons for unavailable actions.
    - preserve credential secrecy; never return raw secrets outside approved
      one-time issue responses.
    - add tests covering authz, idempotency, audit rows, validation errors, and
      successful lifecycle transitions.

    Scope:

    - In: V3 access/IAM mutation contracts and backend implementation.
    - Out: B-ui rendering and unrelated identity-provider administration.

    2026-05-05 partial implementation:

    - 2420d47b added V3 access mutation aliases over existing audited authorities:
      membership bind/change role, service account create/get/rotate/disable/delete,
      project access credential create/get/update/delete/rotate/deliver, and app
      entitlement grant/revoke via enabled=false.
    - Remaining backend gaps: membership remove/soft-delete, invitation lifecycle if
      required, platform IAM user mutation parity, read-model disabled reasons/evidence
      for every operation, and DB/audit integration coverage for the new V3 aliases.

    Completed:

    - e2202804 added the audited/idempotent V3 membership remove lifecycle alias.
    - Added server-owned `V3AccessOperation` metadata to memberships, service
      accounts, credentials, and entitlements list responses.
    - Exposed method/href templates, row-selection disabled reasons, danger levels,
      audit actions, latest actor/timestamp, and access audit evidence links for
      existing audited V3 aliases.
    - Preserved credential secrecy by keeping secret material limited to existing
      approved one-time create/rotate/deliver response paths.
    - Left invitation lifecycle and external identity-provider administration out of
      scope because no current backend authority exists for those flows.
    - Acceptance evidence: make codegen; go test ./cmd/api; go test
      ./packages/services/auth ./packages/services/admin ./packages/services/inventory;
      pnpm --dir packages/web typecheck; git diff --check; bash
      scripts/ci/agent_queue_validate.sh.

    '
- id: A-V3-ACCOUNT-SECURITY-MUTATION-LIFECYCLE-001
  title: Add V3 account security and session mutation lifecycle contracts
  role: A-backend
  status: done
  priority: 1
  owner: A-backend
  branch: agent/A-backend
  completed_at: '2026-05-05'
  commit: 8b2380be
  depends_on:
  - A-V3-ACTION-LIFECYCLE-CONTRACT-AUDIT-001
  acceptance_checks:
  - sh -lc 'rg -q "account/(security|sessions)|revoke|delete|credential|session" doc/api/openapi.draft.yaml packages/services cmd/api'
  - go test ./...
  - bash scripts/ci/agent_queue_validate.sh
  - make queue-git-check
  notes: 'Context:

    `/v3-prod/account/security` and `/v3-prod/account/sessions` still read like
    static tables. Account security closure needs real lifecycle contracts for
    revoking credentials and sessions, while immutable history remains read-only.

    Required outcome:

    - update OpenAPI first for audited account-security mutations: revoke/delete
      credential where supported, revoke one session, revoke all other sessions,
      and expose operation/evidence results.
    - implement handlers/services with auth ownership checks, idempotency for
      retryable mutations, audit rows, typed errors, and sanitized logging.
    - ensure read models expose active vs inactive state so B-ui can default-hide
      inactive/history rows.
    - add unit and handler tests plus integration coverage for audit JSON paths.

    Scope:

    - In: V3 account security/session mutation contracts and backend implementation.
    - Out: frontend wiring and external IdP console features.

    2026-05-05 partial implementation:

    - 2420d47b added V3 account security aliases over existing SSH-key authority:
      create personal SSH key, revoke/delete personal SSH key, and set default key.
    - Remaining backend gaps: account session list is still an empty read model, and
      revoke-one/revoke-others requires a session/token authority beyond the current
      caller-token logout/denylist path.

    Completed:

    - Added server-owned `V3AccountOperation` metadata to the account security read
      model for the existing audited/idempotent SSH-key lifecycle aliases.
    - Exposed create, delete/revoke, and set-default SSH-key method/href templates,
      row-selection disabled reasons, danger levels, audit actions, latest
      actor/timestamp, and evidence links.
    - Kept account session revocation out of this closure task because
      `listV3AccountSessionRows` has no durable session source of truth yet.
      Follow-up remains tracked by `A-V3-ACCOUNT-SESSIONS-REVOCATION-LIFECYCLE-001`.
    - Acceptance evidence: make codegen; go test ./cmd/api; pnpm --dir
      packages/web typecheck; git diff --check; bash
      scripts/ci/agent_queue_validate.sh.

    '
- id: B-V3-CONFIG-LIFECYCLE-OPERATIONS-UX-001
  title: Wire V3 platform configuration lifecycle operations into workbenches
  role: B-ui
  status: done
  priority: 1
  owner: B-ui
  branch: agent/B-ui
  completed_at: '2026-05-05'
  commit: 6abeec3d
  depends_on:
  - A-V3-CONFIG-MUTATION-LIFECYCLE-001
  acceptance_checks:
  - pnpm --dir packages/web exec vitest run src/components/v3
  - pnpm --dir packages/web typecheck
  - sh -lc 'rg -q "OperationsDrawer|config|sku|os-image|quota|publish" packages/web/src/components/v3'
  - bash scripts/ci/agent_queue_validate.sh
  - make queue-git-check
  notes: 'Context:

    Config workbenches are visually consistent but mostly view-only. After the
    backend config lifecycle contract lands, B should expose the actions without
    reverting to table-plus-button sprawl.

    Required outcome:

    - add create/edit/disable/archive/publish affordances confirmed by the
      backend contract.
    - use header CTAs for create/publish and `OperationsDrawer` for selected-row
      mutations with disabled reasons, runbook/evidence links, and refetch.
    - preserve dense rows; move extra lifecycle detail into selected detail panels.
    - add tests for visible actions, disabled operations, success refetch, and
      error/retry states.

    Scope:

    - In: V3 config UI lifecycle wiring.
    - Out: inventing UI-only mutations or broad navigation redesign.

    '
- id: B-V3-ACCESS-GOVERNANCE-WORKBENCH-STANDARDIZE-001
  title: Finish V3 access governance workbenches with lifecycle actions
  role: B-ui
  status: done
  priority: 1
  owner: B-ui
  branch: agent/B-ui
  completed_at: '2026-05-05'
  commit: 916d910b
  depends_on:
  - A-V3-IAM-ACCESS-MUTATION-LIFECYCLE-001
  - B-V3-BILLING-WORKBENCH-ROW-INTENT-001
  acceptance_checks:
  - pnpm --dir packages/web exec vitest run src/components/v3
  - pnpm --dir packages/web typecheck
  - sh -lc 'rg -q "memberships|service-accounts|entitlements|OperationsDrawer|WorkbenchFilterRail" packages/web/src/components/v3/v3-access-subpages.tsx'
  - bash scripts/ci/agent_queue_validate.sh
  - make queue-git-check
  notes: 'Context:

    Plan v2 carry-forward C6 left memberships, service accounts, and
    entitlements on old table shapes. The deeper gap is lifecycle: add/remove,
    rotate/disable, and grant/revoke need to be usable after backend authority
    lands.

    Required outcome:

    - convert memberships, service accounts, and entitlements to the canonical
      filter rail + WorkbenchRow + selected detail pattern.
    - default-hide inactive/disabled/history rows where applicable.
    - wire backend-backed add/remove/change-role, create/rotate/disable/delete,
      and grant/revoke operations through standard drawers/confirmations.
    - show audit/evidence/correlation feedback after mutations.

    Scope:

    - In: V3 access governance UI and tests.
    - Out: backend mutation implementation or raw secret reveal flows.

    '
- id: B-V3-ACCOUNT-SECURITY-SESSIONS-WORKBENCH-STANDARDIZE-001
  title: Finish V3 account security and session lifecycle UX
  role: B-ui
  status: done
  priority: 1
  owner: B-ui
  branch: agent/B-ui
  completed_at: '2026-05-05'
  commit: 0bc77294
  depends_on:
  - A-V3-ACCOUNT-SECURITY-MUTATION-LIFECYCLE-001
  - B-V3-BILLING-WORKBENCH-ROW-INTENT-001
  acceptance_checks:
  - pnpm --dir packages/web exec vitest run src/components/v3
  - pnpm --dir packages/web typecheck
  - sh -lc 'rg -q "account.*security|account.*sessions|OperationsDrawer|WorkbenchFilterRail" packages/web/src/components/v3/v3-account-subpages.tsx'
  - bash scripts/ci/agent_queue_validate.sh
  - make queue-git-check
  notes: 'Context:

    Plan v2 carry-forward C7 left account security and sessions on old table
    shapes. These surfaces should become actionable account controls, not just
    read-only inspection tables.

    Required outcome:

    - convert security credentials and sessions to canonical filter rail,
      default-hide inactive/history rows, and selected-row detail.
    - wire revoke/delete credential, revoke session, and revoke-other-sessions
      actions where the backend contract supports them.
    - preserve immutable history as read-only evidence.
    - add tests for filters, row detail, disabled operations, success refetch,
      and empty filtered states.

    Scope:

    - In: V3 account security/session UI and tests.
    - Out: backend mutation implementation and external IdP administration.

    '
- id: B-V3-WORKBENCH-CHROME-V21-CLEANUP-001
  title: Normalize V3 workbench chrome after Plan v2 conversions
  role: B-ui
  status: done
  priority: 2
  owner: B-ui
  branch: agent/B-ui
  completed_at: '2026-05-05'
  commit: 6ba3820c
  depends_on:
  - B-V3-BILLING-WORKBENCH-ROW-INTENT-001
  acceptance_checks:
  - pnpm --dir packages/web exec vitest run src/components/v3
  - pnpm --dir packages/web typecheck
  - sh -lc 'rg -q "AdminWorkbench|SectionCard|WorkbenchFilterRail|WorkbenchRow" packages/web/src/components/v3/admin packages/web/src/components/v3'
  - bash scripts/ci/agent_queue_validate.sh
  - make queue-git-check
  notes: 'Context:

    Plan v2 standardized behavior, but the post-implementation visual audit
    found remaining chrome drift: SectionCard-wrapped filters above bare
    AdminWorkbench lists, read-only ledgers beside bare workbench sections,
    different empty-state envelopes, and full-width navigate-to-detail rows
    beside narrower selected-detail workbenches.

    Required outcome:

    - choose and implement one wrapper rhythm for filter rail + list + detail:
      either give AdminWorkbench a SectionCard-equivalent envelope or remove the
      extra SectionCard shell around filter rails where appropriate.
    - normalize empty-state envelopes and row/list spacing across converted V3
      workbench surfaces without changing backend behavior.
    - preserve documented exceptions: read-only ledger tables and catalog
      card-grids.
    - add/update primitive tests so future conversions inherit the chrome
      contract automatically.

    Scope:

    - In: frontend primitive/chrome cleanup after Plan v2.
    - Out: new lifecycle mutations and broad page IA changes.

    '
- id: A-V3-ACCESS-MEMBERSHIP-REMOVE-LIFECYCLE-001
  title: Add V3 access membership remove and role-change evidence lifecycle
  role: A-backend
  status: done
  priority: 1
  owner: A-backend
  branch: agent/A-backend
  completed_at: '2026-05-05'
  commit: e2202804
  depends_on:
  - A-V3-ACTION-LIFECYCLE-CONTRACT-AUDIT-001
  acceptance_checks:
  - sh -lc 'rg -q "access/memberships.*(remove|delete|revoke)|membership.*deleted_at|tenant.user.membership" doc/api/openapi.draft.yaml cmd/api packages/services'
  - go test ./cmd/api
  - bash scripts/ci/agent_queue_validate.sh
  - make queue-git-check
  notes: 'Context:

    2420d47b exposed V3 membership bind/change-role through the existing tenant
    membership authority, but there is no V3 remove/soft-delete contract yet.
    Without this, B can add users but cannot complete access governance lifecycle.

    Required outcome:

    - OpenAPI first for removing a user from project and/or tenant membership under
      the V3 access workbench.
    - implement ownership/tenant-admin checks, idempotency, typed errors, audit rows,
      and evidence/correlation output.
    - update read models so removed/inactive membership state is distinguishable from
      active rows and B can default-hide inactive history.

    Scope:

    - In: V3 membership remove/change-role evidence backend.
    - Out: UI wiring and external IdP user deletion.

    2026-05-05 implementation:

    - e2202804 added `POST /api/v1/v3/access/memberships/users/{user_id}/remove`
      with OpenAPI/generated types, tenant-admin ownership checks, idempotency
      guard, project-vs-tenant soft-delete semantics, audit action
      `tenant.user.membership.remove`, evidence/correlation response, and B-ui API
      helper `removeV3AccessUserMembership`.

    '
- id: A-V3-CONFIG-OSIMAGE-POLICY-COMPLETE-001
  title: Complete V3 config OS-image and quota policy mutation authority
  role: A-backend
  status: done
  priority: 1
  owner: A-backend
  branch: agent/A-backend
  completed_at: '2026-05-05'
  commit: a8edfa65
  depends_on:
  - A-V3-ACTION-LIFECYCLE-CONTRACT-AUDIT-001
  acceptance_checks:
  - sh -lc 'rg -q "platform/config/(os-images|quotas)|deprecate|policy|effective_at|actor" doc/api/openapi.draft.yaml cmd/api packages/services/inventory'
  - go test ./cmd/api
  - bash scripts/ci/agent_queue_validate.sh
  - make queue-git-check
  notes: 'Context:

    2420d47b exposed V3 aliases for SKU create/update/activate/deactivate, OS-image
    create/delete, and allocation concurrency policy. The config lifecycle is still
    incomplete for OS-image update/deprecate and richer quota/policy operation state.

    Required outcome:

    - OpenAPI first for OS-image update/deprecate/reactivate where supported and for
      quota/policy mutations that the Config workbench should expose.
    - implement backend handlers/services with idempotency, typed errors, audit logs,
      and latest actor/timestamp/evidence fields in read models.
    - keep PolicyClient as the source of truth; do not hardcode policy constants.

    Scope:

    - In: remaining V3 config backend authority and read-model operation metadata.
    - Out: frontend wiring and broad config-publish workflow redesign unless the
      audit requires it.

    2026-05-05 implementation:

    - a8edfa65 added inventory service authority and V3 contracts for OS-image
      update, deprecate, and reactivate in addition to the existing create/delete
      aliases.
    - Added generated Go/TS types, B-ui API helpers
      `updateV3PlatformConfigOSImage`, `deprecateV3PlatformConfigOSImage`, and
      `reactivateV3PlatformConfigOSImage`, plus focused API tests.
    - Broader quota/policy editor and config-publish workflow remain separate
      lifecycle work; this task now closes the OS-image gap named in the follow-up.

    '
- id: A-V3-ACCOUNT-SESSIONS-REVOCATION-LIFECYCLE-001
  title: Add V3 account session read model and revocation lifecycle authority
  role: A-backend
  status: done
  priority: 1
  owner: A-backend
  branch: agent/A-backend
  completed_at: '2026-05-05'
  commit: a46cd581
  depends_on:
  - A-V3-ACCOUNT-SECURITY-MUTATION-LIFECYCLE-001
  acceptance_checks:
  - sh -lc 'rg -q "account/sessions|revoke.*session|revoke.*others|deny:jti|session_id" doc/api/openapi.draft.yaml cmd/api packages/shared/middleware packages/services/auth'
  - go test ./cmd/api
  - bash scripts/ci/agent_queue_validate.sh
  - make queue-git-check
  notes: 'Context:

    2420d47b exposed V3 SSH-key account security aliases, but
    listV3AccountSessionRows currently returns an empty list and there is no
    session-specific revoke-one/revoke-others authority beyond logout revoking the
    caller token jti.

    Required outcome:

    - define the session identity source of truth for V3 account sessions.
    - OpenAPI first for revoke one session and revoke all other sessions.
    - implement auth ownership checks, idempotency, denylist/session invalidation,
      audit rows, typed errors, and read-model active/inactive state.
    - add tests for current-session protection, revoke-other semantics, and audit.

    Scope:

    - In: V3 account sessions backend/read-model authority.
    - Out: UI wiring and external IdP console session management unless required by
      the chosen authority.

    Completed:

    - Added first-party `account_sessions` authority keyed by OIDC
      `session_state`/`sid` with JWT `jti` fallback and recorder middleware for
      authenticated user traffic.
    - OpenAPI now exposes session rows with active/expired/revoked state,
      operation affordances, and idempotent revoke-one / revoke-others endpoints.
    - Revoke paths enforce ownership and current-session protection, write audit
      evidence, mark sessions revoked, and denylist latest tracked token IDs.
    - Refresh checks revoked provider sessions so a revoked upstream session cannot
      re-enter by minting a new locally accepted access token.
    - Generated Go/TS contracts and B-ui API helpers are updated; focused tests
      cover session operation metadata, current-session detection, status/risk
      helpers, and device parsing.

    '
- id: A-V3-STORAGE-BUCKET-LIFECYCLE-COMPLETE-001
  title: Complete V3 storage bucket update archive delete lifecycle authority
  role: A-backend
  status: done
  priority: 2
  owner: A-backend
  branch: agent/A-backend
  completed_at: '2026-05-05'
  commit: 29426169
  depends_on:
  - A-V3-ACTION-LIFECYCLE-CONTRACT-AUDIT-001
  acceptance_checks:
  - sh -lc 'rg -q "v3/storage.*(update|archive|delete)|storage.bucket.(update|archive|delete)|retention|quota" doc/api/openapi.draft.yaml cmd/api packages/services/storage'
  - go test ./cmd/api
  - bash scripts/ci/agent_queue_validate.sh
  - make queue-git-check
  notes: 'Context:

    V3 storage has create/grants/attachments/credential issue, but bucket-level
    update/archive/delete is still incomplete. The UI should not pretend storage
    lifecycle is complete until bucket lifecycle has backend authority and evidence.

    Required outcome:

    - OpenAPI first for supported bucket update/archive/delete operations.
    - implement project ownership checks, idempotency, provider-safe behavior, audit
      rows, and operation/evidence read-model fields.
    - preserve provider credential secrecy and avoid direct provider-specific data in
      frontend read models.

    Scope:

    - In: V3 storage bucket lifecycle backend completion.
    - Out: B-ui wiring and WEKA S3 capability validation blocked on provider readiness.

    Completed 2026-05-05:
    - Added contract-first V3 storage bucket lifecycle endpoints:
      PATCH /api/v1/v3/storage/{bucket_id}, POST /api/v1/v3/storage/{bucket_id}/archive,
      and DELETE /api/v1/v3/storage/{bucket_id}.
    - Implemented project-scoped ownership checks, idempotency-key enforcement, provider-safe
      delete behavior, active grant/attachment blocking, and audit actions
      storage.bucket.update/archive/delete.
    - Added mutation evidence responses, exposed bucket status in the read model, regenerated
      Go/TypeScript OpenAPI artifacts, and added typed web helpers for B-ui wiring.
    - Acceptance evidence: make codegen; go test ./cmd/api ./packages/services/storage;
      pnpm --dir packages/web typecheck; git diff --check.

    '
- id: A-V3-APPS-ARTIFACTS-LIFECYCLE-COMPLETE-001
  title: Complete V3 apps artifacts lifecycle mutation authority
  role: A-backend
  status: done
  priority: 2
  owner: A-backend
  branch: agent/A-backend
  completed_at: '2026-05-05'
  commit: d02832b1
  depends_on:
  - A-V3-ACTION-LIFECYCLE-CONTRACT-AUDIT-001
  acceptance_checks:
  - sh -lc 'rg -q "app-artifacts|publish-intent|promote|verify|revoke|deprecate|retire" doc/api/openapi.draft.yaml cmd/api packages/services'
  - go test ./cmd/api
  - bash scripts/ci/agent_queue_validate.sh
  - make queue-git-check
  notes: 'Context:

    Apps/artifacts still have V3 UI drift and lifecycle authority varies by route.
    Closure requires explicit artifact publish/promote/verify/revoke/deprecate/retire
    backend contracts or documented read-only exceptions.

    Required outcome:

    - audit existing project app artifact V1 authority and expose V3 aliases only
      where audit/idempotency/ownership rules already hold.
    - add missing V3 OpenAPI/handlers/read-model evidence for artifact lifecycle.
    - preserve registry credential secrecy and include operation/correlation feedback.

    Scope:

    - In: V3 apps/artifacts backend lifecycle completion.
    - Out: B-ui wiring and catalog card-grid redesign.

    Completed 2026-05-05:
    - Audited existing project app artifact authority and reused the existing service-owned
      lifecycle rather than forking registry logic.
    - Added V3 project-header aliases for artifact list/register/publish-intent/pull-intent
      plus verify/revoke/promote/deprecate/retire lifecycle mutations.
    - Preserved existing artifact audit/outbox ownership, registry credential secrecy, project
      scope checks, service-account actor handling, and idempotency gates for lifecycle mutations.
    - Regenerated Go/TypeScript OpenAPI artifacts and added typed V3 web helpers for B-ui wiring.
    - Acceptance evidence: make codegen; go test ./cmd/api; go test ./packages/services/inventory;
      pnpm --dir packages/web typecheck; git diff --check.

    '
- id: A-V3-FINANCE-REFUND-LIFECYCLE-BOUNDARY-001
  title: Define V3 finance refund request and reconciliation mutation boundaries
  role: A-backend
  status: done
  priority: 2
  owner: A-backend
  branch: agent/A-backend
  completed_at: '2026-05-05'
  commit: 80845ebe
  depends_on:
  - A-V3-ACTION-LIFECYCLE-CONTRACT-AUDIT-001
  acceptance_checks:
  - sh -lc 'rg -q "refund|payment.*reconcile|ledger.*immutable|finance" doc/api/openapi.draft.yaml cmd/api packages/services/billing packages/services/payments doc/product'
  - go test ./cmd/api
  - bash scripts/ci/agent_queue_validate.sh
  - make queue-git-check
  notes: 'Context:

    Billing usage is intentionally read-only, while refunds and platform payment
    reconciliation are actionable. V3 needs explicit boundaries so user-facing
    billing does not look unfinished and finance actions remain ledger-safe.

    Required outcome:

    - document and contract which finance rows are immutable ledgers vs actionable
      refund/reconciliation workflows.
    - expose V3 aliases or new contracts only where immutable-ledger and audit rules
      are preserved.
    - include disabled reasons, idempotency, audit/evidence, and correlation output.

    Scope:

    - In: V3 finance/refund backend lifecycle boundary and supported mutations.
    - Out: B-ui rendering and ledger mutation shortcuts.

    Completed:

    - Added V3 finance aliases for admin user refunds and raw payment-session
      support/reconciliation under /api/v1/v3/platform/finance.
    - Kept usage/ledger rows read-only in the contract while exposing only
      audited/idempotent refund and reconciliation workflows.
    - Updated platform finance operation hrefs to the V3 boundary and preserved
      disabled reasons, recovery modes, correlation-oriented support routes, and
      existing finance audit behavior.
    - Regenerated Go/TypeScript OpenAPI artifacts and added typed V3 web helpers
      for refunds, payment-session support reads, and reconciliation.
    - Acceptance evidence: make codegen; go test ./cmd/api; go test
      ./packages/services/billing ./packages/services/payments; pnpm --dir
      packages/web typecheck; git diff --check.

    '
- id: B-V3-ACCOUNT-SESSIONS-REVOCATION-UX-UNBLOCK-001
  title: Wire V3 account session revocation UX now that backend authority landed
  role: B-ui
  status: done
  priority: 1
  owner: B-ui
  branch: agent/B-ui
  completed_at: '2026-05-06'
  commit: 774d902c
  depends_on:
  - A-V3-ACCOUNT-SESSIONS-REVOCATION-LIFECYCLE-001
  - B-V3-ACCOUNT-SECURITY-SESSIONS-WORKBENCH-STANDARDIZE-001
  acceptance_checks:
  - pnpm --dir packages/web exec vitest run src/components/v3/v3-account-security-sessions.test.tsx
  - pnpm --dir packages/web typecheck
  - sh -lc 'rg -q "revokeV3AccountSession|revokeOtherV3AccountSessions" packages/web/src/components/v3/v3-account-subpages.tsx'
  - sh -lc '! rg -q "SESSION_REVOKE_BLOCKED_REASON|Session revocation is not yet available" packages/web/src/components/v3/v3-account-subpages.tsx packages/web/src/components/v3/v3-account-security-sessions.test.tsx'
  - bash scripts/ci/agent_queue_validate.sh
  - make queue-git-check
  notes: 'Context:

    B-V3-ACCOUNT-SECURITY-SESSIONS-WORKBENCH-STANDARDIZE-001 converted the
    sessions surface to the workbench shape, but it kept revocation hard-disabled
    with stale copy from before A-V3-ACCOUNT-SESSIONS-REVOCATION-LIFECYCLE-001
    landed.

    Required outcome:

    - remove the hardcoded session-revocation blocked copy.
    - wire `revokeV3AccountSession` for selected non-current active sessions.
    - wire `revokeOtherV3AccountSessions` as a page/detail action.
    - disable only intentional cases: current session, revoked/expired sessions,
      pending mutation, or backend-provided disabled state.
    - use idempotency keys, refetch on success, and surface success/error feedback.
    - update tests from "disabled with reason" to mutation/refetch coverage and
      current-session disabled coverage.

    Scope:

    - In: `/v3-prod/account/sessions` UX and tests.
    - Out: external IdP session-console administration and personal API-key
      lifecycle.

    '
- id: B-V3-ACCESS-LIFECYCLE-UX-COMPLETE-001
  title: Wire remaining V3 access governance lifecycle UX actions
  role: B-ui
  status: done
  priority: 1
  owner: B-ui
  branch: agent/B-ui
  completed_at: '2026-05-06'
  commit: 1ad4f287
  depends_on:
  - A-V3-IAM-ACCESS-MUTATION-LIFECYCLE-001
  - A-V3-ACCESS-MEMBERSHIP-REMOVE-LIFECYCLE-001
  - B-V3-ACCESS-GOVERNANCE-WORKBENCH-STANDARDIZE-001
  acceptance_checks:
  - pnpm --dir packages/web exec vitest run src/components/v3/v3-access-governance.test.tsx
  - pnpm --dir packages/web typecheck
  - sh -lc 'rg -q "bindV3AccessUserMembership|createV3AccessServiceAccount|deleteV3AccessServiceAccount|upsertV3AccessEntitlement" packages/web/src/components/v3/v3-access-subpages.tsx'
  - bash scripts/ci/agent_queue_validate.sh
  - make queue-git-check
  notes: 'Context:

    Backend access lifecycle aliases exist for membership bind/remove, service
    account create/rotate/delete, and entitlement grant/revoke. The current B
    workbench wiring covers some row actions, but generated helpers for bind
    membership, create/delete service account, and entitlement mutation are not
    consumed by the V3 UI yet.

    Required outcome:

    - expose membership add/change/remove where the backend contract supports it.
    - expose service-account create, rotate, and delete/disable with safe secret
      handling and one-time secret-copy UX only where returned by backend.
    - expose entitlement grant/revoke or enable/disable with audit/evidence feedback.
    - use standard drawer/confirmation patterns, idempotency keys, refetch on
      success, and clear disabled reasons.
    - keep raw secret reveal flows out unless the backend response explicitly
      returns one-time material for that mutation.

    Scope:

    - In: `/v3-prod/access/memberships`, `/v3-prod/access/service-accounts`, and
      `/v3-prod/access/entitlements`.
    - Out: external identity-provider administration and invitation emails unless
      already backed by V3 contracts.

    '
- id: B-V3-CONFIG-LIFECYCLE-UX-COMPLETE-001
  title: Wire remaining V3 platform config lifecycle UX actions
  role: B-ui
  status: done
  priority: 1
  owner: B-ui
  branch: agent/B-ui
  completed_at: '2026-05-06'
  commit: d74d140e
  depends_on:
  - A-V3-CONFIG-MUTATION-LIFECYCLE-001
  - A-V3-CONFIG-OSIMAGE-POLICY-COMPLETE-001
  - B-V3-CONFIG-LIFECYCLE-OPERATIONS-UX-001
  acceptance_checks:
  - pnpm --dir packages/web exec vitest run src/components/v3
  - pnpm --dir packages/web typecheck
  - sh -lc 'rg -q "createV3PlatformConfigSku|updateV3PlatformConfigSku|createV3PlatformConfigOSImage|updateV3PlatformConfigOSImage|setV3PlatformConfigAllocationConcurrencyPolicy" packages/web/src/components/v3'
  - bash scripts/ci/agent_queue_validate.sh
  - make queue-git-check
  notes: 'Context:

    Config lifecycle backend authority exists for SKU create/update, OS-image
    create/update/deprecate/reactivate, and allocation concurrency policy. The
    current UI wiring consumes the OS-image deprecate/reactivate path, but several
    generated config lifecycle helpers are still unused by V3 components.

    Required outcome:

    - wire SKU create/update and any supported activate/deactivate/archive controls.
    - wire OS-image create/update in addition to existing deprecate/reactivate.
    - wire allocation-concurrency policy editing with validation and audit feedback.
    - use OperationsDrawer or the established config workbench action pattern with
      idempotency, refetch, disabled reasons, and error/retry states.
    - preserve intentionally out-of-scope broad policy editor work unless the
      backend contract already supports it.

    Scope:

    - In: `/v3-prod/platform/config/skus`, `/v3-prod/platform/config/os-images`,
      and `/v3-prod/platform/config/quotas`.
    - Out: generic arbitrary policy editor beyond current V3 contracts.

    '
- id: B-V3-STORAGE-BUCKET-LIFECYCLE-UX-001
  title: Wire V3 storage bucket update archive delete lifecycle UX
  role: B-ui
  status: done
  priority: 2
  owner: B-ui
  branch: agent/B-ui
  completed_at: '2026-05-06'
  commit: c3a0d993
  depends_on:
  - A-V3-STORAGE-BUCKET-LIFECYCLE-COMPLETE-001
  - B-V3-STORAGE-WORKBENCH-STANDARDIZE-001
  acceptance_checks:
  - pnpm --dir packages/web exec vitest run src/components/v3
  - pnpm --dir packages/web typecheck
  - sh -lc 'rg -q "updateV3StorageBucket|archiveV3StorageBucket|deleteV3StorageBucket" packages/web/src/components/v3'
  - bash scripts/ci/agent_queue_validate.sh
  - make queue-git-check
  notes: 'Context:

    A-V3-STORAGE-BUCKET-LIFECYCLE-COMPLETE-001 added project-scoped V3 bucket
    update/archive/delete authority and generated B-ui helpers, but those helpers
    are not consumed by the current V3 storage UI.

    Required outcome:

    - expose bucket update/archive/delete from the storage workbench or focused
      bucket detail using the standard action drawer/confirmation pattern.
    - surface backend disabled/blocking states such as active grants or attachments.
    - refetch list/detail after success and show audit/evidence/correlation feedback.
    - preserve WEKA S3 capability limitations; do not invent provider behavior that
      remains blocked by provider readiness.

    Scope:

    - In: `/v3-prod/storage` and `/v3-prod/storage/[id]` bucket lifecycle controls.
    - Out: WEKA S3 protocol-host validation and provider credential internals.

    '
- id: B-V3-APPS-ARTIFACTS-LIFECYCLE-UX-001
  title: Wire V3 app artifact lifecycle UX actions
  role: B-ui
  status: done
  priority: 2
  owner: B-ui
  branch: agent/B-ui
  completed_at: '2026-05-06'
  commit: 7ff52455
  depends_on:
  - A-V3-APPS-ARTIFACTS-LIFECYCLE-COMPLETE-001
  - B-V3-BILLING-WORKBENCH-ROW-INTENT-001
  acceptance_checks:
  - pnpm --dir packages/web exec vitest run src/components/v3
  - pnpm --dir packages/web typecheck
  - sh -lc 'rg -q "revokeV3AppArtifact|deprecateV3AppArtifact|promoteV3AppArtifact|createV3AppArtifactPublishIntent" packages/web/src/components/v3'
  - bash scripts/ci/agent_queue_validate.sh
  - make queue-git-check
  notes: 'Context:

    A-V3-APPS-ARTIFACTS-LIFECYCLE-COMPLETE-001 exposed V3 artifact
    publish-intent, pull-intent, register, verify, revoke, promote, deprecate,
    and retire lifecycle aliases. The current V3 artifacts UI still needs the
    workbench/action counterpart.

    Required outcome:

    - convert `/v3-prod/apps/artifacts` tail work to filter rail + selected-row
      detail if not already done.
    - wire supported artifact lifecycle actions with idempotency, refetch,
      disabled reasons, and audit/evidence feedback.
    - keep registry credentials secret and only show approved one-time pull/publish
      material from backend responses.
    - preserve apps/compute catalog card-grid exception; this task is artifact
      lifecycle only.

    Scope:

    - In: `/v3-prod/apps/artifacts` list/detail/action UX.
    - Out: app catalog card redesign and registry-provider internals.

    '
- id: B-V3-FINANCE-LIFECYCLE-UX-BOUNDARY-001
  title: Wire V3 finance refund and payment reconciliation UX boundaries
  role: B-ui
  status: done
  priority: 2
  owner: B-ui
  branch: agent/B-ui
  completed_at: '2026-05-06'
  commit: 59209bad
  depends_on:
  - A-V3-FINANCE-REFUND-LIFECYCLE-BOUNDARY-001
  - B-V3-BILLING-WORKBENCH-ROW-INTENT-001
  - B-V3-FINANCE-SESSIONS-WORKBENCH-001
  acceptance_checks:
  - pnpm --dir packages/web exec vitest run src/components/v3
  - pnpm --dir packages/web typecheck
  - sh -lc 'rg -q "createV3PlatformFinanceUserRefund|reconcileV3PlatformFinancePaymentSession" packages/web/src/components/v3'
  - bash scripts/ci/agent_queue_validate.sh
  - make queue-git-check
  notes: 'Context:

    A-V3-FINANCE-REFUND-LIFECYCLE-BOUNDARY-001 exposed V3 aliases for admin user
    refunds and payment-session support/reconciliation while keeping ledger rows
    intentionally read-only. The generated V3 finance mutation helpers are not
    fully consumed by current V3 components.

    Required outcome:

    - wire user refund creation through the V3 finance boundary where operators
      currently need the action.
    - wire payment-session reconciliation through
      `reconcileV3PlatformFinancePaymentSession` where the Finance Sessions
      workbench exposes the operation.
    - keep usage/ledger rows read-only with an explicit visual explanation.
    - preserve immutable ledger rules, idempotency, refetch, disabled reasons, and
      audit/evidence/correlation feedback.

    Scope:

    - In: `/v3-prod/platform/finance`, `/v3-prod/platform/finance/sessions`, and
      related user-finance/refund action surfaces.
    - Out: direct ledger edits or provider shortcuts outside the audited backend
      boundary.

    '
- id: C-PLATFORM-CONTROL-VAULT-RECOVERY-AUTOMATION-001
  title: Add platform-control Vault sealed-state preflight and recovery automation
  role: C-ops
  status: done
  priority: 2
  owner: Codex
  branch: agent/C-ops
  completed_at: '2026-05-02'
  commit: 03412a73
  depends_on: []
  acceptance_checks:
  - >-
    sh -lc 'rg -q "Platform-Control Deploy Failure: Vault Sealed" doc/operations/runbooks/Vault_Bootstrap_and_Root_Token_Runbook.md'
  - >-
    sh -lc 'rg -q "vault status|Sealed=false|Vault is sealed" scripts/ci doc/operations/runbooks'
  - bash scripts/ci/agent_queue_validate.sh
  - make queue-git-check
  notes: 'Context:

    On 2026-05-01 a platform-control deploy failed during Vault-backed registry
    secret reconciliation because persistent Vault restarted sealed. K3s recovered
    after the root filesystem incident, but the release deploy path had no clear
    preflight or guided recovery for `Vault is sealed`. We manually unsealed `vault-0`
    using sensitive persistent init material inside the Vault data volume, retried
    the failed GitLab deploy job, and remote validation passed.

    Required outcome:

    - add a platform-control deploy preflight that checks Vault initialized/sealed
    state before secret reconciliation.
    - fail with a specific operator message when Vault is sealed, or implement an
    approved break-glass unseal path that reads escrowed material without printing
    secrets.
    - verify required mounts and platform-control registry secret readability after
    unseal and before continuing deployment.
    - document the supported unseal authority. Do not rely on cluster-only material
    as the long-term escrow model.
    - ensure CI/deploy logs never print the unseal key, root token, operational token,
    or Vault secret values.
    - update release validation evidence so future operators can distinguish "Vault
    sealed" from application deploy failures.

    Scope:

    - In: platform-control deploy scripts, Vault health/preflight checks, runbook
    updates, evidence hooks, and safe retry guidance.
    - Out: changing application secret contracts, replacing Vault, or deploying new
    platform-control workloads.

    '
- id: A-V3-WORKLOAD-LIFECYCLE-CONTRACT-COMPLETE-001
  title: Complete V3 workload lifecycle and connection read-model contract
  role: A-backend
  status: done
  priority: 1
  owner: A-backend
  branch: agent/A-backend
  depends_on: []
  acceptance_checks:
  - go test ./cmd/api -run 'TestV3Workload'
  - sh -lc 'rg -q "lifecycle_actions|connection_facts|correlation_id" doc/api/openapi.draft.yaml cmd/api packages/web/src/lib/gen/openapi.types.ts'
  - bash scripts/ci/agent_queue_validate.sh
  - make queue-git-check
  completed_at: '2026-05-06'
  commit: bdedc33e
  notes: 'Context:

    V3 Workloads can show active compute/app rows, but compute allocation rows and
    detail pages do not expose enough user-actionable lifecycle and connection
    metadata. Users need release/restart capability flags, disabled reasons,
    task/evidence/correlation pivots, and useful connection values like hostname,
    IP, SSH command, and terminal href without centering internal allocation IDs.

    Required outcome:

    - update the V3 workload read-model contract before code changes.
    - expose per-workload lifecycle actions for release and restart where supported,
      including enabled/disabled state and reason.
    - include operation result/task/evidence/correlation metadata for lifecycle
      submissions or clear TODO fields when the owning mutation path is missing.
    - expose connection facts in list/detail read models: hostname/node name, IP or
      endpoint, SSH command, terminal href, and copy-safe labels.
    - keep backend-owned keys opaque; clients must not derive action availability.

    Scope:

    - In: OpenAPI schema, Go read-model assembly, generated TS types, and focused
      read-model tests.
    - Out: frontend buttons, copy UI, and broad Workloads visual redesign.

    '
- id: B-V3-WORKLOAD-ACTIONS-AND-CONNECTION-UX-001
  title: Add V3 workload release/restart and connection-first UX
  role: B-ui
  status: done
  priority: 1
  owner: B-ui
  branch: agent/B-ui
  completed_at: '2026-05-06'
  commit: 7f01d2ca
  depends_on:
  - A-V3-WORKLOAD-LIFECYCLE-CONTRACT-COMPLETE-001
  acceptance_checks:
  - pnpm --dir packages/web exec vitest run src/components/v3
  - pnpm --dir packages/web typecheck
  - sh -lc 'rg -q "Release|Restart|Copy|connection_facts|lifecycle_actions" packages/web/src/components/v3'
  - bash scripts/ci/agent_queue_validate.sh
  - make queue-git-check
  notes: 'Context:

    The new Workloads UI is missing obvious compute allocation actions and hides
    useful connection facts behind detail views or internal IDs. Users care about
    hostname, IP/endpoint, SSH command, terminal link, and safe release/restart
    controls more than allocation UUIDs.

    Required outcome:

    - surface Release and Restart actions for compute allocations where the backend
      contract says they are enabled.
    - show disabled reasons when an action cannot run.
    - place hostname/IP/SSH/terminal facts in the first workload row or immediate
      detail area with copy buttons for copy-safe values.
    - demote internal allocation IDs behind expanded detail/context.
    - show durable operation result/correlation/task/evidence pivots after mutation.

    Scope:

    - In: Workloads list/detail UI and focused tests.
    - Out: backend contract changes, app runtime stop/start redesign, and scheduler
      cluster node operations.

    '
- id: B-V3-WORKLOAD-FILTER-SEGMENTS-001
  title: Replace workload kind dropdown with segmented runtime filter
  role: B-ui
  status: done
  priority: 2
  owner: B-ui
  branch: agent/B-ui
  completed_at: '2026-05-06'
  commit: 7f01d2ca
  depends_on:
  - B-V3-WORKLOADS-WORKBENCH-STANDARDIZE-001
  acceptance_checks:
  - pnpm --dir packages/web exec vitest run src/components/v3/v3-workloads-page.test.tsx
  - pnpm --dir packages/web typecheck
  - sh -lc 'rg -q "All|Compute|Apps" packages/web/src/components/v3/v3-workloads-page.tsx'
  - bash scripts/ci/agent_queue_validate.sh
  notes: 'Context:

    The Workloads kind filter is currently a dropdown even though the product has
    only three meaningful choices: all, compute, and apps. A segmented/icon control
    is faster and makes the user mental model clearer. Later, user preferences can
    decide the default segment.

    Required outcome:

    - replace the runtime dropdown with a segmented/icon control: All, Compute, Apps.
    - keep existing query/filter behavior and tests.
    - leave preference-backed default selection for a follow-up.

    '
- id: AB-V3-SCHEDULER-RUNTIME-NODE-LIFECYCLE-001
  title: Define and wire Slurm/Kubernetes runtime node lifecycle operations
  role: A-backend
  status: done
  priority: 2
  owner: A-backend
  branch: agent/A-backend
  completed_at: '2026-05-06'
  commit: 89b93a3a
  depends_on: []
  acceptance_checks:
  - sh -lc 'rg -q "add.*node|remove.*node|drain|agent" doc/api/openapi.draft.yaml cmd packages/web/src/components/v3'
  - go test ./cmd/api ./packages/services/... 
  - pnpm --dir packages/web exec vitest run src/components/v3
  - bash scripts/ci/agent_queue_validate.sh
  notes: 'Context:

    Kubernetes/RKE2 and Slurm runtime surfaces lack add/remove node and agent
    lifecycle operations. Some controller code already knows how to drain/delete
    nodes, but V3 needs a contract-first workflow with permissions, task/evidence
    pivots, disabled reasons, and UX wiring.

    Required outcome:

    - audit existing Slurm/RKE2 controller capabilities and current API contracts.
    - add or confirm contract endpoints/read models for add/remove/drain/agent
      lifecycle actions.
    - wire backend mutations/read-model capability flags first, then the V3 UX.
    - ensure every privileged mutation writes audit evidence and returns
      correlation/task information.

    '
- id: AB-V3-PAGINATION-STANDARD-001
  title: Standardize V3 pagination and large-list behavior
  role: A-backend
  status: done
  priority: 2
  owner: A-backend
  branch: agent/A-backend
  completed_at: '2026-05-06'
  commit: 4c93f113
  depends_on: []
  acceptance_checks:
  - sh -lc 'rg -q "page_size|cursor|next_cursor|pagination" doc/api/openapi.draft.yaml packages/web/src/components/v3'
  - go test ./cmd/api -run 'V3.*List|Pagination|Cursor'
  - pnpm --dir packages/web exec vitest run src/components/v3
  - bash scripts/ci/agent_queue_validate.sh
  notes: 'Context:

    Several V3 tables/workbenches render too many rows and become long scrolling
    walls of text. Pagination or a deliberate show-more cap must become a common
    contract and UI primitive rather than page-specific fixes.

    Required outcome:

    - define V3 list pagination standard: cursor fields, page_size, default caps,
      total/count semantics, and empty/end states.
    - apply it first to the loudest large surfaces such as billing usage, audit,
      workloads, and platform workbenches where missing.
    - add a shared UI pagination/show-more primitive.

    '
- id: B-V3-COMPUTE-APPS-REAL-DATA-PASS-001
  title: Replace mock-feeling Compute and Apps overview content with real data
  role: B-ui
  status: done
  priority: 2
  owner: B-ui
  branch: agent/B-ui
  completed_at: '2026-05-06'
  commit: ab23cb49
  depends_on: []
  acceptance_checks:
  - pnpm --dir packages/web exec vitest run src/components/v3/v3-compute-page.test.tsx src/components/v3/v3-apps-page.test.tsx
  - pnpm --dir packages/web typecheck
  - sh -lc 'rg -q "mock|placeholder|demo" packages/web/src/components/v3/v3-compute-page.tsx packages/web/src/components/v3/v3-apps-page.tsx && exit 1 || exit 0'
  - bash scripts/ci/agent_queue_validate.sh
  notes: 'Context:

    Compute and Apps overview pages still read like mocks in places: prose and
    real data are interlaced, and the page does not always lead with operationally
    useful state. These catalog pages are intentional exceptions to the workbench
    row pattern, but they still need to feel production-data driven.

    Required outcome:

    - audit Compute and Apps overview cards/sections.
    - remove placeholder/prototype-feeling copy.
    - lead with live capacity, entitlement, launchability, and recent workload
      facts where available.
    - preserve catalog-browse card-grid exception.

    '
- id: C-V3-PLAYWRIGHT-UX-AUDIT-001
  title: Run screenshot-driven V3 UX audit with Playwright
  role: C-ops
  status: todo
  priority: 2
  owner: C-ops
  branch: agent/C-ops
  depends_on: []
  acceptance_checks:
  - sh -lc 'test -d dist/smoke/v3-ux-audit || test -d tmp-ux'
  - sh -lc 'rg -q "blocking UX|inconsistent UX|missing lifecycle|data-density" doc/product'
  - bash scripts/ci/agent_queue_validate.sh
  notes: 'Context:

    After many V3 UX changes, manual review is catching issues that component tests
    miss. We need a Playwright-driven screenshot pass across user and admin
    workflows, grouped by product impact rather than by file.

    Required outcome:

    - capture screenshots for login/personas, launch compute, workloads, workload
      detail, storage, access, billing, apps, compute, platform lifecycle, node
      operations, evidence, finance, config, and IAM.
    - report findings grouped as blocking UX, inconsistent UX, missing lifecycle
      actions, data-density/pagination, and copy/prose issues.
    - do not make UX changes in this task except tiny test harness fixes.

    '
- id: B-V3-SURFACE-ROW-INTENT-CONTRACT-001
  title: Define V3 surface row intent and useful-data contract
  role: B-ui
  status: todo
  priority: 1
  owner: unassigned
  branch: agent/B-ui
  depends_on:
  - C-V3-PLAYWRIGHT-UX-AUDIT-001
  acceptance_checks:
  - sh -lc 'test -f doc/product/V3_Surface_Row_Intent_and_Useful_Data_Audit_v1.md'
  - sh -lc 'rg -q "Navigate-To-Detail Workbench|Operation Drawer|Node Inventory Target|Surface Useful-Data Matrix" doc/product/V3_Surface_Row_Intent_and_Useful_Data_Audit_v1.md'
  - bash scripts/ci/agent_queue_validate.sh
  - make queue-git-check
  notes: 'Context:

    Manual review found that several V3 pages have consistent chrome but still
    do not answer the user/operator decision. Node inventory is the clearest
    example: the list shows status/name/SKU/occupancy/agent hash, but not the
    IP, capacity, image/driver, owner/project, latest operation, or next safe
    action that an operator needs before opening detail. Node operations drawer
    also reads like a documentation catalog rather than a sparse action picker.

    Required outcome:

    - add or finalize `doc/product/V3_Surface_Row_Intent_and_Useful_Data_Audit_v1.md`.
    - classify V3 routes into family landing, selected-row workbench,
      navigate-to-detail workbench, read-only ledger, catalog browse, focused
      workflow, operation drawer, and evidence/event drawer.
    - define useful list/card/table fields by surface before more UI changes.
    - explicitly capture operation drawer anti-patterns: long documentation-like
      drawers, every-theoretical-verb catalogs, repeated generic "Open focused
      action flow" buttons, and destructive flows that look like safe buttons.
    - update `V3_Workbench_Consistency_Plan_v2.md` and
      `V3_Navigation_Journey_Contract_v1.md` if their current rules conflict.

    Scope:

    - In: product contract/docs and backlog sequencing.
    - Out: page implementation changes, backend field additions, and deploy.

    '
- id: A-V3-SURFACE-USEFUL-DATA-READMODEL-GAPS-001
  title: Audit V3 read models against surface useful-data contract
  role: A-backend
  status: todo
  priority: 1
  owner: unassigned
  branch: agent/A-backend
  depends_on:
  - B-V3-SURFACE-ROW-INTENT-CONTRACT-001
  acceptance_checks:
  - sh -lc 'rg -q "read-model gaps|node list|primary IP|latest operation|driver" doc/product doc/api/openapi.draft.yaml cmd/api'
  - go test ./cmd/api -run 'TestV3.*ReadModel|TestV3Platform'
  - bash scripts/ci/agent_queue_validate.sh
  - make queue-git-check
  notes: 'Context:

    UI cannot make rows useful when the read model does not expose the decision
    data. Audit OpenAPI and Go V3 read models against the useful-data matrix
    before B starts broad row-content redesigns.

    Required outcome:

    - compare each major V3 surface read model to
      `V3_Surface_Row_Intent_and_Useful_Data_Audit_v1.md`.
    - produce concrete field-level backend gaps, starting with nodes, workloads,
      storage, compute/apps, billing, evidence, and IAM.
    - classify fields as already available, derivable safely server-side,
      blocked by missing source-of-truth, or intentionally omitted.
    - do not invent client-derived state for backend-owned capabilities.

    Scope:

    - In: audit doc updates, OpenAPI TODOs or task references, focused tests if
      fields are trivial to expose.
    - Out: broad frontend redesign.

    '
- id: A-V3-NODE-INVENTORY-OPERATOR-READMODEL-001
  title: Add operator-useful fields to V3 node inventory read models
  role: A-backend
  status: todo
  priority: 1
  owner: unassigned
  branch: agent/A-backend
  depends_on:
  - A-V3-SURFACE-USEFUL-DATA-READMODEL-GAPS-001
  acceptance_checks:
  - sh -lc 'rg -q "primary_ip|management_ip|maas_ip|driver|image|latest_operation|schedul" doc/api/openapi.draft.yaml cmd/api packages/web/src/lib/gen/openapi.types.ts'
  - go test ./cmd/api -run 'TestV3PlatformNode'
  - bash scripts/ci/agent_queue_validate.sh
  - make queue-git-check
  notes: 'Context:

    `/v3-prod/platform/lifecycle/nodes` currently cannot show enough useful
    operator data in the list because `V3PlatformNodeRow` is too thin. The UI
    needs server-owned node facts rather than client guesses.

    Required outcome:

    - update the V3 node inventory contract before implementation.
    - expose list-level primary/management/MAAS IP where authoritative.
    - expose site/region/rack or placement domain where authoritative.
    - expose OS/image/kernel/driver/CUDA/fabric profile where authoritative.
    - expose heartbeat age/severity rather than raw timestamp only.
    - expose latest node operation summary with correlation/evidence/task href
      where available.
    - expose schedulability/capability flags and disabled reasons for quick
      list actions.
    - add focused API/read-model tests.

    Scope:

    - In: OpenAPI, Go V3 platform node read models, generated TS types, tests.
    - Out: frontend redesign and new destructive operation semantics.

    '
- id: B-V3-NODE-INVENTORY-NAVIGATE-DETAIL-REDESIGN-001
  title: Redesign V3 node inventory as navigate-to-detail operator workbench
  role: B-ui
  status: todo
  priority: 1
  owner: unassigned
  branch: agent/B-ui
  depends_on:
  - B-V3-SURFACE-ROW-INTENT-CONTRACT-001
  - A-V3-NODE-INVENTORY-OPERATOR-READMODEL-001
  acceptance_checks:
  - pnpm --dir packages/web exec vitest run src/components/v3/v3-platform-lifecycle-nodes-operations.test.tsx
  - pnpm --dir packages/web typecheck
  - sh -lc 'rg -q "Back to nodes|Open telemetry|primary_ip|latest_operation|WorkbenchListShell" packages/web/src/components/v3'
  - bash scripts/ci/agent_queue_validate.sh
  - make queue-git-check
  notes: 'Context:

    Node inventory currently uses selected-row workbench chrome, but node detail
    is a rich focused workspace. This creates an awkward sequence: list row
    selects a partial panel, the panel opens a long operation drawer, some
    operations jump to a focused detail page, and back can lose the node-list
    context. The list itself also hides important operator data.

    Required outcome:

    - move `/v3-prod/platform/lifecycle/nodes` to the navigate-to-detail model.
    - row click opens `/v3-prod/platform/lifecycle/nodes/{node_id}`.
    - row content shows operator-useful scan data: hostname, status,
      schedulability, free/used GPUs/slices, active allocations/project/owner,
      SKU/GPU model, site/region/rack, primary IP, OS/image/driver, heartbeat,
      latest operation/evidence, and next safe action where available.
    - keep only safe quick actions in the list row, such as copy host/IP and
      open telemetry; cordon/drain only if backend capability flags and disabled
      reasons make the risk obvious.
    - detail page owns the action hub and backs to the nodes workbench.
    - remove documentation-like operation catalog behavior from the list-level
      flow.

    Scope:

    - In: nodes workbench/detail UI and focused tests.
    - Out: backend field additions beyond consuming the A task, MAAS workflow
      semantics, and unrelated platform lifecycle pages.

    '
- id: B-V3-OPERATION-DRAWER-SPARSE-ACTION-PATTERN-001
  title: Normalize operation drawers into sparse action pickers
  role: B-ui
  status: todo
  priority: 2
  owner: unassigned
  branch: agent/B-ui
  depends_on:
  - B-V3-SURFACE-ROW-INTENT-CONTRACT-001
  acceptance_checks:
  - pnpm --dir packages/web exec vitest run src/components/v3/admin src/components/v3
  - pnpm --dir packages/web typecheck
  - sh -lc 'rg -q "Focused workflow required|Runbook|OperationsDrawer" packages/web/src/components/v3'
  - bash scripts/ci/agent_queue_validate.sh
  notes: 'Context:

    Operation drawers should be sparse action pickers. They currently risk
    becoming documentation pages that list all possible verbs, long descriptions,
    runbook-like prose, and generic focused-flow buttons.

    Required outcome:

    - audit all V3 `OperationsDrawer` consumers.
    - limit default drawer content to state-relevant operations.
    - move long descriptions to runbooks or focused workflows.
    - distinguish safe direct actions, disabled actions, typed-confirmation
      actions, and focused workflow pivots with different copy/treatment.
    - add tests that prevent node-style documentation drawers from returning.

    Scope:

    - In: shared drawer pattern and current consumers.
    - Out: backend operation semantics and non-drawer page redesign.

    '
- id: B-V3-ROW-CONTENT-PASS-USER-SURFACES-001
  title: Apply useful-data row content rules to V3 user surfaces
  role: B-ui
  status: todo
  priority: 2
  owner: unassigned
  branch: agent/B-ui
  depends_on:
  - B-V3-SURFACE-ROW-INTENT-CONTRACT-001
  - A-V3-SURFACE-USEFUL-DATA-READMODEL-GAPS-001
  acceptance_checks:
  - pnpm --dir packages/web exec vitest run src/components/v3
  - pnpm --dir packages/web typecheck
  - sh -lc 'rg -q "copy|hostname|IP|endpoint|last used|Show more|pagination" packages/web/src/components/v3'
  - bash scripts/ci/agent_queue_validate.sh
  notes: 'Context:

    Several user-facing V3 surfaces have the right chrome but not enough useful
    row/card data. Apply the useful-data contract broadly after backend gaps are
    known.

    Required outcome:

    - review workloads, storage, access, account security/sessions, billing,
      apps, compute, and artifacts against the useful-data matrix.
    - demote internal IDs behind detail/context where they do not drive user
      decisions.
    - add copy buttons for copy-safe endpoint/host/IP/SSH/correlation fields.
    - make large ledgers/tables use the pagination/show-more standard.

    Scope:

    - In: user-surface row/card/table content and focused tests.
    - Out: platform-admin surfaces and backend contracts not already available.

    '
- id: B-V3-ROW-CONTENT-PASS-ADMIN-SURFACES-001
  title: Apply useful-data row content rules to V3 admin/platform surfaces
  role: B-ui
  status: todo
  priority: 2
  owner: unassigned
  branch: agent/B-ui
  depends_on:
  - B-V3-SURFACE-ROW-INTENT-CONTRACT-001
  - A-V3-SURFACE-USEFUL-DATA-READMODEL-GAPS-001
  acceptance_checks:
  - pnpm --dir packages/web exec vitest run src/components/v3
  - pnpm --dir packages/web typecheck
  - sh -lc 'rg -q "correlation|evidence|last operation|owner|driver|capacity" packages/web/src/components/v3'
  - bash scripts/ci/agent_queue_validate.sh
  notes: 'Context:

    Platform/admin V3 surfaces should help operators decide, not dump records.
    Apply the useful-data contract across lifecycle, config, evidence, finance,
    IAM, MAAS, and provisioning pages.

    Required outcome:

    - review platform lifecycle, nodes, MAAS, config, evidence, finance, IAM,
      tasks, and provisioning workflow pages against the useful-data matrix.
    - prioritize operational fields: ownership, state, capacity, correlation,
      evidence, latest operation, disabled reason, and next safe action.
    - remove documentation-like prose from drawers and rows.

    Scope:

    - In: admin/platform row/card/detail content and focused tests.
    - Out: user surfaces and backend contracts not already available.

    '
- id: C-V3-UX-REVIEW-ITERATION-RUNBOOK-001
  title: Run iterative UX review against V3 surface row-intent contract
  role: C-ops
  status: todo
  priority: 2
  owner: unassigned
  branch: agent/C-ops
  depends_on:
  - B-V3-SURFACE-ROW-INTENT-CONTRACT-001
  acceptance_checks:
  - sh -lc 'test -d dist/smoke/v3-ux-audit || test -d tmp-ux'
  - sh -lc 'rg -q "wrong model|missing useful data|bad action ownership|density|pagination" doc/product'
  - bash scripts/ci/agent_queue_validate.sh
  notes: 'Context:

    UX review should now classify findings against the row-intent/useful-data
    contract instead of only capturing screenshots.

    Required outcome:

    - run screenshot/video review after deploy.
    - classify every finding as wrong model, missing useful data, bad action
      ownership, data density/pagination, or copy/prose.
    - include concrete before/after screenshots and affected route.
    - do not make product UI changes in this task.

    '
- id: A-V3-ERROR-CORRELATION-TRACKABILITY-001
  title: Enforce correlation-id and actionable diagnostics across V3 errors
  role: A-backend
  status: done
  priority: 1
  owner: A-backend
  branch: agent/A-backend
  completed_at: '2026-05-06'
  commit: 5057b22f
  depends_on: []
  acceptance_checks:
  - sh -lc 'rg -q "correlation_id" doc/api/openapi.draft.yaml cmd/api packages/web/src/components/v3'
  - go test ./cmd/api ./packages/shared/...
  - pnpm --dir packages/web exec vitest run src/components/v3
  - bash scripts/ci/agent_queue_validate.sh
  - make queue-git-check
  notes: 'Context:

    Error responses must be trackable. Some V3 flows have drifted into generic
    failure messages or client-side error displays that do not expose
    `correlation_id`, a log/evidence pivot, or actionable operator guidance.

    Required outcome:

    - audit V3 API error paths and ensure canonical errors include `correlation_id`
      on every non-2xx response.
    - classify changed 5xx paths as upstream dependency or local defect per the
      5xx classification gate.
    - ensure mutation errors returned to the UI preserve and display correlation ID
      and, where available, evidence/log/task links.
    - add regression tests for representative validation, authz, not-found,
      conflict, upstream, and local-defect paths.
    - update UI error primitives to show copyable correlation IDs and meaningful
      next steps instead of only "try again".

    Scope:

    - In: V3 API errors, shared API client error parsing, V3 error display
      primitives, focused tests.
    - Out: redesigning unrelated happy-path page layouts.

    '
- id: A-BACKEND-OBSERVABILITY-GUARD-COVERAGE-001
  title: Expand backend error and observability guard coverage
  role: A-backend
  status: done
  priority: 1
  owner: A-backend
  branch: agent/A-backend
  depends_on: []
  completed_at: '2026-05-06'
  commit: e370b767
  acceptance_checks:
  - bash scripts/ci/canonical_error_guard.sh
  - bash scripts/ci/log_correlation_guard.sh
  - bash scripts/ci/trace_header_guard.sh
  - bash scripts/ci/observability_trace_gate.sh
  - bash scripts/ci/audit_mandatory_guard.sh
  - bash scripts/ci/outbox_tx_guard.sh
  - bash scripts/ci/agent_queue_validate.sh
  - make queue-git-check
  notes: 'Context:

    The current backend observability guards are green, but some are too narrow
    after the route split and V3 expansion. For example, canonical_error_guard
    checks cmd/api/routes.go but newer handlers also live in cmd/api/routes_*.go.

    Required outcome:

    - expand guard scope across cmd/api/routes*.go, gateway route files, worker
      route files, and relevant production service files.
    - fail on production http.Error usage, direct 4xx/5xx writeJSON error bodies,
      request-path warn/error logs without correlation context, direct event
      publish from route layers, and discarded audit helper errors.
    - keep false positives low by excluding *_test.go and documented test-only
      fixtures.
    - update Backend_Error_Observability_Sweep_Plan_v1.md with baseline findings
      from the expanded gates.

    Scope:

    - In: scripts/ci guards, make target wiring if needed, focused guard tests or
      shell smoke checks, governance plan update.
    - Out: fixing every newly discovered route/service violation in the same
      commit unless the fix is trivial.

    '
- id: A-BACKEND-5XX-CLASSIFICATION-SWEEP-001
  title: Classify and test backend 5xx error paths
  role: A-backend
  status: done
  priority: 1
  owner: A-backend
  branch: agent/A-backend
  depends_on:
  - A-BACKEND-OBSERVABILITY-GUARD-COVERAGE-001
  completed_at: '2026-05-06'
  commit: 15eb1c7c
  acceptance_checks:
  - sh -lc 'rg -q "internal_error|upstream_error|service_unavailable" doc/governance/Backend_Error_Observability_Sweep_Plan_v1.md cmd/api packages/services'
  - go test ./cmd/api ./packages/services/... ./packages/shared/...
  - bash scripts/ci/canonical_error_guard.sh
  - bash scripts/ci/log_correlation_guard.sh
  - bash scripts/ci/agent_queue_validate.sh
  - make queue-git-check
  notes: 'Context:

    Coding standards require every changed 5xx path to be classified as local
    defect or upstream dependency. After many V3 route additions, classification
    needs a broad pass instead of ad hoc review comments.

    Required outcome:

    - inventory 5xx response paths in API routes and backend services.
    - classify each changed path as internal_error, upstream_error, or
      service_unavailable with rationale.
    - fix obvious misclassifications without hiding local defects as dependency
      outages.
    - add representative httptest/unit coverage for validation, authz, not-found,
      conflict, dependency-unavailable, and local-defect paths.
    - ensure 5xx logs include correlation_id and resource identifiers needed to
      find the failing query/provider/worker path.

    '
- id: A-BACKEND-WORKER-TRACEABILITY-SWEEP-001
  title: Audit worker and async traceability
  role: A-backend
  status: done
  priority: 2
  owner: A-backend
  branch: agent/A-backend
  depends_on:
  - A-BACKEND-OBSERVABILITY-GUARD-COVERAGE-001
  completed_at: '2026-05-06'
  commit: fb81e109
  acceptance_checks:
  - bash scripts/ci/observability_trace_gate.sh
  - bash scripts/ci/trace_header_guard.sh
  - go test ./cmd/billing-worker ./cmd/provisioning-worker ./cmd/app-runtime-worker ./cmd/webhook-worker ./cmd/notification-relay ./cmd/outbox-relay ./packages/shared/events ./packages/shared/outbox
  - bash scripts/ci/agent_queue_validate.sh
  - make queue-git-check
  notes: 'Context:

    Async flows are where agent debugging usually breaks down: event subject,
    event ID, aggregate ID, correlation ID, and trace headers must survive worker
    hops and outbox relay processing.

    Required outcome:

    - audit billing, provisioning, app-runtime, webhook, notification, and outbox
      worker spans/logs.
    - ensure message-processing spans include correlation_id, event type/subject,
      event_id where available, aggregate/resource identifiers, and error_code on
      failure.
    - verify outbox trace headers are persisted and extracted through relay paths.
    - add focused tests or guard assertions for any worker path changed.

    '
- id: A-BACKEND-AUDIT-OUTBOX-SANITIZATION-SWEEP-001
  title: Sweep privileged mutation audit, outbox, and sanitization guarantees
  role: A-backend
  status: done
  priority: 2
  owner: A-backend
  branch: agent/A-backend
  depends_on:
  - A-BACKEND-OBSERVABILITY-GUARD-COVERAGE-001
  completed_at: '2026-05-06'
  commit: eb846761
  acceptance_checks:
  - bash scripts/ci/audit_mandatory_guard.sh
  - bash scripts/ci/audit_presence_guard.sh
  - bash scripts/ci/outbox_tx_guard.sh
  - bash scripts/ci/log_code_guard.sh
  - go test ./cmd/api ./packages/services/...
  - bash scripts/ci/agent_queue_validate.sh
  - make queue-git-check
  notes: 'Context:

    Privileged mutations must be auditable and safe to inspect. Drift here is
    dangerous because it can make incidents untraceable or leak sensitive values
    into logs/traces/audit metadata.

    Required outcome:

    - audit privileged mutation paths for audit rows in the same transaction where
      required.
    - audit outbox writes for same-transaction domain changes and no direct route
      layer publishing.
    - check audit metadata uses allowlisted keys and never stores raw request or
      response payload dumps.
    - check logs/traces do not include tokens, SSH material, payment references,
      raw credentials, or high-volume PII.
    - add focused tests or guards for any fixed path.

    '
- id: A-BACKEND-EVIDENCE-PIVOT-COVERAGE-001
  title: Ensure backend mutation responses expose evidence pivots
  role: A-backend
  status: done
  priority: 2
  owner: A-backend
  branch: agent/A-backend
  completed_at: '2026-05-06'
  commit: a2e986ff
  depends_on:
  - A-BACKEND-5XX-CLASSIFICATION-SWEEP-001
  acceptance_checks:
  - sh -lc 'rg -q "correlation_id|task_href|evidence_href|operation_id" doc/api/openapi.draft.yaml cmd/api packages/web/src/lib/gen/openapi.types.ts'
  - go test ./cmd/api ./packages/services/...
  - pnpm --dir packages/web exec vitest run src/lib/api src/lib/v3
  - bash scripts/ci/agent_queue_validate.sh
  - make queue-git-check
  notes: 'Context:

    Error and lifecycle responses are only agent-friendly if the next pivot is
    visible without direct SQL. Backend mutations should return durable correlation,
    task, operation, and evidence pointers where the owning workflow has them.

    Required outcome:

    - audit V3 backend mutation responses for correlation_id, task_id/task_href,
      operation_id, audit/evidence hrefs, and disabled reasons.
    - add missing contract fields before code changes when a response shape is
      incomplete.
    - regenerate clients and update representative API/UI tests.
    - keep opaque IDs opaque; clients should display/pivot, not derive backend
      state.

    '
- id: B-V3-RUNTIME-MANAGEMENT-MUTATION-UI-001
  title: Finish V3 shared runtime management mutation UI with runtime-specific terminology
  role: B-ui
  status: todo
  priority: 1
  owner: ''
  branch: agent/B-ui
  completed_at: ''
  commit: ''
  depends_on: []
  acceptance_checks:
  - pnpm --dir packages/web typecheck
  - pnpm --dir packages/web exec vitest run src/components/v3 packages/web/app/v3
  - sh -lc 'E2E_BASE_URL=https://gpuaas-kind-app.tailfe39f5.ts.net pnpm --dir packages/web e2e e2e/v3-workloads.spec.ts e2e/v3-admin-platform.spec.ts'
  - bash scripts/ci/agent_queue_validate.sh
  - make queue-git-check
  notes: 'Context:

    `tmp-ux/v1-v3-migration-audit-2026-05-08.md` recorded that shared runtime
    reads are now mapped to V3 scheduler surfaces, but management actions still
    need V3 workflow mapping and runtime-specific copy. The UI should not present
    Jupyter, vLLM, Slurm, and RKE2 as the same generic runtime-management object
    when the domain terminology differs.

    Required outcome:

    - Use the runtime/app config model to drive labels, nouns, operation copy,
      and worker/member terminology for Jupyter, vLLM, Slurm, and RKE2.
    - Wire available V3 shared-runtime worker operation controls without falling
      back to frozen v1 continuity clients.
    - Keep app-instance controls and scheduler shared-runtime controls distinct
      where the product intent differs.
    - Hide or disable unsupported operations with backend-provided reasons rather
      than mock placeholders.

    Scope:

    - In: V3 scheduler/shared-runtime UI and shared V3 runtime-management primitives.
    - Out: new backend runtime semantics unless the UI proves a missing contract,
      in which case create a separate A-backend follow-up.

    '
- id: A-V3-EVIDENCE-OWNERSHIP-SPLIT-001
  title: Finish V3 evidence ownership split for account project tenant and access scopes
  role: A-backend
  status: todo
  priority: 1
  owner: ''
  branch: agent/A-backend
  completed_at: ''
  commit: ''
  depends_on: []
  acceptance_checks:
  - bash scripts/ci/contracts_validate.sh
  - go test ./cmd/api
  - pnpm --dir packages/web typecheck
  - bash scripts/ci/agent_queue_validate.sh
  - make queue-git-check
  notes: 'Context:

    The V1/V3 migration audit recorded that platform evidence now uses
    `/api/v1/v3/platform/evidence/audit`, and later work added first account,
    project, and access evidence aliases. This task is to finish the ownership
    split deliberately instead of leaving evidence scope as ad hoc frozen audit
    continuity.

    Required outcome:

    - Confirm durable domain ownership for account, project, tenant/access, and
      platform evidence read models.
    - Move remaining V3 evidence UI calls to the correct V3 account/access/project
      route helpers.
    - Keep old `/api/v1/*/audit-logs` routes frozen as internal/demo continuity
      only, not as the product UI dependency.
    - Preserve actor, action, target, result, correlation, sanitized details, and
      pagination behavior across the aliases.

    Scope:

    - In: OpenAPI V3 read-model contract, route ownership, generated clients, and
      V3 evidence UI wiring.
    - Out: broad audit-log schema redesign.

    '
- id: B-V3-FINANCE-DIAGNOSTICS-DRAWER-001
  title: Add V3 finance diagnostics drawer for payment session ledger usage and audit pivots
  role: B-ui
  status: todo
  priority: 2
  owner: ''
  branch: agent/B-ui
  completed_at: ''
  commit: ''
  depends_on: []
  acceptance_checks:
  - pnpm --dir packages/web typecheck
  - pnpm --dir packages/web exec vitest run src/components/v3
  - sh -lc 'E2E_BASE_URL=https://gpuaas-kind-app.tailfe39f5.ts.net pnpm --dir packages/web e2e e2e/v3-admin-platform.spec.ts'
  - bash scripts/ci/agent_queue_validate.sh
  - make queue-git-check
  notes: 'Context:

    The migration audit noted that V3 finance now has reconciliation and diagnostics
    aliases, but operators still need a fuller workbench experience when inspecting
    payment sessions, ledger entries, usage rows, and audit evidence.

    Required outcome:

    - Add an operator diagnostics drawer or equivalent panel on V3 finance payment
      session rows.
    - Show payment session state, reconciliation evidence, ledger/usage pivots,
      audit/correlation links, and copyable IDs.
    - Use V3 finance diagnostics APIs only; do not link back to frozen admin billing
      paths as the primary path.
    - Keep sensitive fields redacted and avoid dumping raw provider payloads.

    Scope:

    - In: V3 finance page UI and focused tests.
    - Out: new billing reconciliation backend behavior unless missing fields block
      the drawer, in which case create a separate A-backend contract task.

    '
- id: B-V3-WORKLOAD-ACCESS-GRANTS-WORKFLOW-001
  title: Complete V3 workload access grant and SSH key management workflow
  role: B-ui
  status: todo
  priority: 1
  owner: ''
  branch: agent/B-ui
  completed_at: ''
  commit: ''
  depends_on: []
  acceptance_checks:
  - pnpm --dir packages/web typecheck
  - pnpm --dir packages/web exec vitest run src/components/v3
  - sh -lc 'E2E_BASE_URL=https://gpuaas-kind-app.tailfe39f5.ts.net pnpm --dir packages/web e2e e2e/v3-workloads.spec.ts'
  - bash scripts/ci/agent_queue_validate.sh
  - make queue-git-check
  notes: 'Context:

    The migration audit recorded allocation access grants and allocation SSH-key
    mutation as not yet a complete V3 workflow. The V3 aliases now exist and the
    workload detail lazy-loads grant data, but the product workflow still needs a
    clean operator/user experience.

    Required outcome:

    - Make the Workload detail Connect/Access surface expose a complete grant
      management flow using V3 allocation access APIs.
    - Support list, create, revoke, and SSH key update states with idempotency,
      confirmation, validation errors, and copyable evidence/correlation IDs.
    - Keep initial page render free of unnecessary access-grant fetches; load
      grant data only when the user opens the management surface.
    - Clarify permission visibility for owner, project admin, and platform admin.

    Scope:

    - In: V3 workload detail access UI and tests.
    - Out: changing allocation authz semantics unless the UI exposes a real contract
      gap.

    '
- id: B-V3-GOVERNED-PLATFORM-PROXY-ACTIONS-001
  title: Convert platform service proxy shortcuts into governed V3 workbench actions
  role: B-ui
  status: todo
  priority: 2
  owner: ''
  branch: agent/B-ui
  completed_at: ''
  commit: ''
  depends_on: []
  acceptance_checks:
  - pnpm --dir packages/web typecheck
  - sh -lc 'E2E_BASE_URL=https://gpuaas-kind-app.tailfe39f5.ts.net pnpm --dir packages/web e2e e2e/v3-admin-platform.spec.ts'
  - bash scripts/ci/agent_queue_validate.sh
  - make queue-git-check
  notes: 'Context:

    The migration audit recorded `/p/grafana`, `/p/temporal`, `/p/netdata/*`,
    `/p/swagger`, and `/p/redoc` as standalone support links rather than governed
    V3 workbench actions. V3 Ops now exposes launch shortcuts, but the model should
    be normalized.

    Required outcome:

    - Present platform proxy launches as governed Ops actions with purpose,
      permission, evidence/runbook context, and disabled reasons.
    - Keep external proxy links visible only when the user has the correct platform
      role and the endpoint is configured.
    - Add copyable proxy URLs where appropriate without using query-string tokens.
    - Preserve existing proxy paths as runtime support endpoints.

    Scope:

    - In: V3 platform Ops proxy action presentation and tests.
    - Out: replacing the proxy infrastructure.

    '
- id: B-V3-MOCK-PROD-PARITY-WORKLOADS-001
  title: Run mock-vs-production parity sweep for V3 workloads list and detail
  role: B-ui
  status: todo
  priority: 1
  owner: ''
  branch: agent/B-ui
  completed_at: ''
  commit: ''
  depends_on: []
  acceptance_checks:
  - sh -lc 'test -f tmp-ux/v3-workloads-mock-prod-parity.md || test -f doc/product/v3-workloads-mock-prod-parity.md'
  - bash scripts/ci/agent_queue_validate.sh
  - make queue-git-check
  notes: 'Context:

    The migration audit recommended a focused mock-vs-prod parity sweep before
    broad UX polish. Workloads list/detail is the highest-impact surface and has
    suspected drift around row affordance, attention severity, and detail/config
    tab regressions.

    Required outcome:

    - Compare current V3 production workloads list/detail against the adopted mock
      intent.
    - Produce concrete findings in the format: mock intent -> production state ->
      fix size -> proposed owning task.
    - Cover row click affordance, action placement, runtime icon/status display,
      filter behavior, attention band severity, Connect/access behavior, and detail
      tab usefulness.
    - Do not make code changes in this task; create implementation tasks from the
      findings.

    '
- id: B-V3-USER-SURFACE-UX-SEQUENCE-001
  title: Finish V3 user-surface UX by surface before admin and ops polish
  role: B-ui
  status: todo
  priority: 1
  owner: Codex
  branch: master
  completed_at: ''
  commit: ''
  depends_on:
  - B-V3-RUNTIME-MANAGEMENT-MUTATION-UI-001
  - B-V3-WORKLOAD-ACCESS-GRANTS-WORKFLOW-001
  acceptance_checks:
  - pnpm --dir packages/web typecheck
  - pnpm --dir packages/web exec vitest run src/components/v3
  - sh -lc 'E2E_BASE_URL=https://gpuaas-kind-app.tailfe39f5.ts.net pnpm --dir packages/web e2e e2e/v3-workloads.spec.ts e2e/v3-user-journey.spec.ts'
  - bash scripts/ci/agent_queue_validate.sh
  - make queue-git-check
  notes: 'Context:

    The V3 UX polish was going in circles because generic page patterns were being
    pushed across unlike product surfaces. Use one main surface at a time, keep the
    current visual feel, and extract shared components only after the surface has a
    coherent product model.

    Required outcome:

    - Workloads first: separate compute allocation actions from app runtime actions,
      and use runtime/app family terminology for Jupyter, vLLM, Slurm, and RKE2.
    - Launch wizards next: align the first-run flow with workload families and avoid
      compute/app terminology collisions.
    - Access next: complete grants, SSH keys, invitations, service accounts, and
      credential copy/revoke flows in the user shell.
    - Account next: finish profile, billing, keys, and audit-oriented account flows.
    - Only after those user surfaces are coherent, apply the same surface-by-surface
      model to admin and ops pages.

    Current implementation pass:

    - Workloads list row actions are being narrowed so Release/Restart are compute
      allocation controls only.
    - Workload detail app controls are being relabeled per workload family instead
      of presenting every app as generic runtime management.
    - App launch placement is being driven by `runtime_presentation`: Slurm uses
      controller/worker placement, RKE2 uses server/agent placement, and
      notebook/inference apps keep single host-placement language.
    - Access pass is active: credential/service-account/member/audit IDs and one-time
      secrets are being converted from raw overflowing text to standard copy/view
      affordances.
    - Access API-backed follow-up remains: project membership should graduate from
      raw user-id binding to user discovery/invitation once the durable endpoint is
      available; do not fake this with mock-only UI.
    - Account pass is active: profile identity subjects, security credentials,
      sessions, and billing refund identifiers are being normalized to the same
      bounded copy/view affordance used by Access.
    - Whole-system pass is active: remaining V3 detail/workbench pages are being
      swept for raw overflowing identifiers and upgraded in place before any
      broader admin/ops redesign.
    - Current whole-system slice covers storage detail mounts/grants/credential
      output, access one-time secret display and connectivity gap labeling,
      platform evidence drawer titles, and platform node command output wrapping.

    '
- id: B-V3-MOCK-PROD-PARITY-STORAGE-COMPUTE-001
  title: Run mock-vs-production parity sweep for V3 storage and compute catalog
  role: B-ui
  status: todo
  priority: 2
  owner: ''
  branch: agent/B-ui
  completed_at: ''
  commit: ''
  depends_on:
  - B-V3-MOCK-PROD-PARITY-WORKLOADS-001
  acceptance_checks:
  - sh -lc 'test -f tmp-ux/v3-storage-compute-mock-prod-parity.md || test -f doc/product/v3-storage-compute-mock-prod-parity.md'
  - bash scripts/ci/agent_queue_validate.sh
  - make queue-git-check
  notes: 'Context:

    The migration audit recommended storage list/detail second and compute catalog
    third after the workloads parity sweep. Suspected storage gaps include
    quick-action availability, action-band priority, inner-table affordances, and
    filter parity. Suspected compute gaps include shopper/discovery filters and
    catalog browsing affordances lost during V3 migration.

    Required outcome:

    - Compare current V3 production storage and compute catalog surfaces against
      the adopted mock intent.
    - Produce concrete findings in the format: mock intent -> production state ->
      fix size -> proposed owning task.
    - Cover storage quick actions, flagged/attention handling, object/detail
      affordances, compute SKU browsing, region/availability filters, BM versus
      slice clarity, and launch handoff.
    - Do not make code changes in this task; create implementation tasks from the
      findings.

    '
- id: A-V3-MAAS-PROVISIONING-FLOWS-OFF-V1-001
  title: Move V3 MAAS provisioning flows off frozen v1 APIs
  role: A-backend
  status: done
  priority: 1
  owner: Codex
  branch: agent/A-backend
  completed_at: '2026-05-08'
  commit: 921f00ec
  depends_on: []
  acceptance_checks:
  - bash scripts/ci/contracts_validate.sh
  - go test ./cmd/api
  - pnpm --dir packages/web typecheck
  - make queue-git-check
  notes: 'Completed from the local V1/V3 migration audit. MAAS site/profile/credential/probe/discovery/ROCE list and mutation calls were moved through V3 platform lifecycle aliases so V3 provisioning pages no longer depend on frozen v1/admin continuity routes for the primary flow.'
- id: A-V3-NODE-OPERATIONS-OFF-V1-001
  title: Move V3 node operation flows off frozen v1 APIs
  role: A-backend
  status: done
  priority: 1
  owner: Codex
  branch: agent/A-backend
  completed_at: '2026-05-08'
  commit: 93881351
  depends_on: []
  acceptance_checks:
  - bash scripts/ci/contracts_validate.sh
  - go test ./cmd/api
  - pnpm --dir packages/web typecheck
  - make queue-git-check
  notes: 'Completed from the local V1/V3 migration audit. Node bootstrap, reenrollment, resource slots, slice topology discovery, probe, agent lifecycle, reactivate/resume lifecycle, retire/remove/detach/force-detach now have V3 lifecycle aliases and the V3 node detail page uses the V3 API helper layer.'
- id: A-V3-PLATFORM-EVIDENCE-AUDIT-FEED-001
  title: Add V3 platform evidence audit feed
  role: A-backend
  status: done
  priority: 1
  owner: Codex
  branch: agent/A-backend
  completed_at: '2026-05-08'
  commit: d6f77a5f
  depends_on: []
  acceptance_checks:
  - bash scripts/ci/contracts_validate.sh
  - go test ./cmd/api
  - pnpm --dir packages/web typecheck
  - make queue-git-check
  notes: 'Completed from the local V1/V3 migration audit. Platform audit drawer rows were moved to `/api/v1/v3/platform/evidence/audit` as the platform-owned V3 evidence read surface.'
- id: B-V3-APP-RUNTIME-CONTROLS-OFF-V1-001
  title: Move V3 app runtime controls off frozen v1 APIs
  role: B-ui
  status: done
  priority: 1
  owner: Codex
  branch: agent/B-ui
  completed_at: '2026-05-08'
  commit: 278d715e
  depends_on: []
  acceptance_checks:
  - pnpm --dir packages/web typecheck
  - pnpm --dir packages/web test
  - make queue-git-check
  notes: 'Completed from the local V1/V3 migration audit. Project app-instance detail, members, member operations, upgrade, rollback, stop/start/restart, and decommission controls now use V3 app-instance aliases instead of frozen v1 project app-instance clients.'
- id: A-V3-SCHEDULER-SHARED-RUNTIME-READ-SURFACE-001
  title: Add V3 scheduler shared runtime read surface
  role: A-backend
  status: done
  priority: 1
  owner: Codex
  branch: agent/A-backend
  completed_at: '2026-05-08'
  commit: f4c1fae4
  depends_on: []
  acceptance_checks:
  - bash scripts/ci/contracts_validate.sh
  - go test ./cmd/api
  - pnpm --dir packages/web typecheck
  - make queue-git-check
  notes: 'Completed from the local V1/V3 migration audit. `/api/v1/v3/schedulers/shared-runtimes` now aliases shared runtime list/detail plus attachments, workers, and worker operations, and the V3 scheduler page renders tenant-shared runtime inventory from that surface.'
- id: B-V3-DEVELOPER-DOWNLOADS-API-001
  title: Move V3 developer downloads to V3 API aliases
  role: B-ui
  status: done
  priority: 2
  owner: Codex
  branch: agent/B-ui
  completed_at: '2026-05-08'
  commit: 10d1d9ee
  depends_on: []
  acceptance_checks:
  - bash scripts/ci/contracts_validate.sh
  - pnpm --dir packages/web typecheck
  - make queue-git-check
  notes: 'Completed from the local V1/V3 migration audit. V3 developer downloads now use `/api/v1/v3/developer/releases*` and `/api/v1/v3/developer/dev-ca*`; returned artifact and CA download URLs also stay under the V3 namespace.'
- id: B-V3-OPS-QUEUE-WORKBENCH-001
  title: Add V3 ops outbox and DLQ queue workbench
  role: B-ui
  status: done
  priority: 1
  owner: Codex
  branch: agent/B-ui
  completed_at: '2026-05-08'
  commit: fa4e252e
  depends_on: []
  acceptance_checks:
  - bash scripts/ci/contracts_validate.sh
  - pnpm --dir packages/web typecheck
  - make queue-git-check
  notes: 'Completed from the local V1/V3 migration audit. V3 Ops now has `/api/v1/v3/platform/ops/outbox/*` and `/api/v1/v3/platform/ops/dlq/*` aliases plus a queue operations panel for row review, payload copy, requeue, and discard.'
- id: B-V3-FINANCE-RECONCILIATION-API-001
  title: Move finance reconciliation diagnostics to V3 API
  role: B-ui
  status: done
  priority: 1
  owner: Codex
  branch: agent/B-ui
  completed_at: '2026-05-08'
  commit: b68889c2
  depends_on: []
  acceptance_checks:
  - bash scripts/ci/contracts_validate.sh
  - pnpm --dir packages/web typecheck
  - make queue-git-check
  notes: 'Completed from the local V1/V3 migration audit. Billing reconciliation list/run/detail and correlation diagnostics now have V3 finance aliases under `/api/v1/v3/platform/finance/reconciliation*` and `/api/v1/v3/platform/finance/diagnostics`, and the V3 finance reconciliation panel uses the V3 API helper.'
- id: B-V3-OPS-FLEET-TELEMETRY-WORKBENCH-001
  title: Add V3 ops fleet telemetry workbench
  role: B-ui
  status: done
  priority: 2
  owner: Codex
  branch: agent/B-ui
  completed_at: '2026-05-08'
  commit: c9e4231b
  depends_on: []
  acceptance_checks:
  - bash scripts/ci/contracts_validate.sh
  - pnpm --dir packages/web typecheck
  - make queue-git-check
  notes: 'Completed from the local V1/V3 migration audit. Fleet telemetry now has a V3 ops alias at `/api/v1/v3/platform/ops/telemetry/fleet`; `/admin/telemetry` cutover lands on `/v3-prod/platform/ops/telemetry`, and the V3 ops page has a fleet telemetry pivot.'
- id: A-V3-OPERATOR-BACKLOG-GAPS-001
  title: Close V3 operator API and UI backlog gaps from migration audit
  role: A-backend
  status: done
  priority: 1
  owner: Codex
  branch: agent/A-backend
  completed_at: '2026-05-08'
  commit: 147d45f2
  depends_on: []
  acceptance_checks:
  - ruby scripts/api/bundle_contracts.rb --write
  - make codegen
  - pnpm --dir packages/web typecheck
  - pnpm --dir packages/web test
  - go test ./...
  - go vet ./...
  - make lint
  - make queue-git-check
  notes: 'Completed from the local V1/V3 migration audit. Added V3 aliases for allocation access grants, allocation SSH keys, scheduler worker operations, and account/project/access evidence audit. Updated scheduler runtime inventory, finance diagnostics, workload access posture, platform ops proxy shortcuts, and storage copy affordances.'
- id: B-V3-ALLOCATION-GRANTS-LAZY-LOAD-001
  title: Lazy-load V3 allocation access grants on workload detail
  role: B-ui
  status: done
  priority: 1
  owner: Codex
  branch: agent/B-ui
  completed_at: '2026-05-08'
  commit: eca937da
  depends_on:
  - A-V3-OPERATOR-BACKLOG-GAPS-001
  acceptance_checks:
  - pnpm --dir packages/web typecheck
  - sh -lc 'E2E_BASE_URL=https://gpuaas-kind-app.tailfe39f5.ts.net pnpm --dir packages/web e2e e2e/v3-workloads.spec.ts --workers=1'
  - make queue-git-check
  notes: 'Completed after kind live e2e exposed unmocked access-grant fetches on initial workload detail render. The access grant panel now fetches only after the user opens the management surface.'
- id: A-V3-DEVELOPER-ROUTE-OWNERSHIP-GUARD-FIX-001
  title: Move V3 developer handlers into the V3 route module
  role: A-backend
  status: done
  priority: 1
  owner: Codex
  branch: agent/A-backend
  completed_at: '2026-05-08'
  commit: 93047ff7
  depends_on:
  - B-V3-DEVELOPER-DOWNLOADS-API-001
  acceptance_checks:
  - bash scripts/ci/contracts_validate.sh
  - go test ./cmd/api
  - go vet ./cmd/api
  - make queue-git-check
  notes: 'Completed after source CI caught the route-structure guard. V3 developer release/dev-CA handlers were moved out of `cmd/api/routes.go` into the V3 read-model route module while preserving the shared v1 helper behavior. This commit passed source CI, kind deploy, and platform-control deploy/remote validation.'
