# Changelog Chinese summary: [CHANGELOG_CN.md](CHANGELOG_CN.md). All notable changes to this repository are documented here. Published harness surfaces are at **2.3.0** unless noted: | Surface | Package / manifest | Version | | --- | --- | --- | | Monorepo root | `morning-star` (`package.json`) | **2.3.0** | | CLI | `@mstar-harness/cli` (`packages/cli`) | **2.3.0** | | Engine | `@mstar-harness/engine` (`packages/engine`) | **2.3.0** | | OpenCode plugin | `@mstar-harness/opencode` (`packages/opencode`) | **2.3.0** | | Cursor plugin | `.cursor-plugin/plugin.json` | **2.3.0** | | Codex plugin | `.codex-plugin/plugin.json` | **2.3.0** | | Kimi plugin | `.kimi-plugin/plugin.json` | **2.3.0** | | ZCode plugin | `.zcode-plugin/plugin.json` | **2.3.0** | | omp plugin | `.omp-plugin/plugin.json` / `.claude-plugin/plugin.json` | **2.3.0** | | Agent Plugins manifest | `plugin.json` | **2.3.0** | Package-specific histories: [`packages/cli/CHANGELOG.md`](packages/cli/CHANGELOG.md), [`packages/opencode/CHANGELOG.md`](packages/opencode/CHANGELOG.md), [`packages/engine/CHANGELOG.md`](packages/engine/CHANGELOG.md). ## [Unreleased] ## [2.3.0] - 2026-08-16 ### Harness - **SDD fix-round mechanics**: `mstar-sdd` gains four mechanical rules for PM fix-wave dispatch and close-out — an **unverified round counts** (a fix round without verification evidence — reviewer not confirmed / report not on disk — is not clean; re-check and count the round, never enter the convergence branch), **full re-entry** (the next fix dispatch carries all open findings, including last round's unverified items; never slice a subset), **capped cross-round excerpt** (from round ≥2 the dispatch brief carries an excerpt of prior rounds' findings and dispositions — advisory ~500 words/round, ~1500 total, suggested values not hard limits), and **honest non-convergence** (open findings at wave close are listed in detail with an explicit re-feed-to-next-round or transfer-to-residual disposition — never silently closed). Folds Candidate C5 into `mstar-sdd` SKILL.md "After all tasks" + `references/file-handoffs.md` cross-reference (the per-task fix loop applies the same mechanics). - **Residual fail-loud handoff contract**: `mstar-plan-artifacts` `status-and-residuals.md` now requires findings to pass engine validation before R# registration — `validateResidual` per entry and `validateStatus` for the whole file; malformed entries (non-object, missing any of the nine required fields id/title/severity/source/scope/decision/owner/target/tracking, or severity outside the enum) are **rejected** — fix and rewrite, never silent pass-through, downgrade-write, or write-then-patch. Folds Candidate C6; the architect-verified D-3 branch (covered-but-untested) is closed by backfilled non-object rejection regression tests in `packages/engine` at both the `validateResidual` level and the `validateStatus` aggregate level (engine suite 658 pass / 0 fail) — zero source diff, no new public API. - **CLI `dispatch validate` non-ASCII literal fix**: bun-executed CLI bundles misdecode raw multi-byte UTF-8 in regex/string literals, so a legal `Branch policy: direct on main — ` (em-dash) was reported as two false violations. Source literals across 20 `packages/engine` + `packages/cli` src files are escaped to `\uXXXX`, a post-build dist escaper guarantees bundle-level ASCII (bun build re-normalizes string escapes), a bundle-smoke regression test covers em-dash + ASCII separators, and `bun run lint:ascii-literals` plus a CI step guard against recurrence. The guard covers `packages/engine` + `packages/cli` source and the CLI dist bundle; the opencode dist bundle is not wired to the escaper — it is not run as a large bun bundle. - **Regression-fixation paired-evidence reference**: new `mstar-skill-authoring/references/regression-fixation.md` — real artifact as test subject (built bundle / command sequences, not a source import), mock host hooks, dual-path assertion consistency, and fix solidification (reproduce → FAIL → fix → PASS → into the regression set); zero external dependencies, explicitly an optional heavy weapon (default stays P6 before/after + application case). SKILL.md gains the References pointer and syncs its verdict enum to the 4-value SSOT (Approve | Request Changes | Needs Discussion | Unconfirmed). - **Dataflow-directed debugging protocol**: `mstar-coding-behavior` §4 Debugging gains a compact diagnosis procedure — map the data flow before judging (input → processing → storage → output, who writes/reads at each step; a bug is a state deviation from expectation at a flow point), four verifiable cross-checks (re-run the repro / log comparison / input-output comparison / dual-path comparison — a hypothesis that cannot be verified on the spot is not a conclusion), and falsify the fix (after fixing, re-run the original repro and compare with expectation; report "verification failed" explicitly instead of pretending success) — cross-referencing, not restating, the existing root-cause and repro-test bullets. - **QC report evidence contract + `Unconfirmed` verdict**: `qc-specialist` report-template findings entries now require `Verification` + `Expected vs observed` on every severity class — Critical/Warning may use the four cross-checks (or a `diff/read/grep` anchor), Suggestion is `diff/read/grep` anchor only — backed by two hard rules (no verifiable cross-check → do not report the finding; a failed evidence channel is not "no problem" — mark the affected scope **Unconfirmed**); the verdict enum gains `Unconfirmed` for evidence-channel failure; `deep-review-lenses.md` now requires every lens finding to carry a diff/read/grep anchor + expected vs observed (no anchor, no report). - **Audit red-team attack pass before vet**: `mstar-audit` Phase 3 gains an attack sub-step before the human vet — take the top candidate findings (by leverage; count scales to finding volume) and run a three-way attack on each (counter-example / simpler explanation / evidence verifiability); survivors pass to vet unchanged, refuted findings are dropped and recorded in the index's "considered and rejected" section (`- : not worth doing because `), hallucinated claims surfaced by the attack are discarded and logged as red-team record lines (never into the findings table, and they do not occupy a "considered and rejected" slot), and findings the attack did not reach are treated as unreviewed and kept for vet — with a one-line boundary reference to the vet step (the attack decides whether a claim stands on its face; vet keeps open-cited-code confirmation and by-design / mis-attribution / duplicate disposition). - **QC consolidated coverage semantics + `Unconfirmed` propagation**: `mstar-review-qc`'s PM consolidated section now requires — unmentioned = unreviewed (a finding / severity item / claim not raised by any seat must be marked `unreviewed` and routed to targeted re-review, never silently treated as covered); zero injection at the consolidation layer (every consolidated entry must trace to a `qcN.md`; the PM's own observations go to a separate Status Update); and any seat verdict `Unconfirmed` → the gate decision must not be `Approve` until the evidence gap is closed (existing targeted re-review path — same `qcN.md` `## Revalidation` in-place verdict update; no new re-review form, N rules unchanged). The PM `Consolidated Decision Template` verdict enum is synced to the 4-value set (Approve | Request Changes | Needs Discussion | Unconfirmed). - Added a **DSHFIND** badge to the README header linking to the plugin directory listing. - **Ephemeral-citation lint (engine)**: new `findEphemeralCitations` scans skill text for short-lived citations — concrete task artifacts (`task--(brief|report|fix-report|diff)`, incl. dot form `task-N.diff`) and SDD deeplinks (`.mstar/sdd/` / `.agents/sdd/` + concrete first segment) — while discriminating placeholder forms (`task-N-report`, ``, `{SDD_DIR}/…`, `.mstar/sdd/**` path globs): zero false positives on the current `skills/` corpus. - **CLI `skill lint`**: third checklist `skill lint (ephemeral citations)` wired into `mstar skill lint` after the five-question checklist; each citation reports as a `skill.ephemeral.` violation (line + match + placeholder rewrite fix) and sets exit 1. - **drift-lint guards**: docs audit-enum set-equality (docs/cli.md `` row and README category-focus lists vs the engine `AUDIT_CATEGORIES` — catches fabricated tokens like `deps` and omissions like `bug` / `direction`), README.md / README_CN.md same-commit bilingual pairing over the push range, and a skills-corpus ephemeral guard reusing `findEphemeralCitations`; plus a `citesKnowledgeConventions` exemption for harness-local knowledge citations. - **History-rewrite push safety**: `mstar-branch-worktree` gains a "History rewrite 与推送安全" section — any history rewrite of an already-pushed branch must first `git fetch` and record the remote **exact OID**, then publish with `--force-with-lease=:` (bare `--force` prohibited); after the rewrite, prior review threads / approvals / check results are no longer current evidence and must be re-reviewed before merging; `mstar-iteration`'s phase-4-5 reference now points at that section as the SSOT for rewrite / force-with-lease / evidence-invalidation rules. - **Authoring devices library**: `skillsbench-authoring.md` gains 6 small composable authoring techniques (calibrated examples file, recall batteries, overcorrection traps, required-explicit-input, questions ≠ write authority, invocation boundary), each mapped onto one or two SkillsBench principles with in-harness instances. - **Bilingual minimal-update rule**: `AGENTS.md` Core Rules now require the minimal counterpart edit for paired docs (README.md/README_CN.md, packages/dsh README triplets) — never re-translate a document to apply an update — with pairing hashes re-recorded (`git hash-object`) in the same change set. - **Knowledge-doc prose hygiene**: `mstar-compound` workflow gains §3.5 — a HEAD-resolvability quality gate (a reader at HEAD — no chat transcripts, dispatch prompts, or unmerged drafts — can resolve every reference and verify every claim) with an mstar-adapted leakage taxonomy (dead session citations, change narration, review choreography, hedges without `simplify:`/`temporary` markers, authoring-language slips) and sanctioned keep rules (R#/finding ids in review bundles, issue references, measured bounds, iteration/plan ids); `writing-specialist` Output Guidance points to the SSOT without duplicating it. - **Future-decision-value classification**: `mstar-compound-refresh` Phase 2 gains a second axis — docs whose rationale / alternatives considered / negative guarantees / reintroduction conditions still guide a future change are **kept regardless of length** — plus a guardrail (a captured rejected approach stays only while the losing idea remains a tempting, meaningful mistake) and an explicit exclusion of frozen-archive seal machinery (rule 6 delete-don't-archive intact). - **Editorial rubric for writing-specialist**: Output Guidance adds the complete-proposition rule (enumerate actor+action / condition / modality / negative guarantee / ownership before trimming; trim only when every factual clause survives), a coverage-by-artifact table over the six mstar surfaces (knowledge docs / plans / review bundles / SKILL.md / README / completion reports), and doc standards (atomic-move rule, tutorial-vs-reference classification). - **QC deep-review lenses**: `deep-review-lenses.md` gains 5 new lenses — Lifecycle & Concurrency, Ownership / Derived-State, Bounds, Enforcement-Path, Real-Entry-Path — each with 2–4 structured questions answerable via diff/read/grep, plus deepened Testing / Contract lenses and signal-map seats (QC3 default += Enforcement-Path / Ownership; QC2 default += Bounds / Real-Entry-Path). - **Audit playbook probes**: `mstar-audit` playbook §1/§2/§4/§5 gain 8 codebase-level probes (derived-state drift, bounds covering the final operation, enforcement bypass, real entry path, externally observable state, user-visible output is behavior, public-but-one-caller, unjustified defaults/public options); §5 adds the prove-or-reject methodology for DEBT findings (consumer three-way classification, hand-rolled vs dependency swap bar, mirrored-fact test, strong-candidate families, guards). - **`/codebase-audit simplify`**: new `simplify` scope variant routes through the existing command — a DEBT-focused deep pass whose findings use Category DEBT and never inline TODOs. - Documented `/codebase-audit` usage and keyword parameters (effort levels, category focus, `branch`, `next`/`roadmap`, `simplify`) in README.md/README_CN.md and docs/cli.md. - Internal `@mstar-harness/engine` devDependencies in cli/opencode/dsh now use the `workspace:*` protocol; the release-prep engine-spec sync step was removed. ### Version alignment - Bump monorepo root, `@mstar-harness/opencode`, `@mstar-harness/cli`, `@mstar-harness/engine`, `@mstar-harness/dsh`, Cursor/Codex/Kimi/ZCode/omp/Claude plugin manifests, and the portable Agent Plugins manifest: **→ 2.3.0**. ## [2.2.0] - 2026-08-13 ### Harness - **dsh plugin**: the context catalog now carries an **`agentFlow`** evidence row — the actual subagent dispatch/settle ledger (`{HARNESS_DIR}/agent-flow.jsonl`, bounded JSONL truncated to ~500 events; single recording core `DshHostAdapter.dispatchGate` behind both the `tools/pre-execute` listener and the `beforeDispatch` host hook; real settle recording — `tools/post-execute` is a VERIFIED registry seam (dispatched for every tool call) settling foreground dispatch calls, background tasks settle via `ctx.tasks.onTaskDone` terminals, paired by exact dispatch identity — settlement is never fabricated, unpaired calls record nothing). The workflow panel's main graph adds the expected-vs-actual subagent flow pipeline: a third column of stage boxes lit by dispatch evidence, a collapsible event-detail footer strip (role → planId#taskId, all five status colors, settled ✓), and the flow-expected / flow-actual / flow-unexpected legend. - **dsh plugin**: the ledger's missing-file state now reads as an EMPTY view (the panel shows the "no actual dispatches yet" empty state from plan merge — not an evidence-missing degrade); the ledger append path is documented single-writer and size-gated with an atomic truncation replace. - **dsh plugin**: fix the unified `mstar-engine-status` catalog row breaking the session round (`session event "user/message" carries non-JSON-serializable data`) when the iteration-gate section cannot be built — no `status.json`, no active steering compass, or an unreadable control doc. The optional `iteration` key is now omitted instead of present-as-`undefined`, keeping the appended message losslessly JSON-serializable at the `Session.append` boundary. - **dsh plugin**: fixed the broken `@mstar-harness/dsh` build gate — the web client bundle (`dist/client.js`) is now emitted by the full build. Root causes: `tsconfig.json` `types` omitted `react` (TS7026: no `JSX.IntrinsicElements` for the panel `.tsx` sources) and the `@deepseek-ai/dsh-client-*` peer-stub workspace links were missing from `node_modules` (TS2307), which failed the build's final `bunx tsc` step and left the client bundle absent. The typecheck gate is green again; `dsh --profile web` boots with the plugin's `/plugins/@mstar-harness/dsh/client.js` registered and served. - **dsh plugin**: mstar slash commands (`/iteration-start`, `/iteration-drive`, `/iteration-loop`, `/codebase-audit`) now declare an `input` hint (new frontmatter `input:` in `commands/*.md`), so the dsh web client **claims** them on menu pick instead of executing immediately: `/name ` is inserted into the composer with the command highlight, the arg hint shows as ghost text, and the line submits only on Enter — the same interaction as `/plan` / `/goal` / `/advisor`. User-typed args are appended to the steered command message as a `## User input` section; quoted frontmatter values (description/input) now register unquoted. Updated `mstar-host/references/dsh.md`. - **dsh plugin**: `@deepseek-ai/dsh-*` peers upgraded to the `0.1.0-rc.3` line (`^0.1.0-rc.3`; `@deepseek-ai/cordis` `^4.0.1` — same-class alignment with the dsh-advisor upstream bump, `dsh-external/dsh-advisor#14`); every installed version below `0.1.0-rc.3` (old `0.0.1-rc.x` / `0.1.0-rc.2` lock entries and nested copies) was purged from `bun.lock` + `node_modules`. The monorepo root gains a `bun` `overrides` entry pinning `@deepseek-ai/dsh-llm` to `^0.1.0-rc.3`: bun otherwise installs same-version nested peer copies for each dependent dsh package, and TS 5.9 package-id resolution treats the copies as distinct modules — the plugin's `MessageSourceMap` augmentation (`mstar-engine-status` catalog kind) no longer merges into the union dsh-agent/dsh-session see, breaking `createUserMessage` typing at the `agent/pre-step` catalog push. `tests/peer-deps.spec.ts` pins `^0.1.0-rc.3`. - **dsh plugin**: dev-time `@deepseek-ai/dsh-*` seam resolution switched from the local **link farm** to the **npm registry** at `0.0.1-rc.5` (bun auto-installs peers via the monorepo-root `.npmrc` `${NPM_TOKEN}`). Removed `scripts/setup-dsh-links.ts` + `dsh:link`/`dsh:link:check` (`prepare` is now build-only); dropped `peerDependenciesMeta.optional` (the old skip-unpublished-peers workaround) and completed the peer set — `dsh-client-runtime`/`dsh-client-locale`/`dsh-client-ui-conversation`/`dsh-client-ui-slots`/`dsh-invariants`/`dsh-jobs` joined the existing peers (all `^0.0.1-rc.5`); added `keywords: ["dsh", "dsh-plugin"]` and `tests/peer-deps.spec.ts` (registry peer contract, peers-not-optional regression). - **dsh plugin**: `@deepseek-ai/dsh-*` peers upgraded to the `0.1.0-rc.6` line (`^0.1.0-rc.6`; `@deepseek-ai/cordis` stays `^4.0.1`) — every lock entry below `0.1.0-rc.6` (`0.1.0-rc.3` pins and any `0.0.1-rc.x` leftovers) was purged from `bun.lock`; the whole dsh tree now resolves at `0.1.0-rc.6` (60 lock entries, single hoisted copy per package). The monorepo-root `bun` `overrides` entry for `@deepseek-ai/dsh-llm` is **removed**: with every dsh package on the same `^0.1.0-rc.6` range bun dedupes to one copy, so the rc.3-era nested-copy workaround is no longer needed (verified: 1 lock entry, 0 nested `dsh-llm` copies; the `MessageSourceMap` augmentation typecheck passes). Root `dependencies` stays engine-only. Seam-resolution docs updated for the public-registry reality (the root `.npmrc` auth token was dropped in 0c884d47): `packages/dsh` README (EN/zh) and `tests/peer-deps.spec.ts` no longer claim a root `.npmrc`/`${NPM_TOKEN}` — the spec now asserts no scoped-registry mapping comes back and the installed `dsh-llm` resolves to exactly `0.1.0-rc.6`. Caveat: `@deepseek-ai/*` publishes `dist-tags.latest = 0.0.1-rc.1` (an ancient line whose packages reference never-published peers like `dsh-user-interaction`), so `bun update @deepseek-ai/...` must not be used — it downgrades to that line and 404s; the lock-purge + `bun install` path is the supported upgrade route. - **dsh plugin**: dev-time dependency strategy for the `@deepseek-ai/dsh-*` seams switched from committed `peer-stubs/` stand-ins to a **link farm** (`packages/dsh/scripts/setup-dsh-links.ts`, dsh-advisor pattern): the REAL packages from a local dsh source tree (`$DSH_SOURCE_DIR` → `$DSH_HOME/source/current` → `~/.dsh/source/current`) are symlinked into the repo-root `node_modules/@deepseek-ai/` (idempotent; `bun run dsh:link` / `dsh:link:check`; wired into `prepare` before the build). `peerDependencies` stay declared (the host provides them at runtime; marked optional so bun 1.2 does not 404 on the private registry); the `peer-stubs/` workspace was removed. - **dsh plugin**: CI (validate job) now detects dsh source-tree availability (`$DSH_SOURCE_DIR` / `~/.dsh/source/current`) and skips the dsh test/typecheck steps when absent — dsh is not run in CI. - **dsh plugin**: `src/index.ts` slimmed from a 3184-line monolith to a module index over `src/gates/*` (pure refactor, zero behavior change — the 27-name export surface is frozen identical by `tests/export-surface.spec.ts`, and the export-surface type layer now runs in CI via `typecheck:tests` (`bunx tsc --noEmit -p tests/tsconfig.json`)). - **dsh plugin**: `HarnessResolver.forWorkspace` now passes `workspaceRoot = the session cwd` (the probe start) — the `{HARNESS_DIR}` probe stops AT the session workspace and never walks up beyond it, so a harness dir above the workspace (e.g. the global `~/.mstar` CLI-install root) is never adopted. The dsh boundary deliberately diverges from the CLI's git-top-level boundary. Explicit `config.harnessDir` still wins outright. - **dsh plugin**: the pre-step catalog is now ONE unified `mstar-engine-status` message — watermark (version, harness dir, enforcement) + iteration phase-gate section (when a steering compass resolves) + workspace-state digest section (plan registry, open residuals, branch/policy anchors, active leases, knowledge summary, compass direction — when the workspace has a `status.json`) — all from one cached `status.json`/compass/knowledge read. - **dsh plugin**: the catalog row is TTL-refreshed per workspace (Config `catalogTtlMs`, default 60000 ms — mid-session plan/compass/residual changes land within one interval while the hot path stays a timestamp compare + cache hit) and digest-gated (injected once per turn, re-injected only when it changed — a long turn shows the catalog once, not per step). - Unify local scratch layout: temp files → `.tmp/*`, git worktrees → `.worktrees/*` (both gitignored); documented in AGENTS.md. - **dsh plugin**: the web client workflow panel is now **"MStar 工作流" / "MStar Workflow"** — a reworked layout (header with version / harness dir / enforcement evenly spread; fixed right sidebar for plans / residuals / knowledge / leases / branches+policy / direction; main body = a **react-flow cyclic workflow graph**) with an upgraded visual system (dsw-token spacing ramp, type hierarchy, dark mode, motion). The graph projects the `mstar-engine-status` catalog through a pure `projectGraph` function (schema constants strictly separated from catalog evidence; never throws; explicit degraded states): a phase ring (iteration-start → autonomous-execute → iteration-close → pr-delivery → merge-ready, loop edge) + plan state machine (Todo → InProgress → InReview → Done / InProgress ⇄ Blocked / unknown bucket), with current-phase highlight, legend, zoom/pan and fitView. `@xyflow/react@^12.11.2` is inlined into `dist/client.js` (MIT; license/size reviewed in guides); the build script now asserts the bundle carries no `import.meta` / ESM statements — the web loader executes plugin bundles as classic `