feat(ticket): expose case tags and independent assignment handling
This commit is contained in:
@@ -81,7 +81,7 @@ Runtime accepts exactly one Flow segment only when the resolved Profile enables
|
||||
|
||||
The generic model-facing `WorkerSpawn` accepts `initial_submit: Vec<Segment>` and routes them unchanged through the shared Workspace spawn request into Runtime `CreateWorkerRequest.initial_input`. It does not have a parallel `initial_text` or a role-specific `SpawnCoder` wrapper. Backend derives the flat content projection from the canonical segment vector, validates Flow shape before spawn, and includes the segment vector in lifecycle idempotency fingerprints. Runtime does not commit Worker creation or report spawn success merely because the initial Submit request entered the Worker's in-memory channel: Runtime assigns the Submit an opaque id, the Worker commits that id as an extension on the same `UserInput` entry as any initial `FlowRuntimeState`, and the execution backend must return a matching typed input-commit acknowledgement. Restoring the same Worker never replays spawn initial segments.
|
||||
|
||||
When an Orchestrator supplies `ticket_id` to generic `WorkerSpawn`, the Worker tool derives the assignment operation id from the durable tool-call id rather than accepting lifecycle authority from model input. The shared Workspace worker-create route projects that request into a Coder Ticket-role intent and atomically applies the existing queued-Ticket assignment operation only after Runtime has returned the input-commit acknowledgement. A spawn or pre-commit input failure therefore leaves the Ticket queued and unassigned.
|
||||
When an Orchestrator supplies `ticket_id` to generic `WorkerSpawn`, it must also supply its observed current `orchestrator_assignment_id`. The tool derives the start operation identity from durable tool-call context, not model role text. The shared guarded Worker-create path accepts the selected Profile/optional Flow and binds Worker assignment plus resource finalization only after Runtime initial-input commit acknowledgement. Assign is delegation without ready/Queue; unresolved dependencies are diagnostics, not a blanket start gate. Backend fences the exact current delegation and authenticated source across reserve/bind/finalize/recovery. A failed or unknown external outcome must be reconciled from durable operation evidence rather than silently creating a replacement. Start does not update Ticket open/closed or Orchestrator self-reported waiting/inprogress/done. See [delivery/start fences](../development/ticket-assignment-delivery.md).
|
||||
|
||||
`RequestFlowTransition` accepts only:
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ Typical role surfaces are therefore:
|
||||
- Reviewer: item `read` and `review`.
|
||||
- Orchestrator: item `read`, `check_readiness`, and `complete`.
|
||||
|
||||
`CompleteTicket` belongs to the Ticket Feature and route-bound Ticket item `complete`, alongside state and close decisions. It takes current item/state CAS, a replay key, reason, and optional references; it requires neither an MR result set nor a Reviewer approval. The former MR collection `complete_ticket` operation is not published. The review descriptor never contains the injected capability token, and a review item route must exactly match the Merge Request captured by that capability before the ordinary review Tool can run.
|
||||
`TicketCaseUpdate` belongs to the Ticket Feature and route-bound Ticket item `case_update`, not this MR provider. Close/reopen/correction judgments take current item/state/nullable closure-key CAS, an exact-retry key, typed reason/explanation and optional references; generic closure requires neither an MR result set nor Reviewer approval. Assignment handling done is an independent self-report and does not close the case, integrate an MR, release actual work or stop a Worker. Explicit user approval conditions remain judgment requirements; MR integration still uses its guarded review path. Historical `CompleteTicket` and former MR collection `complete_ticket` operations are not published. The review descriptor never contains the injected capability token, and a review item route must exactly match the Merge Request captured by that capability before the ordinary review Tool can run.
|
||||
|
||||
## Preserved review and integration gates
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
# Orchestrator worktree and implementation worktree layout
|
||||
|
||||
> Historical layout decision and branch report. The Queue/state and mandatory merge→close→cleanup policy below is superseded by [current work operations](../development/work-items.md). Current delegation starts at Assign without ready/Queue; open/closed case judgments, self-reported assignment handling, guarded MR integration, actual work release and Worker/resource cleanup are independent. Respect the requested return path. The original report is preserved below; explicit attached Workdirs and Backend resource authority, not inferred roots, govern current execution.
|
||||
|
||||
Yoi can run an Orchestrator from a dedicated orchestration worktree while implementation worktrees still belong under the original workspace root. The runtime must therefore distinguish role execution cwd/workspace from the target repository root used for implementation branches and merge-completion.
|
||||
|
||||
This decision records the layout policy for Ticket `00001KTTB479X`.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Ticket evidence and immutable Merge Request results
|
||||
|
||||
Ticket lifecycle, repository integration, and current requirement attestation are separate facts. An incomplete read-side evidence summary does **not** undo a recorded `done` state or a `CompleteTicket` event.
|
||||
Ticket open/closed case state, assignment self-reported waiting/inprogress/done, Worker lifecycle, repository integration, and current requirement attestation are separate facts. An incomplete read-side evidence summary does **not** undo a recorded case judgment or handling result. Historical `done` states and `CompleteTicket` events remain readable as history, not current case states or operations.
|
||||
|
||||
## Evidence subjects
|
||||
|
||||
@@ -16,9 +16,9 @@ A merged MR's review status/timestamps describe **integration approval**, not a
|
||||
|
||||
`approved_current_subject` describes valid source/integration approvals. `review_after_rescope` retains its wire name but now describes exact current requirement attestation, not ordering of wall-clock timestamps. `approved_review` query filtering requires that current attestation. `stale_after_rescope` requires substantive item-edit history and a known source-approved snapshot lacking current attestation; unknown observations are only `missing_evidence`.
|
||||
|
||||
`complete_for_integration` means a nonempty linked MR set has valid source approvals and current requirement evidence, including for partially or fully integrated sets. It is not a claim that open repositories have been integrated, that target integration readiness has been checked, or that Ticket completion is authorized. An MRless Ticket has no applicable MR evidence: `missing` is empty, `review_status` is null, and approval/integration flags remain false. It does not match `missing_evidence` or `approved_review` merely because its state is done.
|
||||
`complete_for_integration` means a nonempty linked MR set has valid source approvals and current requirement evidence, including for partially or fully integrated sets. It is not a claim that open repositories have been integrated, that target integration readiness has been checked, or that Ticket completion is authorized. An MRless Ticket has no applicable MR evidence: `missing` is empty, `review_status` is null, and approval/integration flags remain false. It does not match `missing_evidence` or `approved_review` merely because the case is closed or handling is done.
|
||||
|
||||
CompleteTicket belongs to the Ticket domain. It records the authenticated actor's reason/result and optional references using current item `content_digest`/state CAS and an operation receipt. It needs no MR or Reviewer approval, and does not create or modify those proofs. State setting, completion, close, and reopen share the same transactional update boundary. Exact replay returns current Ticket authority without reapplying a historical decision or appending an event. Historical MR-based `ticket_completion` records remain readable and distinct from new judgment receipts.
|
||||
`TicketCaseUpdate` records the authenticated actor's close/reopen/correction judgment, typed reason, explanation and optional references using current item `content_digest`, open/closed state and explicitly observed nullable closure operation key CAS, plus an exact-replay operation key. It needs no MR or Reviewer approval and creates neither proof. Explicit user approval conditions still govern judgment; guarded MR integration still requires trusted review. Exact replay never reapplies a historical decision or appends another event; reread current authority before a new operation. Historical `CompleteTicket` and MR-based `ticket_completion` records remain readable and distinct from current case receipts. Handling done is an independent self-report, not closure, Backend certification of fulfillment, MR approval/integration, work release or Worker termination. Classification tag edits do not alter a case judgment.
|
||||
|
||||
Writable targets authorize deliverables, not mandatory MRs for every target. Every linked MR remains part of the exact requirement snapshot; no arbitrary latest-review or single-repository shortcut is used.
|
||||
|
||||
|
||||
@@ -26,7 +26,11 @@ Collection interface `yoi.ticket/collection/v1`:
|
||||
| Native operation | Existing Tool identity | Subject identity |
|
||||
| --- | --- | --- |
|
||||
| `query` | `QueryTicket` | Collection; preserves bounded filters, limit and cursor |
|
||||
| `create` | `TicketCreate` | Collection; Backend assigns identity |
|
||||
| `create` | `TicketCreate` | Collection; Backend assigns identity to an open case |
|
||||
| `tag_list` | `WorkspaceTagList` | Workspace classification; bounded stable-ID pagination |
|
||||
| `tag_create` | `WorkspaceTagCreate` | Display name and exact-retry operation key |
|
||||
| `tag_rename` | `WorkspaceTagRename` | Stable tag ID, observed `expected_last_operation_key`, name and operation key |
|
||||
| `tag_delete` | `WorkspaceTagDelete` | Stable tag ID, observed `expected_last_operation_key` and operation key |
|
||||
|
||||
Item interface `yoi.ticket/item/v1`:
|
||||
|
||||
@@ -35,11 +39,16 @@ Item interface `yoi.ticket/item/v1`:
|
||||
| `read` | `ShowTicket` | `event_limit`, `event_cursor` |
|
||||
| `edit` | `TicketEditItem` | title/body replacement and targets edit |
|
||||
| `comment` | `TicketComment` | comment body |
|
||||
| `mark_ready` | `TicketMarkReady` | optional reason |
|
||||
| `intake_ready` | `TicketIntakeReady` | intake summary and optional reason |
|
||||
| `queue` | `TicketQueue` | none |
|
||||
| `transition` | `TicketWorkflowState` | expected/target state, reason and body |
|
||||
| `close` | `TicketClose` | resolution |
|
||||
| `case_update` | `TicketCaseUpdate` | typed close/reopen/correction action, explanation, item/state/nullable closure-key CAS and exact-retry key |
|
||||
| `assignment_tracking_query` | `TicketAssignmentTrackingQuery` | optional retained `assignment_id` |
|
||||
| `assignment_tracking_history` | `TicketAssignmentTrackingHistory` | `assignment_id`, bounded limit and event cursor |
|
||||
| `assignment_tracking_update` | `TicketAssignmentTrackingUpdate` | current `assignment_id`, observed `expected_last_event_id`, operation key and complete self-reported handling |
|
||||
| `orchestrator_assign` | `TicketOrchestratorAssign` | target principal, explicitly observed nullable `expected_assignment_id`, stable `operation_id`; explicit reissue uses a new operation, exact retry keeps the original |
|
||||
| `orchestrator_clear` | `TicketOrchestratorClear` | observed `assignment_id`, stable `operation_id` |
|
||||
| `assignments_query` | `TicketAssignmentsQuery` | bounded limit and `after_assignment_id` cursor for retained rows |
|
||||
| `assignment_diagnostics` | `TicketAssignmentDiagnostics` | `assignment_id`, bounded limit, independent `after_input_event_id` / `after_start_operation_id` cursors |
|
||||
| `assignment_answer` | `TicketAssignmentAnswer` | observed same `assignment_id` / `expected_last_event_id`, stable `operation_key`, bounded answer body |
|
||||
| `tags_set` | `TicketTagsSet` | stable desired `tag_ids`, observed full `expected_tag_ids` set and operation key |
|
||||
| `dependency_check` | `TicketDependencyCheck` | none |
|
||||
| `record_relation` | `TicketRelationRecord` | relation kind, **target Ticket**, optional note |
|
||||
| `remove_relation` | `TicketRelationRemove` | relation kind and **target Ticket** |
|
||||
@@ -50,11 +59,12 @@ The subject `ticket`/`id` parameter is removed from every item descriptor and re
|
||||
|
||||
Access profiles therefore expose different native interfaces:
|
||||
|
||||
- read-only/review: collection `query`; item `read`;
|
||||
- workspace authoring: query/create plus read/edit/comment/ready/queue/close/relation operations;
|
||||
- intake: the authoring surface plus `intake_ready`;
|
||||
- workflow/orchestration: query/read/comment, workflow transition/close/dependency checks, relation operations and orchestration-plan operations;
|
||||
- work-report: query/read/comment only.
|
||||
- read-only/review: collection query/tag list; item read, assignment tracking query/history, retained assignments and sanitized diagnostics;
|
||||
- workspace authoring/intake: query/create, read/edit/comment/case judgment, relation/classification operations, tracking reads, explicit Orchestrator Assign/reissue/clear and continuing answer;
|
||||
- workflow/orchestration: query/read/comment/case judgment, dependency diagnostics, relation/plan/classification operations, tracking reads/self-report update, explicit Assign/reissue/clear and continuing answer;
|
||||
- work-report: query/read/comment/case judgment/classification, assignment reads/diagnostics and continuing answer. Actual exposure is additive from manifest flags; authoring-enabled Coder configurations also expose delegation, subject to Backend authorization.
|
||||
|
||||
There are no current native ready/intake-ready/queue/six-state transition operations. Assign is delegation without a separate Queue; Worker starts are separately guarded and require the current observed `orchestrator_assignment_id` for Orchestrator calls. Assignment public operations call shared typed `WorkspaceClient::execute_server_operation` forwarding with actual Server DTOs; no direct HTTP/storage fallback or second ledger is introduced. Role assignment tools target Orchestrator responsibility only, not Worker execution/lifecycle; target principal is never the actor. Query first, preserve exact operation/input on retry, and reread after conflict/unknown outcome rather than automatically rekeying. Missing host support is a concrete authority error, never an alternate transport.
|
||||
|
||||
No native operation is inferred for a Tool that the Feature did not register. Enabled Ticket tools claimed by the native projection are removed from `/tools`; normal Tool mode is unchanged.
|
||||
|
||||
@@ -64,7 +74,7 @@ No native operation is inferred for a Tool that the Feature did not register. En
|
||||
|
||||
Backend 401/403 failures map to permission denial, 404 to missing objects, and deterministic 400/409/422 validation or workflow failures to invalid arguments when the typed operation fails before any successful mutation. Cancellation and interruption remain distinct. Post-mutation canonical-reference lookups are explicitly marked as unknown-outcome stages, so even a later deterministic HTTP status cannot misreport an already-committed write as a rejection. Transport, server, malformed response, and other post-dispatch failures retain unknown outcome, and mutating operations are not retried automatically.
|
||||
|
||||
Successful reads observe the authoritative item `content_digest`. Successful mutations advance a local observation generation even when the first call uses an internal ID whose canonical alias has not yet been learned. Once a read or mutation reveals the canonical key, the canonical/internal alias groups are merged and invalidated together. Relation mutations also invalidate the reported target Ticket, while queue results invalidate every reported queued Ticket, because those objects' incoming relations or workflow states changed. A stale validator is rejected by the common WIP Host before another Backend dispatch; the caller must rediscover/reinspect and explicitly decide whether to call again.
|
||||
Successful reads observe the authoritative item `content_digest`. Successful mutations advance a local observation generation even when the first call uses an internal ID whose canonical alias has not yet been learned. Once a read or mutation reveals the canonical key, the canonical/internal alias groups are merged and invalidated together. Relation mutations also invalidate the reported target Ticket because its inverse relation view changed. A stale validator is rejected by the common WIP Host before another Backend dispatch; the caller must rediscover/reinspect and explicitly decide whether to call again.
|
||||
|
||||
## Preserved Ticket contracts
|
||||
|
||||
@@ -72,11 +82,12 @@ The projection invokes the existing Tool and scoped Backend routes, so the follo
|
||||
|
||||
- item content digest and audited item/thread/state events;
|
||||
- title/body/targets input validation;
|
||||
- planning-to-ready target validation and write-target requirement;
|
||||
- queue dependency traversal, planning-dependency rejection and cycle detection;
|
||||
- expected-state workflow transitions and close semantics;
|
||||
- open/closed case judgments with item/state/closure-key CAS, typed reason and immutable close/correction/reopen history;
|
||||
- stable classification tag IDs, tag operation CAS, full tag-set comparison and exact-retry receipts;
|
||||
- immutable assignment identity and self-reported waiting/inprogress/done, observed event CAS and complete-payload exact replay;
|
||||
- dependencies as diagnostics rather than ready/Queue or blanket launch gates;
|
||||
- canonical `T-*`/internal-ID resolution and Workspace isolation;
|
||||
- exact forward relation ownership, inverse views and relation target validation;
|
||||
- orchestration-plan validation and bounded query behavior.
|
||||
|
||||
The ordinary JSON Schema is retained as a second validation boundary behind the WIP descriptor. Optional fields omitted by the caller stay omitted, while an explicitly supplied `null` stays present as JSON `null`, so permission matching sees the same input shape as normal Tool mode. Defaults are applied only by the same ordinary typed Tool that applies them in Tool mode.
|
||||
The ordinary JSON Schema is retained as a second validation boundary behind the WIP descriptor. Handling is never inferred from delivery, Worker or MR state. Waiting answers continue the same assignment; explicit done reissue creates a new row and preserves the prior result. Done does not close the case, release work, stop a Worker or require unassignment. Generic reasoned closure has no universal MR/human-approval gate; explicit user conditions and guarded MR integration remain separate. Exact retry retains the same operation key and full input; a receipt is not a fresh observation. On stale/current-assignment or CAS conflicts reread and reconcile; unknown outcomes must not be silently retried as a fresh operation. Optional fields omitted by the caller stay omitted, while an explicitly supplied `null` stays present as JSON `null`, so permission matching sees the same input shape as normal Tool mode. Defaults are applied only by the same ordinary typed Tool that applies them in Tool mode.
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
# Workspace Kanban to backend Orchestrator runtime
|
||||
|
||||
> Historical design, not current operating instructions. O-19 / T-739–T-743 supersede the state/Queue routing and dependency start gates below. Current Ticket cases are open/closed; Assign starts delegation and initial waiting without ready/Queue, handling is an Orchestrator self-report, and MR integration remains independently guarded. See [current work operations](../development/work-items.md), [assignment tracking](../development/ticket-assignment-tracking.md), and [delivery/start fences](../development/ticket-assignment-delivery.md). The original proposal below is preserved, not rewritten as implementation history.
|
||||
|
||||
Workspace Kanban operations are control-plane requests. They may change Ticket state and request orchestration, but they must not directly execute shell, git, filesystem work, or send authority-bearing messages to raw local Worker sockets. The durable boundary is an orchestration event consumed by a backend-internal Orchestrator Worker.
|
||||
|
||||
This document records the design boundary for connecting Kanban operations, Tickets, the Workspace backend, `WorkerRuntimeRegistry`, and filesystem-capable Workers. It is intentionally a planning artifact: it does not require the Workspace backend to implement every table, API, remote protocol, or spawn adapter immediately.
|
||||
|
||||
@@ -45,7 +45,11 @@ Unfinished dependencies remain query/relation diagnostics and do not disable man
|
||||
|
||||
Action projection permits delegation independently of existing Worker occupancy; actual Worker start eligibility still excludes unfinished Worker work and closed cases. `can_start_manual_worker` no longer includes an unresolved-dependency predicate. `can_assign_orchestrator` permits an explicit fresh Assign/reissue operation even when a current row exists; callers can supply the observed expected assignment for CAS. `can_unassign_orchestrator` uses the retained current pointer, not active-work or case-state filtering. These authoring actions are not Worker transfer. Final browser controls must use these Backend decisions rather than recreating old phase/dependency gates.
|
||||
|
||||
Delivery diagnostics are available through the typed Store scan/reservation/ack records and structured `ticket_assignment_delivery_pending` warning (`assignment_id`, `input_event_id`, `delivery_id`, recipient and error category, never content). Existing `ticket_notification_delivery_failed` remains for recipient failures. No browser acknowledgement/status-edit endpoint is introduced: successful delivery is not a user handling update. T-743 can consume the operational query independently of handling without inventing a third status in tracking.
|
||||
Delivery diagnostics are available through the typed Store scan/reservation/ack records and structured `ticket_assignment_delivery_pending` warning (`assignment_id`, `input_event_id`, `delivery_id`, recipient and error category, never content). Existing `ticket_notification_delivery_failed` remains for recipient failures. No browser acknowledgement/status-edit endpoint is introduced: successful delivery is not a user handling update. At the T-743 base `56795fb9`, `openapi/server-api.json` exposes assignment tracking and start fences but no assignment delivery query/receipt endpoint. The Store scan is an internal Rust API, not an authenticated browser/normal Tool/WIP route. Consumers must report this concrete API insufficiency for the owning Server/API handoff, not claim they can query delivery or infer it from handling/Worker state. Saved Assign plus delivery failure remains a saved delegation, never a reason to reassign. Any future diagnostics route must keep delivery, acceptance and actual start evidence separate from self-reported handling, and preserve bounded Workspace/assignment-scoped read authority.
|
||||
|
||||
## T-743 public handoff following the base API gap
|
||||
|
||||
The accepted T-743 public API adds canonical/browser `assignment-diagnostics`, `assignment-tracking/assignments` and fenced `assignment-answer` routes over the existing assignment/origin/delivery/start/receipt authority. The corresponding normal Tools/native WIP use shared typed Workspace forwarding. Diagnostics takes assignment identity and independent input/start cursors, bounds each page, and retains unknown/history distinctions; it does not expose saved rendered content or binding credentials, attest actual model processing, or mutate handling. Continuing answer atomically fences authenticated source/current assignment/observed event and saves the input/receipt, then triggers committed-input notification; it creates neither a new row nor automatic inprogress. These definitions supersede the base's unavailable public read/input surfaces, not the underlying delivery ledger or T-748 transaction ownership. See [assignment tracking](ticket-assignment-tracking.md) for ordinary Tools/WIP names and CAS/retry contracts. Combined route/generated/runtime validation is separately required; source definitions alone do not prove environment rollout.
|
||||
|
||||
## DB caller/transaction handoff for T-748 and protocol boundaries
|
||||
|
||||
|
||||
@@ -30,7 +30,9 @@ Canonical Workspace endpoints:
|
||||
- `POST` on the same path: self-report update with event CAS and exact retry key.
|
||||
- `GET .../assignment-tracking/history`: assignment-scoped handling audit, with `assignment_id`, optional `after_event_id`, and `limit` (1–100). The returned `next_event_id` continues that history.
|
||||
|
||||
Normal tools and route-bound WIP operations expose `TicketAssignmentTrackingQuery`, `TicketAssignmentTrackingHistory`, and `TicketAssignmentTrackingUpdate`. Ticket query/detail and model projections include current assignment tracking. Read access does not grant mutation authority; Backend checks every update.
|
||||
Normal tools and route-bound WIP operations expose `TicketAssignmentTrackingQuery`, `TicketAssignmentTrackingHistory`, and `TicketAssignmentTrackingUpdate`. T-743's public handoff adds `TicketAssignmentsQuery` for bounded retained Orchestrator rows (`GET .../assignment-tracking/assignments`, `after_assignment_id`, limit 1–100, `next_assignment_id`), `TicketAssignmentDiagnostics` for sanitized independent delivery/start pages (`GET .../assignment-diagnostics`, assignment ID, separate input/start cursors), and `TicketAssignmentAnswer` (`POST .../assignment-answer`). Answer uses the existing authenticated operation receipts with assignment/event CAS and bounded body; it continues waiting/inprogress on the same row and does not change handling. Done requires explicit reissue instead.
|
||||
|
||||
`TicketOrchestratorAssign` / `TicketOrchestratorClear` use the existing role-assignment routes with a target principal, observed assignment identity and stable `operation_id`; explicit nullable `expected_assignment_id` is mandatory in Assign Tool/WIP input. These tools target responsibility, not Worker execution/lifecycle, and never derive the actor from model role text. Query first; retry exact full input with the original identity, never automatically generate a fresh key on stale/unknown outcome. Typed forwarding is shared `WorkspaceClient::execute_server_operation`; it does not introduce another ledger or direct HTTP/storage fallback. Read-only/review access includes retained rows and diagnostics, not Assign/clear/answer/self-report mutation. Ticket query/detail and model projections include current assignment tracking; `QueryTicket` also exposes exact current `assigned_principal` and self-reported `handling_status` filters. Read access does not grant mutation authority; Backend checks every update.
|
||||
|
||||
Read a fresh projection before a new update. Do not treat a replayed receipt's last-event identity as the latest observed value. Retained-assignment query exposes Assign attribution and release/replacement independently; the history endpoint pages initial/migrated handling and subsequent self-reports, not delivery acknowledgements.
|
||||
|
||||
|
||||
@@ -6,7 +6,9 @@ Workspace Server control-plane records, append-only Ticket events, and any linke
|
||||
|
||||
## Concepts
|
||||
|
||||
- `Ticket`: durable work record containing intent, requirements, decisions, useful results/evidence, and resolution history.
|
||||
- `Ticket`: durable work record containing intent, requirements, decisions, useful results/evidence, and immutable closure history. Its case state is only `open` or `closed`; open is not readiness, and closed is not necessarily fulfillment.
|
||||
- `Classification tag`: Workspace-owned stable identity with a mutable display name. Multiple tags classify/filter Tickets; they never substitute for closure reasons, delegation or start authority.
|
||||
- `Orchestrator handling`: self-reported `waiting` / `inprogress` / `done` on the current assignment row, with waiting reason, progress, next action and result. These are not case states, Worker states, MR judgments or delivery status.
|
||||
- `Objective`: a first-class medium-term goal with background, strategy, success criteria, and canonical Ticket context links. It neither schedules nor authorizes Ticket work.
|
||||
- `Task`: session-local progress tracking, not the project record.
|
||||
- `Assignment`: an authorized delegation of Ticket work to a Worker, independent from its Profile or Flow.
|
||||
@@ -25,13 +27,17 @@ The Server resolves Workspace access, active configuration, and immutable Profil
|
||||
|
||||
`SpawnTicketWorker` starts and atomically assigns a generic Worker with an `initial_request`. Its registered `profile` is optional (omitted/null selects `builtin:ticket-worker`); `flow` and alias-keyed `workdir_attachments` are optional. No repository or Flow is required for non-code work. Choose an explicit Profile when its tools and instructions fit the task; assignment does not depend on choosing the Coder role. Backend validates claims, derives repository attachment access from declared Ticket targets, and preserves explicit ExternalGrant ceilings. Callers cannot request capabilities through attachment selection.
|
||||
|
||||
The guarded start records acceptance only after spawn, initial input, assignment, and attachment finalization. Do not pre-write `inprogress` or mistake a state update for a launch. On a failed or unknown outcome, reread durable operation evidence before retrying or spawning a replacement. After acceptance, reread Ticket state and current Worker responsibility.
|
||||
Orchestrator Assign delegates handling and persists initial waiting with the assignment/audit/receipt; no separate ready/Queue operation is required. The stable `workspace_agent:workspace-orchestrator` principal is distinct from the concrete registered Worker. Answers during waiting/ongoing work continue the same assignment; status is explicitly self-reported, never automatically set on delivery or acceptance. An explicit reissue after done creates a new assignment row even for the same principal, preserving prior result/release/replacement history. Reopen and Worker exchange alone create neither a fresh delegation nor execution rights. See [assignment tracking](ticket-assignment-tracking.md) and [delivery/start fences](ticket-assignment-delivery.md).
|
||||
|
||||
The guarded start records acceptance only after spawn, initial input, assignment, and attachment finalization. Current Orchestrator starts (including generic Worker spawn and existing-Worker assignment) must carry the observed `orchestrator_assignment_id`. Do not pre-write handling `inprogress` or mistake a case/status update for a launch. On a failed or unknown outcome, reread durable operation evidence before retrying the same operation; never silently spawn a replacement. After acceptance, reread current Worker responsibility and authoritative unfinished work, not merely `current_worker`. Unfinished dependencies are diagnostics for partial work/waiting, not a blanket start refusal, and are not implicitly started; actual authentication, case closure, resource/claim and recovery guards still apply.
|
||||
|
||||
Results can be returned in conversation, optionally recorded in a `TicketComment`, optionally published as a Drive document/artifact when that surface is available, or written/published to an authorized repository. Neither comments nor Drive artifacts are universally required. Preserve concise evidence useful to the user without fabricating work, tests, or conclusions. `implementation_report` is optional historical/audit context, not integration readiness or completion authority.
|
||||
|
||||
The return choice is independent of result format. Examples:
|
||||
|
||||
- Research with review not required: answer the question and optionally record a useful summary; no MR or approval is required for an authorized completion decision.
|
||||
- Research returned to the human: record handling done with a bounded result; leave the case open when no closure was requested. No MR or universal approval is required.
|
||||
- Explicit user confirmation before continuing: record waiting with the specific reason and next action. An answer continues the same assignment; receipt alone is not an inprogress self-report.
|
||||
- Whole request fulfilled and closure requested: separately record handling and a reasoned case close with `completed`. Other closure reasons (not planned, duplicate, unknown, or custom) do not claim fulfillment.
|
||||
- Code requiring independent review before merge: use the trusted review path and guarded MR integration. A Profile, Flow transition, tool invocation, or prose approval is not the review judgment.
|
||||
- Return without conclusion: report the result/limitations and leave the Ticket unconcluded. A finished turn, an artifact, or an approved MR does not itself decide completion.
|
||||
|
||||
@@ -41,9 +47,11 @@ These are instruction/tool contracts, not a claim that a mechanism proves real a
|
||||
|
||||
`QueryTicket` provides bounded discovery/filtering; `ShowTicket` provides authoritative item content and `content_digest`, paged thread, relations, Objectives, and any current MR context. Read the relevant Ticket before implementation, routing, review, state, or conclusion decisions. Check potential duplicates before creation or material rescope. Use `QueryObjective` and `ShowObjective` for broader context without replacing the Ticket read.
|
||||
|
||||
Useful mutation surfaces include `TicketCreate`, `TicketComment`, relation/plan tools, and authorized `TicketWorkflowState`, `CompleteTicket`, and `TicketClose` decisions. Exposure depends on the effective Profile/Feature configuration. Decision tools use current `content_digest` as `expected_content_digest`, expected state, a reason/resolution, stable operation key, and optional supporting references. Backend checks actor authority, CAS, replay, and resource boundaries. It does not enforce a universal state sequence, MR/approval gate, or natural-language satisfaction.
|
||||
Useful mutation surfaces include `TicketCreate`, `TicketComment`, classification and relation/plan tools, `TicketOrchestratorAssign` (explicit delegation or reissue), `TicketOrchestratorClear`, fenced `TicketAssignmentAnswer`, `TicketAssignmentTrackingUpdate`, and `TicketCaseUpdate`. Read current tracking first; use `TicketAssignmentsQuery` for bounded retained rows and `TicketAssignmentDiagnostics` for sanitized separate input/start evidence. `QueryTicket` supports exact current principal and self-reported handling filters. Exposure depends on the effective Profile/Feature configuration and does not grant authority. Ready, Queue, six-state transitions and `CompleteTicket`/`TicketClose` are not current Worker operations; old events remain historical evidence.
|
||||
|
||||
`CompleteTicket` records completion; `TicketClose` records closure. Neither integrates an MR or expands resource grants. Ticket progress/conclusion can occur without commits, MRs, or approvals when consistent with the request. Conversely, code's default publication/review practices must not be erased by confusing an independent Ticket decision with merge authority. Do not claim an unmerged result was integrated. Reread after conflicts and replay a recorded operation only with the same fingerprint.
|
||||
Assign/reissue uses target principal, explicitly observed nullable `expected_assignment_id`, and stable `operation_id`; clear uses the observed assignment_id and operation_id. These role operations do not start/stop Workers. Answers use the same current assignment/event CAS and stable operation_key with bounded body, never an unfenced comment to manufacture continuation. Case judgments use current `content_digest` as `expected_content_digest`, expected open/closed state, explicitly observed nullable `closure_operation_key`, typed close/reopen/correct-closure action, explanation, stable operation key and optional references. Tracking updates use immutable `assignment_id`, observed `last_event_id` as `expected_last_event_id`, stable `operation_key` and the complete handling payload. Tag rename/delete mutations use stable tag identity and observed `expected_last_operation_key`; Ticket tag-set updates compare the observed full `expected_tag_ids` set and send the complete desired `tag_ids` set, never a display name or status-only comparison. Exact retry keeps the same key and entire input; changed input under that key is rejected. Replayed receipts are not fresh observations. After conflict, reread and reconcile, never silently overwrite or retry as a new operation against another assignment. Unknown dispatch outcomes are not success or failure. Saved Assign plus failed notification is not failed delegation and must not prompt another Assign. Do not infer missing delivery/acceptance diagnostics from Worker or handling state; report the concrete unavailable endpoint.
|
||||
|
||||
`TicketCaseUpdate` records an authenticated close, reopen or correction judgment with immutable reason/actor/history. It neither integrates an MR nor expands grants nor changes handling status. Handling done and case closed do not imply one another; done does not require unassignment. Reopen alone is not reissue or old Worker revival. Generic closure can occur without commits, MRs or approvals when consistent with the request, while explicit user approval conditions must be respected. Backend checks actor authority, CAS, replay and resource boundaries, not natural-language satisfaction. Code's guarded MR integration remains separate: do not claim an unmerged result was integrated.
|
||||
|
||||
Relations remain metadata, not a scheduling mechanism: record actual project dependencies, but do not encode capacity, Worker/worktree ownership, or execution ordering as relations. Use orchestration/session records for those concerns and inspect current Backend claim rules rather than inferring launch eligibility from a relation alone.
|
||||
|
||||
@@ -80,7 +88,7 @@ Intake clarifies ambiguous intent, checks duplicates and relevant context, and r
|
||||
|
||||
A useful Ticket records background/motivation, requirements, acceptance criteria, binding decisions/invariants, implementation latitude, and relevant open questions/risks. Include useful result evidence and final resolution when appropriate. Separate confirmed facts, user claims, hypotheses, and undecided questions. Do not copy Worker role boundaries, a temporary plan, or a decision to stop after authoring into the Ticket as a product prohibition. Record an approval gate only when the user asks for it; do not prematurely prescribe implementation tactics.
|
||||
|
||||
Risk flags prompt context checks and reviewer focus, not automatic stop gates. Return to planning only for a named missing decision/information after bounded checks; escalate beyond-scope decisions without inventing new constraints.
|
||||
Risk flags prompt context checks and reviewer focus, not automatic stop gates. Record a waiting reason and next action only for a named missing decision/information after bounded checks; escalate beyond-scope decisions without inventing new constraints or moving the case to a planning state.
|
||||
|
||||
Do not create new umbrella/progress-container Tickets. Split broad work into concrete useful outcomes, record the split in Ticket/Objective context, and use Objectives for enduring medium-term goals. Do not replace umbrellas with parent/child, sub-ticket, part-of, contains, or other hierarchy relations. A concrete planning/design/investigation Ticket is valid when requested. Existing umbrellas can be retired as superseded/decomposed without rewriting history; distinguish container retirement from completion of future work.
|
||||
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
# T-743 → T-748: published domain-helper / caller handoff
|
||||
|
||||
## Source identity and composition
|
||||
|
||||
This inventory belongs to the T-743 commit carrying this file on `work/T-743-ticket-public-surfaces` (T-742 base `56795fb92cb9def9bcd701bd51d92e99526f8eff`). Its exact published SHA and MR ID are recorded in the Ticket publication handoff. It is not a copy of the unpublished T-748 adapter and is not evidence that async DB execution has been integrated or reviewed.
|
||||
|
||||
Normal-merge the validated public T-748 source into this existing work branch. Keep the MR's source/target selectors. Recheck the concrete new call graph below against the merged implementation; no placeholder executor, second connection authority, transaction split, fresh integration branch or force push is needed.
|
||||
|
||||
## Three added synchronous Store signatures
|
||||
|
||||
Declared in `crates/workspace-server/src/store.rs` on `ControlPlaneStore`, implemented by `SqliteWorkspaceStore`:
|
||||
|
||||
```rust
|
||||
fn page_ticket_assignments(
|
||||
&self,
|
||||
workspace_id: &str,
|
||||
ticket_id: &str,
|
||||
after_assignment_id: Option<&str>,
|
||||
limit: usize,
|
||||
) -> Result<ticket::TicketAssignmentsPage>;
|
||||
|
||||
fn page_ticket_assignment_diagnostics(
|
||||
&self,
|
||||
workspace_id: &str,
|
||||
ticket_id: &str,
|
||||
assignment_id: &str,
|
||||
after_input_event_id: Option<&str>,
|
||||
after_start_operation_id: Option<&str>,
|
||||
limit: usize,
|
||||
) -> Result<server_api::TicketAssignmentDiagnosticsPage>;
|
||||
|
||||
fn answer_ticket_assignment(
|
||||
&self,
|
||||
workspace_id: &str,
|
||||
ticket_id: &str,
|
||||
input: &ticket::TicketAssignmentAnswer,
|
||||
source: &TicketOrchestratorAssignmentSourceContext,
|
||||
actor: &str,
|
||||
) -> Result<ticket::TicketAssignmentAnswerReceipt>;
|
||||
```
|
||||
|
||||
Implementations forward whole calls respectively to `assignment_tracking::assignments_page`, `assignment_delivery::diagnostics_page` and `assignment_tracking::answer`.
|
||||
|
||||
The answer helper owns one IMMEDIATE transaction: `require_assignment_source` (including replay), current actionable delegation admission for a new operation, `ticket::sqlite_answer_ticket_assignment_in_transaction` (full input/source fingerprint, retained receipt replay, observed assignment/event, open-case gate, body event, audit attributes and immutable operation result), then commit. Keep this complete helper inside one accepted DB job. Do not validate/CAS on one side of an await and append/receipt on the other. The two read helpers use their existing connection/snapshot boundaries and bounded cursors; the diagnostics input and start cursors are independent.
|
||||
|
||||
## Added async HTTP callers and surrounding synchronous work
|
||||
|
||||
In `crates/workspace-server/src/server.rs`, `WorkspaceContractService`:
|
||||
|
||||
| Canonical caller | Browser forwarding caller | Whole Store operation |
|
||||
| --- | --- | --- |
|
||||
| `ticket_assignments_page` | `ticket_assignments_page_browser` | `page_ticket_assignments` |
|
||||
| `ticket_assignment_diagnostics` | `ticket_assignment_diagnostics_browser` | `page_ticket_assignment_diagnostics` |
|
||||
| `ticket_assignment_answer` | `ticket_assignment_answer_browser` | `answer_ticket_assignment` |
|
||||
|
||||
Canonical paths are `/workspaces/{workspace_id}/tickets/{ticket_id}/assignment-tracking/assignments`, `/assignment-diagnostics` and `/assignment-answer`; Browser equivalents use `/api/w/{workspace_id}/tickets/{ticket_id}/...`. Browser methods forward to canonical methods, so they must not independently repeat a mutation or transaction.
|
||||
|
||||
All three canonical methods currently call `resolve_workspace_ticket_reference` before their Store method. This uses Ticket authority/backend DB reads, so moving only the final Store method is not enough. The answer path also calls `authenticated_assignment_source`; its Runtime branch checks the registered current Workspace Orchestrator through `find_workspace_orchestrator`, while its Account branch derives actor/source exclusively from authenticated request context. Preserve source authentication and the in-transaction source fence; do not turn request target principal into source authority. Own/cloned workspace/Ticket/query/body/context/actor values must cross the common execution boundary without borrowing request frames.
|
||||
|
||||
After the answer returns committed, the current handler calls `find_workspace_orchestrator` and `dispatch_orchestrator_assignment_attention`. Account for the former's DB-backed projection lookup and the latter's Runtime/network dispatch in T-748's existing stage/lane design. Runtime/network waits must not occupy the sole DB worker. Keep commit-before-publication and durable scan/recovery semantics even if the awaiting HTTP request is cancelled or its response is lost. Do not automatically resubmit an accepted mutation with a new operation key.
|
||||
|
||||
## Query authority extension and all entry paths
|
||||
|
||||
`TicketQueryRequest` adds typed `assigned_principal`, `handling_status` and `closure_reason`. Existing `TicketAuthority::query_tickets(query: TicketQueryRequest) -> Result<TicketQueryResponse>` in `authority.rs` applies current role/principal/handling and current closed-case reason constraints in its SQL candidate query **before** limit/pagination. Query text separately searches retained closure judgments, including after correction/reopen.
|
||||
|
||||
The HTTP call graph remains `WorkspaceContractService::ticket_query` → `scoped_query_tickets` → `api.authority.query_tickets(query)`. Canonical and Browser query routing, including the pre-existing browser GET query adapter, converge on this authority. T-748 must cover the whole authority read/enrichment call, not just the added SQL fragment or only one UI route.
|
||||
|
||||
Normal Tool/WIP read/assign/release/answer calls forward typed `WorkspaceServerOperation` values from `crates/worker/src/worker.rs`, through `crates/worker-runtime/src/worker_source.rs`, to the same canonical HTTP contracts. Added variants are `TicketAssignmentSet`, `TicketAssignmentClear`, `TicketAssignmentsPage`, `TicketAssignmentDiagnostics`, and `TicketAssignmentAnswer`; `QueryTicket` uses the existing typed query transport with the added filters. The set/clear variants expose existing assignment Store authority rather than creating additional new Store helpers. Their existing T-748 execution-boundary changes must be retained when resolving merge conflicts.
|
||||
|
||||
No new Tool-specific DB adapter is needed. Frontend helpers in `ticket-operations.ts`, TicketHandling/Tags and list/Orchestrator loaders are consumers, never replacement authorities.
|
||||
|
||||
## Composition validation
|
||||
|
||||
Existing T-743 proof: full selected Rust crate suites, generated contract checks, Web/component/browser tests and real-Worker notification/processing synchronization. See `T-743-public-surface-validation.md` for commands and explicit limits.
|
||||
|
||||
After T-748 composition, add/run the narrow boundary checks for all three new HTTP operations and query paths under controlled DB lock/admission, queue/job bounds, overload response, stale/source refusal, rollback, accepted-job cancellation and exact replay. Retain cookie Origin and signed Runtime-binding denial tests, assignment source fencing, one-transaction receipt/event tests and canonical/Browser route equivalence. Root check and relevant full changed-crate tests must cover the combined tree. Then publish only the same source branch normally, verify provider SHA equals local HEAD, and request fresh independent review of that exact combined source.
|
||||
|
||||
Current publication is neither final independent approval nor target integration, Ticket/MR completion, live update or cleanup.
|
||||
@@ -0,0 +1,51 @@
|
||||
# T-743 additional assignment Tools / WIP handoff
|
||||
|
||||
This is an additive follow-up to `T-743-prompt-surfaces.md`; that prior report/history is not rewritten. Additional scope follows T-743 thread sequence 6 and the parent request. Read current typed T-743 and inspected the backend child's actual Server DTOs/routes, not just the proposed names.
|
||||
|
||||
## Implemented public surface
|
||||
|
||||
| Normal Tool | Native Ticket item operation | Contract |
|
||||
| --- | --- | --- |
|
||||
| `TicketOrchestratorAssign` | `orchestrator_assign` | Explicit delegation/reissue to target principal; required observed nullable `expected_assignment_id`, stable `operation_id` |
|
||||
| `TicketOrchestratorClear` | `orchestrator_clear` | Explicit release of observed assignment_id with stable operation_id; not Worker lifecycle |
|
||||
| `TicketAssignmentsQuery` | `assignments_query` | Bounded retained Orchestrator rows, after_assignment_id / next_assignment_id |
|
||||
| `TicketAssignmentDiagnostics` | `assignment_diagnostics` | Actual sanitized DTO with separate input/start cursors and unknown/history distinctions |
|
||||
| `TicketAssignmentAnswer` | `assignment_answer` | Same current waiting/inprogress assignment, observed event CAS, stable operation_key, bounded body |
|
||||
|
||||
Reissue is the explicit Assign operation with a new caller-chosen operation identity against the observed old assignment. Exact replay retains the original key, full principal/CAS/input; no tool automatically queries a newer row, rewrites the expected identity or generates a new operation. All descriptions require querying current authority first. Target principal is operation data, never source/actor authority; the tools fix the target role to Orchestrator responsibility, leaving real role/principal/authentication checks in Backend. No worker-start/transfer operation was invented.
|
||||
|
||||
The new endpoints are the actual typed canonical definitions for `assignment-tracking/assignments`, `assignment-diagnostics` and `assignment-answer`. `WorkspaceClient` has no dedicated role-assignment method: the shared typed `WorkspaceServerOperation` forwarding surface was extended in the Worker crate, using actual `server_api` request DTOs and the existing host-bound execution authority. No client-crate extension is needed for these operations, no direct HTTP/storage fallback is used by the tools, and no second assignment/delivery/receipt ledger was introduced.
|
||||
|
||||
`QueryTicket` now accepts the actual typed current `assigned_principal`, `handling_status`, and current closed-case `closure_reason`. Closure reason remains separate from classification tag IDs. New read-only/review surfaces contain retained query and diagnostics, never Assign/clear/answer/self-report mutation. Mutation exposure is additive from the actual manifest authoring/thread/workflow flags; availability is not Backend authorization.
|
||||
|
||||
## Changed paths in this follow-up
|
||||
|
||||
- `crates/worker/src/worker.rs`: shared typed operation forwarding and scalar encoded query transport.
|
||||
- `crates/worker/src/feature/builtin/ticket.rs`: feature inventories, query schema, native operation mappings and registration.
|
||||
- `crates/worker/src/feature/builtin/ticket/assignment_public.rs`: new Tools, schemas, input validation and typed bounded/sanitized response handling.
|
||||
- `crates/worker/src/feature/builtin/ticket/assignment_public/tests.rs`: new boundary/transport/WIP/access/profile fixtures.
|
||||
- `crates/worker/src/prompt/system.rs`: effective actual-profile research return, explicit confirmation wait, same-row answer and generic close fixtures without repository/MR prerequisites; guarded integration fixture remains separate.
|
||||
- `resources/prompts/common/tickets.md`: concrete tool names, query-first/CAS/exact replay/actor boundaries.
|
||||
- `docs/development/ticket-assignment-tracking.md`
|
||||
- `docs/development/ticket-assignment-delivery.md`
|
||||
- `docs/development/work-items.md`
|
||||
- `docs/design/ticket-wip-projection.md`
|
||||
- this new report.
|
||||
|
||||
## Validation evidence
|
||||
|
||||
Passed focused commands:
|
||||
|
||||
- `cargo test -p worker --lib feature::builtin::ticket::`: **57 passed**, including 12 new public assignment/filter tests. These exercise required observed null/CAS, unknown model authority fields, same-input replay forwarding, read/diagnostic cursor encoding and bounds, answer body/identity validation, stale/permission/unknown outcome non-retry, diagnostic content/credential stripping, ordinary/WIP equivalence and route binding, read-only exclusions, and actual resolved builtin manifest access.
|
||||
- `cargo test -p worker --lib prompt::system::tests::effective_`: **5 passed**, including the actual resolved-profile no-repo/no-MR research→waiting+answer→reasoned-close fixture and the independent guarded MR-review fixture.
|
||||
- `cargo test -p worker --lib feature::builtin::orchestration::`: **7 passed**.
|
||||
- `cargo test -p worker --lib feature::builtin::manage_worker::tests::worker_lifecycle_spawn_serializes_ticket_assignment_without_workdirs_or_flow`: **1 passed**. The prior concurrent macro blocker no longer prevented this test.
|
||||
- `cargo test -p worker --test feature_invocation_test`: **13 passed**.
|
||||
- Root `cargo check`: passed at the observed combined snapshot, including Runtime, TUI and Server compile closure.
|
||||
- Direct delegated-file `rustfmt --check`, `git diff --check HEAD`, and naming check: passed (`558 matching lines; 0 unapproved; 0 stale exceptions`).
|
||||
|
||||
Root `cargo fmt --all -- --check` was **not clean** at the latest observation: non-delegated concurrent edits still needed formatting in `crates/worker-runtime/src/worker_source.rs` and `crates/workspace-server/src/authority.rs`. No outside-scope formatting write was performed. Parent owns the final combined formatting/validation pass.
|
||||
|
||||
## Limits and return
|
||||
|
||||
Transport/schema fixtures use a recording host-bound Workspace adapter; they prove concrete tool wiring, boundary input, permissions and non-retry behavior, not fresh signed Runtime→Server→DB→notification end-to-end execution or model judgment. Backend child's actual persistence/source-fence tests, generated contract synchronization, UI/browser/visual validation, all-Worker/full-stack tests, final combined acceptance and environment rollout remain parent-owned/separate. New API source definitions and one successful root compile are not whole-Ticket satisfaction evidence. No T-743 completion, review request, commits, pushes, merge, Worker stop or backend ledger implementation was performed.
|
||||
@@ -0,0 +1,64 @@
|
||||
# T-743 delegated Prompt / Profile / Flow / Worker handoff
|
||||
|
||||
## Boundaries
|
||||
|
||||
Base: `56795fb92cb9def9bcd701bd51d92e99526f8eff`, branch `work/T-743-ticket-public-surfaces`. Read typed T-743, O-19 and T-739–T-742, assignment tracking/delivery docs, generated OpenAPI and the Rust testing strategy before tests. This report covers only delegated resources/docs/Worker changes, not the parent's UI/Server/API work. No backend ledger, commits, pushes, merge, review request or Ticket conclusion was performed. Existing reports and history were not rewritten. Two historical design documents received only a supersession notice above their preserved original content.
|
||||
|
||||
## Changes
|
||||
|
||||
- Remove ready/intake-ready/Queue from normal Worker Ticket catalogs and native WIP mappings, including all-capability configurations. Remove obsolete queue-response observation invalidation; preserve inverse relation invalidation. Internal trait adapters are not new public operations.
|
||||
- Align common/role/panel instructions: cases open/closed; stable classification IDs and actual tag/set CAS; assignment waiting/inprogress/done is self-report, independent of Worker/MR/delivery/acceptance/work release.
|
||||
- Answers during waiting/ongoing handling continue the same assignment; explicit done reissue creates a new row even for the same principal and preserves old results. Reopen and Worker exchange alone are not reissue. Done/close do not require unassignment.
|
||||
- Explain full-input operation identity/replay, observed assignment/event CAS, stale reread/reconciliation and unknown outcomes without automatic fresh-operation retry. Distinguish saved Assign from failed delivery. Supply observed `orchestrator_assignment_id` for Orchestrator starts, including generic spawn/existing-Worker assignment.
|
||||
- Preserve explicit user approval conditions and guarded trusted review for MR integration, without a universal MR/human approval gate on generic closure. Flow terminal handoff is not case closure, handling done, work release or Worker stop.
|
||||
- Add catalog exclusion and effective prompt/schema fixtures for research return, confirmation wait and reasoned closure. These are scripted instruction/schema checks, not model judgment or full-stack behavior tests.
|
||||
|
||||
## Delegated diff paths
|
||||
|
||||
Worker:
|
||||
- `crates/worker/src/feature/builtin/ticket.rs`
|
||||
- `crates/worker/src/feature/builtin/ticket/assignment_tracking.rs`
|
||||
- `crates/worker/src/prompt/system.rs`
|
||||
|
||||
Resources:
|
||||
- `resources/flows/coder-review.dcdl`
|
||||
- `resources/profiles/intake.dcdl`
|
||||
- `resources/profiles/orchestrator.dcdl`
|
||||
- `resources/prompts/common/tickets.md`
|
||||
- `resources/prompts/panel/orchestrator_idle_queue_notice.md`
|
||||
- `resources/prompts/role/coder.md`
|
||||
- `resources/prompts/role/intake.md`
|
||||
- `resources/prompts/role/orchestrator.md`
|
||||
- `resources/prompts/role/ticket-worker.md`
|
||||
|
||||
Current docs / historical-status notices:
|
||||
- `docs/development/work-items.md`
|
||||
- `docs/development/ticket-assignment-delivery.md`
|
||||
- `docs/design/ticket-wip-projection.md`
|
||||
- `docs/design/merge-request-wip-projection.md`
|
||||
- `docs/design/ticket-evidence.md`
|
||||
- `docs/design/flow-state-graph.md`
|
||||
- `docs/design/workspace-kanban-orchestrator-runtime.md` (notice only)
|
||||
- `docs/design/orchestrator-worktree-layout.md` (notice only)
|
||||
- this new report
|
||||
|
||||
## Focused validation evidence
|
||||
|
||||
Passed:
|
||||
- `cargo test -p worker --lib prompt::system::tests::effective_`: 5 tests (including new return/wait/close schema fixture).
|
||||
- `cargo test -p worker --lib feature::builtin::ticket::`: 45 tests, including normal/WIP retirement, case CAS, tag schemas/transport, assignment tracking and relation observation tests.
|
||||
- `cargo test -p worker --lib feature::builtin::orchestration::`: 7 tests, including observed delegation forwarding and resource/Profile boundaries.
|
||||
- `cargo test -p manifest --lib builtin_profile::tests::`: 4 tests.
|
||||
- `cargo test -p manifest --lib profile::tests::builtin_orchestrator_keeps_cleanup_tool_providers_enabled`: 1 test.
|
||||
- `cargo test -p flow --lib builtin::tests::`: 2 tests; built-in recipe compiles and keeps current selector review contracts.
|
||||
- Root `cargo check`, `cargo fmt --all -- --check`, `git diff --check HEAD`, and naming check (`558 matching lines; 0 unapproved; 0 stale exceptions`) passed at an earlier snapshot before subsequent concurrent Server/API edits. Worker files were formatted again after the final fixture addition; diff check also passed afterward.
|
||||
|
||||
One subsequent Worker spawn-contract invocation was blocked before test execution by a concurrent parent-owned API edit: `crates/server-api/src/lib.rs:3208` (`ticket_assignments_page`) used `#[context] context: ServerRequestContext`; the API macro requires `#[path]`, `#[query]`, `#[header]`, `#[body]`, `#[binary]` or `#[extension]` and rejected it. Command: `cargo test -p worker --lib feature::builtin::manage_worker::tests::worker_lifecycle_spawn_serializes_ticket_assignment_without_workdirs_or_flow`. No test result or final combined-tree compile success is claimed for that invocation. Parent must revalidate its current API/combined tree.
|
||||
|
||||
## Concrete API / runtime limits
|
||||
|
||||
At base `56795fb9`, generated `openapi/server-api.json` has assignment tracking/history and start fences but no assignment-delivery query/receipt HTTP endpoint. `list_pending_ticket_assignment_deliveries` is an internal Store method, not a browser or normal Tool/WIP route. Normal Worker/WIP Ticket inventories also have no Orchestrator Assign/reissue/clear operation; this change removes obsolete Queue rather than fabricating a replacement operation or ledger. The parent owns any public endpoint/Tool handoff needed to satisfy the whole Ticket. Instructions explicitly require reporting unavailable typed operations and forbid inferring delivery/acceptance from status or Worker state.
|
||||
|
||||
The granted live typed Ticket tools still returned legacy six-state projections for the requested reads; those reads established requirements/history, not evidence that the running environment has adopted the repository's new API. No environment update occurred.
|
||||
|
||||
Not run/claimed: whole Worker test suite, Web/browser/visual validation, generated-contract regeneration/check, live migration, model judgment evaluation, full-stack E2E, final combined-tree root compile after concurrent API changes, or T-748 DB-boundary validation. Parent's concurrent Ticket/Server/API/Web changes are excluded from this implementation's evidence.
|
||||
@@ -0,0 +1,58 @@
|
||||
# T-743 public surfaces: combined implementation and validation
|
||||
|
||||
## Snapshot and scope
|
||||
|
||||
Work branch: `work/T-743-ticket-public-surfaces`, based on T-742's `56795fb92cb9def9bcd701bd51d92e99526f8eff`. This is implementation evidence, not an integration, approval, Ticket conclusion or live-environment update. See the delegated Prompt and Tool reports in this directory for their narrower evidence and earlier blockers; the checks below supersede their earlier compile/format limitations for the combined snapshot.
|
||||
|
||||
The existing Ticket, assignment tracking, assignment delivery and start records remain the authorities. No browser ledger, alternative assignment store or copied DB executor was added.
|
||||
|
||||
## Implemented boundaries
|
||||
|
||||
- Ticket list and detail use open/closed case state, stable classification tag IDs and an independent current responsibility/handling projection. Tags and current/historical closure reasons remain distinct. List filtering for tag IDs, principal, case and current close reason is server-side and preserves cursors; ordinary text search can match retained closure reasons after correction/reopen.
|
||||
- The Orchestrator page reads current assignments with waiting/inprogress/done, reasons, progress, next action and results. Worker liveness, MR evidence, delivery and acceptance do not manufacture a handling status.
|
||||
- Detail supports classification catalog create/list/rename/delete, multiple membership changes, reasoned close/correction/reopen, Assign, observed replacement/reissue, release, retained assignment/result/release history and explicit assignment-fenced answers. Responsibility principal choice uses the real typed user/Worker/Workspace-agent request, not caller authentication data. Backend still validates identities and actual authority.
|
||||
- A saved Assign is not reported as successful delivery or execution. Unknown/stale/permission/unavailable outcomes are distinct. Exact operation snapshots preserve the original key, observed assignment/event or tag set and body; no automatic new delegation is substituted after a lost response.
|
||||
- Pending child operations and observations reset on the Workspace **and** Ticket key, including Workspace changes that retain the same Ticket ID.
|
||||
- Normal Tools/WIP and effective Prompt/Profile/Flow descriptions use Assign as delegation, no ready/Queue prerequisite, same-row continuation answers, explicit new-row reissue and separate case judgment. Retained responsibility and Done are not Worker activity, merge or third-party approval. Historical reports were not rewritten; superseded design descriptions have explicit notices.
|
||||
|
||||
### Canonical API contacts
|
||||
|
||||
Canonical `/workspaces/{workspace_id}/tickets/{ticket_id}` and `/api/w/{workspace_id}/tickets/{ticket_id}` routes expose:
|
||||
|
||||
- GET `assignment-tracking/assignments`: bounded retained rows with assignment-identity pagination.
|
||||
- GET `assignment-diagnostics`: sanitized existing input/delivery/ack/start records, independent input/start cursors, unknown origin/acceptance/actual-processing distinctions; no rendered notification content or binding credentials.
|
||||
- POST `assignment-answer`: authenticated source, observed assignment and handling-event CAS, stable operation-key receipt, body event and audit under one IMMEDIATE transaction. Publication occurs only after the helper returns with its transaction committed. Exact replay retains the receipt; generic history comments do not become unfenced continuing input.
|
||||
- Shared Ticket query principal/handling/current-closure-reason filtering is applied in SQL before paging.
|
||||
|
||||
## Validation
|
||||
|
||||
Passed on the combined working snapshot:
|
||||
|
||||
- Root `cargo check` (normal TUI/Server compile closure).
|
||||
- `cargo test --no-fail-fast -p ticket -p worker-runtime -p worker -p yoi-workspace-server -p server-api`: all selected crate targets passed. Library counts: server-api 98; ticket 99; worker 994; worker-runtime 417; workspace-server 946 with one existing ignored test. Included integration/binary targets also passed. Log: `target/t743-changed-crates-final.log`.
|
||||
- Focused real-Worker delivery fixture now synchronizes on a canonical `RunCompleted` **after** the latest notification plus final Idle, not the initial Idle window, a fixed sleep or acceptance alone. The original pre-processing Idle failure was reproduced and the focused test plus full Server suite passed after the fix.
|
||||
- Focused manifest builtin-profile (4) and builtin Flow (2) tests passed. Effective research-return, confirmation-wait/same-assignment-answer and separate reasoned-close fixtures are included in the Worker suite.
|
||||
- Web `deno task test`: **613 passed**. Web `deno task test:component`: **318 passed**. Web check: **0 errors, 0 warnings**. Static production build passed (existing chunk-size advisory remains).
|
||||
- `ticket_shell_test.ts` plus `ticket_principal_test.ts`: **7 Chromium browser tests passed**. These exercise repository-free creation, server-filter pagination, known/custom close reasons, same-row answer, new-row reissue, retained results/releases, separate close/reopen, stable tag management, ambiguous saved Assign/exact retry, stale and permission denial, and the case/handling/Worker/MR/empty/error matrix in both themes. The native principal-selector test captures the selected target/observed row and waits on the second actual failed request for retry synchronization. Logs: `target/t743-browser-final.log`.
|
||||
- All six server-api TypeScript generators' `--check` commands passed (ticket, repository, runtime, workdir, Worker launch and companion); generated contract provenance is synchronized with OpenAPI.
|
||||
- `cargo fmt --all -- --check`, `git diff --check HEAD` and `env -u LD_LIBRARY_PATH deno run --allow-read --allow-run=git tools/check-state-contract-names.ts` passed; naming check: **558 matching lines, 0 unapproved, 0 stale exceptions**.
|
||||
|
||||
Earlier validation found and corrected the obsolete TUI queued-notice expectation, two delivery tests expecting ordinary comments to generate new continuing input, and a Home fixture missing the canonical assignment-tracking array. One run also exposed an unchanged Runtime cleanup test's differing walker counts. Its focused invocation and subsequent complete selected-crate run passed; no cleanup implementation fix or claim that this intermittent issue has been eliminated is made.
|
||||
|
||||
## Visual evidence
|
||||
|
||||
Baseline captures: `target/web-ux/t743-baseline-light` and `t743-baseline-dark`. Detail after captures: `t743-after-light` and `t743-after-dark`; actual contact-sheet slices were viewed, not merely generated. Conditions include member/non-owner fixture, Backend action-ineligible controls, 1440/768/390px, light/dark, open+done, open+waiting/stopped Worker, inprogress/running Worker/MR, closed/history, empty, long content and deliberate errors.
|
||||
|
||||
The deliberate query-error route retains its expected HTTP 503/document errors, so the full scenario's exit 2 is not presented as a clean no-error capture. Fixture "anonymous" transport is a synthetic member scenario, not proof of live anonymous authorization.
|
||||
|
||||
Principal-selector captures: `t743-principals-light`/`dark` before a styling correction and `t743-principals-final-light`/`dark` after it. Each final bundle has nine captures (agent/account/Worker choices at all three widths), with no capture errors. The first inspection found cramped native fieldset controls. The fix reuses shared Ticket form styling and removes the redundant fieldset border; final light/dark contact sheets were viewed. Controls, labels and focus remain readable without page overflow.
|
||||
|
||||
List/Orchestrator final evidence: `t743-list-final-reviewed-light` and `t743-list-final-reviewed-dark`, 33 captures each. Parent recovered the child's committed check/build and eight summary-model tests, inspected its final capture metadata (only the intentional query-error route had errors), and viewed actual list/Orchestrator screenshots at desktop/narrow/mobile. The refinements remove repeated offline/count prose, preserve the first mobile case in view and fold close-reason controls separately from classification. Parent verified current diff and browser tests, released the delegated file authority and owns the published handoff. This is observed tool/image evidence, not an invented child review verdict.
|
||||
|
||||
## Explicit remaining work and limits
|
||||
|
||||
T-748's DB execution facade is **not** copied or integrated. Its latest notified candidate is local-only and its full Server suite has unresolved failures. When T-748 publishes a validated source, normal-merge it, place each new whole synchronous domain helper/authority query into the common bounded DB execution boundary, keep the answer transaction intact, and leave Runtime/network waiting off the DB worker. Recheck cancellation/overload and commit-before-publication at the combined boundary. The exact combined published source then needs independent trusted review.
|
||||
|
||||
Current evidence does not attest actual model judgment quality. Prompt/Tool fixtures are scripted inclusion/schema/transport tests; Chromium uses a loopback API fixture. The real-Worker Server fixture uses a scripted model with actual Controller/session/Runtime acceptance and canonical processing synchronization. None is a live migration/rollout, proof of actual processing for every production delivery, or completion of T-744's full real-path validation.
|
||||
|
||||
No target integration, Ticket conclusion, live process update or branch/Workdir cleanup was performed.
|
||||
Reference in New Issue
Block a user