feat(skills): resolveSkillBody + renderPrompt + abortDispatchMissingSkill (SR-2) #884
No reviewers
Labels
No labels
area:agents
area:dashboard
area:database
area:design
area:design-review
area:flows
area:infra
area:meta
area:security
area:sessions
area:webhook
area:workdir
security
type:bug
type:chore
type:meta
type:user-story
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
charles/claude-hooks!884
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "dev/870"
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?
Implements the three building blocks of the SR-2 dispatch pipeline. No call-site wiring yet — that follows in SR-4.
Closes #870
What's in this PR
infrastructure/database/agent-skill-store.tsresolveAgentSkillBody(agentType, instanceId, name)— single Drizzle query,ORDER BY scope ASC LIMIT 1(instance wins because'instance' < 'type'in ASCII; the spec'sDESCwas an editorial error). No FS fallback, no delta lookup.getAgentTypeAppendixFlags(agentTypeName)— readsapply_caveman/apply_artifact_stylefrom the first non-builtinagent_typerow; column defaults (caveman=off,artifact-style=on) when no row exists.infrastructure/database/task-store.ts'aborted_no_skill'toTERMINAL_STATUSES.domain/analytics/skill-loader.tsresolveSkillBody(agentType, instanceId, name): Promise<string | null>— thin async wrapper over the infra resolver; domain layer owns the export name, infra layer owns the SQL.renderPrompt(opts: RenderPromptOpts): Promise<string | null>— full pipeline: resolve → interpolate → applyAppendix → caveman (ifglobalCavemanMode || apply_caveman) → artifact-style (ifapply_artifact_style). Missing appendix rows emit[dispatch] appendix_missingand continue; missing primary skill returnsnull.abortDispatchMissingSkill(forge, repo, issueOrPr, agentType, skillName, opts)— logs[dispatch] skill_missing, posts forge comment, strips dispatch label (safe no-op when absent), writestask_historyrow withstatus='aborted_no_skill'. All forge I/O is behind the_abortImplseam for test injection.Test plan
resolveSkillBody.test.ts— 7 tests: instance > type > null, boundary isolation, instanceId=null never returns instance rowrenderPrompt.test.ts— 11 tests: null on missing skill, interpolation, prompt_appendix, both bools on/off, globalCavemanMode override, graceful appendix skip with logabort-missing-skill.test.ts— 5 tests: happy path (comment + label + task_history), structured log fields, label no-op variants, comment failure resiliencebun x turbo run test— 3197 pass, 0 failjust qa— typecheck + biome clean on touched files (pre-existing warnings in unrelated files unchanged)