taskledger 0.4.0__tar.gz → 0.4.2__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.
- taskledger-0.4.2/.archledger/records/building_blocks/al_block_0029.md +37 -0
- taskledger-0.4.2/.archledger/records/building_blocks/al_block_0030.md +24 -0
- taskledger-0.4.2/.archledger/records/building_blocks/al_block_0031.md +22 -0
- taskledger-0.4.2/.archledger/records/building_blocks/al_block_0032.md +22 -0
- taskledger-0.4.2/.archledger/records/building_blocks/al_block_0033.md +22 -0
- taskledger-0.4.2/.archledger/records/building_blocks/al_block_0034.md +22 -0
- taskledger-0.4.2/.archledger/records/concepts/al_concept_0040.md +18 -0
- taskledger-0.4.2/.archledger/records/concepts/al_concept_0041.md +16 -0
- taskledger-0.4.2/.archledger/records/concepts/al_concept_0042.md +16 -0
- taskledger-0.4.2/.archledger/records/concepts/al_concept_0043.md +16 -0
- taskledger-0.4.2/.archledger/records/concepts/al_concept_0044.md +16 -0
- taskledger-0.4.2/.archledger/records/concepts/al_concept_0045.md +16 -0
- taskledger-0.4.2/.archledger/records/constraints/al_constraint_0016.md +17 -0
- taskledger-0.4.2/.archledger/records/constraints/al_constraint_0017.md +17 -0
- taskledger-0.4.2/.archledger/records/constraints/al_constraint_0018.md +17 -0
- taskledger-0.4.2/.archledger/records/constraints/al_constraint_0019.md +17 -0
- taskledger-0.4.2/.archledger/records/contexts/al_context_0020.md +20 -0
- taskledger-0.4.2/.archledger/records/contexts/al_context_0021.md +20 -0
- taskledger-0.4.2/.archledger/records/contexts/al_context_0022.md +20 -0
- taskledger-0.4.2/.archledger/records/contexts/al_context_0023.md +20 -0
- taskledger-0.4.2/.archledger/records/decisions/al_adr_0046.md +38 -0
- taskledger-0.4.2/.archledger/records/decisions/al_adr_0047.md +38 -0
- taskledger-0.4.2/.archledger/records/decisions/al_adr_0048.md +37 -0
- taskledger-0.4.2/.archledger/records/decisions/al_adr_0049.md +37 -0
- taskledger-0.4.2/.archledger/records/decisions/al_adr_0050.md +36 -0
- taskledger-0.4.2/.archledger/records/decisions/al_adr_0051.md +36 -0
- taskledger-0.4.2/.archledger/records/deployment/al_deploy_0039.md +35 -0
- taskledger-0.4.2/.archledger/records/glossary/al_glossary_0061.md +17 -0
- taskledger-0.4.2/.archledger/records/glossary/al_glossary_0062.md +17 -0
- taskledger-0.4.2/.archledger/records/glossary/al_glossary_0063.md +17 -0
- taskledger-0.4.2/.archledger/records/glossary/al_glossary_0064.md +17 -0
- taskledger-0.4.2/.archledger/records/glossary/al_glossary_0065.md +17 -0
- taskledger-0.4.2/.archledger/records/glossary/al_glossary_0066.md +17 -0
- taskledger-0.4.2/.archledger/records/glossary/al_glossary_0067.md +17 -0
- taskledger-0.4.2/.archledger/records/glossary/al_glossary_0068.md +17 -0
- taskledger-0.4.2/.archledger/records/glossary/al_glossary_0069.md +17 -0
- taskledger-0.4.2/.archledger/records/glossary/al_glossary_0070.md +17 -0
- taskledger-0.4.2/.archledger/records/glossary/al_glossary_0071.md +17 -0
- taskledger-0.4.2/.archledger/records/glossary/al_glossary_0072.md +17 -0
- taskledger-0.4.2/.archledger/records/glossary/al_glossary_0073.md +17 -0
- taskledger-0.4.2/.archledger/records/quality_requirements/al_quality_0052.md +27 -0
- taskledger-0.4.2/.archledger/records/quality_requirements/al_quality_0053.md +26 -0
- taskledger-0.4.2/.archledger/records/quality_requirements/al_quality_0054.md +26 -0
- taskledger-0.4.2/.archledger/records/quality_requirements/al_quality_0055.md +27 -0
- taskledger-0.4.2/.archledger/records/quality_requirements/al_quality_0056.md +26 -0
- taskledger-0.4.2/.archledger/records/requirements/al_content_0013.md +26 -0
- taskledger-0.4.2/.archledger/records/requirements/al_content_0014.md +26 -0
- taskledger-0.4.2/.archledger/records/requirements/al_content_0015.md +26 -0
- taskledger-0.4.2/.archledger/records/risks/al_risk_0057.md +18 -0
- taskledger-0.4.2/.archledger/records/risks/al_risk_0058.md +18 -0
- taskledger-0.4.2/.archledger/records/risks/al_risk_0059.md +18 -0
- taskledger-0.4.2/.archledger/records/risks/al_risk_0060.md +18 -0
- taskledger-0.4.2/.archledger/records/runtime/al_runtime_0035.md +33 -0
- taskledger-0.4.2/.archledger/records/runtime/al_runtime_0036.md +36 -0
- taskledger-0.4.2/.archledger/records/runtime/al_runtime_0037.md +28 -0
- taskledger-0.4.2/.archledger/records/runtime/al_runtime_0038.md +30 -0
- taskledger-0.4.2/.archledger/records/runtime/al_runtime_0074.md +30 -0
- taskledger-0.4.2/.archledger/records/runtime/al_runtime_0075.md +32 -0
- taskledger-0.4.2/.archledger/records/runtime/al_runtime_0076.md +30 -0
- taskledger-0.4.2/.archledger/records/runtime/al_runtime_0077.md +32 -0
- taskledger-0.4.2/.archledger/records/runtime/al_runtime_0078.md +31 -0
- taskledger-0.4.2/.archledger/records/stakeholders/al_content_0079.md +15 -0
- taskledger-0.4.2/.archledger/records/stakeholders/al_content_0080.md +15 -0
- taskledger-0.4.2/.archledger/records/strategy/al_strategy_0024.md +26 -0
- taskledger-0.4.2/.archledger/records/strategy/al_strategy_0025.md +26 -0
- taskledger-0.4.2/.archledger/records/strategy/al_strategy_0026.md +26 -0
- taskledger-0.4.2/.archledger/records/strategy/al_strategy_0027.md +26 -0
- taskledger-0.4.2/.archledger/records/strategy/al_strategy_0028.md +26 -0
- taskledger-0.4.2/.archledger/sections/al_content_0001.md +30 -0
- taskledger-0.4.2/.archledger/sections/al_content_0002.md +21 -0
- taskledger-0.4.2/.archledger/sections/al_content_0003.md +24 -0
- taskledger-0.4.2/.archledger/sections/al_content_0004.md +37 -0
- taskledger-0.4.2/.archledger/sections/al_content_0005.md +25 -0
- taskledger-0.4.2/.archledger/sections/al_content_0006.md +20 -0
- taskledger-0.4.2/.archledger/sections/al_content_0007.md +21 -0
- taskledger-0.4.2/.archledger/sections/al_content_0008.md +22 -0
- taskledger-0.4.2/.archledger/sections/al_content_0009.md +22 -0
- taskledger-0.4.2/.archledger/sections/al_content_0010.md +21 -0
- taskledger-0.4.2/.archledger/sections/al_content_0011.md +20 -0
- taskledger-0.4.2/.archledger/sections/al_content_0012.md +15 -0
- taskledger-0.4.2/.archledger/source-state.json +754 -0
- taskledger-0.4.2/.archledger/storage.yaml +5 -0
- taskledger-0.4.2/.archledger.toml +106 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/.codecrate.toml +1 -1
- {taskledger-0.4.0 → taskledger-0.4.2}/.gitignore +2 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/.taskledger.toml +1 -1
- {taskledger-0.4.0 → taskledger-0.4.2}/AGENTS.md +4 -45
- {taskledger-0.4.0 → taskledger-0.4.2}/API.md +34 -2
- taskledger-0.4.2/ARCHITECTURE.md +759 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/CHANGELOG.md +32 -1
- {taskledger-0.4.0/taskledger.egg-info → taskledger-0.4.2}/PKG-INFO +159 -11
- {taskledger-0.4.0 → taskledger-0.4.2}/README.md +156 -10
- {taskledger-0.4.0 → taskledger-0.4.2}/docs/api.rst +37 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/docs/architecture_taskledger_split.rst +8 -5
- {taskledger-0.4.0 → taskledger-0.4.2}/docs/command_contract.rst +72 -1
- {taskledger-0.4.0 → taskledger-0.4.2}/docs/full_task_cycle.rst +19 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/docs/index.rst +1 -0
- taskledger-0.4.2/docs/public_surface.rst +152 -0
- taskledger-0.4.2/docs/service_boundary_whitelist.rst +122 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/docs/sync.rst +14 -16
- {taskledger-0.4.0 → taskledger-0.4.2}/docs/transfer.rst +3 -2
- {taskledger-0.4.0 → taskledger-0.4.2}/docs/usage.rst +147 -7
- {taskledger-0.4.0 → taskledger-0.4.2}/pyproject.toml +21 -3
- taskledger-0.4.2/scripts/find_code_clones.py +224 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/skills/taskledger/SKILL.md +105 -16
- {taskledger-0.4.0 → taskledger-0.4.2}/taskledger/_version.py +3 -3
- {taskledger-0.4.0 → taskledger-0.4.2}/taskledger/api/__init__.py +2 -0
- taskledger-0.4.2/taskledger/api/config.py +608 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/taskledger/api/handoff.py +30 -19
- taskledger-0.4.2/taskledger/api/reviews.py +11 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/taskledger/api/storage.py +9 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/taskledger/api/tasks.py +6 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/taskledger/cli.py +69 -119
- taskledger-0.4.2/taskledger/cli_archive.py +166 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/taskledger/cli_common.py +21 -0
- taskledger-0.4.2/taskledger/cli_config.py +195 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/taskledger/cli_implement.py +5 -4
- {taskledger-0.4.0 → taskledger-0.4.2}/taskledger/cli_misc.py +26 -1
- taskledger-0.4.2/taskledger/cli_pipeline.py +166 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/taskledger/cli_plan.py +13 -5
- {taskledger-0.4.0 → taskledger-0.4.2}/taskledger/cli_release.py +30 -0
- taskledger-0.4.2/taskledger/cli_review.py +173 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/taskledger/cli_sync.py +44 -123
- {taskledger-0.4.0 → taskledger-0.4.2}/taskledger/cli_task.py +76 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/taskledger/cli_validate.py +5 -5
- {taskledger-0.4.0 → taskledger-0.4.2}/taskledger/command_inventory.py +167 -11
- {taskledger-0.4.0 → taskledger-0.4.2}/taskledger/domain/handoff.py +6 -1
- {taskledger-0.4.0 → taskledger-0.4.2}/taskledger/domain/models.py +1 -0
- taskledger-0.4.2/taskledger/domain/review.py +118 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/taskledger/domain/sidecars.py +50 -23
- {taskledger-0.4.0 → taskledger-0.4.2}/taskledger/domain/states.py +2 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/taskledger/exchange.py +22 -8
- {taskledger-0.4.0 → taskledger-0.4.2}/taskledger/services/change_tracking.py +2 -2
- {taskledger-0.4.0 → taskledger-0.4.2}/taskledger/services/check_tracking.py +1 -2
- taskledger-0.4.2/taskledger/services/code_review.py +351 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/taskledger/services/doctor_checks/task_checks.py +134 -1
- taskledger-0.4.2/taskledger/services/event_logging.py +15 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/taskledger/services/git_sync.py +56 -83
- taskledger-0.4.2/taskledger/services/git_utils.py +62 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/taskledger/services/handoff.py +72 -140
- {taskledger-0.4.0 → taskledger-0.4.2}/taskledger/services/html_reports.py +17 -48
- {taskledger-0.4.0 → taskledger-0.4.2}/taskledger/services/implementation_flow.py +7 -7
- taskledger-0.4.2/taskledger/services/markdown_html.py +67 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/taskledger/services/navigation.py +75 -2
- taskledger-0.4.2/taskledger/services/next_action_payload.py +564 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/taskledger/services/plan_editing.py +2 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/taskledger/services/plan_materialization.py +4 -4
- {taskledger-0.4.0 → taskledger-0.4.2}/taskledger/services/planning_flow.py +6 -6
- {taskledger-0.4.0 → taskledger-0.4.2}/taskledger/services/releases.py +170 -29
- {taskledger-0.4.0 → taskledger-0.4.2}/taskledger/services/run_store.py +11 -67
- {taskledger-0.4.0 → taskledger-0.4.2}/taskledger/services/storage_locations.py +12 -53
- {taskledger-0.4.0 → taskledger-0.4.2}/taskledger/services/task_archive.py +2 -2
- {taskledger-0.4.0 → taskledger-0.4.2}/taskledger/services/task_collections.py +4 -4
- taskledger-0.4.2/taskledger/services/task_events.py +73 -0
- taskledger-0.4.2/taskledger/services/task_export.py +512 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/taskledger/services/task_lifecycle.py +15 -18
- {taskledger-0.4.0 → taskledger-0.4.2}/taskledger/services/task_repair.py +3 -4
- {taskledger-0.4.0 → taskledger-0.4.2}/taskledger/services/task_reports.py +55 -2
- {taskledger-0.4.0 → taskledger-0.4.2}/taskledger/services/tasks.py +129 -545
- {taskledger-0.4.0 → taskledger-0.4.2}/taskledger/services/validation_flow.py +2 -2
- taskledger-0.4.2/taskledger/services/worker_context.py +208 -0
- taskledger-0.4.2/taskledger/services/worker_pipeline.py +225 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/taskledger/storage/ledger_config.py +1 -12
- {taskledger-0.4.0 → taskledger-0.4.2}/taskledger/storage/project_config.py +352 -13
- {taskledger-0.4.0 → taskledger-0.4.2}/taskledger/storage/project_identity.py +6 -17
- {taskledger-0.4.0 → taskledger-0.4.2}/taskledger/storage/task_store.py +45 -0
- taskledger-0.4.2/taskledger/storage/toml_edit.py +21 -0
- taskledger-0.4.2/taskledger/storage/worker_pipeline_config.py +419 -0
- taskledger-0.4.2/taskledger/templates/task_report.html +37 -0
- {taskledger-0.4.0 → taskledger-0.4.2/taskledger.egg-info}/PKG-INFO +159 -11
- {taskledger-0.4.0 → taskledger-0.4.2}/taskledger.egg-info/SOURCES.txt +116 -1
- {taskledger-0.4.0 → taskledger-0.4.2}/taskledger.egg-info/requires.txt +2 -0
- taskledger-0.4.2/tests/conftest.py +125 -0
- taskledger-0.4.2/tests/support/fake_command_runner.py +17 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/tests/test_active_task.py +5 -2
- {taskledger-0.4.0 → taskledger-0.4.2}/tests/test_actor_harness_state.py +3 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/tests/test_agent_command_logging.py +4 -2
- {taskledger-0.4.0 → taskledger-0.4.2}/tests/test_agent_session_protocol.py +23 -68
- taskledger-0.4.2/tests/test_code_reviews.py +303 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/tests/test_command_inventory.py +68 -6
- taskledger-0.4.2/tests/test_config_cli.py +300 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/tests/test_delta_remaining_contracts.py +22 -170
- {taskledger-0.4.0 → taskledger-0.4.2}/tests/test_docs_and_skill.py +123 -6
- {taskledger-0.4.0 → taskledger-0.4.2}/tests/test_doctor.py +79 -0
- taskledger-0.4.2/tests/test_event_logging_config.py +252 -0
- taskledger-0.4.2/tests/test_find_code_clones_script.py +99 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/tests/test_help_subprocess.py +33 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/tests/test_html_reports.py +88 -1
- {taskledger-0.4.0 → taskledger-0.4.2}/tests/test_implementation_change_scan.py +8 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/tests/test_json_contracts.py +174 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/tests/test_locks_audit.py +9 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/tests/test_plan_approval_contract.py +5 -2
- {taskledger-0.4.0 → taskledger-0.4.2}/tests/test_plan_revision_workflow.py +14 -1
- {taskledger-0.4.0 → taskledger-0.4.2}/tests/test_project_root_config.py +56 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/tests/test_question_filter_answers.py +19 -25
- {taskledger-0.4.0 → taskledger-0.4.2}/tests/test_release_changelog.py +282 -1
- {taskledger-0.4.0 → taskledger-0.4.2}/tests/test_serve_dashboard.py +16 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/tests/test_service_boundaries.py +25 -15
- {taskledger-0.4.0 → taskledger-0.4.2}/tests/test_storage_bundle_layout.py +5 -2
- {taskledger-0.4.0 → taskledger-0.4.2}/tests/test_storage_sync.py +49 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/tests/test_sync_git.py +112 -4
- {taskledger-0.4.0 → taskledger-0.4.2}/tests/test_task_events.py +13 -0
- taskledger-0.4.2/tests/test_task_markdown_export.py +479 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/tests/test_task_report.py +26 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/tests/test_taskledger_v2_exchange.py +167 -18
- {taskledger-0.4.0 → taskledger-0.4.2}/tests/test_tree_command.py +5 -2
- taskledger-0.4.2/tests/test_worker_pipeline_cli.py +627 -0
- taskledger-0.4.2/tests/test_worker_pipeline_config.py +279 -0
- taskledger-0.4.2/tests/test_worker_pipeline_context.py +210 -0
- taskledger-0.4.2/tests/test_worker_pipeline_handoff.py +163 -0
- taskledger-0.4.2/tests/test_worker_pipeline_plan_template.py +158 -0
- taskledger-0.4.2/tests/test_worker_pipeline_todos.py +241 -0
- taskledger-0.4.0/docs/public_surface.rst +0 -90
- taskledger-0.4.0/docs/service_boundary_whitelist.rst +0 -57
- taskledger-0.4.0/taskledger/templates/task_report.html +0 -218
- taskledger-0.4.0/tests/conftest.py +0 -13
- {taskledger-0.4.0 → taskledger-0.4.2}/.github/workflows/codecov.yml +0 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/.github/workflows/pre-commit.yml +0 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/.github/workflows/python-publish.yml +0 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/.github/workflows/tests.yml +0 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/.pre-commit-config.yaml +0 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/.readthedocs.yaml +0 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/.ruff.toml +0 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/LICENSE +0 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/Makefile +0 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/docs/Makefile +0 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/docs/build.sh +0 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/docs/conf.py +0 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/docs/multi_repo.rst +0 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/docs/requirements.txt +0 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/setup.cfg +0 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/setup.py +0 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/taskledger/__init__.py +0 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/taskledger/__main__.py +0 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/taskledger/api/introductions.py +0 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/taskledger/api/locks.py +0 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/taskledger/api/plans.py +0 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/taskledger/api/project.py +0 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/taskledger/api/questions.py +0 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/taskledger/api/releases.py +0 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/taskledger/api/search.py +0 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/taskledger/api/sync.py +0 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/taskledger/api/task_runs.py +0 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/taskledger/cli_actor.py +0 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/taskledger/cli_ledger.py +0 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/taskledger/cli_migrate.py +0 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/taskledger/cli_question.py +0 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/taskledger/cli_report.py +0 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/taskledger/cli_storage.py +0 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/taskledger/domain/__init__.py +0 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/taskledger/domain/_model_utils.py +0 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/taskledger/domain/active_state.py +0 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/taskledger/domain/actor.py +0 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/taskledger/domain/change.py +0 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/taskledger/domain/check.py +0 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/taskledger/domain/event.py +0 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/taskledger/domain/lock.py +0 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/taskledger/domain/plan.py +0 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/taskledger/domain/policies.py +0 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/taskledger/domain/question.py +0 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/taskledger/domain/release.py +0 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/taskledger/domain/run.py +0 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/taskledger/domain/task.py +0 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/taskledger/errors.py +0 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/taskledger/ids.py +0 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/taskledger/launcher.py +0 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/taskledger/py.typed +0 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/taskledger/search.py +0 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/taskledger/services/__init__.py +0 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/taskledger/services/actors.py +0 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/taskledger/services/agent_logging.py +0 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/taskledger/services/agent_transcripts.py +0 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/taskledger/services/command_runner.py +0 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/taskledger/services/dashboard.py +0 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/taskledger/services/doctor.py +0 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/taskledger/services/doctor_checks/migration_checks.py +0 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/taskledger/services/doctor_checks/project_scan.py +0 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/taskledger/services/handoff_lifecycle.py +0 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/taskledger/services/next_action_model.py +0 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/taskledger/services/phase5_lock_transfer.py +0 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/taskledger/services/plan_hash.py +0 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/taskledger/services/plan_lint.py +0 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/taskledger/services/plan_review.py +0 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/taskledger/services/serve_read_model.py +0 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/taskledger/services/task_queries.py +0 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/taskledger/services/tree.py +0 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/taskledger/services/validation.py +0 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/taskledger/services/web_dashboard.py +0 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/taskledger/services/workflow_guidance.py +0 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/taskledger/storage/__init__.py +0 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/taskledger/storage/agent_logs.py +0 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/taskledger/storage/atomic.py +0 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/taskledger/storage/common.py +0 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/taskledger/storage/events.py +0 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/taskledger/storage/frontmatter.py +0 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/taskledger/storage/indexes.py +0 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/taskledger/storage/init.py +0 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/taskledger/storage/locks.py +0 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/taskledger/storage/meta.py +0 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/taskledger/storage/migrations.py +0 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/taskledger/storage/paths.py +0 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/taskledger/storage/repos.py +0 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/taskledger/templates/__init__.py +0 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/taskledger/templates/base.html +0 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/taskledger/templates/error.html +0 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/taskledger/templates/site_index.html +0 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/taskledger/timeutils.py +0 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/taskledger.egg-info/dependency_links.txt +0 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/taskledger.egg-info/entry_points.txt +0 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/taskledger.egg-info/top_level.txt +0 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/tests/__init__.py +0 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/tests/support/__init__.py +0 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/tests/support/builders.py +0 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/tests/test_atomic_fast_io.py +0 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/tests/test_cli_command_contract.py +0 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/tests/test_cli_import_resilience.py +0 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/tests/test_command_example_linter.py +0 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/tests/test_compact_mutation_output.py +0 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/tests/test_domain_policies.py +0 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/tests/test_events.py +0 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/tests/test_handoff_lifecycle.py +0 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/tests/test_implementation_checks.py +0 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/tests/test_legacy_cleanup_contracts.py +0 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/tests/test_lifecycle_policies.py +0 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/tests/test_models_v1_schema.py +0 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/tests/test_next_action_expired_lock.py +0 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/tests/test_no_log_feature.py +0 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/tests/test_plan_lint.py +0 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/tests/test_plan_review.py +0 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/tests/test_plan_todo_materialization.py +0 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/tests/test_question_add_many.py +0 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/tests/test_question_plan_regeneration.py +0 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/tests/test_search.py +0 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/tests/test_services_dashboard.py +0 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/tests/test_sidecar_collections.py +0 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/tests/test_storage_common.py +0 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/tests/test_storage_init.py +0 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/tests/test_storage_migration.py +0 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/tests/test_storage_repos.py +0 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/tests/test_task_archive.py +0 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/tests/test_taskledger_branch_scoped_ledgers.py +0 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/tests/test_taskledger_cli_api_parity.py +0 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/tests/test_taskledger_v2_cli.py +0 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/tests/test_tasks_service_static.py +0 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/tests/test_todo_implementation_gate.py +0 -0
- {taskledger-0.4.0 → taskledger-0.4.2}/tests/test_workflow_guidance.py +0 -0
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
---
|
|
2
|
+
schema_version: 2
|
|
3
|
+
id: al_block_0029
|
|
4
|
+
type: white_box
|
|
5
|
+
title: "taskledger system"
|
|
6
|
+
status: proposed
|
|
7
|
+
section: building_block_view
|
|
8
|
+
level: 1
|
|
9
|
+
parent: null
|
|
10
|
+
order: 10
|
|
11
|
+
date: "2026-05-23"
|
|
12
|
+
diagram: null
|
|
13
|
+
quality_characteristics: []
|
|
14
|
+
tags: []
|
|
15
|
+
body_format: markdown
|
|
16
|
+
created_at: "2026-05-23T12:30:16Z"
|
|
17
|
+
updated_at: "2026-05-23T12:30:16Z"
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## Motivation
|
|
21
|
+
|
|
22
|
+
taskledger decomposes into five layers with strict downward dependency flow. This decomposition isolates I/O (storage), business rules (domain), orchestration (services), and presentation (CLI/API).
|
|
23
|
+
|
|
24
|
+
## Contained building blocks
|
|
25
|
+
|
|
26
|
+
1. **CLI Layer** (`al_block_0030`) — Typer commands, argument parsing, output rendering
|
|
27
|
+
2. **API Layer** (`al_block_0031`) — Stable Python function wrappers
|
|
28
|
+
3. **Services Layer** (`al_block_0032`) — Lifecycle orchestration, handoffs, inspection
|
|
29
|
+
4. **Domain Layer** (`al_block_0033`) — Models, state machines, policies (no I/O)
|
|
30
|
+
5. **Storage Layer** (`al_block_0034`) — File system persistence, atomic writes, layout
|
|
31
|
+
|
|
32
|
+
## Important interfaces
|
|
33
|
+
|
|
34
|
+
- CLI → Services: function calls with `workspace_root` + task references
|
|
35
|
+
- Services → Domain: policy functions take `PolicyContext`, return `Decision`
|
|
36
|
+
- Services → Storage: record CRUD operations via `task_store.py` functions
|
|
37
|
+
- API → Services: direct function calls mirroring CLI behavior
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
---
|
|
2
|
+
schema_version: 2
|
|
3
|
+
id: al_block_0030
|
|
4
|
+
type: black_box
|
|
5
|
+
title: "CLI Layer"
|
|
6
|
+
status: accepted
|
|
7
|
+
section: building_block_view
|
|
8
|
+
level: 1
|
|
9
|
+
parent: al_block_0029
|
|
10
|
+
order: 10
|
|
11
|
+
date: "2026-05-23"
|
|
12
|
+
interfaces: []
|
|
13
|
+
location: []
|
|
14
|
+
fulfilled_requirements: []
|
|
15
|
+
risks: []
|
|
16
|
+
tags: []
|
|
17
|
+
body_format: markdown
|
|
18
|
+
created_at: "2026-05-23T12:30:23Z"
|
|
19
|
+
updated_at: "2026-05-23T12:30:23Z"
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
Handles command parsing via Typer, task reference resolution (`--task` option, active task default), and output rendering (human text or JSON envelope via `cli_common.py`). Registers 41 command groups from `COMMAND_METADATA`: `actor`, `can`, `commands`, `context`, `deps`, `doctor`, `export`, `file`, `grep`, `handoff`, `harness`, `implement`, `import`, `init`, `intro`, `ledger`, `link`, `lock`, `migrate`, `next-action`, `pipeline`, `plan`, `question`, `reindex`, `release`, `repair`, `report`, `require`, `review`, `search`, `serve`, `snapshot`, `status`, `storage`, `sync`, `symbols`, `task`, `todo`, `tree`, `validate`, `view`. The `review` group provides code-review record support (`review record`, `review list`, `review show`).
|
|
23
|
+
|
|
24
|
+
Source refs: `taskledger/cli.py`, `taskledger/cli_common.py`, `taskledger/cli_task.py`, `taskledger/cli_plan.py`, `taskledger/cli_implement.py`, `taskledger/cli_validate.py`, `taskledger/cli_misc.py`.
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
---
|
|
2
|
+
schema_version: 2
|
|
3
|
+
id: al_block_0031
|
|
4
|
+
type: black_box
|
|
5
|
+
title: "API Layer"
|
|
6
|
+
status: proposed
|
|
7
|
+
section: building_block_view
|
|
8
|
+
level: 1
|
|
9
|
+
parent: al_block_0029
|
|
10
|
+
order: 20
|
|
11
|
+
date: "2026-05-23"
|
|
12
|
+
interfaces: []
|
|
13
|
+
location: []
|
|
14
|
+
fulfilled_requirements: []
|
|
15
|
+
risks: []
|
|
16
|
+
tags: []
|
|
17
|
+
body_format: markdown
|
|
18
|
+
created_at: "2026-05-23T12:30:27Z"
|
|
19
|
+
updated_at: "2026-05-23T12:30:27Z"
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
Stable Python function wrappers under `taskledger/api/` that mirror the CLI surface for programmatic use. Each module (tasks, plans, handoff, locks, etc.) exposes functions that accept workspace paths and return dictionaries matching the JSON output shape. The API layer calls Services directly.
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
---
|
|
2
|
+
schema_version: 2
|
|
3
|
+
id: al_block_0032
|
|
4
|
+
type: black_box
|
|
5
|
+
title: "Services Layer"
|
|
6
|
+
status: proposed
|
|
7
|
+
section: building_block_view
|
|
8
|
+
level: 1
|
|
9
|
+
parent: al_block_0029
|
|
10
|
+
order: 30
|
|
11
|
+
date: "2026-05-23"
|
|
12
|
+
interfaces: []
|
|
13
|
+
location: []
|
|
14
|
+
fulfilled_requirements: []
|
|
15
|
+
risks: []
|
|
16
|
+
tags: []
|
|
17
|
+
body_format: markdown
|
|
18
|
+
created_at: "2026-05-23T12:30:29Z"
|
|
19
|
+
updated_at: "2026-05-23T12:30:29Z"
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
Orchestrates lifecycle flows by coordinating between Domain (policies, models) and Storage (persistence). Key modules: `tasks.py` (core lifecycle operations), `planning_flow.py`, `implementation_flow.py`, `validation_flow.py`, `handoff.py` + `handoff_lifecycle.py`, `doctor.py`, `navigation.py`, `worker_pipeline.py`, `dashboard.py`. Services gather context from storage, call domain policies, and persist results.
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
---
|
|
2
|
+
schema_version: 2
|
|
3
|
+
id: al_block_0033
|
|
4
|
+
type: black_box
|
|
5
|
+
title: "Domain Layer"
|
|
6
|
+
status: proposed
|
|
7
|
+
section: building_block_view
|
|
8
|
+
level: 1
|
|
9
|
+
parent: al_block_0029
|
|
10
|
+
order: 40
|
|
11
|
+
date: "2026-05-23"
|
|
12
|
+
interfaces: []
|
|
13
|
+
location: []
|
|
14
|
+
fulfilled_requirements: []
|
|
15
|
+
risks: []
|
|
16
|
+
tags: []
|
|
17
|
+
body_format: markdown
|
|
18
|
+
created_at: "2026-05-23T12:30:29Z"
|
|
19
|
+
updated_at: "2026-05-23T12:30:29Z"
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
Pure data models, state enums, normalization, and policy decisions with zero I/O dependencies. Defines `TaskRecord`, `PlanRecord`, `TaskRunRecord`, `TaskLock`, `TaskHandoffRecord`, `TaskEvent`, `ActorRef`, `HarnessRef`, and sidecar types (`TaskTodo`, `FileLink`, `AcceptanceCriterion`, `ValidationCheck`). State machine transitions in `states.py`. Policy decisions in `policies.py` return `Decision` objects. All models have `to_dict()` / `from_dict()` for serialization.
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
---
|
|
2
|
+
schema_version: 2
|
|
3
|
+
id: al_block_0034
|
|
4
|
+
type: black_box
|
|
5
|
+
title: "Storage Layer"
|
|
6
|
+
status: proposed
|
|
7
|
+
section: building_block_view
|
|
8
|
+
level: 1
|
|
9
|
+
parent: al_block_0029
|
|
10
|
+
order: 50
|
|
11
|
+
date: "2026-05-23"
|
|
12
|
+
interfaces: []
|
|
13
|
+
location: []
|
|
14
|
+
fulfilled_requirements: []
|
|
15
|
+
risks: []
|
|
16
|
+
tags: []
|
|
17
|
+
body_format: markdown
|
|
18
|
+
created_at: "2026-05-23T12:30:29Z"
|
|
19
|
+
updated_at: "2026-05-23T12:30:29Z"
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
File system persistence for all canonical records. Implements the v2 task bundle layout where each task is a directory under `.taskledger/ledgers/<ledger_ref>/` with sidecar collections for plans, runs, locks, todos, questions, changes, checks, handoffs, and links. Event logging is opt-in (disabled by default) via `[event_logging] enabled = true`; when enabled, append-only `TaskEvent` records are stored in the ledger-level `events/` directory, not per-task sidecars. Key modules: `task_store.py` (CRUD, layout resolution), `frontmatter.py` (YAML/Markdown serialization), `atomic.py` (atomic writes), `locks.py` (lock file operations), `indexes.py` (index rebuilds), `events.py` (append-only event log), `paths.py` (project discovery), `project_config.py` (taskledger.toml parsing), `migrations.py` (storage version upgrades).
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
---
|
|
2
|
+
schema_version: 2
|
|
3
|
+
id: al_concept_0040
|
|
4
|
+
type: concept
|
|
5
|
+
title: "Actor metadata and role semantics"
|
|
6
|
+
status: proposed
|
|
7
|
+
section: cross_cutting_concepts
|
|
8
|
+
order: 10
|
|
9
|
+
date: "2026-05-23"
|
|
10
|
+
applies_to: []
|
|
11
|
+
body_format: markdown
|
|
12
|
+
created_at: "2026-05-23T12:30:59Z"
|
|
13
|
+
updated_at: "2026-05-23T12:30:59Z"
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
Every mutation carries an `ActorRef` (type: agent/user/system, name, role, session ID, harness ID) and optionally a `HarnessRef` (harness identity, kind, capabilities). The system distinguishes user-only actions (plan approval, criterion waivers) from agent actions. Actor metadata is persisted in locks, runs, events, and handoff records for audit trails.
|
|
17
|
+
|
|
18
|
+
Source: `taskledger/domain/actor.py` (`ActorRef`, `HarnessRef`), `taskledger/domain/states.py` (`ActorType`, `ActorRole`, `HarnessKind`).
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
---
|
|
2
|
+
schema_version: 2
|
|
3
|
+
id: al_concept_0041
|
|
4
|
+
type: concept
|
|
5
|
+
title: "JSON output envelope contract"
|
|
6
|
+
status: proposed
|
|
7
|
+
section: cross_cutting_concepts
|
|
8
|
+
order: 20
|
|
9
|
+
date: "2026-05-23"
|
|
10
|
+
applies_to: []
|
|
11
|
+
body_format: markdown
|
|
12
|
+
created_at: "2026-05-23T12:31:00Z"
|
|
13
|
+
updated_at: "2026-05-23T12:31:00Z"
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
When `--json` is passed, every CLI command emits a JSON envelope: `{"ok": bool, "command": str, "result_type": str, "result": ..., "events": [...], "warnings": [...]}`. On error, the envelope includes `error` with `code`, `message`, `details`, and `remediation`. This shape is a public API contract tested by `test_json_contracts.py`. Exit codes map deterministically to error categories.
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
---
|
|
2
|
+
schema_version: 2
|
|
3
|
+
id: al_concept_0042
|
|
4
|
+
type: concept
|
|
5
|
+
title: "YAML front matter serialization"
|
|
6
|
+
status: proposed
|
|
7
|
+
section: cross_cutting_concepts
|
|
8
|
+
order: 30
|
|
9
|
+
date: "2026-05-23"
|
|
10
|
+
applies_to: []
|
|
11
|
+
body_format: markdown
|
|
12
|
+
created_at: "2026-05-23T12:31:00Z"
|
|
13
|
+
updated_at: "2026-05-23T12:31:00Z"
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
All canonical records are `.md` files with YAML front matter (`---` delimited) containing structured metadata and a Markdown body. Read/write is handled by `read_markdown_front_matter` and `write_markdown_front_matter` in `taskledger/storage/frontmatter.py`. Models implement `to_dict()` / `from_dict()` for serialization. Schema version and object type fields enforce contract integrity on read.
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
---
|
|
2
|
+
schema_version: 2
|
|
3
|
+
id: al_concept_0043
|
|
4
|
+
type: concept
|
|
5
|
+
title: "Atomic file writes"
|
|
6
|
+
status: proposed
|
|
7
|
+
section: cross_cutting_concepts
|
|
8
|
+
order: 40
|
|
9
|
+
date: "2026-05-23"
|
|
10
|
+
applies_to: []
|
|
11
|
+
body_format: markdown
|
|
12
|
+
created_at: "2026-05-23T12:31:01Z"
|
|
13
|
+
updated_at: "2026-05-23T12:31:01Z"
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
All file writes go through `atomic_write_text` (temp file → flush/fsync → `os.replace` → directory fsync) or `atomic_create_text` (`O_CREAT | O_EXCL` for lock files). This prevents partial writes on crash. Test environments can disable fsync via `TASKLEDGER_TEST_FAST_IO=1` for speed. Source: `taskledger/storage/atomic.py`.
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
---
|
|
2
|
+
schema_version: 2
|
|
3
|
+
id: al_concept_0044
|
|
4
|
+
type: concept
|
|
5
|
+
title: "Append-only event log"
|
|
6
|
+
status: proposed
|
|
7
|
+
section: cross_cutting_concepts
|
|
8
|
+
order: 50
|
|
9
|
+
date: "2026-05-23"
|
|
10
|
+
applies_to: []
|
|
11
|
+
body_format: markdown
|
|
12
|
+
created_at: "2026-05-23T12:31:01Z"
|
|
13
|
+
updated_at: "2026-05-23T12:31:01Z"
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
When `[event_logging] enabled = true` in `taskledger.toml`, mutations append an immutable `TaskEvent` record to the ledger-level `events/` directory under `.taskledger/ledgers/<ledger_ref>/`. Event logging is disabled by default; when disabled, no new event records are written but existing records remain readable. Events are never modified or deleted. Each event has a deterministic ID, name (e.g., `task.created`, `plan.approved`, `lock.acquired`, `code_review.recorded`), timestamp, and actor metadata. Events support audit trails, handoff context, and `task transcript` output. Duplicate event detection prevents re-appending on retry. Source: `taskledger/storage/events.py`, `taskledger/services/task_events.py`, `taskledger/domain/event.py`.
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
---
|
|
2
|
+
schema_version: 2
|
|
3
|
+
id: al_concept_0045
|
|
4
|
+
type: concept
|
|
5
|
+
title: "Exit code taxonomy"
|
|
6
|
+
status: proposed
|
|
7
|
+
section: cross_cutting_concepts
|
|
8
|
+
order: 60
|
|
9
|
+
date: "2026-05-23"
|
|
10
|
+
applies_to: []
|
|
11
|
+
body_format: markdown
|
|
12
|
+
created_at: "2026-05-23T12:31:01Z"
|
|
13
|
+
updated_at: "2026-05-23T12:31:01Z"
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
Stable exit codes for CLI and error classification: 0 (success), 1 (generic failure), 2 (bad input), 3 (workflow rejection — invalid transition, approval required, dependency blocked), 4 (lock conflict — stale lock requires break), 5 (not found / no active task), 6 (storage error / data integrity), 7 (validation failed). Defined in `taskledger/domain/states.py` and `taskledger/errors.py`. Agents and CI pipelines rely on specific codes for automation.
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
---
|
|
2
|
+
schema_version: 2
|
|
3
|
+
id: al_constraint_0016
|
|
4
|
+
type: constraint
|
|
5
|
+
title: "Python 3.10+ with minimal dependencies"
|
|
6
|
+
status: proposed
|
|
7
|
+
section: architecture_constraints
|
|
8
|
+
order: 10
|
|
9
|
+
date: "2026-05-23"
|
|
10
|
+
category: technical
|
|
11
|
+
impact: "Limits runtime to Python 3.10+ with five dependencies; no database or native extensions."
|
|
12
|
+
body_format: markdown
|
|
13
|
+
created_at: "2026-05-23T12:29:53Z"
|
|
14
|
+
updated_at: "2026-05-23T12:29:53Z"
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
Runtime dependencies are limited to `typer`, `PyYAML`, `Jinja2`, `markdown-it-py`, and `tomli` (Python <3.11 only). This constraint ensures easy installation in constrained environments (CI, containers, Termux) and avoids dependency conflicts with host projects. The trade-off is that features like full-text search use pure-Python implementations rather than native libraries.
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
---
|
|
2
|
+
schema_version: 2
|
|
3
|
+
id: al_constraint_0017
|
|
4
|
+
type: constraint
|
|
5
|
+
title: "File-system canonical storage"
|
|
6
|
+
status: proposed
|
|
7
|
+
section: architecture_constraints
|
|
8
|
+
order: 20
|
|
9
|
+
date: "2026-05-23"
|
|
10
|
+
category: technical
|
|
11
|
+
impact: "State is file-based; query performance depends on index rebuilds."
|
|
12
|
+
body_format: markdown
|
|
13
|
+
created_at: "2026-05-23T12:29:54Z"
|
|
14
|
+
updated_at: "2026-05-23T12:29:54Z"
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
All durable state is stored as Markdown files with YAML front matter in `.taskledger/`. This makes state human-readable, diffable in Git, and inspectable without taskledger. The trade-off is that query performance depends on file scanning and index rebuilding rather than a database engine.
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
---
|
|
2
|
+
schema_version: 2
|
|
3
|
+
id: al_constraint_0018
|
|
4
|
+
type: constraint
|
|
5
|
+
title: "CLI-first with machine-readable JSON output"
|
|
6
|
+
status: proposed
|
|
7
|
+
section: architecture_constraints
|
|
8
|
+
order: 30
|
|
9
|
+
date: "2026-05-23"
|
|
10
|
+
category: technical
|
|
11
|
+
impact: "JSON envelope shape and exit codes are public API contracts; breaking changes require version bumps."
|
|
12
|
+
body_format: markdown
|
|
13
|
+
created_at: "2026-05-23T12:29:54Z"
|
|
14
|
+
updated_at: "2026-05-23T12:29:54Z"
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
The CLI is the primary interface. Every command supports `--json` for machine-readable output with a stable envelope shape (`ok`, `command`, `result_type`, `result`, `events`, `warnings`) and deterministic exit codes. This enables agent harnesses and CI pipelines to consume output programmatically without parsing human text.
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
---
|
|
2
|
+
schema_version: 2
|
|
3
|
+
id: al_constraint_0019
|
|
4
|
+
type: constraint
|
|
5
|
+
title: "Skills must stay outside the Python package"
|
|
6
|
+
status: proposed
|
|
7
|
+
section: architecture_constraints
|
|
8
|
+
order: 40
|
|
9
|
+
date: "2026-05-23"
|
|
10
|
+
category: technical
|
|
11
|
+
impact: "Skill distribution is separate from package distribution; skill installation is a distinct step."
|
|
12
|
+
body_format: markdown
|
|
13
|
+
created_at: "2026-05-23T12:29:55Z"
|
|
14
|
+
updated_at: "2026-05-23T12:29:55Z"
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
Agent skill files (e.g., `skills/taskledger/SKILL.md`) live outside the `taskledger` Python package. They are not packaged as package data, not loaded via `importlib.resources`, and not distributed via PyPI. This separates the concerns of tool functionality (the package) from agent integration instructions (the skill).
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
---
|
|
2
|
+
schema_version: 2
|
|
3
|
+
id: al_context_0020
|
|
4
|
+
type: context_interface
|
|
5
|
+
title: "Agent harnesses"
|
|
6
|
+
status: proposed
|
|
7
|
+
section: context_and_scope
|
|
8
|
+
order: 10
|
|
9
|
+
date: "2026-05-23"
|
|
10
|
+
context_kind: "technical"
|
|
11
|
+
partner: "agent harness (opencode, codex, chatgpt)"
|
|
12
|
+
inputs: []
|
|
13
|
+
outputs: []
|
|
14
|
+
channels: []
|
|
15
|
+
body_format: markdown
|
|
16
|
+
created_at: "2026-05-23T12:29:55Z"
|
|
17
|
+
updated_at: "2026-05-23T12:29:55Z"
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
Agent harnesses invoke taskledger CLI commands as subprocesses. They consume `--json` output and rely on exit codes for automation. Key interactions: `task create`, `plan start`, `plan propose`, `implement start`, `implement log`, `validate start`, `validate check`, `handoff create`, `handoff claim`, `context`. Agents are restricted from user-only actions (plan approval, criterion waivers) by default.
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
---
|
|
2
|
+
schema_version: 2
|
|
3
|
+
id: al_context_0021
|
|
4
|
+
type: context_interface
|
|
5
|
+
title: "Human developers"
|
|
6
|
+
status: proposed
|
|
7
|
+
section: context_and_scope
|
|
8
|
+
order: 20
|
|
9
|
+
date: "2026-05-23"
|
|
10
|
+
context_kind: "technical"
|
|
11
|
+
partner: "terminal user"
|
|
12
|
+
inputs: []
|
|
13
|
+
outputs: []
|
|
14
|
+
channels: []
|
|
15
|
+
body_format: markdown
|
|
16
|
+
created_at: "2026-05-23T12:29:55Z"
|
|
17
|
+
updated_at: "2026-05-23T12:29:55Z"
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
Human developers use the CLI directly in terminals. Key interactions: `task create`, `task show`, `plan approve`, `implement finish`, `validate finish`, `lock break`, `doctor`, `status`, `next-action`. Humans render human-readable output (default) and perform user-only actions like plan approval and criterion waivers.
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
---
|
|
2
|
+
schema_version: 2
|
|
3
|
+
id: al_context_0022
|
|
4
|
+
type: context_interface
|
|
5
|
+
title: "CI systems"
|
|
6
|
+
status: proposed
|
|
7
|
+
section: context_and_scope
|
|
8
|
+
order: 30
|
|
9
|
+
date: "2026-05-23"
|
|
10
|
+
context_kind: "technical"
|
|
11
|
+
partner: "CI runner"
|
|
12
|
+
inputs: []
|
|
13
|
+
outputs: []
|
|
14
|
+
channels: []
|
|
15
|
+
body_format: markdown
|
|
16
|
+
created_at: "2026-05-23T12:29:56Z"
|
|
17
|
+
updated_at: "2026-05-23T12:29:56Z"
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
CI runners invoke taskledger commands in automated pipelines. Key interactions: `status --json`, `doctor`, `validate`, `export`, `snapshot`. CI relies on deterministic exit codes to gate pipeline stages.
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
---
|
|
2
|
+
schema_version: 2
|
|
3
|
+
id: al_context_0023
|
|
4
|
+
type: context_interface
|
|
5
|
+
title: "Python library consumers"
|
|
6
|
+
status: proposed
|
|
7
|
+
section: context_and_scope
|
|
8
|
+
order: 40
|
|
9
|
+
date: "2026-05-23"
|
|
10
|
+
context_kind: "technical"
|
|
11
|
+
partner: "Python import"
|
|
12
|
+
inputs: []
|
|
13
|
+
outputs: []
|
|
14
|
+
channels: []
|
|
15
|
+
body_format: markdown
|
|
16
|
+
created_at: "2026-05-23T12:29:56Z"
|
|
17
|
+
updated_at: "2026-05-23T12:29:56Z"
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
Python code imports from `taskledger.api.*` modules to manage tasks programmatically. The API layer (`taskledger/api/tasks.py`, `taskledger/api/plans.py`, etc.) provides function wrappers that mirror CLI operations without subprocess overhead. Returns dictionaries with the same shapes as JSON output.
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
---
|
|
2
|
+
schema_version: 2
|
|
3
|
+
id: al_adr_0046
|
|
4
|
+
type: adr
|
|
5
|
+
title: "Markdown/YAML front matter as canonical format"
|
|
6
|
+
status: accepted
|
|
7
|
+
section: architecture_decisions
|
|
8
|
+
order: 10
|
|
9
|
+
date: "2026-05-23"
|
|
10
|
+
deciders: []
|
|
11
|
+
supersedes: []
|
|
12
|
+
related: []
|
|
13
|
+
tags: []
|
|
14
|
+
body_format: markdown
|
|
15
|
+
created_at: "2026-05-23T12:31:02Z"
|
|
16
|
+
updated_at: "2026-05-23T12:31:02Z"
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## Context
|
|
20
|
+
|
|
21
|
+
Need a storage format for task state that is durable, human-readable, and version-controllable. Agents and humans need to inspect state without running taskledger.
|
|
22
|
+
|
|
23
|
+
## Decision
|
|
24
|
+
|
|
25
|
+
Store all records as Markdown files with YAML front matter (`---` delimited). Metadata (ID, type, status, dates) goes in YAML; free-form content goes in Markdown body.
|
|
26
|
+
|
|
27
|
+
## Consequences
|
|
28
|
+
|
|
29
|
+
- Positive: State is Git-diffable, human-readable, and editable in any text editor.
|
|
30
|
+
- Positive: No database dependency.
|
|
31
|
+
- Negative: Parsing is slower than binary formats for large datasets.
|
|
32
|
+
- Negative: Schema evolution requires careful validation on read.
|
|
33
|
+
|
|
34
|
+
## Alternatives considered
|
|
35
|
+
|
|
36
|
+
- SQLite: Faster queries but opaque binary format, harder to version-control and inspect.
|
|
37
|
+
- Pure JSON: Easier parsing but not human-friendly for long-form content (plan bodies, handoff contexts).
|
|
38
|
+
- Single JSON index file: Rejected due to merge conflicts and scalability concerns.
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
---
|
|
2
|
+
schema_version: 2
|
|
3
|
+
id: al_adr_0047
|
|
4
|
+
type: adr
|
|
5
|
+
title: "JSON indexes as derived rebuildable caches"
|
|
6
|
+
status: accepted
|
|
7
|
+
section: architecture_decisions
|
|
8
|
+
order: 20
|
|
9
|
+
date: "2026-05-23"
|
|
10
|
+
deciders: []
|
|
11
|
+
supersedes: []
|
|
12
|
+
related: []
|
|
13
|
+
tags: []
|
|
14
|
+
body_format: markdown
|
|
15
|
+
created_at: "2026-05-23T12:31:02Z"
|
|
16
|
+
updated_at: "2026-05-23T12:31:02Z"
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## Context
|
|
20
|
+
|
|
21
|
+
Listing tasks, locks, and dependencies requires scanning many front matter files. Need a way to speed up queries without adding a database.
|
|
22
|
+
|
|
23
|
+
## Decision
|
|
24
|
+
|
|
25
|
+
Maintain JSON index files under `.taskledger/indexes/` as derived caches. They are rebuilt from canonical records by `taskledger reindex` and checked by `doctor indexes`. They are never the source of truth.
|
|
26
|
+
|
|
27
|
+
## Consequences
|
|
28
|
+
|
|
29
|
+
- Positive: Fast list/query operations without parsing all front matter files.
|
|
30
|
+
- Positive: Indexes can always be rebuilt from canonical source.
|
|
31
|
+
- Negative: Indexes can become stale after manual edits or crashes.
|
|
32
|
+
- Negative: `reindex` must be run after out-of-band changes.
|
|
33
|
+
|
|
34
|
+
## Alternatives considered
|
|
35
|
+
|
|
36
|
+
- No indexes (always scan files): Simpler but too slow for large projects.
|
|
37
|
+
- SQLite index: More robust but adds complexity and dependency.
|
|
38
|
+
- In-memory cache: Lost on process restart, not durable.
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
---
|
|
2
|
+
schema_version: 2
|
|
3
|
+
id: al_adr_0048
|
|
4
|
+
type: adr
|
|
5
|
+
title: "Explicit lifecycle gates with policy decisions"
|
|
6
|
+
status: accepted
|
|
7
|
+
section: architecture_decisions
|
|
8
|
+
order: 30
|
|
9
|
+
date: "2026-05-23"
|
|
10
|
+
deciders: []
|
|
11
|
+
supersedes: []
|
|
12
|
+
related: []
|
|
13
|
+
tags: []
|
|
14
|
+
body_format: markdown
|
|
15
|
+
created_at: "2026-05-23T12:31:02Z"
|
|
16
|
+
updated_at: "2026-05-23T12:31:02Z"
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## Context
|
|
20
|
+
|
|
21
|
+
Without lifecycle gates, agents could skip review and implement without approval. Need enforceable transitions between task stages.
|
|
22
|
+
|
|
23
|
+
## Decision
|
|
24
|
+
|
|
25
|
+
Implement lifecycle gates as pure policy functions in `taskledger/domain/policies.py`. Each gate function takes a `PolicyContext` (task, lock, run) and returns a `Decision` (allowed, code, message, exit_code). The state machine in `states.py` defines `ALLOWED_STAGE_TRANSITIONS`. Services call policies before mutating state.
|
|
26
|
+
|
|
27
|
+
## Consequences
|
|
28
|
+
|
|
29
|
+
- Positive: Gate logic is fully testable without I/O setup.
|
|
30
|
+
- Positive: User-only actions (approval, waivers) are enforced at the policy level.
|
|
31
|
+
- Negative: Services must gather full context before calling policies.
|
|
32
|
+
|
|
33
|
+
## Alternatives considered
|
|
34
|
+
|
|
35
|
+
- Free-form state changes: Rejected — agents could bypass review.
|
|
36
|
+
- Database triggers: Rejected — adds database dependency and complexity.
|
|
37
|
+
- CLI-only validation: Rejected — API and programmatic users would bypass gates.
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
---
|
|
2
|
+
schema_version: 2
|
|
3
|
+
id: al_adr_0049
|
|
4
|
+
type: adr
|
|
5
|
+
title: "Typer CLI framework"
|
|
6
|
+
status: accepted
|
|
7
|
+
section: architecture_decisions
|
|
8
|
+
order: 40
|
|
9
|
+
date: "2026-05-23"
|
|
10
|
+
deciders: []
|
|
11
|
+
supersedes: []
|
|
12
|
+
related: []
|
|
13
|
+
tags: []
|
|
14
|
+
body_format: markdown
|
|
15
|
+
created_at: "2026-05-23T12:31:03Z"
|
|
16
|
+
updated_at: "2026-05-23T12:31:03Z"
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## Context
|
|
20
|
+
|
|
21
|
+
Need a CLI framework that supports subcommand groups, type-annotated parameters, and integrates with Click's ecosystem.
|
|
22
|
+
|
|
23
|
+
## Decision
|
|
24
|
+
|
|
25
|
+
Use Typer (built on Click) for the CLI. Typer provides type-annotated parameters, subcommand groups, and automatic help generation. The root app in `cli.py` registers nested Typer apps for each command family.
|
|
26
|
+
|
|
27
|
+
## Consequences
|
|
28
|
+
|
|
29
|
+
- Positive: Clean type-annotated parameter definitions with `Annotated` types.
|
|
30
|
+
- Positive: Click ecosystem compatibility (middleware, testing).
|
|
31
|
+
- Negative: Typer adds `click` as a transitive dependency.
|
|
32
|
+
|
|
33
|
+
## Alternatives considered
|
|
34
|
+
|
|
35
|
+
- Pure Click: More verbose parameter definitions, no type annotation inference.
|
|
36
|
+
- Argparse: Standard library but lacks subcommand ergonomics and type inference.
|
|
37
|
+
- Docopt: Declarative but harder to compose nested subcommands.
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
---
|
|
2
|
+
schema_version: 2
|
|
3
|
+
id: al_adr_0050
|
|
4
|
+
type: adr
|
|
5
|
+
title: "Task bundle directory layout"
|
|
6
|
+
status: accepted
|
|
7
|
+
section: architecture_decisions
|
|
8
|
+
order: 50
|
|
9
|
+
date: "2026-05-23"
|
|
10
|
+
deciders: []
|
|
11
|
+
supersedes: []
|
|
12
|
+
related: []
|
|
13
|
+
tags: []
|
|
14
|
+
body_format: markdown
|
|
15
|
+
created_at: "2026-05-23T12:31:03Z"
|
|
16
|
+
updated_at: "2026-05-23T12:31:03Z"
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## Context
|
|
20
|
+
|
|
21
|
+
Need a storage layout that scales to many sidecar collections per task (plans, runs, locks, todos, questions, changes, checks, handoffs, links) while keeping each record individually addressable. Events are stored at ledger level, not per-task, and are opt-in.
|
|
22
|
+
|
|
23
|
+
## Decision
|
|
24
|
+
|
|
25
|
+
Use a directory-per-task layout (v2 bundle) under `.taskledger/ledgers/<ledger_ref>/`. Each task gets a directory containing the task record (Markdown) and subdirectories for sidecar collections. JSON indexes are derived caches at the ledger level. Event records are stored in the ledger-level `events/` directory (not per-task) and are only written when `[event_logging] enabled = true`.
|
|
26
|
+
|
|
27
|
+
## Consequences
|
|
28
|
+
|
|
29
|
+
- Positive: Each record is a single file — easy to read, edit, and version-control.
|
|
30
|
+
- Positive: Sidecar collections are independently addressable.
|
|
31
|
+
- Negative: Many small files create directory overhead on very large projects.
|
|
32
|
+
|
|
33
|
+
## Alternatives considered
|
|
34
|
+
|
|
35
|
+
- Single JSON index file: Merge conflicts, scalability, not human-readable.
|
|
36
|
+
- Database (SQLite): Opaque, harder to inspect and version-control.
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
---
|
|
2
|
+
schema_version: 2
|
|
3
|
+
id: al_adr_0051
|
|
4
|
+
type: adr
|
|
5
|
+
title: "External skill packaging"
|
|
6
|
+
status: accepted
|
|
7
|
+
section: architecture_decisions
|
|
8
|
+
order: 60
|
|
9
|
+
date: "2026-05-23"
|
|
10
|
+
deciders: []
|
|
11
|
+
supersedes: []
|
|
12
|
+
related: []
|
|
13
|
+
tags: []
|
|
14
|
+
body_format: markdown
|
|
15
|
+
created_at: "2026-05-23T12:31:04Z"
|
|
16
|
+
updated_at: "2026-05-23T12:31:04Z"
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## Context
|
|
20
|
+
|
|
21
|
+
Agent skill files (SKILL.md) provide integration instructions for coding agents. Need to decide where they live relative to the Python package.
|
|
22
|
+
|
|
23
|
+
## Decision
|
|
24
|
+
|
|
25
|
+
Skills live under `skills/taskledger/` in the repository, outside the `taskledger` Python package. They are not packaged as Python package data, not loaded via `importlib.resources`, and not distributed via PyPI as part of the package.
|
|
26
|
+
|
|
27
|
+
## Consequences
|
|
28
|
+
|
|
29
|
+
- Positive: Clean separation between tool functionality and agent integration instructions.
|
|
30
|
+
- Positive: Skills can be versioned independently and distributed through different channels.
|
|
31
|
+
- Negative: Skill installation is a separate step from package installation.
|
|
32
|
+
|
|
33
|
+
## Alternatives considered
|
|
34
|
+
|
|
35
|
+
- Package skills as package data: Coupling skill version to package version, harder to update independently.
|
|
36
|
+
- Load skills via importlib.resources: Adds packaging complexity and coupling.
|