Skills for skills-less providers: seeded bundle indexed from the context file; lab-owned context-file name rule #79
Labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
Cloonar/coding-lab#79
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Context
The embedded skills bundle (
assets/skills, seeded intoSeedMeta.SkillsDir) is only discovered via Claude's.claude/skillsconvention — the content itself is agent-agnostic markdown with frontmatter descriptions that already carry 'use when…' triggers. A provider without native skill discovery (#2 Codex reads AGENTS-style context files only) would get the labctl vocabulary from the context file but none of the workflow playbooks (triage, land-pr, to-issues, to-prd) that carry AFK quality.Decided in provider-seam grill (2026-07-09):
SkillsDir; no content fork, no curation list.name+description), pointing at the seeded path ('when doing X, read /triage/SKILL.md'). Agents that follow file pointers get the full playbooks on demand; the context file grows ~one line per skill, not pages.ContextFileNamemust be a lab-owned, never-tracked name (CLAUDE.local.md,AGENTS.local.md—.local-suffixed convention). Lab must never write a file repos legitimately track (Codex's nativeAGENTS.md): a tracked file can't be hidden by.git/info/exclude, would be clobbered on re-seed, would show in every diff, and would break incogni measure 6. Making the CLI actually READ the lab-owned file is the ADAPTER's job inSeedWorkspace(e.g. Codex project config pointing atAGENTS.local.md) — a live-verified coupling like every other (ADR-0008 bar).Design
SeedMetagainsNativeSkillDiscovery bool(claude-code: true). When false andSkillsDiris non-empty,renderContextFileappends the generated skills index section.SeedMeta.ContextFileName(internal/provider/provider.go) and in the ADR. The conformance suite (follow-up issue) will assert the naming convention.Sequencing
Touches the same
SeedMeta/internal/seedersurface as #75 (in progress). Blocked until #75 merges to avoid churn conflicts — re-triage toready-for-agentthen.Acceptance
NativeSkillDiscovery: falseseeds the bundle and gets a context file listing every bundled skill with correct paths.go:embedsource remains.Agent Brief
Category: enhancement
Summary: Seed the same skills bundle for every provider; for providers without native skill discovery, append a generated skills index to the context file; enforce the lab-owned context-file-name rule.
Sequencing note: the "blocked until #75 merges" condition in the issue body is satisfied — #75 landed via PR #81 (ADR-0033).
SeedMeta.ScrubPatternswas widened there; this issue touches the same struct but a disjoint surface (context file + skills), so no churn conflict remains.Current behavior:
The embedded skills bundle (single
go:embedsource) is seeded into each provider's declaredSeedMeta.SkillsDir, but discovery relies entirely on Claude's.claude/skillsconvention. A provider whose CLI reads only AGENTS-style context files (e.g. the Codex provider, #2) receives the bundle on disk but has no way to learn it exists: the generated context file describes the tracker binding, labctl vocabulary, and triage labels, and never mentions the seeded skills. Such an agent gets none of the workflow playbooks (triage, land-pr, to-issues, to-prd, …) that carry AFK quality.Desired behavior:
SkillsDirgets the identical embedded bundle — no content fork, no per-provider curation list.SeedMetagainsNativeSkillDiscovery bool(claude-code declarestrue). When a provider declaresfalseAND has a non-emptySkillsDir, the rendered context file gains an appended skills-index section: one line per bundled skill, rendered from that skill's frontmatter (name+description), pointing at its seeded path — the shape is "when doing X, read<SkillsDir>/<name>/SKILL.md". Agents that follow file pointers pull the full playbook on demand; the context file grows about one line per skill, not pages.SeedMeta.ContextFileNamemust be a lab-owned, never-tracked name — the.local-suffixed convention (CLAUDE.local.md,AGENTS.local.md). Lab must never write a file repositories legitimately track (e.g. Codex's nativeAGENTS.md): a tracked file can't be hidden by.git/info/exclude, would be clobbered on re-seed, would show in every diff, and would break incogni. Document this on theSeedMeta.ContextFileNamefield and in an ADR. Making the CLI actually read the lab-owned file is the adapter's job in itsSeedWorkspace(e.g. Codex project config pointing atAGENTS.local.md) — a live-verified coupling per the ADR-0008 bar; not this issue's job to build for Codex.CLAUDE.local.mdis unchanged. Pin with the existing golden pattern.Key interfaces:
SeedMeta(provider package) — newNativeSkillDiscovery boolfield, with doc comment; claude-code's declaration sets ittrueand its seedmeta pin test covers it.SeedMeta.SKILL.mdcarries YAML frontmatter withnameanddescription; the description already embeds "use when…" triggers, so index lines need no extra copy.SeedMeta.ContextFileNamedoc comment + a new ADR recording the lab-owned-name hard rule and the index design.Acceptance criteria:
NativeSkillDiscovery: falseand a non-emptySkillsDirseeds the full bundle and gets a context file whose index section lists every bundled skill with a correct seeded path (paths reflect THAT provider's declaredSkillsDir).NativeSkillDiscovery: true(claude-code) gets no index section; its seeded worktree — context file included — is byte-identical to today, pinned by golden.SkillsDirgets no index section regardless of the flag.ContextFileNamefield and in an ADR.go:embedsource — no fork, no curation list.Out of scope:
SeedWorkspacewiring that points the CLI atAGENTS.local.md.Landing audit — PR #86 (
afk/79)Verdict: PASS. Recommending merge.
Verification signal. No readable CI status via the labctl surface (no forge token here), so nothing external vouches — I ran the repo's Go gate myself against
origin/afk/79(which, sincemainis an ancestor ofafk/79, is the post-merge tree):gofmt -l internal/— cleango vet ./internal/seeder/... ./internal/provider/...— cleango teston every changed package — all pass (internal/seeder,internal/provider,internal/provider/claudecode), including the byte-identity goldens and the init-panic frontmatter guard casesgo test ./...— green exceptinternal/tmuxxintegration tests, which fail only because the sandbox has no usable tmux server ("session exited immediately"); untouched by this diff and failing identically at pristine HEAD, exactly as the PR body states.Conventions. Title
feat(seeder): …is Conventional Commits ✓. Body carries a validCloses #79✓ (AFK contract satisfied:afk/79→ #79).Merge state.
mainis an ancestor ofafk/79— no divergence, clean merge, no conflict.Correctness vs. issue #79. Implements every decision: same bundle for every provider (single
go:embed, no content fork);SeedMeta.NativeSkillDiscovery bool(claude-codetrue); index appended in Go only when!NativeSkillDiscovery && SkillsDir != "", so claude-code stays byte-identical (goldens pin it); frontmatter parsed once at package init and fails loudly (panic mirroring thetemplate.Mustidiom); lab-owned context-file-name hard rule documented onContextFileName+ ADR-0035.go.modcorrectly promotesyaml/v2indirect→direct. Sequencing ("blocked until #75") is satisfied — #75 landed via #81.Awaiting explicit free-text merge go-ahead before merging.