patchshuttle 0.1.0a4__tar.gz → 0.1.0a5__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.
- {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a5}/.gitignore +1 -0
- {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a5}/CHANGELOG.md +20 -0
- {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a5}/PKG-INFO +74 -19
- {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a5}/README.md +73 -18
- {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a5}/SPEC_V0_1.md +62 -16
- {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a5}/docs/RELEASE.md +47 -8
- {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a5}/src/patchshuttle/_version.py +1 -1
- {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a5}/src/patchshuttle/cli.py +6 -8
- {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a5}/src/patchshuttle/config.py +1 -0
- {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a5}/src/patchshuttle/errors.py +4 -0
- {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a5}/src/patchshuttle/execution.py +62 -39
- patchshuttle-0.1.0a5/src/patchshuttle/history/__init__.py +35 -0
- patchshuttle-0.1.0a5/src/patchshuttle/history/cli.py +123 -0
- patchshuttle-0.1.0a5/src/patchshuttle/history/models.py +194 -0
- patchshuttle-0.1.0a5/src/patchshuttle/history/records.py +382 -0
- patchshuttle-0.1.0a5/src/patchshuttle/history/storage.py +370 -0
- {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a5}/src/patchshuttle/operations.py +41 -34
- {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a5}/src/patchshuttle/resources/AI_GUIDE.md +24 -0
- {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a5}/src/patchshuttle/resources/PATCHSHUTTLE_PROTOCOL.md +33 -0
- patchshuttle-0.1.0a5/tests/unit/history/test_history.py +373 -0
- patchshuttle-0.1.0a5/tests/unit/history/test_history_integration.py +225 -0
- patchshuttle-0.1.0a5/tests/unit/history/test_history_storage_edges.py +292 -0
- {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a5}/tests/unit/test_cli.py +2 -2
- {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a5}/tests/unit/test_package.py +1 -1
- {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a5}/tests/unit/test_release_configuration.py +1 -1
- {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a5}/tests/unit/test_selfdoc.py +1 -1
- {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a5}/tools/release_checks.py +5 -0
- {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a5}/tools/wheel_smoke.py +6 -0
- {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a5}/.github/workflows/ci.yml +0 -0
- {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a5}/.github/workflows/release.yml +0 -0
- {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a5}/.github/workflows/testpypi.yml +0 -0
- {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a5}/LICENSE +0 -0
- {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a5}/SECURITY.md +0 -0
- {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a5}/pyproject.toml +0 -0
- {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a5}/src/patchshuttle/__init__.py +0 -0
- {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a5}/src/patchshuttle/_ai_log.py +0 -0
- {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a5}/src/patchshuttle/_architecture.py +0 -0
- {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a5}/src/patchshuttle/_diff.py +0 -0
- {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a5}/src/patchshuttle/_html_lint.py +0 -0
- {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a5}/src/patchshuttle/_line_ranges.py +0 -0
- {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a5}/src/patchshuttle/_process.py +0 -0
- {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a5}/src/patchshuttle/_python_discovery.py +0 -0
- {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a5}/src/patchshuttle/_python_structure.py +0 -0
- {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a5}/src/patchshuttle/_python_symbols.py +0 -0
- {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a5}/src/patchshuttle/actions/__init__.py +0 -0
- {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a5}/src/patchshuttle/actions/constructors.py +0 -0
- {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a5}/src/patchshuttle/actions/create.py +0 -0
- {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a5}/src/patchshuttle/actions/modify.py +0 -0
- {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a5}/src/patchshuttle/audit.py +0 -0
- {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a5}/src/patchshuttle/backup.py +0 -0
- {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a5}/src/patchshuttle/checks/__init__.py +0 -0
- {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a5}/src/patchshuttle/checks/constructors.py +0 -0
- {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a5}/src/patchshuttle/checks/runner.py +0 -0
- {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a5}/src/patchshuttle/context.py +0 -0
- {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a5}/src/patchshuttle/formatter_policy.py +0 -0
- {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a5}/src/patchshuttle/formatters/__init__.py +0 -0
- {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a5}/src/patchshuttle/formatters/runner.py +0 -0
- {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a5}/src/patchshuttle/identifiers.py +0 -0
- {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a5}/src/patchshuttle/inventory.py +0 -0
- {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a5}/src/patchshuttle/linters/__init__.py +0 -0
- {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a5}/src/patchshuttle/linters/runner.py +0 -0
- {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a5}/src/patchshuttle/logging.py +0 -0
- {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a5}/src/patchshuttle/models.py +0 -0
- {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a5}/src/patchshuttle/parser.py +0 -0
- {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a5}/src/patchshuttle/planner.py +0 -0
- {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a5}/src/patchshuttle/policy.py +0 -0
- {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a5}/src/patchshuttle/preflight.py +0 -0
- {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a5}/src/patchshuttle/project_python.py +0 -0
- {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a5}/src/patchshuttle/py.typed +0 -0
- {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a5}/src/patchshuttle/registry.py +0 -0
- {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a5}/src/patchshuttle/resources/AUDIT-EXAMPLE.psh.yaml +0 -0
- {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a5}/src/patchshuttle/resources/PATCH-EXAMPLE.psh.yaml +0 -0
- {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a5}/src/patchshuttle/resources/__init__.py +0 -0
- {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a5}/src/patchshuttle/rollback.py +0 -0
- {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a5}/src/patchshuttle/runner.py +0 -0
- {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a5}/src/patchshuttle/runtime_cache.py +0 -0
- {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a5}/src/patchshuttle/selfdoc.py +0 -0
- {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a5}/src/patchshuttle/verification.py +0 -0
- {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a5}/src/patchshuttle/warning_baseline.py +0 -0
- {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a5}/src/patchshuttle/workspace.py +0 -0
- {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a5}/tests/e2e/test_cli_project_cycle.py +0 -0
- {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a5}/tests/integration/test_workflows.py +0 -0
- {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a5}/tests/unit/test_a4_coverage_regressions.py +0 -0
- {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a5}/tests/unit/test_actions.py +0 -0
- {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a5}/tests/unit/test_ai_log.py +0 -0
- {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a5}/tests/unit/test_architecture.py +0 -0
- {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a5}/tests/unit/test_attempt_logging.py +0 -0
- {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a5}/tests/unit/test_audit_verify_execution.py +0 -0
- {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a5}/tests/unit/test_backup.py +0 -0
- {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a5}/tests/unit/test_change_transaction.py +0 -0
- {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a5}/tests/unit/test_check_transaction.py +0 -0
- {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a5}/tests/unit/test_checks.py +0 -0
- {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a5}/tests/unit/test_config.py +0 -0
- {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a5}/tests/unit/test_context_and_constructors.py +0 -0
- {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a5}/tests/unit/test_diff.py +0 -0
- {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a5}/tests/unit/test_execution.py +0 -0
- {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a5}/tests/unit/test_formatters.py +0 -0
- {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a5}/tests/unit/test_formatting_transaction.py +0 -0
- {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a5}/tests/unit/test_guarded_ranges.py +0 -0
- {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a5}/tests/unit/test_html_lint.py +0 -0
- {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a5}/tests/unit/test_identifiers.py +0 -0
- {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a5}/tests/unit/test_inventory.py +0 -0
- {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a5}/tests/unit/test_inventory_transaction.py +0 -0
- {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a5}/tests/unit/test_logging.py +0 -0
- {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a5}/tests/unit/test_manual_rollback.py +0 -0
- {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a5}/tests/unit/test_models.py +0 -0
- {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a5}/tests/unit/test_modify_actions.py +0 -0
- {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a5}/tests/unit/test_operational_execution.py +0 -0
- {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a5}/tests/unit/test_parser.py +0 -0
- {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a5}/tests/unit/test_phase19_cli.py +0 -0
- {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a5}/tests/unit/test_planner.py +0 -0
- {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a5}/tests/unit/test_planner_ux.py +0 -0
- {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a5}/tests/unit/test_policy.py +0 -0
- {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a5}/tests/unit/test_preflight.py +0 -0
- {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a5}/tests/unit/test_project_python.py +0 -0
- {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a5}/tests/unit/test_python_discovery.py +0 -0
- {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a5}/tests/unit/test_python_structure.py +0 -0
- {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a5}/tests/unit/test_python_structure_action.py +0 -0
- {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a5}/tests/unit/test_python_symbols.py +0 -0
- {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a5}/tests/unit/test_registry.py +0 -0
- {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a5}/tests/unit/test_rollback.py +0 -0
- {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a5}/tests/unit/test_runner.py +0 -0
- {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a5}/tests/unit/test_runtime_cache.py +0 -0
- {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a5}/tests/unit/test_warning_baseline.py +0 -0
- {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a5}/tests/unit/test_workspace.py +0 -0
- {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a5}/tools/check_tag.py +0 -0
- {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a5}/tools/index_smoke.py +0 -0
|
@@ -5,6 +5,26 @@ uses semantic versioning, including Python-compatible pre-release versions.
|
|
|
5
5
|
|
|
6
6
|
## Unreleased
|
|
7
7
|
|
|
8
|
+
## 0.1.0a5 - 2026-08-28
|
|
9
|
+
|
|
10
|
+
Fourth alpha release, focused on persistent structured execution history
|
|
11
|
+
for bounded external retrieval and long-term orchestration.
|
|
12
|
+
|
|
13
|
+
### Added
|
|
14
|
+
|
|
15
|
+
- Schema-versioned, append-only structured job history records under
|
|
16
|
+
`patches/history/<job-id>/` separate declared intent from observed execution
|
|
17
|
+
facts, reference detailed logs, preserve successful, failed, declined, and
|
|
18
|
+
rollback attempts, and expose bounded read-only Python and CLI access. History
|
|
19
|
+
persistence is a best-effort secondary artifact and cannot change a job result
|
|
20
|
+
or trigger rollback.
|
|
21
|
+
|
|
22
|
+
### Fixed
|
|
23
|
+
|
|
24
|
+
- Structured history models retain the canonical external `schema` JSON key
|
|
25
|
+
without shadowing Pydantic's legacy `BaseModel.schema` attribute or emitting a
|
|
26
|
+
warning during command startup.
|
|
27
|
+
|
|
8
28
|
## 0.1.0a4 - 2026-08-27
|
|
9
29
|
|
|
10
30
|
Third alpha release, focused on bounded Python source discovery, compact
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: patchshuttle
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.0a5
|
|
4
4
|
Summary: Local, auditable patch workflows for AI-assisted software development
|
|
5
5
|
License-Expression: MIT
|
|
6
6
|
License-File: LICENSE
|
|
@@ -43,7 +43,7 @@ describes a small job, the user reviews and runs it locally, and PatchShuttle
|
|
|
43
43
|
records the result for the next iteration.
|
|
44
44
|
|
|
45
45
|
> [!IMPORTANT]
|
|
46
|
-
> PatchShuttle is alpha software. Version `0.1.
|
|
46
|
+
> PatchShuttle is alpha software. Version `0.1.0a5` implements the complete
|
|
47
47
|
> local v0.1 workflow. It executes bounded read-only
|
|
48
48
|
> audits, approved patch transactions, and approved one-pass verification jobs
|
|
49
49
|
> under a project lock. Patch jobs retain backups, run controlled checks, apply
|
|
@@ -54,9 +54,9 @@ records the result for the next iteration.
|
|
|
54
54
|
> Trusted Publishing workflows are implemented. Every versioned release must
|
|
55
55
|
> pass its own local qualification, GitHub-hosted Windows/Ubuntu matrix,
|
|
56
56
|
> TestPyPI installation, production publication, and post-release smoke gates.
|
|
57
|
-
> The immutable `0.1.0a2` and `0.1.
|
|
58
|
-
> separately scoped `0.1.0a2` ChatGPT end-to-end
|
|
59
|
-
> [docs/RELEASE.md](docs/RELEASE.md).
|
|
57
|
+
> The immutable `0.1.0a2`, `0.1.0a3`, and `0.1.0a4` qualification
|
|
58
|
+
> evidence, plus the separately scoped `0.1.0a2` ChatGPT end-to-end
|
|
59
|
+
> workflow, are retained in [docs/RELEASE.md](docs/RELEASE.md).
|
|
60
60
|
|
|
61
61
|
> [!NOTE]
|
|
62
62
|
> Compared with `0.1.0a2`, version `0.1.0a3` adds AI-facing planner diagnostics,
|
|
@@ -67,14 +67,20 @@ records the result for the next iteration.
|
|
|
67
67
|
> range hash.
|
|
68
68
|
|
|
69
69
|
> [!NOTE]
|
|
70
|
-
>
|
|
71
|
-
> `
|
|
72
|
-
>
|
|
73
|
-
>
|
|
74
|
-
>
|
|
75
|
-
>
|
|
76
|
-
> `
|
|
77
|
-
|
|
70
|
+
> Version `0.1.0a4` adds `search_context`, `read_symbol`, guarded
|
|
71
|
+
> `replace_symbol`, the fixed Ruff F-only check, compact AI log views, Django
|
|
72
|
+
> warning baselines, owner-controlled project-check Python selection,
|
|
73
|
+
> evidence-only Python discovery telemetry, expanded redaction, bounded
|
|
74
|
+
> declaration-only `python_structure` discovery with compact output, and
|
|
75
|
+
> owner-controlled architecture ratchets. These features are included in the
|
|
76
|
+
> immutable `0.1.0a4` PyPI artifacts.
|
|
77
|
+
|
|
78
|
+
> [!NOTE]
|
|
79
|
+
> Version `0.1.0a5` adds schema-versioned append-only structured job
|
|
80
|
+
> history, facts-first records, best-effort persistence, and bounded
|
|
81
|
+
> read-only Python and CLI retrieval. Detailed execution logs remain the
|
|
82
|
+
> diagnostic source; external orchestrators remain responsible for project
|
|
83
|
+
> memory, semantic retrieval, requirements, and user decisions.
|
|
78
84
|
|
|
79
85
|
## Design goals
|
|
80
86
|
|
|
@@ -94,7 +100,7 @@ After publication, install the exact alpha release from PyPI:
|
|
|
94
100
|
```bash
|
|
95
101
|
python -m venv .venv
|
|
96
102
|
python -m pip install --upgrade pip
|
|
97
|
-
python -m pip install "patchshuttle==0.1.
|
|
103
|
+
python -m pip install "patchshuttle==0.1.0a5"
|
|
98
104
|
```
|
|
99
105
|
|
|
100
106
|
For development from a local checkout:
|
|
@@ -107,7 +113,7 @@ To enable opt-in HTML template linting in an installed release, install the
|
|
|
107
113
|
`html` extra:
|
|
108
114
|
|
|
109
115
|
```bash
|
|
110
|
-
python -m pip install "patchshuttle[html]==0.1.
|
|
116
|
+
python -m pip install "patchshuttle[html]==0.1.0a5"
|
|
111
117
|
```
|
|
112
118
|
|
|
113
119
|
For a local development checkout, install both development and HTML extras:
|
|
@@ -871,12 +877,13 @@ python -m coverage report --fail-under=100
|
|
|
871
877
|
python -m build
|
|
872
878
|
python -m twine check dist/*
|
|
873
879
|
python tools/release_checks.py dist
|
|
874
|
-
python tools/wheel_smoke.py dist/patchshuttle-0.1.
|
|
880
|
+
python tools/wheel_smoke.py dist/patchshuttle-0.1.0a5-py3-none-any.whl --version 0.1.0a5
|
|
875
881
|
```
|
|
876
882
|
|
|
877
|
-
The `0.1.0a2` and `0.1.
|
|
878
|
-
Windows compatibility matrix, TestPyPI qualification,
|
|
879
|
-
Publishing, and a clean post-release installation.
|
|
883
|
+
The `0.1.0a2`, `0.1.0a3`, and `0.1.0a4` alpha releases each passed the
|
|
884
|
+
required Ubuntu and Windows compatibility matrix, TestPyPI qualification,
|
|
885
|
+
production PyPI Trusted Publishing, and a clean post-release installation.
|
|
886
|
+
Their exact release and
|
|
880
887
|
workflow links and artifact hashes, together with the separately scoped
|
|
881
888
|
`0.1.0a2` ChatGPT end-to-end evidence, are recorded in
|
|
882
889
|
[docs/RELEASE.md](docs/RELEASE.md). Follow that guide in order for every future
|
|
@@ -929,6 +936,54 @@ confirmation, backup, or project checks.
|
|
|
929
936
|
This is deliberately a structural guard. It does not infer feature boundaries,
|
|
930
937
|
build dependency or call graphs, detect cycles, judge semantic responsibility,
|
|
931
938
|
reorganize files, or change the patch scope selected by the AI.
|
|
939
|
+
|
|
940
|
+
## Structured project history
|
|
941
|
+
|
|
942
|
+
PatchShuttle writes one compact JSON record for each recorded execution attempt to
|
|
943
|
+
`patches/history/<job-id>/<record-id>.json`. These records are intended for
|
|
944
|
+
long-term external ingestion and AI retrieval. They describe PatchShuttle's own
|
|
945
|
+
operations only; requirements, conversations, product decisions, stages, browser
|
|
946
|
+
tests, and semantic project memory belong to an external orchestrator.
|
|
947
|
+
|
|
948
|
+
History has a different purpose from the other outputs:
|
|
949
|
+
|
|
950
|
+
- execution logs contain detailed diagnostic evidence and command output;
|
|
951
|
+
- AI logs are bounded deterministic views derived from execution logs;
|
|
952
|
+
- history records contain compact schema-versioned facts plus references to the
|
|
953
|
+
detailed log and its derived AI-log view.
|
|
954
|
+
|
|
955
|
+
`job.title` and bounded, redacted `job.description` are stored below `declared` as
|
|
956
|
+
operator or AI-supplied intent. They are never presented as observed facts.
|
|
957
|
+
`observed` contains only trusted execution state: status, files, checks, failures,
|
|
958
|
+
rollback, warnings, and reliably targeted symbols. PatchShuttle does not infer
|
|
959
|
+
workarounds, semantic meaning, relationships, or affected symbols it cannot prove.
|
|
960
|
+
|
|
961
|
+
Read records without parsing human-readable logs:
|
|
962
|
+
|
|
963
|
+
```powershell
|
|
964
|
+
patchshuttle history list --limit 20
|
|
965
|
+
patchshuttle history latest
|
|
966
|
+
patchshuttle history latest PATCH-EXAMPLE-001
|
|
967
|
+
patchshuttle history show PATCH-EXAMPLE-001/2026_08_27_120000_000001_abcdef01
|
|
968
|
+
```
|
|
969
|
+
|
|
970
|
+
`latest` and `show` return the full canonical JSON record. `list` returns bounded
|
|
971
|
+
JSON summaries, one per line. Python integrations can call
|
|
972
|
+
`list_history_records`, `latest_history_record`, and `read_history_record` from
|
|
973
|
+
`patchshuttle.history`. External systems may also ingest the per-attempt JSON files
|
|
974
|
+
directly.
|
|
975
|
+
|
|
976
|
+
History writing occurs after the required detailed log and registry update. It is
|
|
977
|
+
best-effort: a history storage failure is exposed through the Python result's
|
|
978
|
+
`history_warning`, but does not turn a completed job into a failure or trigger
|
|
979
|
+
rollback. Existing protocol-1 jobs require no changes. Existing workspaces may add
|
|
980
|
+
`patches/history/**` to `project.ignored_paths`; new default configurations already
|
|
981
|
+
exclude it from workspace inventories.
|
|
982
|
+
|
|
983
|
+
The v1 layout is append-only and uses exclusive file creation. It deliberately has
|
|
984
|
+
no database, JSONL index, semantic search, vector store, relationship graph, or
|
|
985
|
+
Farm-specific behavior.
|
|
986
|
+
|
|
932
987
|
## Manual workflow
|
|
933
988
|
|
|
934
989
|
The implemented local cycle is:
|
|
@@ -6,7 +6,7 @@ describes a small job, the user reviews and runs it locally, and PatchShuttle
|
|
|
6
6
|
records the result for the next iteration.
|
|
7
7
|
|
|
8
8
|
> [!IMPORTANT]
|
|
9
|
-
> PatchShuttle is alpha software. Version `0.1.
|
|
9
|
+
> PatchShuttle is alpha software. Version `0.1.0a5` implements the complete
|
|
10
10
|
> local v0.1 workflow. It executes bounded read-only
|
|
11
11
|
> audits, approved patch transactions, and approved one-pass verification jobs
|
|
12
12
|
> under a project lock. Patch jobs retain backups, run controlled checks, apply
|
|
@@ -17,9 +17,9 @@ records the result for the next iteration.
|
|
|
17
17
|
> Trusted Publishing workflows are implemented. Every versioned release must
|
|
18
18
|
> pass its own local qualification, GitHub-hosted Windows/Ubuntu matrix,
|
|
19
19
|
> TestPyPI installation, production publication, and post-release smoke gates.
|
|
20
|
-
> The immutable `0.1.0a2` and `0.1.
|
|
21
|
-
> separately scoped `0.1.0a2` ChatGPT end-to-end
|
|
22
|
-
> [docs/RELEASE.md](docs/RELEASE.md).
|
|
20
|
+
> The immutable `0.1.0a2`, `0.1.0a3`, and `0.1.0a4` qualification
|
|
21
|
+
> evidence, plus the separately scoped `0.1.0a2` ChatGPT end-to-end
|
|
22
|
+
> workflow, are retained in [docs/RELEASE.md](docs/RELEASE.md).
|
|
23
23
|
|
|
24
24
|
> [!NOTE]
|
|
25
25
|
> Compared with `0.1.0a2`, version `0.1.0a3` adds AI-facing planner diagnostics,
|
|
@@ -30,14 +30,20 @@ records the result for the next iteration.
|
|
|
30
30
|
> range hash.
|
|
31
31
|
|
|
32
32
|
> [!NOTE]
|
|
33
|
-
>
|
|
34
|
-
> `
|
|
35
|
-
>
|
|
36
|
-
>
|
|
37
|
-
>
|
|
38
|
-
>
|
|
39
|
-
> `
|
|
40
|
-
|
|
33
|
+
> Version `0.1.0a4` adds `search_context`, `read_symbol`, guarded
|
|
34
|
+
> `replace_symbol`, the fixed Ruff F-only check, compact AI log views, Django
|
|
35
|
+
> warning baselines, owner-controlled project-check Python selection,
|
|
36
|
+
> evidence-only Python discovery telemetry, expanded redaction, bounded
|
|
37
|
+
> declaration-only `python_structure` discovery with compact output, and
|
|
38
|
+
> owner-controlled architecture ratchets. These features are included in the
|
|
39
|
+
> immutable `0.1.0a4` PyPI artifacts.
|
|
40
|
+
|
|
41
|
+
> [!NOTE]
|
|
42
|
+
> Version `0.1.0a5` adds schema-versioned append-only structured job
|
|
43
|
+
> history, facts-first records, best-effort persistence, and bounded
|
|
44
|
+
> read-only Python and CLI retrieval. Detailed execution logs remain the
|
|
45
|
+
> diagnostic source; external orchestrators remain responsible for project
|
|
46
|
+
> memory, semantic retrieval, requirements, and user decisions.
|
|
41
47
|
|
|
42
48
|
## Design goals
|
|
43
49
|
|
|
@@ -57,7 +63,7 @@ After publication, install the exact alpha release from PyPI:
|
|
|
57
63
|
```bash
|
|
58
64
|
python -m venv .venv
|
|
59
65
|
python -m pip install --upgrade pip
|
|
60
|
-
python -m pip install "patchshuttle==0.1.
|
|
66
|
+
python -m pip install "patchshuttle==0.1.0a5"
|
|
61
67
|
```
|
|
62
68
|
|
|
63
69
|
For development from a local checkout:
|
|
@@ -70,7 +76,7 @@ To enable opt-in HTML template linting in an installed release, install the
|
|
|
70
76
|
`html` extra:
|
|
71
77
|
|
|
72
78
|
```bash
|
|
73
|
-
python -m pip install "patchshuttle[html]==0.1.
|
|
79
|
+
python -m pip install "patchshuttle[html]==0.1.0a5"
|
|
74
80
|
```
|
|
75
81
|
|
|
76
82
|
For a local development checkout, install both development and HTML extras:
|
|
@@ -834,12 +840,13 @@ python -m coverage report --fail-under=100
|
|
|
834
840
|
python -m build
|
|
835
841
|
python -m twine check dist/*
|
|
836
842
|
python tools/release_checks.py dist
|
|
837
|
-
python tools/wheel_smoke.py dist/patchshuttle-0.1.
|
|
843
|
+
python tools/wheel_smoke.py dist/patchshuttle-0.1.0a5-py3-none-any.whl --version 0.1.0a5
|
|
838
844
|
```
|
|
839
845
|
|
|
840
|
-
The `0.1.0a2` and `0.1.
|
|
841
|
-
Windows compatibility matrix, TestPyPI qualification,
|
|
842
|
-
Publishing, and a clean post-release installation.
|
|
846
|
+
The `0.1.0a2`, `0.1.0a3`, and `0.1.0a4` alpha releases each passed the
|
|
847
|
+
required Ubuntu and Windows compatibility matrix, TestPyPI qualification,
|
|
848
|
+
production PyPI Trusted Publishing, and a clean post-release installation.
|
|
849
|
+
Their exact release and
|
|
843
850
|
workflow links and artifact hashes, together with the separately scoped
|
|
844
851
|
`0.1.0a2` ChatGPT end-to-end evidence, are recorded in
|
|
845
852
|
[docs/RELEASE.md](docs/RELEASE.md). Follow that guide in order for every future
|
|
@@ -892,6 +899,54 @@ confirmation, backup, or project checks.
|
|
|
892
899
|
This is deliberately a structural guard. It does not infer feature boundaries,
|
|
893
900
|
build dependency or call graphs, detect cycles, judge semantic responsibility,
|
|
894
901
|
reorganize files, or change the patch scope selected by the AI.
|
|
902
|
+
|
|
903
|
+
## Structured project history
|
|
904
|
+
|
|
905
|
+
PatchShuttle writes one compact JSON record for each recorded execution attempt to
|
|
906
|
+
`patches/history/<job-id>/<record-id>.json`. These records are intended for
|
|
907
|
+
long-term external ingestion and AI retrieval. They describe PatchShuttle's own
|
|
908
|
+
operations only; requirements, conversations, product decisions, stages, browser
|
|
909
|
+
tests, and semantic project memory belong to an external orchestrator.
|
|
910
|
+
|
|
911
|
+
History has a different purpose from the other outputs:
|
|
912
|
+
|
|
913
|
+
- execution logs contain detailed diagnostic evidence and command output;
|
|
914
|
+
- AI logs are bounded deterministic views derived from execution logs;
|
|
915
|
+
- history records contain compact schema-versioned facts plus references to the
|
|
916
|
+
detailed log and its derived AI-log view.
|
|
917
|
+
|
|
918
|
+
`job.title` and bounded, redacted `job.description` are stored below `declared` as
|
|
919
|
+
operator or AI-supplied intent. They are never presented as observed facts.
|
|
920
|
+
`observed` contains only trusted execution state: status, files, checks, failures,
|
|
921
|
+
rollback, warnings, and reliably targeted symbols. PatchShuttle does not infer
|
|
922
|
+
workarounds, semantic meaning, relationships, or affected symbols it cannot prove.
|
|
923
|
+
|
|
924
|
+
Read records without parsing human-readable logs:
|
|
925
|
+
|
|
926
|
+
```powershell
|
|
927
|
+
patchshuttle history list --limit 20
|
|
928
|
+
patchshuttle history latest
|
|
929
|
+
patchshuttle history latest PATCH-EXAMPLE-001
|
|
930
|
+
patchshuttle history show PATCH-EXAMPLE-001/2026_08_27_120000_000001_abcdef01
|
|
931
|
+
```
|
|
932
|
+
|
|
933
|
+
`latest` and `show` return the full canonical JSON record. `list` returns bounded
|
|
934
|
+
JSON summaries, one per line. Python integrations can call
|
|
935
|
+
`list_history_records`, `latest_history_record`, and `read_history_record` from
|
|
936
|
+
`patchshuttle.history`. External systems may also ingest the per-attempt JSON files
|
|
937
|
+
directly.
|
|
938
|
+
|
|
939
|
+
History writing occurs after the required detailed log and registry update. It is
|
|
940
|
+
best-effort: a history storage failure is exposed through the Python result's
|
|
941
|
+
`history_warning`, but does not turn a completed job into a failure or trigger
|
|
942
|
+
rollback. Existing protocol-1 jobs require no changes. Existing workspaces may add
|
|
943
|
+
`patches/history/**` to `project.ignored_paths`; new default configurations already
|
|
944
|
+
exclude it from workspace inventories.
|
|
945
|
+
|
|
946
|
+
The v1 layout is append-only and uses exclusive file creation. It deliberately has
|
|
947
|
+
no database, JSONL index, semantic search, vector store, relationship graph, or
|
|
948
|
+
Farm-specific behavior.
|
|
949
|
+
|
|
895
950
|
## Manual workflow
|
|
896
951
|
|
|
897
952
|
The implemented local cycle is:
|
|
@@ -13,20 +13,17 @@
|
|
|
13
13
|
> on 2026-08-16, followed by successful TestPyPI qualification, production
|
|
14
14
|
> PyPI publication, and a clean installation smoke test. A recorded ChatGPT
|
|
15
15
|
> end-to-end workflow passed on Windows 11 with Python 3.14.2 on 2026-08-17.
|
|
16
|
-
> Version `0.1.
|
|
17
|
-
>
|
|
18
|
-
>
|
|
19
|
-
>
|
|
20
|
-
>
|
|
21
|
-
>
|
|
22
|
-
>
|
|
23
|
-
>
|
|
24
|
-
>
|
|
25
|
-
>
|
|
26
|
-
>
|
|
27
|
-
> PyPI publication, and a clean Windows CPython 3.14 installation on
|
|
28
|
-
> 2026-08-23. TestPyPI and production PyPI contain byte-identical `0.1.0a3`
|
|
29
|
-
> distributions.
|
|
16
|
+
> Version `0.1.0a4` is a published alpha release, not stable `0.1.0`.
|
|
17
|
+
> It retains the published `0.1.0a3` workflow and adds bounded Python source
|
|
18
|
+
> discovery, compact structure output, owner-controlled project-check Python
|
|
19
|
+
> selection, evidence-only discovery telemetry, and owner-controlled Python
|
|
20
|
+
> architecture ratchets. The immutable artifacts were built from commit
|
|
21
|
+
> `f0f6188b6e81727401152023d701f0e065fcc481` and passed the required hosted
|
|
22
|
+
> Windows/Ubuntu matrix, TestPyPI qualification, production PyPI Trusted
|
|
23
|
+
> Publishing, and a clean Windows CPython 3.14 installation on 2026-08-27.
|
|
24
|
+
> TestPyPI and production PyPI contain byte-identical `0.1.0a4`
|
|
25
|
+
> distributions; exact workflow links, sizes, and SHA-256 hashes are recorded
|
|
26
|
+
> in `docs/RELEASE.md`.
|
|
30
27
|
>
|
|
31
28
|
> This document defines the target behavior of PatchShuttle v0.1. The README
|
|
32
29
|
> identifies the currently implemented subset; all other features remain
|
|
@@ -413,6 +410,36 @@ The policy is structural only: it does not inspect source semantics, infer
|
|
|
413
410
|
features or dependencies, build graphs, reorganize files, or choose patch scope.
|
|
414
411
|
Disabling or changing thresholds requires an owner edit to
|
|
415
412
|
`patches/patchshuttle.toml`.
|
|
413
|
+
### 9.2 Persistent structured job history
|
|
414
|
+
|
|
415
|
+
PatchShuttle records compact facts about its own execution attempts separately from
|
|
416
|
+
full diagnostic logs. A history record is a schema-versioned JSON projection of the
|
|
417
|
+
same trusted run state used by logging. It separates submitted intent from observed
|
|
418
|
+
execution facts and references, rather than duplicates, detailed evidence.
|
|
419
|
+
|
|
420
|
+
Version 1 uses one exclusive file per attempt under
|
|
421
|
+
`patches/history/<job-id>/<record-id>.json`. Multiple attempts for the same job ID
|
|
422
|
+
never overwrite one another. Readers validate schema, project identity, record/path
|
|
423
|
+
identity, real-file boundaries, and size and scan limits. External orchestrators may
|
|
424
|
+
ingest these files into their own databases and indexes.
|
|
425
|
+
|
|
426
|
+
Required content includes PatchShuttle and schema versions, job identity and hash,
|
|
427
|
+
timestamp, result and exit code, bounded declared title and description intent,
|
|
428
|
+
planned counts and targets, observed file changes, executed checks, failure and
|
|
429
|
+
rollback facts, check warnings, and references to detailed log, derived AI-log view,
|
|
430
|
+
archived job, and backup. Affected symbols are included only when an explicit
|
|
431
|
+
`replace_symbol` target corresponds to an observed affected file. Relationships are
|
|
432
|
+
`null` in v1 because protocol 1 supplies no authoritative relationship metadata.
|
|
433
|
+
|
|
434
|
+
History creation is a best-effort secondary operation after log and registry
|
|
435
|
+
persistence. Failure to create it does not fail or roll back an otherwise completed
|
|
436
|
+
job. The Python result exposes the bounded warning. Existing job schemas, normalized
|
|
437
|
+
hashes, registry semantics, logs, and AI-log formats remain unchanged.
|
|
438
|
+
|
|
439
|
+
PatchShuttle does not store conversations, requirements, product decisions, stages,
|
|
440
|
+
artifacts, runtime history, semantic memory, or vector indexes. Those remain the
|
|
441
|
+
responsibility of external orchestration systems.
|
|
442
|
+
|
|
416
443
|
## 10. YAML job protocol
|
|
417
444
|
|
|
418
445
|
### 10.1 Canonical extension
|
|
@@ -1930,7 +1957,7 @@ has been tested through a documented end-to-end scenario.
|
|
|
1930
1957
|
TestPyPI and production Trusted Publishing, and a clean production-index
|
|
1931
1958
|
installation on 2026-08-23.
|
|
1932
1959
|
|
|
1933
|
-
###
|
|
1960
|
+
### `0.1.0a4`
|
|
1934
1961
|
|
|
1935
1962
|
- bounded `search_context` and decorator-aware Python `read_symbol` audits;
|
|
1936
1963
|
- guarded `replace_symbol` planning and transactional execution;
|
|
@@ -1952,6 +1979,25 @@ has been tested through a documented end-to-end scenario.
|
|
|
1952
1979
|
the standard-library AST, with no project-code execution, semantic resolution,
|
|
1953
1980
|
cache, persistence, inferred patch scope, or symbol-index implementation verdict.
|
|
1954
1981
|
|
|
1982
|
+
- opt-in compact `python_structure` output that retains bounded navigational
|
|
1983
|
+
identities, source ranges, parse errors, and limit signals;
|
|
1984
|
+
- owner-controlled `modular-monolith` / `package-by-feature` architecture
|
|
1985
|
+
ratchets with bounded stable `ARCH` findings;
|
|
1986
|
+
- immutable artifacts from commit
|
|
1987
|
+
`f0f6188b6e81727401152023d701f0e065fcc481` passed final `main` and tag CI,
|
|
1988
|
+
TestPyPI and production Trusted Publishing, and a clean production-index
|
|
1989
|
+
Windows CPython 3.14 installation on 2026-08-27.
|
|
1990
|
+
### `0.1.0a5`
|
|
1991
|
+
|
|
1992
|
+
- schema-versioned append-only structured records for PatchShuttle job
|
|
1993
|
+
attempts, with declared intent kept separate from observed execution facts;
|
|
1994
|
+
- compact file, check, failure, rollback, warning, and diagnostic-reference
|
|
1995
|
+
metadata without full command output, patch contents, or project memory;
|
|
1996
|
+
- best-effort secondary persistence that cannot change an authoritative job
|
|
1997
|
+
result or trigger rollback;
|
|
1998
|
+
- bounded read-only Python and CLI retrieval for external ingestion, without a
|
|
1999
|
+
database, semantic search, relationship graph, or orchestrator-specific state.
|
|
2000
|
+
|
|
1955
2001
|
### `0.1.0b1`
|
|
1956
2002
|
|
|
1957
2003
|
- AI guide and handoff;
|
|
@@ -2008,7 +2054,7 @@ PatchShuttle v0.1.0 is ready when all of the following are demonstrated:
|
|
|
2008
2054
|
|
|
2009
2055
|
### Current qualification record
|
|
2010
2056
|
|
|
2011
|
-
As of the completed `0.1.
|
|
2057
|
+
As of the completed `0.1.0a4` qualification on 2026-08-27, criteria 1 through
|
|
2012
2058
|
18 above have explicit evidence for that published alpha release: local
|
|
2013
2059
|
implementation and test evidence for criteria 2 through 16, plus independent
|
|
2014
2060
|
hosted CI, TestPyPI, production PyPI, and clean post-release installation
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# PatchShuttle release guide
|
|
2
2
|
|
|
3
|
-
This guide records the immutable published `0.1.0a2` and `0.1.
|
|
3
|
+
This guide records the immutable published `0.1.0a2`, `0.1.0a3`, and `0.1.0a4` evidence and
|
|
4
4
|
the staged qualification procedure for later releases. Do not publish a
|
|
5
5
|
stable `0.1.0` release until every acceptance criterion in `SPEC_V0_1.md` has
|
|
6
6
|
passed and the stable release is approved.
|
|
@@ -98,6 +98,44 @@ The **Tested with ChatGPT** statement remains scoped to the separately recorded
|
|
|
98
98
|
`0.1.0a2` end-to-end workflow above; this release record does not silently
|
|
99
99
|
extend that product claim to `0.1.0a3`.
|
|
100
100
|
|
|
101
|
+
## 0.2. Recorded `0.1.0a4` qualification
|
|
102
|
+
|
|
103
|
+
The immutable `0.1.0a4` artifacts were built from commit
|
|
104
|
+
`f0f6188b6e81727401152023d701f0e065fcc481`. The annotated
|
|
105
|
+
`v0.1.0a4` tag resolves to the same commit. The release adds bounded
|
|
106
|
+
Python source discovery, compact structure output, owner-controlled
|
|
107
|
+
project-check Python selection, evidence-only discovery telemetry, and
|
|
108
|
+
owner-controlled Python architecture ratchets.
|
|
109
|
+
|
|
110
|
+
The release passed these external gates on 2026-08-27:
|
|
111
|
+
|
|
112
|
+
- [final release-candidate CI on `main`](https://github.com/ratundo/patchshuttle/actions/runs/33089001064);
|
|
113
|
+
- [TestPyPI publication](https://github.com/ratundo/patchshuttle/actions/runs/33094686124);
|
|
114
|
+
- [CI for tag `v0.1.0a4`](https://github.com/ratundo/patchshuttle/actions/runs/33095708487);
|
|
115
|
+
- [GitHub `v0.1.0a4` pre-release](https://github.com/ratundo/patchshuttle/releases/tag/v0.1.0a4);
|
|
116
|
+
- [production PyPI Trusted Publishing](https://github.com/ratundo/patchshuttle/actions/runs/33096689962);
|
|
117
|
+
- [production PyPI release](https://pypi.org/project/patchshuttle/0.1.0a4/)
|
|
118
|
+
and a clean post-release installation smoke test.
|
|
119
|
+
|
|
120
|
+
TestPyPI and production PyPI received byte-identical distributions:
|
|
121
|
+
|
|
122
|
+
- wheel `patchshuttle-0.1.0a4-py3-none-any.whl`, 167610 bytes,
|
|
123
|
+
SHA-256:
|
|
124
|
+
`b5a372b3879ea7382903556cb041ff9233d5e44624da28a5d1a2d8a2bdd2c832`;
|
|
125
|
+
- source archive `patchshuttle-0.1.0a4.tar.gz`, 296869 bytes,
|
|
126
|
+
SHA-256:
|
|
127
|
+
`14585ad971f374da2466807e876c4742acd140a069ae2ab159afccec297ad05c`.
|
|
128
|
+
|
|
129
|
+
A separate clean Windows CPython 3.14 temporary environment installed
|
|
130
|
+
`patchshuttle[html]==0.1.0a4` from production PyPI with
|
|
131
|
+
`--no-cache-dir`. `patchshuttle version` reported
|
|
132
|
+
`PatchShuttle 0.1.0a4`; `patchshuttle capabilities` reported
|
|
133
|
+
`patchshuttle_version: 0.1.0a4` and `protocol: 1`.
|
|
134
|
+
|
|
135
|
+
The **Tested with ChatGPT** statement remains scoped to the separately
|
|
136
|
+
recorded `0.1.0a2` end-to-end workflow above. This release record does
|
|
137
|
+
not extend that claim to every action, AI model, project, or intentional
|
|
138
|
+
failure and rollback path.
|
|
101
139
|
## 1. Local release gate
|
|
102
140
|
|
|
103
141
|
From a clean repository root, use Python 3.12 and start with an empty `dist/`
|
|
@@ -119,8 +157,8 @@ python tools/wheel_smoke.py dist/patchshuttle-<VERSION>-py3-none-any.whl --versi
|
|
|
119
157
|
|
|
120
158
|
`release_checks.py` requires exactly one wheel and one source archive for the
|
|
121
159
|
source version and writes `dist/SHA256SUMS`. Replace `<VERSION>` with the exact
|
|
122
|
-
source version under qualification. For the recorded qualification
|
|
123
|
-
was `0.1.
|
|
160
|
+
source version under qualification. For the most recent recorded qualification it
|
|
161
|
+
was `0.1.0a4`. Do not reuse an immutable published version for a future upload.
|
|
124
162
|
|
|
125
163
|
During a source-version transition, metadata in an already-installed editable
|
|
126
164
|
environment may still report the previous version until the package is
|
|
@@ -128,11 +166,12 @@ reinstalled. Source-tree tests validate the imported source version. The build,
|
|
|
128
166
|
`release_checks.py`, and clean-wheel smoke test are the authoritative metadata
|
|
129
167
|
alignment gates for the new distributions.
|
|
130
168
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
169
|
+
Future release candidates must retain explicit coverage for formatter
|
|
170
|
+
baseline-versus-planned classification, per-tool local exclusions,
|
|
171
|
+
`django_import_check`, rollback after runtime `.pyc` creation, bounded Python
|
|
172
|
+
structure discovery, architecture-ratchet evaluation, structured-history wheel
|
|
173
|
+
contents, and clean-installed history persistence and retrieval. Plan and run
|
|
174
|
+
logs must keep exposing resolved formatter and architecture decisions.
|
|
136
175
|
|
|
137
176
|
## 2. Publish the repository and run CI
|
|
138
177
|
|
|
@@ -26,6 +26,7 @@ from patchshuttle.execution import (
|
|
|
26
26
|
record_declined_plan,
|
|
27
27
|
resolve_registered_job,
|
|
28
28
|
)
|
|
29
|
+
from patchshuttle.history.cli import history_command
|
|
29
30
|
from patchshuttle.logging import (
|
|
30
31
|
AttemptLogData,
|
|
31
32
|
current_run_clock,
|
|
@@ -74,6 +75,9 @@ def main(workspace_path: Path | None) -> None:
|
|
|
74
75
|
"""Run local, auditable workflows for AI-assisted project changes."""
|
|
75
76
|
|
|
76
77
|
|
|
78
|
+
main.add_command(history_command)
|
|
79
|
+
|
|
80
|
+
|
|
77
81
|
@main.command()
|
|
78
82
|
def version() -> None:
|
|
79
83
|
"""Print the installed PatchShuttle version."""
|
|
@@ -328,10 +332,7 @@ def snapshot_command() -> None:
|
|
|
328
332
|
except WorkspaceError as error:
|
|
329
333
|
_fail_workspace(error, failure_prefix="SNAPSHOT_FAILED")
|
|
330
334
|
except ExecutionError as error:
|
|
331
|
-
click.echo(
|
|
332
|
-
_render_execution_error(error, prefix="SNAPSHOT_FAILED"),
|
|
333
|
-
err=True,
|
|
334
|
-
)
|
|
335
|
+
click.echo(_render_execution_error(error, prefix="SNAPSHOT_FAILED"), err=True)
|
|
335
336
|
raise click.exceptions.Exit(execution_exit_code(error.code)) from error
|
|
336
337
|
click.echo(
|
|
337
338
|
"\n".join(
|
|
@@ -355,10 +356,7 @@ def handoff_command() -> None:
|
|
|
355
356
|
except WorkspaceError as error:
|
|
356
357
|
_fail_workspace(error, failure_prefix="HANDOFF_FAILED")
|
|
357
358
|
except ExecutionError as error:
|
|
358
|
-
click.echo(
|
|
359
|
-
_render_execution_error(error, prefix="HANDOFF_FAILED"),
|
|
360
|
-
err=True,
|
|
361
|
-
)
|
|
359
|
+
click.echo(_render_execution_error(error, prefix="HANDOFF_FAILED"), err=True)
|
|
362
360
|
raise click.exceptions.Exit(execution_exit_code(error.code)) from error
|
|
363
361
|
click.echo(
|
|
364
362
|
"\n".join(
|
|
@@ -268,6 +268,8 @@ class ExecutionError(RuntimeError):
|
|
|
268
268
|
workspace_comparison: WorkspaceComparison | None = None,
|
|
269
269
|
log_path: Path | None = None,
|
|
270
270
|
archived_job_path: Path | None = None,
|
|
271
|
+
history_path: Path | None = None,
|
|
272
|
+
history_warning: str | None = None,
|
|
271
273
|
) -> None:
|
|
272
274
|
self.code = code
|
|
273
275
|
self.message = message
|
|
@@ -285,6 +287,8 @@ class ExecutionError(RuntimeError):
|
|
|
285
287
|
self.workspace_comparison = workspace_comparison
|
|
286
288
|
self.log_path = log_path
|
|
287
289
|
self.archived_job_path = archived_job_path
|
|
290
|
+
self.history_path = history_path
|
|
291
|
+
self.history_warning = history_warning
|
|
288
292
|
super().__init__(message)
|
|
289
293
|
|
|
290
294
|
def __str__(self) -> str:
|