Skip to content

feat(ui): add full public API management surfaces - #359

Draft
Sertaç Özercan (sozercan) wants to merge 34 commits into
mainfrom
ui-parity
Draft

Sertaç Özercan (sozercan) wants to merge 34 commits into
mainfrom
ui-parity

Conversation

@sozercan

Copy link
Copy Markdown
Member

Summary

  • expand UI schemas, hooks, mocks, and CRUD flows across providers, skills, memory, runtimes, gateways, monitors, security, tools, and identity
  • add Providers, Skills, Memory, System, substrate pool, runtime registration, and GatewayClass surfaces
  • add guarded manifest editing and full-spec task creation with scheduling, provenance, child tasks, workspace policies, and approval visibility
  • reorganize navigation, remove obsolete task surfaces, update UI documentation, and normalize lockfile package sources

Dependency

Testing

  • cd ui && bun install --frozen-lockfile
  • cd ui && bun run lint
  • cd ui && bun run test (145 files, 1018 tests)

Rebuild the ACP v2 change set linearly on the current main branch while preserving the pull request effective tree.

Signed-off-by: Sertac Ozercan <sozercan@gmail.com>
Signed-off-by: Sertac Ozercan <sozercan@gmail.com>
Rebuild the integrated OpenCode runtime change set linearly on the rewritten ACP v2 base.

Signed-off-by: Sertac Ozercan <sozercan@gmail.com>
Signed-off-by: Sertac Ozercan <sozercan@gmail.com>
Signed-off-by: Sertac Ozercan <sozercan@gmail.com>
Signed-off-by: Sertac Ozercan <sozercan@gmail.com>
Signed-off-by: Sertac Ozercan <sozercan@gmail.com>
Signed-off-by: Sertac Ozercan <sozercan@gmail.com>
Signed-off-by: Sertac Ozercan <sozercan@gmail.com>
Signed-off-by: Sertac Ozercan <sozercan@gmail.com>
Signed-off-by: Sertac Ozercan <sozercan@gmail.com>
Signed-off-by: Sertac Ozercan <sozercan@gmail.com>
Signed-off-by: Sertac Ozercan <sozercan@gmail.com>
Signed-off-by: Sertac Ozercan <sozercan@gmail.com>
Signed-off-by: Sertac Ozercan <sozercan@gmail.com>
Signed-off-by: Sertac Ozercan <sozercan@gmail.com>
Signed-off-by: Sertac Ozercan <sozercan@gmail.com>
Signed-off-by: Sertac Ozercan <sozercan@gmail.com>
Signed-off-by: Sertac Ozercan <sozercan@gmail.com>
Signed-off-by: Sertac Ozercan <sozercan@gmail.com>
Signed-off-by: Sertac Ozercan <sozercan@gmail.com>
Signed-off-by: Sertac Ozercan <sozercan@gmail.com>
Signed-off-by: Sertac Ozercan <sozercan@gmail.com>
Signed-off-by: Sertac Ozercan <sozercan@gmail.com>
* docs(harness): record the v1/v2 coexistence plan and phase-0 ADRs

Vendor the full coexistence specification (Revision 4) and record the
Phase 0 decisions: ADR 0016 selects full active coexistence over
blue/green replacement and the zero-active-state bridge, and ADR 0017
fixes the architecture and ownership contracts the implementation is
built against.

Signed-off-by: Sertac Ozercan <sozercan@gmail.com>

* feat(api): add the harness v1/v2 coexistence bridge schema and contract gates

Phase 1 of the coexistence plan:

- Add AgentExecutionControl (durable revisioned backend modes and
  ownership fences), AgentExecutionPolicy (admin-owned v1 compatibility
  policy with structural fail-closed floors), and
  AgentExecutionAdjudication (immutable, fenced operator resolution).
- Make AgentRuntime a discriminated dual-contract union: both protocol
  enum values, immutable optional contractVersion with no default,
  restored v1 bearer auth and capability fields as optional pointers,
  and discriminator CEL that rejects mixed shapes. Restore the v1
  observedAuthRefResourceVersion status surface.
- Add the immutable spec.runtime.contractVersion selector to built-in
  Agents; a missing selector is never protocol evidence and ACP
  planning, dispatch routing, and the v2 OpenCode validator now fail
  closed on anything but an explicit orka.harness.v2 classification.
- Add write-once immutable Task status surfaces: agentExecutionBinding,
  agentExecutionNoExecution, agentExecutionQuarantine, and
  agentExecutionResolutionRef, with exclusivity and cross-protocol
  freeze CEL. Restore status.harnessRuntime and the legacy
  spec.agentRuntime.workspace shape as ratcheted compatibility-read
  surfaces that new Tasks can never introduce.
- Prove the bridge on a real cluster: scripts/coexistence-bridge-crd-
  validate.sh exercises 34 live acceptance/rejection cases covering
  both-baseline round-trips, mixed-shape rejection, immutability, the
  closing-barrier status rules, and policy floors.
- Stamp samples, demo, and e2e Agent manifests with the explicit v2
  selector and mirror the new surfaces in the UI schemas.

Signed-off-by: Sertac Ozercan <sozercan@gmail.com>

* feat(store): add coexistence snapshot, lineage, v1 attempt, and ledger stores

Durable payload foundation for the coexistence release; Kubernetes
control CRDs and coordination Leases remain authoritative:

- Immutable content-addressed execution snapshots, AES-256-GCM
  encrypted at rest with task/digest-bound additional data; persistence
  fails closed until a cipher is configured, and identical persists are
  idempotent while same-key divergence is a duplicate mismatch.
- Session protocol/runtime lineage with an atomic claim: concurrent
  first use converges on exactly one lineage, cross-protocol
  continuation and recreated same-name Session or namespace UIDs fail
  with conflicts, and unclaimed pre-existing Sessions are never
  silently established.
- The durable harness v1 attempt aggregate with the full
  Prepared/Submitting/SubmittedUnknown/CancelRequested state machine,
  fenced version CAS, operation-digest idempotency, and an
  OutcomeUnknown-requires-reason rule.
- The wrapper admission ledger as its own SQLite database: idempotent
  turn admission, digest-mismatch permanent rejection, durable
  non-acceptance proof, terminal and OutcomeUnknown receipts that
  survive restart, and a durable admission-close marker that fails new
  admissions closed while pre-close turns still settle.

Signed-off-by: Sertac Ozercan <sozercan@gmail.com>

* feat(controller): freeze a write-once execution binding before ACP dispatch

Implement the coexistence plan's phase-3 binding stage for the v2 path:

- resolveAgentExecutionCandidate performs pure resolution of the frozen
  session configuration, runtime plan, namespace identity, and durable
  backend admission mode into a canonical snapshot body and a
  digest-stable prospective binding. When the AgentExecutionControl
  singleton exists its v2 backend must be effectively enabled, and the
  admitted mode revision freezes into the binding; a drain-only or
  disabled backend rejects new bindings and never falls back.
- persistAgentExecutionSnapshot idempotently stores the immutable
  encrypted snapshot before any binding write.
- persistAgentExecutionBinding is an uncached compare-if-absent CAS: a
  UID change or deletion never dispatches, an identical candidate
  replays idempotently, and a mismatched candidate is a permanent
  BindingConflict that never overwrites the original binding.
- verifyBoundExecution re-reads the Task and backend control uncached
  immediately before the first executor side effect and blocks dispatch
  on digest drift, deletion, mode closure, or control recreation.

The stage activates when --agent-execution-snapshot-key-file supplies
the AES-256 snapshot key; without it the controller logs that the
coexistence release requires the key and keeps the legacy direct-queue
path so pre-coexistence deployments are not bricked.

Signed-off-by: Sertac Ozercan <sozercan@gmail.com>

* feat(controller): claim session protocol lineage atomically with the lease

Wire the coexistence plan's session-lineage invariant into the v2 path:
ACPSessionContinuity.AcquireMutationLease now establishes or verifies the
Session's protocol/runtime lineage under the just-acquired mutation
lease, so concurrent first-use Tasks serialize on the lease and converge
on exactly one lineage. A lineage conflict (cross-protocol continuation,
a different runtime identity, or a recreated same-name Session or
namespace UID) releases the lease and fails the acquisition instead of
silently reusing opposite runtime state, and never edits the original
lineage. On this pure-v2 line a pre-existing transcript without a
lineage row is adopted as orka.harness.v2 evidence; the dual-controller
sealed-inventory classification replaces that adoption rule.

The dispatcher resolves the namespace UID uncached and threads the
built-in runtime identity and reserved profile digest into lease
acquisition; production wiring always records lineage.

Signed-off-by: Sertac Ozercan <sozercan@gmail.com>

* feat(harness): add v1/v2 coexistence bridge

Signed-off-by: Sertac Ozercan <sozercan@gmail.com>

* feat(harness): complete coexistence rollout safeguards

Signed-off-by: Sertac Ozercan <sozercan@gmail.com>

* fix(harness): harden coexistence recovery paths

Signed-off-by: Sertac Ozercan <sozercan@gmail.com>

* fix(ci): restore coexistence validation

Signed-off-by: Sertac Ozercan <sozercan@gmail.com>

* fix(ci): keep singleton helm controller

Signed-off-by: Sertac Ozercan <sozercan@gmail.com>

* fix(harness): close coexistence safety gaps

Signed-off-by: Sertac Ozercan <sozercan@gmail.com>

* fix(harness): harden coexistence closeout

Signed-off-by: Sertac Ozercan <sozercan@gmail.com>

* fix: harden harness v1 dispatch and admission

Signed-off-by: Sertac Ozercan <sozercan@gmail.com>

* fix: remove invalid admission readiness probe

Signed-off-by: Sertac Ozercan <sozercan@gmail.com>

* fix: send admission smoke requests as JSON

Signed-off-by: Sertac Ozercan <sozercan@gmail.com>

* fix: address coexistence lifecycle review gaps

Signed-off-by: Sertac Ozercan <sozercan@gmail.com>

* fix: close coexistence migration gaps

Signed-off-by: Sertac Ozercan <sozercan@gmail.com>

* fix(ci): seed execution control in substrate e2e

Signed-off-by: Sertac Ozercan <sozercan@gmail.com>

* fix(harness): tighten v1 compatibility admission

Signed-off-by: Sertac Ozercan <sozercan@gmail.com>

* fix(harness): close coexistence safety gaps

Signed-off-by: Sertac Ozercan <sozercan@gmail.com>

* fix(harness): harden coexistence upgrades

Signed-off-by: Sertac Ozercan <sozercan@gmail.com>

* fix(harness): close coexistence review gaps

Signed-off-by: Sertac Ozercan <sozercan@gmail.com>

* fix(ci): align harness secret assertion

Signed-off-by: Sertac Ozercan <sozercan@gmail.com>

* fix(harness): harden cleanup and v1 admission

Signed-off-by: Sertac Ozercan <sozercan@gmail.com>

* feat(harness): complete v1 and v2 coexistence

Signed-off-by: Sertac Ozercan <sozercan@gmail.com>

* fix(harness): allow idempotent policy retries

Signed-off-by: Sertac Ozercan <sozercan@gmail.com>

* fix(admission): allow post-DNAT API egress

Signed-off-by: Sertac Ozercan <sozercan@gmail.com>

* fix(harness): harden wrapper cleanup and recovery

Signed-off-by: Sertac Ozercan <sozercan@gmail.com>

* fix(harness): close v1 admission gaps

Signed-off-by: Sertac Ozercan <sozercan@gmail.com>

* fix(harness): unblock first-use session dispatch

Signed-off-by: Sertac Ozercan <sozercan@gmail.com>

* fix(harness): harden credential safety

Signed-off-by: Sertac Ozercan <sozercan@gmail.com>

* fix(ci): include harness helpers in manager builds

Signed-off-by: Sertac Ozercan <sozercan@gmail.com>

* fix(build): run manager package

Signed-off-by: Sertac Ozercan <sozercan@gmail.com>

* fix(harness): bound cancellation and git cleanup

Signed-off-by: Sertac Ozercan <sozercan@gmail.com>

* fix(harness): harden coexistence retirement gates

Signed-off-by: Sertac Ozercan <sozercan@gmail.com>

* fix(ci): repair coexistence jq filters

Signed-off-by: Sertac Ozercan <sozercan@gmail.com>

* fix(acp): recover incomplete session admission

Signed-off-by: Sertac Ozercan <sozercan@gmail.com>

* fix: harden coexistence admission and redaction

Signed-off-by: Sertac Ozercan <sozercan@gmail.com>

* fix(ci): enable admission for harness render

Signed-off-by: Sertac Ozercan <sozercan@gmail.com>

* fix: harden harness coexistence paths

Signed-off-by: Sertac Ozercan <sozercan@gmail.com>

* fix: address coexistence review findings

Signed-off-by: Sertac Ozercan <sozercan@gmail.com>

* feat: add isolated harness controller modes

Signed-off-by: Sertac Ozercan <sozercan@gmail.com>

* fix(ci): preserve static mode validator executable

Signed-off-by: Sertac Ozercan <sozercan@gmail.com>

* fix(ci): validate static Helm mode fixtures

Signed-off-by: Sertac Ozercan <sozercan@gmail.com>

* fix(ci): validate rendered token request RBAC

Signed-off-by: Sertac Ozercan <sozercan@gmail.com>

* fix(ci): reject wildcard token request grants

Signed-off-by: Sertac Ozercan <sozercan@gmail.com>

* refactor: simplify harness controller modes

Signed-off-by: Sertac Ozercan <sozercan@gmail.com>

* fix: harden harness v1 runtime validation

Signed-off-by: Sertac Ozercan <sozercan@gmail.com>

* fix: scope static controller maintenance reads

Signed-off-by: Sertac Ozercan <sozercan@gmail.com>

* fix: acknowledge harness v1 settlement before deletion

Signed-off-by: Sertac Ozercan <sozercan@gmail.com>

* fix: harden harness v1 isolation edge cases

Signed-off-by: Sertac Ozercan <sozercan@gmail.com>

* fix: close harness v1 recovery gaps

Signed-off-by: Sertac Ozercan <sozercan@gmail.com>

* fix(helm): reject controller watch scope changes

Signed-off-by: Sertac Ozercan <sozercan@gmail.com>

* fix(ci): create substrate namespace before secrets

Signed-off-by: Sertac Ozercan <sozercan@gmail.com>

* fix: avoid cached namespace reads

Signed-off-by: Sertac Ozercan <sozercan@gmail.com>

* fix(ci): configure substrate snapshot store

Signed-off-by: Sertac Ozercan <sozercan@gmail.com>

* fix(harness): enforce isolated mode credentials

Signed-off-by: Sertac Ozercan <sozercan@gmail.com>

* fix(harness): harden isolated controller ownership

Signed-off-by: Sertac Ozercan <sozercan@gmail.com>

* fix(ci): provide harness v1 TLS fixture

Signed-off-by: Sertac Ozercan <sozercan@gmail.com>

* fix: close isolated controller validation gaps

Signed-off-by: Sertac Ozercan <sozercan@gmail.com>

* fix(ci): colocate substrate MCP template

Signed-off-by: Sertac Ozercan <sozercan@gmail.com>

* fix: address harness isolation review findings

Signed-off-by: Sertac Ozercan <sozercan@gmail.com>

* fix: scope control store reads to watch namespace

Signed-off-by: Sertac Ozercan <sozercan@gmail.com>

* fix(harness): harden static mode isolation

Signed-off-by: Sertac Ozercan <sozercan@gmail.com>

* fix(deploy): bootstrap static namespace identity

Signed-off-by: Sertac Ozercan <sozercan@gmail.com>

* fix: address isolated mode review findings

Signed-off-by: Sertac Ozercan <sozercan@gmail.com>

* fix: harden isolated harness installation boundaries

Signed-off-by: Sertac Ozercan <sozercan@gmail.com>

* fix: align admission trust and e2e checks

Signed-off-by: Sertac Ozercan <sozercan@gmail.com>

* fix(e2e): assert admission denial output

Signed-off-by: Sertac Ozercan <sozercan@gmail.com>

* fix: harden isolated harness deployment

Signed-off-by: Sertac Ozercan <sozercan@gmail.com>

* fix: close isolated harness review gaps

Signed-off-by: Sertac Ozercan <sozercan@gmail.com>

* fix: preserve snapshot encryption identity

Signed-off-by: Sertac Ozercan <sozercan@gmail.com>

* fix: harden isolated harness mode handling

Signed-off-by: Sertac Ozercan <sozercan@gmail.com>

* fix(ui): clarify unclassified runtime state

Signed-off-by: Sertac Ozercan <sozercan@gmail.com>

* fix: complete isolated harness integrations

Signed-off-by: Sertac Ozercan <sozercan@gmail.com>

---------

Signed-off-by: Sertac Ozercan <sozercan@gmail.com>
Signed-off-by: Sertac Ozercan <sozercan@gmail.com>
Signed-off-by: Sertac Ozercan <sozercan@gmail.com>
Signed-off-by: Sertac Ozercan <sozercan@gmail.com>
- New schemas: provider, skill, memory/proposal, whoami, substrate pool,
  gateway class, monitor workflow event; task spec gains cron/priorTaskRef/
  requestedBy/transaction/clean-room workspace fields; agent spec gains
  contractVersion, fallbacks, autonomous coordination, ttlAfterLastTask
- Dedupe execution-event schema (task.ts re-exports canonical shapes)
- New hooks: providers/skills/memories/proposals/whoami CRUD+filters,
  substrate pools, agent-runtime registration, gateway classes, task
  plan/children, monitor update/events/patch-preview, security scan
  update/delete/slice detail, tool CRUD, agent update, chat cancel
- MSW default handlers + hook tests for all new surface
- Remove dead pr-create-dialog (endpoint no longer exists) and
  agent-grid-view (superseded by runtime roster)
- Providers: list/detail/create/edit/delete backed by /providers CRUD;
  base URL locked on edit to match server preserve-on-update behavior
- Skills: list/detail (served markdown content)/create/edit/delete
- Memory: governance-first page — memories browser with filters,
  enable/disable/soft-delete/edit, plus a proposal review inbox with
  accept/reject (+note), explicit apply-to-memory, and archive; 501
  renders as a store-not-enabled state
- System: /readyz checks, capability badges (chat, memory store), chat
  orchestrator limits/tools, compat endpoint connect info + model catalog
- Header: free-text namespace switcher with history + whoami default;
  identity popover showing verified caller identity and transaction
  metadata; popover primitive added
- Colocated tests for all of the above
- Runtimes: Substrate actor pools tab (list/create/edit/delete),
  external AgentRuntime registration + spec edit + remove via a shared
  YAML manifest editor; fail-closed dispatch note preserved
- Gateways: cluster GatewayClass tab (contract, category, capabilities,
  acceptance)
- New shared ManifestEditor (js-yaml) for deep specs — the kubectl-edit
  equivalent used by registration and upcoming edit flows
- Agents: creation now stamps runtime.contractVersion=orka.harness.v2
  (empty was fail-closed at dispatch — UI-created runtime agents could
  never run); provider picker offers registered Provider CRs via
  providerRef alongside direct anthropic/openai; detail gains full-spec
  YAML editing
- Monitors: spec editing, monitor event audit trail card, and
  implementation-job patch preview dialog (501/404-aware)
- Security: scan config editing + repository delete with confirm
- Tools: create from HTTP template, spec editing, delete
- Chat: New Chat cancels + deletes the previous server-side session
- ManifestEditor reworked to a guarded render-time reset (lint-clean)
…dashboard approvals

- Task create: schedule/timeZone/concurrency/suspend, env, args, webhook,
  secretRef, retryPolicy, sessionRef, AI systemPrompt/temperature/maxTokens/
  tools/skills + registered Provider refs, agent runtime overrides,
  clean-room workspace policies, and a seeded full-spec YAML mode
- Task detail: requester + transaction provenance card, cron schedule card,
  API-resolved child task table alongside the execution graph
- Dashboard: cross-task 'waiting for approval' inbox from task conditions
- Sidebar: grouped water-column navigation (Operate / Automation / Registry /
  Fabric / Platform) covering the new sections
- Docs: guides/ui.md page table refreshed; ui/README.md replaced with real
  documentation; test-perf fix (single-event fills) for the large form
Signed-off-by: Sertac Ozercan <sozercan@gmail.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 2450967676

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "Codex (@codex) review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "Codex (@codex) address that feedback".

Comment on lines +55 to +60
items.map((provider) => (
<TableRow key={provider.name}>
<TableCell>
<Link
to="/providers/$providerName"
params={{ providerName: provider.name }}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Normalize full Provider objects before rendering the list

For ordinary non-context-token authentication, ListProviders returns full Kubernetes Provider objects whose values live under metadata, spec, and status; only context-token responses use the flat shape assumed here. Consequently provider.name is undefined for normal UI users, producing unusable rows and links and also preventing the task form's Provider selector from working. Normalize both response shapes or render the full Provider shape.

Useful? React with 👍 / 👎.

Comment on lines +56 to +59
<PageHeader
eyebrow="Providers"
title={provider.metadata.name}
description={provider.status?.message}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Handle redacted Provider details for context-token callers

When the UI is authenticated with a context token, GetProvider deliberately returns a flat redacted item rather than a full Provider object. The list links context-token users to this page, but dereferencing provider.metadata.name then throws because metadata and spec are absent. Render the redacted response safely or avoid offering the full-detail route in this authentication context.

Useful? React with 👍 / 👎.

Comment thread ui/src/hooks/use-chat.ts
export function useCancelChatSession() {
const queryClient = useQueryClient()
return useMutation({
mutationFn: (sessionId: string) => api.delete<void>(`/chat/${sessionId}`),

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Pass the selected namespace when cancelling chat

When a chat was created in any selected namespace other than the server's implicit default, this DELETE resolves a different namespace because it omits the namespace query parameter. Clicking New Chat therefore commonly gets a 404/403 while the abandoned turn keeps running and consuming chat concurrency; read the namespace from useUIStore and pass it as the other session mutations do.

Useful? React with 👍 / 👎.

url: 'https://api.example.com/search',
method: 'POST',
timeout: '10s',
authSecretRef: { name: 'my-tool-credentials' },

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Remove protected authentication from the Tool starter

Submitting the New Tool dialog without manually deleting this field always fails: CreateTool calls validateToolRESTMutation, which rejects every REST request containing spec.http.authSecretRef and requires protected HTTP authentication to be configured through Kubernetes RBAC. Seed the REST editor with an allowed unauthenticated example or clearly route protected-tool creation through the Kubernetes API.

Useful? React with 👍 / 👎.

Comment on lines +35 to +36
limits: { maxResidentSessions: 10, maxConcurrentPrompts: 4 },
workspaceGovernance: { mode: 'strict-governed' },

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Seed a valid v2 AgentRuntime registration manifest

The registration starter cannot pass the AgentRuntime CRD schema: the limits object supplies only two of eleven required positive fields, while the strict-governance object omits its required boolean guarantees; the profile also omits required digest/version, adapter, policy, proxy, and resource-class fields and starts required digest/model values invalid. Because the REST handler sends this manifest to Kubernetes, the default Register action is rejected unless users already know and add the undocumented fields.

Useful? React with 👍 / 👎.

Comment on lines +560 to +562
<div className="space-y-2">
<label htmlFor="task-secret-ref" className="text-sm font-medium">Secret ref</label>
<Input id="task-secret-ref" value={secretRefName} onChange={(e) => setSecretRefName(e.target.value)} placeholder="task-credentials" />

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Hide the generic Secret ref for ACP agent Tasks

When an agent Task is selected, this common advanced field still writes top-level spec.secretRef, but built-in and external ACP runtime validation rejects credential SecretRefs, causing the newly created Task to fail instead of dispatching. Restrict this field to container/native-AI Tasks and keep agent repository credentials in the workspace credential-reference fields.

AGENTS.md reference: AGENTS.md:L87-L87

Useful? React with 👍 / 👎.

Comment on lines +289 to +292
if (schedule.trim()) {
body.schedule = schedule.trim()
if (timeZone.trim()) body.timeZone = timeZone.trim()
if (concurrencyPolicy) body.concurrencyPolicy = concurrencyPolicy

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Reject invalid schedule time zones before submission

Any non-empty text entered here is submitted as timeZone, while both scheduled-task controller paths silently ignore time.LoadLocation errors and proceed in the process/default time zone. A typo such as America/Los_Angelesx therefore creates a seemingly valid schedule that runs at the wrong time without an error; validate that the value is a real IANA zone before creating the Task.

Useful? React with 👍 / 👎.

toolCount={toolsData?.items?.length}
isLoading={isLoading}
/>
<NeedsAttention tasks={tasksData?.items ?? []} />

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Fetch all Tasks for the approval inbox

The dashboard requests only one 100-item Task page and passes that page to the new cross-task approval inbox. In namespaces with more than 100 Tasks, any WaitingForApproval=True Task beyond the first API page is silently omitted, so operators can miss work requiring intervention; drive this inbox from useTaskListAll or paginate specifically for waiting Tasks.

Useful? React with 👍 / 👎.

Comment on lines +18 to +21
// Both fields are immutable and rejected on client writes, so everything
// here is verified audit data.
export function TaskIdentityCard({ task }: { task: Task }) {
const requestedBy = task.spec.requestedBy

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Do not label Kubernetes-supplied identity as verified

These fields are server-stamped for REST-created Tasks, but Task CRDs created directly through the Kubernetes API can set arbitrary spec.requestedBy and spec.transaction values on creation because the transition rules only make them immutable afterward and no admission webhook rejects them. Presenting every stored value as verified audit data lets a Kubernetes writer spoof the identity shown here; distinguish REST-stamped provenance or enforce these fields at Kubernetes admission.

Useful? React with 👍 / 👎.

Comment on lines +15 to +18
return useQuery({
queryKey: ['skills', namespace],
queryFn: () => api.get<ListResponse<SkillListItem>>('/skills', { namespace }),
refetchInterval,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Paginate the Skill inventory

GET /skills defaults to a 100-item page and returns further pages through metadata.continue, but this hook fetches only the first page and the new list exposes no pagination control. Namespaces with more than 100 Skills therefore show an incomplete inventory and make later Skills unreachable from the management surface; follow continuation tokens as the runtime hooks do or add list pagination.

Useful? React with 👍 / 👎.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant