一键导入
tracker-publish
Publish approved Claude Harness dependency groups to Linear/Jira-compatible tracker tasks and write the local tracker mapping contract.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Publish approved Claude Harness dependency groups to Linear/Jira-compatible tracker tasks and write the local tracker mapping contract.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Discover and map an existing codebase before planning or changing it.
Change the behavior of existing code — story-driven by default, or --issue N for a GitHub bug fix. Test-first, full verification, code review.
Use when a planned change touches persisted data shape — ORM models, migration files, schema definitions, serialized formats, or message contracts — in /change, /refactor, or /implement on an existing codebase. Routes schema changes through expand-contract and proves reversibility before any deploy.
Generate production code and tests for a story group using agent teams for parallel execution.
Refactor existing code for quality, performance, or maintainability. Enforces core quality principles with ratchet gate.
Generate test plan, test cases, test data fixtures, and Playwright E2E tests mapped to acceptance criteria.
| name | tracker-publish |
| description | Publish approved Claude Harness dependency groups to Linear/Jira-compatible tracker tasks and write the local tracker mapping contract. |
| argument-hint | [--provider linear|jira] [--granularity group|story] [--dry-run] |
| context | fork |
Publish approved story groups to an external tracker. This skill prepares the handoff contract used by the standalone orchestrator; it does not start the orchestrator.
This optional add-on mirrors approved Claude Harness story groups into an external tracker (Linear/Jira), then lets a standalone orchestrator schedule unblocked groups and launch Claude Code in isolated workspaces. The default scaffold remains local-only — use tracker orchestration only when a project wants Linear/Jira to act as the visible work queue and human review surface.
Claude Harness stays the source of truth for planning and verification (/brd → /spec → /design → /auto --group <id>). The tracker is only a control plane: issue status gates whether a group may run, blocker links mirror the local dependency graph, and comments hold proof/PR links. Human review and final merge stay outside the autonomous loop. The orchestrator is external — it polls the tracker, claims eligible unblocked group issues, creates one workspace per group, launches claude --print, reads .claude/state/tracker-runs/<group>/result.json, updates the tracker, and leaves completed work in Human Review.
Recommended tracker states: Published/Todo (created, not eligible) → Ready for Agent (eligible when blockers are terminal/pass) → In Progress (claimed) → Human Review (branch/PR/proof ready) → Done (after human merge). Plus Blocked, Canceled/Cancelled/Duplicate as terminal states.
Safety rules:
Done automatically./auto creates the internal agent teams).Related files: .claude/templates/tracker-config.template.json, .claude/templates/tracker-workflow.template.md, .claude/state/tracker-map.json, .claude/state/tracker-runs/, and the symphony_clone/ orchestrator.
The --granularity flag chooses what becomes a tracker issue:
| Mode | Issue maps to | When to use |
|---|---|---|
group (default) | One tracker issue per dependency group from dependency-graph.md. The group issue body lists every ready story in that group, and the harness command is /auto --group <id> (or whatever HARNESS_COMMAND_TEMPLATE resolves to). | Default for /build projects and any work where a group is reviewed as a single PR. The agent team inside /auto handles per-story decomposition. |
story | One tracker issue per ready story. Each story issue carries Story: E1-S1 plus its group ID. Group-level blockers are mirrored as blocked_by links between story issues. The orchestrator runs each story individually via the per-issue mode override (default mode-vibe for trivial stories; the publisher writes mode-lite or mode-vibe based on story metadata). | When the human reviewer wants one PR per story (smaller diffs, faster review cycle), when stories are independently shippable, or when you want different Claude commands per story (for example, mode-vibe for a docs story, /auto for an API story). |
Picking the right granularity matters more than people think:
group granularity is cheaper to orchestrate (fewer issues, fewer PRs, fewer Linear comments) and lets /auto exploit intra-group parallelism via agent teams. It produces large PRs that need careful human review.story granularity gives you small PRs but loses the intra-group parallelism gain — each story runs as its own orchestrator workspace and the orchestrator pays per-issue overhead (clone, branch, tracker round-trips). On a Max-licence-only setup, this can be slower wall-clock for the same total work.If you do not specify --granularity, default to group. Switch to story only if the human explicitly asks for per-story PRs.
The following files must exist and be approved by the human:
specs/stories/epics.mdspecs/stories/dependency-graph.mdspecs/stories/E*-S*.mdfeatures.jsonspecs/design/component-map.mdspecs/design/api-contracts.md.claude/tracker-config.jsonIf design artifacts are missing, stop and ask the human to run /design first. The orchestrator needs component-map.md so /auto can coordinate agent teams without file ownership conflicts.
Write or update:
.claude/state/tracker-map.json
.claude/state/tracker-runs/
tracker-map.json shape (group granularity):
{
"provider": "linear",
"granularity": "group",
"published_at": "2026-05-01T00:00:00.000Z",
"groups": {
"A": {
"tracker_key": "ENG-101",
"tracker_id": "tracker-internal-id",
"url": "https://linear.app/example/issue/ENG-101",
"stories": ["E1-S1", "E1-S2"],
"depends_on_groups": []
}
},
"stories": {
"E1-S1": {
"group": "A",
"tracker_key": "ENG-101"
}
}
}
tracker-map.json shape (story granularity):
{
"provider": "linear",
"granularity": "story",
"published_at": "2026-05-01T00:00:00.000Z",
"groups": {
"A": {
"stories": ["E1-S1", "E1-S2"],
"depends_on_groups": []
}
},
"stories": {
"E1-S1": {
"group": "A",
"tracker_key": "ENG-101",
"tracker_id": "tracker-internal-id-1",
"url": "https://linear.app/example/issue/ENG-101",
"harness_command": "/build --lite --group A",
"mode_label": "mode-lite",
"blocked_by_stories": []
},
"E1-S2": {
"group": "A",
"tracker_key": "ENG-102",
"tracker_id": "tracker-internal-id-2",
"url": "https://linear.app/example/issue/ENG-102",
"harness_command": "/build --lite --group A",
"mode_label": "mode-lite",
"blocked_by_stories": ["E1-S1"]
}
}
}
Under story granularity, the groups section is informational — every actual tracker issue lives under stories. The orchestrator looks up the story by tracker key and runs the harness command resolved for that story.
needs_breakdown.harness-group, agent-ready.mode-* label when a non-default harness command is intended (for example mode-lite for a /build --lite-eligible scope)..claude/state/tracker-map.json authoritative for the local repo. If you re-publish, update entries in place rather than creating duplicates.--granularity group, default)Read dependency-graph.md and create one tracker issue per dependency group.
Include every ready story in the group issue body.
Include acceptance criteria, feature IDs, owned files from component-map.md, and the harness command:
/auto --group A
Mirror group dependencies as tracker blocker relationships when the provider supports them.
Apply group-A (or equivalent group ID) label.
--granularity story)specs/stories/ and create one tracker issue per story (skip needs_breakdown and stories not in any group).component-map.md, and feature IDs from features.json filtered to that story.Mode: field (e.g. Mode: lite), use that./build --lite eligibility (≤5 stories, single group, no DB/auth — see .claude/skills/build/references/lite-lane.md), use /build --lite --group <group-id> for every story in that group./auto --group <group-id> and let /auto recognise the single-story scope.mode-* label (e.g. mode-lite) when the harness command is not the default /auto.Depends On: in story files) as tracker blocker relationships between story issues. Cross-group dependencies are inherited from the group's blocker links.story-E1-S1 (or the story ID as a slug) label so humans can filter the tracker view by story.--granularity group)## Harness Group
- Group: A
- Harness command: /auto --group A
- Stories: E1-S1, E1-S2
- Depends on groups: none
## Acceptance Criteria
### E1-S1 — Story title
- Criterion 1
- Criterion 2
## Feature IDs
- F001
- F002
## Expected Proof
- Branch or PR URL
- Unit/lint/typecheck result
- Evaluator report
- Security review
- Updated `features.json` pass/fail state
--granularity story)## Harness Story
- Story: E1-S1
- Group: A
- Harness command: /build --lite --group A
- Depends on stories: none
## Acceptance Criteria
- Criterion 1
- Criterion 2
- Criterion 3
## Owned Files (from component-map.md)
- src/research/duckduckgo.py
- tests/test_duckduckgo.py
## Feature IDs
- F001
## Expected Proof
- Branch or PR URL
- Unit/lint/typecheck result for the owned files
- Updated `features.json` entry for this story
/tracker-publish writes the local handoff contract (.claude/state/tracker-map.json + .claude/state/tracker-runs/group-*.md). It does not call Linear directly from Claude's tool surface. The actual remote create happens via one of three transports, picked in this order:
linear:issue:create or equivalent). MCP gives you OAuth and avoids storing the API key.node .claude/skills/tracker-publish/scripts/publish-to-linear.js. Self-contained Node script that:
<project-root>/.env (without overriding existing shell env)tracker-map.json + tracker-config.jsonteam_key)ready_state to a state IDissueCreates one issue per pending grouptracker_key / tracker_id / url back into tracker-map.jsontracker_key already looks real are skippedlinear-cli — if a user has the third-party CLI installed and wants to drive it themselves.# from the project root
node .claude/skills/tracker-publish/scripts/publish-to-linear.js
# dry run (no remote calls, no file writes)
node .claude/skills/tracker-publish/scripts/publish-to-linear.js --dry-run
# override env file location (e.g. when .env lives elsewhere)
node .claude/skills/tracker-publish/scripts/publish-to-linear.js --env-file /path/to/.env
Prerequisites:
LINEAR_API_KEY in <project-root>/.env (the file is git-ignored by the scaffold) or in the shell.tracker.project_slug in .claude/tracker-config.json set to a real Linear project slug — the placeholder replace-with-linear-project-slug is rejected.tracker.team_key (e.g. ENG) matching the team attached to that project. If absent, the script falls back to the first team on the project and warns.config_snapshot (ready_state, running_state, etc.) must exist in the team — the script will print the available states if a name is wrong.After writing the local artifacts, check for Linear MCP. If none:
LINEAR_API_KEY is reachable (project .env or shell).node …/publish-to-linear.js line above) and wait for the user to invoke it.Do not assume the user has shelled in the API key — many users set it only in .env and never export it. Always prefer the script's built-in .env loader over a shell-export requirement.
After publishing, present:
pending-remote-publish placeholders with the follow-up command)Ask the human to confirm the tracker workflow before unattended orchestration begins.