Add New Feature (SAM Workflow)
You MUST convert the user's request into durable planning content through the structured artifact and SAM interfaces:
feature-context-{slug}.md(discovery)codebase/{FOCUS}.md(optional, analysis)architect-{slug}.md(architecture/design spec)- an executable SAM plan whose opaque
plan_refis returned bysam_plan
<feature_request> $ARGUMENTS </feature_request>
Artifact Discovery (Pre-Phase)
Before starting any phase, check whether the feature request references a tracked item — either a GitHub Issue (#N) or a Beads issue ID (e.g. bd-a3f8). In a Beads workspace, use bd show <id> --json for native item lookup; use the artifact adapter only to discover registered structured artifacts.
flowchart TD
Start([Parse feature_request]) --> Q{"Contains 'GitHub Issue: #N' / '#N'<br>OR 'Beads Issue: bd-ID' / bare beads ID?"}
Q -->|Yes — issue selector found| List["Call artifact_list(item_id=N)<br>to discover registered artifacts<br>(N may be int for GitHub or str for beads)"]
Q -->|No — no issue reference| Skip[Skip artifact discovery<br>Proceed normally]
List --> Found{Artifacts returned?}
Found -->|Yes| Store["Store artifact list as discovered_artifacts<br>Include paths and types in each<br>phase delegation prompt"]
Found -->|No or empty| Skip
Store --> Phase1([Proceed to Phase 1])
Skip --> Phase1
When discovered_artifacts is non-empty, append this block to each phase delegation prompt:
<prior_artifacts>
The following artifacts are already registered for this issue. Read any relevant
ones via artifact_read(item_id={issue}, artifact_type="{type}") before
starting your work — they contain prior research and analysis that should
inform your output.
{for each artifact: "- {artifact_type}: {path}"}
</prior_artifacts>
Research-type artifacts (artifact_type="research") are especially valuable — they contain investigation findings gathered before planning began. Phase agents should read these first when present.
Research artifacts as discovery pointers (not authoritative sources): Research entries
record summary findings and upstream source references — they are NOT the primary source.
Research artifacts are discovery pointers, not authoritative documents.
The YAML frontmatter of a research artifact may contain resource_url and/or github_url
fields pointing to the upstream content. Phase agents receiving a research artifact MUST
check these fields and fetch the upstream source before adapting content from the summary.
This is especially important for Phase 1 (feature-researcher) and Phase 3 (architect).
Failure to fetch the primary source causes information loss from the summary layer to
propagate into feature context and architecture decisions.
Registration read-back (applies after every artifact_register call in Phases 1-3): a count
of 1 from artifact list is not proof the content is real — after registering, read the artifact
back and confirm which of three outcomes occurred: (1) content reads back as the document —
proceed; (2) content reads back empty or a literal placeholder (e.g. $(cat ...)) — same failure
as count == 0, re-dispatch; (3) content is not found at all despite the entry existing — the
legacy-artifact case (a manifest entry registered without content), a different failure from "not
registered," report it as such rather than treating it as re-dispatchable.
Canonical write-back across phases: when a later phase resolves a question an earlier artifact posed as open, re-register the earlier artifact with the resolution — including the read-back above confirming the new content is in place — before dispatching the next phase. #2498's feature-context artifact still posed a question as open after the Concerns section had already resolved it; the next phase read the stale artifact fresh and reported it as drifted. Re-registering the resolved artifact before that phase runs is cheaper than a later phase re-discovering the same staleness.
Orchestrator Discipline
You are an orchestrator. You coordinate work across specialized agents.
Shared Delegation Preamble
Every phase delegation prompt starts with this block. Fill {work_type}, {feature_name}, and {issue} from the values in the Template Variables section at the bottom of this skill.
The {quality_vigilance} template variable used in every phase delegation template below expands to the <quality_vigilance> block defined here — this is the single canonical definition.
You are part of a team that is currently working on the {work_type} {feature_name}.
Read the details about the milestone and plan you are a part of at backlog_view(selector="#{issue}").
<quality_vigilance>
Your task among all other things you are doing is to be consistently striving for
product quality improvements and aligning with the design intent. If you see something
that seems misaligned, verify it, and then note your concerns and findings concisely
in your response in a <concerns></concerns> block. Point out duplication, contradictions,
statements of fact without citation, code smells, missing documentation.
For claims derived from research artifacts: verify the claim against the upstream
primary source, not just the local research summary. If the research artifact frontmatter
contains `resource_url` or `github_url`, fetch that URL and check the claim against it.
Cite the fetched primary URL, not the research summary file path, when the claim originates
from external upstream content.
</quality_vigilance>
Plan Artifact Taxonomy
Plan artifacts are either human-decision (immutable — backlog items, grooming output, interview transcripts) or generated (mutable but intent-bound — feature context, architecture spec, task plan). Full taxonomy and divergence rules: Plan Artifact Lifecycle Policy.
Phase 1: Discovery (@dh:feature-researcher)
WHAT / WHY only. The feature-researcher produces problem space and desired outcome — not implementation approach. Output describes what is wanted and why; it does not prescribe how to build it.
Delegation prompt template:
You are part of a team that is currently working on the {work_type} {feature_name}.
Read the details about the milestone and plan you are a part of at backlog_view(selector="#{issue}").
{quality_vigilance}
Research #{issue}: "{title}".
If research artifacts exist for this issue, read them via
artifact_read(item_id={issue}, artifact_type="research") before starting
discovery — they contain prior investigation findings that should be incorporated.
IMPORTANT: Research artifacts are discovery pointers, not authoritative documents.
After reading the research artifact, inspect its YAML frontmatter for `resource_url`
and `github_url` fields. If either is present, fetch the upstream source using
mcp__Ref__ref_read_url (or WebFetch as fallback) and treat it as the authoritative
primary source. Use the local research summary as an index to the primary source only.
If the URL is absent or unreachable (4xx/5xx/timeout), log a warning in the
`## Research Source Notes` section of the feature-context document and proceed from the
local summary — never hard-fail.
Produce feature-context-{slug}.md content with WHAT/WHY analysis — problem space, desired
outcome, stakeholders, risks, open questions.
Do NOT prescribe HOW to build it.
If the feature involves replacing or migrating a local module to an external tool,
you MUST perform a Replacement Coverage Analysis: enumerate all capabilities of the
local module, enumerate the replacement's capabilities, and produce a coverage matrix
(COVERED/PARTIAL/MISSING for each capability). Include the matrix in the feature-context
document. Surface any PARTIAL or MISSING capabilities as questions.
Register your deliverable and return:
1. Call `artifact_register` with the full feature-context content:
mcp__plugin_dh_backlog__artifact_register(
item_id={issue},
artifact_type="feature-context",
artifact_id="plan/feature-context-{slug}.md",
content="<full feature-context markdown>",
agent="feature-researcher"
)
2. Return:
STATUS: DONE
path: plan/feature-context-{slug}.md
After the agent completes, verify the artifact was registered:
uv run "${CLAUDE_PLUGIN_ROOT}/sam_schema/cli.py" artifact list --item-id {issue} --artifact-type feature-context
If count == 0, the agent did not register the artifact. Re-dispatch with an explicit
reminder that artifact_register(content=...) is the agent's responsibility, not the
orchestrator's. The orchestrator MUST NOT call artifact_register as a workaround —
the MCP-native rule is that agents own their artifact storage.
Then apply the registration read-back rule from the Artifact Discovery section above:
uv run "${CLAUDE_PLUGIN_ROOT}/sam_schema/cli.py" artifact read --item-id {issue} --artifact-type feature-context
Phase 2: Codebase Analysis (@dh:codebase-analyzer)
WHAT exists today only. The codebase-analyzer maps existing patterns, conventions, and constraints — not proposed designs. Output describes what is there; it does not prescribe what to add or change.
If helpful, delegate to @dh:codebase-analyzer for one or more focus areas:
- patterns
- architecture
- testing
- conventions
Each focus area produces a markdown document. The agent self-registers each document via artifact_register(content=...) and returns only STATUS: DONE with the artifact ID(s).
Delegation prompt template (one per focus area):
You are part of a team that is currently working on the {work_type} {feature_name}.
Read the details about the milestone and plan you are a part of at backlog_view(selector="#{issue}").
{quality_vigilance}
Analyze {focus_area} for #{issue}: "{title}".
Produce {focus_area}.md content documenting what exists today — patterns,
conventions, constraints.
Do NOT prescribe changes.
Register each document and return:
1. Call `artifact_register` with the full codebase analysis content for each focus area:
mcp__plugin_dh_backlog__artifact_register(
item_id={issue},
artifact_type="codebase-analysis",
artifact_id="plan/codebase-{focus}-{slug}.md",
content="<full codebase analysis markdown>",
agent="codebase-analyzer"
)
Note: A single invocation covering multiple focus areas issues one `artifact_register` call per
focus area with a distinct `artifact_id` per focus.
2. Return:
STATUS: DONE
path: plan/codebase-{focus}-{slug}.md
After the agent completes, verify the artifact was registered:
uv run "${CLAUDE_PLUGIN_ROOT}/sam_schema/cli.py" artifact list --item-id {issue} --artifact-type codebase-analysis
If count == 0, the agent did not register the artifact. Re-dispatch with an explicit
reminder that artifact_register(content=...) is the agent's responsibility, not the
orchestrator's. The orchestrator MUST NOT call artifact_register as a workaround —
the MCP-native rule is that agents own their artifact storage.
Then apply the registration read-back rule from the Artifact Discovery section above:
uv run "${CLAUDE_PLUGIN_ROOT}/sam_schema/cli.py" artifact read --item-id {issue} --artifact-type codebase-analysis
Phase 3: Architecture Spec (design-spec role)
HOW only. The design-spec agent designs the implementation approach — interfaces, data models, module boundaries, and call flows. Output prescribes structure and contracts; it does not re-describe the problem or re-map existing code.
Resolve the design-spec role from the language manifest before delegating:
flowchart TD
Scan[Scan project root for language markers] --> Found{Marker found?}
Found -->|pyproject.toml| Py[Search Python language manifest]
Found -->|package.json| TS[Search TypeScript language manifest]
Found -->|Cargo.toml| Rust[Search Rust language manifest]
Found -->|None| FB["Fallback: dh:task-worker<br>(no specialist profile loaded)"]
Py --> ManifestFound{Manifest exists?}
TS --> ManifestFound
Rust --> ManifestFound
ManifestFound -->|Yes| Resolve["Resolve design-spec role from manifest<br>(Python example: python-engineering:python-cli-design-spec)"]
ManifestFound -->|No| FB["Fallback: dispatch dh:task-worker<br>no specialist profile loaded"]
Resolve --> Store["Store as {resolved_agent}<br>profile_load(agent_name='{resolved_agent}') in delegation prompt"]
Store --> Delegate["Dispatch subagent_type='dh:task-worker'"]
FB --> Delegate
Phase 3 always dispatches subagent_type="dh:task-worker". When a specialist is resolved from the language manifest, the orchestrator instructs task-worker to call mcp__plugin_dh_backlog__profile_load(agent_name="{resolved_agent}") at the start of its prompt — this is the agent_profile MCP tool on the backlog server and is how task-worker loads specialist behavior when no SAM task agent: field is available. Use {resolved_agent} as the agent= metadata in artifact_register to record which specialist produced the spec. This call remains MCP-only.
Domain Signal Detection — Config-Driven (.dh/skill_discovery.yaml)
Before constructing the architect delegation prompt, populate {domain_skills} by reading
the project's skill discovery configuration.
Step 1: Locate the config file
Check whether .dh/skill_discovery.yaml exists in the project root.
flowchart TD
A{".dh/skill_discovery.yaml\nexists?"} -->|YES| B[Read and parse YAML]
B --> C{Valid YAML?}
C -->|NO| W["Emit warning\ndomain_skills = empty\ncontinue"]
C -->|YES| D{"skill_discovery\nmode?"}
D -->|off| E["domain_skills = empty"]
D -->|auto| F["Collect always_use_skills\n+ evaluate skill_rules"]
D -->|suggest| S["Collect always_use_skills\n+ evaluate skill_rules"]
F --> G["Apply avoid_skills filter\nDe-duplicate\ndomain_skills populated"]
S --> SN["Emit note listing\ncandidate skills"]
SN --> SE["domain_skills = empty\n(no injection)"]
SE --> G2["Continue to injection\ntemplate check\n(sees empty — skips)"]
A -->|NO| I["Invoke wizard:\nSkill(skill='dh:setup-skill-discovery', args='--auto')"]
I --> J{File written?}
J -->|YES| B
J -->|"WIZARD_DECLINED\nin output"| K["suggest mode fallback\ndomain_skills = []\ncontinue with note"]
Step 2: Collect {domain_skills}
When file is present, valid YAML, and skill_discovery mode is not off:
- Add all
always_use_skillsentries unconditionally - For each
skill_rulesentry: evaluatewhen:using LLM reasoning against thefeature_requesttext — if the condition is satisfied, add all skills inuse:to the set - Remove any skills listed in
avoid_skills prefer_skillsentries are tiebreaker advisory — do not add unconditionally- De-duplicate the collected set
Suggest mode: When skill_discovery mode is suggest, Steps 1–5 above still execute
(so the candidate list is accurate), but the collected skills are emitted as a note to the
user listing what would be injected — they are not actually injected. After emitting the
note, set domain_skills to empty and continue to the injection template check (which sees
empty and skips injection).
when: Evaluation Semantics — LLM Reasoning
Evaluate each when: field as a natural-language condition against the semantic content of
the feature_request. The rule fires if the condition is unambiguously satisfied. Do not
fire speculatively when uncertain.
Example: when: "involves Python, pytest, or uv" + feature about "pytest fixture for
database" → fires
Example: same rule + feature about "dark mode toggle button" → does not fire
Step 3: Inject into architect prompt
If {domain_skills} is non-empty, prepend this block at the very top of the architect
delegation prompt, before the shared preamble and before any artifact reads.
Ordering constraint when <prior_artifacts> is also present: the domain skill block
MUST come first — it is a blocking prerequisite that must complete before any artifact
reads occur. Place domain skills → then prior_artifacts → then the delegation prompt body.
If {domain_skills} is empty, prior_artifacts placement is unchanged.
Wizard Invocation Protocol
When .dh/skill_discovery.yaml does not exist:
- Inform the user:
"No .dh/skill_discovery.yaml found. Running skill discovery wizard..." - Invoke:
Skill(skill="dh:setup-skill-discovery", args="--auto")(programmatic context) - After wizard returns: re-check for the file (recurse once only)
- If file still absent (
WIZARD_DECLINEDin wizard output): apply suggest-mode fallback
Suggest-mode fallback note:
Note: No
.dh/skill_discovery.yamlconfigured. Skills that may be relevant: [judgment-based list based onfeature_requestcontent]. To configure permanently:/dh:setup-skill-discovery. Continuing without domain skill injection.
Set {domain_skills} to empty and continue without blocking.
{domain_skills formatted as Skill(skill="...") calls}
These are BLOCKING prerequisites — do not read any artifacts or write any design until all Skill() calls above have completed. Training data is not a substitute for live schema documentation loaded by these skills. </domain-skill-injection-template>
If {domain_skills} is empty, do not add any skill-loading block — proceed directly to
the delegation prompt below without modification.
Dispatch: subagent_type="dh:task-worker". Build the delegation prompt from the template below.
Delegation prompt template:
{specialist_skill_block}
You are part of a team that is currently working on the {work_type} {feature_name}.
Read the details about the milestone and plan you are a part of at backlog_view(selector="#{issue}").
{quality_vigilance}
Before designing, discover existing architecture documents nearest the module being changed —
do not write architecture from scratch when one already covers this area. Derive the subtree to
search from the item's `suggested_location` field (read via backlog_view above); scope each glob
there first, then widen only if nothing is found: Glob(pattern="{subtree}/**/ARCHITECTURE.md"),
Glob(pattern="{subtree}/**/CONTEXT.md"), Glob(pattern="{subtree}/**/adrs/ADR-*.md"). Read whatever
exists nearest first, then work outward. Update or extend an existing ARCHITECTURE.md, CONTEXT.md,
or ADR rather than duplicating its content in the new spec.
Design the implementation for #{issue}: "{title}".
Read the feature context via artifact_read(item_id={issue}, artifact_type="feature-context").
[If codebase analysis exists: Read via artifact_read(item_id={issue}, artifact_type="codebase-analysis").]
If research artifacts exist for this issue, read them via
artifact_read(item_id={issue}, artifact_type="research") for prior research
findings that should inform the architecture.
IMPORTANT: Research artifacts are discovery pointers, not authoritative documents.
After reading any research artifact, inspect its YAML frontmatter for `resource_url`
and `github_url` fields. If either is present, fetch the upstream source using
mcp__Ref__ref_read_url (or WebFetch as fallback) and verify currency and completeness
of the research summary against the primary source before designing. If the URL is
absent or unreachable (4xx/5xx/timeout), log a warning in the `## Research Source Notes`
section of the architect document and proceed from the research summary — never hard-fail.
Additionally, run a WebSearch for current best practices relevant to this feature before
finalizing the architecture. Training data is stale; current community practice may differ.
Produce architect-{slug}.md content with interfaces, contracts, data models, module boundaries.
Do NOT implement — define WHAT to build, not the code.
Register your deliverable and return:
1. Call `artifact_register` with the full spec content:
mcp__plugin_dh_backlog__artifact_register(
item_id={issue},
artifact_type="architect",
artifact_id="plan/architect-{slug}.md",
content="<full spec markdown>",
agent="{resolved_agent}"
)
2. Return:
STATUS: DONE
path: plan/architect-{slug}.md
{specialist_skill_block} is built by the orchestrator before dispatch:
- When
{resolved_agent}is set (manifest found):"Load your specialist profile before starting: mcp__plugin_dh_backlog__profile_load(agent_name='{resolved_agent}'). This is a BLOCKING prerequisite — complete it before reading any artifacts or designing.\n\n" - When no manifest found (fallback):
""(empty string — task-worker executes directly without a specialist profile)
After the agent completes, verify the artifact was registered:
uv run "${CLAUDE_PLUGIN_ROOT}/sam_schema/cli.py" artifact list --item-id {issue} --artifact-type architect
If count == 0, the agent did not register the artifact. Re-dispatch with an explicit
reminder that the agent must call artifact_register(content=...) itself — the
orchestrator MUST NOT call artifact_register as a workaround. The MCP-native rule
is that agents own their artifact storage.
Then apply the registration read-back rule from the Artifact Discovery section above:
uv run "${CLAUDE_PLUGIN_ROOT}/sam_schema/cli.py" artifact read --item-id {issue} --artifact-type architect
Phase 4: Task Decomposition (@dh:swarm-task-planner)
Delegate to @dh:swarm-task-planner to:
- before decomposing, read the item's own declared documentation obligations — its "Documentation (will become stale)" section and any ecosystem/completeness checklist — and create a task for each declared obligation. Skipping this makes Phase 5's validator catch the gap expensively, after the plan is already built, instead of during decomposition.
- create the structured plan via
plan createor MCPsam_plan; preserve the returnedplan_refunchanged - ensure every task has:
- Status, Dependencies, Priority, Complexity, Agent
- Acceptance Criteria (3+)
- Verification Steps (3+)
Delegation prompt template:
You are part of a team that is currently working on the {work_type} {feature_name}.
Read the details about the milestone and plan you are a part of at backlog_view(selector="#{issue}").
{quality_vigilance}
Decompose #{issue}: "{title}" into executable tasks.
Read the architecture spec via artifact_read(item_id={issue}, artifact_type="architect").
Read the feature context via artifact_read(item_id={issue}, artifact_type="feature-context").
Before decomposing, also read the item's own "Documentation (will become stale)" section and any
ecosystem/completeness checklist via backlog_view(selector="#{issue}") — create a task for every
obligation declared there.
Create the plan via sam_plan with CLEAR+CoVe task definitions.
REQUIRED — skills field propagation:
The domain skills identified in Phase 3 are:
{domain_skills}
Every task in the generated plan MUST include a `skills` field populated with ALL of
these domain skills as a YAML list. Example:
skills:
- plugin-creator:hook-creator
- plugin-creator:hooks-io-api
If `{domain_skills}` is empty (no domain signals were detected in Phase 3), omit the
`skills` field from all tasks — do not add an empty list.
The `skills` field is consumed by `implement-feature` to inject skill-loading instructions
into each implementation agent's prompt. Omitting it means implementation agents proceed
without domain schema context.
Linking the plan to the backlog item is a step of add-new-feature itself, run in the same
context that read this file — not part of the swarm-task-planner delegation above. Everything
sent to that subagent lives inside the fenced delegation prompt block above; this step sits
outside it. The swarm-task-planner never reads this file, so it cannot perform this step — a
self-report such as "linked to issue #N" is not evidence the link exists. Confirm the link by
reading state, not by trusting a report:
# 1. Read current state — plan is null until the link is written
uv run "${CLAUDE_PLUGIN_ROOT}/sam_schema/cli.py" backlog view --selector "#{issue}"
# 2. If plan is null, write the link using the exact value returned by sam_plan
uv run "${CLAUDE_PLUGIN_ROOT}/sam_schema/cli.py" backlog update --selector "{title}" --plan "{plan_ref}"
# 3. Re-read and confirm plan equals plan_ref before proceeding to Phase 5
uv run "${CLAUDE_PLUGIN_ROOT}/sam_schema/cli.py" backlog view --selector "#{issue}"
The backlog_update(plan=...) call writes the opaque plan_ref into the backlog item's metadata.plan
field. This records the logical address, not a filesystem path. work-backlog-item uses the linked
reference to route directly to implement-feature, and SAM reads the plan through the configured provider.
Phase 5: Plan Validation Gate (@dh:plan-validator)
Delegation prompt template:
You are part of a team that is currently working on the {work_type} {feature_name}.
Read the details about the milestone and plan you are a part of at backlog_view(selector="#{issue}").
{quality_vigilance}
Validate plan {plan_ref} for #{issue}: "{title}".
Check: AC coverage, dependency DAG, agent assignments, verification steps,
impact radius coverage.
Return READY or BLOCKED with specific gaps.
If the validator returns BLOCKED, do not proceed to Phase 6. Fix the identified gaps: for a
specific, scoped gap (e.g. one missing task), dispatch a new, narrowly-scoped delegation to
@dh:swarm-task-planner naming the exact gap and asking it to add or amend that specific task in
the existing plan {plan_ref} — a subagent dispatch terminates after Phase 4 returns, so this is a
fresh call operating on the existing plan address, not a resumed session. Re-run Phase 4 from
scratch only when the plan's overall structure itself is wrong. Retry Phase 5 after either path.
Phase 6: Context Manifest (@dh:dh-context-gathering)
Delegation prompt template:
You are part of a team that is currently working on the {work_type} {feature_name}.
Read the details about the milestone and plan you are a part of at backlog_view(selector="#{issue}").
{quality_vigilance}
Add context manifest to plan {plan_ref} for #{issue}: "{title}".
Read the plan via mcp__plugin_dh_sam__sam_plan(config={"action": "read"}, plan="{plan_ref}").
Write the context manifest via
mcp__plugin_dh_sam__sam_plan(config={"action": "update", "context": "<context manifest>"}, plan="{plan_ref}").
Template Variables
Fill these values before constructing each delegation prompt. All values come from context already in scope — no pre-gathering required.
| Variable | Source |
|---|---|
| {item_ref} | Provider-native item selector — GitHub issue number (int) or Beads ID string (e.g. bd-a3f8) |
| {issue} | Legacy/template alias for the structured artifact adapter's item identifier; preserve its provider-native type |
| {title} | Provider-native item title from bd show in Beads workspaces, or backlog_view for GitHub-backed workflows |
| {slug} | Kebab-case identifier derived from the issue title (e.g., agent-profile-mcp-tool) |
| {work_type} | "production of the feature" for new features; "fixing of an issue in" for bug fixes |
| {feature_name} | Human-readable feature name from the issue title |
| {focus_area} | One of: patterns, architecture, testing, conventions (Phase 2 only) |
| {domain_skills} | Pre-formatted YAML list lines (e.g., - plugin-creator:hook-creator) collected by the Phase 3 domain signal scan; empty string if no signals matched; passed verbatim into Phase 4 delegation prompt |
| {plan_ref} | Opaque logical plan reference returned by sam_plan create; pass it unchanged |
| {quality_vigilance} | Full <quality_vigilance>...</quality_vigilance> block — canonical text defined in §Shared Delegation Preamble above; substitute verbatim when constructing delegation prompts |
Success Outcome
When all phases complete, provide the user:
- the feature slug
- the returned
plan_ref - next step: run the
implement-featureskill with that exactplan_ref
Discovered During Implementation
The architect agent calls artifact_register(content=...) directly, the selected provider stores the body, and the orchestrator receives only STATUS: DONE.
This workflow requires content= on every artifact_register call so later phases receive the body from artifact_read. A registration without content does not satisfy the phase handoff.