patchshuttle 0.1.0a4__tar.gz → 0.1.0a6__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (148) hide show
  1. {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a6}/.github/workflows/ci.yml +37 -5
  2. {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a6}/.gitignore +1 -0
  3. {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a6}/CHANGELOG.md +44 -1
  4. patchshuttle-0.1.0a4/README.md → patchshuttle-0.1.0a6/PKG-INFO +182 -18
  5. patchshuttle-0.1.0a4/PKG-INFO → patchshuttle-0.1.0a6/README.md +138 -55
  6. {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a6}/SPEC_V0_1.md +147 -17
  7. patchshuttle-0.1.0a6/docs/CHATGPT_INTEGRATION.md +54 -0
  8. patchshuttle-0.1.0a6/docs/DJANGO_MIGRATIONS.md +83 -0
  9. patchshuttle-0.1.0a6/docs/NEXT_RELEASE.md +170 -0
  10. {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a6}/docs/RELEASE.md +61 -8
  11. {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a6}/pyproject.toml +5 -0
  12. {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a6}/src/patchshuttle/_architecture.py +3 -1
  13. {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a6}/src/patchshuttle/_python_symbols.py +13 -1
  14. patchshuttle-0.1.0a6/src/patchshuttle/_refactor.py +147 -0
  15. {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a6}/src/patchshuttle/_version.py +1 -1
  16. {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a6}/src/patchshuttle/actions/__init__.py +14 -0
  17. {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a6}/src/patchshuttle/actions/constructors.py +108 -2
  18. {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a6}/src/patchshuttle/actions/create.py +6 -0
  19. {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a6}/src/patchshuttle/actions/modify.py +12 -0
  20. {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a6}/src/patchshuttle/audit.py +34 -0
  21. {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a6}/src/patchshuttle/backup.py +28 -2
  22. {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a6}/src/patchshuttle/cli.py +6 -8
  23. {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a6}/src/patchshuttle/config.py +1 -0
  24. patchshuttle-0.1.0a6/src/patchshuttle/django_app/__init__.py +1 -0
  25. patchshuttle-0.1.0a6/src/patchshuttle/django_app/management/__init__.py +1 -0
  26. patchshuttle-0.1.0a6/src/patchshuttle/django_app/management/commands/__init__.py +1 -0
  27. patchshuttle-0.1.0a6/src/patchshuttle/django_app/management/commands/patchshuttle_migrate.py +50 -0
  28. patchshuttle-0.1.0a6/src/patchshuttle/django_app/workflow.py +306 -0
  29. {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a6}/src/patchshuttle/errors.py +4 -0
  30. {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a6}/src/patchshuttle/execution.py +64 -39
  31. {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a6}/src/patchshuttle/formatters/runner.py +5 -1
  32. patchshuttle-0.1.0a6/src/patchshuttle/history/__init__.py +35 -0
  33. patchshuttle-0.1.0a6/src/patchshuttle/history/cli.py +123 -0
  34. patchshuttle-0.1.0a6/src/patchshuttle/history/models.py +194 -0
  35. patchshuttle-0.1.0a6/src/patchshuttle/history/records.py +382 -0
  36. patchshuttle-0.1.0a6/src/patchshuttle/history/storage.py +370 -0
  37. patchshuttle-0.1.0a6/src/patchshuttle/integrations/__init__.py +1 -0
  38. patchshuttle-0.1.0a6/src/patchshuttle/integrations/mcp_server.py +182 -0
  39. {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a6}/src/patchshuttle/linters/runner.py +1 -1
  40. {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a6}/src/patchshuttle/logging.py +1 -0
  41. {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a6}/src/patchshuttle/models.py +114 -4
  42. {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a6}/src/patchshuttle/operations.py +41 -34
  43. {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a6}/src/patchshuttle/planner.py +248 -187
  44. patchshuttle-0.1.0a6/src/patchshuttle/planning/__init__.py +1 -0
  45. patchshuttle-0.1.0a6/src/patchshuttle/planning/imports.py +184 -0
  46. patchshuttle-0.1.0a6/src/patchshuttle/planning/types.py +194 -0
  47. {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a6}/src/patchshuttle/preflight.py +2 -0
  48. {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a6}/src/patchshuttle/resources/AI_GUIDE.md +107 -0
  49. {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a6}/src/patchshuttle/resources/PATCHSHUTTLE_PROTOCOL.md +112 -2
  50. {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a6}/src/patchshuttle/rollback.py +6 -0
  51. {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a6}/src/patchshuttle/runner.py +18 -18
  52. {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a6}/src/patchshuttle/selfdoc.py +33 -3
  53. patchshuttle-0.1.0a6/tests/integrations/test_django_migrations.py +356 -0
  54. patchshuttle-0.1.0a6/tests/integrations/test_imports.py +186 -0
  55. patchshuttle-0.1.0a6/tests/integrations/test_mcp_server.py +242 -0
  56. patchshuttle-0.1.0a6/tests/unit/history/test_history.py +373 -0
  57. patchshuttle-0.1.0a6/tests/unit/history/test_history_integration.py +225 -0
  58. patchshuttle-0.1.0a6/tests/unit/history/test_history_storage_edges.py +292 -0
  59. {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a6}/tests/unit/test_cli.py +2 -2
  60. {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a6}/tests/unit/test_formatters.py +4 -0
  61. patchshuttle-0.1.0a6/tests/unit/test_move_file.py +217 -0
  62. {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a6}/tests/unit/test_package.py +1 -1
  63. {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a6}/tests/unit/test_preflight.py +2 -0
  64. patchshuttle-0.1.0a6/tests/unit/test_refactor.py +330 -0
  65. {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a6}/tests/unit/test_release_configuration.py +23 -3
  66. {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a6}/tests/unit/test_selfdoc.py +1 -1
  67. patchshuttle-0.1.0a6/tests/unit/test_structural_guards.py +251 -0
  68. patchshuttle-0.1.0a6/tools/django_postgres_smoke.py +88 -0
  69. {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a6}/tools/release_checks.py +5 -0
  70. {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a6}/tools/wheel_smoke.py +6 -0
  71. {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a6}/.github/workflows/release.yml +0 -0
  72. {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a6}/.github/workflows/testpypi.yml +0 -0
  73. {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a6}/LICENSE +0 -0
  74. {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a6}/SECURITY.md +0 -0
  75. {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a6}/src/patchshuttle/__init__.py +0 -0
  76. {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a6}/src/patchshuttle/_ai_log.py +0 -0
  77. {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a6}/src/patchshuttle/_diff.py +0 -0
  78. {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a6}/src/patchshuttle/_html_lint.py +0 -0
  79. {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a6}/src/patchshuttle/_line_ranges.py +0 -0
  80. {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a6}/src/patchshuttle/_process.py +0 -0
  81. {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a6}/src/patchshuttle/_python_discovery.py +0 -0
  82. {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a6}/src/patchshuttle/_python_structure.py +0 -0
  83. {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a6}/src/patchshuttle/checks/__init__.py +0 -0
  84. {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a6}/src/patchshuttle/checks/constructors.py +0 -0
  85. {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a6}/src/patchshuttle/checks/runner.py +0 -0
  86. {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a6}/src/patchshuttle/context.py +0 -0
  87. {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a6}/src/patchshuttle/formatter_policy.py +0 -0
  88. {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a6}/src/patchshuttle/formatters/__init__.py +0 -0
  89. {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a6}/src/patchshuttle/identifiers.py +0 -0
  90. {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a6}/src/patchshuttle/inventory.py +0 -0
  91. {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a6}/src/patchshuttle/linters/__init__.py +0 -0
  92. {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a6}/src/patchshuttle/parser.py +0 -0
  93. {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a6}/src/patchshuttle/policy.py +0 -0
  94. {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a6}/src/patchshuttle/project_python.py +0 -0
  95. {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a6}/src/patchshuttle/py.typed +0 -0
  96. {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a6}/src/patchshuttle/registry.py +0 -0
  97. {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a6}/src/patchshuttle/resources/AUDIT-EXAMPLE.psh.yaml +0 -0
  98. {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a6}/src/patchshuttle/resources/PATCH-EXAMPLE.psh.yaml +0 -0
  99. {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a6}/src/patchshuttle/resources/__init__.py +0 -0
  100. {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a6}/src/patchshuttle/runtime_cache.py +0 -0
  101. {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a6}/src/patchshuttle/verification.py +0 -0
  102. {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a6}/src/patchshuttle/warning_baseline.py +0 -0
  103. {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a6}/src/patchshuttle/workspace.py +0 -0
  104. {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a6}/tests/e2e/test_cli_project_cycle.py +0 -0
  105. {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a6}/tests/integration/test_workflows.py +0 -0
  106. {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a6}/tests/unit/test_a4_coverage_regressions.py +0 -0
  107. {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a6}/tests/unit/test_actions.py +0 -0
  108. {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a6}/tests/unit/test_ai_log.py +0 -0
  109. {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a6}/tests/unit/test_architecture.py +0 -0
  110. {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a6}/tests/unit/test_attempt_logging.py +0 -0
  111. {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a6}/tests/unit/test_audit_verify_execution.py +0 -0
  112. {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a6}/tests/unit/test_backup.py +0 -0
  113. {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a6}/tests/unit/test_change_transaction.py +0 -0
  114. {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a6}/tests/unit/test_check_transaction.py +0 -0
  115. {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a6}/tests/unit/test_checks.py +0 -0
  116. {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a6}/tests/unit/test_config.py +0 -0
  117. {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a6}/tests/unit/test_context_and_constructors.py +0 -0
  118. {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a6}/tests/unit/test_diff.py +0 -0
  119. {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a6}/tests/unit/test_execution.py +0 -0
  120. {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a6}/tests/unit/test_formatting_transaction.py +0 -0
  121. {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a6}/tests/unit/test_guarded_ranges.py +0 -0
  122. {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a6}/tests/unit/test_html_lint.py +0 -0
  123. {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a6}/tests/unit/test_identifiers.py +0 -0
  124. {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a6}/tests/unit/test_inventory.py +0 -0
  125. {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a6}/tests/unit/test_inventory_transaction.py +0 -0
  126. {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a6}/tests/unit/test_logging.py +0 -0
  127. {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a6}/tests/unit/test_manual_rollback.py +0 -0
  128. {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a6}/tests/unit/test_models.py +0 -0
  129. {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a6}/tests/unit/test_modify_actions.py +0 -0
  130. {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a6}/tests/unit/test_operational_execution.py +0 -0
  131. {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a6}/tests/unit/test_parser.py +0 -0
  132. {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a6}/tests/unit/test_phase19_cli.py +0 -0
  133. {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a6}/tests/unit/test_planner.py +0 -0
  134. {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a6}/tests/unit/test_planner_ux.py +0 -0
  135. {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a6}/tests/unit/test_policy.py +0 -0
  136. {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a6}/tests/unit/test_project_python.py +0 -0
  137. {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a6}/tests/unit/test_python_discovery.py +0 -0
  138. {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a6}/tests/unit/test_python_structure.py +0 -0
  139. {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a6}/tests/unit/test_python_structure_action.py +0 -0
  140. {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a6}/tests/unit/test_python_symbols.py +0 -0
  141. {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a6}/tests/unit/test_registry.py +0 -0
  142. {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a6}/tests/unit/test_rollback.py +0 -0
  143. {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a6}/tests/unit/test_runner.py +0 -0
  144. {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a6}/tests/unit/test_runtime_cache.py +0 -0
  145. {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a6}/tests/unit/test_warning_baseline.py +0 -0
  146. {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a6}/tests/unit/test_workspace.py +0 -0
  147. {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a6}/tools/check_tag.py +0 -0
  148. {patchshuttle-0.1.0a4 → patchshuttle-0.1.0a6}/tools/index_smoke.py +0 -0
@@ -47,14 +47,46 @@ jobs:
47
47
  - name: Check formatting
48
48
  run: python -m black --check src tests tools
49
49
  - name: Run tests with branch coverage
50
- run: |
51
- python -m coverage erase
52
- python -m coverage run -m pytest -q
53
- python -m coverage report --fail-under=100
50
+ run: python -m coverage run -m pytest -q
51
+ - name: Require full branch coverage
52
+ run: python -m coverage report --fail-under=100
53
+
54
+ postgres:
55
+ name: Django / PostgreSQL 16
56
+ runs-on: ubuntu-24.04
57
+ timeout-minutes: 10
58
+ services:
59
+ postgres:
60
+ image: postgres:16
61
+ env:
62
+ POSTGRES_DB: patchshuttle_test
63
+ POSTGRES_USER: postgres
64
+ POSTGRES_PASSWORD: disposable-ci-password
65
+ ports:
66
+ - 5432:5432
67
+ options: >-
68
+ --health-cmd pg_isready
69
+ --health-interval 10s
70
+ --health-timeout 5s
71
+ --health-retries 5
72
+ steps:
73
+ - uses: actions/checkout@v7.0.1
74
+ - uses: actions/setup-python@v7.0.0
75
+ with:
76
+ python-version: "3.12"
77
+ - name: Install Django adapter and PostgreSQL driver
78
+ run: python -m pip install -e ".[django]" "psycopg[binary]>=3.2,<4"
79
+ - name: Check migration lifecycle and cross-connection lock
80
+ env:
81
+ PSH_PG_DATABASE: patchshuttle_test
82
+ PSH_PG_USER: postgres
83
+ PSH_PG_PASSWORD: disposable-ci-password
84
+ PSH_PG_PORT: "5432"
85
+ run: python tools/django_postgres_smoke.py
54
86
 
55
87
  package:
56
88
  name: Build and smoke-test distributions
57
- needs: test
89
+ needs: [test, postgres]
58
90
  runs-on: ubuntu-24.04
59
91
  timeout-minutes: 20
60
92
  steps:
@@ -26,5 +26,6 @@ Thumbs.db
26
26
  patches/applied/
27
27
  patches/backups/
28
28
  patches/failed/
29
+ patches/history/
29
30
  patches/logs/
30
31
  patches/state/
@@ -3,7 +3,50 @@
3
3
  All notable changes to PatchShuttle are recorded in this file. The project
4
4
  uses semantic versioning, including Python-compatible pre-release versions.
5
5
 
6
- ## Unreleased
6
+ ## 0.1.0a6 - 2026-10-21
7
+
8
+ ### Added
9
+
10
+ - Guarded `read_imports`, `ensure_import` and `remove_import` with alias-aware AST matching, comment preservation and binding checks.
11
+
12
+ - Optional authenticated MCP history server for ChatGPT, scoped to one workspace and OAuth subject.
13
+ - Optional Django migration command with hashed plans, database locks, pre/post checks, explicit reversals and separate recovery journals.
14
+ - Guarded `move_range` and `move_symbol` source transfers between files,
15
+ including destination fingerprints, structural validation, Python constructors,
16
+ and shared transaction rollback.
17
+ - Guarded `move_file` with destination absence checks, byte/mode preservation,
18
+ explicit deleted-file reporting, and automatic and manual rollback.
19
+
20
+ - Optional AST guards for `replace_symbol`, with hashes and Python version
21
+ reported by `read_symbol`, replacement declaration validation and compile
22
+ validation. Existing text-only job serialization remains compatible.
23
+
24
+ ### Changed
25
+
26
+ - Formatter child interpreters and Black preflight explicitly enable Python
27
+ UTF-8 mode, including under isolated execution.
28
+
29
+ See `docs/NEXT_RELEASE.md` for implemented scope and remaining release work.
30
+
31
+ ## 0.1.0a5 - 2026-08-28
32
+
33
+ Fourth alpha release, focused on persistent structured execution history
34
+ for bounded external retrieval and long-term orchestration.
35
+
36
+ ### Added
37
+
38
+ - Schema-versioned, append-only structured job history records under
39
+ `patches/history/<job-id>/` separate declared intent from observed execution
40
+ facts, reference detailed logs, preserve successful, failed, declined, and
41
+ rollback attempts, and expose bounded read-only Python and CLI access. History
42
+ persistence is a best-effort secondary artifact and cannot change a job result
43
+ or trigger rollback.
44
+
45
+ ### Fixed
46
+
47
+ - Structured history models retain the canonical external `schema` JSON key
48
+ without shadowing Pydantic's legacy `BaseModel.schema` attribute or emitting a
49
+ warning during command startup.
7
50
 
8
51
  ## 0.1.0a4 - 2026-08-27
9
52
 
@@ -1,3 +1,47 @@
1
+ Metadata-Version: 2.4
2
+ Name: patchshuttle
3
+ Version: 0.1.0a6
4
+ Summary: Local, auditable patch workflows for AI-assisted software development
5
+ License-Expression: MIT
6
+ License-File: LICENSE
7
+ Keywords: ai,automation,cli,development-tools,patch
8
+ Classifier: Development Status :: 3 - Alpha
9
+ Classifier: Environment :: Console
10
+ Classifier: Intended Audience :: Developers
11
+ Classifier: Operating System :: OS Independent
12
+ Classifier: Programming Language :: Python :: 3 :: Only
13
+ Classifier: Programming Language :: Python :: 3.10
14
+ Classifier: Programming Language :: Python :: 3.11
15
+ Classifier: Programming Language :: Python :: 3.12
16
+ Classifier: Programming Language :: Python :: 3.13
17
+ Classifier: Programming Language :: Python :: 3.14
18
+ Classifier: Typing :: Typed
19
+ Requires-Python: >=3.10
20
+ Requires-Dist: black<27,>=24
21
+ Requires-Dist: click<9,>=8.1
22
+ Requires-Dist: filelock<4,>=3.30
23
+ Requires-Dist: isort<7,>=5.13
24
+ Requires-Dist: pydantic<3,>=2.6
25
+ Requires-Dist: pyyaml<7,>=6
26
+ Requires-Dist: ruff<1,>=0.16
27
+ Requires-Dist: tomli<3,>=2; python_version < '3.11'
28
+ Provides-Extra: dev
29
+ Requires-Dist: build<2,>=1.2; extra == 'dev'
30
+ Requires-Dist: django<7,>=5.2; extra == 'dev'
31
+ Requires-Dist: mcp<2,>=1.30; extra == 'dev'
32
+ Requires-Dist: pyjwt[crypto]<3,>=2.10; extra == 'dev'
33
+ Requires-Dist: pytest-cov<8,>=5; extra == 'dev'
34
+ Requires-Dist: pytest<10,>=8; extra == 'dev'
35
+ Requires-Dist: twine<7,>=6.1; extra == 'dev'
36
+ Provides-Extra: django
37
+ Requires-Dist: django<7,>=5.2; extra == 'django'
38
+ Provides-Extra: html
39
+ Requires-Dist: djlint<2,>=1.44; extra == 'html'
40
+ Provides-Extra: mcp
41
+ Requires-Dist: mcp<2,>=1.30; extra == 'mcp'
42
+ Requires-Dist: pyjwt[crypto]<3,>=2.10; extra == 'mcp'
43
+ Description-Content-Type: text/markdown
44
+
1
45
  # PatchShuttle
2
46
 
3
47
  PatchShuttle is intended to provide local, auditable patch workflows for
@@ -6,7 +50,7 @@ describes a small job, the user reviews and runs it locally, and PatchShuttle
6
50
  records the result for the next iteration.
7
51
 
8
52
  > [!IMPORTANT]
9
- > PatchShuttle is alpha software. Version `0.1.0a4` implements the complete
53
+ > PatchShuttle is alpha software. Version `0.1.0a6` implements the complete
10
54
  > local v0.1 workflow. It executes bounded read-only
11
55
  > audits, approved patch transactions, and approved one-pass verification jobs
12
56
  > under a project lock. Patch jobs retain backups, run controlled checks, apply
@@ -17,9 +61,9 @@ records the result for the next iteration.
17
61
  > Trusted Publishing workflows are implemented. Every versioned release must
18
62
  > pass its own local qualification, GitHub-hosted Windows/Ubuntu matrix,
19
63
  > TestPyPI installation, production publication, and post-release smoke gates.
20
- > The immutable `0.1.0a2` and `0.1.0a3` qualification evidence, plus the
21
- > separately scoped `0.1.0a2` ChatGPT end-to-end workflow, are retained in
22
- > [docs/RELEASE.md](docs/RELEASE.md).
64
+ > The immutable `0.1.0a2`, `0.1.0a3`, and `0.1.0a4` qualification
65
+ > evidence, plus the separately scoped `0.1.0a2` ChatGPT end-to-end
66
+ > workflow, are retained in [docs/RELEASE.md](docs/RELEASE.md).
23
67
 
24
68
  > [!NOTE]
25
69
  > Compared with `0.1.0a2`, version `0.1.0a3` adds AI-facing planner diagnostics,
@@ -30,14 +74,20 @@ records the result for the next iteration.
30
74
  > range hash.
31
75
 
32
76
  > [!NOTE]
33
- > The current development branch also contains unreleased work completed after
34
- > `0.1.0a3`: `search_context`, `read_symbol`, guarded `replace_symbol`, a fixed
35
- > Ruff F-only check, compact text and JSON AI log views, explicit Django warning
36
- > baselines, owner-controlled project-check Python selection, evidence-only
37
- > Python discovery telemetry, expanded Python secret redaction, nested
38
- > dependency-environment exclusions, and bounded declaration-only
39
- > `python_structure` discovery. These features are available from the source
40
- > branch and are not part of the immutable `0.1.0a3` PyPI artifacts.
77
+ > Version `0.1.0a4` adds `search_context`, `read_symbol`, guarded
78
+ > `replace_symbol`, the fixed Ruff F-only check, compact AI log views, Django
79
+ > warning baselines, owner-controlled project-check Python selection,
80
+ > evidence-only Python discovery telemetry, expanded redaction, bounded
81
+ > declaration-only `python_structure` discovery with compact output, and
82
+ > owner-controlled architecture ratchets. These features are included in the
83
+ > immutable `0.1.0a4` PyPI artifacts.
84
+
85
+ > [!NOTE]
86
+ > Version `0.1.0a5` adds schema-versioned append-only structured job
87
+ > history, facts-first records, best-effort persistence, and bounded
88
+ > read-only Python and CLI retrieval. Detailed execution logs remain the
89
+ > diagnostic source; external orchestrators remain responsible for project
90
+ > memory, semantic retrieval, requirements, and user decisions.
41
91
 
42
92
  ## Design goals
43
93
 
@@ -57,7 +107,7 @@ After publication, install the exact alpha release from PyPI:
57
107
  ```bash
58
108
  python -m venv .venv
59
109
  python -m pip install --upgrade pip
60
- python -m pip install "patchshuttle==0.1.0a4"
110
+ python -m pip install "patchshuttle==0.1.0a6"
61
111
  ```
62
112
 
63
113
  For development from a local checkout:
@@ -70,7 +120,7 @@ To enable opt-in HTML template linting in an installed release, install the
70
120
  `html` extra:
71
121
 
72
122
  ```bash
73
- python -m pip install "patchshuttle[html]==0.1.0a4"
123
+ python -m pip install "patchshuttle[html]==0.1.0a6"
74
124
  ```
75
125
 
76
126
  For a local development checkout, install both development and HTML extras:
@@ -472,6 +522,13 @@ rejects missing, duplicate, syntactically invalid, or stale targets, and does
472
522
  not use fuzzy relocation or automatic line shifting. Exact desired symbol
473
523
  content is an idempotent `NO_CHANGE`.
474
524
 
525
+ The optional `expected_ast_sha256` guard uses the structural hash from
526
+ `read_symbol` to tolerate formatting changes. It ignores ordinary comments,
527
+ includes docstrings and decorators, and is scoped to the reported Python minor
528
+ version. Supply the text hash too when comments must be guarded. AST-guarded
529
+ replacements retain the name and kind and undergo compile and resolution
530
+ validation. See [next-release work](docs/NEXT_RELEASE.md) for current scope.
531
+
475
532
  For a supported plan, the implemented sequence is:
476
533
 
477
534
  1. validate the workspace lock file and acquire a non-blocking cross-platform
@@ -834,12 +891,13 @@ python -m coverage report --fail-under=100
834
891
  python -m build
835
892
  python -m twine check dist/*
836
893
  python tools/release_checks.py dist
837
- python tools/wheel_smoke.py dist/patchshuttle-0.1.0a4-py3-none-any.whl --version 0.1.0a4
894
+ python tools/wheel_smoke.py dist/patchshuttle-0.1.0a6-py3-none-any.whl --version 0.1.0a6
838
895
  ```
839
896
 
840
- The `0.1.0a2` and `0.1.0a3` alpha releases each passed the required Ubuntu and
841
- Windows compatibility matrix, TestPyPI qualification, production PyPI Trusted
842
- Publishing, and a clean post-release installation. Their exact release and
897
+ The `0.1.0a2`, `0.1.0a3`, and `0.1.0a4` alpha releases each passed the
898
+ required Ubuntu and Windows compatibility matrix, TestPyPI qualification,
899
+ production PyPI Trusted Publishing, and a clean post-release installation.
900
+ Their exact release and
843
901
  workflow links and artifact hashes, together with the separately scoped
844
902
  `0.1.0a2` ChatGPT end-to-end evidence, are recorded in
845
903
  [docs/RELEASE.md](docs/RELEASE.md). Follow that guide in order for every future
@@ -892,6 +950,54 @@ confirmation, backup, or project checks.
892
950
  This is deliberately a structural guard. It does not infer feature boundaries,
893
951
  build dependency or call graphs, detect cycles, judge semantic responsibility,
894
952
  reorganize files, or change the patch scope selected by the AI.
953
+
954
+ ## Structured project history
955
+
956
+ PatchShuttle writes one compact JSON record for each recorded execution attempt to
957
+ `patches/history/<job-id>/<record-id>.json`. These records are intended for
958
+ long-term external ingestion and AI retrieval. They describe PatchShuttle's own
959
+ operations only; requirements, conversations, product decisions, stages, browser
960
+ tests, and semantic project memory belong to an external orchestrator.
961
+
962
+ History has a different purpose from the other outputs:
963
+
964
+ - execution logs contain detailed diagnostic evidence and command output;
965
+ - AI logs are bounded deterministic views derived from execution logs;
966
+ - history records contain compact schema-versioned facts plus references to the
967
+ detailed log and its derived AI-log view.
968
+
969
+ `job.title` and bounded, redacted `job.description` are stored below `declared` as
970
+ operator or AI-supplied intent. They are never presented as observed facts.
971
+ `observed` contains only trusted execution state: status, files, checks, failures,
972
+ rollback, warnings, and reliably targeted symbols. PatchShuttle does not infer
973
+ workarounds, semantic meaning, relationships, or affected symbols it cannot prove.
974
+
975
+ Read records without parsing human-readable logs:
976
+
977
+ ```powershell
978
+ patchshuttle history list --limit 20
979
+ patchshuttle history latest
980
+ patchshuttle history latest PATCH-EXAMPLE-001
981
+ patchshuttle history show PATCH-EXAMPLE-001/2026_08_27_120000_000001_abcdef01
982
+ ```
983
+
984
+ `latest` and `show` return the full canonical JSON record. `list` returns bounded
985
+ JSON summaries, one per line. Python integrations can call
986
+ `list_history_records`, `latest_history_record`, and `read_history_record` from
987
+ `patchshuttle.history`. External systems may also ingest the per-attempt JSON files
988
+ directly.
989
+
990
+ History writing occurs after the required detailed log and registry update. It is
991
+ best-effort: a history storage failure is exposed through the Python result's
992
+ `history_warning`, but does not turn a completed job into a failure or trigger
993
+ rollback. Existing protocol-1 jobs require no changes. Existing workspaces may add
994
+ `patches/history/**` to `project.ignored_paths`; new default configurations already
995
+ exclude it from workspace inventories.
996
+
997
+ The v1 layout is append-only and uses exclusive file creation. It deliberately has
998
+ no database, JSONL index, semantic search, vector store, relationship graph, or
999
+ Farm-specific behavior.
1000
+
895
1001
  ## Manual workflow
896
1002
 
897
1003
  The implemented local cycle is:
@@ -916,3 +1022,61 @@ model, or project.
916
1022
  ## License
917
1023
 
918
1024
  PatchShuttle is licensed under the MIT License.
1025
+
1026
+
1027
+ ## Guarded source transfers
1028
+
1029
+ - `move_range`: `path`, `start_line`, `end_line`, source `expected_content`
1030
+ and/or `expected_sha256`, `destination`, `destination_line` and
1031
+ `expected_destination_sha256`.
1032
+ - `move_symbol`: `path`, `symbol`, `expected_ast_sha256`, `destination`,
1033
+ `expected_destination_sha256` and optional `destination_class`.
1034
+
1035
+ Destination hashes cover simulated raw bytes; source range hashes cover
1036
+ canonical LF/UTF-8 text. Destinations must exist or be created earlier in the
1037
+ same job. Range insertion is before the 1-based destination line; EOF+1 appends.
1038
+ Symbol insertion appends at module scope or to the named class. Both files are
1039
+ validated and participate in the same backup/check/rollback transaction.
1040
+
1041
+ Same-file transfers, case-only path differences, duplicate destination names,
1042
+ closure extraction, class-bound super/private-name moves and multiline-string
1043
+ reindentation are rejected. Imports and callers are not automatically rewritten;
1044
+ include explicit edits and focused project checks. These actions move source
1045
+ content and leave the source file present. Whole-file moves are separate work.
1046
+
1047
+
1048
+ ## Whole-file transfers
1049
+
1050
+ `move_file` moves an existing supported text file to an absent destination.
1051
+ Supply `path`, `destination`, and `expected_sha256` of the original raw bytes.
1052
+ The transaction preserves original bytes and permissions, creates missing
1053
+ parent directories, and reports the source in `deleted_files`. Formatters and
1054
+ checks target the surviving destination. Add explicit import and caller edits
1055
+ when moving Python modules; imports are not automatically rewritten.
1056
+
1057
+ The source and destination must not have been touched earlier in the job.
1058
+ Subsequent edits to the destination are supported. Case-only moves, chains,
1059
+ swaps, binary files and reuse of the vacated path are currently rejected.
1060
+ A failed check restores the source and removes the destination. Manual rollback
1061
+ also verifies the applied state and refuses to overwrite a recreated source.
1062
+
1063
+
1064
+ ## Optional integrations
1065
+
1066
+ - `patchshuttle[mcp]`: authenticated, read-only history retrieval for ChatGPT. See [setup and deployment limits](docs/CHATGPT_INTEGRATION.md).
1067
+ - `patchshuttle[django]`: reviewed migration plans, explicit execution/reversal, and a separate recovery journal. See [Django workflow](docs/DJANGO_MIGRATIONS.md).
1068
+
1069
+
1070
+ ## Structural editing and optional adapters in 0.1.0a6
1071
+
1072
+ Use `read_symbol` AST hashes for guarded class/method replacements; use
1073
+ `read_imports`, `ensure_import`, and `remove_import` for structural imports.
1074
+ `move_file`, `move_range`, and `move_symbol` support explicit refactoring plans
1075
+ with shared checks and rollback. Imports and callers are not inferred.
1076
+ See [scope and examples](docs/NEXT_RELEASE.md).
1077
+
1078
+ Optional [ChatGPT history retrieval](docs/CHATGPT_INTEGRATION.md) uses an
1079
+ owner-configured authenticated MCP server (`patchshuttle[mcp]`).
1080
+ Optional [Django migrations](docs/DJANGO_MIGRATIONS.md) provide reviewed plans,
1081
+ locks and recovery journals (`patchshuttle[django]`). A live ChatGPT deployment
1082
+ requires the owner's HTTPS endpoint and OAuth configuration.
@@ -1,40 +1,3 @@
1
- Metadata-Version: 2.4
2
- Name: patchshuttle
3
- Version: 0.1.0a4
4
- Summary: Local, auditable patch workflows for AI-assisted software development
5
- License-Expression: MIT
6
- License-File: LICENSE
7
- Keywords: ai,automation,cli,development-tools,patch
8
- Classifier: Development Status :: 3 - Alpha
9
- Classifier: Environment :: Console
10
- Classifier: Intended Audience :: Developers
11
- Classifier: Operating System :: OS Independent
12
- Classifier: Programming Language :: Python :: 3 :: Only
13
- Classifier: Programming Language :: Python :: 3.10
14
- Classifier: Programming Language :: Python :: 3.11
15
- Classifier: Programming Language :: Python :: 3.12
16
- Classifier: Programming Language :: Python :: 3.13
17
- Classifier: Programming Language :: Python :: 3.14
18
- Classifier: Typing :: Typed
19
- Requires-Python: >=3.10
20
- Requires-Dist: black<27,>=24
21
- Requires-Dist: click<9,>=8.1
22
- Requires-Dist: filelock<4,>=3.30
23
- Requires-Dist: isort<7,>=5.13
24
- Requires-Dist: pydantic<3,>=2.6
25
- Requires-Dist: pyyaml<7,>=6
26
- Requires-Dist: ruff<1,>=0.16
27
- Requires-Dist: tomli<3,>=2; python_version < '3.11'
28
- Provides-Extra: dev
29
- Requires-Dist: build<2,>=1.2; extra == 'dev'
30
- Requires-Dist: django<7,>=5.2; extra == 'dev'
31
- Requires-Dist: pytest-cov<8,>=5; extra == 'dev'
32
- Requires-Dist: pytest<10,>=8; extra == 'dev'
33
- Requires-Dist: twine<7,>=6.1; extra == 'dev'
34
- Provides-Extra: html
35
- Requires-Dist: djlint<2,>=1.44; extra == 'html'
36
- Description-Content-Type: text/markdown
37
-
38
1
  # PatchShuttle
39
2
 
40
3
  PatchShuttle is intended to provide local, auditable patch workflows for
@@ -43,7 +6,7 @@ describes a small job, the user reviews and runs it locally, and PatchShuttle
43
6
  records the result for the next iteration.
44
7
 
45
8
  > [!IMPORTANT]
46
- > PatchShuttle is alpha software. Version `0.1.0a4` implements the complete
9
+ > PatchShuttle is alpha software. Version `0.1.0a6` implements the complete
47
10
  > local v0.1 workflow. It executes bounded read-only
48
11
  > audits, approved patch transactions, and approved one-pass verification jobs
49
12
  > under a project lock. Patch jobs retain backups, run controlled checks, apply
@@ -54,9 +17,9 @@ records the result for the next iteration.
54
17
  > Trusted Publishing workflows are implemented. Every versioned release must
55
18
  > pass its own local qualification, GitHub-hosted Windows/Ubuntu matrix,
56
19
  > TestPyPI installation, production publication, and post-release smoke gates.
57
- > The immutable `0.1.0a2` and `0.1.0a3` qualification evidence, plus the
58
- > separately scoped `0.1.0a2` ChatGPT end-to-end workflow, are retained in
59
- > [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).
60
23
 
61
24
  > [!NOTE]
62
25
  > Compared with `0.1.0a2`, version `0.1.0a3` adds AI-facing planner diagnostics,
@@ -67,14 +30,20 @@ records the result for the next iteration.
67
30
  > range hash.
68
31
 
69
32
  > [!NOTE]
70
- > The current development branch also contains unreleased work completed after
71
- > `0.1.0a3`: `search_context`, `read_symbol`, guarded `replace_symbol`, a fixed
72
- > Ruff F-only check, compact text and JSON AI log views, explicit Django warning
73
- > baselines, owner-controlled project-check Python selection, evidence-only
74
- > Python discovery telemetry, expanded Python secret redaction, nested
75
- > dependency-environment exclusions, and bounded declaration-only
76
- > `python_structure` discovery. These features are available from the source
77
- > branch and are not part of the immutable `0.1.0a3` PyPI artifacts.
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.
78
47
 
79
48
  ## Design goals
80
49
 
@@ -94,7 +63,7 @@ After publication, install the exact alpha release from PyPI:
94
63
  ```bash
95
64
  python -m venv .venv
96
65
  python -m pip install --upgrade pip
97
- python -m pip install "patchshuttle==0.1.0a4"
66
+ python -m pip install "patchshuttle==0.1.0a6"
98
67
  ```
99
68
 
100
69
  For development from a local checkout:
@@ -107,7 +76,7 @@ To enable opt-in HTML template linting in an installed release, install the
107
76
  `html` extra:
108
77
 
109
78
  ```bash
110
- python -m pip install "patchshuttle[html]==0.1.0a4"
79
+ python -m pip install "patchshuttle[html]==0.1.0a6"
111
80
  ```
112
81
 
113
82
  For a local development checkout, install both development and HTML extras:
@@ -509,6 +478,13 @@ rejects missing, duplicate, syntactically invalid, or stale targets, and does
509
478
  not use fuzzy relocation or automatic line shifting. Exact desired symbol
510
479
  content is an idempotent `NO_CHANGE`.
511
480
 
481
+ The optional `expected_ast_sha256` guard uses the structural hash from
482
+ `read_symbol` to tolerate formatting changes. It ignores ordinary comments,
483
+ includes docstrings and decorators, and is scoped to the reported Python minor
484
+ version. Supply the text hash too when comments must be guarded. AST-guarded
485
+ replacements retain the name and kind and undergo compile and resolution
486
+ validation. See [next-release work](docs/NEXT_RELEASE.md) for current scope.
487
+
512
488
  For a supported plan, the implemented sequence is:
513
489
 
514
490
  1. validate the workspace lock file and acquire a non-blocking cross-platform
@@ -871,12 +847,13 @@ python -m coverage report --fail-under=100
871
847
  python -m build
872
848
  python -m twine check dist/*
873
849
  python tools/release_checks.py dist
874
- python tools/wheel_smoke.py dist/patchshuttle-0.1.0a4-py3-none-any.whl --version 0.1.0a4
850
+ python tools/wheel_smoke.py dist/patchshuttle-0.1.0a6-py3-none-any.whl --version 0.1.0a6
875
851
  ```
876
852
 
877
- The `0.1.0a2` and `0.1.0a3` alpha releases each passed the required Ubuntu and
878
- Windows compatibility matrix, TestPyPI qualification, production PyPI Trusted
879
- Publishing, and a clean post-release installation. Their exact release and
853
+ The `0.1.0a2`, `0.1.0a3`, and `0.1.0a4` alpha releases each passed the
854
+ required Ubuntu and Windows compatibility matrix, TestPyPI qualification,
855
+ production PyPI Trusted Publishing, and a clean post-release installation.
856
+ Their exact release and
880
857
  workflow links and artifact hashes, together with the separately scoped
881
858
  `0.1.0a2` ChatGPT end-to-end evidence, are recorded in
882
859
  [docs/RELEASE.md](docs/RELEASE.md). Follow that guide in order for every future
@@ -929,6 +906,54 @@ confirmation, backup, or project checks.
929
906
  This is deliberately a structural guard. It does not infer feature boundaries,
930
907
  build dependency or call graphs, detect cycles, judge semantic responsibility,
931
908
  reorganize files, or change the patch scope selected by the AI.
909
+
910
+ ## Structured project history
911
+
912
+ PatchShuttle writes one compact JSON record for each recorded execution attempt to
913
+ `patches/history/<job-id>/<record-id>.json`. These records are intended for
914
+ long-term external ingestion and AI retrieval. They describe PatchShuttle's own
915
+ operations only; requirements, conversations, product decisions, stages, browser
916
+ tests, and semantic project memory belong to an external orchestrator.
917
+
918
+ History has a different purpose from the other outputs:
919
+
920
+ - execution logs contain detailed diagnostic evidence and command output;
921
+ - AI logs are bounded deterministic views derived from execution logs;
922
+ - history records contain compact schema-versioned facts plus references to the
923
+ detailed log and its derived AI-log view.
924
+
925
+ `job.title` and bounded, redacted `job.description` are stored below `declared` as
926
+ operator or AI-supplied intent. They are never presented as observed facts.
927
+ `observed` contains only trusted execution state: status, files, checks, failures,
928
+ rollback, warnings, and reliably targeted symbols. PatchShuttle does not infer
929
+ workarounds, semantic meaning, relationships, or affected symbols it cannot prove.
930
+
931
+ Read records without parsing human-readable logs:
932
+
933
+ ```powershell
934
+ patchshuttle history list --limit 20
935
+ patchshuttle history latest
936
+ patchshuttle history latest PATCH-EXAMPLE-001
937
+ patchshuttle history show PATCH-EXAMPLE-001/2026_08_27_120000_000001_abcdef01
938
+ ```
939
+
940
+ `latest` and `show` return the full canonical JSON record. `list` returns bounded
941
+ JSON summaries, one per line. Python integrations can call
942
+ `list_history_records`, `latest_history_record`, and `read_history_record` from
943
+ `patchshuttle.history`. External systems may also ingest the per-attempt JSON files
944
+ directly.
945
+
946
+ History writing occurs after the required detailed log and registry update. It is
947
+ best-effort: a history storage failure is exposed through the Python result's
948
+ `history_warning`, but does not turn a completed job into a failure or trigger
949
+ rollback. Existing protocol-1 jobs require no changes. Existing workspaces may add
950
+ `patches/history/**` to `project.ignored_paths`; new default configurations already
951
+ exclude it from workspace inventories.
952
+
953
+ The v1 layout is append-only and uses exclusive file creation. It deliberately has
954
+ no database, JSONL index, semantic search, vector store, relationship graph, or
955
+ Farm-specific behavior.
956
+
932
957
  ## Manual workflow
933
958
 
934
959
  The implemented local cycle is:
@@ -953,3 +978,61 @@ model, or project.
953
978
  ## License
954
979
 
955
980
  PatchShuttle is licensed under the MIT License.
981
+
982
+
983
+ ## Guarded source transfers
984
+
985
+ - `move_range`: `path`, `start_line`, `end_line`, source `expected_content`
986
+ and/or `expected_sha256`, `destination`, `destination_line` and
987
+ `expected_destination_sha256`.
988
+ - `move_symbol`: `path`, `symbol`, `expected_ast_sha256`, `destination`,
989
+ `expected_destination_sha256` and optional `destination_class`.
990
+
991
+ Destination hashes cover simulated raw bytes; source range hashes cover
992
+ canonical LF/UTF-8 text. Destinations must exist or be created earlier in the
993
+ same job. Range insertion is before the 1-based destination line; EOF+1 appends.
994
+ Symbol insertion appends at module scope or to the named class. Both files are
995
+ validated and participate in the same backup/check/rollback transaction.
996
+
997
+ Same-file transfers, case-only path differences, duplicate destination names,
998
+ closure extraction, class-bound super/private-name moves and multiline-string
999
+ reindentation are rejected. Imports and callers are not automatically rewritten;
1000
+ include explicit edits and focused project checks. These actions move source
1001
+ content and leave the source file present. Whole-file moves are separate work.
1002
+
1003
+
1004
+ ## Whole-file transfers
1005
+
1006
+ `move_file` moves an existing supported text file to an absent destination.
1007
+ Supply `path`, `destination`, and `expected_sha256` of the original raw bytes.
1008
+ The transaction preserves original bytes and permissions, creates missing
1009
+ parent directories, and reports the source in `deleted_files`. Formatters and
1010
+ checks target the surviving destination. Add explicit import and caller edits
1011
+ when moving Python modules; imports are not automatically rewritten.
1012
+
1013
+ The source and destination must not have been touched earlier in the job.
1014
+ Subsequent edits to the destination are supported. Case-only moves, chains,
1015
+ swaps, binary files and reuse of the vacated path are currently rejected.
1016
+ A failed check restores the source and removes the destination. Manual rollback
1017
+ also verifies the applied state and refuses to overwrite a recreated source.
1018
+
1019
+
1020
+ ## Optional integrations
1021
+
1022
+ - `patchshuttle[mcp]`: authenticated, read-only history retrieval for ChatGPT. See [setup and deployment limits](docs/CHATGPT_INTEGRATION.md).
1023
+ - `patchshuttle[django]`: reviewed migration plans, explicit execution/reversal, and a separate recovery journal. See [Django workflow](docs/DJANGO_MIGRATIONS.md).
1024
+
1025
+
1026
+ ## Structural editing and optional adapters in 0.1.0a6
1027
+
1028
+ Use `read_symbol` AST hashes for guarded class/method replacements; use
1029
+ `read_imports`, `ensure_import`, and `remove_import` for structural imports.
1030
+ `move_file`, `move_range`, and `move_symbol` support explicit refactoring plans
1031
+ with shared checks and rollback. Imports and callers are not inferred.
1032
+ See [scope and examples](docs/NEXT_RELEASE.md).
1033
+
1034
+ Optional [ChatGPT history retrieval](docs/CHATGPT_INTEGRATION.md) uses an
1035
+ owner-configured authenticated MCP server (`patchshuttle[mcp]`).
1036
+ Optional [Django migrations](docs/DJANGO_MIGRATIONS.md) provide reviewed plans,
1037
+ locks and recovery journals (`patchshuttle[django]`). A live ChatGPT deployment
1038
+ requires the owner's HTTPS endpoint and OAuth configuration.