You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Console: put application execution runs on the normal Kanban, linked to application data #978
A job application is durable data: lead, employer/job URL, tailored artifacts, submit authorization, lifecycle outcome and history.
A run is an execution against that data: Tailor generation, Runner browser fill, a retry, review/approval continuation, or a submit attempt. One application may have many runs.
Problem
The normal Board renders generic instance_runtime_tasks. Application runs are not projected there, so the Board is empty while the Runner is actively working. A separate Applications surface became the only place to see the application queue, which makes one workflow look like two systems.
Required outcome
The normal instance Board/Kanban shows local-artifact and local-apply runs as they start, run, pause, complete, fail, or block.
Each run card shows the linked application title/company, current stage, progress/checkpoint or terminal reason, and a link to its correlated trace/activity.
The card action must be the permitted run control (e.g. review/approve/continue, retry, cancel), using the existing application action service and preserving MCP/UI parity.
The application itself stays data: show application records, artifacts, submit authorization and outcome in the existing Data surface (or a Data sub-view), not as a competing operational board.
Do not create a new separate operational Applications page; migrate/redirect its relevant operational controls into Board and retain any record display only as data.
Preserve generic Board behavior for agents without application runtimes.
Acceptance
When the Job Application Runner executes a fill, its Board immediately shows a running card linked to the BusinessAI application. On the SEEK supervisor checkpoint, the card visibly moves to awaiting-review with the directive/trace. The application record remains visible as data, and Console plus MCP expose the same state/actions.
changed the title [-]Console: unify application pipeline cards with the instance Kanban board[/-][+]Console: put application execution runs on the normal Kanban, linked to application data[/+]on Oct 8, 2026
The implementation must also document this operating model in the user-facing Console/help copy and MCP tool descriptions where relevant:
application data record → one or more Tailor/Runner execution runs → Board card + correlated activity/trace
State explicitly that Data answers what the application is, while Board answers what is executing or waiting now. This needs to be consistent across UI and MCP so users do not have to infer the model from implementation details.
Application executions are now cards on the normal Board, written the way coding (#206) and pipelines (#207A) write theirs: the domain writes a genericinstance_runtime_tasks card, and nothing on the reading side learns what an application is. So subordinate_status, instance_board over MCP, and the console all pick it up with no change on their side.
Keyed on the APPLICATION, not the run — that follows directly from the product model in the issue. One application has many runs, so tailoring, a fill and a retry collapse into one card whose attempts are the runs. Keying on the run id would have produced a new card per retry and buried the application.
Each card carries what only the domain can know:
On the card
From
The job as the lead words it ("Head of Engineering — Business AI Group")
paused and awaiting_review map to needs_human, so a run waiting on a person lands in the column that word belongs to — which is the acceptance line about the card "visibly moving to awaiting-review".
The card is written from the two choke points every transition passes through (syncApplyRun, syncTailorRun) plus each dispatch, so it appears the moment work starts and no transition can forget it.
Parity, by construction
The actions on the card come from getQueueItem — the very read the Applications surface and the typed MCP tools make — so the board cannot offer a control the service would refuse. A control taken from the card posts to that service's own route with the compare-and-set the card was rendered with: a stale card is refused, and there is one audit row per decision however it was made. Console and MCP read the same record.
The application stays data
Its record, artifacts, submit authorization and outcome remain on the existing surface. No new operational page was created, and the generic Board is untouched for agents without application runtimes (asserted by a test).
Three ledgers this had to answer
Each was a real obligation, not a formality:
RUNTIME_TASK_OWNERS — the new card type is classified cloud: it is a projection of PAGS's own run rows, so a runner reconnect sweep must never expire it.
The import graph — putting the payload type in board.ts dragged the generic board into the apply domain's deferred-import cycle. The shape now lives in a leaf (application-card-payload.ts, which imports nothing), shared by writer and reader; only the actions lookup is genuinely two-way, and that cycle is declared with its reason.
Control shapes / file size — the card face and its controls became their own component (components/ApplicationRunFace.tsx, following BoardIssueFace), which took BoardTab.tsx from 900 lines back to 801.
Tests
application-board.test.ts (26, pure) — one card per application; the title from the lead; a lead missing company/location; the stage per kind and status; the checkpoint pause named; the column mapping (a checkpoint pause is not finished work); the directive once decided; the terminal reason; the trace and runner version; and the bounded detail.
application-runner-routes.test.ts (+6, real schema) — a running card appears the moment the fill starts, titled with its job; it moves to needs_human with the checkpoint on the supervisor pause; its actions equal the ones the Applications service computes, and a control through the shared route succeeds; a retry lands on the same card (exactly one row); a terminal run explains itself; and an instance with no application runtime keeps a plain board.
Verification: full suite 860 files / 14,540 tests green; biome exit 0, all four typechecks, and all eleven custom checks clean.
One thing deliberately left for a follow-up: the existing Applications tab was not removed. Its operational controls now also exist on the Board, which is what this issue asked for; retiring or re-labelling that tab as a pure data view is a separate, console-only change with its own test churn.
Activity
[-]Console: unify application pipeline cards with the instance Kanban board[/-][+]Console: put application execution runs on the normal Kanban, linked to application data[/+]serge-ivo commentedon Oct 8, 2026
Documentation/capability requirement
The implementation must also document this operating model in the user-facing Console/help copy and MCP tool descriptions where relevant:
application data record → one or more Tailor/Runner execution runs → Board card + correlated activity/traceState explicitly that Data answers what the application is, while Board answers what is executing or waiting now. This needs to be consistent across UI and MCP so users do not have to infer the model from implementation details.
serge-ivo commentedon Oct 8, 2026
Implemented in 51251d8.
What it does
Application executions are now cards on the normal Board, written the way coding (#206) and pipelines (#207A) write theirs: the domain writes a generic
instance_runtime_taskscard, and nothing on the reading side learns what an application is. Sosubordinate_status,instance_boardover MCP, and the console all pick it up with no change on their side.Keyed on the APPLICATION, not the run — that follows directly from the product model in the issue. One application has many runs, so tailoring, a fill and a retry collapse into one card whose
attemptsare the runs. Keying on the run id would have produced a new card per retry and buried the application.Each card carries what only the domain can know:
bridge_unused)pausedandawaiting_reviewmap toneeds_human, so a run waiting on a person lands in the column that word belongs to — which is the acceptance line about the card "visibly moving to awaiting-review".The card is written from the two choke points every transition passes through (
syncApplyRun,syncTailorRun) plus each dispatch, so it appears the moment work starts and no transition can forget it.Parity, by construction
The actions on the card come from
getQueueItem— the very read the Applications surface and the typed MCP tools make — so the board cannot offer a control the service would refuse. A control taken from the card posts to that service's own route with the compare-and-set the card was rendered with: a stale card is refused, and there is one audit row per decision however it was made. Console and MCP read the same record.The application stays data
Its record, artifacts, submit authorization and outcome remain on the existing surface. No new operational page was created, and the generic Board is untouched for agents without application runtimes (asserted by a test).
Three ledgers this had to answer
Each was a real obligation, not a formality:
RUNTIME_TASK_OWNERS— the new card type is classifiedcloud: it is a projection of PAGS's own run rows, so a runner reconnect sweep must never expire it.board.tsdragged the generic board into the apply domain's deferred-import cycle. The shape now lives in a leaf (application-card-payload.ts, which imports nothing), shared by writer and reader; only the actions lookup is genuinely two-way, and that cycle is declared with its reason.components/ApplicationRunFace.tsx, followingBoardIssueFace), which tookBoardTab.tsxfrom 900 lines back to 801.Tests
application-board.test.ts(26, pure) — one card per application; the title from the lead; a lead missing company/location; the stage per kind and status; the checkpoint pause named; the column mapping (a checkpoint pause is not finished work); the directive once decided; the terminal reason; the trace and runner version; and the bounded detail.application-runner-routes.test.ts(+6, real schema) — a running card appears the moment the fill starts, titled with its job; it moves toneeds_humanwith the checkpoint on the supervisor pause; its actions equal the ones the Applications service computes, and a control through the shared route succeeds; a retry lands on the same card (exactly one row); a terminal run explains itself; and an instance with no application runtime keeps a plain board.Verification: full suite 860 files / 14,540 tests green; biome exit 0, all four typechecks, and all eleven custom checks clean.
One thing deliberately left for a follow-up: the existing Applications tab was not removed. Its operational controls now also exist on the Board, which is what this issue asked for; retiring or re-labelling that tab as a pure data view is a separate, console-only change with its own test churn.
fix: coding-loop ownership isolation — an interrupted run cannot hand…
feat: durable scan scheduling and per-scan observability for the Job …
feat(board): reconcile every durable application onto the Board, and …