Phase 0 of the handoff plan, as a marketplace rather than a flat skills/ directory. Content moved out of the LyraResearch archive and depersonalised: addresses stay in the archive, recipes ship. - plugins/ue-design-skills: 17 skills, 232 failure-mode entries, each with the six required fields; catalog.json as the harness-neutral source of truth and .claude-plugin/ as one adapter over it. - _gate: 16 rules, one poisoned fixture per rule, plus surface coverage so a declared file cannot silently miss the line rules. - ADR-0002 (harness-neutral bundle behind a marketplace) and ADR-0003 (split licensing: CC BY-ND 4.0 prose, Apache-2.0 code and metadata). - LICENSE files at both levels, CONTRIBUTING.md, docs/licensing-options.md as the material the licence decision grew from. Verified: gate.py 0 violations; test_gate.py 16/16 rules redden on their fixtures with a clean baseline and 2 root files reaching the line rules. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
6.6 KiB
status, date, deciders, consulted, informed
| status | date | deciders | consulted | informed |
|---|---|---|---|---|
| accepted | 2026-09-02 | project owner | LyraResearch depersonalization pilot | future contributors |
Harness-neutral skill bundle behind a marketplace
Context and Problem Statement
The skills/ component of ue-toolchain is not speculative work: it already exists as
18 skill bundles in the LyraResearch archive, grown from a line-by-line audit of a
first-party UE 5.6 sample. What is new is turning them into something a stranger can
install.
Two forces pull against each other.
Distribution wants a vendor format. Agent runners discover plugins through their own manifest, in their own directory, with their own rules — component directories must sit at the plugin root, and paths outside it are rejected. Writing to one such format is the only way to get a one-command install today.
The product must outlive that vendor. The owner's constraint is explicit: "не привязывайся к клоду... инструмент должен нормально работать с любым харнесом или агентом." A skill that says "run this vendor command" is not portable content, it is a script for one runner.
There is also a physical question. An agent runner copies the entire plugin root into its
cache on install. If the plugin root is the repository root, then the UE C++ plugin, the
MCP server and examples/ are copied too — for a bundle whose actual payload is
Markdown. The precedent is measured: the VibeUE plugin copied into the reference project
weighs 161 MB.
Decision Drivers
- Content portability is a property of the files, not of the installer. It has to be checkable, or it will rot on the first convenient exception.
- One vendor adapter must not become the interface. Adding a second harness must not
require editing a single file under
skills/. - The install surface should carry only what it delivers. Source trees for the editor plugin and the MCP server are not part of a documentation bundle.
- Discoverability without a runtime. A harness that has never heard of any plugin format still needs to know what is in here and when to reach for each piece.
Considered Options
- Whole repository is one plugin. Vendor manifest at the repo root,
skills/besideEngine/andmcp-server/. - Separate repository for the skills. Independent versioning and release cadence.
- Repository is a marketplace; the bundle is a subdirectory.
Decision Outcome
Chosen: option 3, with a neutral catalog inside the bundle.
ue-toolchain/
├── .claude-plugin/marketplace.json one adapter, points at the bundle
└── plugins/ue-design-skills/ the bundle, and the whole install surface
├── catalog.json source of truth: what is here, when to use it
├── .claude-plugin/plugin.json the same adapter, one level down
├── skills/<name>/SKILL.md plain Markdown + YAML frontmatter
└── _gate/ rules, poisoned fixtures, self-test
Three commitments follow:
The catalog is the source of truth; the vendor manifest is an adapter. catalog.json
lists every skill with id, path, entry, description, use_when and its
references. Any harness can read it, or ignore it and load the directory as context. A
second adapter is a new file beside the first, never an edit under skills/.
Skill content names no harness. Not the vendor, not its path variables, not its
command syntax. The rule holds for everything under skills/; the adapter directories are
exempt because being vendor-specific is their entire job.
Both commitments are enforced, not documented. They became gate rules P13 and P14 the same hour the decision was made. A portability promise that lives only in an ADR is a promise nobody checks.
Consequences
- Good: the install surface holds only Markdown, JSON and the gate. C++ and examples stay out of the plugin cache.
- Good: skills release on their own cadence, before the editor plugin (phase 1) and the MCP server (phase 2) exist.
- Good: the neutrality claim is falsifiable — a single grep decides it.
- Bad: the layout is one level deeper than the component table in the handoff implies
(
plugins/ue-design-skills/, notskills/). The README is updated to match. - Bad: two manifests describe the same bundle. They will drift unless the catalog stays authoritative and adapters are generated or reviewed against it.
- Neutral: nothing here prevents later extraction into its own repository. The bundle is
self-contained by construction — the gate rejects any link that escapes a skill
directory, so it moves with a
mv. That was verified when it moved out of the archive.
Confirmation
Checked at the time of writing, and required for every later change:
claude plugin validate . --strictpasses at the marketplace root and at the bundle root. (passing)python _gate/gate.py .reports zero violations on the bundle. (passing, 14 rules)python _gate/test_gate.pyreports every rule reddening on its own poisoned fixture with a clean baseline. A rule that never reddens is treated as absent and fails the build. (passing, 14/14)- No file under
skills/matches the harness token list — vendor names, vendor path variables, vendor command syntax. (P13) - Every skill directory has a catalog entry whose
pathholds aSKILL.md, and the catalog names no skill that is absent. (P14, both directions) - Adding a second harness adapter changes no file under
skills/. (structural; re-check when the second adapter is written)
Deferred
- Which second adapter comes first. Not guessed. It will be written when a real harness needs it, and it will be the test of whether the catalog was actually enough.
- License.
Still open (handoff question 2). Deliberately removed fromResolved by ADR-0003: prose CC BY-ND 4.0, code and metadata Apache-2.0, holder named. The original wording is kept struck through rather than deleted — the reason the field was left empty is part of how it was filled.catalog.jsonand the vendor manifest rather than filled in with the planned value: a license asserted in shipped metadata before it is chosen is a claim with no author. - Whether the addressed audits are ever published. For now the delivery carries
detection recipes and stable entry identifiers; the source addresses stay in the
research archive, where
_tools/resolve_id.pyresolves any identifier back to the file and line it came from.