project-loop-harness 0.2.3__tar.gz → 0.3.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.
- {project_loop_harness-0.2.3/src/project_loop_harness.egg-info → project_loop_harness-0.3.0}/PKG-INFO +3 -1
- project_loop_harness-0.3.0/agent-tasks/0102-source-drift-health-warning.md +62 -0
- project_loop_harness-0.3.0/agent-tasks/0103-security-policy-v02x.md +46 -0
- project_loop_harness-0.3.0/agent-tasks/0104-python-ci-matrix.md +44 -0
- project_loop_harness-0.3.0/agent-tasks/0105-evidence-copy-observability.md +51 -0
- project_loop_harness-0.3.0/agent-tasks/0106-release-checklist.md +21 -0
- project_loop_harness-0.3.0/agent-tasks/0107-agent-tasks-backlog-index.md +20 -0
- project_loop_harness-0.3.0/agent-tasks/0108-target-bound-code-context-receipts.md +152 -0
- project_loop_harness-0.3.0/agent-tasks/0113-evidence-links-table.md +118 -0
- project_loop_harness-0.3.0/agent-tasks/0114-source-hash-drift.md +78 -0
- project_loop_harness-0.3.0/agent-tasks/0115-context-pack-contract-fixtures.md +72 -0
- project_loop_harness-0.3.0/agent-tasks/README.md +42 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/docs/code-context.md +44 -6
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/docs/context-pack.md +40 -18
- project_loop_harness-0.3.0/docs/growth-plan-v0.2.4-v0.5.md +239 -0
- project_loop_harness-0.3.0/docs/release-checklist.md +66 -0
- project_loop_harness-0.3.0/docs/release-notes/v0.2.4.md +67 -0
- project_loop_harness-0.3.0/docs/release-notes/v0.3.0.md +77 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/pyproject.toml +4 -2
- project_loop_harness-0.3.0/src/pcl/__init__.py +1 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/src/pcl/cli.py +21 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/src/pcl/code_context/impact.py +94 -1
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/src/pcl/code_context/receipts.py +40 -2
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/src/pcl/context.py +188 -16
- project_loop_harness-0.3.0/src/pcl/db/migrations/007_evidence_links.sql +19 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/src/pcl/db.py +1 -1
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/src/pcl/evidence.py +104 -4
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/src/pcl/validators.py +47 -1
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0/src/project_loop_harness.egg-info}/PKG-INFO +3 -1
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/src/project_loop_harness.egg-info/SOURCES.txt +17 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/src/project_loop_harness.egg-info/requires.txt +2 -0
- project_loop_harness-0.3.0/tests/fixtures/context_pack_code_context_contract_v0.json +334 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/tests/test_cli_init.py +7 -4
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/tests/test_code_index.py +187 -1
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/tests/test_context.py +462 -15
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/tests/test_evidence_add.py +304 -10
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/tests/test_migrations.py +179 -50
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/tests/test_validation.py +76 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/tests/test_verification_feedback.py +1 -1
- project_loop_harness-0.2.3/src/pcl/__init__.py +0 -1
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/LICENSE +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/MANIFEST.in +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/Makefile +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/README.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/agent-tasks/0001-hardening-cli.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/agent-tasks/0002-db-migrations.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/agent-tasks/0003-workflow-runner.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/agent-tasks/0004-dashboard-renderer.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/agent-tasks/0005-agent-integration.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/agent-tasks/0006-codex-plugin.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/agent-tasks/0007-mcp-server.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/agent-tasks/0008-loop-lifecycle.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/agent-tasks/0009-defect-lifecycle.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/agent-tasks/0010-reporting-evidence.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/agent-tasks/0011-validation-invariants.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/agent-tasks/0012-audit-log-integrity.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/agent-tasks/0013-validation-diagnostics.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/agent-tasks/0014-escalation-lifecycle.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/agent-tasks/0015-decision-lifecycle.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/agent-tasks/0016-escalation-decision-linkage.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/agent-tasks/0017-next-action-guided-loop.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/agent-tasks/0018-readme-golden-path.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/agent-tasks/0019-recovery-playbook.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/agent-tasks/0020-example-project-refresh.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/agent-tasks/0021-agent-adapter-contract.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/agent-tasks/0022-agent-output-validation.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/agent-tasks/0023-codex-exec-adapter-hardening.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/agent-tasks/0024-claude-manual-adapter-hardening.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/agent-tasks/0025-generic-shell-adapter.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/agent-tasks/0026-agent-job-evidence-ingestion.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/agent-tasks/0027-dashboard-data-contract.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/agent-tasks/0028-dashboard-evidence-navigation.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/agent-tasks/0029-dashboard-risk-and-blockers.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/agent-tasks/0030-distribution-readiness.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/agent-tasks/0031-workflow-proposal-mode.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/agent-tasks/0032-workflow-proposal-review.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/agent-tasks/0033-workflow-verifier.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/agent-tasks/0034-limited-execution-sandbox.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/agent-tasks/0035-automatic-workflow-executor.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/agent-tasks/0036-executor-dogfood-workflow.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/agent-tasks/0037-executor-retry-resume.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/agent-tasks/0038-story-test-lifecycle.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/agent-tasks/0039-workflow-yaml-rule-expressions.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/agent-tasks/0040-test-case-evidence-validation.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/agent-tasks/0041-feature-inspection-commands.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/agent-tasks/0042-report-coverage-context.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/agent-tasks/0043-feature-report.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/agent-tasks/0044-complete-csv-export.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/agent-tasks/0045-filtered-job-inspection.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/agent-tasks/0046-feature-status-lifecycle.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/agent-tasks/0047-feature-coverage-next-action.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/agent-tasks/0048-migration-status-command.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/agent-tasks/0049-render-json-artifact-paths.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/agent-tasks/0050-codex-plugin-package-inventory.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/agent-tasks/0051-mcp-render-artifact-paths.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/agent-tasks/0052-lifecycle-failure-job-cleanup.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/agent-tasks/0053-prompt-job-json-handoff.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/agent-tasks/0054-human-queue-linkage-cli.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/agent-tasks/0055-workflow-proposal-list-filter.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/agent-tasks/0056-sandbox-noop-execution-guard.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/agent-tasks/0057-executor-no-executable-step-guard.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/agent-tasks/0058-dogfood-usability-hardening.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/agent-tasks/0059-checkpoint-review-guidance.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/agent-tasks/0060-pypi-trusted-publishing.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/agent-tasks/0061-context-pack-v1.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/agent-tasks/0062-task-backlog-entity.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/agent-tasks/0063-structured-verification-rubric.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/agent-tasks/0064-task-loop-integration.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/agent-tasks/0065-dashboard-human-decisions.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/agent-tasks/0066-agent-registry-lease.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/agent-tasks/0067-context-pack-improvements.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/agent-tasks/0068-trust-hardening.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/agent-tasks/0069-explainable-code-context-v0.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/agent-tasks/0070-human-decision-cockpit.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/agent-tasks/0071-dogfood-impact-precision.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/agent-tasks/0072-sensitive-omission.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/agent-tasks/0073-code-context-module-split.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/agent-tasks/0074-search-snapshot-consistency.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/agent-tasks/0075-diff-source-modes.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/agent-tasks/0076-schema-version-integrity.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/agent-tasks/0077-index-output-budget-and-impact-noise.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/agent-tasks/0078-context-pack-code-context-bridge.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/agent-tasks/0079-receipt-human-summary.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/agent-tasks/0080-retrieval-eval-gate.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/agent-tasks/0081-diff-modes-completion.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/agent-tasks/0082-receipt-relevance-and-age.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/agent-tasks/0083-required-section-invariant.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/agent-tasks/0084-source-commands-honesty.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/agent-tasks/0085-distribution-source-completeness.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/agent-tasks/0086-command-surface-alignment.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/agent-tasks/0087-verification-suggestion-ids.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/agent-tasks/0088-verification-feedback.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/agent-tasks/0089-dogfood-fixture-propose.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/agent-tasks/0090-eval-baseline-record-compare.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/agent-tasks/0091-refresh-command-scope-fidelity.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/agent-tasks/0092-idempotent-status-transitions.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/agent-tasks/0093-evidence-add-command.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/agent-tasks/0094-job-completion-evidence.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/agent-tasks/0095-supporting-evidence-health.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/agent-tasks/0096-evidence-add-path-guards.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/agent-tasks/0097-evidence-durability-design.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/agent-tasks/0098-field-feedback-next-weight-and-run-report-scope.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/agent-tasks/0099-evidence-copy-mode.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/agent-tasks/0100-evidence-task-linking.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/agent-tasks/0101-evidence-id-allocation-race.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/docs/adoption-guide.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/docs/adr/0001-hybrid-state.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/docs/adr/0002-cli-is-the-runtime.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/docs/adr/0003-static-workflows-before-dynamic-workflows.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/docs/agent-adapter-contract.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/docs/agent-output-template.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/docs/agent-roles.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/docs/architecture.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/docs/dashboard-data-contract.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/docs/dashboard-design.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/docs/data-model.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/docs/distribution.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/docs/evidence-durability-design.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/docs/evidence-entry-paths-design.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/docs/feedback/2026-07-06-ax1-moc1-agent-feedback.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/docs/golden-path.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/docs/implementation-plan.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/docs/master-trace-handoff.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/docs/plh_v0_1_11_review_agenda.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/docs/plh_v0_1_12_review_agenda.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/docs/pypi-publishing.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/docs/recovery-playbook.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/docs/safety-permissions.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/docs/v0.2.0-plan.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/docs/verification-feedback-design.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/docs/verification-feedback.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/docs/verification-rubric.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/docs/workflow-contract.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/scripts/run_advisory_retrieval_eval.py +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/scripts/verify_sdist_contracts.py +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/setup.cfg +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/src/pcl/__main__.py +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/src/pcl/agents.py +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/src/pcl/checkpoints.py +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/src/pcl/code_context/__init__.py +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/src/pcl/code_context/diff.py +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/src/pcl/code_context/eval.py +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/src/pcl/code_context/scan.py +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/src/pcl/code_context/search.py +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/src/pcl/code_context/store.py +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/src/pcl/code_context/summary.py +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/src/pcl/code_context/symbols.py +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/src/pcl/code_context/test_hints.py +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/src/pcl/code_index.py +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/src/pcl/commands.py +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/src/pcl/db/migrations/001_initial.sql +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/src/pcl/db/migrations/002_tasks.sql +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/src/pcl/db/migrations/003_agent_registry.sql +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/src/pcl/db/migrations/004_code_index.sql +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/src/pcl/db/migrations/005_verification_feedback.sql +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/src/pcl/db/migrations/006_evidence_task_link.sql +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/src/pcl/db/schema.sql +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/src/pcl/decisions.py +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/src/pcl/dispatch.py +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/src/pcl/errors.py +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/src/pcl/escalations.py +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/src/pcl/events.py +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/src/pcl/exporters.py +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/src/pcl/guards.py +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/src/pcl/ids.py +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/src/pcl/init_project.py +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/src/pcl/lifecycle.py +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/src/pcl/links.py +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/src/pcl/locales.py +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/src/pcl/mcp_server.py +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/src/pcl/migrations.py +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/src/pcl/paths.py +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/src/pcl/receipt_show.py +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/src/pcl/registry.py +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/src/pcl/renderer.py +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/src/pcl/reports.py +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/src/pcl/resources.py +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/src/pcl/rubric.py +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/src/pcl/stories.py +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/src/pcl/tasks.py +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/src/pcl/templates/dashboard/dashboard.html +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/src/pcl/templates/project/AGENTS.block.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/src/pcl/templates/project/CLAUDE.block.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/src/pcl/templates/project/gitignore.fragment +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/src/pcl/templates/project/pcl.yaml +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/src/pcl/templates/skills/project-control-loop/SKILL.md +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/src/pcl/templates/workflows/defect_repair.yaml +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/src/pcl/templates/workflows/executor_smoke.yaml +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/src/pcl/templates/workflows/feature_coverage.yaml +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/src/pcl/templates/workflows/regression_loop.yaml +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/src/pcl/timeutil.py +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/src/pcl/token_estimation.py +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/src/pcl/update_check.py +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/src/pcl/verification_feedback.py +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/src/pcl/verifications.py +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/src/pcl/workflow_executor.py +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/src/pcl/workflow_proposal_validation.py +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/src/pcl/workflow_proposals.py +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/src/pcl/workflow_sandbox.py +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/src/pcl/workflow_verifier.py +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/src/pcl/workflow_yaml.py +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/src/pcl/workflows.py +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/src/project_loop_harness.egg-info/dependency_links.txt +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/src/project_loop_harness.egg-info/entry_points.txt +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/src/project_loop_harness.egg-info/top_level.txt +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/tests/fixtures/code_context_summary_v0.json +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/tests/fixtures/context_receipt_v0.json +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/tests/fixtures/context_receipt_v0_legacy_string_suggestions.json +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/tests/fixtures/retrieval_adversarial_v0.json +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/tests/fixtures/retrieval_real_history_v0.json +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/tests/fixtures/retrieval_v0.json +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/tests/test_advisory_retrieval_eval_script.py +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/tests/test_agent_adapter_contract.py +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/tests/test_agent_output_validation.py +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/tests/test_agents.py +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/tests/test_audit_log_integrity.py +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/tests/test_checkpoints.py +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/tests/test_claude_manual_adapter.py +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/tests/test_code_context_summary.py +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/tests/test_codex_exec_adapter.py +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/tests/test_codex_plugin.py +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/tests/test_dashboard.py +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/tests/test_dashboard_data_contract.py +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/tests/test_decisions.py +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/tests/test_defects.py +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/tests/test_dispatch.py +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/tests/test_distribution.py +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/tests/test_escalations.py +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/tests/test_examples.py +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/tests/test_features.py +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/tests/test_generic_shell_adapter.py +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/tests/test_golden_path.py +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/tests/test_lifecycle.py +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/tests/test_mcp_server.py +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/tests/test_next_actions.py +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/tests/test_pypi_publishing.py +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/tests/test_receipt_show.py +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/tests/test_recovery_playbook.py +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/tests/test_registry.py +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/tests/test_reports.py +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/tests/test_rubric.py +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/tests/test_stories.py +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/tests/test_tasks.py +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/tests/test_update_check.py +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/tests/test_validation_diagnostics.py +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/tests/test_workflow_executor.py +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/tests/test_workflow_proposals.py +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/tests/test_workflow_sandbox.py +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/tests/test_workflow_verifier.py +0 -0
- {project_loop_harness-0.2.3 → project_loop_harness-0.3.0}/tests/test_workflows.py +0 -0
{project_loop_harness-0.2.3/src/project_loop_harness.egg-info → project_loop_harness-0.3.0}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: project-loop-harness
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.3.0
|
|
4
4
|
Summary: Local control plane for agentic project development loops
|
|
5
5
|
Author: Project Loop Harness Contributors
|
|
6
6
|
License: MIT
|
|
@@ -26,6 +26,8 @@ License-File: LICENSE
|
|
|
26
26
|
Provides-Extra: dev
|
|
27
27
|
Requires-Dist: pytest>=8; extra == "dev"
|
|
28
28
|
Requires-Dist: ruff>=0.6; extra == "dev"
|
|
29
|
+
Requires-Dist: setuptools>=69; extra == "dev"
|
|
30
|
+
Requires-Dist: wheel; extra == "dev"
|
|
29
31
|
Dynamic: license-file
|
|
30
32
|
|
|
31
33
|
# Project Loop Harness
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# 0102: Source drift must surface as evidence health warning
|
|
2
|
+
|
|
3
|
+
Milestone: v0.2.4 Trust Patch
|
|
4
|
+
Priority: P1
|
|
5
|
+
Area: evidence
|
|
6
|
+
Origin: docs/project-loop-harness-v0.2.3-third-party-review.md P1-1 (verified against main)
|
|
7
|
+
|
|
8
|
+
## Problem
|
|
9
|
+
|
|
10
|
+
`_collect_copied_member_findings` in `src/pcl/evidence.py` emits `source_drifted`
|
|
11
|
+
findings (detail `missing` or `size_mismatch`) when the original source of a
|
|
12
|
+
copied evidence member has drifted. But `source_drifted` is not in
|
|
13
|
+
`ADHOC_WARNING_FINDING_CODES` (evidence.py:36), so `_adhoc_assessment` returns
|
|
14
|
+
`health: "ok"` when the only findings are `source_drifted`. Agents and humans
|
|
15
|
+
read "ok" and miss the provenance/freshness problem.
|
|
16
|
+
|
|
17
|
+
## Scope
|
|
18
|
+
|
|
19
|
+
1. Add `"source_drifted"` to `ADHOC_WARNING_FINDING_CODES` in
|
|
20
|
+
`src/pcl/evidence.py`.
|
|
21
|
+
2. Confirm the rendering path in `src/pcl/validators.py` (the
|
|
22
|
+
`elif code == "source_drifted":` branch around line 977) stays consistent
|
|
23
|
+
with the new classification — the finding text must keep re-rendering
|
|
24
|
+
identically through the shared `assess_adhoc_evidence` path (0095 pattern).
|
|
25
|
+
3. Tests that pin the semantics:
|
|
26
|
+
- copied artifact intact + source file deleted → `health: "warning"` with a
|
|
27
|
+
`source_drifted` finding, `detail: "missing"`.
|
|
28
|
+
- copied artifact intact + source size mismatch → `health: "warning"` with
|
|
29
|
+
`detail: "size_mismatch"`.
|
|
30
|
+
- copied artifact intact + source intact → `health: "ok"` (no regression).
|
|
31
|
+
- copied artifact corrupted (`copy_hash_mismatch`) + source drifted →
|
|
32
|
+
still `warning` (both findings present, no double-count crash).
|
|
33
|
+
4. `pcl validate --strict --json` must treat `source_drifted` as a warning that
|
|
34
|
+
remains a warning under strict (extend the existing
|
|
35
|
+
`_strict_warning_remains_warning` coverage), not an error, and must stay
|
|
36
|
+
green overall.
|
|
37
|
+
|
|
38
|
+
## Invariants (what to protect, on the normal paths)
|
|
39
|
+
|
|
40
|
+
- The copied artifact stays usable: no finding may remove or rewrite copied
|
|
41
|
+
files under `.project-loop/evidence/adhoc-files/`; assessment is read-only.
|
|
42
|
+
- The findings array shape is additive-only: existing finding codes, their
|
|
43
|
+
`path`/`detail` fields, and their ordering semantics are unchanged.
|
|
44
|
+
- Health values remain the existing three-level `ok | warning | error`; do not
|
|
45
|
+
introduce `artifact_health` / `source_health` split fields (explicitly
|
|
46
|
+
deferred by approval 2026-07-08).
|
|
47
|
+
|
|
48
|
+
## Non-scope
|
|
49
|
+
|
|
50
|
+
- artifact_health / source_health separation (deferred until dogfood
|
|
51
|
+
source_drift_rate data exists).
|
|
52
|
+
- Schema or migration changes.
|
|
53
|
+
- Context pack / dashboard surfacing changes beyond what the shared
|
|
54
|
+
assessment already propagates.
|
|
55
|
+
|
|
56
|
+
## Acceptance
|
|
57
|
+
|
|
58
|
+
- All tests above green; full `pytest` green.
|
|
59
|
+
- Live smoke: create copied evidence in a scratch project, delete the source,
|
|
60
|
+
run `pcl validate --strict --json` → evidence health shows `warning`,
|
|
61
|
+
strict stays `ok: true`.
|
|
62
|
+
- Release note entry describing the semantic change.
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# 0103: SECURITY.md v0.2.x update and copied-evidence policy
|
|
2
|
+
|
|
3
|
+
Milestone: v0.2.4 Trust Patch
|
|
4
|
+
Priority: P1
|
|
5
|
+
Area: docs/security
|
|
6
|
+
Origin: docs/project-loop-harness-v0.2.3-third-party-review.md P1-2 (verified: SECURITY.md still says `0.1.x` while the released line is 0.2.x)
|
|
7
|
+
|
|
8
|
+
## Problem
|
|
9
|
+
|
|
10
|
+
SECURITY.md states the current public release line is `0.1.x`, contradicting
|
|
11
|
+
the v0.2.3 release. Additionally, v0.2.3 introduced `pcl evidence add --copy`,
|
|
12
|
+
which retains copies of source files under
|
|
13
|
+
`.project-loop/evidence/adhoc-files/` — a new secret-retention surface that the
|
|
14
|
+
security policy does not mention.
|
|
15
|
+
|
|
16
|
+
## Scope
|
|
17
|
+
|
|
18
|
+
Update `SECURITY.md` only (no code changes):
|
|
19
|
+
|
|
20
|
+
1. Supported versions table: `0.2.x` = supported, `<0.2` = not supported.
|
|
21
|
+
2. Add a "Copied evidence" section stating:
|
|
22
|
+
- `.project-loop/evidence/adhoc-files/` may contain copied sensitive source
|
|
23
|
+
files when `--copy` is used.
|
|
24
|
+
- Copied evidence must not be committed unless intentionally curated;
|
|
25
|
+
`.project-loop/` is gitignored by default and should stay so.
|
|
26
|
+
- Redaction is caller responsibility; `pcl` performs path-shape sensitive
|
|
27
|
+
guards (0096) but is not a secret scanner (established v0.1.11 decision —
|
|
28
|
+
keep this wording).
|
|
29
|
+
- MCP / read-only exposure must not reveal raw evidence contents by
|
|
30
|
+
default.
|
|
31
|
+
- Dashboard HTML is a human view, not a machine context source.
|
|
32
|
+
3. Note that the release checklist (0106) will include a SECURITY.md
|
|
33
|
+
supported-versions check per release.
|
|
34
|
+
|
|
35
|
+
## Invariants
|
|
36
|
+
|
|
37
|
+
- Do not weaken any existing statement in SECURITY.md; changes are additive or
|
|
38
|
+
version-string corrections.
|
|
39
|
+
- Keep the established epistemic vocabulary (claims-not-facts; no "scanned /
|
|
40
|
+
guaranteed secret-free" style assertions).
|
|
41
|
+
|
|
42
|
+
## Acceptance
|
|
43
|
+
|
|
44
|
+
- SECURITY.md shows `0.2.x` as the supported line.
|
|
45
|
+
- Copied evidence risks and commit policy are stated.
|
|
46
|
+
- `pytest` green (docs-only change; no test changes expected).
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# 0104: Python 3.10–3.13 CI matrix
|
|
2
|
+
|
|
3
|
+
Milestone: v0.2.4 Trust Patch
|
|
4
|
+
Priority: P2
|
|
5
|
+
Area: ci
|
|
6
|
+
Origin: docs/project-loop-harness-v0.2.3-third-party-review.md P2-1 (verified: ci.yml pins `python-version: '3.11'` while pyproject classifiers list 3.10/3.11/3.12/3.13)
|
|
7
|
+
|
|
8
|
+
## Problem
|
|
9
|
+
|
|
10
|
+
`pyproject.toml` declares `requires-python = ">=3.10"` and classifiers for
|
|
11
|
+
3.10–3.13, but CI runs a single Python 3.11. The advertised support range is
|
|
12
|
+
not continuously verified.
|
|
13
|
+
|
|
14
|
+
## Scope
|
|
15
|
+
|
|
16
|
+
Update `.github/workflows/ci.yml`:
|
|
17
|
+
|
|
18
|
+
1. Run lint + tests + smoke on a matrix of `["3.10", "3.11", "3.12", "3.13"]`:
|
|
19
|
+
- `ruff check .`
|
|
20
|
+
- `pytest`
|
|
21
|
+
- smoke: `pcl --version`; then in a fresh temp directory `pcl init`
|
|
22
|
+
(note: `pcl init` takes no positional argument, run it inside the temp
|
|
23
|
+
cwd), `pcl validate --strict --json`, `pcl render --json`.
|
|
24
|
+
2. Keep build / twine check / sdist contract steps on a single canonical
|
|
25
|
+
version (3.12).
|
|
26
|
+
3. Keep total CI time reasonable — matrix jobs run in parallel; do not add
|
|
27
|
+
new workflow files unless the existing one cannot express it.
|
|
28
|
+
|
|
29
|
+
## Invariants
|
|
30
|
+
|
|
31
|
+
- Existing CI steps (including the advisory retrieval eval step from 0080)
|
|
32
|
+
keep their current blocking/advisory semantics; the matrix must not turn an
|
|
33
|
+
advisory step into a blocking one or vice versa.
|
|
34
|
+
- No changes to pyproject metadata, package code, or tests are expected. If a
|
|
35
|
+
Python-version-specific test failure surfaces, report it in the task output
|
|
36
|
+
rather than papering over it with skips — that finding is the point of this
|
|
37
|
+
task.
|
|
38
|
+
|
|
39
|
+
## Acceptance
|
|
40
|
+
|
|
41
|
+
- CI green on all four Python versions (verify with a branch push / PR run or
|
|
42
|
+
`gh run watch` after pushing the branch).
|
|
43
|
+
- Classifiers and CI matrix agree.
|
|
44
|
+
- Release note mentions the matrix result.
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# 0105: Evidence copy observability
|
|
2
|
+
|
|
3
|
+
Milestone: v0.2.4 Trust Patch
|
|
4
|
+
Priority: P2
|
|
5
|
+
Area: evidence
|
|
6
|
+
Origin: docs/project-loop-harness-v0.2.3-third-party-review.md P2-2
|
|
7
|
+
Depends on: 0102 (both touch src/pcl/evidence.py — start after 0102 merges)
|
|
8
|
+
|
|
9
|
+
## Problem
|
|
10
|
+
|
|
11
|
+
v0.2.3 serialized evidence ID allocation to fix a concurrency race. When
|
|
12
|
+
`evidence add --copy` copies large files, the copy work may extend the time a
|
|
13
|
+
SQLite write transaction/lock is held. We have no measurements, so we cannot
|
|
14
|
+
judge whether reserved-row or counter designs are ever needed. Observability
|
|
15
|
+
first, redesign only if data demands it.
|
|
16
|
+
|
|
17
|
+
## Scope
|
|
18
|
+
|
|
19
|
+
1. Measure and record, for `pcl evidence add --copy` invocations:
|
|
20
|
+
- `copy_duration_ms` (wall time of the file-copy phase)
|
|
21
|
+
- `copied_total_bytes`
|
|
22
|
+
- `member_count`
|
|
23
|
+
These go into the `evidence_added` event payload (additive fields) via the
|
|
24
|
+
standard `append_event` path (both stores, per the 0089 lesson — no
|
|
25
|
+
JSONL-only or SQLite-only side channels).
|
|
26
|
+
2. Where measurable without redesign, record lock-related diagnostics (e.g.
|
|
27
|
+
time spent inside the write transaction) as an additive payload field; if
|
|
28
|
+
it is not cleanly measurable, state so in the task output instead of
|
|
29
|
+
adding invasive instrumentation.
|
|
30
|
+
3. Add a concurrent copy stress test: N parallel `evidence add --copy`
|
|
31
|
+
processes against one project must all succeed deterministically with
|
|
32
|
+
unique IDs (extend the existing 0101 race-test pattern).
|
|
33
|
+
|
|
34
|
+
## Invariants
|
|
35
|
+
|
|
36
|
+
- Timestamps/durations must not break determinism guarantees of existing
|
|
37
|
+
contracts: duration fields live only in event payloads, not in receipts,
|
|
38
|
+
context packs, manifests, or anything byte-compared by tests.
|
|
39
|
+
- ID allocation semantics are unchanged (serialized allocation from 0101 is
|
|
40
|
+
kept as-is).
|
|
41
|
+
- Non-`--copy` `evidence add` behavior and payload shape are unchanged
|
|
42
|
+
except for fields explicitly listed above being absent.
|
|
43
|
+
- No new tables, no migration.
|
|
44
|
+
|
|
45
|
+
## Acceptance
|
|
46
|
+
|
|
47
|
+
- `evidence add --copy --json` emits an event whose payload includes the three
|
|
48
|
+
metrics; existing consumers/tests unaffected (additive-only).
|
|
49
|
+
- Concurrent stress test green and deterministic across repeated runs.
|
|
50
|
+
- Full `pytest` green; `pcl validate --strict --json` green after live copy
|
|
51
|
+
operations in a scratch project.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# 0106: Release checklist contract
|
|
2
|
+
|
|
3
|
+
Milestone: v0.2.4 Trust Patch
|
|
4
|
+
Priority: P2
|
|
5
|
+
Area: docs/release
|
|
6
|
+
Origin: docs/project-loop-harness-v0.2.3-third-party-review.md PLH-0108
|
|
7
|
+
Implementation: orchestrator-authored — deliverable is `docs/release-checklist.md`
|
|
8
|
+
|
|
9
|
+
## Goal
|
|
10
|
+
|
|
11
|
+
Make every release reproducible by contract, capturing the steps and traps
|
|
12
|
+
already proven across v0.1.7–v0.2.3 releases.
|
|
13
|
+
|
|
14
|
+
## Acceptance
|
|
15
|
+
|
|
16
|
+
- `docs/release-checklist.md` exists and covers: version bump, release note,
|
|
17
|
+
ruff, pytest (matrix), editable-install sanity, build, twine check, sdist
|
|
18
|
+
contract verification, fresh-venv wheel smoke, `pcl validate --strict
|
|
19
|
+
--json`, `pcl render --json`, SECURITY.md supported-versions check, tag →
|
|
20
|
+
GitHub Release → trusted publishing → PyPI verification, local pipx update.
|
|
21
|
+
- The v0.2.4 release is executed against this checklist.
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# 0107: agent-tasks backlog index
|
|
2
|
+
|
|
3
|
+
Milestone: v0.2.4 Trust Patch
|
|
4
|
+
Priority: P3
|
|
5
|
+
Area: docs/backlog
|
|
6
|
+
Origin: docs/project-loop-harness-v0.2.3-third-party-review.md PLH-0109
|
|
7
|
+
Implementation: orchestrator-authored — deliverable is `agent-tasks/README.md`
|
|
8
|
+
|
|
9
|
+
## Goal
|
|
10
|
+
|
|
11
|
+
Make the `agent-tasks/` directory navigable: distinguish active backlog from
|
|
12
|
+
completed design history without duplicating `TASKS.md` (which stays the
|
|
13
|
+
canonical ordered index).
|
|
14
|
+
|
|
15
|
+
## Acceptance
|
|
16
|
+
|
|
17
|
+
- `agent-tasks/README.md` exists: explains the spec-first workflow, points to
|
|
18
|
+
`TASKS.md` for the full history, and lists the active backlog with
|
|
19
|
+
milestone/priority/status.
|
|
20
|
+
- New contributors and agents can find the next task from it.
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
# 0108: Target-bound code context receipts
|
|
2
|
+
|
|
3
|
+
Milestone: v0.3.0 Target-Bound Context
|
|
4
|
+
Priority: P1
|
|
5
|
+
Area: code-context/context-pack
|
|
6
|
+
Origin: docs/growth-plan-v0.2.4-v0.5.md v0.3.0; docs/project-loop-harness-v0.2.3-third-party-review.md P2-3
|
|
7
|
+
Depends on: 0113 (evidence_links table, migration 007) — merge first.
|
|
8
|
+
|
|
9
|
+
> **Revision 2026-07-08 (坂本承認):** the original no-migration invariant is
|
|
10
|
+
> **retracted**. Target binding is now persisted as a queryable `evidence_links`
|
|
11
|
+
> row (`link_role="code_context"`, from 0113) **and** embedded in the receipt
|
|
12
|
+
> artifact; receipt selection is a SQL query, not an artifact scan. This unblocks
|
|
13
|
+
> `pcl context check` (v0.3.1) and v0.4 `bound_receipt_coverage` without a second
|
|
14
|
+
> migration later.
|
|
15
|
+
|
|
16
|
+
## Problem
|
|
17
|
+
|
|
18
|
+
`pcl context pack --include-code-context` currently reads the latest
|
|
19
|
+
`context_receipt` evidence row. The pack tells the reader that this is
|
|
20
|
+
`scope: "unscoped_latest"` with `binding_strength: "none"`, which is honest,
|
|
21
|
+
but it still risks handing a worker a receipt from an unrelated task or job.
|
|
22
|
+
|
|
23
|
+
The existing docs reserve `scope: "target_bound"` and
|
|
24
|
+
`binding_strength: "caller_asserted"`, but there is no command path that
|
|
25
|
+
creates or requires such a receipt. v0.3.0 turns that reserved contract into a
|
|
26
|
+
narrow, explicit handoff workflow, backed by queryable link state.
|
|
27
|
+
|
|
28
|
+
## Scope
|
|
29
|
+
|
|
30
|
+
1. Extend `pcl impact --diff` with explicit target flags:
|
|
31
|
+
- `--for-task T-XXXX`
|
|
32
|
+
- `--for-job J-XXXX`
|
|
33
|
+
Exactly zero or one target flag is allowed. Existing diff mode flags
|
|
34
|
+
(`--base`, `--staged`, `--unstaged`, `--include-untracked`,
|
|
35
|
+
`--all-changes`, and provided diff input) keep their current semantics.
|
|
36
|
+
2. Validate the named target before writing a receipt. Missing or malformed
|
|
37
|
+
target IDs must fail with a typed error and must not create evidence or an
|
|
38
|
+
`evidence_links` row.
|
|
39
|
+
3. When a target flag is present, record the binding in **two** places, in the
|
|
40
|
+
same transaction that writes the receipt evidence:
|
|
41
|
+
- An `evidence_links` row (0113 helper): `(evidence_id=<receipt>,
|
|
42
|
+
target_type, target_id, link_role="code_context", created_at)`, where
|
|
43
|
+
`target_type` is `task` or `agent_job`.
|
|
44
|
+
- Target binding metadata inside the `impact/v0` response and the
|
|
45
|
+
`context-receipt/v0` artifact so the receipt is self-describing:
|
|
46
|
+
```json
|
|
47
|
+
{
|
|
48
|
+
"target_binding": {
|
|
49
|
+
"target_type": "task",
|
|
50
|
+
"target_id": "T-0001",
|
|
51
|
+
"binding_strength": "caller_asserted",
|
|
52
|
+
"source": "impact_flag"
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
```
|
|
56
|
+
For job targets, use `target_type: "agent_job"`. The link row and the
|
|
57
|
+
artifact `target_binding` must agree.
|
|
58
|
+
4. Update context-pack receipt selection when `--include-code-context` is used.
|
|
59
|
+
Selection is a **query on `evidence_links`** (0113 helper), not an artifact
|
|
60
|
+
scan:
|
|
61
|
+
- For a task pack, prefer the newest receipt evidence with a matching
|
|
62
|
+
`evidence_links` row `(target_type="task", target_id=<task>,
|
|
63
|
+
link_role="code_context")`.
|
|
64
|
+
- For a job pack, prefer the newest matching
|
|
65
|
+
`(target_type="agent_job", target_id=<job>, link_role="code_context")`.
|
|
66
|
+
- If no matching bound receipt exists, preserve the current unscoped latest
|
|
67
|
+
fallback unless the caller requires a bound receipt.
|
|
68
|
+
5. Add `pcl context pack --require-bound-receipt`, valid only with
|
|
69
|
+
`--include-code-context`. When no matching bound receipt exists, fail with a
|
|
70
|
+
typed error `context_pack_bound_receipt_required` and include a
|
|
71
|
+
target-specific refresh suggestion:
|
|
72
|
+
- `pcl impact --diff --for-task T-XXXX --json`
|
|
73
|
+
- `pcl impact --diff --for-job J-XXXX --json`
|
|
74
|
+
6. Update `code_context.relevance` in the embedded summary:
|
|
75
|
+
- Matching bound receipt: `scope: "target_bound"`,
|
|
76
|
+
`binding_strength: "caller_asserted"`, plus `target_type` and
|
|
77
|
+
`target_id`.
|
|
78
|
+
- Unbound fallback: keep `scope: "unscoped_latest"` and
|
|
79
|
+
`binding_strength: "none"` with an explicit warning.
|
|
80
|
+
- Missing receipt: keep `scope: "missing_receipt"` and
|
|
81
|
+
`binding_strength: "none"`.
|
|
82
|
+
7. Update docs and CLI help for `docs/code-context.md`,
|
|
83
|
+
`docs/context-pack.md`, and relevant tests.
|
|
84
|
+
|
|
85
|
+
## Invariants (what to protect, on the normal paths)
|
|
86
|
+
|
|
87
|
+
- Binding is recorded in lockstep: when a target flag is given, the receipt
|
|
88
|
+
evidence row, its `evidence_links` `code_context` row, and the artifact
|
|
89
|
+
`target_binding` are written in one transaction and must agree. Never write
|
|
90
|
+
the link row without the receipt, or an artifact `target_binding` without the
|
|
91
|
+
link row.
|
|
92
|
+
- Binding is a **caller assertion**, not PLH proof that the receipt is
|
|
93
|
+
semantically relevant. Use claims-not-facts vocabulary; do not add fields such
|
|
94
|
+
as `safe_to_continue`, `verified_relevant`, or `agent_read`.
|
|
95
|
+
- Extend `impact/v0`, `context-receipt/v0`, and `context-pack/v1` **additively**
|
|
96
|
+
via the `code-context-summary/v0` insulation layer (0078). The pack embeds the
|
|
97
|
+
summary and `receipt_ref` (evidence_id / receipt_path) only — never the full
|
|
98
|
+
receipt body or copied evidence contents.
|
|
99
|
+
- `pcl context pack` remains read-only: it must not run `pcl index build`,
|
|
100
|
+
`pcl impact`, Git commands, tests, or any artifact-generating command. It
|
|
101
|
+
reads `evidence_links` and evidence rows only.
|
|
102
|
+
- `source_commands` remain read-only re-fetch commands. Artifact-generating
|
|
103
|
+
commands (`pcl impact …`) appear only under `suggested_refresh_commands`.
|
|
104
|
+
- Existing unscoped latest behavior remains available when
|
|
105
|
+
`--require-bound-receipt` is absent.
|
|
106
|
+
- Deterministic generated artifacts stay deterministic; timestamped facts remain
|
|
107
|
+
in receipt/evidence payloads where timestamps already exist.
|
|
108
|
+
|
|
109
|
+
## Non-scope
|
|
110
|
+
|
|
111
|
+
- Semantic or embedding-based relevance proof.
|
|
112
|
+
- Automatic target inference from changed files, branches, or task text.
|
|
113
|
+
- `pcl context pack --receipt ...` manual receipt selection.
|
|
114
|
+
- `pcl receipt list` / `pcl evidence link` CLI verbs.
|
|
115
|
+
- Dashboard redesign or MCP surface changes.
|
|
116
|
+
- Hosted code analysis, cloud sync, telemetry, or external LLM calls.
|
|
117
|
+
- `pcl context check` preflight (deferred to v0.3.1).
|
|
118
|
+
|
|
119
|
+
## Acceptance
|
|
120
|
+
|
|
121
|
+
- `pcl impact --diff --for-task T-0001 --json` writes a receipt with
|
|
122
|
+
`target_binding.target_type == "task"` and `target_id == "T-0001"`, and an
|
|
123
|
+
`evidence_links` row `(target_type="task", target_id="T-0001",
|
|
124
|
+
link_role="code_context")`.
|
|
125
|
+
- `pcl impact --diff --for-job J-0001 --json` writes a receipt with
|
|
126
|
+
`target_binding.target_type == "agent_job"` and `target_id == "J-0001"`, and
|
|
127
|
+
the matching `code_context` link row.
|
|
128
|
+
- Invalid target IDs and mutually exclusive target flags fail with typed errors
|
|
129
|
+
before any evidence or link row is created.
|
|
130
|
+
- `pcl context pack --task T-0001 --include-code-context --json` chooses the
|
|
131
|
+
newest matching task-bound receipt over a newer unbound receipt, via the
|
|
132
|
+
`evidence_links` query.
|
|
133
|
+
- `pcl context pack --job J-0001 --include-code-context --json` chooses the
|
|
134
|
+
newest matching job-bound receipt over a newer unbound receipt.
|
|
135
|
+
- Without a matching bound receipt and without `--require-bound-receipt`,
|
|
136
|
+
context pack still succeeds with the existing unscoped latest warning and a
|
|
137
|
+
target-specific suggested refresh command.
|
|
138
|
+
- With `--require-bound-receipt` and no matching bound receipt, context pack
|
|
139
|
+
fails with `context_pack_bound_receipt_required` and does not silently fall
|
|
140
|
+
back to unscoped latest.
|
|
141
|
+
- `source_commands` for code-context packs still contain only read-only
|
|
142
|
+
commands; `pcl impact` appears only under `suggested_refresh_commands`.
|
|
143
|
+
- Full `pytest` green.
|
|
144
|
+
- Live smoke in a scratch project:
|
|
145
|
+
1. `pcl init`
|
|
146
|
+
2. create a goal and task
|
|
147
|
+
3. `pcl index build --json`
|
|
148
|
+
4. make a small tracked change
|
|
149
|
+
5. `pcl impact --diff --for-task T-0001 --json`
|
|
150
|
+
6. `pcl context pack --task T-0001 --include-code-context --require-bound-receipt --json`
|
|
151
|
+
7. `pcl validate --strict --json`
|
|
152
|
+
8. `pcl render --json`
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
# 0113: Generic evidence links table (migration 007)
|
|
2
|
+
|
|
3
|
+
Milestone: v0.3.0 Target-Bound Context
|
|
4
|
+
Priority: P1
|
|
5
|
+
Area: schema/evidence
|
|
6
|
+
Origin: docs/growth-plan-v0.2.4-v0.5.md v0.3.0; third-party review 議題1 — migration
|
|
7
|
+
approved and 0108 no-migration invariant retracted (Sakamoto approved 2026-07-08).
|
|
8
|
+
|
|
9
|
+
## Problem
|
|
10
|
+
|
|
11
|
+
Evidence-to-target linkage is currently a single `evidence.linked_task_id`
|
|
12
|
+
column (migration 006), which can only express "supporting evidence for a
|
|
13
|
+
task". v0.3.0 introduces a second link role — a code-context receipt bound
|
|
14
|
+
to a task or job (0108) — and v0.3.2 will add master-trace / intent-index
|
|
15
|
+
roles. A single typed column cannot express a role, and adding one column per
|
|
16
|
+
target type (`linked_job_id`, `linked_goal_id`, and so on) sprawls.
|
|
17
|
+
|
|
18
|
+
Introduce a generic, queryable `evidence_links` table so target-bound receipt
|
|
19
|
+
selection (0108), `pcl context check` (v0.3.1), and v0.4 coverage KPIs become
|
|
20
|
+
SQL queries rather than artifact scans. This is a control-plane primitive, not
|
|
21
|
+
a per-feature column.
|
|
22
|
+
|
|
23
|
+
## Scope
|
|
24
|
+
|
|
25
|
+
1. Add migration `007_evidence_links.sql`:
|
|
26
|
+
```sql
|
|
27
|
+
PRAGMA foreign_keys = ON;
|
|
28
|
+
|
|
29
|
+
CREATE TABLE IF NOT EXISTS evidence_links (
|
|
30
|
+
evidence_id TEXT NOT NULL REFERENCES evidence(id),
|
|
31
|
+
target_type TEXT NOT NULL,
|
|
32
|
+
target_id TEXT NOT NULL,
|
|
33
|
+
link_role TEXT NOT NULL,
|
|
34
|
+
created_at TEXT NOT NULL,
|
|
35
|
+
PRIMARY KEY (evidence_id, target_type, target_id, link_role)
|
|
36
|
+
);
|
|
37
|
+
|
|
38
|
+
CREATE INDEX IF NOT EXISTS idx_evidence_links_target
|
|
39
|
+
ON evidence_links(target_type, target_id, link_role, created_at);
|
|
40
|
+
|
|
41
|
+
-- Backfill existing task-linked evidence as role 'supporting'.
|
|
42
|
+
INSERT OR IGNORE INTO evidence_links(evidence_id, target_type, target_id, link_role, created_at)
|
|
43
|
+
SELECT id, 'task', linked_task_id, 'supporting', created_at
|
|
44
|
+
FROM evidence
|
|
45
|
+
WHERE linked_task_id IS NOT NULL;
|
|
46
|
+
```
|
|
47
|
+
Vocabulary in use now: `target_type` is `task` or `agent_job`;
|
|
48
|
+
`link_role` is `supporting` or `code_context`. Reserve (do not emit yet)
|
|
49
|
+
`goal` / `workflow_run` / `decision` / `escalation` and
|
|
50
|
+
`master_trace` / `intent_index` / `worker_output`.
|
|
51
|
+
2. Write path: `pcl evidence add --task T-XXXX` (evidence.py) keeps setting the
|
|
52
|
+
`evidence.linked_task_id` column (0.x compat) and also inserts an
|
|
53
|
+
`evidence_links` row `(evidence_id, 'task', task_id, 'supporting', now)` in
|
|
54
|
+
the same transaction, before the existing `append_event`.
|
|
55
|
+
3. Read path: `context.py._linked_task_evidence` selects from `evidence_links`
|
|
56
|
+
where `target_type='task' AND link_role='supporting'`, joined to `evidence`
|
|
57
|
+
for the display columns, ordered `created_at, evidence_id`. When the
|
|
58
|
+
`evidence_links` table is absent (pre-migration DB opened by a newer binary
|
|
59
|
+
mid-upgrade), fall back to the current `linked_task_id` column query. Output
|
|
60
|
+
shape, ordering, and member/stored-path resolution are unchanged.
|
|
61
|
+
4. Strict validation (`validators.py`): add a dangling-link check modeled on the
|
|
62
|
+
verification `receipt_evidence_id` check (validators.py:596) — every
|
|
63
|
+
`evidence_links.evidence_id` must resolve to an existing evidence row (the
|
|
64
|
+
existing `PRAGMA foreign_key_check` already covers this; keep an explicit,
|
|
65
|
+
message-consistent check too), and for known target types the `target_id`
|
|
66
|
+
must exist (`task` maps to `tasks`, `agent_job` maps to `agent_jobs`).
|
|
67
|
+
Unknown `target_type` values are tolerated with no error (forward
|
|
68
|
+
compatibility).
|
|
69
|
+
5. Provide two small internal helpers for 0108 to reuse (no new CLI surface):
|
|
70
|
+
insert a link row, and select the newest `evidence_id` for a given
|
|
71
|
+
`(target_type, target_id, link_role)`.
|
|
72
|
+
|
|
73
|
+
## Invariants (what to protect, on the normal paths)
|
|
74
|
+
|
|
75
|
+
- The canonical write path for a task-linked ad-hoc evidence is, in one
|
|
76
|
+
transaction: the `evidence` row plus the `linked_task_id` column plus the
|
|
77
|
+
`evidence_links` row plus the `adhoc_evidence_recorded` event. Do not drop the
|
|
78
|
+
`linked_task_id` column write (compat). Do not write an `evidence_links` row
|
|
79
|
+
without its mirroring `evidence` row.
|
|
80
|
+
- The migration backfill is idempotent (`INSERT OR IGNORE`) and additive: it
|
|
81
|
+
must not update or delete any `evidence` row, and re-running `pcl migrate`
|
|
82
|
+
must be a no-op.
|
|
83
|
+
- `evidence_links` is written only through `pcl` (evidence add today, 0108
|
|
84
|
+
tomorrow). No command deletes links in this task; no raw-SQL mutation path.
|
|
85
|
+
- The existing task context-pack `linked_evidence` output — shape, ordering,
|
|
86
|
+
member/stored paths — is unchanged for existing DBs after backfill.
|
|
87
|
+
- Additive only: no existing table or column is dropped or repurposed. Schema
|
|
88
|
+
version advances 6 to 7; `never-downgrade` and DB-ahead typed rejection (0076)
|
|
89
|
+
continue to hold.
|
|
90
|
+
|
|
91
|
+
## Non-scope
|
|
92
|
+
|
|
93
|
+
- `pcl evidence link` / `unlink` CLI verbs (links are written implicitly by
|
|
94
|
+
`evidence add` and, in 0108, by `impact --for-task/--for-job`).
|
|
95
|
+
- Job / goal / decision linking commands beyond the helper 0108 needs.
|
|
96
|
+
- Dashboard changes. The existing `heading_evidence_links` locale string is an
|
|
97
|
+
unrelated UI heading, not this table.
|
|
98
|
+
- Removing or deprecating `linked_task_id` (deferred past 0.x).
|
|
99
|
+
- Reading `evidence_links` from the code-context receipt selection path (that is
|
|
100
|
+
0108).
|
|
101
|
+
|
|
102
|
+
## Acceptance
|
|
103
|
+
|
|
104
|
+
- Fresh `pcl init` gives schema v7, `evidence_links` present,
|
|
105
|
+
`pcl validate --strict --json` green.
|
|
106
|
+
- A v6 to v7 live migration backfills every `linked_task_id` row into
|
|
107
|
+
`evidence_links` as role `supporting`; backfilled row count equals the number
|
|
108
|
+
of non-null `linked_task_id` rows; a second `pcl migrate` changes nothing.
|
|
109
|
+
- `pcl evidence add --task T-0001` writes both the column and the
|
|
110
|
+
`evidence_links` row; the task context pack lists the evidence identically to
|
|
111
|
+
before.
|
|
112
|
+
- A hand-broken dangling link (an `evidence_links` row whose `target_type='task'`
|
|
113
|
+
`target_id` has no matching task) is reported by `validate --strict`; a row
|
|
114
|
+
with an unknown `target_type` is tolerated (no error).
|
|
115
|
+
- An older (v6-aware) `pcl` binary typed-rejects a v7 DB with
|
|
116
|
+
`schema_version_ahead` (0076 behavior preserved).
|
|
117
|
+
- Full `pytest` green; live smoke in a scratch project (`init`, then `evidence
|
|
118
|
+
add --task`, then `validate --strict`, then context pack).
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# 0114: Source hash drift detection for copied evidence
|
|
2
|
+
|
|
3
|
+
Milestone: v0.3.0 Target-Bound Context
|
|
4
|
+
Priority: P2
|
|
5
|
+
Area: evidence
|
|
6
|
+
Origin: docs/growth-plan-v0.2.4-v0.5.md 論点2; third-party review P1 / 議題2 —
|
|
7
|
+
default-on approved (坂本承認 2026-07-08). Extends 0102.
|
|
8
|
+
|
|
9
|
+
## Problem
|
|
10
|
+
|
|
11
|
+
`_collect_copied_member_findings` in `src/pcl/evidence.py` (the source-freshness
|
|
12
|
+
block at evidence.py:589-605) detects source drift only via `detail: "missing"`
|
|
13
|
+
and `detail: "size_mismatch"`. A **same-size content change** to the source
|
|
14
|
+
file is undetected: `source_drifted` never fires, so a copied evidence member
|
|
15
|
+
whose origin was silently rewritten to a different-but-equal-length body reads
|
|
16
|
+
as fresh. The recorded member `sha256` (`expected_sha256`) is already a
|
|
17
|
+
parameter of this function (evidence.py:545) but is never compared against the
|
|
18
|
+
current source.
|
|
19
|
+
|
|
20
|
+
0102 already classifies `source_drifted` as an evidence-health **warning**, so
|
|
21
|
+
closing this gap needs no health-model change — only the missing hash
|
|
22
|
+
comparison.
|
|
23
|
+
|
|
24
|
+
## Scope
|
|
25
|
+
|
|
26
|
+
1. In `_collect_copied_member_findings`, extend the `else` branch that currently
|
|
27
|
+
only handles the size check: when the source exists **and**
|
|
28
|
+
`source_stat.st_size == size_bytes`, compute the source file sha256 (reuse
|
|
29
|
+
`_sha256_file`, evidence.py:907) and compare to `expected_sha256`.
|
|
30
|
+
- Mismatch → append `{"code": "source_drifted", "path": member_path,
|
|
31
|
+
"detail": "hash_mismatch"}`.
|
|
32
|
+
- `OSError` while reading the source → treat as unreadable and reuse the
|
|
33
|
+
existing `detail: "missing"` finding (do not crash, do not add a new code).
|
|
34
|
+
2. Default-on, no `--deep` flag. The hash is computed **only** in the same-size
|
|
35
|
+
branch, so `missing` and `size_mismatch` stay the cheap fast paths. The
|
|
36
|
+
`copy_max_member_bytes` cap (10MB, 0097) bounds per-member cost.
|
|
37
|
+
3. Confirm the `validators.py` `source_drifted` rendering branch (the
|
|
38
|
+
`elif code == "source_drifted":` branch, ~line 977) renders the new
|
|
39
|
+
`hash_mismatch` detail consistently through the shared
|
|
40
|
+
`assess_adhoc_evidence` path (0095 pattern) — health stays `warning`.
|
|
41
|
+
|
|
42
|
+
## Invariants (what to protect, on the normal paths)
|
|
43
|
+
|
|
44
|
+
- Read-only assessment: no finding rewrites or removes copied artifacts under
|
|
45
|
+
`.project-loop/evidence/adhoc-files/` or any source file.
|
|
46
|
+
- Findings shape is additive-only: `source_drifted` gains one new `detail`
|
|
47
|
+
value, `hash_mismatch`. Existing `missing` / `size_mismatch` details, their
|
|
48
|
+
`path` field, and ordering are unchanged.
|
|
49
|
+
- Copied-artifact health stays semantically **separate** from source freshness
|
|
50
|
+
in wording (0102 invariant): `copy_hash_mismatch` = the copied artifact broke;
|
|
51
|
+
`source_drifted/hash_mismatch` = the origin changed since the copy. Do not
|
|
52
|
+
merge or cross-reference the two codes.
|
|
53
|
+
- Health stays the three-level `ok | warning | error`; no `artifact_health` /
|
|
54
|
+
`source_health` split (still deferred until dogfood `source_drift_rate` data).
|
|
55
|
+
|
|
56
|
+
## Non-scope
|
|
57
|
+
|
|
58
|
+
- A `--deep` / lightweight-vs-deep mode split (unnecessary: the size gate plus
|
|
59
|
+
the 10MB member cap already bound cost).
|
|
60
|
+
- Hashing sources of **reference** (non-copied) members — reference members are
|
|
61
|
+
already hash-checked against the source directly by `_assess_reference_member`.
|
|
62
|
+
- `artifact_health` / `source_health` field separation.
|
|
63
|
+
|
|
64
|
+
## Acceptance
|
|
65
|
+
|
|
66
|
+
- Test: copied artifact intact + source rewritten to different content of the
|
|
67
|
+
**same byte length** → `health: "warning"` with a `source_drifted` finding,
|
|
68
|
+
`detail: "hash_mismatch"`.
|
|
69
|
+
- Test: copied artifact intact + source intact → `health: "ok"` (no regression).
|
|
70
|
+
- Test: `copy_hash_mismatch` (artifact corrupted) + `source_drifted/hash_mismatch`
|
|
71
|
+
co-occur → still `warning`, both findings present, no double-count crash.
|
|
72
|
+
- `pcl validate --strict --json` treats `source_drifted/hash_mismatch` as a
|
|
73
|
+
warning that remains a warning under strict (extend
|
|
74
|
+
`_strict_warning_remains_warning` coverage) and stays green overall.
|
|
75
|
+
- Live smoke: in a scratch project, `evidence add --copy` a file, edit the
|
|
76
|
+
source to same-length different content, `pcl validate --strict --json` →
|
|
77
|
+
evidence health `warning`, detail `hash_mismatch`, strict `ok: true`.
|
|
78
|
+
- Full `pytest` green; release note entry describing the tightened semantics.
|