The skin, pet and community packages left this repository, so packages/skins/
never exists in a checkout of it. Every scanner that still walked it as a
second root did so defensively — family-packages.mjs and
coverage-gate.discoverPackages listed it first and guarded the walk with
existsSync, aggregate.mjs looked for a second aggregate manifest and a second
package index under it, e2e-mount-rewrite searched it for workspace packages,
and seven test files built fixtures under it. The walkers now name packages/ as
the single root and the fixtures and comments follow; modules that only carried
the root in a doc comment are reworded.
scripts/coverage-baseline.json loses the three packages no longer measured here;
its sixteen keys now name exactly the sixteen package directories on disk.
The in-repo fallback paths in scripts/market-build stay untouched: they are the
documented route for building from a checkout that still carries the packages,
and the fixture-based market-build tests populate them deliberately.
The skin center, pet and community-index plugins now live in their own
repositories and are consumed as published npm packages, so this tree drops
them and everything that only existed to serve them in-repo.
Removed: packages/dsh-pet, packages/dsh-community-plugins and
packages/skins/skin-center (history stays in this repository), plus the root
scripts that moved with them (skin center catalog check, the reviewed-hooks
registry, the skin and pet authoring CLIs and their tests, community-index).
scripts/skins-montage.mjs stays: it renders the root README collage from
market/dist, which is this repository's tooling.
Decoupled:
- scripts/sync-shared.mjs no longer mirrors the settings trio, host helpers or
http/mount-once copies into the three packages (114 copies -> 99);
- lib-artifact-fingerprints.json tracks three committed lib/ packages now that
skin-center left;
- packages/dsh-usage drops an unused @linxin666/dsh-pet devDependency;
- the skin/pet/community gates leave ci.yml and the root scripts (they run in
the satellite repositories' own CI);
- scripts/i18n-audit.mjs no longer reads pet's client locale file, and the
test-standards and emoji audits skip .market-inputs (fetched content is not
ours to audit);
- the market build pins the community index in market-inputs.lock.json like the
skin and pet content, so the plugin list the site serves is reproducible from
a commit instead of following whatever npm resolves, and the catalog's skin
repo URLs point at dsh-skins;
- docs (root AGENTS.md, architecture, plugins, development, publish-prep) and
CONTRIBUTING point at the new repositories.
Gated by: aggregate:check, libs:check, runtime-deps:check, market:check,
sync-shared:check, test:standards, docs:check, i18n:check, emoji:check,
typecheck and 307/307 script tests.
Not yet safe to merge: the aggregate's three dependencies resolve from npm,
and the published 0.3.24 still injects the retired settingsScope service, so
the mount smoke stays red until the satellite repositories publish a build
containing the migration.
Turn the repository's test conventions into machine-enforced gates and close
three holes in the CI/CD set.
- scripts/test-standards.mjs: six business test rules (no-arbitrary-sleep,
no-ad-hoc-mock, bdd-title, given-when-then, call-count-only-assertion,
tautological-assertion) with a per-file, per-rule baseline in
scripts/test-standards-baseline.json, so new debt is blocked while the
existing 367-file backlog ratchets down. Rule scope follows the lane:
business tests under packages/, tests/ and desktop/ carry the full
contract, repository tooling under scripts/ only the mechanical rules.
- scripts/emoji-audit.mjs: replaces the inline ci.yml Python emoji step with a
reviewed, unit-tested gate; same ranges and out-of-scope trees, plus a
strict-UTF-8 skip and file:line:column reporting.
- scripts/coverage-gate.mjs with scripts/coverage-baseline.json: a per-package
v8 coverage ratchet (21 packages; repository totals 56.64% lines, 67.74%
branches) with a half-point tolerance for instrumentation noise. The
provider is declared per vitest major: the six 3.x packages carry
@vitest/coverage-v8@^3.2.7 and the root devDependency serves the 4.x fleet.
- ci.yml now runs the previously unenforced pnpm i18n:check, the new
pnpm test:standards, and pnpm emoji:check; nightly.yml is the Tier-2 lane:
both its jobs build before they test, exactly as ci.yml does, then run the
coverage ratchet and three consecutive full-suite runs for flake detection.
- scripts/pr-review.mjs keeps its gate sequence aligned with ci.yml.
- docs/development.md owns the rules, baselines, tiering and the failure-path
audit checklist. Decision recorded in
.agents/notes/implemented/testing/2026-09-16-business-test-discipline-gates.md.
Verified: pnpm test:scripts (three new specifications), pnpm test:standards
(clean baseline; a probe spec fails with three groups), emoji:check parity with
the Python step it replaces, coverage:check over the full fleet, pnpm
typecheck, pnpm test, docs:check, i18n:check, libs:check, aggregate:check,
actionlint, and pnpm install --frozen-lockfile.