Releases: FL03/shepherd
v6.1.9
v6.1.8
v6.1.8 — 2026-06-17
Field-shape deduplication — shctx dups (#157). The third leg of the
mechanical shape-gate set (with dep-hygiene and check-impls-defs). Name-matching
dedup (index_symbols / dedup-check.sql / dedup_write_guard.sh / the conductor
DEDUP-GATE) catches a duplicate ONLY when the second definition reuses the first
one's name. It is blind to the dominant large-workspace rot: a second type for an
existing concept under a different name — the rename-to-evade-dedup shadow that
compiles green and slips every name-keyed gate (a 2026-06-17 audit of one workspace
found 22 such clusters). shctx dups closes that gap by clustering on field
shape, and gives subagents a way to recognize a pre-built struct they can reuse
without remembering its name — the match is surfaced, by shape, at authoring time.
New — shctx dups <scan|check|registry>
scan— workspace census: parses everypub struct/pub enum, fingerprints
each by its(field_name, normalized_type)set, clusters by similarity, and
reports each cluster with members (file:line+ consumer count), pairwise
similarity, and a suggested canonical (lowest dep tier).--updatepersists
the corpus toindex_struct_shapes;--fail-on {medium|high|foundation-blocking}
is a non-zero CLOSE/CI gate. The headlinefoundation-blockingseverity flags an
orphan canonical (zero consumers) sitting beside a live shadow.check <file> | --stdin --as <path>— authoring-time gate: matches a
candidate's NEW defs against the corpus and reports any same-shape existing type
("…is 0.85-similar topkg::X— reuse it?"). Exits5above the block
threshold. Used by the PreToolUse hook and as a coder Phase-0 self-check.registry show|allow|unallow|pin|unpin|update— curatedconcept→canonical
pins + a DO-NOT-MERGE allow-list for intentional distinct-role twins (a venue
Fillvs a backtestSimFill). Tracked at<ns>/dups-registry.json.
Similarity, parsing, storage
- Metric:
sim = name_weight·jaccard(field_names) + (1−name_weight)·jaccard(typed_pairs).
The field-NAME blend catches a shadow that restatedUuid→String/DateTime→String
/f64field-for-field under a new name. Field-less (marker) shapes and shapes
belowdups_min_fieldsare excluded. - Parser (
skills/context/scripts/dups-core.py, stdlib python3) — a brace /
generic / attribute-aware scanner over Rust source realizes the proposal's
"Rust + syn" intent without a build step and is deterministic + unit-testable.
Tree-sitter multi-language is a later extension; the shape model + similarity +
clustering are language-agnostic. DB I/O routes through python'ssqlite3
module (no dependency on thesqlite3binary). - Schema:
migrations/0015_struct_shapes.sqladdsindex_struct_shapes
(the field-shape corpus, sibling ofindex_symbols/index_concepts). - Refresh:
shctx refresh --scope=shapes(folded into--all, hence
sprint open) keeps the corpus current.
Enforcement + integration
- New PreToolUse(Write|Edit) hook
hooks/scripts/dups_write_guard.sh— the
shape-shaped sibling ofdedup_write_guard.sh.@coder.rswrites only;
config[dups].dups_hook = off | warn (default) | block. Fails open at every
step (non-coder, non-rust, no python3, empty corpus → silent pass); it can only
block on a real shape match. - New doctrine
doctrines/shape-dedup.md;zero-duplicate-tolerance.mdgains
Layer 4 + a cross-link. - Config
[dups](docs/configuration.md+ both exampleshepherd.tomls):
dups_threshold,dups_block,dups_name_weight,dups_min_fields,
dups_hook,dups_registry(keys aredups_-prefixed becausecfg_getis
section-agnostic).rust-servicewires ashape-dedupclose gate into
[gates].extra. - Tests:
skills/context/tests/test_cmd_dups.sh(scan/check/registry/gate/persist)
andhooks/tests/test_dups_write_guard.sh(block/warn/off + fast-paths), plus
smoke cases.
Fix — the shctx absent false negative
A live v6.1.7 session reported shctx absent. Root cause: shctx is plugin-local
and never on $PATH — it is invoked by the absolute path
${CLAUDE_PLUGIN_ROOT}/skills/context/scripts/shctx. A command -v shctx /
which shctx probe returns absent by design, and when $CLAUDE_PLUGIN_ROOT
does not propagate into the agent's Bash env (some remote/web launches) even the
full-path invocation fails. Neither is evidence of absence.
hooks/scripts/session_open.shnow surfaces, at SessionStart, the absolute
shctxpath resolved from the hook's own location (hooks/scripts → ../..),
correct regardless of$CLAUDE_PLUGIN_ROOT, with the explicit note that
command -v shctxreturns absent by design. Config-gated
[context].announce_shctx_path = on (default) | off.skills/context/SKILL.mddocuments the rule authoritatively (never PATH;
command -vis the #1 false-negative; invoke by absolute path).- Test:
hooks/tests/test_shctx_locator.sh(surfaces the path with
$CLAUDE_PLUGIN_ROOTunset; off-switch suppresses).
Fix — staged-handoff (v6.1.7) never actually worked
Verifying the v6.1.7 staged-handoff feature (/shepherd:spawn --staged +
seed-ready mailbox signal) surfaced a shipped defect: the mailbox.kind CHECK
constraint (from 0007) was a closed enum
(heartbeat_payload|escalation|ack|status|generic), so
shctx mailbox send --kind=seed-ready was rejected by the schema — the signal
could never be sent. Every future doctrine adding a routing tag would have hit the
same wall, silently.
migrations/0016_mailbox_kind_relax.sqlrebuildsmailboxwith a permissive
CHECK(kind <> '')(root-cause fix, not a one-value patch), preserving columns,
data, the FK, both partial indexes, and the unread view.doctrines/staged-handoff.mdjqconsume snippet corrected to iterate the
JSON array (.[] | select(...);recvemits an array).- Test:
skills/context/tests/test_staged_handoff.shdrives the full
send → recv --unread-only --mark-read → ackseed-ready round-trip.
Both full suites green (hooks 44/44, shctx 44/44).
v6.1.7
v6.1.6
v6.1.6 — 2026-06-15
Two-lane release. Lane A makes teammate-conductors actually leverage the
native Claude Code Workflow (Dynamic Workflows) tool instead of reflexively
ToolSearch-ing for it and mis-degrading. Lane B introduces /shepherd:ponytail
and the senior-engineering operating standard — the primitives that turn the
@auditor and @coder into senior devs, cemented into their profiles and adaptable
to the project and user.
The trigger for Lane A was a live failure: an
/effort ultracodesession, told to
"use the Workflow tool," ranToolSearch select:Workflow, got nothing, and declared
the tool "confirmed absent" — the exact mistake teammate-conductors make. The fix
is not more prose (there was already plenty) but a recorded first-action
self-check that an agent cannot skip.
Lane A — teammates actually leverage Dynamic Workflows
- New doctrine
doctrines/workflow-tool-self-check.md— the operational
front-end for the nativeWorkflowtool, consolidating the detect / never-
ToolSearch / benefit guidance that was scattered acrossreferences/glossary.md §1,
capability-discovery.md §V,workflow-compile-down.md, and
primitive-axis-binding.md §IV(and still got skipped). ONE first action:
is the tokenWorkflowin your visible tool list? → record
workflow_tool: present|absent→ branch. Present → compile gate-free fan-out
out-of-context (framed as the conductor's OWN benefit: clean context window + ≤16
background agents, not a tax). Absent (web/remote, #146) → degrade to in-context
Agent(...)— correct and expected. NEVERToolSearchfor it (the
WORKFLOW-SELFCHECK-TOOLSEARCHanti-pattern), not even under/effort ultracode. - Wired as a first action into
agents/conductor.md(prohibition #22 rewritten +
mode-comparison rows + a step 0 in the teammate compile sequence),agents/shepherd.md
(root Step 0 +[ROOT-START] workflow_tool=…),commands/spawn.md(teammate boot
prompt), andcommands/start.md(lane walk step 0 +WAVE-COMPLETE.workflow_tool/
.fanoutfields). Corrected the stale "always present" phrasing to the
environment-dependent visible-tool-list test. - Enforcement seam: new
@auditorcompleteness extension
(agents/auditor.md §workflow-substrate discipline) — filesPRIMITIVE-INVERSION
when a lane hand-rolled in-context fan-out where the tool was present, and a LOW
finding when the self-check was skipped or the tool was ToolSearched. In-context
fan-out where the tool is absent is correct and never flagged.
Lane B — /shepherd:ponytail + the senior-engineering standard
- New doctrine
doctrines/senior-engineering.md(the "ponytail" doctrine) — the
senior-engineering operating standard for@auditor+@coder, eight primitives
that build on the existing flock doctrines (cite, never duplicate): (I) comprehend
intent before you touch (Chesterton's fence); (II) root-cause over symptom;
(III) blast-radius- & cost-to-reverse-weighted severity; (IV) justify the tradeoff,
not just the change; (V) conform to THIS project and THIS user via a precedence
ladder (project doctrines >[CODE-STYLE]ledger >code-styleskill > adaptation
priors > the neighbors > defaults); (VI) cross-concern systemic-risk detection;
(VII) bounded restraint (the most senior move is often the smaller diff);
(VIII) preserved read-only/tier discipline.SENIOR-STANDARD-MISUSEanti-pattern. - New command
/shepherd:ponytail(commands/ponytail.md, also/ponytail) — an
on-demand senior review → refine → verify pass on a target (diff, path, file, or
PR) outside the sprint pipeline: Pattern 3 (Adversarial Verification) + Pattern 4
(Generate-And-Filter), bounded as the AUDITOR-REFINE loop. Review-only by default;
--applyruns the coder-refine + re-verify loop;--cementpersists the conventions
the pass observed into project memory / the style ledger. Fully adapted via styles,
project doctrines, config, and adaptation priors. - Cemented into the profiles:
agents/auditor.mdandagents/coder.mdnow cite
senior-engineering.mdin §"Doctrines this role honors" with the per-role primitive
summary, and the FIRST-loaded reference skills (auditor.reference.md,
coder.reference.md) carry the senior lens. New config section[ponytail]
(senior_standard,default_mode,max_verify_iterations,apply_requires_approval,
conformance_sources) indocs/configuration.md.
Wiring
skills/shepherd/SKILL.md—/shepherd:ponytail+/ponytailtriggers, command-table
row, and §XI file-map rows for both new doctrines + the command.skills/shepherd/doctrines/README.mdindex — rows forworkflow-tool-self-check.md
andsenior-engineering.md.CLAUDE.mdcommand table + file-contracts;README.mdcommand banner.
v6.1.5
v6.1.5 — 2026-06-15
Kickoff-hardening + config-auto-scaffold + observability release (#147), extended
with two new capabilities — #148 supervised self-heal and #146 capability
auto-discovery — plus a reliability follow-up that repairs the
operator-signaling inversion (the planter under-asked while the shepherds
over-asked), the "Workflow tool is always present" overclaim that made
web/remote sessions give up instead of degrading, and two latent namespace/DB
defects the new kickoff wiring exposed.
Authorized supervised self-heal — AUTONOMOUS-SENTINEL (#148)
- New loop template (
references/loop-templates.md §AUTONOMOUS-SENTINEL) +
binding doctrine (doctrines/autonomous-sentinel.md) for authorized
supervised autonomy — the supervised-remediation superset of SOAK-LOOP.
Stages: PROBE (seeded acceptance predicates, live) → CLASSIFY
(HOLD/REGRESSED/NEW) → ACT (dispatch a ≤S@coderhotfix through the existing
hotfix-dispatch ladder → gates-before-deploy → re-probe) → TERMINATE (K clean
ticks / N-HF cap / hard-stop). Hard rails: gates-before-deploy, ≤S / ≤3
concurrent / ≤N total HF caps, no destructive DB ops, auto-rollback on red,
paper-only (never flip to live without authorization), operator-override-each-
tick, full audit trail. - New config key
[close].autonomous_sentinel(default"off"— detection-only).
It must be"on"AND the seed must declareclose: autonomous-sentinelAND a
completesentinel_railsblock must be present before a single remediation
fires (three independent opt-in gates). New halt codesSENTINEL-RAILS-MISSING
/-SCOPE-EXCEEDED/-HF-CAP/-ROLLBACK/-HARD-STOP/-LOOP-CAP. - Reconciled the depth-3 "remediating inside a watch loop" anti-pattern in
references/loop-templates.md §SOAK-LOOPanddoctrines/outcome-enforcement.md §Seam 4: detection-only stays the DEFAULT and the anti-pattern for the
UNAUTHORIZED case; the explicitly-authorized AUTONOMOUS-SENTINEL case is carved
out.
Capability auto-discovery (#146)
- Shepherd now auto-detects the Claude Code plugins/skills available in the
environment and adapts without operator wiring. A cheap, one-time-per-session
SessionStart probe (hooks/scripts/capability_discovery.sh) enumerates
installed plugins + skills and writes an EPHEMERAL capability roster
(<ns>/cache/discovered-capabilities.json, gitignored) kept strictly distinct
from the operator-curatedtoolkit.json— discovery never overwrites intent.
The roster is merged at read time into the[TOOLKIT]surfaces (SessionStart
roster + engineer/coder/planter brief injection via the newshctx toolkit discovered), labeled auto-discovered and bounded at 12. - New doctrine
doctrines/capability-discovery.mdcodifies the guarded-integration
pattern ("if/rememberis available → use at handoff/CLOSE-FINALIZE + resume,
else shepherd-native"; same forsuperpowers,pr-review-toolkit), so behavior
degrades cleanly when a plugin is absent — shepherd never hard-depends on a
third-party plugin. - The probe also records whether the native
Workflowtool is present;
web/remote sessions that omit it degrade to in-contextAgent(...)fan-out
instead of giving up (cross-referenced inreferences/glossary.md). - New config key
[discovery].auto_capabilities(ondefault |off), resolved
viacfg_get(local → project → XDG-global precedence). Zero hot-path cost,
fail-open.
Seed-optional kickoff (#8)
/shepherd:start(Step 0) and/shepherd:spawn(Hard-stop #2 / Check 6) no
longer hard-refuse on a missing seed for a single--scope sprintrun: derive
the objective from the repo/issue ledger, or ask ONE batched kickoff question,
then run — perdoctrines/operator-signaling.md §"Seed is recommended, not required".--paralleland multi-sprint--scope patch|minor|versionwalks
still HARD-refuse (seeds are load-bearing there for collision detection + walk
enumeration).
Config auto-scaffold (#15)
- New
shctx config initscaffolds.claude/shepherd.tomlfrom the bundled
minimal template when absent (idempotent): derives[project].name(git
remote → cwd basename) and[gates](Cargo.toml→cargo, go.mod→go,
pyproject/setup.py→pytest+ruff, package.json→npm), and realigns[paths]to
the active shctx namespace. Addsshctx config get/show/path. - Wired at kickoff: start/spawn root scaffold →
[CONFIG]notice → PROCEED
(action-biased); plant scaffold → ONE batchedAskUserQuestionto refine
[branching]+[gates](replaces the #120 hard STOP).
Observability dashboard (#13)
- New
shctx dash— a one-glance, read-only sprint snapshot composed from
primitives the root already maintains (focus, graph state, live teammates,
unread mailbox, open escalations, active loops, GitHub cache freshness). No
new table/subsystem; bash-3.2-safe; degrades cleanly on missing DB/tmux.
Monitoring recipe:/shepherd:loop <interval> shctx dash.
Four config toggles (#10)
shctx config get <key> [default]is the uniform resolver (local→project→XDG)
the toggles read through. Defaults reproduce pre-v6.1.5 behavior exactly:
[autorun].on_grade_floor(abort),[autorun].inter_sprint_pause(brief),
[spawn].max_parallel(4),[spawn].dashboard_cadence(3m). The
previously-undocumented[autorun]section is now indocs/configuration.md.
Neutralized the bundled example (#9) + subagent-preference (#11)
examples/axiom/→examples/rust-service/; scrubbed all domain-specific
references (finance/polymarket/geo-block) from the example and ~23 doctrine
teaching snippets.geo-block-law.mdrewritten as a generic
regulated-upstream-API teaching example. Historical.artifacts/docs are
intentionally left intact.doctrines/agent-excellence.mdRule 6 (token-conservation / subagent
preference) is now wired into every agent profile.
Reliability follow-up — operator-signaling inversion
doctrines/operator-signaling.md (v6.1.4) was correct, but its posture was
never reproduced into the agent profiles that actually become system prompts at
runtime. AskUserQuestion is granted correctly in every profile — the inversion
was a prose-propagation gap, not a tools-grant bug:
agents/planter.md: added a standing "the planter asks freely" posture at
the top of plant mode (previously the ONLY trigger was the rare no-config
bootstrap branch, so the common case invented answers instead of asking).agents/conductor.md: SOLO =AskUserQuestionis a narrow escape valve only;
TEAMMATE mode MUST NOT call it (theMODE-MISUSEhalt code now names the
tool).agents/shepherd.md: root action-bias note — the defined gates are the only
operator stop points; no invented mid-run confirmation asks.
Reliability follow-up — the Workflow tool is NOT "always present"
references/glossary.mdlisted the nativeWorkflowtool alongside
Agent/Bash/Editas always-present and blamed any absence solely on "a
build below the Dynamic Workflows floor." Claude-Code-on-the-web /
remote-execution sessions omit it even on a supporting build, so a
spawn/loop that reached for it gave up instead of degrading. Corrected to
environment-dependent presence, with the visible-tool-list test as the
only authority and degrade-to-Agent(...)as the documented path (ties into
#146).
Reliability follow-up — two latent defects the kickoff wiring exposed
Both were invisible to the green suites (the harnesses set neither
CLAUDE_PLUGIN_ROOT nor a shepherd.db registry); #15's config-scaffold pulled
them onto the kickoff hot path:
shctx_skill_root()returned bare$CLAUDE_PLUGIN_ROOT, butschema/+
references/live at$CLAUDE_PLUGIN_ROOT/skills/context/.scaffold.sh's
cp references/naming-conventions.mdaborted underset -e, soshctx init/config initnever created the DB and every downstreamshctxcommand
failed. Now prefers the dispatcher-exportedSHCTX_SKILL_ROOT, else
$CLAUDE_PLUGIN_ROOT/skills/context. Verified end-to-end (init exits 0,
createsshepherd.db, copiesCONVENTIONS.md).- 9 hooks hardcoded
$ns/root.dbwhile v6.1.2+shctx initcreates
shepherd.db, so[[ -f "$DB" ]]was always false → silent no-op, disabling
the spawn-coordination guards (coordinate_drive_guard,
worktree_teardown_guard,teammate_idle, …) on every modern project. New
hook_db_path()inhooks/scripts/_lib.shmirrors the skills-side
shctx_db_path()(prefershepherd.db, fall back to an existingroot.db,
defaultshepherd.db); all 9 assignments route through it.
Tests: hooks 38/38 (+1 for the #146 capability-discovery probe), context 42/42.
v6.1.4
v6.1.3
v6.1.3 — 2026-06-12
The toolkit-hardening, bash-3.2-portability, and outcome-enforcement release. Fixes the v6.1.2 toolkit "Permission denied" that fired at session start, repairs three macOS bash-3.2 breakages (including a silently-broken hotfix guard and unbounded precompact-snapshot pileup), removes the retired autorun/parallel machinery for good, and adds a behavioral layer that makes the seeded outcome — not just green gates — the thing that closes a sprint.
Toolkit — the v6.1.2 feature, hardened
- The reported bug.
hooks/scripts/toolkit_surface.shandskills/context/scripts/cmd_toolkit.shshipped in v6.1.2 with git mode100644(non-executable). The SessionStart hook is invoked by path, so it failed withPermission deniedon every new session. Both are now100755. A new regression guard —hooks/tests/test_exec_bits.sh— asserts every path-invoked hook/CLI script carries the executable bit (the smoke harness runs scripts viabash <file>, which is mode-agnostic, so this class slipped past every other test). - CLI ↔ docs reconciliation. The documented
addsyntax was unusable (add <name> --desc=… --globalwhile the CLI required--name=,--description=,--scope=global). The CLI now accepts the ergonomic aliases--global/--local(for--scope=…) and--desc(for--description);commands/toolkit.mdanddoctrines/toolkit.mdare corrected to match. - Doctrine accuracy. Dropped
apifrom the canonical type enum (it is non-canonical → WARN); markedscope+capabilitiesrequired (thevalidatecommand enforces them); reworded the over-promising "pinned never drop" and "add is idempotent" claims to match the code (add refuses duplicates; pinned-first within the cap). - Bounded injection + defensiveness.
shctx toolkit md(the brief-injection surface) now caps at 12 entries, pinned-first, matching the SessionStart hook; interactiveliststays uncapped. Empty-capabilitiesrendering is guarded. Newhooks/tests/test_toolkit_surface.shcovers merge / local-wins / pinned-first / 12-cap / graceful-empty;test_toolkit.shgains alias coverage.
bash 3.2 portability (macOS default /bin/bash)
Three hooks/CLI scripts used bash-4-only constructs that silently broke on the operator's platform:
hotfix_vehicle_guard.sh(#135). Used${SUBAGENT_TYPE,,}(bash-4 lowercase) → "bad substitution" on 3.2, so anH=1hotfix spawned as ashepherd:conductorteammate slipped past the guard. Replaced with portabletr. The guard's primary case now actually enforces —test_hotfix_vehicle_guard.shgoes 9/10 → 10/10.precompact_snapshot.sh. The retention trim usedmapfile(bash 4+); on 3.2 it died underset -u, so snapshots were written but never trimmed — the "so many precompact files" pileup. Replaced with a portable read loop; retention (default 5) now holds.cmd_issues.sh.declare -A(associative arrays) is a fatal "invalid option" on 3.2, breakingshctx issuesoutright. Reworked to safeprintf -v/${!var}indirection (noeval).
These two fixes turn the hooks smoke suite from 33/35 → 37/37 (the two newly-green tests plus the two new toolkit tests).
Precompact snapshots — relocated + meaningful
- Relocated from
<workdir>/snapshots/to<workdir>/memory/snapshots/, co-located with other ephemeral rehydration state. Writer (precompact_snapshot.sh) and reader (focus_rehydrate.sh) move together; a fail-open one-time migration sweeps any snapshots from the legacy location, and the reader falls back to it so an in-flight snapshot taken before the upgrade still rehydrates. - Kept (they are meaningful): snapshots carry the focus digest, graph cursor, trace tail, mailbox, and lock state — the load-bearing compaction-resilience payload. The "noise" perception was the broken retention (above), now fixed.
Outcome enforcement — make the seeded outcome close the sprint
Shepherd ships code and green gates reliably but drifts off the outcome a seed promised. New doctrines/outcome-enforcement.md binds outcome verification to four existing seams, behavioral wiring only — no new schema or state table:
- Seam 1 — SEED: each
seed §6deliverable's acceptance is a runnable predicate (grep+count / structural assertion / LOC floor / log·metric·DB query / health probe), not prose (references/seed-template.md §6-bis). - Seam 2 — PLAN-GATE: the
@criticconfirms every deliverable carries a runnable predicate; a plan that drops one or leaves prose-only fails withPLAN-MISSING-OUTCOME-VERIFICATION(agents/critic.md). - Seam 3 — CLOSE (the enforcement point): the close auditor re-runs every seeded predicate against live HEAD/state before grading; a promised-true predicate that now returns false is an
OUTCOME-REGRESSION(HIGH) that caps the completeness grade (agents/auditor.md,agents/conductor.md §3,references/grading-rubric.md). Reuses the same read-only re-run INTRO already runs on the prior sprint. - Seam 4 — SOAK (optional, post-close): a new SOAK-LOOP template (
references/loop-templates.md, a WATCH-LOOP specialization) re-verifies the predicates on a wall-clock interval (T+1d, T+7d) via native/loop+Monitor, surfacingOUTCOME-REGRESSIONon post-delivery drift. Detection-only; never auto-remediates. Invoke:/shepherd:loop "soak outcomes for <sprint>" --agent worker --interval 1d --max 6.
Retired-command cleanup
Deleted the thin retired-redirect stubs (/shepherd:autorun + /shepherd:parallel, retired since v5.1.4): commands/{autorun,parallel}.md and skills/shepherd/{autorun,parallel,planter}.md. References in CLAUDE.md and SKILL.md are scrubbed; the live --auto / --parallel <N> flags, the [autorun].min_grade config key, and the shepherd-parallel-<slug> teammate-naming prefix are unaffected.
Doctrine + brief fixes (batched issues)
- #61 —
agents/engineer.mdgains a work-shape→vehicle tier-matching table so a conductor/teammate is not allocated for single-file or markdown work. - #100 —
agents/conductor.mdboot adds a hard W0-GATE precondition: no body batch fires until INTRO ground-truth certification has passed (block-and-recheck, never proceed-and-hope). - #120 — the planter (
agents/planter.md,commands/plant.md) now has a fresh-project bootstrap: when.claude/shepherd.tomlis absent it surfacesexamples/minimal/shepherd.tomland stops for operator confirmation. - #123 — reconciled the
-dev.Nseed-filename conflict: intermediate per-sprint seeds may carry-devN; the version-scale-roadmap restriction applies only to final shipped artifacts (doctrines/version-scale-roadmap.md,references/seed-template.md).
Closed as verified-shipped
Verified present + wired and closed: #107 (toolkit registry, v6.1.2), #121 (namespace resolution parity, v6.0.8), #134 (Focus Loop, v6.0.9), #87 (compile telemetry, v6.0.9), #103 (engineer model pin + ENGINEER-MODEL-FAIL, v6.0.3+), #99 (teammate git guard, v6.0.9), #119 (planter discovery wave, v6.0.7+), and #135 (hotfix vehicle guard — fixed and now enforcing, this release).
Test suite — repaired the shctx harness (23/40 → 40/40)
The skills/context/tests suite had 17 pre-existing failures (present on main) — not a sqlite issue (the migrations apply cleanly), but v6.1.2 renames that never reached the test harness:
root.db→shepherd.db:shctx initnow createsshepherd.db, but the harness (_setup.sh) and 22 tests still hardcodedroot.dbin their directsqlite3queries → "no such table" against a fresh empty file. Renamed throughout (leavingtest_workdir.sh's intentional legacy-detection assertions).plans/+reports/→docs/plans/+docs/reports/:test_init/test_lintreferenced the pre-v6.1.2 top-level dirs the scaffold no longer creates.cmd_doctor.shhard-coded the labelroot.dbregardless of the actual file — now reports the realshctx_db_pathbasename (a real cosmetic bug).test_compile_telemetryasserted spaced JSON ("…": 1) against compact output ("…":1).
Both suites now pass clean: hooks 37/37, context 40/40.
v6.1.2
v6.1.2 — 2026-06-11
The self-improvement-substrate release: a persistent tool toolkit so a session never forgets a capability, a standardized + back-compatible workdir layout, per-flock-role loop templates, discovery waves on Dynamic Workflows, and a flock-profile polish pass.
Toolkit — persistent tool memory (operator request)
The flagship of this version. A mutable registry (toolkit.json) of commonly-used tools — MCP servers, skills, plugins, CLIs, ssh targets — so a Claude Code session never forgets a capability exists and the operator never has to re-explain it (e.g. ssh pzzld@laptop for a self-hosted dev surface, the context7 MCP). It is the tool-memory sibling of the adaptation loop's lesson-memory (doctrines/self-improvement.md).
- Two tiers, merged at read time. Project-local
<namespace>/toolkit.json(tracked) ⊕ user-global$XDG_CONFIG_HOME/shepherd/toolkit.json; thescopefield routes each entry, and local overrides global on name collision — so cross-project tools live once, globally. - Entry schema. Required
{ name, scope (local|global), type (mcp|skill|plugin|cli), capabilities[], description }plus optionalinvocation,when,tags,pinned. JSON Schema atskills/context/references/toolkit.schema.json; the validator warns (never fails) on a non-canonicaltypeso ssh/service targets are permitted. - CLI. New
skills/context/scripts/cmd_toolkit.sh(registered inshctx):toolkit list|add|rm|pin|unpin|show|md|init|validate. Lazily creates the file on firstadd;mdemits compact markdown (graceful-empty — nothing on an empty registry, exactly likeshctx adapt priors). - Three surfaces keep it in front of the model. (1) A SessionStart hook
hooks/scripts/toolkit_surface.shinjects a compact, ≤12-entry, pinned-first roster every session (fail-open; suppressed by[hooks].quiet_warnings); (2) theshctx toolkitCLI; (3) a[TOOLKIT]block injected into engineer/coder/planter briefs viacmd_inject.sh(variable-tail, cache-discipline-preserving). - Doctrine + command + examples.
skills/shepherd/doctrines/toolkit.md(bounded / graceful-empty / never-store-secrets),commands/toolkit.md(/shepherd:toolkit),examples/{axiom,minimal}/toolkit.json, and the five tool-using agents (engineer, coder, worker, discovery, planter) gained a one-line toolkit-awareness nudge. Test:skills/context/tests/test_toolkit.sh.
Standardized workdir layout — one consistent tree, totally back-compatible (operator request)
The per-project workdir now follows a standardized internal tree — docs/{plans,reports,diagrams,handoffs,specs,journal}/, logs/, archive/, cache/, scripts/, templates/, tmp/, types/, plus toolkit.json (tracked) and shepherd.db (gitignored). Adopted additively per the #121 "never mass-rename" invariant.
root.db→shepherd.db, with auto-detection.shctx_db_path()prefersshepherd.db, falls back to legacyroot.db, defaults toshepherd.dbfor new projects — mirroring the existing.shepherd/↔.artifacts/resolution. Zero change for legacy trees.plans/+reports/now nest underdocs/.[paths]defaults updated;scaffold.shscaffolds the full tree with.gitkeepfor tracked-but-empty dirs.- Opt-in migration.
shctx migrate --layout v2git mvsplans/→docs/plans/,reports/→docs/reports/, renamesroot.db→shepherd.db, and creates the new dirs — idempotent, no-clobber. *.{group}.{ext}naming, formalized.references/naming-conventions.mddocuments the uniform<slug>.<group>.<ext>rule and adds log patterns{date}.log.md(human) +{ts}.log.jsonl(machine);cmd_lint.shaccepts both the legacy and new locations + log groups..gitignorecoversshepherd.db*under both namespaces and keepstoolkit.jsontracked.
Per-role loop templates — bounded, role-shaped Loop-Until-Done (operator request)
/shepherd:loop (Pattern 6) gains a per-flock-role catalog so the loop primitive is reusable per agent. New skills/shepherd/references/loop-templates.md defines seven templates — CODER-CONVERGENCE (fix-until-green), DISCOVERY-EXHAUST (research-until-comprehensive), WORKER-WATCH / WORKER-CONVERGENCE, AUDITOR-REFINE, ENGINEER-PLAN-REFINE, and the orchestrator's FOCUS-LOOP — each specializing an existing composite, each with a hard --max cap and a measurable terminate-on predicate. New binding doctrine skills/shepherd/doctrines/loop-templates.md; commands/loop.md points operators at the catalog. No new halt codes (reuses the v6.0.9 circuit-breaker set).
Discovery waves compile to Dynamic Workflows (operator request)
All discovery fan-out now compiles like coder/audit fan-out instead of dispatching as inline Agent batches. doctrines/workflow-compile-down.md §V documents INTRO-COMBO-WAVE and DISCOVERY-COMBO-WAVE as compile targets (gate-free, parallel-safe → one Promise.all of discovery + auditor [+ worker] spawns); intro-combo-wave.md and discovery-combo-wave.md adopt the compile framing; pipeline.md gains the missing DISCOVERY-COMBO-WAVE taxonomy row. The compiler cmd_graph.sh was already role-agnostic (spawns_for_node expands any role mix) and verified end-to-end — the change is a clarifying comment plus a fixed latent bug where a node typed dynamic_workflow would not have matched the compiler's literal node-type key.
Spawn flow — per-sprint context certification, teammate Dynamic Workflows, default FOCUS-LOOP (operator request)
Four coordinated /shepherd:spawn fixes so the team substrate behaves as designed:
- Per-sprint context-certification wave. The spawn-flow walkthrough now makes the root's INTRO-COMBO-WAVE explicit (it was mandated in
agents/shepherd.mdbut omitted fromcommands/spawn.md's flow):@discovery× N gather ground-truth, intro-mode@auditor× 2 certify it (regression / carry-forward / freshness) — the sprint's own certifiable current context. Always-on under spawn (every T-shirt) and fresh per sprint — each--scope patch/--autosprint and each--parallelsibling certifies its own; a prior sprint's context is never inherited.intro-combo-wave.mdgains the spawn framing. - Teammate-conductors compile their lane fan-out. The contract required it (
dispatch-cascade.md §IV-bis,conductor.md) but no operational instruction existed, so teammates dispatched in-context. Added the explicitshctx graph compile --segment=<entry> --verify→ run →shctx graph marksequence (in-context fallback only on confirmed runtime failure) to thecommands/spawn.mdteammate boot prompt andagents/conductor.mdStep 2 + hard-prohibition #22; hand-rolled in-context step fan-out is aPRIMITIVE-INVERSIONoff-substrate violation. Reconciled the self-contradictorySKILL.md §X: under spawn, both root and each teammate compile their respective fan-out (mode-agnostic). - Root adopts the FOCUS-LOOP by default on team init. Coordinate mode is reframed as operating the Pattern-6 FOCUS-LOOP (wake → act → probe, opened at SEED-VERIFY), entered the instant teammates spawn — the active engine, not a passive focus-record write backstopped only by
coordinate_drive_guard.sh. The root stays engaged and drives until CLOSE-FINALIZE. - Long-running conductors adopt their own FOCUS-LOOP. A teammate-conductor opens a lane-keyed focus loop at Step 0 (lane start, before any node — so a teammate that skips INTRO still gets one) and runs wake → act → probe over its lane micro-Stage-Graph, refreshing at each wave so a long lane doesn't drift.
All four default-on, config-gatable via the new [focus].loop_default key; doctrine framing in coordinate-active-drive.md.
Flock profile polish
Description-field shrink for the two genuinely bloated meta profiles — conductor (198→157 chars) and shepherd (195→152) — moving mode/tier detail into the body; planter/auditor tightened further. Frontmatter already consistent across all nine (name → color → model → thinking → description → tools); no value changes.
Foundation
- Version moved to 6.1.2 across the six sources of truth (
plugin.json,marketplace.json×2 keys, bothSKILL.mdfrontmatters,README.md, this file). - Removed a stray tracked
err.txtand the dogfood repo's.artifacts/tree reorganized onto the standard layout (plans/+reports/→docs/). - All new bash honors house style —
set -uo pipefail, source_lib.sh || exit 0, exit-0-always hooks,resolve_namespace/resolve_workdir(never hardcoding.artifacts/.shepherd), and graceful-empty reads. New test auto-discovered byskills/context/tests/run.sh.