/tc — Technical Change Tracker
Track every code change with structured JSON records and accessible HTML output.
Ensures AI bot sessions can resume seamlessly when previous sessions expire or are abandoned.
Designed for deployment across multiple projects.
First-Use Detection (MANDATORY — Every Session)
At the start of EVERY session, before doing any work:
- Check if
docs/TC/tc_config.json exists in the current working directory
- If it EXISTS: follow the Session Start Protocol in the
/tc resume section
- If it does NOT exist: prompt the user:
TC tracking is not initialized in this project. Would you like to set it up?
This enables structured change tracking, AI session handoff, and HTML documentation.
Run /tc init to get started.
- Wait for the user's response. If they agree, run
/tc init.
- If the user declines, continue without TC tracking for this session.
A global skill is installed at ~/.claude/skills/tc.md to ensure this check runs
in every project, even those that haven't been initialized yet.
Overview
Each Technical Change (TC) is a structured record that documents:
- What changed (files, code, configuration)
- Why it changed (motivation, scope, design decisions)
- Who changed it (human or AI bot session)
- When it changed (revision history with timestamps)
- How it was tested (test cases with evidence from logs)
- Where work stands (session handoff data for bot continuity)
Storage Location
Each project stores TCs at {project_root}/docs/TC/:
docs/TC/
├── tc_config.json # Project settings
├── tc_registry.json # Master index
├── index.html # Dashboard
├── records/
│ └── TC-001-MM-DD-YY-name/
│ ├── tc_record.json # System of record
│ └── tc_record.html # Human-readable
└── evidence/
└── TC-001/ # Log snippets, screenshots
TC Naming Convention
- Parent TC:
TC-NNN-MM-DD-YY-functionality-slug (e.g., TC-001-04-03-26-user-authentication)
- Sub-TC:
TC-NNN.A or TC-NNN.A.1 (letter = revision, number = sub-revision)
- NNN = sequential number, MM-DD-YY = creation date, slug = kebab-case functionality name
Implementation States
planned → in_progress → implemented → tested → deployed
│ │ │ │ │
└→ blocked ←┘ └→ in_progress ←──────┘
│ │ │ (rework/hotfix)
│ │ └→ paused → in_progress
│ │ │
│ └──────→└→ voided (terminal — cancelled)
└→ voided
- paused: Development work temporarily stopped. Can resume to
in_progress or cancel to voided.
- voided: TC cancelled entirely. Terminal state — cannot transition out.
Commands
/tc init
Initialize TC tracking in the current project. Run this once per project.
Steps:
- Check if
docs/TC/tc_config.json exists. If yes, report "Already initialized" with current stats and stop.
- Detect project name: try CLAUDE.md first heading, then package.json name, then pyproject.toml name, then directory basename. Confirm with user.
- Create directories:
docs/TC/, docs/TC/records/, docs/TC/evidence/
- Create
tc_config.json:{
"project_name": "<detected>",
"tc_root": "docs/TC",
"created": "<ISO 8601 now>",
"skills_library_path": "<absolute path to skills_library/TC>",
"auto_track": true,
"auto_regenerate_html": true,
"auto_regenerate_dashboard": true,
"default_author": "Claude",
"categories": ["feature","bugfix","refactor","infrastructure","documentation","hotfix","enhancement"]
}
- Create
tc_registry.json:{
"project_name": "<name>",
"created": "<ISO 8601>",
"updated": "<ISO 8601>",
"next_tc_number": 1,
"records": [],
"statistics": {
"total": 0,
"by_status": {"planned":0,"in_progress":0,"blocked":0,"implemented":0,"tested":0,"deployed":0,"paused":0,"voided":0},
"by_scope": {"feature":0,"bugfix":0,"refactor":0,"infrastructure":0,"documentation":0,"hotfix":0,"enhancement":0},
"by_priority": {"critical":0,"high":0,"medium":0,"low":0}
}
}
- Generate empty dashboard: run
python "<skills_path>/generators/generate_dashboard.py" "docs/TC/tc_registry.json"
- Update CLAUDE.md: read existing file (or create new). Check for marker
## Technical Change (TC) Tracking (MANDATORY). If not found, append the contents of init/claude_md_snippet.md with {skills_library_path} replaced with the actual absolute path.
- Update
.claude/settings.local.json: read existing file (or create {"permissions":{"allow":[]}}). Merge TC permissions from init/settings_template.json (with paths substituted). Deduplicate. Write back.
- Report all created/updated files. Suggest
/tc create as next step.
/tc create
Create a new TC record.
Steps:
- Read
docs/TC/tc_registry.json
- Generate TC ID:
TC-{next_tc_number:03d}-{MM-DD-YY}-{slugify(name)}
- Ask user for:
- Title (default: formatted version of the slug)
- Scope: feature, bugfix, refactor, infrastructure, documentation, hotfix, enhancement
- Priority: critical, high, medium, low (default: medium)
- Summary (at least 10 characters)
- Motivation (why is this change needed?)
- Create directory:
docs/TC/records/TC-NNN-MM-DD-YY-slug/
- Create
tc_record.json with all fields initialized:
- status = "planned"
- revision_history = [R1 creation event]
- session_context.current_session populated with this session's info
- All arrays initialized to []
- approval.approved = false, test_coverage_status = "none"
- Add entry to tc_registry.json records array. Increment next_tc_number. Recompute statistics.
- Generate HTML: run the tc_record HTML generator
- Regenerate dashboard: run the dashboard generator
- Report: display TC ID, link to HTML, suggest next steps
/tc update
Update an existing TC record. This is the general-purpose update command.
Steps:
- Read the TC record from
docs/TC/records/<tc-dir>/tc_record.json
- Determine what to update (user may specify, or you determine from context):
- Status change: validate transition with state machine. Ask for reason.
- Add files: append to files_affected array
- Add test case: create new test entry with sequential ID (T1, T2...)
- Update test result: set actual_result, status, evidence, tested_by, tested_date
- Add evidence: append to a test case's evidence array
- Update handoff: update session_context.handoff fields
- Add notes: append to notes field
- Add sub-TC: append to sub_tcs array
- For EVERY change:
- Append a new revision entry to revision_history (sequential R-id, timestamp, author, summary, field_changes with old/new values and reason)
- Update the
updated timestamp
- Update
metadata.last_modified and metadata.last_modified_by
- Update
session_context.current_session.last_active
- Write tc_record.json (atomic: write to .tmp, then rename)
- Update tc_registry.json (sync status, scope, priority, updated, test_summary). Recompute statistics.
- If auto_regenerate_html: regenerate TC HTML
- If status changed and auto_regenerate_dashboard: regenerate dashboard
/tc status [tc-id]
View TC status.
Without tc-id: Read tc_registry.json and display a summary table of all TCs:
- TC ID, Title, Status (with badge), Scope, Priority, Tests (pass/total), Last Updated
With tc-id: Read the specific TC record and display:
- Full status including handoff data, test results, revision count, files affected
- Any validation errors
/tc resume
Resume work on a TC from a previous session.
Steps:
- Read the TC record
- Display the handoff section prominently:
- Progress summary
- Next steps (numbered)
- Blockers (highlighted)
- Key context
- Files in progress with their states
- Recent decisions
- Archive the current session to session_history:
- Move current_session data to a new entry in session_history
- Set ended = now
- Create new current_session with this session's info
- Append revision entry: "Session resumed by [platform/model]"
- Write tc_record.json
- Prompt: "Ready to continue. Here are the next steps: [list from handoff]"
/tc close
Close a TC by transitioning it to deployed.
Steps:
- Read the TC record
- Validate current status allows transition to
deployed
- Check all test cases — warn if any are pending/fail/blocked
- Ask for:
- Approval: who is approving? (user name or "self")
- Approval notes (optional)
- Final test coverage assessment (none/partial/full)
- Update:
- status = "deployed"
- approval.approved = true
- approval.approved_by, approved_date, approval_notes, test_coverage_status
- Append final revision entry
- Archive session to session_history
- Write tc_record.json and update registry
- Regenerate HTML and dashboard
- Report: "TC-NNN closed and deployed."
/tc export
Regenerate ALL HTML files from their JSON records.
Steps:
- Read tc_registry.json
- For each record: run the TC HTML generator on its tc_record.json
- Run the dashboard generator
- Report: "Regenerated X TC pages and dashboard."
/tc dashboard
Regenerate just the dashboard index.html.
Steps:
- Run the dashboard generator on tc_registry.json
- Report path to generated index.html
/tc retro <retro_changelog.json>
Retroactively create TC records in bulk from a structured changelog file.
Use this when onboarding an existing project with extensive undocumented history.
Steps:
- Read the retro_changelog.json file (must match
schemas/tc_retro_changelog.schema.json)
- Validate the changelog structure
- Run the batch generator:
python "{skills_library_path}/generators/generate_retro_tcs.py" "<retro_changelog.json>" "docs/TC"
- The generator will:
- Create a TC record for each entry (TC-001 through TC-NNN)
- Validate every record against the schema
- Generate HTML for every record
- Update the registry with all entries
- Regenerate the dashboard
- Report: total created, any errors, link to dashboard
Retro Changelog Format (retro_changelog.json):
{
"project": "Project Name",
"default_author": "retroactive",
"changes": [
{
"title": "Feature or Change Title",
"scope": "feature|bugfix|refactor|infrastructure|documentation|hotfix|enhancement",
"priority": "critical|high|medium|low",
"status": "deployed",
"date": "YYYY-MM-DD",
"description": "What changed and why (10+ chars)",
"motivation": "Why this change was needed (optional)",
"files": ["path/to/file.py", "path/to/other.py"],
"tags": ["tag1", "tag2"],
"version": "v1.0.0"
}
]
}
Building the changelog: Claude should analyze the project's git history, docs, changelogs,
README, and code to build the retro_changelog.json. Group related changes into single TCs.
Each TC should represent one logical unit of work (a feature, a fix, a refactor).
/tc retro --from-git
Auto-generate the retro_changelog.json directly from git history instead of building it manually.
Steps:
- Run the git-to-changelog generator:
python "{skills_library_path}/generators/generate_retro_from_git.py" \
--repo-path "." \
--output "retro_changelog.json" \
--project-name "Project Name" \
--since "2024-01-01" \
--until "2026-04-05"
- The generator will:
- Parse
git log to extract all commits with files changed, dates, authors, messages
- Group related commits into logical TCs using:
- Merge commit / PR boundaries (primary, if the repo uses merge/squash workflow)
- File-overlap clustering (commits touching the same files)
- Time-proximity grouping (same author, within ~2 hour window)
- Auto-detect scope from commit messages: "fix" -> bugfix, "feat" -> feature, "refactor" -> refactor, "docs" -> documentation, "chore"/"ci" -> infrastructure
- Auto-detect priority: default medium, "critical"/"urgent"/"hotfix" -> critical/high
- Write a valid
retro_changelog.json matching schemas/tc_retro_changelog.schema.json
- Review the generated changelog (optional but recommended — edit titles, adjust scopes/priorities)
- Feed it into the batch TC generator:
python "{skills_library_path}/generators/generate_retro_tcs.py" "retro_changelog.json" "docs/TC"
- Report: total TCs created, link to dashboard
CLI Options:
| Flag |
Default |
Description |
--repo-path PATH |
. |
Path to the git repository |
--output PATH |
retro_changelog.json |
Output file path |
--project-name NAME |
auto-detected |
Project name for the changelog header |
--since DATE |
(all history) |
Only include commits after YYYY-MM-DD |
--until DATE |
(all history) |
Only include commits up to YYYY-MM-DD |
--author NAME |
retroactive |
Default author field in the changelog |
--time-window HOURS |
2 |
Clustering time window in hours |
/tc link [|HEAD|--range A..B]
Link git commits to a TC record. Appends to git.commits[], merges files into files_affected[], adds a revision entry.
Steps:
- Resolve the SHA (default: HEAD). For
--range, resolve all commits in the range.
- For each commit: read metadata via
git show, skip if SHA already linked (dedup).
- Append to
git.commits[] with link_source: "manual".
- Merge
files_changed into files_affected[] (skip duplicates).
- Append revision history entry: "Linked N commit(s)".
- Regenerate TC HTML.
/tc git status
Show the git integration state of all TC records.
Output:
- Unlinked TCs: Records with no
git block (candidates for /tc link)
- Linked TCs: Records with
git.commits[] populated (with commit count)
- Online-enriched TCs: Records with PR metadata
- Unlinked commits: Recent commits on the current branch not linked to any TC
- Uncommitted files: Matching
files_affected[] of in-progress TCs
/tc pr link []
(Online opt-in) Link a PR/MR to a TC record. Requires gh (GitHub) or glab (GitLab) CLI.
Steps:
- Auto-detect provider from
git remote -v.
- If no PR number given, find PR for current branch via
gh pr view <branch>.
- Populate
git.remotes[].pr with number, URL, state, review decision, merge commit.
- Append revision entry. Regenerate TC HTML.
- Graceful degradation: if CLI is missing or unauthenticated, report and exit cleanly.
/tc sync [|--all]
(Online opt-in) Refresh PR metadata for TCs with linked PRs.
Steps:
- For each TC with
git.remotes[].pr.number populated:
- Query current PR state via
gh pr view or glab mr view.
- Update state, review_decision, merged_sha, last_synced.
- If PR state changed, append revision entry.
- Report: "Updated N TC(s)" or "No changes (offline or up-to-date)".
/tc git install-merge-driver
Register the TC registry merge driver to handle tc_registry.json conflicts during rebases and merges.
Steps:
- Run:
git config merge.tc-registry.driver 'python "<path>/tc_registry_merge.py" %O %A %B'
- Add to
.gitattributes: docs/TC/tc_registry.json merge=tc-registry
- Report: "Merge driver registered."
Auto-Detection Rules — Non-Blocking Subagent Pattern
TC tracking MUST NOT interrupt the main workflow. Use background subagents for all bookkeeping.
During Work
- NEVER stop to update TC records inline. Focus entirely on the task.
- Do not read/write TC files between code changes.
- The main agent's job is to code, not to do paperwork.
At Natural Milestones
When a logical unit of work is complete (feature done, test passing, stopping point):
- Spawn a background Agent (run_in_background=true) with this prompt:
"Read docs/TC/tc_registry.json. Find the in_progress TC. Read its tc_record.json. Update files_affected with [list files changed]. Append a revision entry summarizing what was done. Update session_context.current_session.last_active. Write the updated record. Regenerate the TC HTML and dashboard."
- The main agent continues working without waiting.
Only Surface Questions When Genuinely Needed
- "This work doesn't match any active TC — should I create one?" (ask once per session, not per file)
- "TC-NNN looks complete — transition to implemented?" (at milestones only, don't nag)
- Never interrupt the user for routine TC bookkeeping.
At Session End
Before the session closes, spawn a final background Agent to write the handoff summary:
- progress_summary: what was accomplished
- next_steps: what still needs doing
- blockers: anything preventing progress
- key_context: important decisions, gotchas, patterns the next bot needs
- files_in_progress: which files are mid-edit
On Session Start
- Check if
docs/TC/ exists in the project
- If yes: read tc_registry.json, find in_progress/blocked TCs
- Display handoff summary for any active TCs
- Ask user if they want to resume
Validation Rules (Always Enforced)
- State machine: only valid transitions allowed (see diagram above)
- Sequential IDs: revision_history uses R1,R2,R3...; test_cases uses T1,T2,T3...
- Append-only history: revision_history entries are never modified or deleted
- Approval consistency: approved=true requires approved_by and approved_date
- TC ID format: must match
TC-NNN-MM-DD-YY-slug pattern
- Sub-TC ID format: must match
TC-NNN.A or TC-NNN.A.N pattern
- HTML escaping: all user data is escaped before HTML rendering
- Atomic writes: JSON files written to .tmp then renamed
- Registry stats: recomputed on every registry write
Python Generators
Located at {skills_library_path}/generators/:
# Generate individual TC HTML
python "generators/generate_tc_html.py" "<path_to_tc_record.json>" [--output <path>]
# Generate dashboard
python "generators/generate_dashboard.py" "<path_to_tc_registry.json>" [--output <path>]
# Validate a TC record
python "validators/validate_tc.py" "<path_to_tc_record.json>"
# Validate the registry
python "validators/validate_tc.py" --registry "<path_to_tc_registry.json>"
# Retroactive batch creation
python "generators/generate_retro_tcs.py" "<retro_changelog.json>" "<docs/TC/>"
# Generate retro_changelog.json from git history
python "generators/generate_retro_from_git.py" [--repo-path .] [--output retro_changelog.json] [--project-name "Name"] [--since 2024-01-01] [--until 2026-04-05]
# --- Git Integration ---
# Link commit(s) to a TC record
python "generators/tc_git_link.py" "<tc_record.json>" [<sha>|HEAD] [--range A..B]
# Show git integration status for all TCs (finds unlinked TCs + unlinked commits)
python "generators/tc_git_status.py" "<docs/TC/>" [--unlinked-only] [--show-candidates]
# Auto-link HEAD to the single in-progress TC (used by PostToolUse hook)
python "generators/tc_git_autolink.py" --if-commit [<docs/TC/>]
# Pre-commit advisory: warn if staged files aren't in any active TC (used by PreToolUse hook)
python "generators/tc_precommit_check.py" --if-commit [<docs/TC/>]
# Registry 3-way merge driver (register with git config for conflict resolution)
python "generators/tc_registry_merge.py" <base> <ours> <theirs>
# --- Online (opt-in) ---
# Link a PR/MR to a TC record (requires gh or glab CLI)
python "generators/tc_pr_link.py" "<tc_record.json>" [<pr_number>]
# Refresh PR metadata for all TCs with linked PRs
python "generators/tc_sync.py" "<docs/TC/>" [<tc_id>]
# --- Session Lifecycle ---
# Display session start report with active TC handoff data
python "generators/tc_session_start.py" "<docs/TC/>" [--json]
# Archive current session and write handoff data
python "generators/tc_session_end.py" "<tc_record.json>" [--summary "..."] [--next "..."]
All generators use Python stdlib only — no external dependencies.
All generators validate their input before producing output.
All HTML output is self-contained with inlined CSS (works from file:// URLs).
All HTML output is WCAG AA+ accessible with rem-based fonts, high contrast dark theme, skip links, and aria labels.
1---2name: tc3description: Technical Change tracking skill. Use when user says /tc, /tc init, /tc create, /tc update, /tc status, /tc resume, /tc close, /tc export, /tc dashboard, or /tc retro. Also auto-runs at session start to check for TC initialization and active TCs. Tracks code changes with structured JSON records and accessible HTML output for AI session continuity.4---56# /tc — Technical Change Tracker78Track every code change with structured JSON records and accessible HTML output.9Ensures AI bot sessions can resume seamlessly when previous sessions expire or are abandoned.10Designed for deployment across multiple projects.1112## First-Use Detection (MANDATORY — Every Session)1314At the start of EVERY session, before doing any work:15161. Check if `docs/TC/tc_config.json` exists in the current working directory172. **If it EXISTS**: follow the Session Start Protocol in the `/tc resume` section183. **If it does NOT exist**: prompt the user:19 > TC tracking is not initialized in this project. Would you like to set it up?20 > This enables structured change tracking, AI session handoff, and HTML documentation.21 > Run `/tc init` to get started.224. Wait for the user's response. If they agree, run `/tc init`.235. If the user declines, continue without TC tracking for this session.2425A global skill is installed at `~/.claude/skills/tc.md` to ensure this check runs26in every project, even those that haven't been initialized yet.2728## Overview2930Each Technical Change (TC) is a structured record that documents:31- **What** changed (files, code, configuration)32- **Why** it changed (motivation, scope, design decisions)33- **Who** changed it (human or AI bot session)34- **When** it changed (revision history with timestamps)35- **How it was tested** (test cases with evidence from logs)36- **Where work stands** (session handoff data for bot continuity)3738### Storage Location39Each project stores TCs at `{project_root}/docs/TC/`:40```41docs/TC/42├── tc_config.json # Project settings43├── tc_registry.json # Master index44├── index.html # Dashboard45├── records/46│ └── TC-001-MM-DD-YY-name/47│ ├── tc_record.json # System of record48│ └── tc_record.html # Human-readable49└── evidence/50 └── TC-001/ # Log snippets, screenshots51```5253### TC Naming Convention54- **Parent TC**: `TC-NNN-MM-DD-YY-functionality-slug` (e.g., `TC-001-04-03-26-user-authentication`)55- **Sub-TC**: `TC-NNN.A` or `TC-NNN.A.1` (letter = revision, number = sub-revision)56- NNN = sequential number, MM-DD-YY = creation date, slug = kebab-case functionality name5758### Implementation States59```60planned → in_progress → implemented → tested → deployed61 │ │ │ │ │62 └→ blocked ←┘ └→ in_progress ←──────┘63 │ │ │ (rework/hotfix)64 │ │ └→ paused → in_progress65 │ │ │66 │ └──────→└→ voided (terminal — cancelled)67 └→ voided68```6970- **paused**: Development work temporarily stopped. Can resume to `in_progress` or cancel to `voided`.71- **voided**: TC cancelled entirely. Terminal state — cannot transition out.7273---7475## Commands7677### /tc init78Initialize TC tracking in the current project. Run this once per project.7980**Steps:**811. Check if `docs/TC/tc_config.json` exists. If yes, report "Already initialized" with current stats and stop.822. Detect project name: try CLAUDE.md first heading, then package.json name, then pyproject.toml name, then directory basename. Confirm with user.833. Create directories: `docs/TC/`, `docs/TC/records/`, `docs/TC/evidence/`844. Create `tc_config.json`:85 ```json86 {87 "project_name": "<detected>",88 "tc_root": "docs/TC",89 "created": "<ISO 8601 now>",90 "skills_library_path": "<absolute path to skills_library/TC>",91 "auto_track": true,92 "auto_regenerate_html": true,93 "auto_regenerate_dashboard": true,94 "default_author": "Claude",95 "categories": ["feature","bugfix","refactor","infrastructure","documentation","hotfix","enhancement"]96 }97 ```985. Create `tc_registry.json`:99 ```json100 {101 "project_name": "<name>",102 "created": "<ISO 8601>",103 "updated": "<ISO 8601>",104 "next_tc_number": 1,105 "records": [],106 "statistics": {107 "total": 0,108 "by_status": {"planned":0,"in_progress":0,"blocked":0,"implemented":0,"tested":0,"deployed":0,"paused":0,"voided":0},109 "by_scope": {"feature":0,"bugfix":0,"refactor":0,"infrastructure":0,"documentation":0,"hotfix":0,"enhancement":0},110 "by_priority": {"critical":0,"high":0,"medium":0,"low":0}111 }112 }113 ```1146. Generate empty dashboard: run `python "<skills_path>/generators/generate_dashboard.py" "docs/TC/tc_registry.json"`1157. Update CLAUDE.md: read existing file (or create new). Check for marker `## Technical Change (TC) Tracking (MANDATORY)`. If not found, append the contents of `init/claude_md_snippet.md` with `{skills_library_path}` replaced with the actual absolute path.1168. Update `.claude/settings.local.json`: read existing file (or create `{"permissions":{"allow":[]}}`). Merge TC permissions from `init/settings_template.json` (with paths substituted). Deduplicate. Write back.1179. Report all created/updated files. Suggest `/tc create` as next step.118119### /tc create <functionality-name>120Create a new TC record.121122**Steps:**1231. Read `docs/TC/tc_registry.json`1242. Generate TC ID: `TC-{next_tc_number:03d}-{MM-DD-YY}-{slugify(name)}`1253. Ask user for:126 - Title (default: formatted version of the slug)127 - Scope: feature, bugfix, refactor, infrastructure, documentation, hotfix, enhancement128 - Priority: critical, high, medium, low (default: medium)129 - Summary (at least 10 characters)130 - Motivation (why is this change needed?)1314. Create directory: `docs/TC/records/TC-NNN-MM-DD-YY-slug/`1325. Create `tc_record.json` with all fields initialized:133 - status = "planned"134 - revision_history = [R1 creation event]135 - session_context.current_session populated with this session's info136 - All arrays initialized to []137 - approval.approved = false, test_coverage_status = "none"1386. Add entry to tc_registry.json records array. Increment next_tc_number. Recompute statistics.1397. Generate HTML: run the tc_record HTML generator1408. Regenerate dashboard: run the dashboard generator1419. Report: display TC ID, link to HTML, suggest next steps142143### /tc update <tc-id>144Update an existing TC record. This is the general-purpose update command.145146**Steps:**1471. Read the TC record from `docs/TC/records/<tc-dir>/tc_record.json`1482. Determine what to update (user may specify, or you determine from context):149 - **Status change**: validate transition with state machine. Ask for reason.150 - **Add files**: append to files_affected array151 - **Add test case**: create new test entry with sequential ID (T1, T2...)152 - **Update test result**: set actual_result, status, evidence, tested_by, tested_date153 - **Add evidence**: append to a test case's evidence array154 - **Update handoff**: update session_context.handoff fields155 - **Add notes**: append to notes field156 - **Add sub-TC**: append to sub_tcs array1573. For EVERY change:158 - Append a new revision entry to revision_history (sequential R-id, timestamp, author, summary, field_changes with old/new values and reason)159 - Update the `updated` timestamp160 - Update `metadata.last_modified` and `metadata.last_modified_by`161 - Update `session_context.current_session.last_active`1624. Write tc_record.json (atomic: write to .tmp, then rename)1635. Update tc_registry.json (sync status, scope, priority, updated, test_summary). Recompute statistics.1646. If auto_regenerate_html: regenerate TC HTML1657. If status changed and auto_regenerate_dashboard: regenerate dashboard166167### /tc status [tc-id]168View TC status.169170**Without tc-id**: Read tc_registry.json and display a summary table of all TCs:171- TC ID, Title, Status (with badge), Scope, Priority, Tests (pass/total), Last Updated172173**With tc-id**: Read the specific TC record and display:174- Full status including handoff data, test results, revision count, files affected175- Any validation errors176177### /tc resume <tc-id>178Resume work on a TC from a previous session.179180**Steps:**1811. Read the TC record1822. Display the handoff section prominently:183 - Progress summary184 - Next steps (numbered)185 - Blockers (highlighted)186 - Key context187 - Files in progress with their states188 - Recent decisions1893. Archive the current session to session_history:190 - Move current_session data to a new entry in session_history191 - Set ended = now1924. Create new current_session with this session's info1935. Append revision entry: "Session resumed by [platform/model]"1946. Write tc_record.json1957. Prompt: "Ready to continue. Here are the next steps: [list from handoff]"196197### /tc close <tc-id>198Close a TC by transitioning it to deployed.199200**Steps:**2011. Read the TC record2022. Validate current status allows transition to `deployed`2033. Check all test cases — warn if any are pending/fail/blocked2044. Ask for:205 - Approval: who is approving? (user name or "self")206 - Approval notes (optional)207 - Final test coverage assessment (none/partial/full)2085. Update:209 - status = "deployed"210 - approval.approved = true211 - approval.approved_by, approved_date, approval_notes, test_coverage_status212 - Append final revision entry213 - Archive session to session_history2146. Write tc_record.json and update registry2157. Regenerate HTML and dashboard2168. Report: "TC-NNN closed and deployed."217218### /tc export219Regenerate ALL HTML files from their JSON records.220221**Steps:**2221. Read tc_registry.json2232. For each record: run the TC HTML generator on its tc_record.json2243. Run the dashboard generator2254. Report: "Regenerated X TC pages and dashboard."226227### /tc dashboard228Regenerate just the dashboard index.html.229230**Steps:**2311. Run the dashboard generator on tc_registry.json2322. Report path to generated index.html233234### /tc retro <retro_changelog.json>235Retroactively create TC records in bulk from a structured changelog file.236Use this when onboarding an existing project with extensive undocumented history.237238**Steps:**2391. Read the retro_changelog.json file (must match `schemas/tc_retro_changelog.schema.json`)2402. Validate the changelog structure2413. Run the batch generator:242 ```bash243 python "{skills_library_path}/generators/generate_retro_tcs.py" "<retro_changelog.json>" "docs/TC"244 ```2454. The generator will:246 - Create a TC record for each entry (TC-001 through TC-NNN)247 - Validate every record against the schema248 - Generate HTML for every record249 - Update the registry with all entries250 - Regenerate the dashboard2515. Report: total created, any errors, link to dashboard252253**Retro Changelog Format** (`retro_changelog.json`):254```json255{256 "project": "Project Name",257 "default_author": "retroactive",258 "changes": [259 {260 "title": "Feature or Change Title",261 "scope": "feature|bugfix|refactor|infrastructure|documentation|hotfix|enhancement",262 "priority": "critical|high|medium|low",263 "status": "deployed",264 "date": "YYYY-MM-DD",265 "description": "What changed and why (10+ chars)",266 "motivation": "Why this change was needed (optional)",267 "files": ["path/to/file.py", "path/to/other.py"],268 "tags": ["tag1", "tag2"],269 "version": "v1.0.0"270 }271 ]272}273```274275**Building the changelog**: Claude should analyze the project's git history, docs, changelogs,276README, and code to build the retro_changelog.json. Group related changes into single TCs.277Each TC should represent one logical unit of work (a feature, a fix, a refactor).278279#### /tc retro --from-git280Auto-generate the retro_changelog.json directly from git history instead of building it manually.281282**Steps:**2831. Run the git-to-changelog generator:284 ```bash285 python "{skills_library_path}/generators/generate_retro_from_git.py" \286 --repo-path "." \287 --output "retro_changelog.json" \288 --project-name "Project Name" \289 --since "2024-01-01" \290 --until "2026-04-05"291 ```2922. The generator will:293 - Parse `git log` to extract all commits with files changed, dates, authors, messages294 - Group related commits into logical TCs using:295 - Merge commit / PR boundaries (primary, if the repo uses merge/squash workflow)296 - File-overlap clustering (commits touching the same files)297 - Time-proximity grouping (same author, within ~2 hour window)298 - Auto-detect scope from commit messages: "fix" -> bugfix, "feat" -> feature, "refactor" -> refactor, "docs" -> documentation, "chore"/"ci" -> infrastructure299 - Auto-detect priority: default medium, "critical"/"urgent"/"hotfix" -> critical/high300 - Write a valid `retro_changelog.json` matching `schemas/tc_retro_changelog.schema.json`3013. Review the generated changelog (optional but recommended — edit titles, adjust scopes/priorities)3024. Feed it into the batch TC generator:303 ```bash304 python "{skills_library_path}/generators/generate_retro_tcs.py" "retro_changelog.json" "docs/TC"305 ```3065. Report: total TCs created, link to dashboard307308**CLI Options:**309| Flag | Default | Description |310|------|---------|-------------|311| `--repo-path PATH` | `.` | Path to the git repository |312| `--output PATH` | `retro_changelog.json` | Output file path |313| `--project-name NAME` | auto-detected | Project name for the changelog header |314| `--since DATE` | (all history) | Only include commits after YYYY-MM-DD |315| `--until DATE` | (all history) | Only include commits up to YYYY-MM-DD |316| `--author NAME` | `retroactive` | Default author field in the changelog |317| `--time-window HOURS` | `2` | Clustering time window in hours |318319### /tc link <tc-id> [<sha>|HEAD|--range A..B]320Link git commits to a TC record. Appends to `git.commits[]`, merges files into `files_affected[]`, adds a revision entry.321322**Steps:**3231. Resolve the SHA (default: HEAD). For `--range`, resolve all commits in the range.3242. For each commit: read metadata via `git show`, skip if SHA already linked (dedup).3253. Append to `git.commits[]` with `link_source: "manual"`.3264. Merge `files_changed` into `files_affected[]` (skip duplicates).3275. Append revision history entry: "Linked N commit(s)".3286. Regenerate TC HTML.329330### /tc git status331Show the git integration state of all TC records.332333**Output:**334- **Unlinked TCs**: Records with no `git` block (candidates for `/tc link`)335- **Linked TCs**: Records with `git.commits[]` populated (with commit count)336- **Online-enriched TCs**: Records with PR metadata337- **Unlinked commits**: Recent commits on the current branch not linked to any TC338- **Uncommitted files**: Matching `files_affected[]` of in-progress TCs339340### /tc pr link <tc-id> [<pr-number>]341**(Online opt-in)** Link a PR/MR to a TC record. Requires `gh` (GitHub) or `glab` (GitLab) CLI.342343**Steps:**3441. Auto-detect provider from `git remote -v`.3452. If no PR number given, find PR for current branch via `gh pr view <branch>`.3463. Populate `git.remotes[].pr` with number, URL, state, review decision, merge commit.3474. Append revision entry. Regenerate TC HTML.3485. **Graceful degradation**: if CLI is missing or unauthenticated, report and exit cleanly.349350### /tc sync [<tc-id>|--all]351**(Online opt-in)** Refresh PR metadata for TCs with linked PRs.352353**Steps:**3541. For each TC with `git.remotes[].pr.number` populated:355 - Query current PR state via `gh pr view` or `glab mr view`.356 - Update state, review_decision, merged_sha, last_synced.3572. If PR state changed, append revision entry.3583. Report: "Updated N TC(s)" or "No changes (offline or up-to-date)".359360### /tc git install-merge-driver361Register the TC registry merge driver to handle `tc_registry.json` conflicts during rebases and merges.362363**Steps:**3641. Run: `git config merge.tc-registry.driver 'python "<path>/tc_registry_merge.py" %O %A %B'`3652. Add to `.gitattributes`: `docs/TC/tc_registry.json merge=tc-registry`3663. Report: "Merge driver registered."367368---369370## Auto-Detection Rules — Non-Blocking Subagent Pattern371372TC tracking MUST NOT interrupt the main workflow. Use background subagents for all bookkeeping.373374### During Work375- **NEVER stop to update TC records inline.** Focus entirely on the task.376- Do not read/write TC files between code changes.377- The main agent's job is to code, not to do paperwork.378379### At Natural Milestones380When a logical unit of work is complete (feature done, test passing, stopping point):381- Spawn a **background Agent** (run_in_background=true) with this prompt:382 "Read docs/TC/tc_registry.json. Find the in_progress TC. Read its tc_record.json. Update files_affected with [list files changed]. Append a revision entry summarizing what was done. Update session_context.current_session.last_active. Write the updated record. Regenerate the TC HTML and dashboard."383- The main agent continues working without waiting.384385### Only Surface Questions When Genuinely Needed386- "This work doesn't match any active TC — should I create one?" (ask once per session, not per file)387- "TC-NNN looks complete — transition to implemented?" (at milestones only, don't nag)388- Never interrupt the user for routine TC bookkeeping.389390### At Session End391Before the session closes, spawn a final background Agent to write the handoff summary:392- progress_summary: what was accomplished393- next_steps: what still needs doing394- blockers: anything preventing progress395- key_context: important decisions, gotchas, patterns the next bot needs396- files_in_progress: which files are mid-edit397398### On Session Start3991. Check if `docs/TC/` exists in the project4002. If yes: read tc_registry.json, find in_progress/blocked TCs4013. Display handoff summary for any active TCs4024. Ask user if they want to resume403404---405406## Validation Rules (Always Enforced)4074081. **State machine**: only valid transitions allowed (see diagram above)4092. **Sequential IDs**: revision_history uses R1,R2,R3...; test_cases uses T1,T2,T3...4103. **Append-only history**: revision_history entries are never modified or deleted4114. **Approval consistency**: approved=true requires approved_by and approved_date4125. **TC ID format**: must match `TC-NNN-MM-DD-YY-slug` pattern4136. **Sub-TC ID format**: must match `TC-NNN.A` or `TC-NNN.A.N` pattern4147. **HTML escaping**: all user data is escaped before HTML rendering4158. **Atomic writes**: JSON files written to .tmp then renamed4169. **Registry stats**: recomputed on every registry write417418---419420## Python Generators421422Located at `{skills_library_path}/generators/`:423424```bash425# Generate individual TC HTML426python "generators/generate_tc_html.py" "<path_to_tc_record.json>" [--output <path>]427428# Generate dashboard429python "generators/generate_dashboard.py" "<path_to_tc_registry.json>" [--output <path>]430431# Validate a TC record432python "validators/validate_tc.py" "<path_to_tc_record.json>"433434# Validate the registry435python "validators/validate_tc.py" --registry "<path_to_tc_registry.json>"436437# Retroactive batch creation438python "generators/generate_retro_tcs.py" "<retro_changelog.json>" "<docs/TC/>"439440# Generate retro_changelog.json from git history441python "generators/generate_retro_from_git.py" [--repo-path .] [--output retro_changelog.json] [--project-name "Name"] [--since 2024-01-01] [--until 2026-04-05]442443# --- Git Integration ---444445# Link commit(s) to a TC record446python "generators/tc_git_link.py" "<tc_record.json>" [<sha>|HEAD] [--range A..B]447448# Show git integration status for all TCs (finds unlinked TCs + unlinked commits)449python "generators/tc_git_status.py" "<docs/TC/>" [--unlinked-only] [--show-candidates]450451# Auto-link HEAD to the single in-progress TC (used by PostToolUse hook)452python "generators/tc_git_autolink.py" --if-commit [<docs/TC/>]453454# Pre-commit advisory: warn if staged files aren't in any active TC (used by PreToolUse hook)455python "generators/tc_precommit_check.py" --if-commit [<docs/TC/>]456457# Registry 3-way merge driver (register with git config for conflict resolution)458python "generators/tc_registry_merge.py" <base> <ours> <theirs>459460# --- Online (opt-in) ---461462# Link a PR/MR to a TC record (requires gh or glab CLI)463python "generators/tc_pr_link.py" "<tc_record.json>" [<pr_number>]464465# Refresh PR metadata for all TCs with linked PRs466python "generators/tc_sync.py" "<docs/TC/>" [<tc_id>]467468# --- Session Lifecycle ---469470# Display session start report with active TC handoff data471python "generators/tc_session_start.py" "<docs/TC/>" [--json]472473# Archive current session and write handoff data474python "generators/tc_session_end.py" "<tc_record.json>" [--summary "..."] [--next "..."]475```476477All generators use Python stdlib only — no external dependencies.478All generators validate their input before producing output.479All HTML output is self-contained with inlined CSS (works from file:// URLs).480All HTML output is WCAG AA+ accessible with rem-based fonts, high contrast dark theme, skip links, and aria labels.