@mstar-harness/dsh 3.5.1 → 3.6.0-alpha.2
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/README.i18n.yaml +2 -2
- package/README.md +15 -17
- package/README.zh.md +15 -17
- package/dist/client/index.d.ts +1 -1
- package/dist/client/panel/PanelView.d.ts +2 -2
- package/dist/client/panel/use-mstar-engine-status.d.ts +8 -8
- package/dist/client.js +5 -5
- package/dist/gates/_shared.d.ts +46 -14
- package/dist/gates/agent-personas.d.ts +3 -3
- package/dist/gates/fallbacks-advisory.d.ts +2 -2
- package/dist/gates/fallbacks-probe.d.ts +12 -6
- package/dist/gates/fallbacks-seeds.d.ts +12 -10
- package/dist/gates/fallbacks-structural.d.ts +101 -0
- package/dist/gates/goal-bridge.d.ts +1 -1
- package/dist/gates/role-persona.d.ts +191 -0
- package/dist/gates/system-prompt.d.ts +7 -5
- package/dist/index.d.ts +2 -2
- package/dist/index.js +136 -111
- package/harness-skills/mstar-artifacts/references/status-and-residuals.md +25 -13
- package/harness-skills/mstar-coding-behavior/SKILL.md +2 -0
- package/harness-skills/mstar-harness-core/SKILL.md +13 -1
- package/harness-skills/mstar-iteration/SKILL.md +1 -1
- package/harness-skills/mstar-iteration/references/phase-3-iteration-close.md +12 -2
- package/package.json +20 -20
- package/dist/gates/fallbacks-decoration.d.ts +0 -108
package/README.i18n.yaml
CHANGED
|
@@ -2,5 +2,5 @@
|
|
|
2
2
|
# Blob hashes (git hash-object) of each side as of the last confirmation that
|
|
3
3
|
# both languages say the same thing (dsh i18n contract: a pair is three
|
|
4
4
|
# sibling files; editing either side obligates re-confirming and re-recording).
|
|
5
|
-
README.md:
|
|
6
|
-
README.zh.md:
|
|
5
|
+
README.md: 0ac2dde792b70de22ca30d83141dd3144a975c72
|
|
6
|
+
README.zh.md: 29ec00188f7e58176dadb85d3688a4f7551dad74
|
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
English | [中文](README.zh.md)
|
|
4
4
|
|
|
5
|
-

|
|
6
6
|
|
|
7
7
|
[Morning Star](https://github.com/btspoony/mstar-harness) as a first-class dsh (DeepSeek Harness) host — a cordis function plugin that mounts the mstar engine in-process, implements the engine `HostAdapter` (`host: 'dsh'`), guards `{HARNESS_DIR}/status.json` writes (validate + advisory; repair-escape under hard), blocks disallowed subagent dispatches when `Enforcement: hard` is on, lints `SKILL.md` writes under the mounted skill roots, mounts the mstar `skills/` mirror through the dsh skill-filesystem provider (single canonical mount), and appends a durable `mstar-engine-status` catalog row to every composed agent step. Boot with a dsh Loader app; everything acts through the seam's refusal/advisory channels, never by patching the tools.
|
|
8
8
|
|
|
@@ -51,8 +51,8 @@ The **two-command install is the contract** — folding a `dsh-llm-fallbacks` ro
|
|
|
51
51
|
| `enforcement` | `'hard' \| 'soft'` | compass, else warn-only | Per-deployment override. Precedence: Config wins; else the Assignment's own `**Enforcement**: hard` header flag (dispatch gate only); else the repo `.mstarc` `[config] enforcement`; else the iteration compass frontmatter; else warn-only. Config / `.mstarc` `soft` are the ONLY local rollbacks — an Assignment-level `soft` does NOT override a hard compass. |
|
|
52
52
|
| `dispatchTools` | `string[]` | `['subagent', 'subagent_fork']` | Delegation tool names the dispatch gate matches — the dsh preset's TWO delegation tools, `subagent` and its fork sibling `subagent_fork` (both carry Assignment-shaped `{ description, prompt }` args; a `toolName` config may rename instances). |
|
|
53
53
|
| `dispatchBinding` | `string` | unset → fail-closed `empty-binding` under hard | The dispatching agent's own harness role (the anti-recursion CALLER); an Assignment whose `Execute as` equals it is self-recursion. |
|
|
54
|
-
| `roleMap` | `Record<string, string>` | unset | mstar role id (`Execute as`) → dsh-llm-fallbacks role id. A taxonomy bridge for logging + future rule-driven interop ONLY — never consulted by the
|
|
55
|
-
| `rolePersonas` | `Record<string, string>` | unset (bundled mirror default) | mstar role id (`Execute as`) → persona text; the
|
|
54
|
+
| `roleMap` | `Record<string, string>` | unset | mstar role id (`Execute as`) → dsh-llm-fallbacks role id. A taxonomy bridge for logging + future rule-driven interop ONLY — never consulted by the persona channel (see LLM fallbacks integration). |
|
|
55
|
+
| `rolePersonas` | `Record<string, string>` | unset (bundled mirror default) | mstar role id (`Execute as`) → persona text; the native subagent persona channel's **override** source — a role-matched start (one-shot `start` or the opt-in continuable `startContinuable`) merges the persona into the native request `persona` slot (the child embodies the role persona INSTEAD OF the deployment persona; persisted + reapplied on resume); when unset for a role, the bundled `harness-agents/` mirror default is used (see LLM fallbacks integration). |
|
|
56
56
|
| `skillRoots` | `string[]` | unset (no custom-root registration) | Additional skill roots registered with the dsh skill-filesystem provider (`customSkillDirs` semantics — scanned before user roots). Dev-time: the mirror `<repo-root>/skills` absolute path. |
|
|
57
57
|
| `bundledSkillDir` | `string` | packaged `harness-skills/` mirror (package-relative) | Bundled skill root registered with the dsh skill-filesystem provider (`bundledSkillDir` semantics — scanned last, trusted). Defaults to the package's OWN `harness-skills/` mirror (synced by `bundle-assets`; gitignored) — package-relative, NOT cwd-anchored. An explicit value wins. |
|
|
58
58
|
| `catalogTtlMs` | `number` | `60000` | Pre-step catalog cache refresh interval (ms): how often the per-workspace unified `mstar-engine-status` catalog row (watermark + iteration gate + workspace-state digest) re-reads `status.json` / the compass / the knowledge index. The hot path is a timestamp compare + cache hit between refreshes; a mid-session plan/compass/residual change lands within one interval. |
|
|
@@ -133,7 +133,7 @@ A `tools/pre-execute` branch (BEFORE the subagent prompt branch) gates the **`wo
|
|
|
133
133
|
|
|
134
134
|
## LLM fallbacks integration
|
|
135
135
|
|
|
136
|
-
The optional `dsh-llm-fallbacks` plugin (installed with the second command — see Install paths) powers **role-based subagent configuration
|
|
136
|
+
The optional `dsh-llm-fallbacks` plugin (installed with the second command — see Install paths) powers **role-based subagent configuration** — the role seeds and the adoption advisory; role persona delivery itself rides dsh's NATIVE subagent persona channel (independent of fallbacks, see below). The mstar plugin carries **zero runtime AND zero type references** to the package — `src/` has no import of it (runtime or type); the consumed service surface is mirrored by the local structural types in `src/gates/fallbacks-structural.ts`, and the package itself is a **dev-time-only dependency** of the mstar plugin (type mirroring + the real-package test harness). `dist/` names the package only in ONE string literal — the probe's loader-entry match — never an import or a type reference; the interop is a decision-point **capability probe**, never a module-internals read.
|
|
137
137
|
|
|
138
138
|
### Capability probe
|
|
139
139
|
|
|
@@ -144,15 +144,13 @@ Two views over the mounted state (point-in-time reads at decision points, no cac
|
|
|
144
144
|
|
|
145
145
|
Distinct states: **mounted** (service applied — full capability), **unmounted** (no entry: the fallbacks plugin was not installed — the mstar capability degrades, never breaks), **disabled** (entry present but disabled/grouped — capability off), and the HMR window (entry lives, service absent — the loader fallback covers it).
|
|
146
146
|
|
|
147
|
-
### Role
|
|
147
|
+
### Role persona delivery (native subagent persona channel)
|
|
148
148
|
|
|
149
|
-
|
|
149
|
+
Persona delivery rides dsh's NATIVE `SubagentStartRequest.persona` slot (`@deepseek-ai/dsh-subagent`): the plugin intercepts the `ctx.subagents` service READ through the cordis `internal/get` waterfall — the framework's documented service-read interception hook — and wraps the runtime value so a role-matched start merges the persona into the request BEFORE the child is composed — on BOTH start surfaces: the one-shot `start` AND the opt-in continuable `startContinuable` (tool-subagent `backgroundMode: 'continuable'`; its `ContinuableStartSpec.request` carries the same `persona` slot). The underlying `SubagentRuntime` object is never mutated (no monkey-patching), and the wrapping listener is fiber-scoped (an HMR re-apply unwinds and restores it, re-binding the fresh Config). Native semantics (dsh `0.1.2-alpha.2`): the request persona registers the scoped `deployment:persona` section (order 0) on the child, SHADOWING the deployment persona for that child alone — the child EMBODIES the role persona instead of coexisting with it — is persisted in the child descriptor, and is reapplied on resume. Role identity uses the SAME engine Assignment header grammar as the dispatch gate. Persona lookup is the single `personaFor` chain — `rolePersonas[executeAs]` → bundled mirror default → skip — **never gated on `roleMap` or on the fallbacks mounted state** (persona delivery is fallbacks-independent). An explicit request persona (tool-subagent's own `Config.persona`) wins over the role persona — caller intent is never overridden.
|
|
150
150
|
|
|
151
|
-
**
|
|
152
|
-
|
|
153
|
-
**Unmounted degradation is same-channel + one debug log**: no fallbacks entry → the persona is still injected through the identical decoration channel (from the mstar Config or the harness-agents mirror default), with exactly one source-aware debug log; mounted → one info-level interop log carrying the service version. The listener never throws — `agents` service absent, child unresolvable, non-Assignment or role-unmatched prompts are skip/no-op (the dispatch itself is never affected).
|
|
151
|
+
**Capability gate (per surface)**: one-shot `SubagentRuntime.start` REJECTS a persona request for a provider without the native `persona` capability (fail loud, no silent degradation — out-of-process providers ship without it), so the channel checks `getProvider(name).capabilities.persona` FIRST on that surface. The continuable surface is gated by the NATIVE continuable contract instead — `SubagentCapabilities` is documented as ONE-SHOT-scoped and continuable children are composed by the continuation manager itself, gated by `provider.prepareContinuable`; the channel checks that, skipping the merge for providers without continuable support (the native start fails loud on its own — the persona is never logged as delivered for a start that would reject). Either way the merge is skipped with one contained debug log and the start proceeds unchanged — never a failed dispatch.
|
|
154
152
|
|
|
155
|
-
**
|
|
153
|
+
**Zero-config defaults**: when `rolePersonas` has no entry for a role, the persona comes from the bundled `harness-agents/` mirror — the repo-root `agents/` shells synced by `bundle-assets` at build (shipped in the published tarball; package-relative resolution, so the bundle works from any launch cwd). The shell file stem is the role id; the default is its frontmatter `description` block scalar. A shell is eligible when its frontmatter `mode` is absent or `subagent` — the `primary` shell (`project-manager`) is never offered as a subagent persona default. A default whose description carries the interpolation hazard (`{{` paired with a later `}}`) is warned + skipped at extraction (never a boot throw); a shell edit (mtime change) re-extracts on the next decision-point read. With the mirror absent (`bundle-assets` not run) lookups are config-only, and a config miss logs one debug per apply.
|
|
156
154
|
|
|
157
155
|
### Role seeds + adoption advisory
|
|
158
156
|
|
|
@@ -172,8 +170,8 @@ On the loader-fallback path (no service) the structural `roles.list` read is pre
|
|
|
172
170
|
|
|
173
171
|
| Key | Type | Default | Meaning |
|
|
174
172
|
| --- | --- | --- | --- |
|
|
175
|
-
| `roleMap` | `Record<string, string>` | unset | mstar role id → fallbacks role id. **Taxonomy bridge** for logging + future rule-driven interop only — unused
|
|
176
|
-
| `rolePersonas` | `Record<string, string>` | unset (bundled mirror default) | mstar role id → persona text; the
|
|
173
|
+
| `roleMap` | `Record<string, string>` | unset | mstar role id → fallbacks role id. **Taxonomy bridge** for logging + future rule-driven interop only — unused by the persona channel by design (persona delivery is `rolePersonas`/mirror-sourced). |
|
|
174
|
+
| `rolePersonas` | `Record<string, string>` | unset (bundled mirror default) | mstar role id → persona text; the persona channel's **override** source — a mirror default is used when a role has no entry. |
|
|
177
175
|
|
|
178
176
|
## Service
|
|
179
177
|
|
|
@@ -504,7 +502,7 @@ closed and archived 2026-08-10.
|
|
|
504
502
|
|
|
505
503
|
## Development
|
|
506
504
|
|
|
507
|
-
Commands (from `packages/dsh`): the coverage gate is per-file 100% on `src/` (dsh testing policy); the build bun-bundles the src entries into `dist/` (engine + schemastery inlined; `@deepseek-ai/cordis` and the runtime seam imports — `@deepseek-ai/dsh-skill-filesystem`, `@deepseek-ai/dsh-tools` (`defineTool`), `@deepseek-ai/dsh-llm` — external
|
|
505
|
+
Commands (from `packages/dsh`): the coverage gate is per-file 100% on `src/` (dsh testing policy); the build bun-bundles the src entries into `dist/` (engine + schemastery inlined; `@deepseek-ai/cordis` and the runtime seam imports — `@deepseek-ai/dsh-skill-filesystem`, `@deepseek-ai/dsh-tools` (`defineTool`), `@deepseek-ai/dsh-llm` — external), runs `build-client` (`scripts/build-client-bundle.ts` — the closure-factory CJS browser bundle per spec §6.2, `dist/client.js`) and emits tsc declarations.
|
|
508
506
|
|
|
509
507
|
```sh
|
|
510
508
|
bun test --coverage
|
|
@@ -558,13 +556,13 @@ The catalog row is appended at the END of the composed step messages, after dele
|
|
|
558
556
|
- **Profile-bundle install into the `web` profile: registry and local checkout** — `dsh plugin --profile web add @mstar-harness/dsh` (registry) and `add <local checkout>` are the supported paths; both run through the same pnpm + reconcile mechanism (the reconcile step joins `@mstar-harness/dsh` to `dsh.profile.bundles`). A local checkout needs a prior `bun run build` — the package has no `prepare` script (the monorepo builds packages explicitly), so an unbuilt checkout installs an empty `dist/`.
|
|
559
557
|
- **`lintSkillWrite` typed veto not production-wired** — the incoming-document hard veto (`SkillLintVetoError`, code `skill-lint.veto`) is exported and test-covered, but has no production caller yet: the engine `HostAdapter` has no content-carrying skill-write hook (only `beforeStatusWrite`/`beforeDispatch`/`beforeMerge`), and the fs intent slot is content-blind. Wiring lands with a future content-carrying hook; until then the listener path enforces only via the repair-escape advisory (never a veto).
|
|
560
558
|
- **CLI `HOST_SIGNALS` lacks the `subagent` token** — the engine `ToolSignal` union includes it and `detectHost` handles it, but `packages/cli` `HOST_SIGNALS` is not updated yet, so `mstar host detect --signals subagent` would reject until the CLI list is updated on upstreaming.
|
|
561
|
-
- **Entry is a module index over `src/gates/*`** — the split shipped: `src/index.ts`
|
|
559
|
+
- **Entry is a module index over `src/gates/*`** — the split shipped: `src/index.ts` re-exports the frozen 56-name export surface (31 value + 25 type-only names; `Config` counts once) from the gate modules (`_shared` / `status` / `skill-lint` / `seams` / `dispatch` / `catalog` / `tools` / `adapter`) and keeps the plugin manifest, the single cordis augmentation point, the command registration, and the `apply()` startup wiring. The surface is frozen by `tests/export-surface.spec.ts` — the runtime value-export set plus, under `typecheck:tests` (`bunx tsc --noEmit -p tests/tsconfig.json`), the value-namespace identity and the per-name type-only probes.
|
|
562
560
|
- **Engine dsh rows are upstreaming-destined** — the dsh changes to engine `host.ts` (`DetectResult`, `ToolSignal`, `resolveSkillRoot`) live in the mstar-workflow engine mirror and are intended for a user-authorized upstream PR into mstar-harness; the `mstar-host` skill mirror (§ Detect / § Resolve loaded skill root / `references/dsh.md`) updates with it.
|
|
563
561
|
- **Iteration stepper: Step 1 is compass-driven, Step 5 is schema-driven** — the zone dashboard's Step 1 (iteration-start) is the current step while the steering compass is `status: active` (Phase 1 in flight — no gate verdict, so no PASS/FAIL badge); Step 5 (merge-ready) is a schema constant the engine gate never lights as current (transition covers Phase 2→3→4 only), so it always renders idle — recorded in the iteration guide, not a defect. The full panel-limitation list lives in the Web client plugin section.
|
|
564
|
-
- **`dsh-llm-fallbacks` is
|
|
562
|
+
- **`dsh-llm-fallbacks` is an optional dev-time-only dependency** — dsh `0.1.2-alpha.2` natively covers subagent customization, so fallbacks is strictly optional: `src/` carries zero imports of it (runtime and type — the consumed surface is the local structural mirror `fallbacks-structural.ts`, kept in sync by the probe's exact-keys drift gate plus the `typecheck:tests` real → view assignability check), `package.json` carries it only under `devDependencies` (type mirroring + the real-package test harness), and `dist/` carries no import and no type reference (only ONE string literal naming the package — the probe's loader-entry match; the advisory logs say `fallbacks`). Activation is a SEPARATE explicit install (two-command contract), never transitive; there is no `--external` guard anymore — a future value import must re-add a runtime dependency by design.
|
|
565
563
|
- **Role→model override NOT delivered this batch** — routing a role to a fallbacks `model` (or persona via fallbacks rules) would require rewriting the child's `agentOptions` on the start request, but start-request options are caller-controlled (tool-subagent's own Config; call args are `description`/`prompt`/`run_in_background` only, deep-frozen). Awaits upstream `fallbacks-explicit-role-tool` or the N-B1 systemPrompt adoption (roadmap §10.4).
|
|
566
|
-
- **
|
|
567
|
-
- **Persona injection is fallbacks-independent** — `dsh-llm-fallbacks` only routes LLM failures; it is never required for
|
|
564
|
+
- **Persona delivery is dsh-native — no additive section** — the role persona merges into `SubagentStartRequest.persona` (one-shot `start` AND the opt-in continuable `startContinuable`) and SHADOWS the deployment persona for role-matched children (child embodies the role; persisted + reapplied on resume). There is NO `mstar:role-persona` system-prompt section anymore (plan 20260831-dsh-alpha2-optional-fallbacks).
|
|
565
|
+
- **Persona injection is fallbacks-independent** — `dsh-llm-fallbacks` only routes LLM failures; it is never required for persona delivery. Unmounted → the same persona lands via the native channel with the single delivery debug log (AC-4). One-shot starts for providers without the native `persona` capability (out-of-process) skip the persona with one contained debug log; continuable starts for providers without `prepareContinuable` skip it the same way (the native start fails loud on its own) — the start is never failed by the channel for either.
|
|
568
566
|
- **Fork gating is default-only; explicit `dispatchTools` can omit `subagent_fork`** — a custom `dispatchTools` list overrides the default wholesale (pre-existing rename pattern), so a deployment that declares its own list must include `subagent_fork` to keep fork dispatches gated.
|
|
569
567
|
- **Persona values must not contain `{{...}}`** — dsh system-prompt renders persona text with strict `{{variable}}` interpolation and throws on a `{{` paired with a later `}}` (unknown/malformed/undefined reference), which would break child prompt assembly for every role-matched dispatch. The Config schema rejects such `rolePersonas` values at plugin mount with a clear error; the escape rule is single braces or rewording (a lone `{{` with no later `}}` renders as literal prose).
|
|
570
568
|
- **Seed re-convergence after a fallbacks HMR re-mount is bounded by the seeded-only preservation design** — the seed registry is per-apply in-memory state, so a fiber swap (HMR / settings edit) drops it and both declarers re-declare from scratch. The mstar re-declare merge-preserves ONLY ids that are already seeded (seeded-only by design), so in the preset-last commit ordering the preset rows' seeded annotations are not restored by the re-declare — they recover at the NEXT fallbacks apply (the upstream preset self-declare re-seeds them). The advisory one-shot latch re-arms when the `llm-fallbacks` service disappears (an inject teardown), so the next decision point re-converges the mstar side; the preset side is a documented transient of the seeded-only preservation design.
|
package/README.zh.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
[English](README.md) | 中文
|
|
4
4
|
|
|
5
|
-

|
|
6
6
|
|
|
7
7
|
让 [Morning Star](https://github.com/btspoony/mstar-harness) 成为一等公民的 dsh(DeepSeek Harness)宿主——一个 cordis 函数插件,将 mstar engine 进程内挂载,实现 engine `HostAdapter`(`host: 'dsh'`),守护 `{HARNESS_DIR}/status.json` 写入(校验 + 咨询;hard 下按修复逃生放行),在 `Enforcement: hard` 开启时阻止被禁止的 subagent 派发,对挂载技能根下的 `SKILL.md` 写入执行技能撰写 lint,通过 dsh skill-filesystem 提供者挂载 mstar `skills/` 镜像(单一规范挂载),并向每个组合后的 agent 步骤追加一条持久化的 `mstar-engine-status` catalog 行。随 dsh Loader 应用启动;一切均通过 seam 的拒绝/咨询通道行使职责,从不改动工具本身。
|
|
8
8
|
|
|
@@ -51,8 +51,8 @@ dsh plugin --profile web add dsh-llm-fallbacks
|
|
|
51
51
|
| `enforcement` | `'hard' \| 'soft'` | compass,否则仅告警 | 按部署覆盖。优先级:Config 优先;否则取 Assignment 自身的 `**Enforcement**: hard` 头字段(仅派发闸门);否则取仓库 `.mstarc` `[config] enforcement`;否则取迭代 compass frontmatter;否则仅告警。Config / `.mstarc` `soft` 是仅有的本地回滚——Assignment 级 `soft` 不能覆盖 hard compass。 |
|
|
52
52
|
| `dispatchTools` | `string[]` | `['subagent', 'subagent_fork']` | 派发闸门匹配的委派工具名——dsh preset 的**两个**委派工具:`subagent` 及其 fork 兄弟 `subagent_fork`(两者都携带 Assignment 形态的 `{ description, prompt }` 参数;`toolName` 配置可重命名实例)。 |
|
|
53
53
|
| `dispatchBinding` | `string` | 未设置 → hard 下 fail-closed `empty-binding` | 派发方 agent 自身的 harness 角色(反递归 caller);Assignment 的 `Execute as` 等于它即自我递归。 |
|
|
54
|
-
| `roleMap` | `Record<string, string>` | 未设置 | mstar 角色 id(`Execute as`)→ dsh-llm-fallbacks 角色 id
|
|
55
|
-
| `rolePersonas` | `Record<string, string>` | 未设置(打包镜像默认) | mstar 角色 id(`Execute as`)→ persona
|
|
54
|
+
| `roleMap` | `Record<string, string>` | 未设置 | mstar 角色 id(`Execute as`)→ dsh-llm-fallbacks 角色 id。**仅**作日志与未来规则驱动互操作的分类桥——persona 通道从不读取它(见 LLM fallbacks integration)。 |
|
|
55
|
+
| `rolePersonas` | `Record<string, string>` | 未设置(打包镜像默认) | mstar 角色 id(`Execute as`)→ persona 文本;原生 subagent persona 通道的**覆盖**来源——角色匹配的 start(一次性 `start` 或可选的 continuable `startContinuable`)会把 persona 合入原生请求的 `persona` 槽(子会话体现角色 persona 而**非**部署 persona;持久化并在 resume 时重放);某角色未设置时使用打包的 `harness-agents/` 镜像默认值(见 LLM fallbacks integration)。 |
|
|
56
56
|
| `skillRoots` | `string[]` | 未设置(不注册自定义根) | 向 dsh skill-filesystem 提供者注册的额外技能根(`customSkillDirs` 语义——先于用户根扫描)。开发期:镜像 `<repo-root>/skills` 的绝对路径。 |
|
|
57
57
|
| `bundledSkillDir` | `string` | 打包的 `harness-skills/` 镜像(包相对路径) | 向 dsh skill-filesystem 提供者注册的打包技能根(`bundledSkillDir` 语义——最后扫描、受信任)。默认取包内自带的 `harness-skills/` 镜像(`bundle-assets` 同步;gitignore)——包相对路径,**非** cwd 锚定。显式值优先。 |
|
|
58
58
|
| `catalogTtlMs` | `number` | `60000` | pre-step catalog 缓存刷新间隔(毫秒):按工作区缓存的统一 `mstar-engine-status` 行(水印 + 迭代闸门 + 工作区摘要)多久重读一次 `status.json` / compass / 知识索引。刷新间隔之间热路径只是时间戳比较 + Map 命中;会话中 plan/compass/residual 的变化会在一个间隔内落地。 |
|
|
@@ -133,7 +133,7 @@ profile bundle 组合出以下行——注册表行来自 `@deepseek-ai/dsh-base
|
|
|
133
133
|
|
|
134
134
|
## LLM fallbacks integration
|
|
135
135
|
|
|
136
|
-
可选的 `dsh-llm-fallbacks` 插件(以第二条命令安装——见 Install paths)驱动**基于角色的 subagent
|
|
136
|
+
可选的 `dsh-llm-fallbacks` 插件(以第二条命令安装——见 Install paths)驱动**基于角色的 subagent 配置**——角色种子与采纳建议;角色 persona 交付本身走 dsh 原生 subagent persona 通道(与 fallbacks 无关,见下文)。mstar 插件对该包携带**零运行时与零类型引用**——`src/` 无任何导入(运行时或类型);被消费的服务面由 `src/gates/fallbacks-structural.ts` 的本地结构类型镜像,该包仅是 mstar 插件的**开发期依赖**(类型镜像 + 真实包测试 harness)。`dist/` 仅在 1 处字符串字面量中命名该包——探测的 loader 条目匹配——绝非导入或类型引用;互操作是决策点**能力探测**,绝不读取其他插件的模块内部。
|
|
137
137
|
|
|
138
138
|
### 能力探测
|
|
139
139
|
|
|
@@ -144,15 +144,13 @@ profile bundle 组合出以下行——注册表行来自 `@deepseek-ai/dsh-base
|
|
|
144
144
|
|
|
145
145
|
状态区分:**mounted**(服务已 apply——完整能力)、**unmounted**(无条目:未安装 fallbacks 插件——mstar 能力降级,绝不中断)、**disabled**(条目存在但禁用/分组——能力关闭),以及 HMR 窗口(条目在、服务缺——loader 回退覆盖)。
|
|
146
146
|
|
|
147
|
-
###
|
|
147
|
+
### 角色 persona 交付(原生 subagent persona 通道)
|
|
148
148
|
|
|
149
|
-
|
|
149
|
+
persona 交付走 dsh 原生的 `SubagentStartRequest.persona` 槽(`@deepseek-ai/dsh-subagent`):插件经 cordis `internal/get` waterfall——框架文档化的服务读取拦截钩子——拦截 `ctx.subagents` 的服务读取并包装运行时值,使角色匹配的 start 在子会话组装之前把 persona 合入请求——**同时覆盖两个启动面**:一次性 `start` 与可选的 continuable `startContinuable`(tool-subagent `backgroundMode: 'continuable'`;其 `ContinuableStartSpec.request` 携带同一个 `persona` 槽)。底层 `SubagentRuntime` 对象绝不被改动(无 monkey-patching),包装监听器归 apply fiber 所有(HMR 重挂载会先卸载再恢复,并重新绑定新 Config)。原生语义(dsh `0.1.2-alpha.2`):请求 persona 会以作用域化的 `deployment:persona` 段(order 0)注册到子会话上,对该子会话**遮蔽**部署 persona——子会话**体现**角色 persona 而非与其共存——并持久化进子会话描述符、在 resume 时重放。角色身份使用与派发闸门相同的 engine Assignment 头语法。persona 查找是单一 `personaFor` 链——`rolePersonas[executeAs]` → 打包镜像默认 → 跳过——**从不以 `roleMap` 或 fallbacks 挂载状态为前提**(persona 交付与 fallbacks 无关)。显式的请求 persona(tool-subagent 自身的 `Config.persona`)优先于角色 persona——绝不覆盖调用方意图。
|
|
150
150
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
**未挂载的降级为同通道 + 一条 debug 日志**:无 fallbacks 条目 → persona 仍经完全相同的装饰通道注入(来自 mstar Config 或 harness-agents 镜像默认值),仅多一条来源可辨的 debug 日志;已挂载 → 一条携带服务版本的 info 级互操作日志。监听器绝不抛出——`agents` 服务缺失、子会话无法解析、非 Assignment 或角色未匹配的提示均跳过/无操作(派发本身永不受影响)。
|
|
151
|
+
**能力闸门(按启动面)**:一次性 `SubagentRuntime.start` 会对不具备原生 `persona` 能力的提供者直接拒绝 persona 请求(fail loud、绝不静默降级——进程外提供者即无此能力),因此该启动面通道先检查 `getProvider(name).capabilities.persona`。continuable 启动面改按**原生 continuable 契约**闸门——`SubagentCapabilities` 文档仅限一次性路径,continuable 子会话由延续管理器自行组装、以 `provider.prepareContinuable` 为闸门;通道检查该字段,对不支持 continuable 的提供者跳过合并(原生 start 会自行 fail loud——绝不会在会被拒绝的 start 上把 persona 记为已交付)。两种情况都以一条受控 debug 日志跳过合并、启动原样继续——通道绝不因此使派发失败。
|
|
154
152
|
|
|
155
|
-
|
|
153
|
+
**零配置默认值**:当 `rolePersonas` 未为某角色配置条目时,persona 取自打包的 `harness-agents/` 镜像——构建时由 `bundle-assets` 从仓库根 `agents/` 同步(随发布 tarball 携带;包相对路径解析,任意启动 cwd 均可用)。镜像文件名主干即角色 id;默认值为其 frontmatter `description` 块标量。镜像 shell 在 frontmatter `mode` 缺失或为 `subagent` 时才有资格——`primary` shell(`project-manager`)绝不作为 subagent persona 默认值。默认值 description 若含插值风险(配对的 `{{`/`}}`)则在提取时告警并跳过(绝非启动抛错);shell 改动(mtime 变化)会在下一次决策点读取时重新提取。镜像缺失(未运行 `bundle-assets`)时查找仅走配置,配置也未命中时每次 apply 记一条 debug。
|
|
156
154
|
|
|
157
155
|
### 角色 seeds 与采纳建议(Adoption advisory)
|
|
158
156
|
|
|
@@ -172,8 +170,8 @@ loader 回退路径(无服务)保留结构化 `roles.list` 读取(缺失 i
|
|
|
172
170
|
|
|
173
171
|
| Key | Type | Default | Meaning |
|
|
174
172
|
| --- | --- | --- | --- |
|
|
175
|
-
| `roleMap` | `Record<string, string>` | 未设置 | mstar 角色 id → fallbacks 角色 id
|
|
176
|
-
| `rolePersonas` | `Record<string, string>` | 未设置(打包镜像默认) | mstar 角色 id → persona
|
|
173
|
+
| `roleMap` | `Record<string, string>` | 未设置 | mstar 角色 id → fallbacks 角色 id。**仅**作日志与未来规则驱动互操作的分类桥——persona 通道按设计不使用(persona 交付以 `rolePersonas`/镜像为源)。 |
|
|
174
|
+
| `rolePersonas` | `Record<string, string>` | 未设置(打包镜像默认) | mstar 角色 id → persona 文本;persona 通道的**覆盖**来源——某角色无条目时使用镜像默认值。 |
|
|
177
175
|
|
|
178
176
|
## Service
|
|
179
177
|
|
|
@@ -280,7 +278,7 @@ dsh web # 启动 → 服务 /plugins/@mstar-harness/dsh/clie
|
|
|
280
278
|
|
|
281
279
|
## Development
|
|
282
280
|
|
|
283
|
-
命令(在 `packages/dsh` 下执行):覆盖率门禁为 `src/` 逐文件 100%(dsh 测试策略);构建命令把 src 条目 bun 打包进 `dist/`(内联 engine 与 schemastery;`@deepseek-ai/cordis` 与运行时 seam 导入——`@deepseek-ai/dsh-skill-filesystem`、`@deepseek-ai/dsh-tools`(`defineTool`)、`@deepseek-ai/dsh-llm
|
|
281
|
+
命令(在 `packages/dsh` 下执行):覆盖率门禁为 `src/` 逐文件 100%(dsh 测试策略);构建命令把 src 条目 bun 打包进 `dist/`(内联 engine 与 schemastery;`@deepseek-ai/cordis` 与运行时 seam 导入——`@deepseek-ai/dsh-skill-filesystem`、`@deepseek-ai/dsh-tools`(`defineTool`)、`@deepseek-ai/dsh-llm`——保持外部),运行 `build-client`(`scripts/build-client-bundle.ts`——按 spec §6.2 产出的 closure-factory CJS 浏览器 bundle `dist/client.js`)并输出 tsc 声明。
|
|
284
282
|
|
|
285
283
|
```sh
|
|
286
284
|
bun test --coverage
|
|
@@ -331,13 +329,13 @@ catalog 行在委托之后追加到组合步骤消息的**末尾**——请求
|
|
|
331
329
|
- **profile-bundle 安装到 `web` profile:registry 与 local checkout**——`dsh plugin --profile web add @mstar-harness/dsh`(registry)与 `add <本地检出>` 为受支持途径,均走同一 pnpm + reconcile 机制(reconcile 步骤把 `@mstar-harness/dsh` 并入 `dsh.profile.bundles`)。local checkout 需要先执行 `bun run build`——本包没有 `prepare` 脚本(monorepo 显式构建各包),未构建的检出会装入空的 `dist/`。
|
|
332
330
|
- **`lintSkillWrite` 类型化否决尚未接入生产**——传入文档分支的 hard 否决(`SkillLintVetoError`,码 `skill-lint.veto`)已导出并测试覆盖,但尚无生产调用方:engine `HostAdapter` 没有携带内容的技能写入钩子(只有 `beforeStatusWrite`/`beforeDispatch`/`beforeMerge`),且 fs intent 槽位内容盲。接线随未来携带内容的钩子落地;在此之前监听器路径只通过修复逃生咨询执行(从不否决)。
|
|
333
331
|
- **CLI `HOST_SIGNALS` 缺少 `subagent` token**——engine `ToolSignal` 联合已包含它且 `detectHost` 能处理,但 `packages/cli` 的 `HOST_SIGNALS` 尚未更新,`mstar host detect --signals subagent` 会拒绝,直到上游化时更新 CLI 列表。
|
|
334
|
-
- **入口是 `src/gates/*` 之上的模块索引**——拆分已交付:`src/index.ts
|
|
332
|
+
- **入口是 `src/gates/*` 之上的模块索引**——拆分已交付:`src/index.ts` 从各 gate 模块(`_shared` / `status` / `skill-lint` / `seams` / `dispatch` / `catalog` / `tools` / `adapter`)原样 re-export 冻结的 56 名导出面(31 值导出 + 25 type-only 名;`Config` 计一次),并保留插件 manifest、单一 cordis augmentation 点、命令注册与 `apply()` 启动接线。导出面由 `tests/export-surface.spec.ts` 冻结——运行时值导出集 + `typecheck:tests`(`bunx tsc --noEmit -p tests/tsconfig.json`)下的值命名空间恒等与逐名类型探测。
|
|
335
333
|
- **engine dsh 行待上游化**——engine `host.ts` 的 dsh 改动(`DetectResult`、`ToolSignal`、`resolveSkillRoot`)位于 mstar-workflow engine 镜像,计划经用户授权的上游 PR 合入 mstar-harness;`mstar-host` 技能镜像(§ Detect / § Resolve loaded skill root / `references/dsh.md`)随之一并更新。
|
|
336
334
|
- **迭代 stepper:Step 1 为 compass 驱动,Step 5 为 schema 驱动**——zone dashboard 的 Step 1(iteration-start)在 steering compass `status: active`(Phase 1 进行中)时为当前步(无 gate 判定 → 无 PASS/FAIL 徽标);Step 5(merge-ready)是 engine 闸门永不点亮为当前的 schema 常量(transition 只覆盖 Phase 2→3→4,merge-ready 从不是 gate transition);仅当 Step 4 为当前步时作为 `next` 渲染,其余为 idle——已记录于迭代 guide,非缺陷。完整面板限制清单见 Web 客户端插件一节。
|
|
337
|
-
- **`dsh-llm-fallbacks`
|
|
335
|
+
- **`dsh-llm-fallbacks` 为可选的开发期依赖**——dsh `0.1.2-alpha.2` 原生覆盖 subagent 定制,fallbacks 因此严格可选:`src/` 对其零导入(运行时与类型——被消费面是本地结构镜像 `fallbacks-structural.ts`,由探测的 exact-keys 漂移闸门 + `typecheck:tests` 的 real → view 可赋值检查保持同步),`package.json` 仅在 `devDependencies` 携带它(类型镜像 + 真实包测试 harness),`dist/` 无导入也无类型引用(仅 1 处命名该包的字符串字面量——探测的 loader 条目匹配;建议日志写作 `fallbacks`)。激活是**单独显式安装**(双命令契约),绝不传递;不再有 `--external` 护栏——未来的值导入必须按设计重新加入运行时依赖。
|
|
338
336
|
- **本批次未交付角色→模型覆盖**——把角色路由到 fallbacks `model`(或经 fallbacks 规则路由 persona)需要改写启动请求上的子会话 `agentOptions`,但启动请求选项由调用方控制(tool-subagent 自己的 Config;调用参数仅为 `description`/`prompt`/`run_in_background`,且深度冻结)。等待上游 `fallbacks-explicit-role-tool` 或 N-B1 systemPrompt 采纳(roadmap §10.4)。
|
|
339
|
-
-
|
|
340
|
-
- **persona 注入与 fallbacks 无关**——`dsh-llm-fallbacks` 只路由 LLM
|
|
337
|
+
- **persona 交付为 dsh 原生——不再有附加段**——角色 persona 合入 `SubagentStartRequest.persona`(一次性 `start` 与可选的 continuable `startContinuable` 两个启动面),对角色匹配的子会话**遮蔽**部署 persona(子会话体现角色;持久化并在 resume 时重放)。`mstar:role-persona` system-prompt 段已不复存在(plan 20260831-dsh-alpha2-optional-fallbacks)。
|
|
338
|
+
- **persona 注入与 fallbacks 无关**——`dsh-llm-fallbacks` 只路由 LLM 失败;persona 交付从不依赖它。未挂载 → 同一 persona 经原生通道交付,仅一条交付 debug 日志(AC-4)。一次性 start 中不具备原生 `persona` 能力的提供者(进程外)以一条受控 debug 日志跳过 persona;continuable start 中不具备 `prepareContinuable` 的提供者同样跳过(原生 start 会自行 fail loud)——通道绝不因两者使 start 失败。
|
|
341
339
|
- **fork 门禁仅默认开启;显式 `dispatchTools` 可省略 `subagent_fork`**——自定义 `dispatchTools` 列表整体覆盖默认(既有重命名模式),因此自行声明列表的部署须包含 `subagent_fork` 才能继续门禁 fork 派发。
|
|
342
340
|
- **persona 值绝不能包含 `{{...}}`**——dsh system-prompt 以严格 `{{variable}}` 插值渲染 persona 文本,对与后文 `}}` 配对的 `{{`(未知/畸形/未定义引用)直接抛错,会破坏每一次角色匹配派发的子会话提示组装。Config schema 在插件挂载时以清晰报错拒绝此类 `rolePersonas` 值;转义规则是改用单花括号或改写措辞(不带后续 `}}` 的孤立 `{{` 按字面散文渲染)。
|
|
343
341
|
- **fallbacks HMR 重挂后的 seeds 再收敛受 seeded-only preservation 设计边界限制**——seed registry 是每次 apply 的内存态,纤程切换(HMR / 设置编辑)会丢弃它并让双方 declarer 从头重放。mstar re-declare 只合并保留**已 seeded** 的 id(seeded-only,设计使然),因此在 preset-last 提交顺序下,preset 行的 seeded 注记不会被 re-declare 恢复——它们在下一次 fallbacks apply 时恢复(上游 preset 自声明重新播种)。`llm-fallbacks` 服务消失时 advisory 一次性 latch 会重新武装(inject teardown),因此下一个决策点会重新收敛 mstar 侧;preset 侧是 seeded-only preservation 设计的有文档说明的暂时现象。
|
package/dist/client/index.d.ts
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* thunk — the trajectory precedent shape). The tab label re-reads through
|
|
9
9
|
* `ctx.locale.bind(NS)` so a locale switch flips it without re-registering.
|
|
10
10
|
*/
|
|
11
|
-
import type { ClientContext } from '@deepseek-ai/
|
|
11
|
+
import type { Context as ClientContext } from '@deepseek-ai/cordis';
|
|
12
12
|
/** Cordis service faces the plugin waits for (spec §4.4: slots + sessions + locale). */
|
|
13
13
|
export declare const inject: string[];
|
|
14
14
|
export declare function apply(ctx: ClientContext): void;
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
*
|
|
5
5
|
* Inputs: the session standard kit (`ConvViewProps`) and the typed `t` seat
|
|
6
6
|
* (`locale: 'mstar-panel'`). The catalog row + message time come from the
|
|
7
|
-
* `useMstarEngineStatus()` hook riding the kit's `
|
|
7
|
+
* `useMstarEngineStatus()` hook riding the kit's `useChat` selector (spec
|
|
8
8
|
* §5) — the render body is a pure function of (source, lastUpdated, t).
|
|
9
9
|
*
|
|
10
10
|
* Layout (spec panel-tabs §2, plan 20260811-panel-tabs-shell): root grid
|
|
@@ -64,4 +64,4 @@ export interface PanelContentProps {
|
|
|
64
64
|
* AgentEventDock — 无双份日志, the dock is removed with this plan).
|
|
65
65
|
*/
|
|
66
66
|
export declare function PanelContent({ tab, source, t }: PanelContentProps): React.JSX.Element;
|
|
67
|
-
export declare function PanelView({ t,
|
|
67
|
+
export declare function PanelView({ t, useChat }: MstarPanelViewProps): React.JSX.Element;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Data hook for the workflow panel (spec §5): subscribes to the active
|
|
3
|
-
* session's conversation
|
|
4
|
-
* (`
|
|
5
|
-
* `mstar-engine-status` catalog row.
|
|
3
|
+
* session's conversation log through the session standard kit's chat target
|
|
4
|
+
* (`useChat`, a uSES selector hook over the `chat` conversation view target)
|
|
5
|
+
* and scans the log for the latest `mstar-engine-status` catalog row.
|
|
6
6
|
*
|
|
7
7
|
* Node discriminator (spec §2.4): `kind === 'context'` + `form === 'catalog'`
|
|
8
8
|
* + `source.kind === 'mstar-engine-status'`; the LATEST row wins (snapshot
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
* instead of bubbling a crash (spec §5 degradation path; the strict-session
|
|
19
19
|
* slot normally guarantees a session — the guard is belt-and-suspenders).
|
|
20
20
|
*/
|
|
21
|
-
import type {
|
|
21
|
+
import type { ChatSnapshot } from '@deepseek-ai/dsh-client-ui-chat/client';
|
|
22
22
|
import type { SnapshotSelectorHook } from '@deepseek-ai/dsh-client-ui-slots';
|
|
23
23
|
import type { MstarEngineStatusSource } from '../../types.ts';
|
|
24
24
|
/** The hook result: the latest catalog row plus its message time (spec §5). */
|
|
@@ -28,10 +28,10 @@ export interface MstarEngineStatusView {
|
|
|
28
28
|
lastUpdated: number | null;
|
|
29
29
|
}
|
|
30
30
|
/**
|
|
31
|
-
* `useMstarEngineStatus(
|
|
32
|
-
* hook (spec §5). The session standard kit's `
|
|
31
|
+
* `useMstarEngineStatus(useChat): MstarEngineStatusView` — the panel's data
|
|
32
|
+
* hook (spec §5). The session standard kit's `useChat` is passed in (the
|
|
33
33
|
* view ring hands it to every `conversation.view` entry); the hook rides it as
|
|
34
|
-
* a selector over the
|
|
34
|
+
* a selector over the chat target snapshot, so a snapshot bump (new catalog
|
|
35
35
|
* row) re-runs the selection and refreshes the panel.
|
|
36
36
|
*
|
|
37
37
|
* The hook never throws (spec §5 degradation path; Task 3 contract): a
|
|
@@ -39,4 +39,4 @@ export interface MstarEngineStatusView {
|
|
|
39
39
|
* signal instead of bubbling a crash — the strict-session slot normally
|
|
40
40
|
* guarantees a session, the guard is belt-and-suspenders.
|
|
41
41
|
*/
|
|
42
|
-
export declare function useMstarEngineStatus(
|
|
42
|
+
export declare function useMstarEngineStatus(useChat: SnapshotSelectorHook<ChatSnapshot>): MstarEngineStatusView;
|
package/dist/client.js
CHANGED
|
@@ -4662,7 +4662,7 @@ function sameView(a, b) {
|
|
|
4662
4662
|
}
|
|
4663
4663
|
function selectEngineStatus(snapshot) {
|
|
4664
4664
|
try {
|
|
4665
|
-
const row = latestEngineStatusRow(snapshot.nodes);
|
|
4665
|
+
const row = latestEngineStatusRow(snapshot.legacy.nodes);
|
|
4666
4666
|
if (row === null)
|
|
4667
4667
|
return EMPTY;
|
|
4668
4668
|
return { source: row.source, lastUpdated: row.time };
|
|
@@ -4670,9 +4670,9 @@ function selectEngineStatus(snapshot) {
|
|
|
4670
4670
|
return EMPTY;
|
|
4671
4671
|
}
|
|
4672
4672
|
}
|
|
4673
|
-
function useMstarEngineStatus(
|
|
4673
|
+
function useMstarEngineStatus(useChat) {
|
|
4674
4674
|
try {
|
|
4675
|
-
const view =
|
|
4675
|
+
const view = useChat(selectEngineStatus, sameView);
|
|
4676
4676
|
return view ?? EMPTY;
|
|
4677
4677
|
} catch {
|
|
4678
4678
|
return EMPTY;
|
|
@@ -4703,8 +4703,8 @@ function PanelContent({ tab, source, t }) {
|
|
|
4703
4703
|
t
|
|
4704
4704
|
});
|
|
4705
4705
|
}
|
|
4706
|
-
function PanelView({ t,
|
|
4707
|
-
const { source, lastUpdated } = useMstarEngineStatus(
|
|
4706
|
+
function PanelView({ t, useChat }) {
|
|
4707
|
+
const { source, lastUpdated } = useMstarEngineStatus(useChat);
|
|
4708
4708
|
const [tab, setTab] = import_react3.useState("tasks");
|
|
4709
4709
|
if (source === null || source === undefined) {
|
|
4710
4710
|
return /* @__PURE__ */ jsx_runtime12.jsx("div", {
|
package/dist/gates/_shared.d.ts
CHANGED
|
@@ -73,22 +73,26 @@ export interface Config {
|
|
|
73
73
|
/**
|
|
74
74
|
* Taxonomy bridge: mstar role id → fallbacks role id (the
|
|
75
75
|
* `dsh-llm-fallbacks` role taxonomy). Logging + future rule-driven
|
|
76
|
-
* interop only — NOT required for persona
|
|
77
|
-
* the
|
|
76
|
+
* interop only — NOT required for persona delivery (`rolePersonas` is
|
|
77
|
+
* the channel's only payload source). Absent → no bridge mapping.
|
|
78
78
|
*/
|
|
79
79
|
roleMap?: Record<string, string>;
|
|
80
80
|
/**
|
|
81
|
-
* mstar role id → persona text — the
|
|
82
|
-
* source (plan `20260814-dsh-fallbacks-integration` Task 2
|
|
83
|
-
*
|
|
84
|
-
* `
|
|
85
|
-
*
|
|
86
|
-
*
|
|
87
|
-
*
|
|
81
|
+
* mstar role id → persona text — the native persona channel's only
|
|
82
|
+
* payload source (plan `20260814-dsh-fallbacks-integration` Task 2;
|
|
83
|
+
* channel reworked onto the native `SubagentStartRequest.persona` slot by
|
|
84
|
+
* plan `20260831-dsh-alpha2-optional-fallbacks` Task 3). A role-matched
|
|
85
|
+
* one-shot start merges the persona into the request's native `persona`
|
|
86
|
+
* slot — dsh composes it as the scoped shadowing `deployment:persona`
|
|
87
|
+
* section on the child, persists it in the child descriptor, and reapplies
|
|
88
|
+
* it on resume. Lookup is DIRECT — never gated on `roleMap` or on the
|
|
89
|
+
* fallbacks mounted state (persona delivery is fallbacks-independent).
|
|
90
|
+
* Absent → no merge.
|
|
88
91
|
*
|
|
89
|
-
* INTERPOLATION CONSTRAINT: dsh
|
|
90
|
-
*
|
|
91
|
-
*
|
|
92
|
+
* INTERPOLATION CONSTRAINT: dsh renders persona text with STRICT
|
|
93
|
+
* `{{variable}}` interpolation (the native persona has the same template
|
|
94
|
+
* semantics as the deployment persona) and throws on any `{{` paired with
|
|
95
|
+
* a later `}}` (unknown/malformed/undefined reference), so persona values
|
|
92
96
|
* MUST NOT contain that pattern — a violating persona would break child
|
|
93
97
|
* prompt assembly at the child's first render, for EVERY role-matched
|
|
94
98
|
* dispatch. The Config schema rejects such values at plugin mount with a
|
|
@@ -130,7 +134,8 @@ export interface Config {
|
|
|
130
134
|
* (`renderPrompt` → `interpolate` in `@deepseek-ai/dsh-system-prompt`) scans
|
|
131
135
|
* section text for `{{` and THROWS on any `{{` paired with a later `}}` in
|
|
132
136
|
* the same text (unknown variable, malformed group, or undefined value).
|
|
133
|
-
* Persona text lands in the `
|
|
137
|
+
* Persona text lands in the native request `persona` slot verbatim (the
|
|
138
|
+
* same STRICT `{{...}}` template semantics as the deployment persona), so a
|
|
134
139
|
* persona containing this pattern breaks child prompt assembly at the
|
|
135
140
|
* child's first render — every role-matched dispatch. The Config schema
|
|
136
141
|
* rejects such values at validation (plugin mount) with a clear error. The
|
|
@@ -156,12 +161,39 @@ export declare const PERSONA_INTERPOLATION_HAZARD: RegExp;
|
|
|
156
161
|
* can never break prompt assembly.
|
|
157
162
|
*/
|
|
158
163
|
export declare function stripInterpolationHazard(text: string): string;
|
|
159
|
-
/** Schemastery configuration schema for the plugin consumer. Object keys are optional by default (`.optional()` is a vendored-fork addition not present in npm schemastery); omitted ARRAY keys would materialize as `[]` (schemastery empty-value default — the tool-subagent `toolFilter` pitfall) and omitted DICT keys would materialize as `{}`, so the dispatch keys and the
|
|
164
|
+
/** Schemastery configuration schema for the plugin consumer. Object keys are optional by default (`.optional()` is a vendored-fork addition not present in npm schemastery); omitted ARRAY keys would materialize as `[]` (schemastery empty-value default — the tool-subagent `toolFilter` pitfall) and omitted DICT keys would materialize as `{}`, so the dispatch keys and the persona keys all preserve omission via `.default(undefined)`. */
|
|
160
165
|
export declare const Config: z<Config>;
|
|
161
166
|
/** One violation line for logs and the typed veto message. */
|
|
162
167
|
export declare function formatViolation(violation: ValidationResult): string;
|
|
163
168
|
/** Narrow an unknown value to a record. */
|
|
164
169
|
export declare function asRecord(value: unknown): Record<string, unknown> | undefined;
|
|
170
|
+
/**
|
|
171
|
+
* Cap on the plan / lease rows joined into the `<mstar_engine_status>`
|
|
172
|
+
* catalog state lines (plan `20260830-dsh-catalog-cap` D1): ONE catalog-owned
|
|
173
|
+
* constant shared by the `plans:` and `leases:` joins so an oversized
|
|
174
|
+
* workflow snapshot cannot balloon the single-line catalog state section.
|
|
175
|
+
* Numeric precedent: `DIGEST_PLAN_CAP` in `system-prompt.ts` (digest-side,
|
|
176
|
+
* non-Done-only — intentionally NOT reused here; the catalog renders the
|
|
177
|
+
* full, unfiltered snapshot rows).
|
|
178
|
+
*/
|
|
179
|
+
export declare const CATALOG_STATE_JOIN_LIMIT = 8;
|
|
180
|
+
/**
|
|
181
|
+
* Join the screened projection of `items` in catalog-array order, capped at
|
|
182
|
+
* `cap`: when `items.length > cap` the FIRST `cap` items render followed by
|
|
183
|
+
* a final `+N more` overflow marker (`N = items.length - cap`) as the last
|
|
184
|
+
* join element; at or under the cap the full join renders with no marker.
|
|
185
|
+
* The `render` callback owns any per-item `stripInterpolationHazard`
|
|
186
|
+
* screening (before the join, same as the uncapped code); the marker is an
|
|
187
|
+
* engine-derived literal and stays unscreened. Callers guard the empty case
|
|
188
|
+
* (`length === 0` → `none` / `none registered` / `none active`) — this
|
|
189
|
+
* helper is never reached for empty arrays.
|
|
190
|
+
*
|
|
191
|
+
* Hoisted from `system-prompt.ts` (plan `20260830-dsh-catalog-cap` D3) so
|
|
192
|
+
* the GLOBAL digest and the catalog state lines share ONE join-capping
|
|
193
|
+
* implementation; `_shared.ts` imports no gates-local module, so no import
|
|
194
|
+
* cycle is introduced.
|
|
195
|
+
*/
|
|
196
|
+
export declare function joinCapped<T>(items: readonly T[], cap: number, separator: string, render: (item: T) => string): string;
|
|
165
197
|
/**
|
|
166
198
|
* Resolve the hard-enforcement flag for the artifact gates: explicit
|
|
167
199
|
* Config override wins, else the repo `.mstarc` `[config] enforcement`,
|
|
@@ -19,12 +19,12 @@ export interface PersonaLookup {
|
|
|
19
19
|
/** The mirror root (`harness-agents/`); absent → mirror defaults are skipped. */
|
|
20
20
|
agentsDir?: string;
|
|
21
21
|
}
|
|
22
|
-
/** Warn sink for extraction-time hazards (bound by the
|
|
22
|
+
/** Warn sink for extraction-time hazards (bound by the persona channel to its warn sink). */
|
|
23
23
|
export type PersonaWarnSink = (message: string) => void;
|
|
24
24
|
/**
|
|
25
|
-
* The
|
|
25
|
+
* The persona channel's single lookup: `rolePersonas[roleId]` → mirror
|
|
26
26
|
* default → undefined. Pure — the mirror root is passed explicitly (the
|
|
27
|
-
*
|
|
27
|
+
* channel supplies the apply-bound packaged root; tests supply fixtures).
|
|
28
28
|
*
|
|
29
29
|
* @param roleId - the mstar role id (Assignment `Execute as`).
|
|
30
30
|
* @param lookup - the config override map and the mirror root.
|
|
@@ -36,14 +36,14 @@
|
|
|
36
36
|
* dispatch/apply flow is never affected).
|
|
37
37
|
*
|
|
38
38
|
* Module boundary: no barrel — the entry imports this module by explicit
|
|
39
|
-
* relative path (the
|
|
39
|
+
* relative path (the role-persona module pattern).
|
|
40
40
|
*/
|
|
41
41
|
import type { Context } from '@deepseek-ai/cordis';
|
|
42
42
|
/** Logger label for the adoption advisory (dsh logger naming: `<scope>/<subject>`). */
|
|
43
43
|
export declare const ADVISORY_LOGGER = "mstar/fallbacks-advisory";
|
|
44
44
|
/** Advisory log levels the module sink understands. */
|
|
45
45
|
export type AdvisoryLogLevel = 'debug' | 'warn';
|
|
46
|
-
/** Module-level advisory log sink — bound by `apply` to `ctx.logger(ADVISORY_LOGGER)` (
|
|
46
|
+
/** Module-level advisory log sink — bound by `apply` to `ctx.logger(ADVISORY_LOGGER)` (role-persona module pattern). */
|
|
47
47
|
export type AdvisoryLogSink = (level: AdvisoryLogLevel, message: string) => void;
|
|
48
48
|
/**
|
|
49
49
|
* Bind the advisory log sink (the entry `apply` binds it to
|
|
@@ -2,11 +2,17 @@
|
|
|
2
2
|
* Capability probes for the OPTIONAL `dsh-llm-fallbacks` plugin (plan
|
|
3
3
|
* `20260814-dsh-fallbacks-integration` Task 1 — probe foundation).
|
|
4
4
|
*
|
|
5
|
-
* The fallbacks plugin is
|
|
6
|
-
*
|
|
7
|
-
* ZERO runtime
|
|
5
|
+
* The fallbacks plugin is an optional SEPARATE install (two-command
|
|
6
|
+
* contract) and a dev-time-only dependency of this package: src carries
|
|
7
|
+
* ZERO imports of it (runtime and type) — the consumed service surface is
|
|
8
|
+
* the local structural mirror in `fallbacks-structural.ts`, so `dist/`
|
|
9
|
+
* carries zero runtime AND zero type references to `dsh-llm-fallbacks`.
|
|
10
|
+
* When the dev dependency is installed, the package's
|
|
8
11
|
* `declare module '@deepseek-ai/cordis'` augmentation types
|
|
9
|
-
* `ctx.get('llm-fallbacks')` for importers
|
|
12
|
+
* `ctx.get('llm-fallbacks')` for importers — under `typecheck:tests` the
|
|
13
|
+
* uncast return in {@link fallbacksService} is the compile-time real →
|
|
14
|
+
* view assignability gate (the published build never loads the
|
|
15
|
+
* augmentation; the untyped string overload applies there).
|
|
10
16
|
*
|
|
11
17
|
* Two views:
|
|
12
18
|
* - {@link fallbacksService} — the named cordis service while the plugin is
|
|
@@ -19,7 +25,7 @@
|
|
|
19
25
|
* concurrently (plugin-inventory philosophy).
|
|
20
26
|
*/
|
|
21
27
|
import type { Context } from '@deepseek-ai/cordis';
|
|
22
|
-
import type {
|
|
28
|
+
import type { FallbacksServiceView } from './fallbacks-structural.ts';
|
|
23
29
|
/** Loader entry name of the `dsh-llm-fallbacks` plugin row. */
|
|
24
30
|
export declare const FALLBACKS_ENTRY_NAME = "dsh-llm-fallbacks";
|
|
25
31
|
/**
|
|
@@ -44,7 +50,7 @@ export interface LoaderEntryView {
|
|
|
44
50
|
fiber: unknown;
|
|
45
51
|
}
|
|
46
52
|
/** Service view: the named `llm-fallbacks` cordis service while applied. */
|
|
47
|
-
export declare function fallbacksService(ctx: Context):
|
|
53
|
+
export declare function fallbacksService(ctx: Context): FallbacksServiceView | undefined;
|
|
48
54
|
/**
|
|
49
55
|
* The fallbacks loader row when present and enabled (group rows skipped).
|
|
50
56
|
* Unlike {@link fallbacksMounted}, NO live-fiber requirement: the entry is
|