Mechanical rename produced by scripts/msd-rename.cjs: gsd/Gsd/GSD -> msd/Msd/MSD across contents and paths, upstream package/repo coordinates -> @golem15/msd-core and golem15com/msd-core. Deep links into upstream history, sibling upstream packages, the GSD-2 import feature, CHANGELOG.md and .changeset/ are kept as-is. Hand edits on top: MSD block-letter banner and logos, LICENSE copyright line, package/plugin identity, regenerated lockfile, install-tree fixtures, derived registries and benchmark baseline; migration checksum baseline re-locked (MSD keeps its own install state, so no install had applied the old sums); sort-order and regex-escaped expectations in tests adjusted.
2.8 KiB
2.8 KiB
id, title, group
| id | title | group |
|---|---|---|
| 3970 | Per-Task External-Tracker Content-Resolution Seam | v1.7.0 Features |
Purpose: Let a capability declare that an external issue tracker — beads, Linear, Jira,
GitHub Issues — owns a task's content (<action>/<verify>/<acceptance_criteria>/
<read_first>/<done>), not just its status, so execute-plan.md can resolve that content
from the tracker at execution time instead of reading it inline out of PLAN.md.
What changed (ADR-3646, #3970):
- A new optional feature-body manifest field,
taskContentResolver, declares atrackerPrefix(matched against a task's<task tracker-id="beads:MSD-42">attribute — everything before the first:) and a boundedinvoke(binary,argscarrying the{{id}}placeholder,timeoutMs). execute-plan.md's per-task loop gains one new, unconditional call before that task'sread_firstgate:msd_run task resolve-content --plan <path> --task-id <tracker-id> --raw. A task with notracker-idattribute is unaffected — the call is only made when the attribute is present, and resolves instantly to a no-op for every project that declares none.- The safety property is a real process exit code, not a prose dispatch. No capability
registered for the tracker, or resolution succeeds with empty content, exits
0withresolved: falseand falls back to inlinePLAN.md— the one legitimate pre-migration boundary case. Resolution succeeding with non-empty content exits0withresolved: trueand itscontentsupersedes the task's inline fields for every downstream gate in the execute step. A resolver that is declared but fails — tracker unreachable, id not found, timeout, malformed JSON — makestask resolve-contentitself exit non-zero, whichexecute-plan.mdtreats as a hard halt: stop, surface the tracker-id/prefix/stderr, never fall back to stalePLAN.mdcontent. execute:taskis a new dispatch shape below wave granularity, deliberately not one of the 12 existing loop extension points (discuss:pre…ship:post) and not routed throughmsd_run loop render-hooks <point>/activeHooks. It exists because the existingstep/gateprose-dispatch mechanism cannot deliver a hard-halt guarantee while dispatch reliability at that layer is an open concern (#3647) — see ADR-3646's Context and Rejected Alternatives for the full reasoning.
See Develop a task-content resolver capability
for the authoring walkthrough, Capability manifest → taskContentResolver
for the field reference, and
loop-hook-dispatch.md
for how execute:task differs from the twelve prose-dispatched points.