claude-skills/engineering/skills/tc-tracker/references/lifecycle.md
Reza Rezvani 1851c8fb09 fix(plugins): restructure 9 multi-skill domain plugins into ./skills/ layout
Same root cause as #587/#591 — Claude Code's runtime loader rejects
array-form skills paths like ["./content-production", "./ai-seo", ...]
even when each entry is a valid subdirectory containing SKILL.md.
`claude plugin validate` accepts them but the loader does not.

The proven canonical layout (used by self-improving-agent in #536):

  <plugin>/
  ├── .claude-plugin/plugin.json    skills: "./skills"
  └── skills/
      ├── <skill-1>/SKILL.md
      ├── <skill-2>/SKILL.md
      └── ...

Restructured 9 multi-skill domain plugins:
- business-growth (4 skills moved)
- c-level-advisor (28)
- engineering (36)
- engineering-team (32)
- finance (2)
- marketing-skill (43)
- product-team (12)
- project-management (8)
- ra-qm-team (13)

Also fixed standalone plugins that had root SKILL.md + ./skills/ subdir
(agenthub, autoresearch-agent, executive-mentor, playwright-pro). The
loader rejected them despite skills="./skills" because of the conflicting
root SKILL.md (compare self-improving-agent which works because PR #536
moved its root SKILL.md). Moved each root SKILL.md into ./skills/<name>/.

Restored standalone plugin folders to their original paths after the
multi-skill restructure swept them into parent skills/ directories
(marketplace.json source paths require original locations).

Removed 7 orphaned marketplace entries that pointed to skill folders
without their own plugin.json (content-creator, demand-gen,
fullstack-engineer, aws-architect, product-manager, scrum-master,
skill-security-auditor) — these were already non-functional.

Bumped patch versions on every changed plugin and synced
marketplace.json. Marketplace now lists 29 working plugins (down
from 36).

After merge: users run `/plugin marketplace update claude-code-skills`
followed by `/plugin update --all` to pick up the working layout.
2026-05-02 22:51:20 +02:00

3.9 KiB

TC Lifecycle and State Machine

A TC moves through six implementation states. Transitions are validated on every write — invalid moves are rejected with a clear error.

State Diagram

                +-----------+
                |  planned  |
                +-----------+
                  |       ^
                  v       |
                +-------------+
        +-----> | in_progress | <-----+
        |       +-------------+       |
        |         |       |           |
        v         |       v           |
   +---------+    |  +-------------+  |
   | blocked |<---+  | implemented |  |
   +---------+       +-------------+  |
        |                  |          |
        v                  v          |
   +---------+         +--------+     |
   | planned |         | tested |-----+
   +---------+         +--------+
                            |
                            v
                       +----------+
                       | deployed |
                       +----------+
                            |
                            v
                       in_progress (rework / hotfix)

Transition Table

From Allowed Transitions
planned in_progress, blocked
in_progress blocked, implemented
blocked in_progress, planned
implemented tested, in_progress
tested deployed, in_progress
deployed in_progress

Same-status transitions are no-ops and always allowed. Anything else is an error.

State Definitions

State Meaning Required Before Moving Forward
planned TC has been created with description and motivation Decide implementation approach
in_progress Active development Code changes captured in files_affected
blocked Cannot proceed (dependency, decision needed) At least one entry in handoff.blockers
implemented Code complete, awaiting tests All target files in files_affected
tested Test cases executed, results recorded At least one test_case with status pass (or explicit skip with rationale)
deployed Approved and shipped approval.approved=true with approved_by and approved_date

Recovery Flows

"I committed before testing"

  1. Status is implemented.
  2. Write tests, run them, set test_cases[*].status = pass.
  3. Transition implemented -> tested.

"Production bug in a deployed TC"

  1. Open the deployed TC.
  2. Transition deployed -> in_progress.
  3. Add a new revision summarizing the rework.
  4. Walk forward through implemented -> tested -> deployed again.

"Blocked, then unblocked"

  1. From in_progress, transition to blocked. Add blockers to handoff.blockers.
  2. When unblocked, transition blocked -> in_progress and clear/move blockers to notes.

"Cancelled work"

There is no cancelled state. If a TC is abandoned:

  1. Add a final revision: "Cancelled — reason: ...".
  2. Move to blocked.
  3. Add a [CANCELLED] tag.
  4. Leave the record in place — never delete it (history is append-only).

Status Field Discipline

  • Update status ONLY through tc_update.py --set-status. Never edit JSON by hand.
  • Every status change creates a new revision entry with field = status, action = changed, and reason populated.
  • The registry's statistics.by_status is recomputed on every write.

Anti-patterns

Anti-pattern Why it's wrong
Skipping tested and going straight to deployed Bypasses validation; misleads downstream consumers
Deleting a record to "cancel" a TC History is append-only; deletion breaks the audit trail
Re-using a TC ID after deletion Sequential numbering must be preserved
Changing status without a --reason Future maintainers cannot reconstruct intent
Long-lived in_progress TCs (weeks+) Either too big — split into sub-TCs — or stalled and should be marked blocked