taskledger 0.1.2__tar.gz → 0.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 (174) hide show
  1. taskledger-0.2.0/.github/workflows/pre-commit.yml +31 -0
  2. {taskledger-0.1.2 → taskledger-0.2.0}/.pre-commit-config.yaml +10 -5
  3. {taskledger-0.1.2 → taskledger-0.2.0}/.taskledger.toml +10 -1
  4. {taskledger-0.1.2 → taskledger-0.2.0}/API.md +5 -0
  5. {taskledger-0.1.2 → taskledger-0.2.0}/CHANGELOG.md +20 -0
  6. taskledger-0.2.0/Makefile +9 -0
  7. {taskledger-0.1.2/taskledger.egg-info → taskledger-0.2.0}/PKG-INFO +69 -20
  8. {taskledger-0.1.2 → taskledger-0.2.0}/README.md +67 -19
  9. {taskledger-0.1.2 → taskledger-0.2.0}/docs/api.rst +5 -0
  10. {taskledger-0.1.2 → taskledger-0.2.0}/docs/command_contract.rst +79 -2
  11. taskledger-0.2.0/docs/service_boundary_whitelist.rst +57 -0
  12. {taskledger-0.1.2 → taskledger-0.2.0}/docs/usage.rst +60 -5
  13. {taskledger-0.1.2 → taskledger-0.2.0}/pyproject.toml +7 -1
  14. {taskledger-0.1.2 → taskledger-0.2.0}/skills/taskledger/SKILL.md +41 -19
  15. {taskledger-0.1.2 → taskledger-0.2.0}/taskledger/_version.py +3 -3
  16. {taskledger-0.1.2 → taskledger-0.2.0}/taskledger/api/project.py +114 -6
  17. {taskledger-0.1.2 → taskledger-0.2.0}/taskledger/api/tasks.py +10 -0
  18. {taskledger-0.1.2 → taskledger-0.2.0}/taskledger/cli.py +212 -13
  19. {taskledger-0.1.2 → taskledger-0.2.0}/taskledger/cli_implement.py +21 -26
  20. taskledger-0.2.0/taskledger/cli_ledger.py +511 -0
  21. {taskledger-0.1.2 → taskledger-0.2.0}/taskledger/cli_migrate.py +11 -2
  22. {taskledger-0.1.2 → taskledger-0.2.0}/taskledger/cli_misc.py +123 -18
  23. {taskledger-0.1.2 → taskledger-0.2.0}/taskledger/cli_task.py +200 -0
  24. {taskledger-0.1.2 → taskledger-0.2.0}/taskledger/command_inventory.py +12 -2
  25. {taskledger-0.1.2 → taskledger-0.2.0}/taskledger/domain/models.py +17 -0
  26. {taskledger-0.1.2 → taskledger-0.2.0}/taskledger/domain/states.py +11 -1
  27. taskledger-0.2.0/taskledger/exchange.py +763 -0
  28. taskledger-0.2.0/taskledger/ids.py +40 -0
  29. taskledger-0.2.0/taskledger/services/command_runner.py +22 -0
  30. {taskledger-0.1.2 → taskledger-0.2.0}/taskledger/services/doctor.py +204 -15
  31. {taskledger-0.1.2 → taskledger-0.2.0}/taskledger/services/handoff.py +13 -1
  32. taskledger-0.2.0/taskledger/services/implementation_flow.py +464 -0
  33. {taskledger-0.1.2 → taskledger-0.2.0}/taskledger/services/plan_lint.py +12 -1
  34. taskledger-0.2.0/taskledger/services/planning_flow.py +387 -0
  35. {taskledger-0.1.2 → taskledger-0.2.0}/taskledger/services/releases.py +9 -0
  36. taskledger-0.2.0/taskledger/services/task_queries.py +81 -0
  37. taskledger-0.2.0/taskledger/services/task_reports.py +919 -0
  38. {taskledger-0.1.2 → taskledger-0.2.0}/taskledger/services/tasks.py +485 -928
  39. taskledger-0.2.0/taskledger/services/tree.py +504 -0
  40. {taskledger-0.1.2 → taskledger-0.2.0}/taskledger/services/validation.py +6 -6
  41. taskledger-0.2.0/taskledger/services/validation_flow.py +394 -0
  42. {taskledger-0.1.2 → taskledger-0.2.0}/taskledger/storage/atomic.py +26 -2
  43. {taskledger-0.1.2 → taskledger-0.2.0}/taskledger/storage/init.py +33 -16
  44. taskledger-0.2.0/taskledger/storage/ledger_config.py +278 -0
  45. taskledger-0.2.0/taskledger/storage/migrations.py +509 -0
  46. {taskledger-0.1.2 → taskledger-0.2.0}/taskledger/storage/paths.py +13 -3
  47. {taskledger-0.1.2 → taskledger-0.2.0}/taskledger/storage/project_config.py +75 -26
  48. taskledger-0.2.0/taskledger/storage/project_identity.py +160 -0
  49. {taskledger-0.1.2 → taskledger-0.2.0}/taskledger/storage/task_store.py +64 -22
  50. {taskledger-0.1.2 → taskledger-0.2.0/taskledger.egg-info}/PKG-INFO +69 -20
  51. {taskledger-0.1.2 → taskledger-0.2.0}/taskledger.egg-info/SOURCES.txt +22 -1
  52. {taskledger-0.1.2 → taskledger-0.2.0}/taskledger.egg-info/requires.txt +1 -0
  53. taskledger-0.2.0/tests/__init__.py +0 -0
  54. taskledger-0.2.0/tests/conftest.py +13 -0
  55. taskledger-0.2.0/tests/support/__init__.py +1 -0
  56. taskledger-0.2.0/tests/support/builders.py +231 -0
  57. {taskledger-0.1.2 → taskledger-0.2.0}/tests/test_active_task.py +12 -6
  58. {taskledger-0.1.2 → taskledger-0.2.0}/tests/test_agent_session_protocol.py +73 -12
  59. taskledger-0.2.0/tests/test_atomic_fast_io.py +30 -0
  60. {taskledger-0.1.2 → taskledger-0.2.0}/tests/test_cli_command_contract.py +6 -0
  61. {taskledger-0.1.2 → taskledger-0.2.0}/tests/test_command_example_linter.py +1 -0
  62. taskledger-0.2.0/tests/test_compact_mutation_output.py +331 -0
  63. {taskledger-0.1.2 → taskledger-0.2.0}/tests/test_delta_remaining_contracts.py +56 -206
  64. {taskledger-0.1.2 → taskledger-0.2.0}/tests/test_handoff_lifecycle.py +9 -1
  65. {taskledger-0.1.2 → taskledger-0.2.0}/tests/test_json_contracts.py +1 -1
  66. {taskledger-0.1.2 → taskledger-0.2.0}/tests/test_locks_audit.py +10 -2
  67. {taskledger-0.1.2 → taskledger-0.2.0}/tests/test_plan_lint.py +101 -0
  68. {taskledger-0.1.2 → taskledger-0.2.0}/tests/test_project_root_config.py +2 -2
  69. {taskledger-0.1.2 → taskledger-0.2.0}/tests/test_question_plan_regeneration.py +14 -24
  70. {taskledger-0.1.2 → taskledger-0.2.0}/tests/test_release_changelog.py +40 -312
  71. taskledger-0.2.0/tests/test_service_boundaries.py +375 -0
  72. {taskledger-0.1.2 → taskledger-0.2.0}/tests/test_sidecar_collections.py +1 -1
  73. {taskledger-0.1.2 → taskledger-0.2.0}/tests/test_storage_bundle_layout.py +219 -5
  74. {taskledger-0.1.2 → taskledger-0.2.0}/tests/test_storage_common.py +11 -9
  75. {taskledger-0.1.2 → taskledger-0.2.0}/tests/test_storage_init.py +2 -2
  76. taskledger-0.2.0/tests/test_storage_migration.py +965 -0
  77. taskledger-0.2.0/tests/test_task_report.py +332 -0
  78. taskledger-0.2.0/tests/test_taskledger_branch_scoped_ledgers.py +145 -0
  79. {taskledger-0.1.2 → taskledger-0.2.0}/tests/test_taskledger_cli_api_parity.py +1 -0
  80. {taskledger-0.1.2 → taskledger-0.2.0}/tests/test_taskledger_v2_cli.py +215 -213
  81. taskledger-0.2.0/tests/test_taskledger_v2_exchange.py +675 -0
  82. {taskledger-0.1.2 → taskledger-0.2.0}/tests/test_todo_implementation_gate.py +47 -170
  83. taskledger-0.2.0/tests/test_tree_command.py +573 -0
  84. taskledger-0.1.2/.github/workflows/pre-commit.yml +0 -13
  85. taskledger-0.1.2/taskledger/exchange.py +0 -370
  86. taskledger-0.1.2/taskledger/ids.py +0 -19
  87. taskledger-0.1.2/taskledger/storage/migrations.py +0 -207
  88. taskledger-0.1.2/tests/conftest.py +0 -8
  89. taskledger-0.1.2/tests/test_storage_migration.py +0 -429
  90. taskledger-0.1.2/tests/test_taskledger_v2_exchange.py +0 -373
  91. {taskledger-0.1.2 → taskledger-0.2.0}/.codecrate.toml +0 -0
  92. {taskledger-0.1.2 → taskledger-0.2.0}/.github/workflows/codecov.yml +0 -0
  93. {taskledger-0.1.2 → taskledger-0.2.0}/.github/workflows/python-publish.yml +0 -0
  94. {taskledger-0.1.2 → taskledger-0.2.0}/.github/workflows/tests.yml +0 -0
  95. {taskledger-0.1.2 → taskledger-0.2.0}/.gitignore +0 -0
  96. {taskledger-0.1.2 → taskledger-0.2.0}/.readthedocs.yaml +0 -0
  97. {taskledger-0.1.2 → taskledger-0.2.0}/.ruff.toml +0 -0
  98. {taskledger-0.1.2 → taskledger-0.2.0}/AGENTS.md +0 -0
  99. {taskledger-0.1.2 → taskledger-0.2.0}/LICENSE +0 -0
  100. {taskledger-0.1.2 → taskledger-0.2.0}/docs/Makefile +0 -0
  101. {taskledger-0.1.2 → taskledger-0.2.0}/docs/architecture_taskledger_split.rst +0 -0
  102. {taskledger-0.1.2 → taskledger-0.2.0}/docs/build.sh +0 -0
  103. {taskledger-0.1.2 → taskledger-0.2.0}/docs/conf.py +0 -0
  104. {taskledger-0.1.2 → taskledger-0.2.0}/docs/full_task_cycle.rst +0 -0
  105. {taskledger-0.1.2 → taskledger-0.2.0}/docs/index.rst +0 -0
  106. {taskledger-0.1.2 → taskledger-0.2.0}/docs/multi_repo.rst +0 -0
  107. {taskledger-0.1.2 → taskledger-0.2.0}/docs/public_surface.rst +0 -0
  108. {taskledger-0.1.2 → taskledger-0.2.0}/docs/requirements.txt +0 -0
  109. {taskledger-0.1.2 → taskledger-0.2.0}/setup.cfg +0 -0
  110. {taskledger-0.1.2 → taskledger-0.2.0}/setup.py +0 -0
  111. {taskledger-0.1.2 → taskledger-0.2.0}/taskledger/__init__.py +0 -0
  112. {taskledger-0.1.2 → taskledger-0.2.0}/taskledger/__main__.py +0 -0
  113. {taskledger-0.1.2 → taskledger-0.2.0}/taskledger/api/__init__.py +0 -0
  114. {taskledger-0.1.2 → taskledger-0.2.0}/taskledger/api/handoff.py +0 -0
  115. {taskledger-0.1.2 → taskledger-0.2.0}/taskledger/api/introductions.py +0 -0
  116. {taskledger-0.1.2 → taskledger-0.2.0}/taskledger/api/locks.py +0 -0
  117. {taskledger-0.1.2 → taskledger-0.2.0}/taskledger/api/plans.py +0 -0
  118. {taskledger-0.1.2 → taskledger-0.2.0}/taskledger/api/questions.py +0 -0
  119. {taskledger-0.1.2 → taskledger-0.2.0}/taskledger/api/releases.py +0 -0
  120. {taskledger-0.1.2 → taskledger-0.2.0}/taskledger/api/search.py +0 -0
  121. {taskledger-0.1.2 → taskledger-0.2.0}/taskledger/api/task_runs.py +0 -0
  122. {taskledger-0.1.2 → taskledger-0.2.0}/taskledger/cli_actor.py +0 -0
  123. {taskledger-0.1.2 → taskledger-0.2.0}/taskledger/cli_common.py +0 -0
  124. {taskledger-0.1.2 → taskledger-0.2.0}/taskledger/cli_plan.py +0 -0
  125. {taskledger-0.1.2 → taskledger-0.2.0}/taskledger/cli_question.py +0 -0
  126. {taskledger-0.1.2 → taskledger-0.2.0}/taskledger/cli_release.py +0 -0
  127. {taskledger-0.1.2 → taskledger-0.2.0}/taskledger/cli_validate.py +0 -0
  128. {taskledger-0.1.2 → taskledger-0.2.0}/taskledger/domain/__init__.py +0 -0
  129. {taskledger-0.1.2 → taskledger-0.2.0}/taskledger/domain/policies.py +0 -0
  130. {taskledger-0.1.2 → taskledger-0.2.0}/taskledger/errors.py +0 -0
  131. {taskledger-0.1.2 → taskledger-0.2.0}/taskledger/launcher.py +0 -0
  132. {taskledger-0.1.2 → taskledger-0.2.0}/taskledger/py.typed +0 -0
  133. {taskledger-0.1.2 → taskledger-0.2.0}/taskledger/search.py +0 -0
  134. {taskledger-0.1.2 → taskledger-0.2.0}/taskledger/services/__init__.py +0 -0
  135. {taskledger-0.1.2 → taskledger-0.2.0}/taskledger/services/actors.py +0 -0
  136. {taskledger-0.1.2 → taskledger-0.2.0}/taskledger/services/dashboard.py +0 -0
  137. {taskledger-0.1.2 → taskledger-0.2.0}/taskledger/services/handoff_lifecycle.py +0 -0
  138. {taskledger-0.1.2 → taskledger-0.2.0}/taskledger/services/navigation.py +0 -0
  139. {taskledger-0.1.2 → taskledger-0.2.0}/taskledger/services/phase5_lock_transfer.py +0 -0
  140. {taskledger-0.1.2 → taskledger-0.2.0}/taskledger/services/serve_read_model.py +0 -0
  141. {taskledger-0.1.2 → taskledger-0.2.0}/taskledger/services/web_dashboard.py +0 -0
  142. {taskledger-0.1.2 → taskledger-0.2.0}/taskledger/storage/__init__.py +0 -0
  143. {taskledger-0.1.2 → taskledger-0.2.0}/taskledger/storage/common.py +0 -0
  144. {taskledger-0.1.2 → taskledger-0.2.0}/taskledger/storage/events.py +0 -0
  145. {taskledger-0.1.2 → taskledger-0.2.0}/taskledger/storage/frontmatter.py +0 -0
  146. {taskledger-0.1.2 → taskledger-0.2.0}/taskledger/storage/indexes.py +0 -0
  147. {taskledger-0.1.2 → taskledger-0.2.0}/taskledger/storage/locks.py +0 -0
  148. {taskledger-0.1.2 → taskledger-0.2.0}/taskledger/storage/meta.py +0 -0
  149. {taskledger-0.1.2 → taskledger-0.2.0}/taskledger/storage/repos.py +0 -0
  150. {taskledger-0.1.2 → taskledger-0.2.0}/taskledger/timeutils.py +0 -0
  151. {taskledger-0.1.2 → taskledger-0.2.0}/taskledger.egg-info/dependency_links.txt +0 -0
  152. {taskledger-0.1.2 → taskledger-0.2.0}/taskledger.egg-info/entry_points.txt +0 -0
  153. {taskledger-0.1.2 → taskledger-0.2.0}/taskledger.egg-info/top_level.txt +0 -0
  154. {taskledger-0.1.2 → taskledger-0.2.0}/tests/test_actor_harness_state.py +0 -0
  155. {taskledger-0.1.2 → taskledger-0.2.0}/tests/test_cli_import_resilience.py +0 -0
  156. {taskledger-0.1.2 → taskledger-0.2.0}/tests/test_command_inventory.py +0 -0
  157. {taskledger-0.1.2 → taskledger-0.2.0}/tests/test_docs_and_skill.py +0 -0
  158. {taskledger-0.1.2 → taskledger-0.2.0}/tests/test_doctor.py +0 -0
  159. {taskledger-0.1.2 → taskledger-0.2.0}/tests/test_domain_policies.py +0 -0
  160. {taskledger-0.1.2 → taskledger-0.2.0}/tests/test_events.py +0 -0
  161. {taskledger-0.1.2 → taskledger-0.2.0}/tests/test_implementation_change_scan.py +0 -0
  162. {taskledger-0.1.2 → taskledger-0.2.0}/tests/test_legacy_cleanup_contracts.py +0 -0
  163. {taskledger-0.1.2 → taskledger-0.2.0}/tests/test_lifecycle_policies.py +0 -0
  164. {taskledger-0.1.2 → taskledger-0.2.0}/tests/test_models_v1_schema.py +0 -0
  165. {taskledger-0.1.2 → taskledger-0.2.0}/tests/test_plan_approval_contract.py +0 -0
  166. {taskledger-0.1.2 → taskledger-0.2.0}/tests/test_plan_todo_materialization.py +0 -0
  167. {taskledger-0.1.2 → taskledger-0.2.0}/tests/test_question_add_many.py +0 -0
  168. {taskledger-0.1.2 → taskledger-0.2.0}/tests/test_question_filter_answers.py +0 -0
  169. {taskledger-0.1.2 → taskledger-0.2.0}/tests/test_search.py +0 -0
  170. {taskledger-0.1.2 → taskledger-0.2.0}/tests/test_serve_dashboard.py +0 -0
  171. {taskledger-0.1.2 → taskledger-0.2.0}/tests/test_services_dashboard.py +0 -0
  172. {taskledger-0.1.2 → taskledger-0.2.0}/tests/test_storage_repos.py +0 -0
  173. {taskledger-0.1.2 → taskledger-0.2.0}/tests/test_task_events.py +0 -0
  174. {taskledger-0.1.2 → taskledger-0.2.0}/tests/test_tasks_service_static.py +0 -0
@@ -0,0 +1,31 @@
1
+ name: pre-commit
2
+
3
+ on:
4
+ pull_request:
5
+ push:
6
+
7
+ jobs:
8
+ pre-commit:
9
+ runs-on: ubuntu-latest
10
+
11
+ steps:
12
+ - uses: actions/checkout@v4
13
+
14
+ - uses: actions/setup-python@v5
15
+ with:
16
+ python-version: "3.13"
17
+
18
+ - uses: actions/setup-node@v4
19
+ with:
20
+ node-version: "20"
21
+
22
+ - name: Install Python tools
23
+ run: |
24
+ python -m pip install --upgrade pip
25
+ python -m pip install "ruff==0.15.12"
26
+
27
+ - name: Install Node tools
28
+ run: |
29
+ npm install -g prettier@2.7.1 @prettier/plugin-xml@2.2.0 eslint
30
+
31
+ - uses: pre-commit/action@v3.0.1
@@ -17,14 +17,19 @@ exclude: |
17
17
  (LICENSE.*|COPYING.*)|
18
18
  default_language_version:
19
19
  python: python3
20
- node: "16.17.0"
21
20
  repos:
22
- - repo: https://github.com/astral-sh/ruff-pre-commit
23
- rev: v0.15.12
21
+ - repo: local
24
22
  hooks:
25
- - id: ruff
26
- args: [--fix, --exit-non-zero-on-fix, --config=.ruff.toml]
23
+ - id: ruff-check
24
+ name: ruff check
25
+ entry: ruff check --fix --exit-non-zero-on-fix --config=.ruff.toml --force-exclude
26
+ language: system
27
+ types_or: [python, pyi]
27
28
  - id: ruff-format
29
+ name: ruff format
30
+ entry: ruff format --force-exclude
31
+ language: system
32
+ types_or: [python, pyi]
28
33
  - repo: https://github.com/asottile/pyupgrade
29
34
  rev: v3.21.2
30
35
  hooks:
@@ -1,8 +1,11 @@
1
1
  # Project-local taskledger configuration.
2
2
  # This file lives in the source project root.
3
- config_version = 1
3
+ config_version = 2
4
4
  taskledger_dir = '.taskledger'
5
5
 
6
+ # Stable project identity. Commit this with your source tree.
7
+ project_uuid = "081c7c05-2d10-42b7-9b37-3d814c2f400a"
8
+
6
9
  # Project-local taskledger overrides.
7
10
  # The source-budget settings below are the active composition defaults.
8
11
  # Lower them for stricter prompts, or raise them when a run needs more context.
@@ -18,3 +21,9 @@ taskledger_dir = '.taskledger'
18
21
  # workflow_schema = "opsx-lite"
19
22
  # project_context = "Project-specific workflow guidance."
20
23
  # default_artifact_order = ["analysis", "plan", "implementation", "validation"]
24
+
25
+ # Taskledger branch-scoped state. This block is intentionally safe to commit.
26
+ ledger_ref = "main"
27
+ ledger_parent_ref = ""
28
+ ledger_next_task_number = 60
29
+ ledger_branch_guard = "off"
@@ -54,10 +54,12 @@ from taskledger.errors import (
54
54
  - `project_export`
55
55
  - `project_import`
56
56
  - `project_snapshot`
57
+ - `project_tree`
57
58
 
58
59
  ### `taskledger.api.tasks`
59
60
 
60
61
  - `create_task`
62
+ - `record_completed_task`
61
63
  - `show_active_task`
62
64
  - `activate_task`
63
65
  - `deactivate_task`
@@ -82,11 +84,14 @@ from taskledger.errors import (
82
84
  - `todo_status`
83
85
  - `next_todo`
84
86
  - `task_dossier`
87
+ - `render_task_report`
88
+ - `TaskReportOptions`
85
89
  - `next_action`
86
90
  - `can_perform`
87
91
  - `reindex`
88
92
  - `repair_task_record`
89
93
  - `repair_orphaned_planning_run`
94
+ - `repair_planning_command_changes`
90
95
 
91
96
  ### `taskledger.api.plans`
92
97
 
@@ -1,5 +1,25 @@
1
1
  # Changelog
2
2
 
3
+ ## v0.1.2 - 2026-04-30
4
+
5
+ ### Fixed
6
+
7
+ - Fixed orphaned planning run lifecycle recovery so plan regeneration safely finishes the latest orphaned planning run with audit evidence, plan approval rejects tasks with any running run, and `implement start` reports structured conflict details including run id, run type, lock match status, and suggested diagnostic command.
8
+ - Aligned `next-action` and `can implement` so they never recommend `implement start` when a running run or run/lock mismatch blocks implementation.
9
+ - Expanded `taskledger doctor` and `taskledger doctor locks` to report run/lock mismatches with specific repair guidance.
10
+
11
+ ### Added
12
+
13
+ - Added `taskledger repair run` for guarded, reasoned, audited repair of orphaned running planning runs.
14
+
15
+ ### Documentation
16
+
17
+ - Updated taskledger skill, command contract, and API docs with running-run conflict protocol and `repair run` usage.
18
+
19
+ ### Quality
20
+
21
+ - Expanded regression coverage for plan regeneration recovery, approval guards, next-action alignment, doctor diagnostics, and repair lifecycle. Targeted pytest, ruff, format, and mypy passed.
22
+
3
23
  ## v0.1.1 - 2026-04-29
4
24
 
5
25
  ### Added
@@ -0,0 +1,9 @@
1
+ .PHONY: release-check
2
+
3
+ release-check:
4
+ python3 -m compileall -q taskledger tests
5
+ PYTEST_DISABLE_PLUGIN_AUTOLOAD=1 python3 -m pytest -q
6
+ python3 -m ruff check --config=.ruff.toml .
7
+ python3 -m mypy taskledger
8
+ python3 -m build
9
+ python3 -m twine check dist/*
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: taskledger
3
- Version: 0.1.2
3
+ Version: 0.2.0
4
4
  Summary: Durable project-state storage and CLI for coding workflows
5
5
  Author: Taskledger Contributors
6
6
  Maintainer: Holger Nahrstaedt
@@ -33,6 +33,7 @@ Provides-Extra: dev
33
33
  Requires-Dist: build; extra == "dev"
34
34
  Requires-Dist: mypy; extra == "dev"
35
35
  Requires-Dist: pytest; extra == "dev"
36
+ Requires-Dist: pytest-xdist; extra == "dev"
36
37
  Requires-Dist: ruff; extra == "dev"
37
38
  Requires-Dist: twine; extra == "dev"
38
39
  Requires-Dist: types-PyYAML; extra == "dev"
@@ -136,14 +137,15 @@ taskledger validate check --criterion ac-0001 --status pass --evidence "pytest -
136
137
  taskledger validate finish --result passed --summary "Validated the rewrite."
137
138
  ```
138
139
 
139
- If validation finds an implementation bug, keep the accepted plan and restart
140
- implementation explicitly:
140
+ For manually completed work (e.g., manual testing, operations tasks, or work
141
+ completed outside the task-first lifecycle), use `task record` to create a
142
+ done task directly without acquiring lifecycle locks. **Note**: `task record`
143
+ does not replace the normal task lifecycle; it is for recording work already
144
+ completed, not as a shortcut for active task management.
141
145
 
142
146
  ```bash
143
- taskledger validate finish --result failed --summary "Parser edge case still fails."
144
- taskledger next-action
145
- taskledger context --for implementation --format markdown
146
- taskledger implement restart --summary "Fix failed validation findings."
147
+ taskledger task record "Deploy to production" --summary "Deployed v0.4.1 to prod" --change "infra/deploy.sh:run:Updated prod config" --evidence "Monitoring shows no errors"
148
+ taskledger task record "Manual API testing" --summary "Tested new endpoints" --allow-empty-record --reason "Exploratory testing, no formal changes tracked"
147
149
  ```
148
150
 
149
151
  If validation finds an implementation bug, keep the accepted plan and restart
@@ -270,21 +272,47 @@ fresh-context transfer.
270
272
  ## Storage layout
271
273
 
272
274
  `taskledger` keeps project-local configuration in the workspace root and durable
273
- records under the configured storage root:
275
+ records under the configured storage root. The checked-in `.taskledger.toml`
276
+ stores only a branch-scoped ledger pointer and next task number. Operational task
277
+ state remains ignored under `.taskledger/ledgers/<ledger_ref>/`:
274
278
 
275
279
  ```text
276
- taskledger.toml
280
+ .taskledger.toml
277
281
  .taskledger/
278
- intros/
279
- releases/
280
- tasks/
281
- events/
282
- indexes/ # optional derived caches and registries
282
+ storage.yaml
283
+ ledgers/
284
+ main/
285
+ intros/
286
+ releases/
287
+ tasks/
288
+ events/
289
+ indexes/ # optional derived caches and registries
283
290
  ```
284
291
 
285
- Markdown files are canonical. Task, plan, and run listings scan those records
286
- directly. JSON files under `.taskledger/indexes/` are optional derived caches or
287
- registries and are not required for task correctness.
292
+ Markdown files are canonical. Task, plan, and run listings scan only the current
293
+ ledger by default. JSON files under the current ledger's `indexes/` directory are
294
+ optional derived caches or registries and are not required for task correctness.
295
+
296
+ ### Branch-scoped ledgers
297
+
298
+ `.taskledger/` stays ignored and local. `.taskledger.toml` is safe to commit and
299
+ contains the current `ledger_ref`, optional parent ref, and the next logical task
300
+ number for the checked-out source branch.
301
+
302
+ When starting long-lived branch-local work, fork the ledger pointer after creating
303
+ the Git branch:
304
+
305
+ ```bash
306
+ git checkout -b feature-a
307
+ taskledger ledger fork feature-a
308
+ git add .taskledger.toml
309
+ ```
310
+
311
+ Returning to a branch whose `.taskledger.toml` points back to `main` hides the
312
+ feature branch's active task and task list. Two ledgers may both contain a logical
313
+ `task-0030`; this is expected because task IDs are scoped by `ledger_ref`. Use
314
+ `taskledger ledger adopt --from REF TASK_REF` when branch-local task history
315
+ should be copied into the current ledger.
288
316
 
289
317
  You can also point `taskledger.toml` at an external storage root:
290
318
 
@@ -352,6 +380,7 @@ taskledger context --for planning --format markdown
352
380
  taskledger context --for implementation --format markdown
353
381
  taskledger context --for validation --format json
354
382
  taskledger task dossier --format markdown
383
+ taskledger task report --task task-0030 -o task30.md
355
384
  taskledger handoff create --mode implementation --intended-actor agent --intended-harness codex
356
385
  taskledger handoff claim handoff-0001
357
386
  taskledger handoff close handoff-0001 --reason "Implementation started."
@@ -412,11 +441,22 @@ for task-first handoff guidance.
412
441
  ## Export, import, and snapshots
413
442
 
414
443
  ```bash
415
- taskledger --json export
416
- taskledger import ./taskledger-export.json --replace
444
+ taskledger export ./taskledger-transfer.tar.gz
445
+ taskledger import ./taskledger-transfer.tar.gz --replace
417
446
  taskledger snapshot ./artifacts
418
447
  ```
419
448
 
449
+ Cross-machine imports preserve durable task/run data, but imported runtime locks
450
+ are quarantined by default. After importing an in-progress implementation,
451
+ run:
452
+
453
+ ```bash
454
+ taskledger next-action
455
+ taskledger implement resume --reason "Continue imported implementation."
456
+ ```
457
+
458
+ Use `--lock-policy keep` only for diagnostic full-fidelity lock restoration.
459
+
420
460
  ## Skill packaging
421
461
 
422
462
  Agent workflows work best when the `taskledger` skill is installed in the
@@ -436,6 +476,15 @@ Keep this skill outside the Python package. No additional
436
476
  ## Development
437
477
 
438
478
  ```bash
439
- pytest -q
479
+ python -m pytest -m "not slow"
480
+ python -m pytest -m "not slow" -n auto
481
+ python -m pytest -n auto
482
+ python -m pytest
440
483
  ruff check .
441
484
  ```
485
+
486
+ Full release-readiness sweep:
487
+
488
+ ```bash
489
+ make release-check
490
+ ```
@@ -94,14 +94,15 @@ taskledger validate check --criterion ac-0001 --status pass --evidence "pytest -
94
94
  taskledger validate finish --result passed --summary "Validated the rewrite."
95
95
  ```
96
96
 
97
- If validation finds an implementation bug, keep the accepted plan and restart
98
- implementation explicitly:
97
+ For manually completed work (e.g., manual testing, operations tasks, or work
98
+ completed outside the task-first lifecycle), use `task record` to create a
99
+ done task directly without acquiring lifecycle locks. **Note**: `task record`
100
+ does not replace the normal task lifecycle; it is for recording work already
101
+ completed, not as a shortcut for active task management.
99
102
 
100
103
  ```bash
101
- taskledger validate finish --result failed --summary "Parser edge case still fails."
102
- taskledger next-action
103
- taskledger context --for implementation --format markdown
104
- taskledger implement restart --summary "Fix failed validation findings."
104
+ taskledger task record "Deploy to production" --summary "Deployed v0.4.1 to prod" --change "infra/deploy.sh:run:Updated prod config" --evidence "Monitoring shows no errors"
105
+ taskledger task record "Manual API testing" --summary "Tested new endpoints" --allow-empty-record --reason "Exploratory testing, no formal changes tracked"
105
106
  ```
106
107
 
107
108
  If validation finds an implementation bug, keep the accepted plan and restart
@@ -228,21 +229,47 @@ fresh-context transfer.
228
229
  ## Storage layout
229
230
 
230
231
  `taskledger` keeps project-local configuration in the workspace root and durable
231
- records under the configured storage root:
232
+ records under the configured storage root. The checked-in `.taskledger.toml`
233
+ stores only a branch-scoped ledger pointer and next task number. Operational task
234
+ state remains ignored under `.taskledger/ledgers/<ledger_ref>/`:
232
235
 
233
236
  ```text
234
- taskledger.toml
237
+ .taskledger.toml
235
238
  .taskledger/
236
- intros/
237
- releases/
238
- tasks/
239
- events/
240
- indexes/ # optional derived caches and registries
239
+ storage.yaml
240
+ ledgers/
241
+ main/
242
+ intros/
243
+ releases/
244
+ tasks/
245
+ events/
246
+ indexes/ # optional derived caches and registries
241
247
  ```
242
248
 
243
- Markdown files are canonical. Task, plan, and run listings scan those records
244
- directly. JSON files under `.taskledger/indexes/` are optional derived caches or
245
- registries and are not required for task correctness.
249
+ Markdown files are canonical. Task, plan, and run listings scan only the current
250
+ ledger by default. JSON files under the current ledger's `indexes/` directory are
251
+ optional derived caches or registries and are not required for task correctness.
252
+
253
+ ### Branch-scoped ledgers
254
+
255
+ `.taskledger/` stays ignored and local. `.taskledger.toml` is safe to commit and
256
+ contains the current `ledger_ref`, optional parent ref, and the next logical task
257
+ number for the checked-out source branch.
258
+
259
+ When starting long-lived branch-local work, fork the ledger pointer after creating
260
+ the Git branch:
261
+
262
+ ```bash
263
+ git checkout -b feature-a
264
+ taskledger ledger fork feature-a
265
+ git add .taskledger.toml
266
+ ```
267
+
268
+ Returning to a branch whose `.taskledger.toml` points back to `main` hides the
269
+ feature branch's active task and task list. Two ledgers may both contain a logical
270
+ `task-0030`; this is expected because task IDs are scoped by `ledger_ref`. Use
271
+ `taskledger ledger adopt --from REF TASK_REF` when branch-local task history
272
+ should be copied into the current ledger.
246
273
 
247
274
  You can also point `taskledger.toml` at an external storage root:
248
275
 
@@ -310,6 +337,7 @@ taskledger context --for planning --format markdown
310
337
  taskledger context --for implementation --format markdown
311
338
  taskledger context --for validation --format json
312
339
  taskledger task dossier --format markdown
340
+ taskledger task report --task task-0030 -o task30.md
313
341
  taskledger handoff create --mode implementation --intended-actor agent --intended-harness codex
314
342
  taskledger handoff claim handoff-0001
315
343
  taskledger handoff close handoff-0001 --reason "Implementation started."
@@ -370,11 +398,22 @@ for task-first handoff guidance.
370
398
  ## Export, import, and snapshots
371
399
 
372
400
  ```bash
373
- taskledger --json export
374
- taskledger import ./taskledger-export.json --replace
401
+ taskledger export ./taskledger-transfer.tar.gz
402
+ taskledger import ./taskledger-transfer.tar.gz --replace
375
403
  taskledger snapshot ./artifacts
376
404
  ```
377
405
 
406
+ Cross-machine imports preserve durable task/run data, but imported runtime locks
407
+ are quarantined by default. After importing an in-progress implementation,
408
+ run:
409
+
410
+ ```bash
411
+ taskledger next-action
412
+ taskledger implement resume --reason "Continue imported implementation."
413
+ ```
414
+
415
+ Use `--lock-policy keep` only for diagnostic full-fidelity lock restoration.
416
+
378
417
  ## Skill packaging
379
418
 
380
419
  Agent workflows work best when the `taskledger` skill is installed in the
@@ -394,6 +433,15 @@ Keep this skill outside the Python package. No additional
394
433
  ## Development
395
434
 
396
435
  ```bash
397
- pytest -q
436
+ python -m pytest -m "not slow"
437
+ python -m pytest -m "not slow" -n auto
438
+ python -m pytest -n auto
439
+ python -m pytest
398
440
  ruff check .
399
441
  ```
442
+
443
+ Full release-readiness sweep:
444
+
445
+ ```bash
446
+ make release-check
447
+ ```
@@ -33,11 +33,13 @@ Project API
33
33
  - ``project_export``
34
34
  - ``project_import``
35
35
  - ``project_snapshot``
36
+ - ``project_tree``
36
37
 
37
38
  Task API
38
39
  --------
39
40
 
40
41
  - ``create_task``
42
+ - ``record_completed_task``
41
43
  - ``show_active_task``
42
44
  - ``activate_task``
43
45
  - ``deactivate_task``
@@ -62,11 +64,14 @@ Task API
62
64
  - ``todo_status``
63
65
  - ``next_todo``
64
66
  - ``task_dossier``
67
+ - ``render_task_report``
68
+ - ``TaskReportOptions``
65
69
  - ``next_action``
66
70
  - ``can_perform``
67
71
  - ``reindex``
68
72
  - ``repair_task_record``
69
73
  - ``repair_orphaned_planning_run``
74
+ - ``repair_planning_command_changes``
70
75
 
71
76
  Plan API
72
77
  --------
@@ -34,6 +34,19 @@ when explicitly targeting another task.
34
34
 
35
35
  Optional positional task refs are not supported.
36
36
 
37
+ Archive import lock policy
38
+ --------------------------
39
+
40
+ Archive imports support explicit lock handling:
41
+
42
+ .. code-block:: bash
43
+
44
+ taskledger import ./taskledger-transfer.tar.gz --replace [--lock-policy drop|quarantine|keep]
45
+
46
+ The default is ``quarantine`` so imported source-machine runtime locks are not
47
+ restored as active ``lock.yaml`` files. ``keep`` is diagnostic-only behavior
48
+ for full-fidelity lock restoration.
49
+
37
50
  Positional Resource Refs
38
51
  ------------------------
39
52
 
@@ -41,6 +54,8 @@ Positional refs are reserved for the direct resource being changed or shown:
41
54
 
42
55
  .. code-block:: bash
43
56
 
57
+ taskledger task create TITLE [options]
58
+ taskledger task record TITLE [options]
44
59
  taskledger task activate TASK_REF
45
60
  taskledger task follow-up PARENT_REF TITLE [options]
46
61
  taskledger todo done TODO_ID --task TASK_REF --evidence "pytest -q"
@@ -61,11 +76,32 @@ Release boundaries are durable project records, not task lifecycle states:
61
76
  taskledger release show 0.4.1
62
77
  taskledger release changelog 0.4.2 --since 0.4.1 --until-task task-0035 --output /tmp/taskledger-0.4.2-changelog-source.md
63
78
 
64
- ``release tag`` writes a durable release record under ``.taskledger/releases/``.
79
+ ``release tag`` writes a durable release record under the current ledger's
80
+ ``releases/`` directory.
65
81
  ``release changelog`` is read-oriented: it renders Markdown or JSON changelog
66
82
  context from done tasks and may write an external output file, but it does not
67
83
  mutate ledger state.
68
84
 
85
+ Ledger commands
86
+ ---------------
87
+
88
+ Branch-scoped ledgers isolate ignored local task state by the checked-in
89
+ ``ledger_ref`` stored in ``.taskledger.toml``:
90
+
91
+ .. code-block:: bash
92
+
93
+ taskledger ledger status
94
+ taskledger ledger list
95
+ taskledger ledger fork feature-a
96
+ taskledger ledger switch main
97
+ taskledger ledger adopt --from feature-a task-0030
98
+ taskledger ledger doctor
99
+
100
+ ``ledger fork`` creates a new local namespace under
101
+ ``.taskledger/ledgers/<ref>/`` and updates only Taskledger-owned ledger keys in
102
+ ``.taskledger.toml``. ``ledger switch`` changes the checked-in pointer to an
103
+ existing local ledger. ``ledger adopt`` copies a task from another local ledger
104
+ into the current ledger and renumbers on collision.
69
105
  ``next-action`` result contract
70
106
  -------------------------------
71
107
 
@@ -118,6 +154,35 @@ For an approved task with a non-implementation run still marked running,
118
154
  ``next-action`` must not direct agents to ``taskledger implement start``.
119
155
  It should report a repair-oriented action and point to ``taskledger doctor``.
120
156
  Truly cancelled tasks recover through ``taskledger task uncancel --reason "..."``
157
+
158
+ Compact mutation output
159
+ ........................
160
+
161
+ Mutation commands emit compact acknowledgements instead of full task or run records.
162
+ This reduces LLM context consumption during implementation loops.
163
+
164
+ The following commands produce compact output:
165
+
166
+ - ``todo add``: emits ``todo_added`` result with new todo, progress, and next command.
167
+ - ``todo done`` / ``todo undone``: emits ``todo_update`` result with todo id, status, progress, and next command.
168
+ - ``implement finish``: emits ``task_lifecycle`` result with task id, run id, status, and next command.
169
+
170
+ Human mode shows a one-line summary:
171
+
172
+ .. code-block:: text
173
+
174
+ added todo-0001 on task-0001 (0/3 done)
175
+ done todo-0001 on task-0001 (1/3 done)
176
+ finished implementation run-0001 task task-0001 -> implemented
177
+
178
+ JSON mode wraps the compact result in the standard success envelope with ``result_type``.
179
+
180
+ For full task, run, or todo details after a mutation, use:
181
+
182
+ - ``taskledger task show`` or ``taskledger status`` for task-level detail.
183
+ - ``taskledger todo show TODO_ID`` for individual todo detail.
184
+ - ``taskledger next-action`` for the next concrete step.
185
+ - ``taskledger todo next`` for the next open todo.
121
186
  to a durable non-active stage rather than directly re-entering an active stage.
122
187
 
123
188
  Run and lock repair
@@ -261,6 +326,11 @@ Taskledger uses:
261
326
  * per-record ``object_type``
262
327
  * per-file ``file_version`` for durable Markdown/YAML/JSON record files
263
328
 
329
+ Storage layout version history:
330
+
331
+ * Layout 2: Introduced branch-scoped ledgers under ``taskledger_dir/ledgers/<ledger_ref>/``
332
+ * Layout 3: Consolidates layout-2 root-level task state into branch-scoped ledgers; migrates legacy root ``tasks/``, ``events/``, ``intros/``, ``releases/``, and ``active-task.yaml`` into the active ledger namespace
333
+
264
334
  Taskledger does not silently rewrite storage during read-only commands.
265
335
 
266
336
  If the installed taskledger version can read but not write an older workspace,
@@ -274,7 +344,14 @@ To migrate:
274
344
  taskledger migrate plan
275
345
  taskledger migrate apply --backup
276
346
 
277
- Indexes under ``taskledger_dir/indexes/`` are optional derived caches or
347
+ After migration to layout 3, verify health with:
348
+
349
+ .. code-block:: bash
350
+
351
+ taskledger doctor
352
+ taskledger ledger doctor
353
+
354
+ Indexes under ``taskledger_dir/ledgers/<ledger_ref>/indexes/`` are optional derived caches or
278
355
  registries. Task, plan, and run commands must continue to work from canonical
279
356
  Markdown/YAML records even when task/run/plan JSON cache files are absent. The
280
357
  remaining derived caches may be plain JSON arrays with no version metadata and
@@ -0,0 +1,57 @@
1
+ Service boundary whitelist
2
+ ==========================
3
+
4
+ This note tracks temporary static-boundary whitelist entries enforced by
5
+ ``tests/test_service_boundaries.py``.
6
+
7
+ The whitelist is debt tracking, not a permanent exception list. When an item
8
+ drops below budget or is removed, update this note and the related test
9
+ constants.
10
+
11
+ Module line budget whitelist (>2000 lines)
12
+ -----------------------------------------
13
+
14
+ * ``taskledger/services/tasks.py``
15
+
16
+ * Current reason: Compatibility facade still contains multiple workflows in
17
+ one file.
18
+ * Target split direction: Split into ``task_lifecycle.py``,
19
+ ``planning_flow.py``, ``implementation_flow.py``, ``validation_flow.py``,
20
+ ``task_queries.py``, ``task_repair.py``, and ``command_capture.py``.
21
+
22
+ Current split status
23
+ --------------------
24
+
25
+ Implemented in this tranche:
26
+
27
+ * ``taskledger/services/planning_flow.py``
28
+ * ``taskledger/services/implementation_flow.py``
29
+ * ``taskledger/services/validation_flow.py``
30
+ * ``taskledger/services/tasks.py`` delegates plan, implement, and validate
31
+ entrypoints to the new modules.
32
+
33
+ Remaining target: continue reducing ``taskledger/services/tasks.py`` to a
34
+ smaller compatibility facade and move residual helpers into focused modules.
35
+
36
+ Function line budget whitelist (>250 lines)
37
+ -------------------------------------------
38
+
39
+ * ``taskledger/cli_task.py::register_task_v2_commands``
40
+ * ``taskledger/cli_plan.py::register_plan_v2_commands``
41
+ * ``taskledger/cli_implement.py::register_implement_v2_commands``
42
+ * ``taskledger/services/doctor.py::inspect_v2_project``
43
+ * ``taskledger/services/navigation.py::can_perform``
44
+ * ``taskledger/services/web_dashboard.py::_render_dashboard_css``
45
+ * ``taskledger/services/web_dashboard.py::_render_dashboard_script``
46
+
47
+ Catch-all exception whitelist (``except Exception``)
48
+ ----------------------------------------------------
49
+
50
+ Current allowed sites are listed with reasons in
51
+ ``tests/test_service_boundaries.py`` under ``EXCEPT_EXCEPTION_WHITELIST``.
52
+
53
+ Policy intent:
54
+
55
+ * Allow catch-all handling only in doctor/repair and resilience wrappers.
56
+ * Block new catch-all sites unless explicitly reviewed and justified.
57
+ * Require whitelist edits to be intentional and reasoned.