Skip to content

feat: zed target — .zed detection and Zed's silent frontmatter rules - #92

Merged
singhharsh1708 merged 1 commit into
mainfrom
feat/zed-adapter
Jul 28, 2026
Merged

feat: zed target — .zed detection and Zed's silent frontmatter rules#92
singhharsh1708 merged 1 commit into
mainfrom
feat/zed-adapter

Conversation

@singhharsh1708

Copy link
Copy Markdown
Owner

The bug

Zed reads the vendor-neutral .agents/skills/<name>/SKILL.md path — Kitbash was already emitting it. But nothing in a Zed-only repo announces that: the agents adapter probes .agents/ and .codex/, and Zed creates neither.

So a repo whose only agent marker was .zed/ compiled to nothing but the eager AGENTS.md floor, paying a skill's whole body every session on an agent that can lazy-load it for free. For prereview that is ~560 standing tokens instead of ~40 — the 13× tax the benchmark exists to measure, charged to a target that never needed to pay it.

The target

zed detects .zed/ and emits the byte-identical file agents does, so a repo with both compiles that skill once, not twice. Ten targets, nine output files.

It also enforces two constraints Zed applies and KSF does not. Both fail silently in Zed — the skill is dropped at load with no diagnostic in the UI, which is the capability loss spec §2 forbids:

  • name must match ^[a-z0-9]+(-[a-z0-9]+)*$. KSF's NAME_RE is looser and permits a doubled or trailing hyphen, so tidy--commits is a legal skill name Zed will not load. Zed's 64-character cap is unreachable from here — KSF caps names at 41.
  • description must be non-empty and at most 1024 UTF-8 bytes, not characters — a trap for non-ASCII text, where 600 characters can be 1,200 bytes. Manifested skills are bounded at 200 characters (600 bytes at worst), so only an unmanifested SKILL.md, whose frontmatter is copied through unvalidated, can breach either bound.
⚠ tidy--commits → zed: name must match ^[a-z0-9]+(-[a-z0-9]+)*$ — no leading,
  trailing or doubled hyphen; Zed drops the skill at load with no diagnostic
⚠ wide-desc → zed: description is 1200 bytes, over Zed's 1024-byte limit
  (the limit is bytes, not characters); Zed drops the skill at load with no diagnostic

Both are warnings, so compile --strict fails on them.

No disable-model-invocation key is emitted. Zed accepts one, but KSF has no field meaning "never auto-invoke" — triggers.auto is a hint for auto-invocation — so synthesizing a value would guess at the author's intent and could suppress a skill they expect to fire.

The honesty bug this surfaced

kitbash explain <skill> zed answered "no capability degradation" for a skill Zed discards entirely. Literally true, reads as false, and it is exactly the class of silent loss this project exists to prevent — in our own tool.

Adapters can now declare target-specific constraints through an optional lint() separate from emit(). explain reads it directly rather than emitting files to find out.

Verification

  • 9 new e2e assertions: .zed/-only detection, frontmatter shape, no false positives on a conforming skill, shared-path single-write with no conflict, each of the three constraint breaches, --strict failure, and explain surfacing the rejection.
  • npm run check clean · full suite green · npm run bench deterministic · node site/build.mjs --check current.
  • Benchmark regenerated with the zed row; docs, site, config id table and target counts updated (9 → 10 targets; "nine files" prose left alone, since it is still nine files).

Release

Version bumped to 0.12.0 with a CHANGELOG section. Tag v0.12.0 after merge to trigger release.yml.

Zed reads the vendor-neutral .agents/skills/<name>/SKILL.md path, but
nothing in a Zed-only repo announces that: the `agents` adapter probes
.agents/ and .codex/, neither of which Zed creates. A repo whose only
agent marker was .zed/ therefore compiled to nothing but the eager
AGENTS.md floor — paying a skill's whole body every session on an agent
that can lazy-load it for free.

The new target detects .zed/ and emits the byte-identical file `agents`
does, so a repo with both compiles that skill once, not twice. Ten
targets, nine output files.

It also surfaces two constraints Zed enforces and KSF does not, both of
which Zed applies silently — the skill is dropped at load with no
diagnostic in the UI, which is the capability loss spec §2 forbids:

  - name must match ^[a-z0-9]+(-[a-z0-9]+)*$. KSF's NAME_RE is looser and
    permits a doubled or trailing hyphen, so `tidy--commits` is a legal
    skill name Zed will not load.
  - description must be non-empty and at most 1024 UTF-8 *bytes*, not
    characters — a trap for non-ASCII text, where 600 characters can be
    1,200 bytes. Manifested skills are bounded at 200 characters, so only
    an unmanifested SKILL.md, whose frontmatter is copied through
    unvalidated, can breach either bound.

No disable-model-invocation key is emitted: KSF has no field meaning
"never auto-invoke" (triggers.auto is a hint *for* auto-invocation), so
synthesizing a value would guess at the author's intent.

Fixes a related honesty bug found while wiring it up. `explain <skill>
zed` answered "no capability degradation" for a skill Zed discards
entirely — true, but it reads as false. Adapters can now declare
target-specific constraints via an optional lint() separate from emit(),
and explain reads them directly.
@vercel

vercel Bot commented Jul 28, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
kitbash Ready Ready Preview, Comment Jul 28, 2026 12:37pm

@github-actions github-actions Bot added documentation Docs, spec, RFCs, README, site dependencies Dependency or action version bumps benchmark Benchmark script or measured numbers labels Jul 28, 2026
@singhharsh1708
singhharsh1708 merged commit 72664e9 into main Jul 28, 2026
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

benchmark Benchmark script or measured numbers dependencies Dependency or action version bumps documentation Docs, spec, RFCs, README, site

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant