From 720e0efed2b4b012fa0a8c4dbdbd6ce5ea293495 Mon Sep 17 00:00:00 2001 From: Giovanni Costagliola Date: Fri, 12 Jun 2026 19:02:09 +0200 Subject: [PATCH 1/3] refactor(agentic-harness): extract the coordination protocol from sdd-coordination The two-way handoff (activate, owned segment, hand-back, write-back), auto-invokable vs human-gated activation, and the two rules (one owner per phase/concern, one source of truth per artifact) were SDD-specific prose in sdd-coordination.md, but the protocol is system-agnostic. Extract it into shared/coordination-protocol.md so each process area (spec process, issue tracking, future areas) adds an instance file with its per-system map instead of duplicating protocol prose. sdd-coordination.md is now the SDD instance: a pointer to the protocol plus the per-system coordination map. --- .../shared/coordination-protocol.md | 63 +++++++++++++++++++ agentic-harness/shared/sdd-coordination.md | 56 +++-------------- 2 files changed, 72 insertions(+), 47 deletions(-) create mode 100644 agentic-harness/shared/coordination-protocol.md diff --git a/agentic-harness/shared/coordination-protocol.md b/agentic-harness/shared/coordination-protocol.md new file mode 100644 index 0000000..1ea2680 --- /dev/null +++ b/agentic-harness/shared/coordination-protocol.md @@ -0,0 +1,63 @@ +# Coordination protocol + +When a project has a **process layer** installed — a spec-driven development (SDD) system, an +issue tracker — the harness does not run beside it: the two **work coordinated**. This file +defines the generic protocol every coordination follows; the per-area instance files apply it +to concrete systems: + +- `${CLAUDE_PLUGIN_ROOT}/shared/sdd-coordination.md` — the spec process (SDD systems) +- `${CLAUDE_PLUGIN_ROOT}/shared/tracker-coordination.md` — issue tracking + +A future process area adds an **instance file** with its per-system map; it does not add new +protocol prose here. `harness-setup` reads the protocol and the instance maps at generation +time; the generated orchestrator cannot read these files at runtime, so the relevant values +are **inlined** when the orchestrator is generated. + +A harness is the *who/how/when* of the work — agents, skills, order. A process layer is part of +the *project process* the work follows — what to build, what work is ready and in what state. +They are different layers, so they compose cleanly once the boundary is drawn. Detection of +which system is present is a separate concern: see +`${CLAUDE_PLUGIN_ROOT}/shared/detection-signatures.md`. + +## The coordination model + +A coordinated system owns a **bounded segment or concern** of the workflow — for an SDD system, +usually the spec/plan/decompose front-end; for a tracker, the work state. The orchestrator stays +the driver and coordinates that segment through a **two-way handoff**, the same shape for every +system: + +1. **Activate (hand-in).** At the boundary the system owns, the orchestrator composes a + **contextual prompt** from what it already holds — the goal, the constraints, the context it + has gathered — and activates the system's entry point so it starts cleanly without + re-gathering: + - *Auto-invokable* (a CLI or MCP entry point) → the orchestrator invokes it directly with the + contextual prompt. + - *Human-gated* (an IDE, a SaaS UI, or a workflow with an approval step) → the orchestrator + emits the contextual prompt for the user, **pauses**, and resumes when the user confirms + the step is done. +2. **The system runs its owned segment.** The orchestrator does **not** duplicate it — it never + re-derives requirements an SDD owns, and never keeps a parallel status file beside a tracker. +3. **Hand-back (return).** The system signals completion; its artifacts — a spec, a plan, a task + graph, an issue with its state — are the **contract**. The orchestrator detects completion + (the artifact is present, a flag is set, or the user confirms) and resumes. +4. **The orchestrator resumes its owned segment** — parallel execution, integration, + cross-boundary QA — reading the system's artifacts as its input and **writing status and + decisions back** in the system's own conventions. The final deliverable still goes to the + user's target path. + +### Two rules that keep it clean + +- **One owner per phase, one owner per concern.** Mark each orchestrator phase as either + delegated (`→ {system}`) or orchestrator-owned, and give each concern (requirements, task + decomposition, work state) exactly one owning system. A phase or concern a system owns is not + re-done by an agent, and vice versa. This is what prevents the parallel-and-conflicting flow + the coordination exists to avoid. +- **One source of truth per artifact.** The system's artifacts are **referenced**, never copied + into `_agents_workspace/`. The orchestrator reads them in place and writes status back in + place. Copying a spec or an issue into the workspace creates a second copy that drifts — the + same anti-pattern the `CLAUDE.md` pointer avoids by not duplicating the file system. + +Friction is minimised by the two ends of the handoff: the **contextual prompt** on hand-in means +the system does not re-ask what the orchestrator already knows, and the +**artifact-as-contract** on hand-back means the orchestrator does not re-derive what the system +already settled. diff --git a/agentic-harness/shared/sdd-coordination.md b/agentic-harness/shared/sdd-coordination.md index 420042b..43ec7b4 100644 --- a/agentic-harness/shared/sdd-coordination.md +++ b/agentic-harness/shared/sdd-coordination.md @@ -1,52 +1,14 @@ # SDD coordination -When a project has a spec-driven development (SDD) system installed, the harness does not run -beside it — the two **work coordinated**. This file defines how the generated orchestrator and an -installed SDD system compose: who owns which part of the workflow, how the orchestrator hands work -in, and how it picks the work back up. `harness-setup` reads this to bake the coordination into the -orchestrator it generates; the orchestrator itself cannot read this file at runtime, so the -relevant values are **inlined** at generation time. - -A harness is the *who/how/when* of the work — agents, skills, order. An SDD system is the -*project process* the work follows — requirements, design, decomposition, decision records. They -are different layers, so they compose cleanly once the boundary is drawn. Detection of which -system is present is a separate concern: see `${CLAUDE_PLUGIN_ROOT}/shared/detection-signatures.md`. - -## The coordination model - -An SDD system owns a **bounded segment** of the workflow — usually the spec/plan/decompose -front-end, and for the heavier systems part of the build too. The orchestrator stays the driver -and coordinates that segment through a **two-way handoff**, the same shape for every system: - -1. **Activate (hand-in).** At the phase boundary the SDD owns, the orchestrator composes a - **contextual prompt** from what it already holds — the goal, the constraints, the context it has - gathered — and activates the SDD's entry point so the SDD starts cleanly without re-gathering: - - *Auto-invokable* (a CLI or MCP entry point) → the orchestrator invokes it directly with the - contextual prompt. - - *Human-gated* (an IDE, or a workflow with an approval step) → the orchestrator emits the - contextual prompt for the user, **pauses**, and resumes when the user confirms the step is done. -2. **The SDD runs its owned segment.** The orchestrator does **not** duplicate it — it never - re-derives the requirements or the plan the SDD owns. -3. **Hand-back (return).** The SDD signals completion; its artifacts — the spec, plan, tasks, - approved design, or task graph — are the **contract**. The orchestrator detects completion (the - artifact is present, an approval flag is set, or the user confirms) and resumes. -4. **The orchestrator resumes its owned segment** — parallel execution, integration, cross-boundary - QA — reading the SDD artifacts as its input and **writing status and decisions back** in the - SDD's own conventions. The final deliverable still goes to the user's target path. - -### Two rules that keep it clean - -- **One owner per phase.** Mark each orchestrator phase as either delegated (`→ SDD: {system}`) or - orchestrator-owned. A phase the SDD owns is not re-done by an agent, and vice versa. This is what - prevents the parallel-and-conflicting flow the coordination exists to avoid. -- **One source of truth per artifact.** SDD artifacts are **referenced**, never copied into - `_agents_workspace/`. The orchestrator reads them in place and writes status back in place. Copying - a spec into the workspace creates a second copy that drifts — the same anti-pattern the `CLAUDE.md` - pointer avoids by not duplicating the file system. - -Friction is minimised by the two ends of the handoff: the **contextual prompt** on hand-in means the -SDD does not re-ask what the orchestrator already knows, and the **artifact-as-contract** on -hand-back means the orchestrator does not re-derive what the SDD already settled. +The spec-process instance of the harness coordination protocol. The protocol itself — the +two-way handoff (activate, owned segment, hand-back, write-back), auto-invokable vs human-gated +activation, and the two rules (**one owner per phase**, **one source of truth per artifact**) — +is in `${CLAUDE_PLUGIN_ROOT}/shared/coordination-protocol.md`; read it first. This file applies +it to spec-driven development (SDD) systems: an SDD system owns a **bounded segment** of the +workflow — usually the spec/plan/decompose front-end, and for the heavier systems part of the +build too — and the per-system map below gives the concrete values `harness-setup` inlines into +the generated orchestrator. Detection of which system is present is a separate concern: see +`${CLAUDE_PLUGIN_ROOT}/shared/detection-signatures.md`. ## Per-system coordination map From 11d030c432f88831ac2ff6141d1924ec8c36cbed Mon Sep 17 00:00:00 2001 From: Giovanni Costagliola Date: Fri, 12 Jun 2026 19:02:24 +0200 Subject: [PATCH 2/3] feat(agentic-harness): add tracker-advisor and generalize the process-layers gate (v0.7.0) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit New tracker-advisor skill: detects whether a software project lacks an issue tracker suited to agentic work and, if so, advises a best-fit git-managed option (Beads, Backlog.md, git-bug, git-issues, Beans — or GitHub Issues / Linear / Jira as advise-only SaaS) and delegates setup to that system's own installer. Mirrors spec-advisor: offline-first curated shortlist + decision tree, scan-first stay-out, opt-in online in two narrow forms, never authors issues, writes nothing to CLAUDE.md. All shortlist facts verified against official repos; git-issues and Beans flagged early-stage. harness-setup's Step 0 SDD branch becomes a generic process-layers gate — a table of advisor areas (spec process, issue tracking) with one shared gate algorithm — so a future advisor adds a row, not a new conditional. New shared/tracker-coordination.md (per-tracker command map; the tracker owns the work-state concern), tracker addenda in the orchestrator template (phase 0 pulls ready work or creates the issue; integrate writes status back; never copy issue content into the workspace), an Issue tracking line in the CLAUDE.md pointer, and tracker detection signatures (incl. the git-bug refs/bugs check, the bare-backlog/ and ISSUE_TEMPLATE weak-signal rules, and the Taskmaster spec-derived boundary). Both advisors gain a symmetric installer failure contract: report plainly, record no coordination context, leave a clean retry path, and tell the caller to proceed as if no system is present. --- .claude-plugin/marketplace.json | 6 +- agentic-harness/.claude-plugin/plugin.json | 5 +- agentic-harness/README.md | 7 +- agentic-harness/shared/claude-md-pointer.md | 21 ++- .../shared/detection-signatures.md | 71 +++++++-- .../shared/tracker-coordination.md | 73 +++++++++ agentic-harness/skills/harness-setup/SKILL.md | 91 +++++++---- .../references/orchestrator-template.md | 94 +++++++++-- agentic-harness/skills/spec-advisor/SKILL.md | 17 +- .../spec-advisor/references/spec-systems.md | 2 +- .../skills/tracker-advisor/SKILL.md | 150 ++++++++++++++++++ .../references/tracker-systems.md | 132 +++++++++++++++ 12 files changed, 597 insertions(+), 72 deletions(-) create mode 100644 agentic-harness/shared/tracker-coordination.md create mode 100644 agentic-harness/skills/tracker-advisor/SKILL.md create mode 100644 agentic-harness/skills/tracker-advisor/references/tracker-systems.md diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json index 2397820..5e115ec 100644 --- a/.claude-plugin/marketplace.json +++ b/.claude-plugin/marketplace.json @@ -13,10 +13,10 @@ { "name": "agentic-harness", "source": "./agentic-harness", - "description": "Stand up, assess, and maintain an agentic harness in an existing repo — generate project-specific agent teams and the skills they use, then assess how effectively they are used", - "version": "0.5.0", + "description": "Stand up, assess, and maintain an agentic harness in an existing repo — generate project-specific agent teams and the skills they use, assess how effectively they are used, and advise on spec-driven development systems and agent-suited issue trackers", + "version": "0.7.0", "category": "engineering", - "tags": ["harness", "agents", "skills", "scaffolding", "orchestration", "multi-agent", "meta-skill"] + "tags": ["harness", "agents", "skills", "scaffolding", "orchestration", "multi-agent", "meta-skill", "issue-tracker", "spec-driven-development"] }, { "name": "developer-tools", diff --git a/agentic-harness/.claude-plugin/plugin.json b/agentic-harness/.claude-plugin/plugin.json index b53e9a5..e2769d6 100644 --- a/agentic-harness/.claude-plugin/plugin.json +++ b/agentic-harness/.claude-plugin/plugin.json @@ -1,7 +1,7 @@ { "name": "agentic-harness", - "version": "0.6.0", - "description": "Stand up, assess, and maintain an agentic harness in an existing repo. A meta-tool that generates project-specific agent teams and the skills they use, then assesses how effectively they are used. When a spec-driven development system is present, the generated orchestrator coordinates with it — activating the spec workflow and resuming on hand-back. Three skills: harness-setup (build, extend, maintain), harness-review (read-only assessment), and spec-advisor (advise and delegate setup of a spec-driven development system).", + "version": "0.7.0", + "description": "Stand up, assess, and maintain an agentic harness in an existing repo. A meta-tool that generates project-specific agent teams and the skills they use, then assesses how effectively they are used. When a spec-driven development system or an issue tracker is present, the generated orchestrator coordinates with it — activating the spec workflow and resuming on hand-back, pulling ready work and writing status back. Four skills: harness-setup (build, extend, maintain), harness-review (read-only assessment), spec-advisor (advise and delegate setup of a spec-driven development system), and tracker-advisor (advise and delegate setup of an agent-suited issue tracker).", "author": { "name": "MrBogomips", "url": "https://github.com/MrBogomips" @@ -18,6 +18,7 @@ "scaffolding", "agent-scaffolding", "multi-agent", + "issue-tracker", "claude-code-plugin" ] } diff --git a/agentic-harness/README.md b/agentic-harness/README.md index 4bce3a1..d5a80d4 100644 --- a/agentic-harness/README.md +++ b/agentic-harness/README.md @@ -4,15 +4,16 @@ Stand up, assess, and maintain an **agentic harness** inside an existing reposit This plugin does not do your domain work. It builds and maintains the agents and skills that do. -## The three skills +## The four skills - **`harness-setup`** — the writer. Analyzes the project, designs an agent team and the skills they use, generates them into `.claude/`, builds an orchestrator, and registers a pointer in `CLAUDE.md` that makes the orchestrator the repo's entry point — a hard gate routing every prompt through it. Also extends an existing harness, applies a review context, and records every change. - **`harness-review`** — read-only. Inventories the harness, detects drift, and assesses how effectively the skills and agents are actually used (from project memory, the `CLAUDE.md` pointer, and the `.claude/` inventory), then produces a prioritized *review context* that `harness-setup` can act on. - **`spec-advisor`** — detects whether a software project lacks a spec-driven development system and, if so, advises the best-fit option (GitHub Spec Kit, OpenSpec, BMAD-METHOD, Agent OS, Taskmaster, AWS Kiro, ADR tooling) and delegates setup to that system's own installer. Offline-first; scans first and stays out if a system is already present; never authors specs itself. +- **`tracker-advisor`** — detects whether a software project lacks an issue tracker suited to agentic work and, if so, advises the best-fit option (Beads, Backlog.md, git-bug, git-issues, Beans, or GitHub Issues / Linear / Jira via their official access paths) and delegates setup to that system's own installer. Same posture as `spec-advisor`: offline-first, scans first and stays out, never authors issues. -When a project **already has** a spec system, `harness-setup` makes the generated orchestrator coordinate with it rather than run beside it: the orchestrator activates the spec workflow with a contextual prompt, the spec system runs its owned segment, and the orchestrator resumes on a clean hand-back — one owner per phase, no duplicated artifacts. The detection signatures and the per-system coordination map are shared knowledge under `shared/` (`detection-signatures.md`, `sdd-coordination.md`). +When a project **already has** a spec system or an issue tracker, `harness-setup` makes the generated orchestrator coordinate with it rather than run beside it: the orchestrator activates the spec workflow with a contextual prompt and resumes on a clean hand-back, and it pulls ready work from the tracker at intake and writes status back at integrate — one owner per phase and per concern, no duplicated artifacts. The detection signatures, the coordination protocol, and the per-system coordination maps are shared knowledge under `shared/` (`detection-signatures.md`, `coordination-protocol.md`, `sdd-coordination.md`, `tracker-coordination.md`). -The harness loop: **review → setup → review again.** `spec-advisor` is offered alongside it when a software project has no spec system yet. +The harness loop: **review → setup → review again.** The advisors are offered alongside it when a software project lacks the matching process layer. Keeping a repo-native tracker in sync with a human-oriented one (Jira, Linear) is planned for a future release. ## Skills, not commands diff --git a/agentic-harness/shared/claude-md-pointer.md b/agentic-harness/shared/claude-md-pointer.md index a5d8a96..3dd308e 100644 --- a/agentic-harness/shared/claude-md-pointer.md +++ b/agentic-harness/shared/claude-md-pointer.md @@ -8,7 +8,8 @@ wrong place for anything the file system already holds. After a harness is built or changed, write (or update) one short section in the target project's `CLAUDE.md`. It carries three things — plus, when the project has an installed -spec-driven development (SDD) system, one line recording how the orchestrator coordinates with it: +process layer (an SDD system, an issue tracker), one line per layer recording how the +orchestrator coordinates with it: 1. The harness's **goal**, in one line. 2. The **entry-point directive** — a hard gate making the orchestrator skill the single entry @@ -16,6 +17,8 @@ spec-driven development (SDD) system, one line recording how the orchestrator co 3. A **change-history** table. 4. *(only when an SDD system is present)* a **spec-process** line — which system, and the segment the orchestrator hands to it. +5. *(only when an issue tracker is present)* an **issue-tracking** line — which tracker, and how + the orchestrator pulls ready work and writes status back. This is enough for a fresh session: the entry-point directive gates every prompt to the orchestrator, and the orchestrator triages and handles the rest from the files under `.claude/`. @@ -32,6 +35,9 @@ instruction layer, so it does not depend on the skill description triggering on **Spec process:** {system} ({version}) — orchestrator activates it for {owned segment}; hand-back via {contract}. *(omit this line entirely when no SDD system is present)* +**Issue tracking:** {tracker} ({version}) — orchestrator pulls ready work via {ready-work query}; +status written back via {write-back convention}. *(omit this line entirely when no tracker is present)* + **Entry point — applies to every prompt in this repo:** You MUST invoke the `{orchestrator-skill-name}` skill *before* responding to any request — new work, a follow-up, a re-run, a question, or a change to a previous result. It is the single entry point; do not craft a @@ -50,9 +56,12 @@ orchestrator's first phase, so a trivial or off-domain prompt still routes throu and is answered quickly there. This keeps the orchestrator the reliable entry point without spinning up a team for every message. -The spec-process line records the **coordination relationship**, not the spec contents — the -requirements, plan, and tasks stay in the SDD system's own files. The full coordination model is in -`${CLAUDE_PLUGIN_ROOT}/shared/sdd-coordination.md`. +The spec-process and issue-tracking lines record the **coordination relationship**, not the +contents — the requirements, plan, and tasks stay in the SDD system's own files, and the issues +stay in the tracker's own store. The coordination protocol is in +`${CLAUDE_PLUGIN_ROOT}/shared/coordination-protocol.md`, with the per-area instances in +`${CLAUDE_PLUGIN_ROOT}/shared/sdd-coordination.md` and +`${CLAUDE_PLUGIN_ROOT}/shared/tracker-coordination.md`. ### When the repo has more than one harness @@ -60,7 +69,7 @@ Write the hard-gate sentence **once**, as a shared routing preamble above the pe "Before responding to any request, invoke the orchestrator whose domain matches it; if none matches, answer directly" — and keep each `## Harness: {domain}` section to its goal, an **Orchestrator:** `{orchestrator-skill-name}` line (so the preamble can resolve domain → orchestrator), its -spec-process line, and change history. Do not repeat "invoke *this* orchestrator before any prompt" +spec-process and issue-tracking lines, and change history. Do not repeat "invoke *this* orchestrator before any prompt" in every section: N such directives contradict each other. One preamble routes by domain; each section just names the orchestrator it routes to. @@ -75,6 +84,8 @@ Leave these out of `CLAUDE.md`: - Detailed execution rules — they belong in the skills and the orchestrator. - The spec contents — the spec-process line names the system and the coordinated segment only; the requirements/plan/tasks live in the SDD system's own files, the single source of truth. +- The issue contents — the issue-tracking line names the tracker and the touchpoints only; the + issues live in the tracker's own store, the single source of truth for work state. The pointer is a signpost, not a manifest. Keep it small enough that it stays correct. diff --git a/agentic-harness/shared/detection-signatures.md b/agentic-harness/shared/detection-signatures.md index 2c4ee60..ad54e45 100644 --- a/agentic-harness/shared/detection-signatures.md +++ b/agentic-harness/shared/detection-signatures.md @@ -1,25 +1,30 @@ # Detection signatures -The scan-first knowledge behind flow Step 1. This is a curated **reference of facts**, not a -set of recommendations: it tells you how to recognise a spec system or an ADR registry that is -already present, so the skill can report it and stay out. A generic search cannot reliably -re-derive these signatures each run — the on-disk layouts drift in load-bearing ways (BMAD -changed its directories between v4 and v6) and several systems share filenames — so they live -here as knowledge. +The scan-first knowledge behind flow Step 1 of `spec-advisor` and `tracker-advisor` (and behind +`harness-setup`'s process-layers gate). This is a curated **reference of facts**, not a set of +recommendations: it tells you how to recognise a spec system, an ADR registry, or an issue +tracker that is already present, so the skill can report it and stay out. A generic search +cannot reliably re-derive these signatures each run — the on-disk layouts drift in load-bearing +ways (BMAD changed its directories between v4 and v6) and several systems share filenames — so +they live here as knowledge. ## How to scan -Look for the signature paths below at the repository root and one or two levels in. A hit means -a spec system or decision-record registry **already exists**. When you find one: +Look for the signature paths below at the repository root and one or two levels in. One +signature is **not a path**: git-bug stores issues as git objects under the `refs/bugs/` +namespace, so check it with `git for-each-ref refs/bugs` (read-only) — a filesystem scan will +silently miss it. A hit means a system of that area **already exists**. When you find one: -- Report **what** is present and **where** (the matched path), then **stop**. -- Do not push a second system on top of one that is already in use. The skill is advisory and - detection-first: an existing process is the user's decision, and stacking a second SDD system - on top of it creates exactly the duplication the skill is built to avoid. +- Report **what** is present and **where** (the matched path or ref), then **stop** for that + area. +- Do not push a second system on top of one that is already in use. The skills are advisory and + detection-first: an existing process is the user's decision, and stacking a second system on + top of it creates exactly the duplication the skills are built to avoid. -This is a read-only report — the scan itself writes nothing. +This is a read-only report — the scan itself writes nothing. Each advisor scans its own area's +table; `harness-setup` scans both. -## Path → system table +## Spec systems and ADR registries — path → system table | Signature path(s) | System | Notes | |---|---|---| @@ -33,9 +38,21 @@ This is a read-only report — the scan itself writes nothing. | `.kiro/specs//{requirements,design,tasks}.md`, `.kiro/steering/` | AWS Kiro (IDE) | EARS-style `requirements.md`. Kiro is an **IDE**, not a repo install — see the Kiro caveat in `spec-systems.md`. | | `docs/adr/`, `doc/adr/`, `.adr-dir`, `.log4brains.yml` | ADR tooling | A *decision-record* registry, not a full spec process. `.log4brains.yml` ⇒ log4brains specifically; `.adr-dir` / `docs/adr/` ⇒ adr-tools-style. | +## Issue trackers — path → system table + +| Signature path(s) | Tracker | Notes | +|---|---|---| +| `.beads/` (holds an embedded Dolt db and/or `issues.jsonl`) | Beads (`bd`) | Graph-based, git-synced issue db built for coding agents. | +| `backlog/` or `.backlog/` containing `config.yml` | Backlog.md | Markdown task manager. A bare `backlog/` directory **without** the config is ambiguous — see rule 4. | +| `.issues/` with YAML-frontmatter markdown files | git-issues | Minimal single-binary tracker; may also leave a generated `.agent.md`. | +| `.beans/` with `.beans.yml` | Beans | Flat-file markdown tracker with a GraphQL query CLI. | +| `refs/bugs/` ref namespace (`git for-each-ref refs/bugs`) | git-bug | Issues live as **git objects**, not files — the filesystem shows nothing. | +| `.github/ISSUE_TEMPLATE/` | GitHub Issues (weak signal) | Usage signal only — see rule 5; never conclude on it silently. | +| `.taskmaster/` | Taskmaster | **Spec-derived** task decomposition, not a general tracker — see rule 6. | + ## Disambiguation rules -Three cases need a rule because the raw signal is ambiguous. +Six cases need a rule because the raw signal is ambiguous. ### 1. The shared `requirements.md + design.md + tasks.md` triple — resolve by parent directory @@ -67,3 +84,27 @@ tooling and distinguish the tool: `.log4brains.yml` ⇒ log4brains; a plain `doc `.adr-dir` pointer ⇒ adr-tools-style. A project can hold ADRs *and* still lack a spec system — if only ADR signals are present, say so plainly, since the user may legitimately want to add a spec process alongside their existing decision records (offer it; do not assume it). + +### 4. A bare `backlog/` directory is not Backlog.md + +`backlog/` is an ordinary word that projects use for their own notes. Only the directory +**containing Backlog.md's `config.yml`** identifies the tool. A bare `backlog/` without the +config is genuinely ambiguous: report exactly what was found and ask, rather than concluding a +tracker is present. + +### 5. `.github/ISSUE_TEMPLATE/` is a weak signal — report and ask + +Issue templates show that GitHub Issues *has been configured at some point*, not that it is the +project's active tracker — many repos carry vestigial templates. Report "GitHub Issues appears +to be in use" and **ask** whether it is the active tracker. If yes, a tracker is present (it is +agent-reachable via `gh`) — stay out. If no, continue as if no tracker were found. Never treat +the templates alone as a silent stay-out, and never ignore them silently either. + +### 6. Taskmaster appears in both tables — it is spec-derived, not a general tracker + +`.taskmaster/` decomposes and tracks tasks **derived from a spec or PRD**; it pairs with a spec +system rather than serving general issue intake. `spec-advisor` treats it as an SDD pairing +(its own table row above). `tracker-advisor` reports it — "spec-derived task tracking is +covered by Taskmaster" — and stays out unless the user explicitly asks for a general issue +tracker alongside it. When both Taskmaster and a general tracker exist, work state needs one +owner per item — see `${CLAUDE_PLUGIN_ROOT}/shared/tracker-coordination.md`. diff --git a/agentic-harness/shared/tracker-coordination.md b/agentic-harness/shared/tracker-coordination.md new file mode 100644 index 0000000..0993696 --- /dev/null +++ b/agentic-harness/shared/tracker-coordination.md @@ -0,0 +1,73 @@ +# Tracker coordination + +The issue-tracking instance of the harness coordination protocol. The protocol itself — the +two-way handoff, auto-invokable vs human-gated activation, and the two rules (**one owner per +phase/concern**, **one source of truth per artifact**) — is in +`${CLAUDE_PLUGIN_ROOT}/shared/coordination-protocol.md`; read it first. This file applies it to +issue trackers: a tracker owns the **work-state concern** — what work exists, what is ready, +and what state each item is in — and the per-tracker map below gives the concrete values +`harness-setup` inlines into the generated orchestrator. Detection of which tracker is present +is a separate concern: see `${CLAUDE_PLUGIN_ROOT}/shared/detection-signatures.md`. + +## The tracker coordination model + +Unlike an SDD system, a tracker does not own a phase of the workflow — it owns a concern that +**brackets** the workflow. The orchestrator touches it at two points: + +1. **Phase 0 (intake & triage) — pull or create.** Once triage routes a request in as in-domain + work: if a matching ready item exists (`{READY_QUERY}`), claim it and carry its ID through + the run; if the work is new, create the issue (`{CREATE_CMD}`) so the tracker owns the work + state from the start. For a human-gated tracker (a SaaS UI with no configured CLI/MCP + access), emit the contextual prompt and **pause** per the protocol. +2. **Integrate / finish — write status back.** When the deliverable is written, update the + issue (`{STATUS_WRITEBACK}`) — close it or transition its state, referencing the + deliverable's path. Never delete issues and never rewrite human-authored issue prose — the + tracker owns intent and history, the harness owns execution. + +Between those two points the issue is **referenced, not copied**: agents carry the issue ID in +workspace artifact headers and read the issue in place. The orchestrator keeps no parallel +status file — work state has exactly one owner. + +## Per-tracker coordination map + +`harness-setup` looks up the detected tracker's row and inlines these concrete values into the +orchestrator. Commands are the curated baseline; confirm against the tracker's own docs if a +flag fails. + +| Tracker | Ready-work query | Create | Status write-back | Auto-invokable? | +|---|---|---|---|---| +| **Beads (`bd`)** | `bd ready --json` | `bd create "title"` | claim with `bd update {id} --claim`; close with `bd close {id} "summary"` | yes (CLI) | +| **Backlog.md** | `backlog task list` (CLI or its MCP server) | `backlog task create` | `backlog task edit` status transition | yes (CLI / MCP) | +| **git-issues** | `issues next` | author a new `.issues/` entry per its conventions | `issues claim {id}` → `issues done {id}` | yes (CLI) | +| **Beans** | `beans list` or a GraphQL query | `beans create` | `beans update` / `beans archive` | yes (CLI) | +| **git-bug** | `git bug ls` | `git bug add` | update state / comment via the `git bug` CLI | yes (CLI) | +| **GitHub Issues** | `gh issue list --json number,title,state,labels` | `gh issue create` | `gh issue close` / `gh issue comment` | yes (`gh`, authenticated) | +| **Linear** | its official MCP server (mcp.linear.app) | MCP create-issue tool | MCP update/comment tools | yes when the MCP server is configured; otherwise human-gated | +| **Jira** | the Atlassian MCP server (mcp.atlassian.com) | MCP create tool | MCP transition/comment tools | yes when the MCP server is configured; otherwise human-gated | + +For Linear and Jira without a configured MCP server, every touch is human-gated: emit the +contextual prompt (what to file or update, with the values to enter), pause, and resume on the +user's confirmation. Do not scrape or guess at SaaS state. + +### Taskmaster boundary — one owner for work state + +Taskmaster (`.taskmaster/`) tracks **spec-derived task state**, not general issue intake; it +belongs to the spec process (see `${CLAUDE_PLUGIN_ROOT}/shared/sdd-coordination.md`). When +Taskmaster co-exists with a general tracker, keep one owner per item: work decomposed from a +spec routes its status through `.taskmaster/tasks/tasks.json`; bugs and general work intake +route through the tracker. Never mirror the same item's state in both. + +## How `harness-setup` uses this + +1. After detecting the present tracker (Step 0), look up its row above and capture the + **coordination context**: `{tracker, version, entry point, ready-work query, create + convention, status write-back, auto-invokable}`. +2. With the user, settle which phases touch the tracker (phase 0 pull/create, integrate + write-back) and whether access is auto-invokable or human-gated (Step 2). Fold the decision + into the change manifest. +3. Splice the **Tracker coordination addenda** from `harness-setup`'s + `references/orchestrator-template.md` into the chosen template (A / B / C), substituting the + concrete values from the coordination context (Step 5). The generated orchestrator must be + self-contained — inline the commands; do not leave it pointing at this file. +4. Record the relationship in the `CLAUDE.md` pointer's **Issue tracking** line — see + `${CLAUDE_PLUGIN_ROOT}/shared/claude-md-pointer.md`. diff --git a/agentic-harness/skills/harness-setup/SKILL.md b/agentic-harness/skills/harness-setup/SKILL.md index 594a81a..fafe832 100644 --- a/agentic-harness/skills/harness-setup/SKILL.md +++ b/agentic-harness/skills/harness-setup/SKILL.md @@ -1,6 +1,6 @@ --- name: harness-setup -description: "Build, extend, and maintain a project's agentic harness — the agents, skills, and orchestrator under .claude/. This skill writes files. Use it to set up, scaffold, extend, rebuild, or sync a harness, to add or change an agent or skill, or to apply a review context from harness-review; on request it also discovers and registers fitting MCP/plugin tools. For read-only assessment of an existing harness, use harness-review — this skill is the writer, that one is the reader. Not for authoring a single standalone skill or plugin (use plugin-dev or skill-creator), or one-shot automation recommendations (use claude-code-setup). Not for choosing a project's spec-driven development system — use spec-advisor." +description: "Build, extend, and maintain a project's agentic harness — the agents, skills, and orchestrator under .claude/. This skill writes files. Use it to set up, scaffold, extend, rebuild, or sync a harness, to add or change an agent or skill, or to apply a review context from harness-review; on request it also discovers and registers fitting MCP/plugin tools. For read-only assessment of an existing harness, use harness-review — this skill is the writer, that one is the reader. Not for authoring a single standalone skill or plugin (use plugin-dev or skill-creator), or one-shot automation recommendations (use claude-code-setup). Not for choosing a project's spec-driven development system or issue tracker — use spec-advisor or tracker-advisor." model: inherit --- @@ -49,22 +49,36 @@ plan is confirmed. Record the answers. Asking is the default; a "no" is a fine answer, but a silent skip is not. Running happens only on a yes — see Step 1b. This confirms the approach; the concrete list of files and tools is approved separately at Step 2b, before anything is written. -5. **Account for the project's spec process.** A harness is the *who/how/when* of the work; a - spec-driven development (SDD) system is the *project process* the work follows. They are - complementary, so check which case applies — scan with +5. **Account for the project's process layers.** A harness is the *who/how/when* of the work; a + project may also follow *process layers* — a spec process (what to build) and an issue + tracker (what work is ready and in what state). They are complementary to the harness, so + check each advisor area — scan with `${CLAUDE_PLUGIN_ROOT}/shared/detection-signatures.md`: - - **No SDD system, project looks like software** → offer to run the `spec-advisor` skill, which - advises which SDD system fits and delegates setup to that system's own installer. Offering is - the default; running is gated on a yes, and nothing is installed without `spec-advisor`'s own - per-system approval. If the user installs one, fold its coordination into the plan below. - - **An SDD system is present** → do not re-recommend and do not install. Identify the system and - version, look up its row in `${CLAUDE_PLUGIN_ROOT}/shared/sdd-coordination.md`, and record a - **coordination context** — `{system, version, owned-segment, activation, auto-invokable, - hand-back contract, write-back rule}` — to carry into Step 2 and Step 5. This is the lightweight - read `harness-setup` needs to bake the coordination into the orchestrator; `spec-advisor` still - owns recommending and installing. - Record the answer either way. + | Process area | Advisor skill | Coordination map | + |---|---|---| + | Spec process (SDD) | `spec-advisor` | `${CLAUDE_PLUGIN_ROOT}/shared/sdd-coordination.md` | + | Issue tracking | `tracker-advisor` | `${CLAUDE_PLUGIN_ROOT}/shared/tracker-coordination.md` | + + The same gate applies to every area: + - **No system, project looks like software** → offer to run the area's advisor skill, which + advises what fits and delegates setup to the chosen system's own installer. Offering is the + default; running is gated on a yes, and nothing is installed without the advisor's own + per-system approval. If the user installs one, fold its coordination into the plan below. + **If the advisor reports an installer failure, treat the area as having no system** — record + no coordination context; the advisor leaves the retry path with the user. + - **A system is present** (detected, or just installed) → do not re-recommend and do not + install. Identify the system and version, look up its row in the area's coordination map, + and record a **coordination context** — for SDD `{system, version, owned-segment, + activation, auto-invokable, hand-back contract, write-back rule}`; for a tracker + `{tracker, version, entry point, ready-work query, create convention, status write-back, + auto-invokable}` — to carry into Step 2 and Step 5. This is the lightweight read + `harness-setup` needs to bake the coordination into the orchestrator; the advisor skills + still own recommending and installing. The protocol behind every map is + `${CLAUDE_PLUGIN_ROOT}/shared/coordination-protocol.md`. + + Record the answer for each area either way. A future advisor adds a row to the table; the + gate itself does not change. ## Step 1: Analyze the domain @@ -122,15 +136,23 @@ covers them. criteria table is in `references/agent-design-patterns.md`. Prefer a few focused agents over many thin ones; coordination cost grows with team size. -**Coordinate with the spec process.** If Step 0 recorded a coordination context (an SDD system is -present), decide *with the user* how the orchestrator and the SDD compose — they must work together -without overlap and with minimal friction, not run in parallel. Using -`${CLAUDE_PLUGIN_ROOT}/shared/sdd-coordination.md`, settle: which phases the orchestrator **delegates** -to the SDD (the spec/plan/decompose segment it owns) versus **owns** (typically execution, -integration, and a cross-boundary QA pass); and whether activation is **auto-invokable** (the -orchestrator calls the SDD's CLI/MCP entry point with a contextual prompt) or **human-gated** (it -emits the prompt and pauses for the user, as with an IDE or an approval step). Fold the decision into -the Step 2b manifest so it is approved before any write. +**Coordinate with the process layers.** If Step 0 recorded a coordination context, decide *with +the user* how the orchestrator and each present system compose — they must work together without +overlap and with minimal friction, not run in parallel. + +- **Spec process (SDD).** Using `${CLAUDE_PLUGIN_ROOT}/shared/sdd-coordination.md`, settle: which + phases the orchestrator **delegates** to the SDD (the spec/plan/decompose segment it owns) versus + **owns** (typically execution, integration, and a cross-boundary QA pass); and whether activation + is **auto-invokable** (the orchestrator calls the SDD's CLI/MCP entry point with a contextual + prompt) or **human-gated** (it emits the prompt and pauses for the user, as with an IDE or an + approval step). +- **Issue tracker.** Using `${CLAUDE_PLUGIN_ROOT}/shared/tracker-coordination.md`, settle: which + phases touch the tracker (phase 0 pulls ready work or creates the issue; integrate writes status + back); whether access is **auto-invokable** (CLI / configured MCP) or **human-gated** (a SaaS UI + with no configured access); and the **one-status-owner rule** when Taskmaster or an SDD task + artifact co-exists with the tracker — each item's work state has exactly one owning system. + +Fold the decisions into the Step 2b manifest so they are approved before any write. ## Step 2b: Approve the change manifest — required before any write @@ -232,12 +254,17 @@ Build into the orchestrator: - **The tools registry**, when tool discovery (Step 1b) has run: it lives in this orchestrator's `references/` directory as `tools.md`, and agents and skills reference tools by role from it. -- **SDD coordination**, when Step 0 recorded a coordination context: splice the addenda from +- **SDD coordination**, when Step 0 recorded an SDD coordination context: splice the addenda from `references/orchestrator-template.md` (SDD coordination section) into the orchestrator's phase 0, prepare, and integrate phases, **inlining the system's concrete artifact paths and entry point** — the orchestrator cannot read the shared file at runtime. Mark each phase as delegated (`→ SDD: {system}`) or orchestrator-owned. The model is in `${CLAUDE_PLUGIN_ROOT}/shared/sdd-coordination.md`. +- **Tracker coordination**, when Step 0 recorded a tracker coordination context: splice the + addenda from `references/orchestrator-template.md` (Tracker coordination section) into the + orchestrator's phase 0 and integrate phases, **inlining the tracker's concrete commands** (the + ready-work query, the create command, the status write-back). The model is in + `${CLAUDE_PLUGIN_ROOT}/shared/tracker-coordination.md`. When extending rather than building new, modify the existing orchestrator — do not create a second one. Reflect a new agent in the team composition, task assignment, data flow, and @@ -288,8 +315,11 @@ Before calling a setup or change complete: - [ ] If an SDD system is present: the orchestrator activates it via a contextual prompt and resumes on hand-back, every phase has exactly one owner, and no SDD artifact is copied into `_agents_workspace/`. +- [ ] If a tracker is present: phase 0 pulls ready work or creates the issue, integrate writes + status back, each item's work state has exactly one owner, and no issue content is copied + into `_agents_workspace/`. - [ ] The `CLAUDE.md` pointer is registered (goal + entry-point directive (hard gate) + change - history; plus the spec-process line when an SDD system is present). + history; plus the spec-process and issue-tracking lines when those systems are present). - [ ] The change-history table records this change. - [ ] The user was asked whether to run tool research (and, on an existing harness, tool maintenance), and the answer was recorded — whatever they chose. @@ -313,6 +343,9 @@ Before calling a setup or change complete: - `${CLAUDE_PLUGIN_ROOT}/shared/harness-model.md`, `${CLAUDE_PLUGIN_ROOT}/shared/execution-modes.md`, `${CLAUDE_PLUGIN_ROOT}/shared/claude-md-pointer.md` — shared concepts. -- `${CLAUDE_PLUGIN_ROOT}/shared/detection-signatures.md` — how to recognise an installed SDD system - (shared with `spec-advisor`); `${CLAUDE_PLUGIN_ROOT}/shared/sdd-coordination.md` — the - orchestrator↔SDD coordination model and the per-system coordination map. +- `${CLAUDE_PLUGIN_ROOT}/shared/detection-signatures.md` — how to recognise an installed SDD + system or issue tracker (shared with `spec-advisor` and `tracker-advisor`); + `${CLAUDE_PLUGIN_ROOT}/shared/coordination-protocol.md` — the generic coordination protocol; + `${CLAUDE_PLUGIN_ROOT}/shared/sdd-coordination.md` and + `${CLAUDE_PLUGIN_ROOT}/shared/tracker-coordination.md` — the per-area instances with their + per-system coordination maps. diff --git a/agentic-harness/skills/harness-setup/references/orchestrator-template.md b/agentic-harness/skills/harness-setup/references/orchestrator-template.md index ac209b5..db1c2c7 100644 --- a/agentic-harness/skills/harness-setup/references/orchestrator-template.md +++ b/agentic-harness/skills/harness-setup/references/orchestrator-template.md @@ -12,6 +12,7 @@ state the mode per phase. - [Template B — subagent (fallback / lightweight)](#template-b--subagent-fallback--lightweight) - [Template C — hybrid](#template-c--hybrid) - [SDD coordination](#sdd-coordination) + - [Tracker coordination](#tracker-coordination) - [Authoring rules](#authoring-rules) - [Follow-up keywords](#follow-up-keywords) @@ -22,9 +23,10 @@ state the mode per phase. The first choice when two or more agents need to talk while they work. Build the team with `TeamCreate`; coordinate over a shared task list and `SendMessage`. -> If the project has an installed SDD system, also splice in the [SDD coordination](#sdd-coordination) -> addenda (phase 0, prepare, integrate) so the orchestrator hands work to the spec process and -> resumes on hand-back. +> If the project has an installed SDD system and/or issue tracker, also splice in the matching +> [SDD coordination](#sdd-coordination) addenda (phase 0, prepare, integrate) and/or +> [Tracker coordination](#tracker-coordination) addenda (phase 0, work, integrate), so the +> orchestrator hands work to the spec process and keeps the tracker as the work-state owner. ````markdown --- @@ -118,8 +120,8 @@ nudges or reassigns a stuck member, and checks state with `TaskGet`. When team communication is unnecessary, or the team tools are unavailable. Spawn each agent with the `Agent` tool and collect return values. -> If the project has an installed SDD system, also splice in the [SDD coordination](#sdd-coordination) -> addenda (phase 0, prepare, integrate). +> If the project has an installed SDD system and/or issue tracker, also splice in the matching +> [SDD coordination](#sdd-coordination) and/or [Tracker coordination](#tracker-coordination) addenda. ````markdown --- @@ -171,9 +173,10 @@ Keep `_agents_workspace/`; report a summary. A different mode per phase. State `**Execution mode:** {team | subagent}` at the top of each phase. -> If the project has an installed SDD system, the [SDD coordination](#sdd-coordination) addenda -> attach to whichever phases own the context check, the prepare step, and the integrate step — -> regardless of each phase's execution mode. +> If the project has an installed SDD system and/or issue tracker, the +> [SDD coordination](#sdd-coordination) and/or [Tracker coordination](#tracker-coordination) +> addenda attach to whichever phases own the context check, the prepare step, and the integrate +> step — regardless of each phase's execution mode. ````markdown --- @@ -292,6 +295,75 @@ task loop), and have the orchestrator own only what the SDD does not: typically integration, and a cross-boundary QA pass over the SDD's output. When Taskmaster pairs with a spec system, anchor requirements to the spec and route **task status** through `.taskmaster/tasks/tasks.json`. +## Tracker coordination + +Use this when the project has an installed issue tracker. The model — the tracker as the +**work-state owner**, the phase-0 pull-or-create, the write-back, and the per-tracker command map — +is in `${CLAUDE_PLUGIN_ROOT}/shared/tracker-coordination.md`. This section turns it into three +**addenda** you splice into whichever template you picked (A / B / C). The generated orchestrator +cannot read that shared file at runtime, so **inline the concrete values** from the detected +tracker's coordination row: `{tracker}`, `{READY_QUERY}` (its ready-work query), `{CREATE_CMD}` +(its create command), `{STATUS_WRITEBACK}` (its close/transition convention), and auto-invokable or +human-gated access. + +Unlike an SDD system, a tracker does not own a phase — it owns the work-state **concern** that +brackets the run. Reference issues by ID; never copy issue content into `_agents_workspace/`, and +keep no parallel status file beside the tracker. + +### Addendum T1 — phase 0 (context check): pull ready work, or create the issue +Add to the context-check step of phase 0 (intake & triage), reached only after triage routes the +request in as in-{domain} work: + +``` +- Check the tracker for a matching ready item: run `{READY_QUERY}`. If one matches this request, + claim it and carry its ID through the run. +- If the work is new, create the issue first (`{CREATE_CMD}`), so {tracker} owns the work state + from the start — then proceed with its ID. +- Human-gated access (no CLI/MCP configured): emit a contextual prompt stating what to file or + look up, and **pause** until the user confirms. +``` + +### Addendum T2 — work: reference the issue, do not copy it +Add to the prepare/work phases: + +``` +- Carry the issue ID in the headers of workspace artifacts (`issue: {tracker-id}`); read the + issue in place when context is needed. +- Do not copy issue content into `_agents_workspace/`, and keep no status file of your own — + {tracker} is the single owner of work state. +``` + +### Addendum T3 — integrate / finish: write status back in {tracker}'s conventions +Add to the integrate (team) or finish (subagent) phase: + +``` +- The final deliverable goes to the user's target path as usual. +- Write status back: {STATUS_WRITEBACK}, referencing the deliverable's path. Never delete issues + and never rewrite human-authored issue prose — the tracker owns intent and history, the + harness owns execution. +``` + +### Worked snippet — Beads (auto-invokable) +- **READY_QUERY:** `bd ready --json` · **CREATE_CMD:** `bd create "title"` · + **STATUS_WRITEBACK:** `bd update {id} --claim` on start, `bd close {id} "summary"` on completion + +``` +### Phase 0: intake & triage +... triage (trivial/off-domain → answer and stop); then the context-check branch ... +- Run `bd ready --json`; if an item matches this request, claim it (`bd update {id} --claim`) + and carry the ID. If the work is new, `bd create "title"` first. +### Phase 4: integrate +- Write the deliverable; `bd close {id} "done — see {deliverable path}"`. +``` + +### Composing with an SDD system +When both an SDD system and a tracker are present, the SDD addenda own *what to build* (spec, +plan, decomposition) and the tracker addenda own *work state* (ready, in progress, done) — splice +both, and give each item's status exactly one owner. When Taskmaster is present, spec-derived +tasks route their status through `.taskmaster/tasks/tasks.json`, general issues through the +tracker — never mirror one item's state in both (see the Taskmaster boundary in +`${CLAUDE_PLUGIN_ROOT}/shared/tracker-coordination.md`). + ## Authoring rules 1. State the execution mode at the top. For hybrid, a per-phase mode table is required. @@ -303,8 +375,10 @@ system, anchor requirements to the spec and route **task status** through `.task call out the transition points. 6. Make error handling realistic — do not assume everything succeeds. 7. Include at least one normal and one error test scenario. -8. When an SDD system is present, splice in the [SDD coordination](#sdd-coordination) addenda with - the system's concrete values inlined, and mark each phase as delegated or orchestrator-owned. +8. When an SDD system and/or issue tracker is present, splice in the matching + [SDD coordination](#sdd-coordination) / [Tracker coordination](#tracker-coordination) addenda + with the system's concrete values inlined; mark each phase as delegated or orchestrator-owned, + and give each item's work state exactly one owner. ## Follow-up keywords diff --git a/agentic-harness/skills/spec-advisor/SKILL.md b/agentic-harness/skills/spec-advisor/SKILL.md index 73d57ef..3b9cb34 100644 --- a/agentic-harness/skills/spec-advisor/SKILL.md +++ b/agentic-harness/skills/spec-advisor/SKILL.md @@ -1,6 +1,6 @@ --- name: spec-advisor -description: "Detect whether a software project lacks a spec-driven development system and, if so, advise which one fits (GitHub Spec Kit, OpenSpec, BMAD-METHOD, Agent OS, Taskmaster, AWS Kiro, ADR tooling) and delegate setup to that system's own installer. Use when setting up a project's spec or planning process, when asked which spec system or SDD framework a project should use, when adopting spec-driven development, or when harness-setup detects a software project with no spec system. Scans first for any existing spec or ADR registry and stays out if one is present. Does NOT author specs itself (the installed system owns that), does NOT build the .claude/ agent harness (that is harness-setup), and does NOT create Claude Code components (that is plugin-dev or skill-creator)." +description: "Detect whether a software project lacks a spec-driven development system and, if so, advise which one fits (GitHub Spec Kit, OpenSpec, BMAD-METHOD, Agent OS, Taskmaster, AWS Kiro, ADR tooling) and delegate setup to that system's own installer. Use when setting up a project's spec or planning process, when asked which spec system or SDD framework a project should use, when adopting spec-driven development, or when harness-setup detects a software project with no spec system. Scans first for any existing spec or ADR registry and stays out if one is present. Does NOT author specs itself (the installed system owns that), does NOT build the .claude/ agent harness (that is harness-setup), does NOT create Claude Code components (that is plugin-dev or skill-creator), and does NOT choose an issue or bug tracker (that is tracker-advisor)." model: inherit --- @@ -24,6 +24,7 @@ This skill does **not**: | Does NOT | Use instead | |---|---| | Author specs, PRDs, or ADRs | the **installed system** — it owns its workflow | +| Choose or set up an issue tracker | **tracker-advisor** | | Build the `.claude/` agent harness (agents, skills, orchestrator) | **harness-setup** | | Assess how well a harness is used | **harness-review** | | Create Claude Code components (skills, agents, plugins) | **plugin-dev / skill-creator** | @@ -114,9 +115,17 @@ the user at the official source (kiro.dev), and stop. Do not run an installer or - **Detection ambiguity** — resolve the shared `requirements/design/tasks` triple by parent directory first (per `${CLAUDE_PLUGIN_ROOT}/shared/detection-signatures.md`); if still ambiguous, report exactly what was found and ask, rather than guessing the system. -- **Installer failure** — report the failure and point the user at the system's official - troubleshooting source. Do not partially hand-roll the setup; a half-installed system is worse - than a clean failure the user can retry. +- **Installer failure** — apply the failure contract: + 1. **Report plainly** — the command run, the error, and the system's official troubleshooting + source. Do not partially hand-roll the setup; a half-installed system is worse than a clean + failure the user can retry. + 2. **Record nothing** — a failed install leaves no coordination context; the project still + counts as having no spec system. + 3. **Leave a clean retry path** — name any artifacts the failed installer left behind so the + user can remove them and retry; do not delete them without the user's say-so. + 4. **Tell the caller** — when invoked from `harness-setup`, state the outcome explicitly: + "install failed — proceed as if no system is present," so nothing downstream assumes the + system exists. - **User declines at any gate** — stop cleanly. The skill is advisory; an off-ramp taken is a valid outcome, not a failure. diff --git a/agentic-harness/skills/spec-advisor/references/spec-systems.md b/agentic-harness/skills/spec-advisor/references/spec-systems.md index 5339034..31e3995 100644 --- a/agentic-harness/skills/spec-advisor/references/spec-systems.md +++ b/agentic-harness/skills/spec-advisor/references/spec-systems.md @@ -58,7 +58,7 @@ skill's. - **Philosophy / stages:** parse a PRD into a task graph, then track and expand tasks. - **Claude Code affinity:** high — built for agent task execution; MCP option integrates directly. - **Maturity:** active and popular. -- **Best-fit:** task decomposition and tracking. It **pairs** with a spec system rather than replacing one — recommend it *alongside* a spec tool when the need is breaking an existing spec into trackable work. +- **Best-fit:** task decomposition and tracking. It **pairs** with a spec system rather than replacing one — recommend it *alongside* a spec tool when the need is breaking an existing spec into trackable work. For general issue/bug intake (not spec-derived tasks), the tracker shortlist is `tracker-advisor`'s concern. ### spec-workflow-mcp - **Official repo:** github.com/Pimzino/spec-workflow-mcp diff --git a/agentic-harness/skills/tracker-advisor/SKILL.md b/agentic-harness/skills/tracker-advisor/SKILL.md new file mode 100644 index 0000000..de2c9d7 --- /dev/null +++ b/agentic-harness/skills/tracker-advisor/SKILL.md @@ -0,0 +1,150 @@ +--- +name: tracker-advisor +description: "Detect whether a software project lacks an issue tracker suited to agentic work and, if so, advise which one fits (Beads, Backlog.md, git-bug, git-issues, Beans, or GitHub Issues, Linear, Jira via their official access paths) and delegate setup to that system's own installer. Use when choosing or setting up a project's issue, bug, or work tracker, when asked how agents should pull ready work or record work state, or when harness-setup detects a software project with no tracker. Scans first and stays out if a tracker is already present. Does NOT author, triage, or groom issues (the installed tracker owns that), does NOT choose a spec system or spec-derived task decomposition such as Taskmaster (that is spec-advisor), does NOT build the .claude/ agent harness (that is harness-setup), and does NOT sync two trackers with each other." +model: inherit +--- + +# Tracker advisor — choose and set up an agent-suited issue tracker + +When a software project has no issue tracker that agents can work — no place to pull ready work +from or write work state back to — this skill helps the user **choose** a fitting one and +**delegates setup to that system's own installer**. It never authors, triages, or grooms issues — +the installed tracker owns its workflow. The skill advises; it writes nothing of its own except +by running the chosen system's installer, and only after explicit approval. + +It is offline-first. Everything needed to scan, recommend, and name an install command is in the +curated reference and the shared detection signatures; the network is reached only with the +user's say-so (see the online policy in `references/tracker-systems.md`). + +## What this skill is not — and which skill to use instead + +The "no duplication" boundary is the point of this skill, so it is worth stating as hard limits. +This skill does **not**: + +| Does NOT | Use instead | +|---|---| +| Author, triage, or groom issues | the **installed tracker** — it owns its workflow | +| Choose a spec system, or spec-derived task decomposition (Taskmaster) | **spec-advisor** | +| Build the `.claude/` agent harness (agents, skills, orchestrator) | **harness-setup** | +| Assess how well a harness is used | **harness-review** | +| Create Claude Code components (skills, agents, plugins) | **plugin-dev / skill-creator** | +| Keep two trackers in sync (repo-native ⇄ Jira/Linear) | a planned future capability of this plugin — name it and stop | +| Push a tracker when one is already present | nothing — the scan reports and stops | +| Write to `CLAUDE.md` | nothing — the chosen system's on-disk artifacts are self-evident | + +A tracker is a *project process*, not a role-tool that agents call ad hoc — so, like a spec +system, it is kept out of the harness `tools.md` registry. If the request is to build or change +the agent harness, that is `harness-setup`; if it is to assess one, that is `harness-review`. +This skill is only about choosing and standing up the project's issue-tracking process. + +## The flow + +Run these in order. Each gate is an off-ramp: the skill is advisory, not coercive, so a "no" +anywhere ends the run cleanly. + +### Step 0 — Scope check: is this a software project? + +These trackers are built for software work. Confirm the project is software before going +further — look for a manifest or source: `package.json`, `pyproject.toml`, `go.mod`, +`Cargo.toml`, `pom.xml`, a `*.csproj`, `Gemfile`, and the like. If the project is not software +(docs, content, data, ops config with no codebase), explain briefly that an agent-oriented issue +tracker is not the right tool and **stop**. + +### Step 1 — Scan first: is a tracker already present? + +Using `${CLAUDE_PLUGIN_ROOT}/shared/detection-signatures.md` (the issue-trackers table), scan +for any existing tracker. **If one is found, report what is present and where, then stop.** Do +not push a second tracker on top of one already in use — stacking trackers splits the work +state, exactly the duplication this skill exists to avoid. This is a read-only report; the scan +writes nothing. Three signals need their rules from that reference before concluding: + +- **git-bug is not a path** — check `git for-each-ref refs/bugs` (rule: issue trackers table). +- **`.github/ISSUE_TEMPLATE/` is a weak signal** — report "GitHub Issues appears to be in use" + and **ask** whether it is the active tracker; if yes, stop (it is agent-reachable via `gh`); + if no, continue (rule 5). +- **Taskmaster is spec-derived, not a general tracker** — report that spec-derived task + tracking is covered, and continue only if the user explicitly wants a general issue tracker + alongside it (rule 6). + +### Step 2 — Opt-in gate: offer a recommendation + +If no tracker is found, offer to recommend one. This is the opt-in gate: a "no" ends the run +cleanly. Offering is the default; nothing past this point happens without the user's yes. + +### Step 3 — Profile for fit + +A good recommendation depends on how the work runs, so gather a few quick signals — by asking, +or by inferring from what Step 0 already saw: + +- **Single agent or concurrent agents** — concurrent work needs collision-safe IDs and a + ready-work queue (Beads's home ground); a single agent tolerates anything. +- **Dependency-graph need** — does work block other work in ways agents must query, or is a + flat list enough? +- **Human surface** — do humans want a kanban/board view (Backlog.md), or is the CLI enough? +- **Existing SaaS commitment** — a team already living in GitHub Issues, Linear, or Jira points + at the advise-only profiles, not a new tool. +- **Git-purist vs MCP appetite** — issues as git objects (git-bug) vs markdown files vs an MCP + surface. + +### Step 4 — Recommend (offline) + +From the curated shortlist and the **selection decision tree** in +`references/tracker-systems.md`, present **2–3 best-fit candidates** with rationale — not a +single verdict. Flag the early-stage entries (git-issues, Beans) as such. Before finalizing, +**offer** the opt-in discovery search (a broad "is there anything newer than the shortlist?" web +search); run it **only on an explicit yes**, and if it stalls or the environment is offline, +fall back silently to the curated data. Then the **user picks one explicitly**. Do not choose on +their behalf. + +### Step 5 — Delegate setup + +For the selected system: + +1. **Optionally fetch current setup details** from that system's **official repository** (the + URL in its profile) — install command and docs. This is the authoritative fetch (online form + b), a precise pull from the canonical source, not a broad search. Skip it offline and use the + curated install command. For the early-stage entries it is strongly recommended. +2. **Present the install command and get explicit approval before executing it.** An install is + an exec-and-write — it changes the user's repo and environment — so it is gated exactly like + harness-setup's change manifest. State the command, what it will create, and where. +3. **Run or guide the system's own installer.** Then **confirm what was created and where**. +4. **Never author issues.** Once the tracker is installed, its own workflow takes over. The + skill's job ends at a working, confirmed install. + +**SaaS special case — GitHub Issues, Linear, Jira.** These are services, not repo packages, so +they are **detect-and-advise only**: explain the option, name the official access path (`gh`; +the vendor MCP servers), and stop — configuring credentials is the user's call. For Linear and +Jira, note that keeping a repo-native tracker in sync with them is a planned future capability +of this plugin. The SaaS/MCP caveat in `references/tracker-systems.md` has the detail. + +## Error handling and graceful degradation + +- **Offline, or a search stalls** — fall back to the curated data; never block on the network. + The offline path is complete on its own. +- **Detection ambiguity** — apply the disambiguation rules in + `${CLAUDE_PLUGIN_ROOT}/shared/detection-signatures.md` (bare `backlog/`, the ISSUE_TEMPLATE + weak signal, Taskmaster); if still ambiguous, report exactly what was found and ask, rather + than guessing the system. +- **Installer failure** — apply the failure contract: + 1. **Report plainly** — the command run, the error, and the system's official troubleshooting + source. Do not partially hand-roll the setup; a half-installed system is worse than a clean + failure the user can retry. + 2. **Record nothing** — a failed install leaves no coordination context; the project still + counts as having no tracker. + 3. **Leave a clean retry path** — name any artifacts the failed installer left behind so the + user can remove them and retry; do not delete them without the user's say-so. + 4. **Tell the caller** — when invoked from `harness-setup`, state the outcome explicitly: + "install failed — proceed as if no system is present," so nothing downstream assumes the + tracker exists. +- **User declines at any gate** — stop cleanly. The skill is advisory; an off-ramp taken is a + valid outcome, not a failure. + +## References + +- `${CLAUDE_PLUGIN_ROOT}/shared/detection-signatures.md` — the scan-first knowledge: the + issue-trackers path→system table (plus the git-bug ref check) and the disambiguation rules + (bare `backlog/`, ISSUE_TEMPLATE weak signal, Taskmaster boundary). Shared with + `spec-advisor` and `harness-setup`. +- `references/tracker-systems.md` — the per-system profiles (official repo/docs URL, install + command, philosophy, agent affinity, maturity, best-fit), the selection decision tree, the + SaaS/MCP caveat, and the online policy. diff --git a/agentic-harness/skills/tracker-advisor/references/tracker-systems.md b/agentic-harness/skills/tracker-advisor/references/tracker-systems.md new file mode 100644 index 0000000..eb8cfc0 --- /dev/null +++ b/agentic-harness/skills/tracker-advisor/references/tracker-systems.md @@ -0,0 +1,132 @@ +# Issue trackers — curated profiles + +The recommend-and-delegate knowledge behind flow Steps 4 and 5. One profile per tracker in the +curated shortlist, then the selection decision tree, the SaaS/MCP caveat, and the online policy. + +These are the facts the skill reasons over offline. Treat install commands and URLs as +load-bearing: when a tracker is **selected** (not before), the official-repo fetch in flow Step 5 +is what confirms the current command — these values are the offline baseline and the source of +the URL to fetch. + +For how a generated orchestrator coordinates with each of these trackers once it is installed +(the phase-0 ready-work pull, the status write-back, and the per-tracker command map), see +`${CLAUDE_PLUGIN_ROOT}/shared/tracker-coordination.md` — that is `harness-setup`'s concern, not +this skill's. + +## Per-system profiles + +### Beads (`bd`) +- **Official repo:** github.com/steveyegge/beads +- **Install (into repo):** `brew install beads` or `npm install -g @beads/bd`, then `bd` init in the repo. `bd setup claude` wires the Claude Code integration. +- **On-disk artifacts:** `.beads/` (embedded Dolt database plus a git-synced `issues.jsonl` export) +- **Philosophy:** a graph-based, git-backed issue database built as working memory for coding agents — dependency types (blocks, parent/child, related, discovered-from), `bd ready --json` for unblocked work, hash-based IDs that survive concurrent branches. +- **Agent affinity:** highest of the shortlist — ready-work queries, atomic claim, multi-agent-safe IDs, JSON everywhere. +- **Maturity:** v1.x, actively maintained; license GPL-3.0. +- **Best-fit:** multi-agent concurrency, dependency-heavy work, high-volume task creation. + +### Backlog.md +- **Official repo:** github.com/MrLesk/Backlog.md +- **Install (into repo):** `npm i -g backlog.md` (or `bun add -g backlog.md`, `brew install backlog-md`), then `backlog init` +- **On-disk artifacts:** `backlog/` (or `.backlog/`) containing `config.yml` and markdown task files +- **Philosophy:** markdown-native tasks in git — one diffable file per task — with a CLI (`backlog task create/edit/list`), a terminal/web kanban board, and a bundled MCP server (`backlog mcp start`). +- **Agent affinity:** high — first-class MCP support and a clean CLI; tasks stay human-readable. +- **Maturity:** actively maintained, frequent releases; license MIT. +- **Best-fit:** solo devs or small teams who want a human-browsable kanban over plain markdown, with agents working the same files. + +### git-bug +- **Official repo:** github.com/git-bug/git-bug +- **Install (into repo):** install the binary (releases or package manager); issues then live in the repo itself — no init scaffolding in the working tree. +- **On-disk artifacts:** none in the working tree — issues are **git objects** under the `refs/bugs/` namespace (detect with `git for-each-ref refs/bugs`). +- **Philosophy:** distributed, offline-first bug tracking embedded in git, with CLI/TUI/web interfaces and bridges to GitHub and GitLab. +- **Agent affinity:** medium — solid CLI (`git bug add`, `git bug ls`), but no ready-work/dependency model and the object storage is less directly inspectable than files. +- **Maturity:** long-lived project, maintained at a slower cadence; license GPL-3.0. +- **Best-fit:** pure-git purists who want issues to travel with clones and bridge to a forge. + +### git-issues — early-stage +- **Official repo:** github.com/git-issues/git-issues +- **Install (into repo):** single Go binary; issues live as YAML-frontmatter markdown in `.issues/` +- **Philosophy:** the minimal agent loop — `issues next` → `issues claim` → `issues done` — plus a TUI board for humans and a generated `.agent.md` context file. +- **Agent affinity:** high in design (the next/claim/done verbs are agent-shaped), small in surface. +- **Maturity:** **young — no formal releases yet.** Confirm current state at the official repo before recommending; present it as an early-stage option, not an established one. License LGPL-2.1. +- **Best-fit:** minimal-footprint projects that want exactly the claim/done loop and nothing else. + +### Beans — early-stage +- **Official repo:** github.com/hmans/beans +- **Install (into repo):** `brew install hmans/beans/beans` or `go install github.com/hmans/beans@latest`, then `beans init` +- **On-disk artifacts:** `.beans/` with `.beans.yml` +- **Philosophy:** flat-file markdown issues with a built-in GraphQL query engine, so agents pull exactly the fields they need; archived issues double as project memory. +- **Agent affinity:** high in design — token-efficient structured queries over plain files. +- **Maturity:** **v0.x, under heavy development — APIs may change.** Present as early-stage. License Apache-2.0. +- **Best-fit:** small projects that value token-efficient structured queries over ecosystem maturity. + +### GitHub Issues — SaaS, advise only +- **Official source:** github.com (CLI: cli.github.com) +- **Install:** **none into the repo.** If the project is hosted on GitHub, the tracker already exists; agent access is `gh issue list --json …`, `gh issue create`, `gh issue close`, `gh issue comment` (authenticated `gh`). +- **Philosophy:** the forge's native tracker — deep PR/commit context, team-visible, zero extra tooling. +- **Agent affinity:** good via `gh` JSON output; no dependency graph or ready-work model. +- **Best-fit:** GitHub-hosted teams who want one tracker humans and agents share, with no new tool. + +### Linear — SaaS via MCP, advise only +- **Official source:** linear.app (MCP server: mcp.linear.app, vendor-provided) +- **Install:** **none into the repo.** Agent access is the official MCP server: `claude mcp add --transport http linear-server https://mcp.linear.app/mcp`, then authenticate via `/mcp`. +- **Philosophy:** a modern human-oriented tracker; the MCP server exposes issue search/create/update to agents. +- **Agent affinity:** good when the MCP server is configured; cloud-dependent, not git-managed. +- **Best-fit:** teams already running on Linear. A repo-native tracker can still be added for agent-side work — keeping the two in sync is a planned future capability of this plugin, not this skill. + +### Jira — SaaS via MCP, advise only +- **Official source:** atlassian.com (MCP: the Atlassian remote MCP server at mcp.atlassian.com, vendor-provided) +- **Install:** **none into the repo.** Agent access is the official Atlassian MCP server (added via `mcp-remote` to `https://mcp.atlassian.com/v1/sse`), OAuth-scoped to the user's own permissions. +- **Philosophy:** the enterprise standard — rich custom workflows, heavyweight for small teams. +- **Agent affinity:** workable via MCP; workflows are per-project custom, so agents must read them, not assume them. +- **Best-fit:** organizations already committed to Jira. As with Linear, dual-tracker sync with a repo-native tracker is a planned future capability of this plugin. + +### Taskmaster — boundary note, not a profile +Taskmaster (`.taskmaster/`) is **spec-derived task decomposition** — it parses a PRD into a task +graph and tracks those tasks. It belongs to the spec process and sits in `spec-advisor`'s +shortlist, not this one. If the need is "break the spec into trackable work," route to +`spec-advisor`; if Taskmaster is already present, see disambiguation rule 6 in +`${CLAUDE_PLUGIN_ROOT}/shared/detection-signatures.md`. + +## Selection decision tree + +Walk this top-down with the profile gathered in flow Step 3; the first match that fits wins, and +present 2–3 candidates with rationale rather than a single verdict. + +1. **Already committed to GitHub Issues / Linear / Jira as the team's tracker?** → that SaaS + profile — **advise only** (see caveat); for Linear/Jira mention the planned dual-tracker sync + path. +2. **Multiple agents working concurrently, or dependency-graph needs?** → Beads. +3. **Want a human-browsable kanban over plain markdown files?** → Backlog.md. +4. **Want issues as pure git objects that travel with clones, with forge bridges?** → git-bug. +5. **Want the most minimal claim/done loop, comfortable with early-stage tools?** → git-issues + or Beans (flag both as early-stage). +6. **Only need spec-derived task decomposition?** → that is Taskmaster — route to + `spec-advisor`. + +## SaaS / MCP caveat + +GitHub Issues, Linear, and Jira are **services**, not repository packages. A Claude Code skill +cannot install a SaaS into a repo, and scaffolding fake local state for one would be worse than +doing nothing. So for these the skill is **detect-and-advise only**: explain the option, point at +the official access path (`gh` for GitHub; the vendor MCP servers for Linear and Jira), and stop. +Configuring an MCP server is the user's call under their own credentials — name the official +command, do not run authentication flows for them. The same rule applies to any future SaaS +option: if setup means "sign into a service," advise, do not install. + +## Online policy + +The default is **fully offline** — everything above is enough to scan, profile, recommend, and +name an install command without touching the network. Online access is never automatic and takes +exactly two narrow forms: + +- **(a) Discovery search** — a broad "is there anything new, or a newer option than the shortlist?" + web search. **Offer** it before finalizing a recommendation; run it **only on an explicit yes**. + If it stalls or the environment is offline, fall back silently to the curated data above. +- **(b) Authoritative fetch** — once the user **selects** a system, fetch its current setup details + (install command, docs) from **that system's official repository** — the URL in its profile + above — not a broad search. This is a precise fetch from the canonical source, the lean way to + confirm the command is current before you ask for approval to run it. For the early-stage + entries (git-issues, Beans) this fetch is **strongly recommended**, since young tools change + fast. + +Neither form runs on its own. The offline path is complete; online is opt-in and additive. From 49042079901eb22b7864866335b88eaa255132c1 Mon Sep 17 00:00:00 2001 From: Giovanni Costagliola Date: Fri, 12 Jun 2026 19:02:24 +0200 Subject: [PATCH 3/3] test(ci): assert plugin and marketplace versions stay in sync The agentic-harness 0.4.0 and 0.6.0 releases bumped plugin.json without marketplace.json (stuck at 0.5.0 until this branch) and nothing caught it. validate-versions.sh compares every plugin.json version against its marketplace.json entry and flags marketplace entries with no plugin directory; registered as the fourth structural suite. --- tests/README.md | 1 + tests/ci/run-structural-tests.sh | 1 + tests/validate-versions.sh | 102 +++++++++++++++++++++++++++++++ 3 files changed, 104 insertions(+) create mode 100755 tests/validate-versions.sh diff --git a/tests/README.md b/tests/README.md index 3a8712a..b53d984 100644 --- a/tests/README.md +++ b/tests/README.md @@ -15,6 +15,7 @@ Runs on every push/PR to `main`. Requires `jq`. | `validate-plugin.sh` | plugin.json, SKILL.md/AGENT.md frontmatter, marketplace.json | | `validate-connectors.sh` | `~~placeholder` references match CONNECTORS.md entries | | `validate-references.sh` | `references/` paths in SKILL.md resolve to existing files | +| `validate-versions.sh` | every plugin.json version matches its marketplace.json entry; no orphan entries | ## Layer 2: Skill Scenarios (manual) diff --git a/tests/ci/run-structural-tests.sh b/tests/ci/run-structural-tests.sh index 580d7cb..e837a65 100755 --- a/tests/ci/run-structural-tests.sh +++ b/tests/ci/run-structural-tests.sh @@ -27,6 +27,7 @@ run_test() { run_test "$TESTS_DIR/validate-plugin.sh" "Plugin Structure" run_test "$TESTS_DIR/validate-connectors.sh" "Connector References" run_test "$TESTS_DIR/validate-references.sh" "Reference Paths" +run_test "$TESTS_DIR/validate-versions.sh" "Version Sync" echo "" echo "================================================" diff --git a/tests/validate-versions.sh b/tests/validate-versions.sh new file mode 100755 index 0000000..3427672 --- /dev/null +++ b/tests/validate-versions.sh @@ -0,0 +1,102 @@ +#!/usr/bin/env bash +# Layer 1: Plugin/marketplace version sync validation +# Checks that every plugin's plugin.json version matches its marketplace.json entry, +# and that every marketplace entry corresponds to an existing plugin directory. +set -euo pipefail + +REPO_ROOT="$(cd "$(dirname "$0")/.." && pwd)" +MANIFEST="$REPO_ROOT/.claude-plugin/marketplace.json" +ERRORS=0 +WARNINGS=0 + +red() { printf '\033[0;31m%s\033[0m\n' "$*"; } +yellow() { printf '\033[0;33m%s\033[0m\n' "$*"; } +green() { printf '\033[0;32m%s\033[0m\n' "$*"; } + +error() { red "ERROR: $*"; ERRORS=$((ERRORS + 1)); } +warn() { yellow "WARN: $*"; WARNINGS=$((WARNINGS + 1)); } +ok() { green "OK: $*"; } + +if ! command -v jq >/dev/null 2>&1; then + error "jq is required but not installed" + red "FAILED: $ERRORS error(s)" + exit 1 +fi + +if [[ ! -f "$MANIFEST" ]]; then + error "marketplace manifest not found at $MANIFEST" + red "FAILED: $ERRORS error(s)" + exit 1 +fi + +if ! jq empty "$MANIFEST" 2>/dev/null; then + error "marketplace.json is not valid JSON" + red "FAILED: $ERRORS error(s)" + exit 1 +fi + +# Forward pass: every plugin dir's plugin.json version must match its marketplace entry. +# Track seen plugin names in a space-separated string (bash 3.2 compatible — no associative arrays). +seen_names="" +for plugin_dir in "$REPO_ROOT"/*/; do + plugin_json="$plugin_dir/.claude-plugin/plugin.json" + [[ -f "$plugin_json" ]] || continue + + if ! jq empty "$plugin_json" 2>/dev/null; then + error "$(basename "$plugin_dir"): plugin.json is not valid JSON" + continue + fi + + name="$(jq -r '.name // empty' "$plugin_json")" + pver="$(jq -r '.version // empty' "$plugin_json")" + + if [[ -z "$name" ]]; then + error "$(basename "$plugin_dir"): plugin.json has no name" + continue + fi + seen_names="$seen_names $name" + + if [[ -z "$pver" ]]; then + error "$name: plugin.json has no version" + continue + fi + + mver="$(jq -r --arg n "$name" '.plugins[] | select(.name == $n) | .version // empty' "$MANIFEST")" + + if [[ -z "$mver" ]]; then + error "$name: no marketplace.json entry with a version (plugin.json says $pver)" + elif [[ "$pver" != "$mver" ]]; then + error "$name: version drift — plugin.json=$pver, marketplace.json=$mver" + else + ok "$name: version $pver in sync" + fi +done + +# Reverse pass: every marketplace entry must correspond to an existing plugin directory. +while IFS= read -r entry_name; do + [[ -z "$entry_name" ]] && continue + found=false + for seen in $seen_names; do + if [[ "$seen" == "$entry_name" ]]; then + found=true + break + fi + done + if [[ "$found" == "false" ]]; then + error "marketplace.json entry '$entry_name' has no matching plugin directory" + fi +done < <(jq -r '.plugins[].name' "$MANIFEST") + +# Summary +echo "" +echo "============================" +if [[ $ERRORS -gt 0 ]]; then + red "FAILED: $ERRORS error(s), $WARNINGS warning(s)" + exit 1 +elif [[ $WARNINGS -gt 0 ]]; then + yellow "PASSED with $WARNINGS warning(s)" + exit 0 +else + green "PASSED: all plugin versions in sync with marketplace.json" + exit 0 +fi