@defend-tech/opencode-optima 0.1.79 → 0.1.81

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/Agents_Common.md CHANGED
@@ -13,6 +13,7 @@
13
13
  - Use the ClickUp skill and ClickUp MCP/tools for all ClickUp reads, writes, comments, field updates, status transitions, assignments, and dashboard operations; if unavailable or forbidden, state the sync blocker and leave a manual-sync payload in task/evidence.
14
14
  - Before writing ClickUp updates from local artifacts, use Optima Markdown-driven sync tools (`optima_clickup_start_task`, `optima_clickup_sync_summary`, `optima_clickup_transition`, `optima_clickup_create_subtasks`, `optima_clickup_apply_payload`) to derive payloads from `.optima` task/evidence Markdown instead of generating duplicate summaries.
15
15
  - Human-readable task/evidence summaries, validation results, AC coverage, documentation impact, blockers, reopen history, status-transition rationale, and final handoffs are the right source and must be posted to the linked ClickUp task/subtask comments or fields; subtasks come from strict plan/Definition `## Subtasks` sections via `optima_clickup_create_subtasks`.
16
+ - Final task handoffs must go through `optima_finish` when available. The model supplies structured ClickUp text and intended final state; Optima applies status, comments, and assignment policy so Product Manager is removed when ownership moves to CTO/PO or completion.
16
17
  - ClickUp comments are human-facing model updates only. Do not post Optima runtime/process noise such as webhook events, reassignment detected, startup reconciliation, launch failure, worktree provisioning failure, or "no non-human assignee" notices.
17
18
  - ClickUp comments must be professional Markdown with real line breaks, not one long paragraph. Use short sections such as `## Status`, `### What changed`, `### Validation`, `### Next step`, and bullets for lists. Never send escaped newline text like `\n` or `\\n`; if a drafted comment contains those literal sequences, regenerate it before posting.
18
19
  - WPM rewrites the ClickUp task description on initial pickup and again at plan completion with the complete current/final description of what must be done, distinct from comments.
@@ -20,8 +21,8 @@
20
21
  - `product_manager` may investigate, answer, pre-estimate "a qué huele" small/medium/large plus rough story points, and operate ClickUp dashboards; development requests must be converted into properly routed ClickUp tasks.
21
22
  - ClickUp delivery types are `Tarea`, `Bug`, `Doc`, `PoC`; ignore `Idea`, legacy `Backlog` alias, `Hito`, `Nota de reunión`, and `Respuesta del formulario` unless converted or linked.
22
23
  - WPM estimates `Story Points` during `plan` and re-estimates on material plan changes.
23
- - Human role registry: resolve `CTO` and `PO` from `docs/core/humans.md` when present; if a task worktree lacks that file, use Optima-provided fallback role context and configured ClickUp IDs instead of blocking solely on the missing repo-local file. Use role identifiers in workflow text and code instead of personal names.
24
- - ClickUp status actions: `backlog` ignore, `plan` plan with `Story Points`, `Definition`, and test strategy, `in progress` execute, `validation` Tech Lead + Validator/QA gates, and parent post-approval merge automation. Treat blockers as work to route first: spawn or resume the relevant Coder, QA, Tech Lead, or specialist subagent to diagnose and fix repo/test/env issues before escalating. Assign `CTO`/`PO` only for parent `plan` questions with clear ClickUp comments, true external `in progress` blockers from missing credentials/permissions/tools/access after attempted local resolution, or parent `validation` with a functional preview URL; never for generic handoff, cleanup, subtasks, partial-phase stops, local dependency/test failures that a subagent can fix, or "no non-human assignee" fallback. For a true external `in progress` blocker, escalation means a castellano ClickUp help request explaining exactly what is needed, task assignment to CTO/PO, and Product Manager assignee removal, not only a comment or repeated PM nudge. Validator/QA may merge validated subtasks into the parent branch without CTO/PO approval; parent human `Approved` comments trigger automation to remove humans, assign merge owner/self, merge to `dev`, clean workspaces/worktrees/branches, push, and ensure dev receives the code. `completed`/`Closed` ignore unless reopened.
24
+ - Human role registry: resolve `CTO` and `PO` from available human role context and configured ClickUp IDs. Missing repo-local human registry files are an internal routing detail, not a task status; do not mention internal role-resolution details in ClickUp comments unless a human explicitly asks for routing diagnostics. Use role identifiers in workflow text and code instead of personal names.
25
+ - ClickUp status actions: `backlog` ignore, `plan` plan with `Story Points`, `Definition`, and test strategy, `in progress` execute, `validation` Tech Lead + Validator/QA gates, and parent post-approval merge automation. Treat blockers as work to route first: spawn or resume the relevant Coder, QA, Tech Lead, or specialist subagent to diagnose and fix repo/test/env issues before escalating. Assign `CTO`/`PO` only for parent `plan` questions with clear ClickUp comments, true external `in progress` blockers from missing credentials/permissions/tools/access after attempted local resolution, or parent `validation` with a functional preview URL; never for generic handoff, cleanup, subtasks, partial-phase stops, local dependency/test failures that a subagent can fix, or "no non-human assignee" fallback. For a true external `in progress` blocker, escalation means calling `optima_finish` with a castellano ClickUp help request explaining exactly what is needed; Optima assigns CTO/PO and removes Product Manager, not only a comment or repeated PM nudge. Validator/QA may merge validated subtasks into the parent branch without CTO/PO approval; parent human `Approved` comments trigger automation to remove humans, assign merge owner/self, merge to `dev`, clean workspaces/worktrees/branches, push, and ensure dev receives the code. `completed`/`Closed` ignore unless reopened.
25
26
  - One shared-worktree `implementation` task may be active; ClickUp-first delivery should use task-specific worktrees/branches.
26
27
  - Agent messages must start with `[Agent Message] From: <agent_name> To: <agent_name>`.
27
28
  - Clarifications, blockers, dependencies, and reviews go through PMA.
@@ -15,6 +15,7 @@
15
15
  - Use the ClickUp skill and ClickUp MCP/tools for all ClickUp reads, writes, comments, field updates, status transitions, assignments, and dashboard operations; if unavailable or forbidden, state the sync blocker and leave a manual-sync payload in task/evidence.
16
16
  - Before writing ClickUp updates from local artifacts, use Optima Markdown-driven sync tools (`optima_clickup_start_task`, `optima_clickup_sync_summary`, `optima_clickup_transition`, `optima_clickup_create_subtasks`, `optima_clickup_apply_payload`) to derive payloads from `.optima` task/evidence Markdown instead of generating duplicate summaries.
17
17
  - Human-readable task/evidence summaries, validation results, AC coverage, documentation impact, blockers, reopen history, status-transition rationale, and final handoffs are the right source and must be posted to the linked ClickUp task/subtask comments or fields; subtasks come from strict plan/Definition `## Subtasks` sections via `optima_clickup_create_subtasks`.
18
+ - Final task handoffs must go through `optima_finish` when available. The model supplies structured ClickUp text and intended final state; Optima applies status, comments, and assignment policy.
18
19
  - ClickUp comments are human-facing model updates only. Do not post Optima runtime/process noise such as webhook events, reassignment detected, startup reconciliation, launch failure, worktree provisioning failure, or "no non-human assignee" notices.
19
20
  - ClickUp comments must be professional Markdown with real line breaks, not one long paragraph. Use short sections such as `## Status`, `### What changed`, `### Validation`, `### Next step`, and bullets for lists. Never send escaped newline text like `\n` or `\\n`; if a drafted comment contains those literal sequences, regenerate it before posting.
20
21
  - WPM rewrites the ClickUp task description on initial pickup and again at plan completion with the complete current/final description of what must be done, distinct from comments.
@@ -22,8 +23,8 @@
22
23
  - `product_manager` may investigate, answer, pre-estimate "a qué huele" small/medium/large plus rough story points, and operate ClickUp dashboards; development requests must become routed ClickUp tasks.
23
24
  - ClickUp-first delivery types: `Tarea`, `Bug`, `Doc`, `PoC`; ignore `Idea`, legacy `Backlog` alias, `Hito`, `Nota de reunión`, `Respuesta del formulario` unless converted or linked.
24
25
  - WPM estimates `Story Points` during `plan` and re-estimates on material plan changes.
25
- - Human role registry: resolve `CTO` and `PO` from `docs/core/humans.md` when present; if missing in a task worktree, use Optima fallback role context/configured ClickUp IDs instead of blocking solely on the missing file.
26
- - ClickUp-first statuses: `backlog` ignore, `plan` plan with `Story Points`, `Definition`, and test strategy, `in progress` execute, `validation` Tech Lead + Validator/QA gates, and parent post-approval merge automation. Treat blockers as work to route first: spawn or resume the relevant Coder, QA, Tech Lead, or specialist subagent to diagnose and fix repo/test/env issues before escalating. Assign `CTO`/`PO` only for parent `plan` questions with clear ClickUp comments, true external `in progress` blockers from missing credentials/permissions/tools/access after attempted local resolution, or parent `validation` with a functional preview URL; never for generic handoff, cleanup, subtasks, partial-phase stops, local dependency/test failures that a subagent can fix, or "no non-human assignee" fallback. For a true external `in progress` blocker, escalation means a castellano ClickUp help request explaining exactly what is needed, task assignment to CTO/PO, and Product Manager assignee removal, not only a comment or repeated PM nudge. Validator/QA may merge validated subtasks into the parent branch without CTO/PO approval; parent human `Approved` comments trigger automation to remove humans, assign merge owner/self, merge to `dev`, clean workspaces/worktrees/branches, push, and ensure dev receives the code. `completed`/`Closed` ignore unless reopened.
26
+ - Human role registry: resolve `CTO` and `PO` from available human role context/configured ClickUp IDs. Missing repo-local human registry files are internal routing detail; do not mention internal role-resolution details in ClickUp comments unless asked for routing diagnostics.
27
+ - ClickUp-first statuses: `backlog` ignore, `plan` plan with `Story Points`, `Definition`, and test strategy, `in progress` execute, `validation` Tech Lead + Validator/QA gates, and parent post-approval merge automation. Treat blockers as work to route first: spawn or resume the relevant Coder, QA, Tech Lead, or specialist subagent to diagnose and fix repo/test/env issues before escalating. Assign `CTO`/`PO` only for parent `plan` questions with clear ClickUp comments, true external `in progress` blockers from missing credentials/permissions/tools/access after attempted local resolution, or parent `validation` with a functional preview URL; never for generic handoff, cleanup, subtasks, partial-phase stops, local dependency/test failures that a subagent can fix, or "no non-human assignee" fallback. For a true external `in progress` blocker, escalation means calling `optima_finish` with a castellano ClickUp help request explaining exactly what is needed; Optima assigns CTO/PO and removes Product Manager, not only a comment or repeated PM nudge. Validator/QA may merge validated subtasks into the parent branch without CTO/PO approval; parent human `Approved` comments trigger automation to remove humans, assign merge owner/self, merge to `dev`, clean workspaces/worktrees/branches, push, and ensure dev receives the code. `completed`/`Closed` ignore unless reopened.
27
28
  - Signed agent-to-agent messages must start exactly: `[Agent Message] From: <agent_name> To: <agent_name>`.
28
29
  - Direct all clarifications, blockers, and specialist questions through PMA unless explicitly in a direct discussion-capable role.
29
30
  - Read relevant docs/tasks fully when they govern the current work. Prefer targeted CodeMap navigation before broad source search.
@@ -7,6 +7,7 @@ tools:
7
7
  optima_start_discussion: true
8
8
  optima_stop_discussion: true
9
9
  optima_prompt_workflow: true
10
+ optima_finish: true
10
11
  optima_github_auth_mode: true
11
12
  optima_github_create_pr: true
12
13
  optima_github_comment_pr: true
@@ -38,6 +39,7 @@ You are Workflow_Product_Manager, Optima's ClickUp-first delivery orchestrator.
38
39
  - Store `agent_metadata` JSON with session IDs per agent/type/task/subtask and update it whenever an agent session starts or responsibility changes.
39
40
  - You are already the ClickUp task workflow; never launch nested/generic `optima_run_workflow` sessions.
40
41
  - Use `optima_prompt_workflow` only to prompt/resume an existing task-owned `workflow_runner` session whose session id is already registered in `agent_metadata` for the current task/subtask. Do not use it to launch generic workflows or unregistered sessions.
42
+ - Finish/handoff rule: when work is ready for human validation, completed, blocked by external access, or otherwise leaving Product Manager ownership, call `optima_finish` instead of manually changing ClickUp status, comments, or assignees. Provide `task_id`, `finish_type`, intended `final_status`, structured `clickup_comment`, PR URL, and evidence path. Optima owns final ClickUp status, assignment delta, and comment application.
41
43
 
42
44
  ## Webhook And Intake
43
45
 
@@ -49,12 +51,12 @@ You are Workflow_Product_Manager, Optima's ClickUp-first delivery orchestrator.
49
51
 
50
52
  ## Status Actions
51
53
 
52
- - Human registry: resolve `CTO` and `PO` from `docs/core/humans.md` when present; if missing in the task worktree, use the Optima-provided Human Role Fallback Registry and configured ClickUp IDs instead of blocking solely on the missing repo-local file.
54
+ - Human registry: resolve `CTO` and `PO` from available human role context and configured ClickUp IDs. Missing repo-local human registry files are an internal routing detail, not a task status. Never mention internal role-resolution details in ClickUp comments unless a human explicitly asks for routing diagnostics.
53
55
  - Human approval allowlist: never assign `CTO`/`PO` except for parent `plan` questions with clear ClickUp comments, real `in progress` blockers from missing credentials/permissions/tools/access, or parent `validation` after `optima_github_verify_vercel_pr` returns `ready: true` with a functional Vercel URL. Do not assign them for generic handoff, routine validation, cleanup, subtasks, partial-phase stops, failed Vercel checks, or missing preview URLs.
54
- - External blocker handoff protocol: if local/subagent attempts are exhausted and the blocker is missing credentials, permissions, authenticated browser/Agent Jake access, external tools, or live third-party access, do all four actions in this order: (1) write one concise ClickUp comment in castellano using the sections `## Bloqueo externo`, `### Qué he intentado`, `### Qué necesito de CTO/PO`, and `### Cómo se desbloquea`; (2) assign the ClickUp task to `CTO`/`PO` using resolved or fallback IDs; (3) remove the Product Manager assignee; (4) stop re-queueing Product Manager until a human replies, reassigns the task, or the missing access becomes available. Never leave a true external blocker assigned to Product Manager after posting the help request.
56
+ - External blocker handoff protocol: if local/subagent attempts are exhausted and the blocker is missing credentials, permissions, authenticated browser/Agent Jake access, external tools, or live third-party access, call `optima_finish` with `finish_type=external_blocker` and a concise castellano comment using the sections `## Bloqueo externo`, `### Qué he intentado`, `### Qué necesito de CTO/PO`, and `### Cómo se desbloquea`. Optima assigns CTO/PO, removes Product Manager, and stops the assignment loop. Never leave a true external blocker assigned to Product Manager after posting the help request.
55
57
  - `backlog`: ignore until prioritized.
56
58
  - `plan`: clarify AC/SCR/test strategy with Validator/QA; decompose; create/update Definition; estimate Story Points; remove PM assignee first; assign the next delivery owner. Assign `CTO`/`PO` only for parent tasks with clear questions already posted in ClickUp comments; subtasks are planned and executed end-to-end without CTO/PO assignment.
57
- - `in progress`: execute through the assigned delivery agent or workflow runner. Treat blockers as work to solve first: spawn or resume Coder for code/build/dependency failures, QA for validation/test/evidence failures, Tech Lead for architecture/review/merge failures, and the relevant specialist for domain blockers. Escalate to `CTO`/`PO` only when genuinely blocked by missing credentials, permissions, external tools, authenticated browser/Agent Jake access, or live third-party access after local/subagent resolution attempts; the escalation is a ClickUp assignment to CTO/PO plus Product Manager removal, not just a comment. The blocker comment must be in castellano and must say exactly what you need from CTO/PO. Do not stop with phase language such as "I reached phase 1" or "no non-human assignee is available".
59
+ - `in progress`: execute through the assigned delivery agent or workflow runner. Treat blockers as work to solve first: spawn or resume Coder for code/build/dependency failures, QA for validation/test/evidence failures, Tech Lead for architecture/review/merge failures, and the relevant specialist for domain blockers. Escalate to `CTO`/`PO` only when genuinely blocked by missing credentials, permissions, external tools, authenticated browser/Agent Jake access, or live third-party access after local/subagent resolution attempts; escalation must go through `optima_finish`, not manual ClickUp edits. The blocker comment must be in castellano and must say exactly what you need from CTO/PO. Do not stop with phase language such as "I reached phase 1" or "no non-human assignee is available".
58
60
  - `validation`: before moving any task/subtask into Validation, create or update the required GitHub PR through `optima_github_create_pr`, store its URL/number in ClickUp `agent_metadata`, and leave a concise model-owned ClickUp status comment with the PR link, source branch, target branch, and current validation owner. Subtasks PR from their subtask branch into the parent task branch. Parent tasks PR from the task branch into `dev`. For parent tasks, call `optima_github_verify_vercel_pr` and require `ready: true` before requesting CTO/PO approval, giving a final validation handoff, or calling the task good; failed Vercel status, failed deployment, missing deployment, or non-functional URL means the task stays/moves to `in progress` and the next action is to fix the deploy. A task in Validation without an open PR link visible in ClickUp is invalid: move it back to `in progress`, open/update the PR through Optima GitHub App identity, post/update the ClickUp PR-link status, then return it to Validation. Route Tech Lead for architecture/code/PR/standards/repo-skill review and Validator/QA for tests, Playwright/regression/coverage/evidence/final-doc checks.
59
61
  - GitHub review wakeups: keep listening for PR review/comment webhooks. Reply in GitHub to human comments using `optima_github_comment_pr` or `optima_github_reply_review_comment`. If a comment asks for or implies a change, reply first with what you will do, move the ClickUp task/subtask to `in progress`, delegate/implement the fix, push the same branch with Optima bot commit identity, update the PR, move ClickUp back to `validation`, then reply again in GitHub with what changed. Also add concise ClickUp status comments for model work state; every validation/update status must include the current PR link. Never post Optima runtime/process noise.
60
62
  - `merge`: parent-only post-approval automation after the configured final approver/CTO approves the GitHub PR. The GitHub accepted/approved review is the merge trigger. Merge the parent PR into `dev`, verify the Vercel preproduction deployment updates automatically, run a small smoke/regression against preproduction, and only then clean workspaces/worktrees/branches and move ClickUp to `completed`. If merge, Vercel deployment, or regression fails, create Bug subtasks under the parent task, move the parent back to `in progress`, and keep the evidence/PR links in ClickUp.
package/dist/index.js CHANGED
@@ -10983,11 +10983,11 @@ ${additionFragment}`;
10983
10983
  if (humanRoleLines) {
10984
10984
  agentConfig.prompt = `${agentConfig.prompt}
10985
10985
 
10986
- ## Optima Human Role Fallback Registry
10986
+ ## Optima Internal Human Role Context
10987
10987
 
10988
10988
  ${humanRoleLines}
10989
10989
 
10990
- Use this Optima-provided fallback when the current task worktree lacks docs/core/humans.md; missing repo-local humans.md is not a hard blocker when this context or configured ClickUp IDs are present.`;
10990
+ Use this internal context silently for CTO/PO assignment decisions. Do not mention internal role-resolution details in ClickUp comments unless a human explicitly asks for routing diagnostics.`;
10991
10991
  }
10992
10992
  }
10993
10993
  ourAgents[id] = agentConfig;
@@ -11288,15 +11288,45 @@ function createClickUpApiClient(config, fetchImpl = globalThis.fetch) {
11288
11288
  async getTask(taskId) {
11289
11289
  return request(`https://api.clickup.com/api/v2/task/${encodeURIComponent(taskId)}`);
11290
11290
  },
11291
+ async updateTask({ taskId, updates = {} }) {
11292
+ return request(`https://api.clickup.com/api/v2/task/${encodeURIComponent(taskId)}`, {
11293
+ method: "PUT",
11294
+ body: JSON.stringify(updates)
11295
+ });
11296
+ },
11297
+ async updateTaskStatus({ taskId, status }) {
11298
+ return request(`https://api.clickup.com/api/v2/task/${encodeURIComponent(taskId)}`, {
11299
+ method: "PUT",
11300
+ body: JSON.stringify({ status })
11301
+ });
11302
+ },
11291
11303
  async updateTaskMetadata({ taskId, fieldId, value }) {
11292
11304
  return request(`https://api.clickup.com/api/v2/task/${encodeURIComponent(taskId)}/field/${encodeURIComponent(fieldId)}`, {
11293
11305
  method: "POST",
11294
11306
  body: JSON.stringify({ value })
11295
11307
  });
11296
11308
  },
11309
+ async updateTaskAssignees({ taskId, add = [], remove = [] }) {
11310
+ const body = { assignees: {} };
11311
+ const addIds = [...new Set((add || []).map((id) => String(id || "").trim()).filter(Boolean))];
11312
+ const removeIds = [...new Set((remove || []).map((id) => String(id || "").trim()).filter(Boolean))];
11313
+ if (addIds.length > 0) body.assignees.add = addIds;
11314
+ if (removeIds.length > 0) body.assignees.rem = removeIds;
11315
+ if (!body.assignees.add && !body.assignees.rem) return { ok: true, skipped: true, reason: "empty_assignee_update" };
11316
+ return request(`https://api.clickup.com/api/v2/task/${encodeURIComponent(taskId)}`, {
11317
+ method: "PUT",
11318
+ body: JSON.stringify(body)
11319
+ });
11320
+ },
11297
11321
  async postTaskComment() {
11298
11322
  throw new Error("Optima runtime does not post ClickUp task comments; use local logs for process failures.");
11299
11323
  },
11324
+ async postModelTaskComment({ taskId, comment }) {
11325
+ return request(`https://api.clickup.com/api/v2/task/${encodeURIComponent(taskId)}/comment`, {
11326
+ method: "POST",
11327
+ body: JSON.stringify({ comment_text: String(comment || "") })
11328
+ });
11329
+ },
11300
11330
  async addTaskTag() {
11301
11331
  throw new Error("Optima runtime does not add ClickUp task tags; use local logs for process failures.");
11302
11332
  },
@@ -11338,9 +11368,21 @@ function createTestClickUpApiClient(config) {
11338
11368
  metadata.set(String(taskId || ""), value);
11339
11369
  return { ok: true };
11340
11370
  },
11371
+ async updateTask() {
11372
+ return { ok: true };
11373
+ },
11374
+ async updateTaskStatus() {
11375
+ return { ok: true };
11376
+ },
11377
+ async updateTaskAssignees() {
11378
+ return { ok: true };
11379
+ },
11341
11380
  async postTaskComment() {
11342
11381
  return { ok: true };
11343
11382
  },
11383
+ async postModelTaskComment() {
11384
+ return { ok: true };
11385
+ },
11344
11386
  async addTaskTag() {
11345
11387
  return { ok: true };
11346
11388
  },
@@ -11701,6 +11743,53 @@ function clickUpWebhookLifecycleLog(worktree, entry) {
11701
11743
  var activeClickUpWebhookListeners = /* @__PURE__ */ new Map();
11702
11744
  var activeClickUpWebhookLifecycleRegistry = /* @__PURE__ */ new Map();
11703
11745
  var activeClickUpTaskRoutes = /* @__PURE__ */ new Map();
11746
+ var CLICKUP_HUMAN_HANDOFF_TEXT_PATTERNS = [
11747
+ /\bhuman validation requested\b/i,
11748
+ /\bhuman validation\/approval\b/i,
11749
+ /\bplease review pr\b/i,
11750
+ /\bapprove or request changes\b/i,
11751
+ /\bCTO\/PO\b/i,
11752
+ /\bBloqueo externo\b/i,
11753
+ /\bQué necesito de CTO\/PO\b/i,
11754
+ /\bCómo se desbloquea\b/i
11755
+ ];
11756
+ function clickUpCommentCollectionText(response = {}) {
11757
+ return clickUpCommentListItems(response).map((comment) => clickUpCommentText(comment)).filter(Boolean).join("\n\n");
11758
+ }
11759
+ function hasClickUpHumanHandoffText(text = "") {
11760
+ const value = String(text || "");
11761
+ return value.length > 0 && CLICKUP_HUMAN_HANDOFF_TEXT_PATTERNS.some((pattern) => pattern.test(value));
11762
+ }
11763
+ function configuredHumanRoleAssigneeIds(config = {}) {
11764
+ const roleIds = config.routing?.humanRoleClickUpIds || {};
11765
+ return [...new Set(["CTO", "PO"].map((role) => String(roleIds[role] || "").trim()).filter(Boolean))];
11766
+ }
11767
+ async function selfHealClickUpHumanHandoffAssignment({ clickupClient, config, worktree = process.cwd(), taskId, task, commentsResponse = null } = {}) {
11768
+ const productManagerAssigneeId = String(config?.routing?.productManagerAssigneeId || "").trim();
11769
+ if (!taskId || !productManagerAssigneeId || !isClickUpTaskAssignedToProductManager(task, productManagerAssigneeId)) return { changed: false, reason: "not_pm_assigned" };
11770
+ if (typeof clickupClient?.updateTaskAssignees !== "function") return { changed: false, reason: "assignee_update_unavailable" };
11771
+ const humanAssigneeIds = configuredHumanRoleAssigneeIds(config);
11772
+ if (humanAssigneeIds.length === 0) return { changed: false, reason: "missing_human_role_ids" };
11773
+ let candidateText = "";
11774
+ if (commentsResponse) candidateText = clickUpCommentCollectionText(commentsResponse);
11775
+ if (!candidateText && typeof clickupClient?.getTaskComments === "function") {
11776
+ try {
11777
+ const response = await clickupClient.getTaskComments({ taskId, limit: CLICKUP_WEBHOOK_STARTUP_COMMENT_LIMIT });
11778
+ candidateText = clickUpCommentCollectionText(response);
11779
+ } catch (error) {
11780
+ appendClickUpWebhookLocalLog(worktree, { type: "human_handoff_comment_scan_failed", taskId, message: error.message });
11781
+ }
11782
+ }
11783
+ if (!hasClickUpHumanHandoffText(candidateText)) return { changed: false, reason: "no_human_handoff_signal" };
11784
+ try {
11785
+ await clickupClient.updateTaskAssignees({ taskId, add: humanAssigneeIds, remove: [productManagerAssigneeId] });
11786
+ appendClickUpWebhookLocalLog(worktree, { type: "human_handoff_assignment_self_healed", taskId, add: humanAssigneeIds, remove: [productManagerAssigneeId] });
11787
+ return { changed: true, reason: "human_handoff_assignment_self_healed", add: humanAssigneeIds, remove: [productManagerAssigneeId] };
11788
+ } catch (error) {
11789
+ appendClickUpWebhookLocalLog(worktree, { type: "human_handoff_assignment_self_heal_failed", taskId, add: humanAssigneeIds, remove: [productManagerAssigneeId], message: error.message });
11790
+ return { changed: false, reason: "assignee_update_failed", message: error.message };
11791
+ }
11792
+ }
11704
11793
  async function ensureClickUpTaskWorktreeForWebhook({ opencodeBaseUrl = "", opencodeBaseUrlConfigured = false, openchamberBaseUrl = "", openchamberBaseUrlConfigured = false, clickupClient = null, webhookWorktree = process.cwd(), fetchImpl = globalThis.fetch, ...options } = {}) {
11705
11794
  void opencodeBaseUrlConfigured;
11706
11795
  if (!openchamberBaseUrlConfigured || !openchamberBaseUrl) return ensureClickUpTaskWorktree(options);
@@ -12090,13 +12179,13 @@ function formatClickUpWebhookPrompt({ eventType, taskId, payload, branch = "", w
12090
12179
  branch ? `Branch: ${branch}` : null,
12091
12180
  worktree ? `Worktree: ${worktree}` : null,
12092
12181
  deliveryEvidencePath ? `Delivery evidence path: ${deliveryEvidencePath}` : null,
12093
- humanRoleLines ? "Human role fallback registry (Optima-provided; non-blocking if repo docs/core/humans.md is missing):" : null,
12182
+ humanRoleLines ? "Internal human role context for silent CTO/PO assignment decisions:" : null,
12094
12183
  humanRoleLines || null,
12095
12184
  commentText ? `Comment: ${commentText}` : null,
12096
12185
  "",
12097
12186
  "Handle this ClickUp Product Manager event using the ClickUp-first workflow rules. Do not assume broad chat routing; this event passed Optima webhook gates.",
12098
- "If local/subagent attempts are exhausted and the blocker is missing credentials, permissions, authenticated browser/Agent Jake access, external tools, or live third-party access, post the concrete help request in castellano using sections ## Bloqueo externo, ### Qu\xE9 he intentado, ### Qu\xE9 necesito de CTO/PO, and ### C\xF3mo se desbloquea; then assign CTO/PO using fallback registry IDs, remove the Product Manager assignee, and stop re-queueing Product Manager until a human replies or reassigns the task. Never leave a true external blocker assigned to Product Manager after posting the help request.",
12099
- "If the task worktree lacks docs/core/humans.md, use the Optima-provided human role fallback registry above instead of blocking solely on that missing file.",
12187
+ "If local/subagent attempts are exhausted and the blocker is missing credentials, permissions, authenticated browser/Agent Jake access, external tools, or live third-party access, post the concrete help request in castellano using sections ## Bloqueo externo, ### Qu\xE9 he intentado, ### Qu\xE9 necesito de CTO/PO, and ### C\xF3mo se desbloquea; then assign CTO/PO using the internal role context/configured IDs, remove the Product Manager assignee, and stop re-queueing Product Manager until a human replies or reassigns the task. Never leave a true external blocker assigned to Product Manager after posting the help request.",
12188
+ "Use internal human role context silently. Do not mention internal role-resolution details in ClickUp comments unless a human explicitly asks for routing diagnostics.",
12100
12189
  deliveryEvidencePath ? `Final merge-trackable evidence must be written under ${deliveryEvidencePath}; use .optima only as local mirror/staging.` : null
12101
12190
  ].filter((part) => part !== null).join("\n");
12102
12191
  }
@@ -12525,6 +12614,12 @@ async function reconcileClickUpStartup({ config, state = {}, worktree = process.
12525
12614
  routed.ignored += 1;
12526
12615
  continue;
12527
12616
  }
12617
+ const humanHandoffSelfHeal = await selfHealClickUpHumanHandoffAssignment({ clickupClient, config, worktree, taskId, task });
12618
+ if (humanHandoffSelfHeal.changed) {
12619
+ routed.ignored += 1;
12620
+ routed.tasks.push({ taskId, action: "self_healed_human_handoff_assignment", ok: true, sessionId: null, branch: null, worktree: null, verification: humanHandoffSelfHeal.reason, delivered: false });
12621
+ continue;
12622
+ }
12528
12623
  if (watchdogMode) {
12529
12624
  const existingMetadata = clickUpTaskAgentMetadata(task, config.routing.metadataFieldId);
12530
12625
  const metadata = normalizeAgentMetadataJson(existingMetadata);
@@ -14181,6 +14276,55 @@ async function OptimaPlugin(input = {}, pluginOptions = {}) {
14181
14276
  }
14182
14277
  return { ok: true, auth };
14183
14278
  };
14279
+ const finishClickUpTask = async ({ taskId, finishType = "", finalStatus = "", comment = "", prUrl = "", evidencePath = "" } = {}) => {
14280
+ if (!clickUpWebhookValidation.complete) return { ok: false, error: "clickup_not_configured" };
14281
+ if (!runtimeClickUpClient?.getTask) return { ok: false, error: "clickup_client_unavailable" };
14282
+ const normalizedTaskId = String(taskId || "").trim();
14283
+ if (!normalizedTaskId) return { ok: false, error: "task_id_required" };
14284
+ const normalizedFinishType = String(finishType || "").trim().toLowerCase().replace(/[\s-]+/g, "_");
14285
+ const inferredStatus = normalizedFinishType === "external_blocker" ? "in progress" : normalizedFinishType === "human_validation" ? "validation" : normalizedFinishType === "completed" ? "completed" : "";
14286
+ const status = String(finalStatus || inferredStatus || "").trim();
14287
+ const routing = clickUpWebhookValidation.config.routing || {};
14288
+ const productManagerAssigneeId = String(routing.productManagerAssigneeId || "").trim();
14289
+ const humanAssignees = ["CTO", "PO"].map((role) => String(routing.humanRoleClickUpIds?.[role] || "").trim()).filter(Boolean);
14290
+ const addAssignees = ["external_blocker", "human_validation"].includes(normalizedFinishType) ? humanAssignees : [];
14291
+ const removeAssignees = ["external_blocker", "human_validation", "completed"].includes(normalizedFinishType) && productManagerAssigneeId ? [productManagerAssigneeId] : [];
14292
+ const task = await runtimeClickUpClient.getTask(normalizedTaskId);
14293
+ const currentAssignees = clickUpAssigneeIds(task);
14294
+ const assignmentDelta = {
14295
+ add: [...new Set(addAssignees.filter((id) => !currentAssignees.includes(id)))],
14296
+ remove: [...new Set(removeAssignees.filter((id) => currentAssignees.includes(id)))]
14297
+ };
14298
+ const applied = [];
14299
+ if (status && runtimeClickUpClient.updateTaskStatus) {
14300
+ await runtimeClickUpClient.updateTaskStatus({ taskId: normalizedTaskId, status });
14301
+ applied.push("status");
14302
+ }
14303
+ if ((assignmentDelta.add.length > 0 || assignmentDelta.remove.length > 0) && runtimeClickUpClient.updateTaskAssignees) {
14304
+ await runtimeClickUpClient.updateTaskAssignees({ taskId: normalizedTaskId, add: assignmentDelta.add, remove: assignmentDelta.remove });
14305
+ applied.push("assignees");
14306
+ }
14307
+ const normalizedComment = String(comment || "").replace(/\\r\\n/g, "\n").replace(/\\n/g, "\n").trim();
14308
+ const commentWithContext = [
14309
+ normalizedComment,
14310
+ prUrl ? `
14311
+ PR: ${prUrl}` : "",
14312
+ evidencePath ? `
14313
+ Evidencia: ${evidencePath}` : ""
14314
+ ].join("").trim();
14315
+ if (commentWithContext && runtimeClickUpClient.postModelTaskComment) {
14316
+ await runtimeClickUpClient.postModelTaskComment({ taskId: normalizedTaskId, comment: commentWithContext });
14317
+ applied.push("comment");
14318
+ }
14319
+ return {
14320
+ ok: true,
14321
+ taskId: normalizedTaskId,
14322
+ finishType: normalizedFinishType || "status_update",
14323
+ status: status || null,
14324
+ assignmentDelta,
14325
+ applied
14326
+ };
14327
+ };
14184
14328
  const tools = {
14185
14329
  optima_init: tool({
14186
14330
  description: "Initialize the Optima workflow and CodeMap in the current repository",
@@ -14395,6 +14539,32 @@ Restart or reload OpenCode manually if the newly scaffolded config or agents are
14395
14539
  return JSON.stringify(payload, null, 2);
14396
14540
  }
14397
14541
  }),
14542
+ optima_finish: tool({
14543
+ description: "Finish or hand off a ClickUp task through Optima. The model provides structured ClickUp text and intended final state; Optima applies status, comment, and assignment policy.",
14544
+ args: {
14545
+ task_id: tool.schema.string().describe("ClickUp task ID to finish or hand off"),
14546
+ finish_type: tool.schema.string().describe("One of: completed, human_validation, external_blocker, needs_work, status_update"),
14547
+ final_status: tool.schema.string().describe("Optional ClickUp status to set. If empty, Optima infers from finish_type where possible."),
14548
+ clickup_comment: tool.schema.string().describe("Human-facing structured ClickUp comment text with real line breaks. Use castellano for blocker/help comments."),
14549
+ pr_url: tool.schema.string().describe("Optional GitHub PR URL to include in the final ClickUp comment"),
14550
+ evidence_path: tool.schema.string().describe("Optional evidence path to include in the final ClickUp comment")
14551
+ },
14552
+ async execute(args) {
14553
+ try {
14554
+ const result = await finishClickUpTask({
14555
+ taskId: args.task_id,
14556
+ finishType: args.finish_type,
14557
+ finalStatus: args.final_status,
14558
+ comment: args.clickup_comment,
14559
+ prUrl: args.pr_url,
14560
+ evidencePath: args.evidence_path
14561
+ });
14562
+ return JSON.stringify(result, null, 2);
14563
+ } catch (error) {
14564
+ return JSON.stringify({ ok: false, error: error.message }, null, 2);
14565
+ }
14566
+ }
14567
+ }),
14398
14568
  optima_clickup_create_subtasks: tool({
14399
14569
  description: "Generate dry-run ClickUp subtask creation payloads from a strict Markdown ## Subtasks section",
14400
14570
  args: {
@@ -14963,7 +15133,7 @@ Follow-up: use optima_prompt_workflow with session_id '${sessionId}' to check in
14963
15133
  }
14964
15134
  };
14965
15135
  }
14966
- OptimaPlugin.__internals = { BUNDLE_AGENTS_DIR, BUNDLE_ASSETS_DIR, CLICKUP_DEFINITION_DOC_PARENT, activeClickUpWebhookLifecycleRegistry, cleanupManagedClickUpWebhook, deleteClickUpWebhookBestEffort, BUNDLE_POLICIES_DIR, buildClickUpApplyPayloadResult, buildClickUpCreateSubtasksPayload, buildClickUpReviewAutomationPlan, buildClickUpStartTaskPayload, buildClickUpSummaryPayload, buildClickUpTransitionPayload, buildOptimaAgents, clickUpCommentLedgerKey, clickUpCommentMentionsProductManager, clickUpWebhookAuditLogDir, clickUpWebhookAuditLogPath, compactPromptPath, createClickUpApiClient, createGitHubApiClient, createTestClickUpApiClient, createOpenCodeSession, createOpenCodeSessionControl, deliveryEvidencePathForClickUpTask, ensureClickUpTaskWorktree, ensureClickUpTaskWorktreeForWebhook, ensureClickUpTaskWorktreeOpenChamber, ensureClickUpWebhookSubscription, gitHubPullRequestContextFromPayload, gitHubWebhookExpectedPath, handleClickUpWebhookRequest, handleGitHubWebhookRequest, inspectOpenCodeSessionActivity, isClickUpDerivedWorktreeSibling, isClickUpSubtaskRoute, isClickUpWebhookStateActive, isSameOrNestedPath, normalizeClickUpWebhookConfig, normalizeClickUpWebhookLogLevel, normalizeOpenCodeBaseUrl, openCodeSessionExists, promptOpenCodeSessionControl, probeOpenCodeSessionControl, readClickUpCommentLedger, readClickUpWebhookState, readOpenCodeSessionControl, readOpenCodeSessionMessages, reconcileClickUpStartup, registerOpenChamberClickUpWorktree, routeGitHubWebhookEvent, scheduleClickUpAssignmentWatchdog, scheduleClickUpStartupReconciliation, syncOpenChamberWorktreeVisibility, waitForOpenCodeReadiness, recordClickUpCommentVersionProcessed, resyncClickUpWebhookForSignatureDrift, resolveIncludeFile, resolveIncludes, resolveOptimaPluginOptions, resolveSecretReference, routeClickUpWebhookEvent, sendOpenCodeSessionEvent, sendOpenCodeSessionEventDirect, summarizeOpenCodeMessages, verifyOpenCodeSessionEventDelivery, stableClickUpCommentVersionMarker, startClickUpWebhookListener, validateClickUpWebhookState, verifyClickUpSignature, verifyGitHubSignature, writeClickUpWebhookState, decideClickUpStatusAction, deriveClickUpBranchName, deriveClickUpPendingSubtaskBranch, deriveClickUpPrTarget, deriveClickUpRequiredPullRequest, deriveClickUpWorktree, determineClickUpMergeAuthority, ensureOptimaGitignoreRules, explicitSafeInputWorktree, finalApprovalAssignees, formatRepairResult, formatValidationResult, isIgnoredClickUpTaskType, isOptimaPluginPackageWorktree, isSafeWritableDirectory, loadHumansRegistry, mergeClickUpAgentMetadata, mergeClickUpSessionMetadata, migrateLegacyOptimaLayout, normalizeAgentMetadataJson, normalizeClickUpStatus, normalizeClickUpTaskType, normalizePromptResponseParts, normalizeWorkflowTaskPath, optimaRepairDependencies, parseClickUpSubtasksMarkdown, parseHumansRegistry, parseMarkdownArtifact, parseMarkdownSections, planOptimaRepair, preEstimateClickUpWork, readMarkdownArtifact, resolveHumanRoles, resolveSafeWorktree, safeWorktreeOrFailure, stripRawLogSections, validateMainWorkspaceBranchSafety, workflowFinalMessageFromPromptResponse };
15136
+ OptimaPlugin.__internals = { BUNDLE_AGENTS_DIR, BUNDLE_ASSETS_DIR, CLICKUP_DEFINITION_DOC_PARENT, activeClickUpWebhookLifecycleRegistry, cleanupManagedClickUpWebhook, deleteClickUpWebhookBestEffort, BUNDLE_POLICIES_DIR, buildClickUpApplyPayloadResult, buildClickUpCreateSubtasksPayload, buildClickUpReviewAutomationPlan, buildClickUpStartTaskPayload, buildClickUpSummaryPayload, buildClickUpTransitionPayload, buildOptimaAgents, clickUpCommentLedgerKey, clickUpCommentMentionsProductManager, clickUpWebhookAuditLogDir, clickUpWebhookAuditLogPath, compactPromptPath, createClickUpApiClient, createGitHubApiClient, createTestClickUpApiClient, createOpenCodeSession, createOpenCodeSessionControl, deliveryEvidencePathForClickUpTask, ensureClickUpTaskWorktree, ensureClickUpTaskWorktreeForWebhook, ensureClickUpTaskWorktreeOpenChamber, ensureClickUpWebhookSubscription, gitHubPullRequestContextFromPayload, gitHubWebhookExpectedPath, handleClickUpWebhookRequest, handleGitHubWebhookRequest, inspectOpenCodeSessionActivity, isClickUpDerivedWorktreeSibling, isClickUpSubtaskRoute, isClickUpWebhookStateActive, isSameOrNestedPath, normalizeClickUpWebhookConfig, normalizeClickUpWebhookLogLevel, normalizeOpenCodeBaseUrl, openCodeSessionExists, promptOpenCodeSessionControl, probeOpenCodeSessionControl, readClickUpCommentLedger, readClickUpWebhookState, readOpenCodeSessionControl, readOpenCodeSessionMessages, reconcileClickUpStartup, registerOpenChamberClickUpWorktree, routeGitHubWebhookEvent, scheduleClickUpAssignmentWatchdog, selfHealClickUpHumanHandoffAssignment, scheduleClickUpStartupReconciliation, syncOpenChamberWorktreeVisibility, waitForOpenCodeReadiness, recordClickUpCommentVersionProcessed, resyncClickUpWebhookForSignatureDrift, resolveIncludeFile, resolveIncludes, resolveOptimaPluginOptions, resolveSecretReference, routeClickUpWebhookEvent, sendOpenCodeSessionEvent, sendOpenCodeSessionEventDirect, summarizeOpenCodeMessages, verifyOpenCodeSessionEventDelivery, stableClickUpCommentVersionMarker, startClickUpWebhookListener, validateClickUpWebhookState, verifyClickUpSignature, verifyGitHubSignature, writeClickUpWebhookState, decideClickUpStatusAction, deriveClickUpBranchName, deriveClickUpPendingSubtaskBranch, deriveClickUpPrTarget, deriveClickUpRequiredPullRequest, deriveClickUpWorktree, determineClickUpMergeAuthority, ensureOptimaGitignoreRules, explicitSafeInputWorktree, finalApprovalAssignees, formatRepairResult, formatValidationResult, isIgnoredClickUpTaskType, isOptimaPluginPackageWorktree, isSafeWritableDirectory, loadHumansRegistry, mergeClickUpAgentMetadata, mergeClickUpSessionMetadata, migrateLegacyOptimaLayout, normalizeAgentMetadataJson, normalizeClickUpStatus, normalizeClickUpTaskType, normalizePromptResponseParts, normalizeWorkflowTaskPath, optimaRepairDependencies, parseClickUpSubtasksMarkdown, parseHumansRegistry, parseMarkdownArtifact, parseMarkdownSections, planOptimaRepair, preEstimateClickUpWork, readMarkdownArtifact, resolveHumanRoles, resolveSafeWorktree, safeWorktreeOrFailure, stripRawLogSections, validateMainWorkspaceBranchSafety, workflowFinalMessageFromPromptResponse };
14967
15137
  export {
14968
15138
  OptimaPlugin as default
14969
15139
  };
@@ -10990,11 +10990,11 @@ ${additionFragment}`;
10990
10990
  if (humanRoleLines) {
10991
10991
  agentConfig.prompt = `${agentConfig.prompt}
10992
10992
 
10993
- ## Optima Human Role Fallback Registry
10993
+ ## Optima Internal Human Role Context
10994
10994
 
10995
10995
  ${humanRoleLines}
10996
10996
 
10997
- Use this Optima-provided fallback when the current task worktree lacks docs/core/humans.md; missing repo-local humans.md is not a hard blocker when this context or configured ClickUp IDs are present.`;
10997
+ Use this internal context silently for CTO/PO assignment decisions. Do not mention internal role-resolution details in ClickUp comments unless a human explicitly asks for routing diagnostics.`;
10998
10998
  }
10999
10999
  }
11000
11000
  ourAgents[id] = agentConfig;
@@ -11295,15 +11295,45 @@ function createClickUpApiClient(config, fetchImpl = globalThis.fetch) {
11295
11295
  async getTask(taskId) {
11296
11296
  return request(`https://api.clickup.com/api/v2/task/${encodeURIComponent(taskId)}`);
11297
11297
  },
11298
+ async updateTask({ taskId, updates = {} }) {
11299
+ return request(`https://api.clickup.com/api/v2/task/${encodeURIComponent(taskId)}`, {
11300
+ method: "PUT",
11301
+ body: JSON.stringify(updates)
11302
+ });
11303
+ },
11304
+ async updateTaskStatus({ taskId, status }) {
11305
+ return request(`https://api.clickup.com/api/v2/task/${encodeURIComponent(taskId)}`, {
11306
+ method: "PUT",
11307
+ body: JSON.stringify({ status })
11308
+ });
11309
+ },
11298
11310
  async updateTaskMetadata({ taskId, fieldId, value }) {
11299
11311
  return request(`https://api.clickup.com/api/v2/task/${encodeURIComponent(taskId)}/field/${encodeURIComponent(fieldId)}`, {
11300
11312
  method: "POST",
11301
11313
  body: JSON.stringify({ value })
11302
11314
  });
11303
11315
  },
11316
+ async updateTaskAssignees({ taskId, add = [], remove = [] }) {
11317
+ const body = { assignees: {} };
11318
+ const addIds = [...new Set((add || []).map((id) => String(id || "").trim()).filter(Boolean))];
11319
+ const removeIds = [...new Set((remove || []).map((id) => String(id || "").trim()).filter(Boolean))];
11320
+ if (addIds.length > 0) body.assignees.add = addIds;
11321
+ if (removeIds.length > 0) body.assignees.rem = removeIds;
11322
+ if (!body.assignees.add && !body.assignees.rem) return { ok: true, skipped: true, reason: "empty_assignee_update" };
11323
+ return request(`https://api.clickup.com/api/v2/task/${encodeURIComponent(taskId)}`, {
11324
+ method: "PUT",
11325
+ body: JSON.stringify(body)
11326
+ });
11327
+ },
11304
11328
  async postTaskComment() {
11305
11329
  throw new Error("Optima runtime does not post ClickUp task comments; use local logs for process failures.");
11306
11330
  },
11331
+ async postModelTaskComment({ taskId, comment }) {
11332
+ return request(`https://api.clickup.com/api/v2/task/${encodeURIComponent(taskId)}/comment`, {
11333
+ method: "POST",
11334
+ body: JSON.stringify({ comment_text: String(comment || "") })
11335
+ });
11336
+ },
11307
11337
  async addTaskTag() {
11308
11338
  throw new Error("Optima runtime does not add ClickUp task tags; use local logs for process failures.");
11309
11339
  },
@@ -11345,9 +11375,21 @@ function createTestClickUpApiClient(config) {
11345
11375
  metadata.set(String(taskId || ""), value);
11346
11376
  return { ok: true };
11347
11377
  },
11378
+ async updateTask() {
11379
+ return { ok: true };
11380
+ },
11381
+ async updateTaskStatus() {
11382
+ return { ok: true };
11383
+ },
11384
+ async updateTaskAssignees() {
11385
+ return { ok: true };
11386
+ },
11348
11387
  async postTaskComment() {
11349
11388
  return { ok: true };
11350
11389
  },
11390
+ async postModelTaskComment() {
11391
+ return { ok: true };
11392
+ },
11351
11393
  async addTaskTag() {
11352
11394
  return { ok: true };
11353
11395
  },
@@ -11708,6 +11750,53 @@ function clickUpWebhookLifecycleLog(worktree, entry) {
11708
11750
  var activeClickUpWebhookListeners = /* @__PURE__ */ new Map();
11709
11751
  var activeClickUpWebhookLifecycleRegistry = /* @__PURE__ */ new Map();
11710
11752
  var activeClickUpTaskRoutes = /* @__PURE__ */ new Map();
11753
+ var CLICKUP_HUMAN_HANDOFF_TEXT_PATTERNS = [
11754
+ /\bhuman validation requested\b/i,
11755
+ /\bhuman validation\/approval\b/i,
11756
+ /\bplease review pr\b/i,
11757
+ /\bapprove or request changes\b/i,
11758
+ /\bCTO\/PO\b/i,
11759
+ /\bBloqueo externo\b/i,
11760
+ /\bQué necesito de CTO\/PO\b/i,
11761
+ /\bCómo se desbloquea\b/i
11762
+ ];
11763
+ function clickUpCommentCollectionText(response = {}) {
11764
+ return clickUpCommentListItems(response).map((comment) => clickUpCommentText(comment)).filter(Boolean).join("\n\n");
11765
+ }
11766
+ function hasClickUpHumanHandoffText(text = "") {
11767
+ const value = String(text || "");
11768
+ return value.length > 0 && CLICKUP_HUMAN_HANDOFF_TEXT_PATTERNS.some((pattern) => pattern.test(value));
11769
+ }
11770
+ function configuredHumanRoleAssigneeIds(config = {}) {
11771
+ const roleIds = config.routing?.humanRoleClickUpIds || {};
11772
+ return [...new Set(["CTO", "PO"].map((role) => String(roleIds[role] || "").trim()).filter(Boolean))];
11773
+ }
11774
+ async function selfHealClickUpHumanHandoffAssignment({ clickupClient, config, worktree = process.cwd(), taskId, task, commentsResponse = null } = {}) {
11775
+ const productManagerAssigneeId = String(config?.routing?.productManagerAssigneeId || "").trim();
11776
+ if (!taskId || !productManagerAssigneeId || !isClickUpTaskAssignedToProductManager(task, productManagerAssigneeId)) return { changed: false, reason: "not_pm_assigned" };
11777
+ if (typeof clickupClient?.updateTaskAssignees !== "function") return { changed: false, reason: "assignee_update_unavailable" };
11778
+ const humanAssigneeIds = configuredHumanRoleAssigneeIds(config);
11779
+ if (humanAssigneeIds.length === 0) return { changed: false, reason: "missing_human_role_ids" };
11780
+ let candidateText = "";
11781
+ if (commentsResponse) candidateText = clickUpCommentCollectionText(commentsResponse);
11782
+ if (!candidateText && typeof clickupClient?.getTaskComments === "function") {
11783
+ try {
11784
+ const response = await clickupClient.getTaskComments({ taskId, limit: CLICKUP_WEBHOOK_STARTUP_COMMENT_LIMIT });
11785
+ candidateText = clickUpCommentCollectionText(response);
11786
+ } catch (error) {
11787
+ appendClickUpWebhookLocalLog(worktree, { type: "human_handoff_comment_scan_failed", taskId, message: error.message });
11788
+ }
11789
+ }
11790
+ if (!hasClickUpHumanHandoffText(candidateText)) return { changed: false, reason: "no_human_handoff_signal" };
11791
+ try {
11792
+ await clickupClient.updateTaskAssignees({ taskId, add: humanAssigneeIds, remove: [productManagerAssigneeId] });
11793
+ appendClickUpWebhookLocalLog(worktree, { type: "human_handoff_assignment_self_healed", taskId, add: humanAssigneeIds, remove: [productManagerAssigneeId] });
11794
+ return { changed: true, reason: "human_handoff_assignment_self_healed", add: humanAssigneeIds, remove: [productManagerAssigneeId] };
11795
+ } catch (error) {
11796
+ appendClickUpWebhookLocalLog(worktree, { type: "human_handoff_assignment_self_heal_failed", taskId, add: humanAssigneeIds, remove: [productManagerAssigneeId], message: error.message });
11797
+ return { changed: false, reason: "assignee_update_failed", message: error.message };
11798
+ }
11799
+ }
11711
11800
  async function ensureClickUpTaskWorktreeForWebhook({ opencodeBaseUrl = "", opencodeBaseUrlConfigured = false, openchamberBaseUrl = "", openchamberBaseUrlConfigured = false, clickupClient = null, webhookWorktree = process.cwd(), fetchImpl = globalThis.fetch, ...options } = {}) {
11712
11801
  void opencodeBaseUrlConfigured;
11713
11802
  if (!openchamberBaseUrlConfigured || !openchamberBaseUrl) return ensureClickUpTaskWorktree(options);
@@ -12097,13 +12186,13 @@ function formatClickUpWebhookPrompt({ eventType, taskId, payload, branch = "", w
12097
12186
  branch ? `Branch: ${branch}` : null,
12098
12187
  worktree ? `Worktree: ${worktree}` : null,
12099
12188
  deliveryEvidencePath ? `Delivery evidence path: ${deliveryEvidencePath}` : null,
12100
- humanRoleLines ? "Human role fallback registry (Optima-provided; non-blocking if repo docs/core/humans.md is missing):" : null,
12189
+ humanRoleLines ? "Internal human role context for silent CTO/PO assignment decisions:" : null,
12101
12190
  humanRoleLines || null,
12102
12191
  commentText ? `Comment: ${commentText}` : null,
12103
12192
  "",
12104
12193
  "Handle this ClickUp Product Manager event using the ClickUp-first workflow rules. Do not assume broad chat routing; this event passed Optima webhook gates.",
12105
- "If local/subagent attempts are exhausted and the blocker is missing credentials, permissions, authenticated browser/Agent Jake access, external tools, or live third-party access, post the concrete help request in castellano using sections ## Bloqueo externo, ### Qu\xE9 he intentado, ### Qu\xE9 necesito de CTO/PO, and ### C\xF3mo se desbloquea; then assign CTO/PO using fallback registry IDs, remove the Product Manager assignee, and stop re-queueing Product Manager until a human replies or reassigns the task. Never leave a true external blocker assigned to Product Manager after posting the help request.",
12106
- "If the task worktree lacks docs/core/humans.md, use the Optima-provided human role fallback registry above instead of blocking solely on that missing file.",
12194
+ "If local/subagent attempts are exhausted and the blocker is missing credentials, permissions, authenticated browser/Agent Jake access, external tools, or live third-party access, post the concrete help request in castellano using sections ## Bloqueo externo, ### Qu\xE9 he intentado, ### Qu\xE9 necesito de CTO/PO, and ### C\xF3mo se desbloquea; then assign CTO/PO using the internal role context/configured IDs, remove the Product Manager assignee, and stop re-queueing Product Manager until a human replies or reassigns the task. Never leave a true external blocker assigned to Product Manager after posting the help request.",
12195
+ "Use internal human role context silently. Do not mention internal role-resolution details in ClickUp comments unless a human explicitly asks for routing diagnostics.",
12107
12196
  deliveryEvidencePath ? `Final merge-trackable evidence must be written under ${deliveryEvidencePath}; use .optima only as local mirror/staging.` : null
12108
12197
  ].filter((part) => part !== null).join("\n");
12109
12198
  }
@@ -12532,6 +12621,12 @@ async function reconcileClickUpStartup({ config, state = {}, worktree = process.
12532
12621
  routed.ignored += 1;
12533
12622
  continue;
12534
12623
  }
12624
+ const humanHandoffSelfHeal = await selfHealClickUpHumanHandoffAssignment({ clickupClient, config, worktree, taskId, task });
12625
+ if (humanHandoffSelfHeal.changed) {
12626
+ routed.ignored += 1;
12627
+ routed.tasks.push({ taskId, action: "self_healed_human_handoff_assignment", ok: true, sessionId: null, branch: null, worktree: null, verification: humanHandoffSelfHeal.reason, delivered: false });
12628
+ continue;
12629
+ }
12535
12630
  if (watchdogMode) {
12536
12631
  const existingMetadata = clickUpTaskAgentMetadata(task, config.routing.metadataFieldId);
12537
12632
  const metadata = normalizeAgentMetadataJson(existingMetadata);
@@ -14188,6 +14283,55 @@ async function OptimaPlugin(input = {}, pluginOptions = {}) {
14188
14283
  }
14189
14284
  return { ok: true, auth };
14190
14285
  };
14286
+ const finishClickUpTask = async ({ taskId, finishType = "", finalStatus = "", comment = "", prUrl = "", evidencePath = "" } = {}) => {
14287
+ if (!clickUpWebhookValidation.complete) return { ok: false, error: "clickup_not_configured" };
14288
+ if (!runtimeClickUpClient?.getTask) return { ok: false, error: "clickup_client_unavailable" };
14289
+ const normalizedTaskId = String(taskId || "").trim();
14290
+ if (!normalizedTaskId) return { ok: false, error: "task_id_required" };
14291
+ const normalizedFinishType = String(finishType || "").trim().toLowerCase().replace(/[\s-]+/g, "_");
14292
+ const inferredStatus = normalizedFinishType === "external_blocker" ? "in progress" : normalizedFinishType === "human_validation" ? "validation" : normalizedFinishType === "completed" ? "completed" : "";
14293
+ const status = String(finalStatus || inferredStatus || "").trim();
14294
+ const routing = clickUpWebhookValidation.config.routing || {};
14295
+ const productManagerAssigneeId = String(routing.productManagerAssigneeId || "").trim();
14296
+ const humanAssignees = ["CTO", "PO"].map((role) => String(routing.humanRoleClickUpIds?.[role] || "").trim()).filter(Boolean);
14297
+ const addAssignees = ["external_blocker", "human_validation"].includes(normalizedFinishType) ? humanAssignees : [];
14298
+ const removeAssignees = ["external_blocker", "human_validation", "completed"].includes(normalizedFinishType) && productManagerAssigneeId ? [productManagerAssigneeId] : [];
14299
+ const task = await runtimeClickUpClient.getTask(normalizedTaskId);
14300
+ const currentAssignees = clickUpAssigneeIds(task);
14301
+ const assignmentDelta = {
14302
+ add: [...new Set(addAssignees.filter((id) => !currentAssignees.includes(id)))],
14303
+ remove: [...new Set(removeAssignees.filter((id) => currentAssignees.includes(id)))]
14304
+ };
14305
+ const applied = [];
14306
+ if (status && runtimeClickUpClient.updateTaskStatus) {
14307
+ await runtimeClickUpClient.updateTaskStatus({ taskId: normalizedTaskId, status });
14308
+ applied.push("status");
14309
+ }
14310
+ if ((assignmentDelta.add.length > 0 || assignmentDelta.remove.length > 0) && runtimeClickUpClient.updateTaskAssignees) {
14311
+ await runtimeClickUpClient.updateTaskAssignees({ taskId: normalizedTaskId, add: assignmentDelta.add, remove: assignmentDelta.remove });
14312
+ applied.push("assignees");
14313
+ }
14314
+ const normalizedComment = String(comment || "").replace(/\\r\\n/g, "\n").replace(/\\n/g, "\n").trim();
14315
+ const commentWithContext = [
14316
+ normalizedComment,
14317
+ prUrl ? `
14318
+ PR: ${prUrl}` : "",
14319
+ evidencePath ? `
14320
+ Evidencia: ${evidencePath}` : ""
14321
+ ].join("").trim();
14322
+ if (commentWithContext && runtimeClickUpClient.postModelTaskComment) {
14323
+ await runtimeClickUpClient.postModelTaskComment({ taskId: normalizedTaskId, comment: commentWithContext });
14324
+ applied.push("comment");
14325
+ }
14326
+ return {
14327
+ ok: true,
14328
+ taskId: normalizedTaskId,
14329
+ finishType: normalizedFinishType || "status_update",
14330
+ status: status || null,
14331
+ assignmentDelta,
14332
+ applied
14333
+ };
14334
+ };
14191
14335
  const tools = {
14192
14336
  optima_init: tool({
14193
14337
  description: "Initialize the Optima workflow and CodeMap in the current repository",
@@ -14402,6 +14546,32 @@ Restart or reload OpenCode manually if the newly scaffolded config or agents are
14402
14546
  return JSON.stringify(payload, null, 2);
14403
14547
  }
14404
14548
  }),
14549
+ optima_finish: tool({
14550
+ description: "Finish or hand off a ClickUp task through Optima. The model provides structured ClickUp text and intended final state; Optima applies status, comment, and assignment policy.",
14551
+ args: {
14552
+ task_id: tool.schema.string().describe("ClickUp task ID to finish or hand off"),
14553
+ finish_type: tool.schema.string().describe("One of: completed, human_validation, external_blocker, needs_work, status_update"),
14554
+ final_status: tool.schema.string().describe("Optional ClickUp status to set. If empty, Optima infers from finish_type where possible."),
14555
+ clickup_comment: tool.schema.string().describe("Human-facing structured ClickUp comment text with real line breaks. Use castellano for blocker/help comments."),
14556
+ pr_url: tool.schema.string().describe("Optional GitHub PR URL to include in the final ClickUp comment"),
14557
+ evidence_path: tool.schema.string().describe("Optional evidence path to include in the final ClickUp comment")
14558
+ },
14559
+ async execute(args) {
14560
+ try {
14561
+ const result = await finishClickUpTask({
14562
+ taskId: args.task_id,
14563
+ finishType: args.finish_type,
14564
+ finalStatus: args.final_status,
14565
+ comment: args.clickup_comment,
14566
+ prUrl: args.pr_url,
14567
+ evidencePath: args.evidence_path
14568
+ });
14569
+ return JSON.stringify(result, null, 2);
14570
+ } catch (error) {
14571
+ return JSON.stringify({ ok: false, error: error.message }, null, 2);
14572
+ }
14573
+ }
14574
+ }),
14405
14575
  optima_clickup_create_subtasks: tool({
14406
14576
  description: "Generate dry-run ClickUp subtask creation payloads from a strict Markdown ## Subtasks section",
14407
14577
  args: {
@@ -14970,7 +15140,7 @@ Follow-up: use optima_prompt_workflow with session_id '${sessionId}' to check in
14970
15140
  }
14971
15141
  };
14972
15142
  }
14973
- OptimaPlugin.__internals = { BUNDLE_AGENTS_DIR, BUNDLE_ASSETS_DIR, CLICKUP_DEFINITION_DOC_PARENT, activeClickUpWebhookLifecycleRegistry, cleanupManagedClickUpWebhook, deleteClickUpWebhookBestEffort, BUNDLE_POLICIES_DIR, buildClickUpApplyPayloadResult, buildClickUpCreateSubtasksPayload, buildClickUpReviewAutomationPlan, buildClickUpStartTaskPayload, buildClickUpSummaryPayload, buildClickUpTransitionPayload, buildOptimaAgents, clickUpCommentLedgerKey, clickUpCommentMentionsProductManager, clickUpWebhookAuditLogDir, clickUpWebhookAuditLogPath, compactPromptPath, createClickUpApiClient, createGitHubApiClient, createTestClickUpApiClient, createOpenCodeSession, createOpenCodeSessionControl, deliveryEvidencePathForClickUpTask, ensureClickUpTaskWorktree, ensureClickUpTaskWorktreeForWebhook, ensureClickUpTaskWorktreeOpenChamber, ensureClickUpWebhookSubscription, gitHubPullRequestContextFromPayload, gitHubWebhookExpectedPath, handleClickUpWebhookRequest, handleGitHubWebhookRequest, inspectOpenCodeSessionActivity, isClickUpDerivedWorktreeSibling, isClickUpSubtaskRoute, isClickUpWebhookStateActive, isSameOrNestedPath, normalizeClickUpWebhookConfig, normalizeClickUpWebhookLogLevel, normalizeOpenCodeBaseUrl, openCodeSessionExists, promptOpenCodeSessionControl, probeOpenCodeSessionControl, readClickUpCommentLedger, readClickUpWebhookState, readOpenCodeSessionControl, readOpenCodeSessionMessages, reconcileClickUpStartup, registerOpenChamberClickUpWorktree, routeGitHubWebhookEvent, scheduleClickUpAssignmentWatchdog, scheduleClickUpStartupReconciliation, syncOpenChamberWorktreeVisibility, waitForOpenCodeReadiness, recordClickUpCommentVersionProcessed, resyncClickUpWebhookForSignatureDrift, resolveIncludeFile, resolveIncludes, resolveOptimaPluginOptions, resolveSecretReference, routeClickUpWebhookEvent, sendOpenCodeSessionEvent, sendOpenCodeSessionEventDirect, summarizeOpenCodeMessages, verifyOpenCodeSessionEventDelivery, stableClickUpCommentVersionMarker, startClickUpWebhookListener, validateClickUpWebhookState, verifyClickUpSignature, verifyGitHubSignature, writeClickUpWebhookState, decideClickUpStatusAction, deriveClickUpBranchName, deriveClickUpPendingSubtaskBranch, deriveClickUpPrTarget, deriveClickUpRequiredPullRequest, deriveClickUpWorktree, determineClickUpMergeAuthority, ensureOptimaGitignoreRules, explicitSafeInputWorktree, finalApprovalAssignees, formatRepairResult, formatValidationResult, isIgnoredClickUpTaskType, isOptimaPluginPackageWorktree, isSafeWritableDirectory, loadHumansRegistry, mergeClickUpAgentMetadata, mergeClickUpSessionMetadata, migrateLegacyOptimaLayout, normalizeAgentMetadataJson, normalizeClickUpStatus, normalizeClickUpTaskType, normalizePromptResponseParts, normalizeWorkflowTaskPath, optimaRepairDependencies, parseClickUpSubtasksMarkdown, parseHumansRegistry, parseMarkdownArtifact, parseMarkdownSections, planOptimaRepair, preEstimateClickUpWork, readMarkdownArtifact, resolveHumanRoles, resolveSafeWorktree, safeWorktreeOrFailure, stripRawLogSections, validateMainWorkspaceBranchSafety, workflowFinalMessageFromPromptResponse };
15143
+ OptimaPlugin.__internals = { BUNDLE_AGENTS_DIR, BUNDLE_ASSETS_DIR, CLICKUP_DEFINITION_DOC_PARENT, activeClickUpWebhookLifecycleRegistry, cleanupManagedClickUpWebhook, deleteClickUpWebhookBestEffort, BUNDLE_POLICIES_DIR, buildClickUpApplyPayloadResult, buildClickUpCreateSubtasksPayload, buildClickUpReviewAutomationPlan, buildClickUpStartTaskPayload, buildClickUpSummaryPayload, buildClickUpTransitionPayload, buildOptimaAgents, clickUpCommentLedgerKey, clickUpCommentMentionsProductManager, clickUpWebhookAuditLogDir, clickUpWebhookAuditLogPath, compactPromptPath, createClickUpApiClient, createGitHubApiClient, createTestClickUpApiClient, createOpenCodeSession, createOpenCodeSessionControl, deliveryEvidencePathForClickUpTask, ensureClickUpTaskWorktree, ensureClickUpTaskWorktreeForWebhook, ensureClickUpTaskWorktreeOpenChamber, ensureClickUpWebhookSubscription, gitHubPullRequestContextFromPayload, gitHubWebhookExpectedPath, handleClickUpWebhookRequest, handleGitHubWebhookRequest, inspectOpenCodeSessionActivity, isClickUpDerivedWorktreeSibling, isClickUpSubtaskRoute, isClickUpWebhookStateActive, isSameOrNestedPath, normalizeClickUpWebhookConfig, normalizeClickUpWebhookLogLevel, normalizeOpenCodeBaseUrl, openCodeSessionExists, promptOpenCodeSessionControl, probeOpenCodeSessionControl, readClickUpCommentLedger, readClickUpWebhookState, readOpenCodeSessionControl, readOpenCodeSessionMessages, reconcileClickUpStartup, registerOpenChamberClickUpWorktree, routeGitHubWebhookEvent, scheduleClickUpAssignmentWatchdog, selfHealClickUpHumanHandoffAssignment, scheduleClickUpStartupReconciliation, syncOpenChamberWorktreeVisibility, waitForOpenCodeReadiness, recordClickUpCommentVersionProcessed, resyncClickUpWebhookForSignatureDrift, resolveIncludeFile, resolveIncludes, resolveOptimaPluginOptions, resolveSecretReference, routeClickUpWebhookEvent, sendOpenCodeSessionEvent, sendOpenCodeSessionEventDirect, summarizeOpenCodeMessages, verifyOpenCodeSessionEventDelivery, stableClickUpCommentVersionMarker, startClickUpWebhookListener, validateClickUpWebhookState, verifyClickUpSignature, verifyGitHubSignature, writeClickUpWebhookState, decideClickUpStatusAction, deriveClickUpBranchName, deriveClickUpPendingSubtaskBranch, deriveClickUpPrTarget, deriveClickUpRequiredPullRequest, deriveClickUpWorktree, determineClickUpMergeAuthority, ensureOptimaGitignoreRules, explicitSafeInputWorktree, finalApprovalAssignees, formatRepairResult, formatValidationResult, isIgnoredClickUpTaskType, isOptimaPluginPackageWorktree, isSafeWritableDirectory, loadHumansRegistry, mergeClickUpAgentMetadata, mergeClickUpSessionMetadata, migrateLegacyOptimaLayout, normalizeAgentMetadataJson, normalizeClickUpStatus, normalizeClickUpTaskType, normalizePromptResponseParts, normalizeWorkflowTaskPath, optimaRepairDependencies, parseClickUpSubtasksMarkdown, parseHumansRegistry, parseMarkdownArtifact, parseMarkdownSections, planOptimaRepair, preEstimateClickUpWork, readMarkdownArtifact, resolveHumanRoles, resolveSafeWorktree, safeWorktreeOrFailure, stripRawLogSections, validateMainWorkspaceBranchSafety, workflowFinalMessageFromPromptResponse };
14974
15144
 
14975
15145
  // src/sanitize_cli.js
14976
15146
  var { migrateLegacyOptimaLayout: migrateLegacyOptimaLayout2 } = OptimaPlugin.__internals;
@@ -21,7 +21,7 @@
21
21
 
22
22
  - `product_manager` may answer, investigate, operate dashboards, and pre-estimate "a qué huele" small/medium/large plus rough story points; WPM owns delivery routing.
23
23
  - Supported delivery task types are `Tarea`, `Bug`, `Doc`, and `PoC`; ignore `Idea`, legacy `Backlog` alias, `Hito`, `Nota de reunión`, and `Respuesta del formulario` unless converted or linked to delivery work.
24
- - Human role registry: resolve `CTO` and `PO` from `docs/core/humans.md` when present; if a task worktree lacks that file, use the Optima-provided human role fallback context and configured ClickUp IDs instead of blocking solely on the missing repo-local file. Use role identifiers in workflow text and automation config.
24
+ - Human role registry: resolve `CTO` and `PO` from available human role context and configured ClickUp IDs. Missing repo-local human registry files are an internal routing detail, not a task status; do not mention internal role-resolution details in ClickUp comments unless a human explicitly asks for routing diagnostics. Use role identifiers in workflow text and automation config.
25
25
  - Status actions are deterministic: `backlog` ignore, `plan` plan plus `Story Points`, test strategy, and `Definition`, `in progress` execute, `validation` split Tech Lead and Validator/QA gates, `merge` parent post-approval automation, and `completed`/`Closed` ignore unless reopened.
26
26
  - Human approval assignment is prohibited except for the strict allowlist: parent `plan` with clear questions already posted in ClickUp comments; `in progress` blocked by missing credentials, permissions, authenticated browser/Agent Jake access, external tools, or live third-party access after local/subagent attempts; or parent `validation` after `optima_github_verify_vercel_pr` returns `ready: true` for the current PR with a functional Vercel preproduction/preview URL. For true external `in progress` blockers, post the exact human action needed in castellano, assign CTO/PO in ClickUp, and remove Product Manager so PM watchdogs stop looping. Do not assign `CTO`/`PO` for generic handoff, routine validation, cleanup, subtask planning/validation, partial-phase stops, failed Vercel checks, or missing preview URLs.
27
27
  - Store ClickUp `agent_metadata` JSON with session IDs per agent/type/task/subtask; keep `Definition` as the plan contract and final Documentation as delivered behavior docs.
@@ -13,7 +13,7 @@
13
13
  - Routing comes from `docs/core/task_model.md`: `tiny` lightweight, `standard` bounded, `complex` decomposed; full mode supports all, mini mode refuses complex.
14
14
  - `product_manager` may answer/investigate/dashboard/pre-estimate "a qué huele" plus rough story points; development asks become routed ClickUp tasks.
15
15
  - ClickUp-first types: execute `Tarea`, `Bug`, `Doc`, `PoC`; ignore `Idea`, legacy `Backlog` alias, `Hito`, `Nota de reunión`, `Respuesta del formulario` unless converted/linked.
16
- - Human role registry: resolve `CTO` and `PO` from `docs/core/humans.md` when present; if missing in a task worktree, use Optima-provided fallback role context/configured ClickUp IDs instead of blocking solely on the missing file.
16
+ - Human role registry: resolve `CTO` and `PO` from available human role context/configured ClickUp IDs. Missing repo-local human registry files are internal routing detail; do not mention internal role-resolution details in ClickUp comments unless asked for routing diagnostics.
17
17
  - ClickUp-first statuses: `backlog` ignore, `plan` plan with `Story Points`, `Definition`, and test strategy; assign `CTO`/`PO` only for parent `plan` questions with clear ClickUp comments, real `in progress` blockers from missing credentials/tools/access/authenticated browser or Agent Jake/live third-party access after local/subagent attempts, or parent `validation` after `optima_github_verify_vercel_pr` returns `ready: true` with a functional Vercel URL. True external `in progress` blockers require a castellano ClickUp help request, CTO/PO assignment, and Product Manager removal; subtasks merge directly into the parent branch after Validator/QA passes without CTO/PO assignment; parent `Approved` comments trigger automation to remove humans, assign merge owner/self, merge to `dev`, clean workspaces/worktrees/branches, push, and ensure dev/preproduction receives the code; `completed`/`Closed` ignore unless reopened.
18
18
  - Shared-worktree rule: one active `implementation` task at a time; isolated `investigation`/`spec` may run in parallel if non-conflicting.
19
19
  - Git rules: principal workspace stays on `dev`, never `main`; parent branches use `<type>/<parent-id>`; subtask branches use non-nested `<type>/<parent-id>-subtask-<subtask-id>` and pending subtasks use `<type>/<parent-id>-pending-<title-slug>`; parent task pulls remote once at start; subtasks start from and PR to the parent local branch, bootstrapping the parent from `dev`/`origin/dev` first when missing; PoC branches stay `poc/<clickup-task-id>`; parents PR to `dev`, releases PR `dev` -> `main`; failed/conflicted subtask or parent merges return the affected item to `in progress` for the coding owner; no direct `main` pushes.
@@ -20,7 +20,7 @@
20
20
  - Human-readable task/evidence summaries, validation results, AC coverage, documentation impact, blockers, reopen history, status-transition rationale, and final handoffs must be posted to linked ClickUp task/subtask comments or fields.
21
21
  - Raw logs stay in evidence storage; ClickUp receives concise summaries, paths/links, or relevant excerpts only, never wholesale raw logs.
22
22
  - WPM owns ClickUp `Story Points` during `plan`, re-estimation on material plan changes, `agent_metadata` session JSON, `Definition` plan-contract linking, and parent approval routing after validation.
23
- - Human role registry: resolve `CTO` and `PO` from `docs/core/humans.md` when present; if a task worktree lacks that file, use Optima-provided fallback role context and configured ClickUp IDs instead of blocking solely on the missing repo-local file. Use role identifiers in workflow text and automation config.
23
+ - Human role registry: resolve `CTO` and `PO` from available human role context and configured ClickUp IDs. Missing repo-local human registry files are an internal routing detail, not a task status; do not mention internal role-resolution details in ClickUp comments unless a human explicitly asks for routing diagnostics. Use role identifiers in workflow text and automation config.
24
24
  - Human approval assignment is prohibited except for three cases: parent `plan` with clear ClickUp-commented questions, true `in progress` blockers caused by missing credentials/permissions/tools/authenticated browser or Agent Jake/live third-party access after local/subagent attempts, or parent `validation` after `optima_github_verify_vercel_pr` returns `ready: true` with a functional Vercel preproduction/preview URL. For those true external `in progress` blockers, assign CTO/PO in ClickUp, remove Product Manager, and explain the exact needed human action in a concise castellano ClickUp comment. Do not assign `CTO`/`PO` for generic handoff, routine validation, cleanup, subtask work, partial-phase stops, failed Vercel checks, or missing preview URLs.
25
25
  - Subtask merge authority belongs to Validator/QA after successful subtask validation: subtask PRs target and merge into the parent branch/workspace without `CTO`/`PO` assignment or approval.
26
26
  - Parent merge authority is split: after Tech Lead and Validator/QA pass plus a ready Vercel PR deployment gate, WPM/Validator may assign `CTO`/`PO` only under the parent-validation allowlist; after a human comments `Approved`, automation removes human assignees, assigns itself or the merge owner, merges to `dev`, cleans workspaces/worktrees/branches, pushes to `dev`, and ensures the dev/preproduction environment contains the code.
@@ -14,7 +14,7 @@
14
14
  - Sync human-readable task/evidence summaries, validation results, AC coverage, documentation impact, blockers, reopen history, status-transition rationale, and final handoffs to linked ClickUp task/subtask comments or fields.
15
15
  - Keep raw logs in evidence storage; ClickUp receives concise summaries, paths/links, or relevant excerpts only, never wholesale raw logs.
16
16
  - WPM owns `Story Points` during `plan`, re-estimation on material plan changes, `agent_metadata`, `Definition` plan-contract linking, and parent approval routing after validation.
17
- - Human role registry: resolve `CTO` and `PO` from `docs/core/humans.md` when present; if missing in a task worktree, use Optima fallback role context/configured ClickUp IDs instead of blocking solely on the missing file.
17
+ - Human role registry: resolve `CTO` and `PO` from available human role context/configured ClickUp IDs. Missing repo-local human registry files are internal routing detail; do not mention internal role-resolution details in ClickUp comments unless asked for routing diagnostics.
18
18
  - Human approval assignment is prohibited except for parent `plan` questions with clear ClickUp comments, true `in progress` blockers from missing credentials/tools/access/authenticated browser or Agent Jake/live third-party access after local/subagent attempts, or parent `validation` after `optima_github_verify_vercel_pr` returns `ready: true` with a functional Vercel URL. True external `in progress` blocker escalation means a concrete castellano help request, ClickUp assignment to CTO/PO, and Product Manager removal; never use it for generic handoff, cleanup, subtasks, phase stops, failed Vercel checks, or missing preview URLs.
19
19
  - Validator/QA may merge validated subtask PRs into the parent branch/workspace without `CTO`/`PO` assignment or approval.
20
20
  - Parent merge authority uses the validation allowlist only after a ready Vercel PR deployment gate: after a human comments `Approved`, automation removes human assignees, assigns merge owner/self, merges to `dev`, cleans workspaces/worktrees/branches, pushes, and ensures dev/preproduction receives the code.
@@ -11,7 +11,8 @@
11
11
  - Delivery task types: `Tarea`, `Bug`, `Doc`, `PoC`.
12
12
  - Ignored task types: `Idea`, legacy `Backlog` alias, `Hito`, `Nota de reunión`, `Respuesta del formulario` unless converted or linked to delivery work; `Idea` is non-delivery.
13
13
  - `product_manager` may pre-estimate "a qué huele" small/medium/large plus rough story points, but development requests must be converted to routed ClickUp work.
14
- - Human role registry: resolve `CTO` and `PO` from `docs/core/humans.md` when present; if a task worktree lacks that file, use Optima fallback role context and configured ClickUp IDs instead of blocking solely on the missing repo-local file. Use role identifiers in workflow text and automation config.
14
+ - Human role registry: resolve `CTO` and `PO` from available human role context and configured ClickUp IDs. Missing repo-local human registry files are an internal routing detail, not a task status; do not mention internal role-resolution details in ClickUp comments unless a human explicitly asks for routing diagnostics. Use role identifiers in workflow text and automation config.
15
+ - Final task handoffs must use `optima_finish` when available: the model supplies structured ClickUp text and intended final state, while Optima applies status, comments, and assignment policy.
15
16
  - Status-to-action mapping: `backlog` -> `ignore`, `plan` -> `plan`, `in progress` -> `execute`, `validation` -> `validate`, `merge` -> `merge`, `completed`/`Closed` -> `ignore` unless reopened. `plan` does not imply generic human approval assignment; `merge` is parent-only post-approval automation, while subtasks merge after successful Validator/QA validation without waiting for a human approval status.
16
17
  - Branch-safe type slugs are lowercase ASCII: `tarea`, `bug`, `doc`, `poc`.
17
18
 
@@ -19,7 +20,7 @@
19
20
 
20
21
  - Agents must not assign ClickUp tasks to `CTO` or `PO` except for the explicit cases below; generic handoff, routine validation, duplicate-assignee cleanup, or incomplete phase handoff are prohibited.
21
22
  - **Parent planning questions:** only a parent task in `plan` may assign `CTO`/`PO`, and only after clear, concrete questions have been posted in ClickUp comments. Subtasks are planned and executed end-to-end without CTO/PO planning assignment.
22
- - **Real in-progress blocker:** a task in `in progress` may assign/escalate to `CTO`/`PO` only when blocked by missing credentials, permissions, authenticated browser/Agent Jake access, external tools, or live third-party access after local/subagent attempts are exhausted. Escalation means posting a concrete ClickUp help request in castellano explaining exactly what is needed, assigning CTO/PO, and removing the Product Manager assignee so watchdogs stop re-queueing PM until a human replies/reassigns. Agents must not stop at informal phase boundaries such as "I reached phase 1"; phases should have been subtasks, otherwise finish the accepted task.
23
+ - **Real in-progress blocker:** a task in `in progress` may assign/escalate to `CTO`/`PO` only when blocked by missing credentials, permissions, authenticated browser/Agent Jake access, external tools, or live third-party access after local/subagent attempts are exhausted. Escalation means calling `optima_finish` with a concrete ClickUp help request in castellano explaining exactly what is needed; Optima assigns CTO/PO and removes the Product Manager assignee so watchdogs stop re-queueing PM until a human replies/reassigns. Agents must not stop at informal phase boundaries such as "I reached phase 1"; phases should have been subtasks, otherwise finish the accepted task.
23
24
  - **Parent validation approval:** only a parent task in `validation` may assign `CTO`/`PO` for final validation, and only after `optima_github_verify_vercel_pr` returns `ready: true` for the current parent PR with a functional Vercel preproduction/preview URL. After a human comments `Approved`, automation reassigns to itself or the merge owner, removes human assignees, merges, cleans workspaces/worktrees/branches, pushes to `dev`, and ensures the dev/preproduction environment contains the code.
24
25
 
25
26
  ## Routing Rules
@@ -6,8 +6,9 @@
6
6
  - Slices: `foundation`, `core`, `logic`, `ui`, `polish`, `qa`, `docs`.
7
7
  - ClickUp-first delivery types: `Tarea`, `Bug`, `Doc`, `PoC`; ignored types: `Idea`, legacy `Backlog` alias, `Hito`, `Nota de reunión`, `Respuesta del formulario` unless converted/linked.
8
8
  - Product Manager without workflow never develops; it may pre-estimate "a qué huele" small/medium/large plus rough story points and route development into ClickUp tasks.
9
- - Human role registry: resolve `CTO` and `PO` from `docs/core/humans.md` when present; if missing in a task worktree, use Optima fallback role context/configured ClickUp IDs instead of blocking solely on the missing file.
10
- - ClickUp-first actions: `backlog` ignore, `plan` plan with `Story Points`, `Definition`, and test strategy; assign `CTO`/`PO` only for parent planning questions with clear ClickUp comments, real `in progress` blockers caused by missing credentials/tools/access/authenticated browser or Agent Jake/live third-party access after local/subagent attempts, or parent `validation` after `optima_github_verify_vercel_pr` returns `ready: true` with a functional Vercel URL. For true external `in progress` blockers, post a concrete castellano ClickUp help request explaining exactly what is needed, assign CTO/PO, and remove Product Manager so PM watchdogs stop looping until a human replies/reassigns. Subtasks execute end-to-end and merge to the parent branch after Validator/QA passes without CTO/PO approval; parent `Approved` comments trigger automation to remove humans, assign merge owner/self, merge to `dev`, clean workspaces/worktrees/branches, push, and ensure dev/preproduction receives the code; `completed`/`Closed` ignore unless reopened.
9
+ - Human role registry: resolve `CTO` and `PO` from available human role context/configured ClickUp IDs. Missing repo-local human registry files are internal routing detail; do not mention internal role-resolution details in ClickUp comments unless asked for routing diagnostics.
10
+ - Final task handoffs must use `optima_finish` when available; Optima applies final status, comment, and assignments.
11
+ - ClickUp-first actions: `backlog` ignore, `plan` plan with `Story Points`, `Definition`, and test strategy; assign `CTO`/`PO` only for parent planning questions with clear ClickUp comments, real `in progress` blockers caused by missing credentials/tools/access/authenticated browser or Agent Jake/live third-party access after local/subagent attempts, or parent `validation` after `optima_github_verify_vercel_pr` returns `ready: true` with a functional Vercel URL. For true external `in progress` blockers, call `optima_finish` with a concrete castellano ClickUp help request explaining exactly what is needed; Optima assigns CTO/PO and removes Product Manager so PM watchdogs stop looping until a human replies/reassigns. Subtasks execute end-to-end and merge to the parent branch after Validator/QA passes without CTO/PO approval; parent `Approved` comments trigger automation to remove humans, assign merge owner/self, merge to `dev`, clean workspaces/worktrees/branches, push, and ensure dev/preproduction receives the code; `completed`/`Closed` ignore unless reopened.
11
12
  - Routing: keep `tiny` to one slice and usually one specialist; keep `standard` bounded; decompose `complex` into slice-based subtasks.
12
13
  - `complex + implementation` normally uses `workflow_runner` in full mode.
13
14
  - WPM stores `agent_metadata`, re-estimates `Story Points` on material plan changes, and keeps `Definition` plan contract separate from final Documentation.
@@ -18,7 +18,7 @@ We adhere to a strict test pyramid strategy to ensure 100% reliability.
18
18
  - **Planning Participation:** Validator/QA participates during `plan` for test strategy, required new coverage, Playwright needs, regression scope, and documentation-validation expectations.
19
19
  - **Regression:** A full regression suite must be run by the Developer before handing over for technical review.
20
20
  - **Split Validation:** Tech Lead reviews architecture, code, PR readiness, standards, and repo-skill use; Validator/QA verifies tests, Playwright flows, regression, required coverage, evidence, and final documentation freshness.
21
- - **Human Role Registry:** Resolve `CTO` and `PO` from `docs/core/humans.md` when present; if a task worktree lacks that file, use Optima fallback role context and configured ClickUp IDs instead of blocking solely on the missing repo-local file. Use role identifiers in workflow text and automation config.
21
+ - **Human Role Registry:** Resolve `CTO` and `PO` from available human role context and configured ClickUp IDs. Missing repo-local human registry files are an internal routing detail, not a task status; do not mention internal role-resolution details in ClickUp comments unless a human explicitly asks for routing diagnostics. Use role identifiers in workflow text and automation config.
22
22
  - **Human Approval Allowlist:** Assign `CTO`/`PO` only for parent `plan` questions with clear ClickUp comments, real `in progress` blockers caused by missing credentials/permissions/tools/access/authenticated browser or Agent Jake/live third-party access after local/subagent attempts, or parent `validation` after `optima_github_verify_vercel_pr` returns `ready: true` with a functional Vercel URL. For true external `in progress` blockers, post the concrete help request in castellano, assign CTO/PO in ClickUp, and remove Product Manager. Never assign them for generic handoff, routine validation, cleanup, subtasks, partial-phase stops, failed Vercel checks, or missing preview URLs.
23
23
  - **Merge Execution Gate:** Validator/QA may merge validated subtask PRs into the parent branch/workspace without human approval. Parent PRs to `dev` require Tech Lead and Validator/QA pass plus the parent-validation allowlist; after a human comments `Approved`, automation removes human assignees, assigns itself or the merge owner, merges, cleans workspaces/worktrees/branches, pushes to `dev`, and ensures the dev environment contains the code. Any conflicted or failed merge returns the affected task/subtask to `in progress` for the coding owner.
24
24
  - **Documentation Gate:** Validator/QA must fail validation when final documentation is missing or outdated; `Definition` is only the plan contract, not the delivered documentation.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@defend-tech/opencode-optima",
3
- "version": "0.1.79",
3
+ "version": "0.1.81",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+ssh://git@github.com/defend-tech/opencode-optima.git"