tcw-cli 2.1.2__tar.gz → 2.2.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (151) hide show
  1. {tcw_cli-2.1.2/tcw_cli.egg-info → tcw_cli-2.2.0}/PKG-INFO +182 -43
  2. {tcw_cli-2.1.2 → tcw_cli-2.2.0}/README.md +181 -42
  3. {tcw_cli-2.1.2 → tcw_cli-2.2.0}/pyproject.toml +1 -1
  4. tcw_cli-2.2.0/tcw/__init__.py +1 -0
  5. {tcw_cli-2.1.2 → tcw_cli-2.2.0}/tcw/capabilities/cli.py +12 -8
  6. {tcw_cli-2.1.2 → tcw_cli-2.2.0}/tcw/serve/__init__.py +41 -0
  7. tcw_cli-2.1.2/tcw/serve/dist/client/assets/index-Dz5B7M8G.js → tcw_cli-2.2.0/tcw/serve/dist/client/assets/index-CCjF_dHr.js +24 -24
  8. {tcw_cli-2.1.2 → tcw_cli-2.2.0}/tcw/serve/dist/client/index.html +1 -1
  9. {tcw_cli-2.1.2 → tcw_cli-2.2.0}/tcw/store/base.py +443 -7
  10. {tcw_cli-2.1.2 → tcw_cli-2.2.0}/tcw/store/fs.py +103 -8
  11. {tcw_cli-2.1.2 → tcw_cli-2.2.0}/tcw/store/project.py +1 -1
  12. {tcw_cli-2.1.2 → tcw_cli-2.2.0}/tcw/taxonomy/cli.py +9 -7
  13. {tcw_cli-2.1.2 → tcw_cli-2.2.0}/tcw/tracker/intake.py +87 -65
  14. {tcw_cli-2.1.2 → tcw_cli-2.2.0}/tcw/tracker/jira.py +30 -0
  15. tcw_cli-2.2.0/tcw/tracker/progress.py +163 -0
  16. tcw_cli-2.2.0/tcw/tracker/sync.py +410 -0
  17. {tcw_cli-2.1.2 → tcw_cli-2.2.0}/tcw/work/cli.py +600 -84
  18. {tcw_cli-2.1.2 → tcw_cli-2.2.0}/tcw/work/projection.py +63 -0
  19. {tcw_cli-2.1.2 → tcw_cli-2.2.0/tcw_cli.egg-info}/PKG-INFO +182 -43
  20. {tcw_cli-2.1.2 → tcw_cli-2.2.0}/tcw_cli.egg-info/SOURCES.txt +13 -1
  21. tcw_cli-2.2.0/tests/test_cli_help_coverage.py +55 -0
  22. tcw_cli-2.2.0/tests/test_configuration_text_home.py +61 -0
  23. {tcw_cli-2.1.2 → tcw_cli-2.2.0}/tests/test_documentation_config.py +2 -1
  24. {tcw_cli-2.1.2 → tcw_cli-2.2.0}/tests/test_documentation_sync_wiring.py +24 -24
  25. {tcw_cli-2.1.2 → tcw_cli-2.2.0}/tests/test_eval_fixture.py +1 -1
  26. {tcw_cli-2.1.2 → tcw_cli-2.2.0}/tests/test_eval_grading.py +51 -0
  27. {tcw_cli-2.1.2 → tcw_cli-2.2.0}/tests/test_plugin_manifests.py +1 -1
  28. {tcw_cli-2.1.2 → tcw_cli-2.2.0}/tests/test_repo_lifecycle.py +3 -1
  29. {tcw_cli-2.1.2 → tcw_cli-2.2.0}/tests/test_skill_lifecycle_parity.py +133 -56
  30. tcw_cli-2.2.0/tests/test_skill_path_pointers.py +25 -0
  31. {tcw_cli-2.1.2 → tcw_cli-2.2.0}/tests/test_tracker_binding.py +27 -6
  32. {tcw_cli-2.1.2 → tcw_cli-2.2.0}/tests/test_tracker_client.py +25 -0
  33. tcw_cli-2.2.0/tests/test_tracker_comment.py +550 -0
  34. tcw_cli-2.2.0/tests/test_tracker_help.py +88 -0
  35. {tcw_cli-2.1.2 → tcw_cli-2.2.0}/tests/test_tracker_import.py +63 -3
  36. tcw_cli-2.2.0/tests/test_tracker_inheritance.py +686 -0
  37. tcw_cli-2.2.0/tests/test_tracker_link.py +295 -0
  38. tcw_cli-2.2.0/tests/test_tracker_strict.py +714 -0
  39. tcw_cli-2.2.0/tests/test_tracker_surface.py +405 -0
  40. tcw_cli-2.2.0/tests/test_tracker_sync.py +965 -0
  41. tcw_cli-2.2.0/tests/test_tracker_sync_config.py +113 -0
  42. {tcw_cli-2.1.2 → tcw_cli-2.2.0}/tests/test_tracker_validate.py +7 -5
  43. tcw_cli-2.1.2/tcw/__init__.py +0 -1
  44. tcw_cli-2.1.2/tests/test_tracker_link.py +0 -192
  45. {tcw_cli-2.1.2 → tcw_cli-2.2.0}/LICENSE +0 -0
  46. {tcw_cli-2.1.2 → tcw_cli-2.2.0}/setup.cfg +0 -0
  47. {tcw_cli-2.1.2 → tcw_cli-2.2.0}/tcw/capabilities/__init__.py +0 -0
  48. {tcw_cli-2.1.2 → tcw_cli-2.2.0}/tcw/cli.py +0 -0
  49. {tcw_cli-2.1.2 → tcw_cli-2.2.0}/tcw/refs.py +0 -0
  50. {tcw_cli-2.1.2 → tcw_cli-2.2.0}/tcw/serve/dist/client/assets/index-CXNiOIeg.css +0 -0
  51. {tcw_cli-2.1.2 → tcw_cli-2.2.0}/tcw/serve/dist/client/theme-init.js +0 -0
  52. {tcw_cli-2.1.2 → tcw_cli-2.2.0}/tcw/serve/dist/server.cjs +0 -0
  53. {tcw_cli-2.1.2 → tcw_cli-2.2.0}/tcw/serve/runtime.py +0 -0
  54. {tcw_cli-2.1.2 → tcw_cli-2.2.0}/tcw/stdin.py +0 -0
  55. {tcw_cli-2.1.2 → tcw_cli-2.2.0}/tcw/store/__init__.py +0 -0
  56. {tcw_cli-2.1.2 → tcw_cli-2.2.0}/tcw/store/checkouts.py +0 -0
  57. {tcw_cli-2.1.2 → tcw_cli-2.2.0}/tcw/taxonomy/__init__.py +0 -0
  58. {tcw_cli-2.1.2 → tcw_cli-2.2.0}/tcw/tracker/__init__.py +0 -0
  59. {tcw_cli-2.1.2 → tcw_cli-2.2.0}/tcw/tracker/claim.py +0 -0
  60. {tcw_cli-2.1.2 → tcw_cli-2.2.0}/tcw/validate.py +0 -0
  61. {tcw_cli-2.1.2 → tcw_cli-2.2.0}/tcw/work/__init__.py +0 -0
  62. {tcw_cli-2.1.2 → tcw_cli-2.2.0}/tcw/work/generate.py +0 -0
  63. {tcw_cli-2.1.2 → tcw_cli-2.2.0}/tcw/work/hooks.py +0 -0
  64. {tcw_cli-2.1.2 → tcw_cli-2.2.0}/tcw/work/prompts/implement.md +0 -0
  65. {tcw_cli-2.1.2 → tcw_cli-2.2.0}/tcw/work/prompts/inbox.md +0 -0
  66. {tcw_cli-2.1.2 → tcw_cli-2.2.0}/tcw/work/prompts/plan.md +0 -0
  67. {tcw_cli-2.1.2 → tcw_cli-2.2.0}/tcw/work/prompts/postmortem.md +0 -0
  68. {tcw_cli-2.1.2 → tcw_cli-2.2.0}/tcw/work/prompts/request.md +0 -0
  69. {tcw_cli-2.1.2 → tcw_cli-2.2.0}/tcw/work/prompts/spec.md +0 -0
  70. {tcw_cli-2.1.2 → tcw_cli-2.2.0}/tcw/work/prompts/verify.md +0 -0
  71. {tcw_cli-2.1.2 → tcw_cli-2.2.0}/tcw/work/recursion.py +0 -0
  72. {tcw_cli-2.1.2 → tcw_cli-2.2.0}/tcw/work/resolve.py +0 -0
  73. {tcw_cli-2.1.2 → tcw_cli-2.2.0}/tcw/work/templates.py +0 -0
  74. {tcw_cli-2.1.2 → tcw_cli-2.2.0}/tcw_cli.egg-info/dependency_links.txt +0 -0
  75. {tcw_cli-2.1.2 → tcw_cli-2.2.0}/tcw_cli.egg-info/entry_points.txt +0 -0
  76. {tcw_cli-2.1.2 → tcw_cli-2.2.0}/tcw_cli.egg-info/requires.txt +0 -0
  77. {tcw_cli-2.1.2 → tcw_cli-2.2.0}/tcw_cli.egg-info/top_level.txt +0 -0
  78. {tcw_cli-2.1.2 → tcw_cli-2.2.0}/tests/test_body_prompt.py +0 -0
  79. {tcw_cli-2.1.2 → tcw_cli-2.2.0}/tests/test_capabilities.py +0 -0
  80. {tcw_cli-2.1.2 → tcw_cli-2.2.0}/tests/test_capabilities_federation.py +0 -0
  81. {tcw_cli-2.1.2 → tcw_cli-2.2.0}/tests/test_capabilities_reset.py +0 -0
  82. {tcw_cli-2.1.2 → tcw_cli-2.2.0}/tests/test_capabilities_rm.py +0 -0
  83. {tcw_cli-2.1.2 → tcw_cli-2.2.0}/tests/test_capabilities_sidecar.py +0 -0
  84. {tcw_cli-2.1.2 → tcw_cli-2.2.0}/tests/test_capability_ref_wording.py +0 -0
  85. {tcw_cli-2.1.2 → tcw_cli-2.2.0}/tests/test_committed_paths.py +0 -0
  86. {tcw_cli-2.1.2 → tcw_cli-2.2.0}/tests/test_cut_version.py +0 -0
  87. {tcw_cli-2.1.2 → tcw_cli-2.2.0}/tests/test_documentation_prompt.py +0 -0
  88. {tcw_cli-2.1.2 → tcw_cli-2.2.0}/tests/test_documented_cli_surface.py +0 -0
  89. {tcw_cli-2.1.2 → tcw_cli-2.2.0}/tests/test_environment_hardness.py +0 -0
  90. {tcw_cli-2.1.2 → tcw_cli-2.2.0}/tests/test_epic_completable.py +0 -0
  91. {tcw_cli-2.1.2 → tcw_cli-2.2.0}/tests/test_eval_coverage.py +0 -0
  92. {tcw_cli-2.1.2 → tcw_cli-2.2.0}/tests/test_eval_files_changed.py +0 -0
  93. {tcw_cli-2.1.2 → tcw_cli-2.2.0}/tests/test_eval_runner.py +0 -0
  94. {tcw_cli-2.1.2 → tcw_cli-2.2.0}/tests/test_external_work_store.py +0 -0
  95. {tcw_cli-2.1.2 → tcw_cli-2.2.0}/tests/test_falsification_rule.py +0 -0
  96. {tcw_cli-2.1.2 → tcw_cli-2.2.0}/tests/test_generate_hook.py +0 -0
  97. {tcw_cli-2.1.2 → tcw_cli-2.2.0}/tests/test_inbox_title.py +0 -0
  98. {tcw_cli-2.1.2 → tcw_cli-2.2.0}/tests/test_lifecycle_baseline.py +0 -0
  99. {tcw_cli-2.1.2 → tcw_cli-2.2.0}/tests/test_lifecycle_hooks.py +0 -0
  100. {tcw_cli-2.1.2 → tcw_cli-2.2.0}/tests/test_lifecycle_inert.py +0 -0
  101. {tcw_cli-2.1.2 → tcw_cli-2.2.0}/tests/test_lifecycle_policy.py +0 -0
  102. {tcw_cli-2.1.2 → tcw_cli-2.2.0}/tests/test_lifecycle_validation.py +0 -0
  103. {tcw_cli-2.1.2 → tcw_cli-2.2.0}/tests/test_multiproject.py +0 -0
  104. {tcw_cli-2.1.2 → tcw_cli-2.2.0}/tests/test_non_git_writes.py +0 -0
  105. {tcw_cli-2.1.2 → tcw_cli-2.2.0}/tests/test_project_overrides.py +0 -0
  106. {tcw_cli-2.1.2 → tcw_cli-2.2.0}/tests/test_project_registry.py +0 -0
  107. {tcw_cli-2.1.2 → tcw_cli-2.2.0}/tests/test_projection.py +0 -0
  108. {tcw_cli-2.1.2 → tcw_cli-2.2.0}/tests/test_prompt_fallback.py +0 -0
  109. {tcw_cli-2.1.2 → tcw_cli-2.2.0}/tests/test_qualified_ref.py +0 -0
  110. {tcw_cli-2.1.2 → tcw_cli-2.2.0}/tests/test_recursion.py +0 -0
  111. {tcw_cli-2.1.2 → tcw_cli-2.2.0}/tests/test_refs.py +0 -0
  112. {tcw_cli-2.1.2 → tcw_cli-2.2.0}/tests/test_remote_session_setup.py +0 -0
  113. {tcw_cli-2.1.2 → tcw_cli-2.2.0}/tests/test_resolve.py +0 -0
  114. {tcw_cli-2.1.2 → tcw_cli-2.2.0}/tests/test_retention.py +0 -0
  115. {tcw_cli-2.1.2 → tcw_cli-2.2.0}/tests/test_scaffold.py +0 -0
  116. {tcw_cli-2.1.2 → tcw_cli-2.2.0}/tests/test_serve.py +0 -0
  117. {tcw_cli-2.1.2 → tcw_cli-2.2.0}/tests/test_serve_descendants.py +0 -0
  118. {tcw_cli-2.1.2 → tcw_cli-2.2.0}/tests/test_serve_projection.py +0 -0
  119. {tcw_cli-2.1.2 → tcw_cli-2.2.0}/tests/test_serve_resolve.py +0 -0
  120. {tcw_cli-2.1.2 → tcw_cli-2.2.0}/tests/test_serve_runtime.py +0 -0
  121. {tcw_cli-2.1.2 → tcw_cli-2.2.0}/tests/test_serve_write.py +0 -0
  122. {tcw_cli-2.1.2 → tcw_cli-2.2.0}/tests/test_session_bootstrap.py +0 -0
  123. {tcw_cli-2.1.2 → tcw_cli-2.2.0}/tests/test_shipped_prompts.py +0 -0
  124. {tcw_cli-2.1.2 → tcw_cli-2.2.0}/tests/test_show_json.py +0 -0
  125. {tcw_cli-2.1.2 → tcw_cli-2.2.0}/tests/test_skill_flow.py +0 -0
  126. {tcw_cli-2.1.2 → tcw_cli-2.2.0}/tests/test_smoke.py +0 -0
  127. {tcw_cli-2.1.2 → tcw_cli-2.2.0}/tests/test_stage_verb.py +0 -0
  128. {tcw_cli-2.1.2 → tcw_cli-2.2.0}/tests/test_status_parity.py +0 -0
  129. {tcw_cli-2.1.2 → tcw_cli-2.2.0}/tests/test_stdin.py +0 -0
  130. {tcw_cli-2.1.2 → tcw_cli-2.2.0}/tests/test_stdin_cli.py +0 -0
  131. {tcw_cli-2.1.2 → tcw_cli-2.2.0}/tests/test_store_bounds.py +0 -0
  132. {tcw_cli-2.1.2 → tcw_cli-2.2.0}/tests/test_store_editor.py +0 -0
  133. {tcw_cli-2.1.2 → tcw_cli-2.2.0}/tests/test_store_nodes.py +0 -0
  134. {tcw_cli-2.1.2 → tcw_cli-2.2.0}/tests/test_store_provisioning.py +0 -0
  135. {tcw_cli-2.1.2 → tcw_cli-2.2.0}/tests/test_store_publication.py +0 -0
  136. {tcw_cli-2.1.2 → tcw_cli-2.2.0}/tests/test_subprocess_stdin.py +0 -0
  137. {tcw_cli-2.1.2 → tcw_cli-2.2.0}/tests/test_taxonomy.py +0 -0
  138. {tcw_cli-2.1.2 → tcw_cli-2.2.0}/tests/test_tombstone.py +0 -0
  139. {tcw_cli-2.1.2 → tcw_cli-2.2.0}/tests/test_tracker_absent.py +0 -0
  140. {tcw_cli-2.1.2 → tcw_cli-2.2.0}/tests/test_tracker_claim.py +0 -0
  141. {tcw_cli-2.1.2 → tcw_cli-2.2.0}/tests/test_tracker_claimability.py +0 -0
  142. {tcw_cli-2.1.2 → tcw_cli-2.2.0}/tests/test_tracker_cli.py +0 -0
  143. {tcw_cli-2.1.2 → tcw_cli-2.2.0}/tests/test_tracker_config.py +0 -0
  144. {tcw_cli-2.1.2 → tcw_cli-2.2.0}/tests/test_tracker_replay.py +0 -0
  145. {tcw_cli-2.1.2 → tcw_cli-2.2.0}/tests/test_unpushed_version_script.py +0 -0
  146. {tcw_cli-2.1.2 → tcw_cli-2.2.0}/tests/test_validate.py +0 -0
  147. {tcw_cli-2.1.2 → tcw_cli-2.2.0}/tests/test_validate_target.py +0 -0
  148. {tcw_cli-2.1.2 → tcw_cli-2.2.0}/tests/test_work.py +0 -0
  149. {tcw_cli-2.1.2 → tcw_cli-2.2.0}/tests/test_work_autocommit.py +0 -0
  150. {tcw_cli-2.1.2 → tcw_cli-2.2.0}/tests/test_work_review.py +0 -0
  151. {tcw_cli-2.1.2 → tcw_cli-2.2.0}/tests/test_work_tags.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: tcw-cli
3
- Version: 2.1.2
3
+ Version: 2.2.0
4
4
  Summary: Taxonomy · Capabilities · Work — a storage-abstracted framework for describing and evolving a software project.
5
5
  License: Apache License
6
6
  Version 2.0, January 2004
@@ -247,7 +247,7 @@ other's content.
247
247
  - [Documentation](#documentation)
248
248
  - [Skills — the judgment layer](#skills--the-judgment-layer)
249
249
  - [Reading a lifecycle stage](#reading-a-lifecycle-stage)
250
- - [Review agents and slash commands](#review-agents-and-slash-commands)
250
+ - [Review agents and command skills](#review-agents-and-command-skills)
251
251
  - [Status](#status)
252
252
  - [Further reading](#further-reading)
253
253
 
@@ -430,20 +430,20 @@ by installing `tcw-cli` from PyPI with `pipx`, so one installed mid-session
430
430
  cannot run until the next one begins. That first session needs network access. It
431
431
  installs over an existing `pipx install tcw-cli` rather than beside it, and
432
432
  leaves a development checkout (`pip install -e .`) alone. If `tcw` goes missing
433
- anyway, `pipx install tcw-cli` is the whole fix — the **`tcw-plugin`** skill
433
+ anyway, `pipx install tcw-cli` is the whole fix — the **`tcw-setup`** skill
434
434
  carries the cases where it is not.
435
435
 
436
- In **Codex** (skills only, no slash commands):
436
+ In **Codex**:
437
437
 
438
438
  ```bash
439
439
  codex plugin marketplace add brocef/TCW --ref main
440
440
  codex plugin add tcw@tcw
441
441
  ```
442
442
 
443
- Codex has no session-start hook, so ask the agent to run the **`tcw-plugin`**
444
- setup — it runs the same install script Claude runs automatically.
443
+ Codex has no session-start hook, so ask the agent to run the **`tcw-setup`**
444
+ skill — it runs the same install script Claude runs automatically.
445
445
 
446
- The plugin ships the agent skills, slash commands, and read-only review agents
446
+ The plugin ships the agent skills, command skills, and read-only review agents
447
447
  listed under [Skills](#skills--the-judgment-layer).
448
448
 
449
449
  ### As a Python package
@@ -565,8 +565,10 @@ projects. Each component group also has its own `init`: `tcw taxonomy init`,
565
565
  `tcw capabilities init`, `tcw work init`.
566
566
 
567
567
  To bootstrap a taxonomy or capabilities ledger on a project that already has a
568
- codebase, run `/tcw-taxonomy-init` or `/tcw-capabilities-init` — the assistant
569
- studies your code, proposes a first draft, refines it with you, and writes it.
568
+ codebase, ask for the `tcw-setup` skill — the assistant studies your code,
569
+ proposes a first draft, refines it with you, and writes it. To change a working
570
+ project's configuration afterwards — documentation entries, lifecycle bindings,
571
+ a tracker, where stores live — ask for the `tcw-configure` skill.
570
572
 
571
573
  ---
572
574
 
@@ -579,8 +581,9 @@ a work item.
579
581
  tcw work tracker list # tickets the configured query selects
580
582
  tcw work tracker show ENG-482 # one ticket, and whether it is yours to take
581
583
  tcw work tracker import ENG-482 # take the ticket and get a work item for it
582
- tcw work tracker link <slug> ENG-482 # take it for an item you already have
584
+ tcw work tracker link <slug> ENG-482 # record that an item and a ticket are the same work
583
585
  tcw work tracker unlink <slug> --reason "wrong ticket"
586
+ tcw work tracker sync --all # retry tickets that did not follow their items
584
587
  ```
585
588
 
586
589
  Configuration goes in the node's `tcw-config.yaml`:
@@ -596,6 +599,11 @@ work:
596
599
  token-env: TCW_JIRA_API_TOKEN
597
600
  transitions:
598
601
  claim: Start Progress
602
+ statuses: # optional: where a bound ticket goes as its item moves
603
+ active: In Progress
604
+ review: In Review
605
+ completed: Done
606
+ discarded: Won't Do
599
607
  timeout-seconds: 15 # optional
600
608
  ```
601
609
 
@@ -603,6 +611,32 @@ work:
603
611
  environment variables; TCW reads them at the moment it makes a request, so a token
604
612
  cannot be committed by accident.
605
613
 
614
+ **Write the shared settings once.** In a workspace of connected nodes, a node's
615
+ `tracker` block takes any setting it leaves out from its parent nodes, all the way
616
+ up. So the site, credentials and claim transition can live in the workspace root,
617
+ and each package writes only the tickets it wants to see:
618
+
619
+ ```yaml
620
+ # packages/api/tcw-config.yaml
621
+ work:
622
+ tracker:
623
+ candidate-query: project = EX AND component = api AND status = "To Do"
624
+ ```
625
+
626
+ The nearest file wins each setting, and `credentials` and `transitions` merge
627
+ setting by setting too. A node with no `tracker` block of its own has no tracker,
628
+ whatever its parents say. Two rules keep this safe:
629
+
630
+ - **`credentials` must sit beside `base-url`.** A node that sets its own `base-url`
631
+ must also set both of its own `credentials` keys, even if the address is the same
632
+ as its parent's, so a token is never sent to a site chosen in a different file.
633
+ - **A node with its own board is checked like any tracking node.** If it holds the
634
+ shared settings, it needs a `candidate-query` of its own. Keeping shared settings
635
+ in a node without a board avoids that.
636
+
637
+ A mistake in a parent's settings is reported by `tcw validate` in every node that
638
+ inherits it, naming the parent's file.
639
+
606
640
  `tracker show` reports two different things, and the distinction matters:
607
641
 
608
642
  - **claimable** — whether this ticket currently offers the transition you
@@ -625,15 +659,116 @@ ticket's text goes into the item as its raw input, with a link back, and the ite
625
659
  request still gets written the usual way. A ticket assigned to someone else is
626
660
  refused, and so is one that is already closed.
627
661
 
628
- Running `import` again for the same ticket gives you the same item rather than a
629
- second one, and if the first run took the ticket but stopped before creating the
662
+ Running `import` again for the same ticket in the same node gives you the same item
663
+ rather than a second one, and if the first run took the ticket but stopped before creating the
630
664
  item, the second run finishes the job. One ticket can deliberately become several
631
- items with `--part api`, `--part web`, and so on. `unlink` removes a wrong binding
632
- and keeps a record of it with your reason; it never changes the ticket in Jira.
633
-
634
- Two limits to know. On a workflow that lets anyone start a ticket from any status,
635
- two people can both take the same ticket, and TCW does not stop that. And two runs
636
- by the same Jira account at the same moment can both create an item.
665
+ items with `--part api`, `--part web`, and so on.
666
+
667
+ **Recording that a ticket and an item are the same work.** `tracker link` is the
668
+ other half, and it does only that: it writes the cross-reference down and leaves
669
+ Jira alone. The ticket keeps its status and whoever holds it — you can link a ticket
670
+ somebody else is assigned, because writing a note about a ticket takes it from
671
+ nobody. On your side nothing but the binding is written, so the item keeps its
672
+ status, its owner and its documents. Any item can be linked, a finished one
673
+ included, which is how work that is already done gets tied to the ticket that
674
+ tracked it; the same goes for `unlink`, so a binding pointed at the wrong ticket is
675
+ repairable wherever you find it. A finished item's folder is kept out of git by
676
+ default, so a binding on one stays on your machine along with the rest of that
677
+ item. `unlink` keeps a record of what was bound and your
678
+ reason, and like `link` it never changes the ticket in Jira.
679
+
680
+ **Seeing which ticket an item answers.** A bound item says so wherever you read it:
681
+ `tcw work show` adds a `tracker:` line with the ticket, the provider, the part and
682
+ the ticket's link; its row on `tcw work list` ends with the ticket key, and notes the part and anything
683
+ not yet sent to the ticket; `tcw work show
684
+ --json` carries it as `tracker`; and `tcw serve`'s item page shows the ticket as a
685
+ link. What you see is what the binding records, not what Jira says right now, so
686
+ none of it needs the tracker configured or reachable. A binding file that cannot be
687
+ read is reported in the same places instead of breaking the board.
688
+
689
+ **Tickets follow their items.** `link` claims nothing, so `tcw work start` does:
690
+ starting a bound item claims its ticket by the same rules `import` uses. After that,
691
+ `submit`, `rework`, `complete` and discarding move the ticket to the status you map
692
+ the item's new status to under `statuses` (`discarded` can name a status per
693
+ resolution, such as `duplicate: Duplicate`); a status you leave out sends nothing,
694
+ and `active` is required once you map any other. `import` on a ticket that is only
695
+ linked still refuses rather than claiming it.
696
+
697
+ TCW moves a ticket only when it is assigned to you and is still where the item's
698
+ previous status left it. A ticket someone else holds, one moved on in Jira, or one
699
+ whose workflow does not offer a single transition to the mapped status is left
700
+ alone. Your local move always happens and is committed first; when the ticket does
701
+ not follow, the command exits 1, says the item moved, and records why — *pending*
702
+ when Jira could not be reached or your credentials are missing, *conflicting* when
703
+ Jira's answer stopped it. `tcw work show` and `tcw work list` show that state, and
704
+ `tcw work tracker sync <slug>` (or `--all`) retries it once the cause is fixed. `sync`
705
+ acts only on items you started, because it acts as whoever runs it. A ticket that
706
+ followed first time leaves no record and no change in your repository.
707
+
708
+ Two things are not caught: a move made in `tcw serve`, and a command interrupted
709
+ between its commit and its call to Jira, leave no record, so the board shows them as
710
+ in step; `sync <slug>` checks such an item but will not move its ticket. And a
711
+ binding whose ticket link is on a different Jira site from the one configured is
712
+ never written through — `import` and `link` refuse it and name the item.
713
+
714
+ Five limits to know. A ticket bound to several parts moves only when the last open
715
+ part here moves; parts in other nodes are not seen. On a workflow that lets anyone start a ticket from any status,
716
+ two people can both take the same ticket, and TCW does not stop that outside strict
717
+ mode (below). Two runs by the
718
+ same Jira account at the same moment can both create an item. Each node keeps its
719
+ own bindings: importing one ticket in two nodes of a workspace, even nodes sharing
720
+ inherited settings, gives two items, one in each. And a ticket held by a finished
721
+ item can be bound to a second item, open or finished, with no warning — a discarded
722
+ item's ticket is meant to be available again, and TCW cannot tell that case from the
723
+ other.
724
+
725
+ **Comments on the ticket.** Set `comments: true` in the `tracker` block and each
726
+ move also leaves a short comment on the ticket, such as
727
+ `TCW: "Checkout page" (part api) went to review.`, for anyone who follows the work
728
+ in Jira rather than in the repository. A `link` template adds a link, for example
729
+ `link: https://tcw.example.com/work/{slug}` for a team that hosts `tcw serve`; the
730
+ only placeholders are `{project}` and `{slug}`. Nothing from `spec.md`, `plan.md` or
731
+ the other lifecycle documents is ever copied. A comment is posted only while the
732
+ ticket is assigned to you, and a ticket held by someone else gets none. When a
733
+ comment cannot be posted, the command exits 1, `show` prints a `tracker comment:`
734
+ line, and `tcw work tracker sync` sends it later. Before resending, it looks for the
735
+ comment on the ticket, so a post that landed without an answer is not repeated.
736
+ Limits: a newer move's comment replaces one still waiting; two runs at once, or an
737
+ edited or deleted comment, can still give a repeat; moves in `tcw serve` post
738
+ nothing. On a Jira Service Management project a comment may be visible to
739
+ customers, so leave comments off there unless item titles may be seen. Every copy
740
+ of `tcw` on the project must understand these keys before you set them: an older
741
+ one treats the whole `tracker` block as broken.
742
+
743
+ **Strict mode: no work without a ticket.** Set `strict: true` in the `tracker` block
744
+ when every piece of work must come from a ticket you have claimed. Then:
745
+
746
+ - `tcw work new` and `tcw work inbox accept` refuse and point you at
747
+ `tcw work tracker import <ticket>`. `new --epic` is allowed; epics are never gated.
748
+ - `tcw work start` refuses an item with no ticket. For a bound item it claims the
749
+ ticket *first*, and starts the item only if the claim worked.
750
+ - `submit`, `rework` and completing as `done` read the ticket first and refuse unless
751
+ it is assigned to you and is where the item's last step left it. A `--worktree`
752
+ item is checked before anything is merged.
753
+ - A claim on a workflow that would let a second person claim the same ticket is
754
+ refused, by `start` and by `import`; the ticket is left claimed for you to release.
755
+ - An epic can be created and started, since it only groups work, but not with
756
+ `--worktree`.
757
+ - A ticket shared by several parts is recognised only from the parts' items in
758
+ this checkout. If the part that held the ticket back was completed elsewhere, or
759
+ was not kept (`work.retain`), the last part's `complete` is refused; put the
760
+ ticket in the status the message names, or discard.
761
+ - Discarding is always allowed. `drop` refuses an item that was ever bound — discard
762
+ it instead, so the record stays.
763
+ - `tcw serve` refuses the same changes, since it cannot check a ticket, and names the
764
+ command to use.
765
+
766
+ A refusal changes nothing in your project and says what to fix; a `start` or `import`
767
+ refused after claiming leaves the ticket claimed. There is no flag to get past it;
768
+ `--force` and `--take-over` do not. Strict mode needs Jira: while it cannot be
769
+ reached, gated commands refuse. It also needs `statuses.active`,
770
+ `statuses.completed` and a `statuses.discarded` covering every discard reason, which
771
+ `tcw validate` checks. To turn it off, set `strict: false` or remove the key.
637
772
 
638
773
  Two guarantees worth stating plainly. A project with no `tracker` block behaves
639
774
  exactly as before, with no new required setting and no network access. And
@@ -663,48 +798,52 @@ Every command group also has `--help`, and a `check` that validates its tree.
663
798
  ## Skills — the judgment layer
664
799
 
665
800
  The CLI is the _mechanism_. Fifteen skills in [`skills/`](skills/) supply the
666
- _judgment_ that drives it — the parts a deterministic tool cannot decide. Nine
667
- carry a distinct procedure; the other six all compose one lifecycle stage and
668
- are listed together at the end.
801
+ _judgment_ that drives it — the parts a deterministic tool cannot decide. They
802
+ come in three groups, told apart by name: eight core skills (seven in the table
803
+ below, and `tcw-work-stage`, which composes a lifecycle stage and is described
804
+ after it), four `tcw-commands-*` skills for the everyday workflow, and three
805
+ optional `tcw-extras-*` skills.
669
806
 
670
807
  | Skill | What it does |
671
808
  | ---------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |
672
809
  | [`tcw-work`](skills/tcw-work/SKILL.md) | Plans a request through spec and plan, drives implementation and verification, triages the inbox, runs the lifecycle, decomposes epics, searches the board |
673
810
  | [`tcw-capabilities`](skills/tcw-capabilities/SKILL.md) | The capability-delta planning check, contradiction detection, and the ledger flip at completion |
674
- | [`tcw-taxonomy`](skills/tcw-taxonomy/SKILL.md) | Declaring vocabulary and features, linking them, and federating shared vocabulary |
675
- | [`tcw-plugin`](skills/tcw-plugin/SKILL.md) | Installs the CLI from PyPI, and maps the other skills |
676
- | [`tcw-report`](skills/tcw-report/SKILL.md) | Reporting a `tcw` bug or suggestion upstream to [this project's issues](https://github.com/brocef/TCW/issues) |
677
- | [`tcw-triage-issues`](skills/tcw-triage-issues/SKILL.md) | Sweeps **your** project's GitHub issues and turns the ones worth doing into work items |
811
+ | [`tcw-taxonomy`](skills/tcw-taxonomy/SKILL.md) | Declaring vocabulary and features, linking them, and resolving vocabulary inherited from another project |
812
+ | [`tcw-setup`](skills/tcw-setup/SKILL.md) | Gets TCW working: installs or repairs the CLI, sets up a repository, starts a taxonomy or capabilities ledger |
813
+ | [`tcw-configure`](skills/tcw-configure/SKILL.md) | Changes a project's configuration: lifecycle bindings, Definition of Done, documentation entries, tracker, stores, connected and inherited projects |
678
814
  | [`documentation-sync`](skills/documentation-sync/SKILL.md) | Keeps README, changelogs, release notes, and driving skills moving with the code that changes them |
679
815
  | [`tcw-post-mortem`](skills/tcw-post-mortem/SKILL.md) | Finds which lifecycle stage could first have caught a problem, once one has surfaced |
680
- | [`autonomous-work`](skills/autonomous-work/SKILL.md) | Drives work items to completion unattended, consulting two read-only advisors wherever the lifecycle would ask you |
816
+
817
+ **Extras.** `tcw-extras-*` skills are optional, built for one way of working, and not needed to use TCW.
818
+
819
+ | Skill | What it does |
820
+ | ----- | ------------ |
821
+ | [`tcw-extras-autonomous-work`](skills/tcw-extras-autonomous-work/SKILL.md) | Drives work items to completion unattended, consulting two read-only advisors wherever the lifecycle would ask you |
822
+ | [`tcw-extras-triage-issues`](skills/tcw-extras-triage-issues/SKILL.md) | Sweeps **your** project's GitHub issues and turns the ones worth doing into work items |
823
+ | [`tcw-extras-report`](skills/tcw-extras-report/SKILL.md) | Reporting a `tcw` bug or suggestion upstream to [this project's issues](https://github.com/brocef/TCW/issues) |
681
824
 
682
825
  They name `tcw` commands and never reimplement tool logic: mechanism stays in the
683
826
  binary, judgment stays in the skills.
684
827
 
685
828
  ### Reading a lifecycle stage
686
829
 
687
- Six more skills do one job between them: hand you a stage's own working document
688
- and the instructions your project resolves for it, as a single read rather than a
689
- file you open and a command you run separately. They only read — `tcw work stage
690
- gate` is still what refuses.
691
-
692
- [`tcw-work-stage`](skills/tcw-work-stage/SKILL.md) is the general one and takes
693
- the stage id, so it reaches all seven stages including `inbox` and `postmortem`.
694
- The other five bake their stage in and ask only for the work item, which is
695
- optional: `tcw-work-stage-request`, `tcw-work-stage-spec`,
696
- `tcw-work-stage-plan`, `tcw-work-stage-implement`, `tcw-work-stage-verify`.
830
+ One more skill, [`tcw-work-stage`](skills/tcw-work-stage/SKILL.md), hands you a
831
+ stage's own working document and the instructions your project resolves for it,
832
+ as a single read rather than a file you open and a command you run separately.
833
+ It takes the stage id and the work item, so it reaches all seven stages
834
+ including `inbox` and `postmortem`, under Claude and Codex alike. It only reads
835
+ — `tcw work stage gate` is still what refuses.
697
836
 
698
- ### Review agents and slash commands
837
+ ### Review agents and command skills
699
838
 
700
839
  Three read-only review agents ship alongside them — `tcw-verifier`,
701
840
  `tcw-backlog-auditor`, and `tcw-post-mortem`, which accelerates the skill of the
702
- same name — plus slash commands for each skill's main procedure
703
- (`/tcw-plan-work`, `/tcw-drive-work-to-completion`, `/tcw-verify-work`,
704
- `/tcw-process-inbox`, `/tcw-work-search`, `/tcw-triage-issues`,
705
- `/tcw-audit-work-backlog`, `/tcw-consolidate-plans`, `/tcw-taxonomy-init`,
706
- `/tcw-capabilities-init`, `/tcw-docs-sync-setup`, `/tcw-cut-version`,
707
- `/tcw-post-mortem`).
841
+ same name. Four command skills carry the everyday workflows:
842
+ `tcw-commands-plan-work`, `tcw-commands-drive-work-to-completion`,
843
+ `tcw-commands-verify-work` and `tcw-commands-process-inbox`. The three extras,
844
+ `tcw-extras-autonomous-work`, `tcw-extras-triage-issues` and
845
+ `tcw-extras-report`, are optional. Under Claude and Codex alike, every entry
846
+ point is a skill.
708
847
 
709
848
  ---
710
849
 
@@ -31,7 +31,7 @@ other's content.
31
31
  - [Documentation](#documentation)
32
32
  - [Skills — the judgment layer](#skills--the-judgment-layer)
33
33
  - [Reading a lifecycle stage](#reading-a-lifecycle-stage)
34
- - [Review agents and slash commands](#review-agents-and-slash-commands)
34
+ - [Review agents and command skills](#review-agents-and-command-skills)
35
35
  - [Status](#status)
36
36
  - [Further reading](#further-reading)
37
37
 
@@ -214,20 +214,20 @@ by installing `tcw-cli` from PyPI with `pipx`, so one installed mid-session
214
214
  cannot run until the next one begins. That first session needs network access. It
215
215
  installs over an existing `pipx install tcw-cli` rather than beside it, and
216
216
  leaves a development checkout (`pip install -e .`) alone. If `tcw` goes missing
217
- anyway, `pipx install tcw-cli` is the whole fix — the **`tcw-plugin`** skill
217
+ anyway, `pipx install tcw-cli` is the whole fix — the **`tcw-setup`** skill
218
218
  carries the cases where it is not.
219
219
 
220
- In **Codex** (skills only, no slash commands):
220
+ In **Codex**:
221
221
 
222
222
  ```bash
223
223
  codex plugin marketplace add brocef/TCW --ref main
224
224
  codex plugin add tcw@tcw
225
225
  ```
226
226
 
227
- Codex has no session-start hook, so ask the agent to run the **`tcw-plugin`**
228
- setup — it runs the same install script Claude runs automatically.
227
+ Codex has no session-start hook, so ask the agent to run the **`tcw-setup`**
228
+ skill — it runs the same install script Claude runs automatically.
229
229
 
230
- The plugin ships the agent skills, slash commands, and read-only review agents
230
+ The plugin ships the agent skills, command skills, and read-only review agents
231
231
  listed under [Skills](#skills--the-judgment-layer).
232
232
 
233
233
  ### As a Python package
@@ -349,8 +349,10 @@ projects. Each component group also has its own `init`: `tcw taxonomy init`,
349
349
  `tcw capabilities init`, `tcw work init`.
350
350
 
351
351
  To bootstrap a taxonomy or capabilities ledger on a project that already has a
352
- codebase, run `/tcw-taxonomy-init` or `/tcw-capabilities-init` — the assistant
353
- studies your code, proposes a first draft, refines it with you, and writes it.
352
+ codebase, ask for the `tcw-setup` skill — the assistant studies your code,
353
+ proposes a first draft, refines it with you, and writes it. To change a working
354
+ project's configuration afterwards — documentation entries, lifecycle bindings,
355
+ a tracker, where stores live — ask for the `tcw-configure` skill.
354
356
 
355
357
  ---
356
358
 
@@ -363,8 +365,9 @@ a work item.
363
365
  tcw work tracker list # tickets the configured query selects
364
366
  tcw work tracker show ENG-482 # one ticket, and whether it is yours to take
365
367
  tcw work tracker import ENG-482 # take the ticket and get a work item for it
366
- tcw work tracker link <slug> ENG-482 # take it for an item you already have
368
+ tcw work tracker link <slug> ENG-482 # record that an item and a ticket are the same work
367
369
  tcw work tracker unlink <slug> --reason "wrong ticket"
370
+ tcw work tracker sync --all # retry tickets that did not follow their items
368
371
  ```
369
372
 
370
373
  Configuration goes in the node's `tcw-config.yaml`:
@@ -380,6 +383,11 @@ work:
380
383
  token-env: TCW_JIRA_API_TOKEN
381
384
  transitions:
382
385
  claim: Start Progress
386
+ statuses: # optional: where a bound ticket goes as its item moves
387
+ active: In Progress
388
+ review: In Review
389
+ completed: Done
390
+ discarded: Won't Do
383
391
  timeout-seconds: 15 # optional
384
392
  ```
385
393
 
@@ -387,6 +395,32 @@ work:
387
395
  environment variables; TCW reads them at the moment it makes a request, so a token
388
396
  cannot be committed by accident.
389
397
 
398
+ **Write the shared settings once.** In a workspace of connected nodes, a node's
399
+ `tracker` block takes any setting it leaves out from its parent nodes, all the way
400
+ up. So the site, credentials and claim transition can live in the workspace root,
401
+ and each package writes only the tickets it wants to see:
402
+
403
+ ```yaml
404
+ # packages/api/tcw-config.yaml
405
+ work:
406
+ tracker:
407
+ candidate-query: project = EX AND component = api AND status = "To Do"
408
+ ```
409
+
410
+ The nearest file wins each setting, and `credentials` and `transitions` merge
411
+ setting by setting too. A node with no `tracker` block of its own has no tracker,
412
+ whatever its parents say. Two rules keep this safe:
413
+
414
+ - **`credentials` must sit beside `base-url`.** A node that sets its own `base-url`
415
+ must also set both of its own `credentials` keys, even if the address is the same
416
+ as its parent's, so a token is never sent to a site chosen in a different file.
417
+ - **A node with its own board is checked like any tracking node.** If it holds the
418
+ shared settings, it needs a `candidate-query` of its own. Keeping shared settings
419
+ in a node without a board avoids that.
420
+
421
+ A mistake in a parent's settings is reported by `tcw validate` in every node that
422
+ inherits it, naming the parent's file.
423
+
390
424
  `tracker show` reports two different things, and the distinction matters:
391
425
 
392
426
  - **claimable** — whether this ticket currently offers the transition you
@@ -409,15 +443,116 @@ ticket's text goes into the item as its raw input, with a link back, and the ite
409
443
  request still gets written the usual way. A ticket assigned to someone else is
410
444
  refused, and so is one that is already closed.
411
445
 
412
- Running `import` again for the same ticket gives you the same item rather than a
413
- second one, and if the first run took the ticket but stopped before creating the
446
+ Running `import` again for the same ticket in the same node gives you the same item
447
+ rather than a second one, and if the first run took the ticket but stopped before creating the
414
448
  item, the second run finishes the job. One ticket can deliberately become several
415
- items with `--part api`, `--part web`, and so on. `unlink` removes a wrong binding
416
- and keeps a record of it with your reason; it never changes the ticket in Jira.
417
-
418
- Two limits to know. On a workflow that lets anyone start a ticket from any status,
419
- two people can both take the same ticket, and TCW does not stop that. And two runs
420
- by the same Jira account at the same moment can both create an item.
449
+ items with `--part api`, `--part web`, and so on.
450
+
451
+ **Recording that a ticket and an item are the same work.** `tracker link` is the
452
+ other half, and it does only that: it writes the cross-reference down and leaves
453
+ Jira alone. The ticket keeps its status and whoever holds it — you can link a ticket
454
+ somebody else is assigned, because writing a note about a ticket takes it from
455
+ nobody. On your side nothing but the binding is written, so the item keeps its
456
+ status, its owner and its documents. Any item can be linked, a finished one
457
+ included, which is how work that is already done gets tied to the ticket that
458
+ tracked it; the same goes for `unlink`, so a binding pointed at the wrong ticket is
459
+ repairable wherever you find it. A finished item's folder is kept out of git by
460
+ default, so a binding on one stays on your machine along with the rest of that
461
+ item. `unlink` keeps a record of what was bound and your
462
+ reason, and like `link` it never changes the ticket in Jira.
463
+
464
+ **Seeing which ticket an item answers.** A bound item says so wherever you read it:
465
+ `tcw work show` adds a `tracker:` line with the ticket, the provider, the part and
466
+ the ticket's link; its row on `tcw work list` ends with the ticket key, and notes the part and anything
467
+ not yet sent to the ticket; `tcw work show
468
+ --json` carries it as `tracker`; and `tcw serve`'s item page shows the ticket as a
469
+ link. What you see is what the binding records, not what Jira says right now, so
470
+ none of it needs the tracker configured or reachable. A binding file that cannot be
471
+ read is reported in the same places instead of breaking the board.
472
+
473
+ **Tickets follow their items.** `link` claims nothing, so `tcw work start` does:
474
+ starting a bound item claims its ticket by the same rules `import` uses. After that,
475
+ `submit`, `rework`, `complete` and discarding move the ticket to the status you map
476
+ the item's new status to under `statuses` (`discarded` can name a status per
477
+ resolution, such as `duplicate: Duplicate`); a status you leave out sends nothing,
478
+ and `active` is required once you map any other. `import` on a ticket that is only
479
+ linked still refuses rather than claiming it.
480
+
481
+ TCW moves a ticket only when it is assigned to you and is still where the item's
482
+ previous status left it. A ticket someone else holds, one moved on in Jira, or one
483
+ whose workflow does not offer a single transition to the mapped status is left
484
+ alone. Your local move always happens and is committed first; when the ticket does
485
+ not follow, the command exits 1, says the item moved, and records why — *pending*
486
+ when Jira could not be reached or your credentials are missing, *conflicting* when
487
+ Jira's answer stopped it. `tcw work show` and `tcw work list` show that state, and
488
+ `tcw work tracker sync <slug>` (or `--all`) retries it once the cause is fixed. `sync`
489
+ acts only on items you started, because it acts as whoever runs it. A ticket that
490
+ followed first time leaves no record and no change in your repository.
491
+
492
+ Two things are not caught: a move made in `tcw serve`, and a command interrupted
493
+ between its commit and its call to Jira, leave no record, so the board shows them as
494
+ in step; `sync <slug>` checks such an item but will not move its ticket. And a
495
+ binding whose ticket link is on a different Jira site from the one configured is
496
+ never written through — `import` and `link` refuse it and name the item.
497
+
498
+ Five limits to know. A ticket bound to several parts moves only when the last open
499
+ part here moves; parts in other nodes are not seen. On a workflow that lets anyone start a ticket from any status,
500
+ two people can both take the same ticket, and TCW does not stop that outside strict
501
+ mode (below). Two runs by the
502
+ same Jira account at the same moment can both create an item. Each node keeps its
503
+ own bindings: importing one ticket in two nodes of a workspace, even nodes sharing
504
+ inherited settings, gives two items, one in each. And a ticket held by a finished
505
+ item can be bound to a second item, open or finished, with no warning — a discarded
506
+ item's ticket is meant to be available again, and TCW cannot tell that case from the
507
+ other.
508
+
509
+ **Comments on the ticket.** Set `comments: true` in the `tracker` block and each
510
+ move also leaves a short comment on the ticket, such as
511
+ `TCW: "Checkout page" (part api) went to review.`, for anyone who follows the work
512
+ in Jira rather than in the repository. A `link` template adds a link, for example
513
+ `link: https://tcw.example.com/work/{slug}` for a team that hosts `tcw serve`; the
514
+ only placeholders are `{project}` and `{slug}`. Nothing from `spec.md`, `plan.md` or
515
+ the other lifecycle documents is ever copied. A comment is posted only while the
516
+ ticket is assigned to you, and a ticket held by someone else gets none. When a
517
+ comment cannot be posted, the command exits 1, `show` prints a `tracker comment:`
518
+ line, and `tcw work tracker sync` sends it later. Before resending, it looks for the
519
+ comment on the ticket, so a post that landed without an answer is not repeated.
520
+ Limits: a newer move's comment replaces one still waiting; two runs at once, or an
521
+ edited or deleted comment, can still give a repeat; moves in `tcw serve` post
522
+ nothing. On a Jira Service Management project a comment may be visible to
523
+ customers, so leave comments off there unless item titles may be seen. Every copy
524
+ of `tcw` on the project must understand these keys before you set them: an older
525
+ one treats the whole `tracker` block as broken.
526
+
527
+ **Strict mode: no work without a ticket.** Set `strict: true` in the `tracker` block
528
+ when every piece of work must come from a ticket you have claimed. Then:
529
+
530
+ - `tcw work new` and `tcw work inbox accept` refuse and point you at
531
+ `tcw work tracker import <ticket>`. `new --epic` is allowed; epics are never gated.
532
+ - `tcw work start` refuses an item with no ticket. For a bound item it claims the
533
+ ticket *first*, and starts the item only if the claim worked.
534
+ - `submit`, `rework` and completing as `done` read the ticket first and refuse unless
535
+ it is assigned to you and is where the item's last step left it. A `--worktree`
536
+ item is checked before anything is merged.
537
+ - A claim on a workflow that would let a second person claim the same ticket is
538
+ refused, by `start` and by `import`; the ticket is left claimed for you to release.
539
+ - An epic can be created and started, since it only groups work, but not with
540
+ `--worktree`.
541
+ - A ticket shared by several parts is recognised only from the parts' items in
542
+ this checkout. If the part that held the ticket back was completed elsewhere, or
543
+ was not kept (`work.retain`), the last part's `complete` is refused; put the
544
+ ticket in the status the message names, or discard.
545
+ - Discarding is always allowed. `drop` refuses an item that was ever bound — discard
546
+ it instead, so the record stays.
547
+ - `tcw serve` refuses the same changes, since it cannot check a ticket, and names the
548
+ command to use.
549
+
550
+ A refusal changes nothing in your project and says what to fix; a `start` or `import`
551
+ refused after claiming leaves the ticket claimed. There is no flag to get past it;
552
+ `--force` and `--take-over` do not. Strict mode needs Jira: while it cannot be
553
+ reached, gated commands refuse. It also needs `statuses.active`,
554
+ `statuses.completed` and a `statuses.discarded` covering every discard reason, which
555
+ `tcw validate` checks. To turn it off, set `strict: false` or remove the key.
421
556
 
422
557
  Two guarantees worth stating plainly. A project with no `tracker` block behaves
423
558
  exactly as before, with no new required setting and no network access. And
@@ -447,48 +582,52 @@ Every command group also has `--help`, and a `check` that validates its tree.
447
582
  ## Skills — the judgment layer
448
583
 
449
584
  The CLI is the _mechanism_. Fifteen skills in [`skills/`](skills/) supply the
450
- _judgment_ that drives it — the parts a deterministic tool cannot decide. Nine
451
- carry a distinct procedure; the other six all compose one lifecycle stage and
452
- are listed together at the end.
585
+ _judgment_ that drives it — the parts a deterministic tool cannot decide. They
586
+ come in three groups, told apart by name: eight core skills (seven in the table
587
+ below, and `tcw-work-stage`, which composes a lifecycle stage and is described
588
+ after it), four `tcw-commands-*` skills for the everyday workflow, and three
589
+ optional `tcw-extras-*` skills.
453
590
 
454
591
  | Skill | What it does |
455
592
  | ---------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |
456
593
  | [`tcw-work`](skills/tcw-work/SKILL.md) | Plans a request through spec and plan, drives implementation and verification, triages the inbox, runs the lifecycle, decomposes epics, searches the board |
457
594
  | [`tcw-capabilities`](skills/tcw-capabilities/SKILL.md) | The capability-delta planning check, contradiction detection, and the ledger flip at completion |
458
- | [`tcw-taxonomy`](skills/tcw-taxonomy/SKILL.md) | Declaring vocabulary and features, linking them, and federating shared vocabulary |
459
- | [`tcw-plugin`](skills/tcw-plugin/SKILL.md) | Installs the CLI from PyPI, and maps the other skills |
460
- | [`tcw-report`](skills/tcw-report/SKILL.md) | Reporting a `tcw` bug or suggestion upstream to [this project's issues](https://github.com/brocef/TCW/issues) |
461
- | [`tcw-triage-issues`](skills/tcw-triage-issues/SKILL.md) | Sweeps **your** project's GitHub issues and turns the ones worth doing into work items |
595
+ | [`tcw-taxonomy`](skills/tcw-taxonomy/SKILL.md) | Declaring vocabulary and features, linking them, and resolving vocabulary inherited from another project |
596
+ | [`tcw-setup`](skills/tcw-setup/SKILL.md) | Gets TCW working: installs or repairs the CLI, sets up a repository, starts a taxonomy or capabilities ledger |
597
+ | [`tcw-configure`](skills/tcw-configure/SKILL.md) | Changes a project's configuration: lifecycle bindings, Definition of Done, documentation entries, tracker, stores, connected and inherited projects |
462
598
  | [`documentation-sync`](skills/documentation-sync/SKILL.md) | Keeps README, changelogs, release notes, and driving skills moving with the code that changes them |
463
599
  | [`tcw-post-mortem`](skills/tcw-post-mortem/SKILL.md) | Finds which lifecycle stage could first have caught a problem, once one has surfaced |
464
- | [`autonomous-work`](skills/autonomous-work/SKILL.md) | Drives work items to completion unattended, consulting two read-only advisors wherever the lifecycle would ask you |
600
+
601
+ **Extras.** `tcw-extras-*` skills are optional, built for one way of working, and not needed to use TCW.
602
+
603
+ | Skill | What it does |
604
+ | ----- | ------------ |
605
+ | [`tcw-extras-autonomous-work`](skills/tcw-extras-autonomous-work/SKILL.md) | Drives work items to completion unattended, consulting two read-only advisors wherever the lifecycle would ask you |
606
+ | [`tcw-extras-triage-issues`](skills/tcw-extras-triage-issues/SKILL.md) | Sweeps **your** project's GitHub issues and turns the ones worth doing into work items |
607
+ | [`tcw-extras-report`](skills/tcw-extras-report/SKILL.md) | Reporting a `tcw` bug or suggestion upstream to [this project's issues](https://github.com/brocef/TCW/issues) |
465
608
 
466
609
  They name `tcw` commands and never reimplement tool logic: mechanism stays in the
467
610
  binary, judgment stays in the skills.
468
611
 
469
612
  ### Reading a lifecycle stage
470
613
 
471
- Six more skills do one job between them: hand you a stage's own working document
472
- and the instructions your project resolves for it, as a single read rather than a
473
- file you open and a command you run separately. They only read — `tcw work stage
474
- gate` is still what refuses.
475
-
476
- [`tcw-work-stage`](skills/tcw-work-stage/SKILL.md) is the general one and takes
477
- the stage id, so it reaches all seven stages including `inbox` and `postmortem`.
478
- The other five bake their stage in and ask only for the work item, which is
479
- optional: `tcw-work-stage-request`, `tcw-work-stage-spec`,
480
- `tcw-work-stage-plan`, `tcw-work-stage-implement`, `tcw-work-stage-verify`.
614
+ One more skill, [`tcw-work-stage`](skills/tcw-work-stage/SKILL.md), hands you a
615
+ stage's own working document and the instructions your project resolves for it,
616
+ as a single read rather than a file you open and a command you run separately.
617
+ It takes the stage id and the work item, so it reaches all seven stages
618
+ including `inbox` and `postmortem`, under Claude and Codex alike. It only reads
619
+ — `tcw work stage gate` is still what refuses.
481
620
 
482
- ### Review agents and slash commands
621
+ ### Review agents and command skills
483
622
 
484
623
  Three read-only review agents ship alongside them — `tcw-verifier`,
485
624
  `tcw-backlog-auditor`, and `tcw-post-mortem`, which accelerates the skill of the
486
- same name — plus slash commands for each skill's main procedure
487
- (`/tcw-plan-work`, `/tcw-drive-work-to-completion`, `/tcw-verify-work`,
488
- `/tcw-process-inbox`, `/tcw-work-search`, `/tcw-triage-issues`,
489
- `/tcw-audit-work-backlog`, `/tcw-consolidate-plans`, `/tcw-taxonomy-init`,
490
- `/tcw-capabilities-init`, `/tcw-docs-sync-setup`, `/tcw-cut-version`,
491
- `/tcw-post-mortem`).
625
+ same name. Four command skills carry the everyday workflows:
626
+ `tcw-commands-plan-work`, `tcw-commands-drive-work-to-completion`,
627
+ `tcw-commands-verify-work` and `tcw-commands-process-inbox`. The three extras,
628
+ `tcw-extras-autonomous-work`, `tcw-extras-triage-issues` and
629
+ `tcw-extras-report`, are optional. Under Claude and Codex alike, every entry
630
+ point is a skill.
492
631
 
493
632
  ---
494
633
 
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "tcw-cli"
7
- version = "2.1.2"
7
+ version = "2.2.0"
8
8
  description = "Taxonomy · Capabilities · Work — a storage-abstracted framework for describing and evolving a software project."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.11"