SR-2 resolveSkillBody + renderPrompt + abortDispatchMissingSkill #870
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
2 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
charles/claude-hooks#870
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?
User story
As a platform engineer, I want a single resolver that picks the right skill body for a
(agent_type, instance_id, name)triple, a single render pipeline that interpolates vars and appends the recommended style guides, and a missing-row policy that fails loud-but-graceful, so that every dispatch path uses the same code with no fallback magic.Acceptance criteria
Resolver
resolveSkillBody(agentType, instanceId | null, name): Promise<string | null>inapps/server/src/domain/analytics/skill-loader.ts.agent_skillwithORDER BY scope DESC LIMIT 1(instance row wins because'instance' > 'type'lexicographically).nullwhen neither layer has a row. No filesystem fallback. No<base>-deltalookup.Render pipeline
renderPrompt(opts): Promise<string>whereoptscarries{ agentType, instanceId, skillName, vars, instance, globalCavemanMode }.resolveSkillBody→interpolate(template, vars)→applyAppendix(prompt, instance.prompt_appendix)→ caveman (ifglobalCavemanMode || agent_type.apply_caveman) → artifact-style (ifagent_type.apply_artifact_style).resolveSkillBody(..., 'caveman')/resolveSkillBody(..., 'artifact-style'). If a recommended appendix body is missing, log[dispatch] appendix_missingand continue without it (do NOT abort).Missing-row policy
abortDispatchMissingSkill(forge, repo, issueOrPr, agentType, skillName)helper:[dispatch] skill_missingwith{forge, repo, issue, type, name, instance_id}.🚫 Dispatch aborted: skill '<name>' missing for agent type '<type>'. Seed it at /agents/<type>/skills.task_historyrow withoutcome = 'aborted_no_skill'.nulland callabortDispatchMissingSkill(...)thenreturn.Tests
resolveSkillBody.test.ts— instance > type > null. Single-query behaviour proven via fixture.renderPrompt.test.ts— appendix order, both bools off, both bools on,globalCavemanModeoverridesapply_caveman = 0, missing appendix logs and continues.abort-missing-skill.test.ts— happy path: comment posted, label stripped, task_history row written,outcome = 'aborted_no_skill'.Out of scope
skillForEvent/STATELESS_SKILLS/maybeApplyCavemanAppendix(covered in SR-4).References
specs/skills-rework.md§Resolution rules, §Dispatch path, §Missing-row policy.apps/server/src/domain/analytics/skill-loader.ts.apps/server/src/domain/workflow/event-handlers.ts.🦵 @charles kicked the queue — re-running implement on @dev.