feat: structured worker positions for deterministic orchestration - #5
Open
WuFenG-Hub wants to merge 2 commits into
Open
feat: structured worker positions for deterministic orchestration#5WuFenG-Hub wants to merge 2 commits into
WuFenG-Hub wants to merge 2 commits into
Conversation
Introduce a second-level worker classification (position) under metabot_type='worker', modeled after job-market roles: dev, researcher, designer, writer, operator. Each position carries persona templates (role/soul/goal/bio), default skills and permission notes. - DB: metabots.position TEXT column + idempotent migration; legacy workers keep NULL and stay fully compatible. - Store: create/update round-trips position; twin bots never carry one; promoting a worker to twin clears it. - UI: Persona tab position dropdown applies the built-in templates (still editable afterwards); default skills shown as guidance. - Orchestration: group-task roster/profile lines expose position and the chair playbook assigns subtasks by position first, falling back to role/bio semantic matching only when no position fits. - Directory: list-metabots entries carry position for twin planning. - Position stays local-only: never published on-chain (covered by tests). - Tests: positions/directory/prompt coverage + updated expectations.
newfish
added a commit
that referenced
this pull request
Aug 8, 2026
P0-1: failed noise steps no longer block owner acceptance - acceptGroupTask counts only active steps (blocked/ready/queued/running) as unfinished; failed/cancelled steps (mistaken mentions, aborted turns) pass - failed->completed transition added to the step state machine; ignoreFailedSteps demotes noise steps with an ignored marker, auto-run on review entry P0-2: member_names now honored on create - RPC create no longer force-overrides autoSelectWorkers=true; explicit members (ids or names) are used as-is, full-roster auto-select only when none named P0-3: kickoff no longer triggers the whole roster - kickoff roster line drops the @ prefixes - mention matching is word-boundary @name only; a bare name (roster line, recap text) never triggers a reply - per-tick cap/cooldown skips are DEFERRED and retried on a later tick, so a skipped worker still gets its chance instead of being dropped P1-4: DELIVERABLE parsing hardened - chair messages never collected; URI-shaped tokens with placeholder/malformed URIs (metaapp://<pinId>, metaapp://[PINID]) rejected as a whole - cleanup hatch: deliverable-delete store method + RPC endpoint + skill action P1-5: chair planning directive embeds the full member roster (name/role/bio/goal) P2-6: show/getGroupTask returns the latest group transcript (messages) P2-7: chair auto responses suppressed when the Twin already replied to the triggering message (reply_pin match), plus a 1-per-tick cap on auto responses P2-8: same-message multi-step creation fixed by the word-boundary mention rule Tests: 83 pass across groupTaskDaemon/orchestrationBridge/service/store suites
newfish
added a commit
that referenced
this pull request
Aug 8, 2026
… tag occurrence - New groupTaskDeliverableParser module: strictly line-scoped, one candidate per [DELIVERABLE] tag occurrence (two tag lines -> two rows), strict validation (placeholder <pinId>/[PINID] and ellipsis/truncation rejected; a real URI must carry a 64-hex+i0 pinid token or be an ^https?:// URL), trailing markdown/punctuation and full-width paren annotations never leak into the recorded URI, kind follows the candidate's own scheme. - Daemon ingestion records every valid candidate separately (dedupe per msg_pin_id + uri + kind) instead of one row per message, so real URIs on sibling tag lines are no longer dropped (#7 msg94: metaapp + share link). - Correction-first aggregation hook (findSupersededDeliverable) lands with the ingestion rewrite: a message declaring 更正/修正/以…为准 supersedes the matched prior row in place (same author + shared pinid token). - Regression set from the real #5/#6/#7 messages (placeholder planning samples, truncated metafile, body dir paths, paren annotations, multi-line and single-line-multi-tag messages, trailing markdown).
This was referenced Aug 9, 2026
- keep both feature sets: structured positions (HEAD) + OpenTeam remote teammates (upstream) in types, daemon prompt roster, and SKILL docs - remote members render without a fake 'position: generic' label - fix PR's own missing 'position' field on renderer Metabot type (build was broken since 2026-08-08; no CI ever caught it) - drop 2 unused eslint-disable directives inherited from upstream baseline
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
背景与问题
当前 MetaBot 只有两级分类:
metabot_type取'twin' | 'worker'(建表 CHECK 约束)。worker 之间的区分完全依赖自由文本role / soul / goal / bio,带来两个痛点:name (role)+ role/bio 文本做语义猜测(groupTaskPrompts.ts),结果不可枚举、不可回归测试;「任务需要什么能力 → 谁适合」没有结构化映射。方案:参照二级招聘市场模式,给 worker 增加结构化「职位(position)」维度——内置 dev / researcher / designer / writer / operator 五个职位,各带 persona 模板(role/soul/goal/bio)、默认技能与权限说明。编排时职位优先匹配、自由文本语义兜底,即信息检索的双通道结构:精确索引层(职位)负责快速命中,语义层覆盖无法归类的自定义 bot。
改动内容
src/main/sqliteStore.tsmetabots.position TEXT列 + 幂等迁移migrateMetabotPositionColumn();重建表迁移兼容透传src/main/metabotStore.tsundefined保留旧值src/main/positions.ts(新增)getPositions/getPosition/normalizePosition/positionAppliesTosrc/main/preload.ts/src/main/main.ts/src/renderer/types/electron.d.tsmetabot:getPositionsMetaBotEditTabs.tsx+MetabotsManager.tsx+i18n.tsgroupTaskPrompts.ts/groupTaskDaemon.ts- name (worker, position: dev);profile 行注入 Position;chair playbook 新增「按职位优先分配、语义兜底」规则metabotDirectoryService.tslist-metabots输出 position,供 twin 规划SKILLs/metabot-group-task/SKILL.mdtests/metabotPosition.test.mjs(新增) + 既有测试更新兼容性
position = NULL→ 展示「未设定(通用)」,编排自动走语义兜底,功能零回退metabot_typeCHECK 约束不动;twin 逻辑不变EDIT_TAB_SYNC_GROUPS不含 position,有测试守护)验证
npm run compile:electron:与基线相比零新增编译错误(基线 15 个为本地 node_modules 依赖缺失导致,与本次改动无关)tests/metabotPosition.test.mjs:8/8 通过groupTaskStore/groupTaskDaemon/groupTaskService/twinWorkerDirectoryService等 77 项 mjs 测试 +metabotEditTabs7 项 tsx 测试全过设计取舍