Files
roboco/panel/lib/lifecycle.json
T
08c02e2251 [79d686f0] Add page-scoped refresh button to the navbar (#351)
* [870467e6] Frontend: page-scoped refresh provider, hook, and navbar button (#347)

* [55376b8a] Create page-scoped refresh provider and context (#327)

* [55376b8a] feat(panel): add page-scoped refresh context and provider

* [55376b8a] docs(frontend): add page-refresh-provider component documentation

---------

Co-authored-by: Frontend Developer 1 <fe-dev-1@roboco.tech>
Co-authored-by: Frontend Documenter <fe-doc@roboco.tech>

* [a0c02d0f] Add public usePageRefresh hook (#332)

* [a0c02d0f] test(hooks): assert usePageRefresh is exported from hooks barrel

* [a0c02d0f] feat(hooks): add public usePageRefresh hook with provider and tests

* [a0c02d0f] fix(panel): move hook test wrappers to components and rename providers.tsx to unshadow barrel

* [a0c02d0f] docs(panel): document usePageRefresh hook and PageRefreshProvider API

---------

Co-authored-by: Frontend Developer 2 <fe-dev-2@roboco.tech>
Co-authored-by: Frontend Documenter <fe-doc@roboco.tech>
Co-authored-by: Renn F <rennf93@users.noreply.github.com>

* [5f28dd9b] Add navbar refresh button and remove inline dashboard refresh buttons (#336)

* [5f28dd9b] Align PageRefreshProvider with active hook API and remove inline dashboard refresh buttons

* [5f28dd9b] Remove unused scope-keyed PageRefreshProvider, context, and associated tests

* [5f28dd9b] Address QA revision: add header refresh tests, page-scoped label, remove dead provider code and .venv symlink, revert formatting-only changes

* [5f28dd9b] Remove remaining inline dashboard refresh buttons and committed .venv symlink

* [5f28dd9b] docs(frontend): update page-refresh provider docs and panel README for navbar refresh button

* [5f28dd9b] fix(panel): remove .venv symlink, ignore root .venv entries, and thin task-detail page data fetch into useTaskDetail hook

* [5f28dd9b] Extract GitBrowser data fetching into useGitBrowser hook and add tests; verify .venv cleanup and task-detail thin hook usage

* [5f28dd9b] fix(panel): remove root .venv symlink, restore .gitignore anchored rule, and revert lifecycle.json formatting noise

* Delete .venv

---------

Co-authored-by: Frontend Developer 2 <fe-dev-2@roboco.tech>
Co-authored-by: Frontend Documenter <fe-doc@roboco.tech>

---------

Co-authored-by: Frontend Developer 1 <fe-dev-1@roboco.tech>
Co-authored-by: Frontend Documenter <fe-doc@roboco.tech>
Co-authored-by: Frontend Developer 2 <fe-dev-2@roboco.tech>
Co-authored-by: Renn F <rennf93@users.noreply.github.com>

* [b8e1de1b] Fix navbar refresh button disabled state when registry is empty (#356) (#358)

* [b8e1de1b] fix(panel): derive navbar refresh disabled state from registry, not unused prop

PageRefreshProvider now computes `disabled` from whether any refresh
callback is currently registered (registry size > 0) instead of a
static, never-passed `disabled` prop that left the button permanently
enabled. header.tsx now destructures `disabled` from usePageRefresh()
and disables the button on `disabled || loading`. Updated the tests
that asserted the old always-enabled-by-default behavior and added a
new header test asserting the button is disabled with zero registered
callbacks.

* [b8e1de1b] docs(panel): document PageRefreshProvider disabled state derived from registry

Updated documentation to reflect the refactored PageRefreshProvider behavior: the `disabled` state is now derived from whether any refresh callbacks are currently registered (empty registry = disabled), rather than a static `disabled` prop. Clarified in both panel/README.md and the full component guide that the navbar refresh button disables when no callbacks are registered and when a refresh cycle is in progress. Updated API documentation to remove the now-removed `disabled` prop from PageRefreshProviderProps and updated code examples and test coverage descriptions to reflect the new callback-driven semantics.

---------

Co-authored-by: Frontend Developer 1 <fe-dev-1@roboco.tech>
Co-authored-by: Frontend Documenter <fe-doc@roboco.tech>

* test(panel): mock usePageRefresh in tests predating the provider

Merge-skew: the page-refresh feature makes CommandCenter and the agent
detail page call usePageRefresh; three tests merged from master render
them without the new provider. Mock the hook module, matching the
files' stub-everything style.

---------

Co-authored-by: Frontend Developer 1 <fe-dev-1@roboco.tech>
Co-authored-by: Frontend Documenter <fe-doc@roboco.tech>
Co-authored-by: Frontend Developer 2 <fe-dev-2@roboco.tech>
Co-authored-by: Renn F <rennf93@users.noreply.github.com>
2026-07-09 05:27:14 +02:00

786 lines
19 KiB
JSON

{
"claim_rules": {
"auditor": [],
"cell_pm": [
"needs_revision",
"pending"
],
"ceo": [],
"developer": [
"needs_revision",
"pending"
],
"documenter": [
"awaiting_documentation",
"pending"
],
"head_marketing": [],
"main_pm": [
"needs_revision",
"pending"
],
"pr_reviewer": [
"awaiting_pr_review",
"pending"
],
"product_owner": [],
"qa": [
"awaiting_qa"
]
},
"intents": [
{
"allowed_roles": [
"documenter"
],
"composes": [],
"description": "Claim awaiting_documentation. Returns evidence inline.",
"name": "claim_doc_task",
"pre_side_effects": [],
"side_effects": []
},
{
"allowed_roles": [
"pr_reviewer"
],
"composes": [],
"description": "Claim an assembled-PR review task (awaiting_pr_review) WITHOUT transitioning it — mirrors QA's claim_review. The assembled diff and the parent task's acceptance criteria are returned inline.",
"name": "claim_gate_review",
"pre_side_effects": [],
"side_effects": []
},
{
"allowed_roles": [
"pr_reviewer"
],
"composes": [
"claim",
"start"
],
"description": "Claim an inbound external-PR review task and start work. pending -> claimed -> in_progress.",
"name": "claim_pr_review",
"pre_side_effects": [],
"side_effects": []
},
{
"allowed_roles": [
"qa"
],
"composes": [],
"description": "Claim a task in awaiting_qa for review. Returns evidence inline.",
"name": "claim_review",
"pre_side_effects": [],
"side_effects": []
},
{
"allowed_roles": [
"cell_pm",
"main_pm"
],
"composes": [
"complete"
],
"description": "Cell PM merges the PR (leaf into the cell branch, or the gated cell→root PR into the root branch) + transitions to completed; Main PM escalates the root to the CEO (who merges root→master). The merge runs BEFORE the complete transition: TaskService.complete asserts the PR is already merged, so the choreographer verb body (cell_pm_complete / main_pm_complete) owns the merge-first ordering — no trailing pr_merge side_effect is declared here.",
"name": "complete",
"pre_side_effects": [],
"side_effects": []
},
{
"allowed_roles": [
"cell_pm",
"main_pm"
],
"composes": [],
"description": "Stamp parent acceptance criteria onto an existing child's parent_ac_refs after the fact \u2014 for a replacement child whose delegate omitted covers_parent_criteria. Or, targeting your OWN root/coordination task, declare criteria as root-owned (only your own machinery satisfies them \u2014 never push these into a cell). No status change; the verb body owns ownership + criterion validation.",
"name": "declare_coverage",
"pre_side_effects": [],
"side_effects": []
},
{
"allowed_roles": [
"cell_pm",
"main_pm"
],
"composes": [
"create_subtask"
],
"description": "Create a subtask under the current task. Validates the delegation chain (main_pm->cell_pm; cell_pm->its team's devs) and the assignee-vs-task_type rule (Cell PMs get planning-typed tasks; devs get code/research, UX devs also design). documentation is NOT delegatable — the lifecycle auto-creates the doc phase after the code subtask passes QA.",
"name": "delegate",
"pre_side_effects": [],
"side_effects": []
},
{
"allowed_roles": [
"head_marketing",
"main_pm",
"product_owner"
],
"composes": [
"escalate_to_ceo"
],
"description": "Escalate to CEO with reason. Transitions to awaiting_ceo_approval.",
"name": "escalate_to_ceo",
"pre_side_effects": [],
"side_effects": []
},
{
"allowed_roles": [
"cell_pm",
"main_pm"
],
"composes": [],
"description": "Escalate to your role's escalation_target.",
"name": "escalate_up",
"pre_side_effects": [],
"side_effects": []
},
{
"allowed_roles": [
"qa"
],
"composes": [
"qa_fail"
],
"description": "Fail QA with concrete issues. Transitions needs_revision.",
"name": "fail_review",
"pre_side_effects": [],
"side_effects": []
},
{
"allowed_roles": [
"cell_pm",
"developer",
"documenter",
"main_pm",
"pr_reviewer",
"qa"
],
"composes": [],
"description": "Return your most-actionable task or signal idle.",
"name": "give_me_work",
"pre_side_effects": [],
"side_effects": []
},
{
"allowed_roles": [
"developer",
"documenter",
"qa"
],
"composes": [
"block"
],
"description": "Escalate to PM. Logs a struggle journal entry.",
"name": "i_am_blocked",
"pre_side_effects": [],
"side_effects": []
},
{
"allowed_roles": [
"developer"
],
"composes": [
"submit_verification",
"submit_qa"
],
"description": "Submit work for QA. Auto-runs in_progress->verifying then verifying->awaiting_qa. Strict - PR must be open (call open_pr first) and >=1 commit.",
"name": "i_am_done",
"pre_side_effects": [],
"side_effects": []
},
{
"allowed_roles": [
"auditor",
"cell_pm",
"developer",
"documenter",
"head_marketing",
"main_pm",
"pr_reviewer",
"product_owner",
"prompter",
"qa",
"secretary"
],
"composes": [],
"description": "Signal you have no work. PMs auto-pause owned in_progress tasks.",
"name": "i_am_idle",
"pre_side_effects": [],
"side_effects": []
},
{
"allowed_roles": [
"documenter"
],
"composes": [
"docs_complete"
],
"description": "Signal docs complete. Transitions to awaiting_pm_review.",
"name": "i_documented",
"pre_side_effects": [],
"side_effects": []
},
{
"allowed_roles": [
"cell_pm",
"main_pm"
],
"composes": [
"claim",
"set_plan",
"start"
],
"description": "PM mirror of i_will_work_on for parent tasks. Claim, plan, transition to in_progress; from there delegate subtasks.",
"name": "i_will_plan",
"pre_side_effects": [],
"side_effects": []
},
{
"allowed_roles": [
"developer"
],
"composes": [
"claim",
"set_plan",
"start"
],
"description": "Claim a task, set the plan, and transition to in_progress. Atomic - preconditions checked before any state mutation.",
"name": "i_will_work_on",
"pre_side_effects": [],
"side_effects": []
},
{
"allowed_roles": [
"developer"
],
"composes": [],
"description": "Push the branch and open a PR. Atomic - preconditions (assignee, >=1 commit, no prior PR) checked BEFORE any git operation. After success, call i_am_done.",
"name": "open_pr",
"pre_side_effects": [],
"side_effects": [
"push_branch",
"create_pr"
]
},
{
"allowed_roles": [
"qa"
],
"composes": [
"qa_pass"
],
"description": "Pass QA. Transitions awaiting_qa -> awaiting_documentation.",
"name": "pass_review",
"pre_side_effects": [],
"side_effects": []
},
{
"allowed_roles": [
"pr_reviewer"
],
"composes": [
"pr_review_done"
],
"description": "Post one complete change-request to the external PR and finish the review task. in_progress -> completed.",
"name": "post_pr_review",
"pre_side_effects": [],
"side_effects": []
},
{
"allowed_roles": [
"pr_reviewer"
],
"composes": [
"pr_fail"
],
"description": "Fail the assembled-PR review with concrete issues. Transitions awaiting_pr_review -> needs_revision, routed back like a QA fail.",
"name": "pr_fail",
"pre_side_effects": [],
"side_effects": []
},
{
"allowed_roles": [
"pr_reviewer"
],
"composes": [
"pr_pass"
],
"description": "Pass the assembled-PR review. Transitions awaiting_pr_review -> awaiting_pm_review so the PM can merge.",
"name": "pr_pass",
"pre_side_effects": [],
"side_effects": []
},
{
"allowed_roles": [
"cell_pm"
],
"composes": [],
"description": "Hand a claimed/in_progress task to another developer in your own cell. The branch is keyed to the task (not the agent), so it is preserved — the new developer continues the work-in-progress. No status change.",
"name": "reassign",
"pre_side_effects": [],
"side_effects": []
},
{
"allowed_roles": [
"cell_pm",
"main_pm"
],
"composes": [
"request_changes"
],
"description": "Reject the merge review with concrete issues. Transitions awaiting_pm_review -> needs_revision, routed back like a QA fail (original developer for a leaf, revision PM for an assembled task). Use this for an AC/scope violation caught at merge review — never i_am_blocked/escalate, which have no revision routing.",
"name": "request_changes",
"pre_side_effects": [],
"side_effects": []
},
{
"allowed_roles": [
"cell_pm",
"developer",
"documenter",
"main_pm",
"qa"
],
"composes": [
"resume"
],
"description": "Resume a paused task you own. paused -> in_progress.",
"name": "resume",
"pre_side_effects": [],
"side_effects": []
},
{
"allowed_roles": [
"main_pm"
],
"composes": [
"submit_for_review"
],
"description": "Main PM opens the root→master PR and moves the root task to awaiting_pr_review for the main reviewer (the root analogue of the cell PM's submit_up). After pr_pass, call complete to escalate to the CEO. For branch-bearing roots (a Main-PM root-subtask assembles the cells' merged work); branchless coordination roots skip the gate and complete directly. The gate is branch-keyed, not task_type-keyed — a root is planning-typed, never code.",
"name": "submit_root",
"pre_side_effects": [
"create_root_pr"
],
"side_effects": []
},
{
"allowed_roles": [
"cell_pm"
],
"composes": [
"submit_for_review"
],
"description": "Cell PM opens the cell→root PR and moves the cell task into the PR-review gate (awaiting_pr_review). The cell reviewer reviews the assembled diff; after pr_pass the same Cell PM completes it.",
"name": "submit_up",
"pre_side_effects": [
"create_pr"
],
"side_effects": []
},
{
"allowed_roles": [
"developer"
],
"composes": [],
"description": "Rebase your task's branch onto its current base THROUGH the gate (raw git is denied). Use when your branch has fallen behind its base — e.g. a sibling task's PR merged into the parent branch while you worked. Fetches origin, rebases head onto base, and force-pushes (with-lease). No DB state change. On conflicts the rebase is aborted and the conflicted files are returned — resolve by hand, commit, then sync_branch again.",
"name": "sync_branch",
"pre_side_effects": [],
"side_effects": []
},
{
"allowed_roles": [
"auditor",
"cell_pm",
"head_marketing",
"main_pm",
"product_owner"
],
"composes": [],
"description": "List actionable tasks in your scope.",
"name": "triage",
"pre_side_effects": [],
"side_effects": []
},
{
"allowed_roles": [
"main_pm"
],
"composes": [],
"description": "List actionable tasks across all teams (Main PM only).",
"name": "triage_all",
"pre_side_effects": [],
"side_effects": []
},
{
"allowed_roles": [
"cell_pm",
"main_pm"
],
"composes": [
"unblock"
],
"description": "PM unblocks a blocked task; restores pre-block state.",
"name": "unblock",
"pre_side_effects": [],
"side_effects": []
},
{
"allowed_roles": [
"cell_pm",
"developer",
"documenter",
"main_pm",
"pr_reviewer",
"qa"
],
"composes": [],
"description": "Voluntarily release a claim back to pending. The branch is keyed to the task (not the agent), so it is preserved — the new developer continues the work-in-progress. No status change.",
"name": "unclaim",
"pre_side_effects": [],
"side_effects": []
}
],
"transitions": [
{
"action": "cancel",
"roles": [
"ceo"
],
"source": "awaiting_ceo_approval",
"target": "cancelled"
},
{
"action": "ceo_approve",
"roles": [
"ceo"
],
"source": "awaiting_ceo_approval",
"target": "completed"
},
{
"action": "ceo_reject",
"roles": [
"ceo"
],
"source": "awaiting_ceo_approval",
"target": "needs_revision"
},
{
"action": "ceo_reject_to_pool",
"roles": [
"ceo"
],
"source": "awaiting_ceo_approval",
"target": "pending"
},
{
"action": "docs_complete",
"roles": [
"documenter"
],
"source": "awaiting_documentation",
"target": "awaiting_pm_review"
},
{
"action": "cancel",
"roles": [
"cell_pm",
"ceo",
"main_pm"
],
"source": "awaiting_documentation",
"target": "cancelled"
},
{
"action": "claim",
"roles": [
"documenter"
],
"source": "awaiting_documentation",
"target": "claimed"
},
{
"action": "escalate_to_ceo",
"roles": [
"head_marketing",
"main_pm",
"product_owner"
],
"source": "awaiting_pm_review",
"target": "awaiting_ceo_approval"
},
{
"action": "cancel",
"roles": [
"cell_pm",
"ceo",
"main_pm"
],
"source": "awaiting_pm_review",
"target": "cancelled"
},
{
"action": "complete",
"roles": [
"cell_pm",
"main_pm"
],
"source": "awaiting_pm_review",
"target": "completed"
},
{
"action": "request_changes",
"roles": [
"cell_pm",
"main_pm"
],
"source": "awaiting_pm_review",
"target": "needs_revision"
},
{
"action": "pr_pass",
"roles": [
"pr_reviewer"
],
"source": "awaiting_pr_review",
"target": "awaiting_pm_review"
},
{
"action": "cancel",
"roles": [
"cell_pm",
"ceo",
"main_pm"
],
"source": "awaiting_pr_review",
"target": "cancelled"
},
{
"action": "claim",
"roles": [
"pr_reviewer"
],
"source": "awaiting_pr_review",
"target": "claimed"
},
{
"action": "pr_fail",
"roles": [
"pr_reviewer"
],
"source": "awaiting_pr_review",
"target": "needs_revision"
},
{
"action": "qa_pass",
"roles": [
"qa"
],
"source": "awaiting_qa",
"target": "awaiting_documentation"
},
{
"action": "cancel",
"roles": [
"cell_pm",
"ceo",
"main_pm"
],
"source": "awaiting_qa",
"target": "cancelled"
},
{
"action": "claim",
"roles": [
"qa"
],
"source": "awaiting_qa",
"target": "claimed"
},
{
"action": "qa_fail",
"roles": [
"qa"
],
"source": "awaiting_qa",
"target": "needs_revision"
},
{
"action": "cancel",
"roles": [
"cell_pm",
"ceo",
"main_pm"
],
"source": "backlog",
"target": "cancelled"
},
{
"action": "activate",
"roles": null,
"source": "backlog",
"target": "pending"
},
{
"action": "escalate_to_ceo",
"roles": [
"head_marketing",
"main_pm",
"product_owner"
],
"source": "blocked",
"target": "awaiting_ceo_approval"
},
{
"action": "cancel",
"roles": [
"cell_pm",
"ceo",
"main_pm"
],
"source": "blocked",
"target": "cancelled"
},
{
"action": "unblock",
"roles": null,
"source": "blocked",
"target": "in_progress"
},
{
"action": "unblock",
"roles": null,
"source": "blocked",
"target": "pending"
},
{
"action": "cancel",
"roles": [
"cell_pm",
"ceo",
"main_pm"
],
"source": "claimed",
"target": "cancelled"
},
{
"action": "start",
"roles": null,
"source": "claimed",
"target": "in_progress"
},
{
"action": "submit_pm_review",
"roles": null,
"source": "in_progress",
"target": "awaiting_pm_review"
},
{
"action": "submit_for_review",
"roles": null,
"source": "in_progress",
"target": "awaiting_pr_review"
},
{
"action": "block",
"roles": null,
"source": "in_progress",
"target": "blocked"
},
{
"action": "cancel",
"roles": [
"cell_pm",
"ceo",
"main_pm"
],
"source": "in_progress",
"target": "cancelled"
},
{
"action": "pr_review_done",
"roles": [
"pr_reviewer"
],
"source": "in_progress",
"target": "completed"
},
{
"action": "pause",
"roles": null,
"source": "in_progress",
"target": "paused"
},
{
"action": "submit_verification",
"roles": null,
"source": "in_progress",
"target": "verifying"
},
{
"action": "cancel",
"roles": [
"cell_pm",
"ceo",
"main_pm"
],
"source": "needs_revision",
"target": "cancelled"
},
{
"action": "claim",
"roles": null,
"source": "needs_revision",
"target": "claimed"
},
{
"action": "cancel",
"roles": [
"cell_pm",
"ceo",
"main_pm"
],
"source": "paused",
"target": "cancelled"
},
{
"action": "resume",
"roles": null,
"source": "paused",
"target": "in_progress"
},
{
"action": "cancel",
"roles": [
"cell_pm",
"ceo",
"main_pm"
],
"source": "pending",
"target": "cancelled"
},
{
"action": "claim",
"roles": null,
"source": "pending",
"target": "claimed"
},
{
"action": "submit_qa",
"roles": null,
"source": "verifying",
"target": "awaiting_qa"
},
{
"action": "cancel",
"roles": [
"cell_pm",
"ceo",
"main_pm"
],
"source": "verifying",
"target": "cancelled"
}
]
}