Skip to content
Merged
4 changes: 4 additions & 0 deletions .changes/unreleased/preset-roles.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
category: Added
---
- Preset roles: bundle 7 omp-style generic subagent roles (designer, librarian, reviewer, scout, security-reviewer, sonic, task) declared automatically on apply via the role-seeds surface (config `presets: 'bundled' | 'none'`, default `bundled`); `presetRoles` exported from the package root.
6 changes: 3 additions & 3 deletions .mstar/knowledge/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@

| Document | Source Plan | Description | Status |
|----------|-------------|-------------|--------|
| [architecture-patterns/dsh-llm-fallbacks.md](architecture-patterns/dsh-llm-fallbacks.md) | llm-fallbacks-plugin | dsh LLM fallback 双 waterfall 恢复架构(ADR-1..4、两块制配置模型 rootChain + roles.list/rules + inherit 语义、append-not-replace、legacy 三通道与 schemastery 未知键保留、warn-not-crash 校验、单遍历决策、冷却/安全阀、always-cap、状态机、gateway 通道与 KD-G3/种子不变量、入口面、**消费面(库 API re-export + 具名 service llm-fallbacks)**、**role-seeds 能力(companion 自配置 / 双存储 / 派生状态 / 9-key service)**、已知限制) | Active |
| [best-practices/dsh-cordis-plugin-authoring.md](best-practices/dsh-cordis-plugin-authoring.md) | llm-fallbacks-plugin | dsh 第三方 cordis 插件创作 playbook(bundle/client/真实包链接 DSH_HOME/构建/设置入口两形态与 gateway 数据面/remote events 失效刷新/schemastery 组合未知键保留与 schema-breaking 迁移三通道/事件监听组合顺序与 persona 可读性/关键坑/**具名 cordis 服务注册(值形式 ctx.provide + 多 fiber dedupe + Context merge + createRequire version + 纯函数 vs 闭包身份区分)**) | Active |
| [architecture-patterns/dsh-llm-fallbacks.md](architecture-patterns/dsh-llm-fallbacks.md) | llm-fallbacks-plugin | dsh LLM fallback 双 waterfall 恢复架构(ADR-1..4、两块制配置模型 rootChain + roles.list/rules + inherit 语义、append-not-replace、legacy 三通道与 schemastery 未知键保留、warn-not-crash 校验、单遍历决策、冷却/安全阀、always-cap、状态机、gateway 通道与 KD-G3/种子不变量、入口面、**消费面(库 API re-export + 具名 service llm-fallbacks)**、**role-seeds 能力(companion 自配置 / 双存储 / 派生状态 / 9-key service)**、**preset roles(bundled 预设 / D9.3 自声明时序 / 四处同步 / client 连锁)**、已知限制) | Active |
| [best-practices/dsh-cordis-plugin-authoring.md](best-practices/dsh-cordis-plugin-authoring.md) | llm-fallbacks-plugin | dsh 第三方 cordis 插件创作 playbook(bundle/client/真实包链接 DSH_HOME/构建/设置入口两形态与 gateway 数据面/remote events 失效刷新/schemastery 组合未知键保留与 schema-breaking 迁移三通道/事件监听组合顺序与 persona 可读性/关键坑/**具名 cordis 服务注册(值形式 ctx.provide + 多 fiber dedupe + Context merge + createRequire version + 纯函数 vs 闭包身份区分)**/**条件注入子 fire 模式(apply 尾部后台动作、fire-and-forget + terminal catch、multi-fiber 门控)**) | Active |
| [workflow-patterns/harness-sandbox-verification.md](workflow-patterns/harness-sandbox-verification.md) | llm-fallbacks-plugin | dsh 沙箱兼容验证模式(scratch DSH_HOME / 只读 git apply --check / 编译级验证) | Active |
| [build-errors/css-modules-hash-invalid-selector.md](build-errors/css-modules-hash-invalid-selector.md) | llm-fallbacks-settings-style | CSS Modules 哈希类名数字开头 → 浏览器静默丢弃样式规则(构建根因 + 双位置契约断言 + CSSOM 验证模式) | Active |
| [build-errors/dsh-client-bundle-purity-gate.md](build-errors/dsh-client-bundle-purity-gate.md) | fallbacks-plugin-config-card | Client bundle purity 门失明缺口:alwaysBundle 静默内联使 require-only 断言失明(94 kB 负向探针实证);resolveId 门 + emitted-surface token 扫描双层修复 | Active |
| [architecture-patterns/dsh-settings-slot-contract.md](architecture-patterns/dsh-settings-slot-contract.md) | llm-fallbacks-settings-style | dsh web settings slot 契约(settings.plugin.item 插件配置卡/section/general.item/action/onboarding;order tie 语义;navIcon fallback;inject vs register;三个注册面) | Active |
| [architecture-patterns/dsh-gateway-settings-channel.md](architecture-patterns/dsh-gateway-settings-channel.md) | llm-fallbacks-settings-gateway | 插件自有 settings gateway 通道模式(GatewayService + 显式 `ctx.typert.register` contribution;wire 契约/KD-G3 无 revision 守卫/KD-G5 可选 settings/reset 语义/种子不变量;**跨写者 RMW race(R-002)/读写 containment 守卫/additive wire 字段**)——advisor + fallbacks 双实例验证;20260811 remote events 失效刷新;**20260813 SRC `@Remote` claims 对 link 插件失效(模块私有标记表)→ 显式注册是模块身份无关路径** | Active |
| [architecture-patterns/dsh-gateway-settings-channel.md](architecture-patterns/dsh-gateway-settings-channel.md) | llm-fallbacks-settings-gateway | 插件自有 settings gateway 通道模式(GatewayService + 显式 `ctx.typert.register` contribution;wire 契约/KD-G3 无 revision 守卫/KD-G5 可选 settings/reset 语义/种子不变量;**跨写者 RMW race(R-002)/读写 containment 守卫/additive wire 字段/注入子注册序=激活序/SettingsProvider init publish 清 seed**)——advisor + fallbacks 双实例验证;20260811 remote events 失效刷新;**20260813 SRC `@Remote` claims 对 link 插件失效(模块私有标记表)→ 显式注册是模块身份无关路径** | Active |
| [architecture-patterns/dsh-mount-point-map.md](architecture-patterns/dsh-mount-point-map.md) | fallbacks-mount-map-command | dsh 外部插件挂载点地图(32 seams:settings/gateway/events/commands/会话面/安装面分类 verdict)+ 五列证据标准与可证伪门禁方法 | Active |
| [architecture-patterns/dsh-conversation-surface-mounting.md](architecture-patterns/dsh-conversation-surface-mounting.md) | fallbacks-aux-seams | 会话转录挂载模式:conversationEvents 注册表 + conversation.chat.node keyed 座位双段挂载;纯渲染纪律与 degrade-never-crash(W-001,引擎无 try/catch) | Active |
| [best-practices/dsh-settings-ui-fidelity.md](best-practices/dsh-settings-ui-fidelity.md) | llm-fallbacks-settings-ui-fidelity | dsh web 设置 UI 保真参考(参照文件地图含插件配置卡 chrome、几何/token 词表、逐维度对照方法、用户可见差异裁决) | Active |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,12 @@ gateway 响应加字段用 **additive** 模式:`readResult()` 统一附加(`
测试 double 钉事件名集合(drift-visible);`grep settings/changed|models/changed`
零残留。

### 注入子注册序 = 激活序;SettingsProvider init publish 清 seed(2026-08-16 实证)

- **cordis 注入子按注册序同波激活**(Fiber `_reload` 先 `await Promise.resolve()`,微任务 FIFO):apply 内多个 `ctx.inject([...])` 子按注册先后激活。依赖「先注册子先执行」的隐式顺序(如 writeRoles live 先于 preset fire)成立但脆弱——**新 fire 点应注册于 apply 最尾部**,并在注释钉住理由(preset 子见 `dsh-llm-fallbacks.md` Preset roles 节)。
- **SettingsProvider init publish 清 seed(F-005 教训)**:cordis `Service` 构造同步 provide 但不跑 `[Service.init]`;dsh-settings init 的 `publish(await load())` 会**清掉 init 完成前 publish 的任何 seed**(测试 double 人造物;file-backed HMR 因文档持久化天然规避)。测试「settings 移除→恢复→注入子 re-fire」时,须手工构造 fresh provider 并在子再激活前同步 seed——四断言面(re-fire 证明 / no-delta 零写 / 无重复 / user section 未变)各自独立失败才算钉住。
- **re-fire 语义**:settings 子每次激活 re-fire(无 per-apply 单发 guard);declare 幂等 + registry re-commit 保持 badge 正确。

## Why This Matters

- 设置数据面彻底离开 apiproxy expose 机制:插件命名空间在未打 patch 的宿主上不出现于
Expand Down Expand Up @@ -202,4 +208,4 @@ gateway 响应加字段用 **additive** 模式:`readResult()` 统一附加(`

*Source: iteration iter-20260811-fallbacks-mount-only `guides/gateway-channel-design.md`(ADR-1..ADR-5 契约),
与 dsh-advisor `src/gateway.ts` 对照验证。2026-08-12 compound 提升(结构化重写为模式层)。
2026-08-15 刷新:跨写者 RMW race(R-002)、读写 containment 守卫、additive wire 字段先例。*
2026-08-15 刷新:跨写者 RMW race(R-002)、读写 containment 守卫、additive wire 字段先例。2026-08-16 刷新:注入子注册序=激活序、SettingsProvider init publish 清 seed(iter-20260816-fallbacks-preset-roles F-005 实证)。*
16 changes: 15 additions & 1 deletion .mstar/knowledge/architecture-patterns/dsh-llm-fallbacks.md
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,20 @@ order 100)、会话转录切换行(`conversationEvents` + `conversation.chat
- **防御纪律**:读写路径**同用** `roleRows()`/`roleRules()` containment 守卫(legacy/畸形 composed roles 降级不崩);client store `revertSeed` 镜像 save 的 writable/saving/generation 守卫;卡片 `seededIds` 每次 render 派生(无存储状态)。seeds.ts io-seamed(零 `@deepseek-ai/*` value import,client bundle purity)。
- **已知边界**:settings user-layer 跨写者 RMW race 无 revision guard(与既有 set/reset 同源通道限制,last-writer-wins,有界可恢复)——R-002 defer,见 `dsh-gateway-settings-channel.md`。

### Preset roles:bundled 预设角色(iter-20260816-fallbacks-preset-roles)

插件自带 **7 个 omp 风格通用子代理角色**(designer / librarian / reviewer / scout / security-reviewer / sonic / task),默认 apply 时经既有 seeds 面**自声明**(插件自身成为 seeds 的调用方,零新 io seam)——dsh 宿主开箱即有通用角色 taxonomy:

- **机制**:`src/presets.ts` 导出 `presetRoles: readonly SeedDeclaration[]`(纯数据,persona = 提炼自 omp bundled agents 提示词的精简指令文,快照 2026-08-16,spec 定稿逐字冻结);config 键 `presets: 'bundled' | 'none'`(默认 `'bundled'`,**四处同步**:config.ts interface+default / schema.ts union-of-const+default(照抄 revertPolicy 先例)/ **gateway `CONFIG_KEYS`**(漏掉则 `set({presets})` 被未知键拒绝且 get wire 缺键)/ tests);包根 re-export `presetRoles`(非 service 键,9-key service 零改动)。
- **D9.3 自声明时序(apply 同步签名,关键约束)**:cordis async-apply 的 rejection 会经 `_reload` 把整条 fiber 打成 FAILED(插件整体不加载)→ **否决 async 化**;注入子一个 tick 后才激活(cordis Fiber `_reload` 微任务波按注册序激活)→ apply 尾部**同步 fire 必中 settings-unavailable stub** → 定案:apply 尾部(全部既有 wiring 之后)注册**新** `ctx.inject(['settings'])` 条件子,子激活回调内 `seeds.declare(presetRoles, seedsIo)` + 同步挂 `.catch`(terminal:logger.error 带 `llm-fallbacks: seeds:` 前缀、registry 不 commit、不阻断 apply、无进程内重试)。
- **不得复用早注册的 writeRoles 注入子**:它注册先于 `installSettingsSection`,fire 时 `source()` 仍是 base-only → 以错误基线物化会**整键覆盖 operator user-layer 行**(写覆盖事故);尾部新子保证 `writeRoles` live + `source()` composed(`setSource` 同步执行,无 load 竞态)。
- **multi-fiber 门控**:fire 仅发生在成功注册 service 的 fiber(provide try 置 ownership 标志、dedupe catch 置 false);second fiber 不 fire;declare 幂等 + settings 写队列串行为双兜底。
- **`presets:'none'`**:fire 时读 live composed source 短路(零声明零写);**无 `enabled` 门**(enabled:false 默认安装态仍物化 7 行——taxonomy 物化不在 no-op 短路范围内)。
- **client 连锁**:host 默认值增长会连锁 client——`parseFallbacksConfig` fold 镜像(保持 `parseFallbacksConfig({})` toEqual `defaultFallbacksConfig` 不变量)+ `FallbacksCard` `assembleConfig` 携带新键(否则卡片 clean/dirty JSON 比较永久 dirty);`export-surface.spec.ts` `LIBRARY_EXPORT_KEYS` SSOT 同步新导出。
- **测试隔离纪律**:legacy 套件若断言 roles.list 精确形状,须 pin `presets:'none'`(默认 bundled 会物化 7 行改变观测值);`tests/support/harness.ts` `cfg()` 默认 pin none。
- 冲突/覆盖/幂等语义**零新逻辑**(完全沿用 seeds 既有 declare 语义:operator 同名行保留 + conflict warn、no-delta 零写、derived seeded 不落盘)。
- 发布:0.1.6 minor;fragment 命名 preset roles 表面(presetRoles 导出 + presets 键)。

### 已知限制(open residual)

- 失败码默认 ['AUTH','QUOTA','RATE_LIMIT'];5xx/TRANSPORT 等由 llm-retry 先行退避,预算耗尽后同样进入 fallback 决策,无需额外配置。
Expand All @@ -171,4 +185,4 @@ order 100)、会话转录切换行(`conversationEvents` + `conversation.chat
- 设置页/目录/状态块:tests/fallbacks-store.spec.ts(61 用例)。
- 真实宿主端到端剧本:docs/verification.md §4(QA gate)。

*Source: iteration iter-20260810-llm-fallbacks(specs/llm-fallbacks-spec.md)+ iter-20260810-fallbacks-settings-ux(specs/fallbacks-settings-runtime-spec.md,D-1..D-6 提升)+ iter-20260810-fallbacks-settings-gateway + iter-20260811-fallbacks-mount-only(Plan B:role rules-only、marker 移除、patch 体系删除)+ iter-20260815-fallbacks-role-seeds(specs/fallbacks-role-seeds-spec.md:role-seeds 能力、D5 service API、双存储模型、R1–R4、release 0.1.4 minor),随实现验证。2026-08-12 刷新:由 patch 时代更新为纯挂载现实。2026-08-13 刷新:由链键 specificity / roles.default 时代更新为两块制现实。2026-08-15 刷新:新增 role-seeds 能力节(9-key service)。*
*Source: iteration iter-20260810-llm-fallbacks(specs/llm-fallbacks-spec.md)+ iter-20260810-fallbacks-settings-ux(specs/fallbacks-settings-runtime-spec.md,D-1..D-6 提升)+ iter-20260810-fallbacks-settings-gateway + iter-20260811-fallbacks-mount-only(Plan B:role rules-only、marker 移除、patch 体系删除)+ iter-20260815-fallbacks-role-seeds(specs/fallbacks-role-seeds-spec.md:role-seeds 能力、D5 service API、双存储模型、R1–R4、release 0.1.4 minor),随实现验证。2026-08-12 刷新:由 patch 时代更新为纯挂载现实。2026-08-13 刷新:由链键 specificity / roles.default 时代更新为两块制现实。2026-08-15 刷新:新增 role-seeds 能力节(9-key service)。2026-08-16 刷新:新增 Preset roles 节(bundled 预设、D9.3 自声明时序、四处同步、client 连锁、0.1.6)。*
10 changes: 10 additions & 0 deletions .mstar/knowledge/best-practices/dsh-cordis-plugin-authoring.md
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,16 @@ dsh 插件 = npm 包,package.json 声明 dsh.bundle.patch(指向 bundle/cord
- 单点真相:服务方法 = 直接引用 index re-export 的同一函数(`toBe` 同一性测试钉住),不复制逻辑。
- **有状态方法的身份(2026-08-15 实证)**:服务面可以是「无状态纯函数 + 有状态闭包」混合——legacy 纯函数方法与库 re-export **同一绑定**(`toBe` 同一),但 per-apply 有状态方法(如 seeds `declareSeeds`/`revertSeededPersona`)是**闭包**(捕获 apply() 内建的 manager),与库 re-export **不是**同一引用。文档必须区分两种身份(写「与库导出同一绑定」会过度声称,2026-08-15 修过此 doc bug);测试同样分型钉住(纯函数 `toBe` vs 闭包行为)。

### 条件注入子 fire 模式(apply 尾部触发后台动作,2026-08-16 实证)

插件需要在 apply 后做**异步后台动作**(如经 settings 通道物化默认数据)时的安全模式:

- **apply 保持同步签名**:cordis 虽 await thenable 返回值,但 rejection 经 `_reload` 使整条 fiber **FAILED**(插件整体不加载)——headless 组合会把运行时整个拖死;且 `void → Promise<void>` 是公共库面非 additive 变更。异步动作一律 fire-and-forget + **同步挂 `.catch`**(无 unhandled rejection 窗口)。
- **不要在 apply 尾部同步触发**:`ctx.inject` 子一个 tick 后才激活,同步触发必中「服务未就绪」stub。定案:**注册新的条件注入子**(`ctx.inject(['settings'])`),子激活回调内执行动作;子不激活 = 服务结构性不存在 = 零副作用(headless 边界天然成立)。
- **不要复用早注册的注入子**:早注册子激活时 `setSource`/绑定可能尚未就绪(base-only 基线 → 整键覆盖事故);新 fire 点注册于 apply 最尾部,按注册序激活保证依赖先 live。
- **multi-fiber 门控**:同一动作只应发生在成功注册 service 的 fiber(provide try 置 ownership 标志、dedupe catch 置 false);second fiber 不重复执行;动作本身幂等(no-delta)作双兜底。
- 失败面:logger.error 一条带前缀、状态不 commit、不阻断 apply、无进程内重试(下次 apply / 子再激活即重试)。测试须 `vi.waitFor`(fire 在激活后一个 tick)+ 负向断言 settle 窗口。

## Why This Matters

每条模式都踩过坑(registry 404、closure-factory 契约、schemastery cast、waterfall 注册顺序),按此 playbook 可绕过全部已知陷阱;验证证据链见迭代 review bundle。
Expand Down
4 changes: 4 additions & 0 deletions CONCEPTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,3 +83,7 @@ npm 的 Trusted Publishing(OIDC provenance,无 token)**只对已存在的
### role seeds(角色种子)
companion 插件经释放面声明 `[{id, persona}]`、由本插件自动补全角色 taxonomy 的机制(iter-20260815-fallbacks-role-seeds):持久面 = operator 配置 `roles.list[]` 普通行(物化仅 `{id, persona}` 两键),内存面 = per-apply `FallbacksSeedManager` registry;`seeded`/`personaOverridden` **派生不存储**(round-trip 构造性无孤儿 override)。释放面 = 9-key service 的 `declareSeeds`(a) / `getEffectiveRoles`(b) / `revertSeededPersona`(c) + gateway `seeds` wire + `fallbacks/revert-seed`。seed id 按 as-declared 过 `ROLE_ID_PATTERN`(零 coercion),chain/fallback/prompt/permissions 永不被动(R4)。
*Avoid:* 「seed 覆盖配置」「mstar patch 写插件行」(fold bundle row 已证伪——同 loader-entry id 启动崩溃 / 异 id 双实例)

### bundled preset roles(内置预设角色)
插件自身携带的默认角色声明(iter-20260816-fallbacks-preset-roles):`presetRoles` 包根导出 + config `presets: 'bundled' | 'none'`(默认 bundled)——插件在 apply 尾部经条件注入子自声明 7 个 omp 风格通用角色(designer/librarian/reviewer/scout/security-reviewer/sonic/task),operator 可关(none = 零声明零写)。与 companion 声明的区别:seeds 的**调用方是插件自身**;语义(冲突保留/幂等/derived seeded)完全复用。
*Avoid:* 默认 none(bundled 语义开箱即有)· async 化 apply 自声明(fiber FAILED)· 复用早注册注入子 fire(base-only 基线覆盖 operator 行)
Loading
Loading