engineering-process 0.5.1__tar.gz → 0.6.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (188) hide show
  1. {engineering_process-0.5.1/engineering_process.egg-info → engineering_process-0.6.0}/PKG-INFO +71 -5
  2. {engineering_process-0.5.1 → engineering_process-0.6.0}/PRODUCTION_STANDARD.md +31 -0
  3. {engineering_process-0.5.1 → engineering_process-0.6.0}/README.md +70 -4
  4. {engineering_process-0.5.1 → engineering_process-0.6.0}/VERSIONING.md +25 -0
  5. {engineering_process-0.5.1 → engineering_process-0.6.0}/engineering_process/__init__.py +1 -1
  6. {engineering_process-0.5.1 → engineering_process-0.6.0}/engineering_process/cli.py +222 -0
  7. {engineering_process-0.5.1 → engineering_process-0.6.0}/engineering_process/command_catalog.py +2 -0
  8. {engineering_process-0.5.1 → engineering_process-0.6.0}/engineering_process/contracts.py +1485 -179
  9. {engineering_process-0.5.1 → engineering_process-0.6.0}/engineering_process/distribution_verify.py +2 -0
  10. {engineering_process-0.5.1 → engineering_process-0.6.0}/engineering_process/evidence.py +286 -5
  11. {engineering_process-0.5.1 → engineering_process-0.6.0}/engineering_process/lifecycle.py +558 -5
  12. {engineering_process-0.5.1 → engineering_process-0.6.0}/engineering_process/process_graph.py +6 -1
  13. engineering_process-0.6.0/engineering_process/recommendation.py +517 -0
  14. engineering_process-0.6.0/engineering_process/remote_verification.py +498 -0
  15. {engineering_process-0.5.1 → engineering_process-0.6.0/engineering_process.egg-info}/PKG-INFO +71 -5
  16. {engineering_process-0.5.1 → engineering_process-0.6.0}/engineering_process.egg-info/SOURCES.txt +17 -0
  17. {engineering_process-0.5.1 → engineering_process-0.6.0}/examples/change.json +1 -0
  18. {engineering_process-0.5.1 → engineering_process-0.6.0}/examples/project.json +22 -0
  19. engineering_process-0.6.0/examples/recommendation-resolution.json +21 -0
  20. engineering_process-0.6.0/examples/recommendation-review-assignment.json +22 -0
  21. engineering_process-0.6.0/examples/recommendation-review.json +60 -0
  22. engineering_process-0.6.0/examples/recommendation.json +89 -0
  23. engineering_process-0.6.0/examples/remote-verification-evidence.json +26 -0
  24. engineering_process-0.6.0/examples/remote-verification-request.json +40 -0
  25. {engineering_process-0.5.1 → engineering_process-0.6.0}/improvement-catalog.json +3 -2
  26. {engineering_process-0.5.1 → engineering_process-0.6.0}/process-graph.json +1 -1
  27. {engineering_process-0.5.1 → engineering_process-0.6.0}/process_assets/skills/assess-design/SKILL.md +16 -3
  28. {engineering_process-0.5.1 → engineering_process-0.6.0}/process_assets/skills/run-change/references/execution.md +43 -7
  29. {engineering_process-0.5.1 → engineering_process-0.6.0}/process_assets/skills/verify-change/SKILL.md +11 -3
  30. {engineering_process-0.5.1 → engineering_process-0.6.0}/pyproject.toml +13 -1
  31. engineering_process-0.6.0/release.json +51 -0
  32. {engineering_process-0.5.1 → engineering_process-0.6.0}/schemas/change.schema.json +18 -1
  33. {engineering_process-0.5.1 → engineering_process-0.6.0}/schemas/evidence-receipt.schema.json +36 -1
  34. {engineering_process-0.5.1 → engineering_process-0.6.0}/schemas/lifecycle.schema.json +26 -0
  35. {engineering_process-0.5.1 → engineering_process-0.6.0}/schemas/project.schema.json +92 -2
  36. engineering_process-0.6.0/schemas/recommendation-resolution.schema.json +60 -0
  37. engineering_process-0.6.0/schemas/recommendation-review-assignment.schema.json +56 -0
  38. engineering_process-0.6.0/schemas/recommendation-review.schema.json +112 -0
  39. engineering_process-0.6.0/schemas/recommendation.schema.json +178 -0
  40. engineering_process-0.6.0/schemas/remote-verification-evidence.schema.json +61 -0
  41. engineering_process-0.6.0/schemas/remote-verification-request.schema.json +116 -0
  42. engineering_process-0.6.0/tests/test_recommendation.py +578 -0
  43. engineering_process-0.6.0/tests/test_remote_verification.py +833 -0
  44. engineering_process-0.6.0/tests/test_remote_verification_adapter.py +360 -0
  45. {engineering_process-0.5.1 → engineering_process-0.6.0}/tests/test_schemas.py +4 -0
  46. {engineering_process-0.5.1 → engineering_process-0.6.0}/tests/test_self_hosting.py +11 -1
  47. {engineering_process-0.5.1 → engineering_process-0.6.0}/tests/test_skills.py +31 -0
  48. engineering_process-0.5.1/release.json +0 -46
  49. {engineering_process-0.5.1 → engineering_process-0.6.0}/LICENSE +0 -0
  50. {engineering_process-0.5.1 → engineering_process-0.6.0}/MANIFEST.in +0 -0
  51. {engineering_process-0.5.1 → engineering_process-0.6.0}/PROCESS_IMPROVEMENT.md +0 -0
  52. {engineering_process-0.5.1 → engineering_process-0.6.0}/bundles.json +0 -0
  53. {engineering_process-0.5.1 → engineering_process-0.6.0}/engineering_process/__main__.py +0 -0
  54. {engineering_process-0.5.1 → engineering_process-0.6.0}/engineering_process/_download_worker.py +0 -0
  55. {engineering_process-0.5.1 → engineering_process-0.6.0}/engineering_process/_supervisor_posix.py +0 -0
  56. {engineering_process-0.5.1 → engineering_process-0.6.0}/engineering_process/_supervisor_windows.py +0 -0
  57. {engineering_process-0.5.1 → engineering_process-0.6.0}/engineering_process/_windows_job.py +0 -0
  58. {engineering_process-0.5.1 → engineering_process-0.6.0}/engineering_process/adoption.py +0 -0
  59. {engineering_process-0.5.1 → engineering_process-0.6.0}/engineering_process/artifact_attestation.py +0 -0
  60. {engineering_process-0.5.1 → engineering_process-0.6.0}/engineering_process/bootstrap.py +0 -0
  61. {engineering_process-0.5.1 → engineering_process-0.6.0}/engineering_process/bounded_process.py +0 -0
  62. {engineering_process-0.5.1 → engineering_process-0.6.0}/engineering_process/bundles.py +0 -0
  63. {engineering_process-0.5.1 → engineering_process-0.6.0}/engineering_process/diagnostics.py +0 -0
  64. {engineering_process-0.5.1 → engineering_process-0.6.0}/engineering_process/distribution.py +0 -0
  65. {engineering_process-0.5.1 → engineering_process-0.6.0}/engineering_process/environment.py +0 -0
  66. {engineering_process-0.5.1 → engineering_process-0.6.0}/engineering_process/evidence_transport.py +0 -0
  67. {engineering_process-0.5.1 → engineering_process-0.6.0}/engineering_process/git.py +0 -0
  68. {engineering_process-0.5.1 → engineering_process-0.6.0}/engineering_process/git_attributes.py +0 -0
  69. {engineering_process-0.5.1 → engineering_process-0.6.0}/engineering_process/helper_launch.py +0 -0
  70. {engineering_process-0.5.1 → engineering_process-0.6.0}/engineering_process/impact.py +0 -0
  71. {engineering_process-0.5.1 → engineering_process-0.6.0}/engineering_process/improvement.py +0 -0
  72. {engineering_process-0.5.1 → engineering_process-0.6.0}/engineering_process/lifecycle_routes.py +0 -0
  73. {engineering_process-0.5.1 → engineering_process-0.6.0}/engineering_process/managed.py +0 -0
  74. {engineering_process-0.5.1 → engineering_process-0.6.0}/engineering_process/markdown.py +0 -0
  75. {engineering_process-0.5.1 → engineering_process-0.6.0}/engineering_process/publication.py +0 -0
  76. {engineering_process-0.5.1 → engineering_process-0.6.0}/engineering_process/release.py +0 -0
  77. {engineering_process-0.5.1 → engineering_process-0.6.0}/engineering_process/release_candidate.py +0 -0
  78. {engineering_process-0.5.1 → engineering_process-0.6.0}/engineering_process/requirements-build.txt +0 -0
  79. {engineering_process-0.5.1 → engineering_process-0.6.0}/engineering_process/requirements-dev.txt +0 -0
  80. {engineering_process-0.5.1 → engineering_process-0.6.0}/engineering_process/requirements-release.txt +0 -0
  81. {engineering_process-0.5.1 → engineering_process-0.6.0}/engineering_process/requirements-runtime.txt +0 -0
  82. {engineering_process-0.5.1 → engineering_process-0.6.0}/engineering_process/runner.py +0 -0
  83. {engineering_process-0.5.1 → engineering_process-0.6.0}/engineering_process/runtime.py +0 -0
  84. {engineering_process-0.5.1 → engineering_process-0.6.0}/engineering_process/skills.py +0 -0
  85. {engineering_process-0.5.1 → engineering_process-0.6.0}/engineering_process/supervision.py +0 -0
  86. {engineering_process-0.5.1 → engineering_process-0.6.0}/engineering_process/supplemental.py +0 -0
  87. {engineering_process-0.5.1 → engineering_process-0.6.0}/engineering_process/syncing.py +0 -0
  88. {engineering_process-0.5.1 → engineering_process-0.6.0}/engineering_process/tooling.py +0 -0
  89. {engineering_process-0.5.1 → engineering_process-0.6.0}/engineering_process.egg-info/dependency_links.txt +0 -0
  90. {engineering_process-0.5.1 → engineering_process-0.6.0}/engineering_process.egg-info/entry_points.txt +0 -0
  91. {engineering_process-0.5.1 → engineering_process-0.6.0}/engineering_process.egg-info/requires.txt +0 -0
  92. {engineering_process-0.5.1 → engineering_process-0.6.0}/engineering_process.egg-info/top_level.txt +0 -0
  93. {engineering_process-0.5.1 → engineering_process-0.6.0}/examples/adoption-migration.json +0 -0
  94. {engineering_process-0.5.1 → engineering_process-0.6.0}/examples/automation-policy.json +0 -0
  95. {engineering_process-0.5.1 → engineering_process-0.6.0}/examples/automation-proposal-policy.json +0 -0
  96. {engineering_process-0.5.1 → engineering_process-0.6.0}/examples/automation-proposal.json +0 -0
  97. {engineering_process-0.5.1 → engineering_process-0.6.0}/examples/improvement-catalog.json +0 -0
  98. {engineering_process-0.5.1 → engineering_process-0.6.0}/examples/improvement-disposition.json +0 -0
  99. {engineering_process-0.5.1 → engineering_process-0.6.0}/examples/improvement-reproduction.json +0 -0
  100. {engineering_process-0.5.1 → engineering_process-0.6.0}/examples/improvement-resolution.json +0 -0
  101. {engineering_process-0.5.1 → engineering_process-0.6.0}/examples/improvement-signal.json +0 -0
  102. {engineering_process-0.5.1 → engineering_process-0.6.0}/examples/plan.json +0 -0
  103. {engineering_process-0.5.1 → engineering_process-0.6.0}/examples/release-change.json +0 -0
  104. {engineering_process-0.5.1 → engineering_process-0.6.0}/examples/release.json +0 -0
  105. {engineering_process-0.5.1 → engineering_process-0.6.0}/examples/review.json +0 -0
  106. {engineering_process-0.5.1 → engineering_process-0.6.0}/process_assets/skills/build-frontend/SKILL.md +0 -0
  107. {engineering_process-0.5.1 → engineering_process-0.6.0}/process_assets/skills/build-frontend-foundation/SKILL.md +0 -0
  108. {engineering_process-0.5.1 → engineering_process-0.6.0}/process_assets/skills/change-api/SKILL.md +0 -0
  109. {engineering_process-0.5.1 → engineering_process-0.6.0}/process_assets/skills/cross-repo-change/SKILL.md +0 -0
  110. {engineering_process-0.5.1 → engineering_process-0.6.0}/process_assets/skills/define-change-contract/SKILL.md +0 -0
  111. {engineering_process-0.5.1 → engineering_process-0.6.0}/process_assets/skills/design-module/SKILL.md +0 -0
  112. {engineering_process-0.5.1 → engineering_process-0.6.0}/process_assets/skills/evolve-process/SKILL.md +0 -0
  113. {engineering_process-0.5.1 → engineering_process-0.6.0}/process_assets/skills/finish-change/SKILL.md +0 -0
  114. {engineering_process-0.5.1 → engineering_process-0.6.0}/process_assets/skills/govern-ui/SKILL.md +0 -0
  115. {engineering_process-0.5.1 → engineering_process-0.6.0}/process_assets/skills/implement-change/SKILL.md +0 -0
  116. {engineering_process-0.5.1 → engineering_process-0.6.0}/process_assets/skills/implement-module/SKILL.md +0 -0
  117. {engineering_process-0.5.1 → engineering_process-0.6.0}/process_assets/skills/implement-use-case/SKILL.md +0 -0
  118. {engineering_process-0.5.1 → engineering_process-0.6.0}/process_assets/skills/integrate-mcp/SKILL.md +0 -0
  119. {engineering_process-0.5.1 → engineering_process-0.6.0}/process_assets/skills/maintain-docs/SKILL.md +0 -0
  120. {engineering_process-0.5.1 → engineering_process-0.6.0}/process_assets/skills/plan-change/SKILL.md +0 -0
  121. {engineering_process-0.5.1 → engineering_process-0.6.0}/process_assets/skills/publish-change/SKILL.md +0 -0
  122. {engineering_process-0.5.1 → engineering_process-0.6.0}/process_assets/skills/review-change/SKILL.md +0 -0
  123. {engineering_process-0.5.1 → engineering_process-0.6.0}/process_assets/skills/run-change/SKILL.md +0 -0
  124. {engineering_process-0.5.1 → engineering_process-0.6.0}/process_assets/skills/run-project-command/SKILL.md +0 -0
  125. {engineering_process-0.5.1 → engineering_process-0.6.0}/process_assets/skills/specify-use-case/SKILL.md +0 -0
  126. {engineering_process-0.5.1 → engineering_process-0.6.0}/schemas/adoption-migration.schema.json +0 -0
  127. {engineering_process-0.5.1 → engineering_process-0.6.0}/schemas/automation-policy.schema.json +0 -0
  128. {engineering_process-0.5.1 → engineering_process-0.6.0}/schemas/automation-proposal-policy.schema.json +0 -0
  129. {engineering_process-0.5.1 → engineering_process-0.6.0}/schemas/automation-proposal.schema.json +0 -0
  130. {engineering_process-0.5.1 → engineering_process-0.6.0}/schemas/improvement-catalog.schema.json +0 -0
  131. {engineering_process-0.5.1 → engineering_process-0.6.0}/schemas/improvement-disposition.schema.json +0 -0
  132. {engineering_process-0.5.1 → engineering_process-0.6.0}/schemas/improvement-reproduction.schema.json +0 -0
  133. {engineering_process-0.5.1 → engineering_process-0.6.0}/schemas/improvement-resolution.schema.json +0 -0
  134. {engineering_process-0.5.1 → engineering_process-0.6.0}/schemas/improvement-signal.schema.json +0 -0
  135. {engineering_process-0.5.1 → engineering_process-0.6.0}/schemas/plan.schema.json +0 -0
  136. {engineering_process-0.5.1 → engineering_process-0.6.0}/schemas/process-graph.schema.json +0 -0
  137. {engineering_process-0.5.1 → engineering_process-0.6.0}/schemas/process-lock.schema.json +0 -0
  138. {engineering_process-0.5.1 → engineering_process-0.6.0}/schemas/release-change.schema.json +0 -0
  139. {engineering_process-0.5.1 → engineering_process-0.6.0}/schemas/release.schema.json +0 -0
  140. {engineering_process-0.5.1 → engineering_process-0.6.0}/schemas/review.schema.json +0 -0
  141. {engineering_process-0.5.1 → engineering_process-0.6.0}/schemas/reviewer-attestation.schema.json +0 -0
  142. {engineering_process-0.5.1 → engineering_process-0.6.0}/schemas/supplemental-verification.schema.json +0 -0
  143. {engineering_process-0.5.1 → engineering_process-0.6.0}/schemas/verification.schema.json +0 -0
  144. {engineering_process-0.5.1 → engineering_process-0.6.0}/setup.cfg +0 -0
  145. {engineering_process-0.5.1 → engineering_process-0.6.0}/templates/AGENTS.process.md +0 -0
  146. {engineering_process-0.5.1 → engineering_process-0.6.0}/templates/PULL_REQUEST_TEMPLATE.md +0 -0
  147. {engineering_process-0.5.1 → engineering_process-0.6.0}/templates/adopt-process-windows-job.py +0 -0
  148. {engineering_process-0.5.1 → engineering_process-0.6.0}/templates/adopt-process.py +0 -0
  149. {engineering_process-0.5.1 → engineering_process-0.6.0}/tests/test_adoption.py +0 -0
  150. {engineering_process-0.5.1 → engineering_process-0.6.0}/tests/test_adoption_runner.py +0 -0
  151. {engineering_process-0.5.1 → engineering_process-0.6.0}/tests/test_artifact_attestation.py +0 -0
  152. {engineering_process-0.5.1 → engineering_process-0.6.0}/tests/test_bootstrap.py +0 -0
  153. {engineering_process-0.5.1 → engineering_process-0.6.0}/tests/test_bounded_process.py +0 -0
  154. {engineering_process-0.5.1 → engineering_process-0.6.0}/tests/test_bundles.py +0 -0
  155. {engineering_process-0.5.1 → engineering_process-0.6.0}/tests/test_cli.py +0 -0
  156. {engineering_process-0.5.1 → engineering_process-0.6.0}/tests/test_completed_release_dispatch.py +0 -0
  157. {engineering_process-0.5.1 → engineering_process-0.6.0}/tests/test_completion_evidence_transport.py +0 -0
  158. {engineering_process-0.5.1 → engineering_process-0.6.0}/tests/test_contracts.py +0 -0
  159. {engineering_process-0.5.1 → engineering_process-0.6.0}/tests/test_diagnostics.py +0 -0
  160. {engineering_process-0.5.1 → engineering_process-0.6.0}/tests/test_distribution.py +0 -0
  161. {engineering_process-0.5.1 → engineering_process-0.6.0}/tests/test_distribution_verify.py +0 -0
  162. {engineering_process-0.5.1 → engineering_process-0.6.0}/tests/test_environment.py +0 -0
  163. {engineering_process-0.5.1 → engineering_process-0.6.0}/tests/test_evals.py +0 -0
  164. {engineering_process-0.5.1 → engineering_process-0.6.0}/tests/test_impact.py +0 -0
  165. {engineering_process-0.5.1 → engineering_process-0.6.0}/tests/test_improvement.py +0 -0
  166. {engineering_process-0.5.1 → engineering_process-0.6.0}/tests/test_lifecycle.py +0 -0
  167. {engineering_process-0.5.1 → engineering_process-0.6.0}/tests/test_process_graph.py +0 -0
  168. {engineering_process-0.5.1 → engineering_process-0.6.0}/tests/test_process_install.py +0 -0
  169. {engineering_process-0.5.1 → engineering_process-0.6.0}/tests/test_publication.py +0 -0
  170. {engineering_process-0.5.1 → engineering_process-0.6.0}/tests/test_publish_event.py +0 -0
  171. {engineering_process-0.5.1 → engineering_process-0.6.0}/tests/test_pypi_publication.py +0 -0
  172. {engineering_process-0.5.1 → engineering_process-0.6.0}/tests/test_release.py +0 -0
  173. {engineering_process-0.5.1 → engineering_process-0.6.0}/tests/test_release_candidate.py +0 -0
  174. {engineering_process-0.5.1 → engineering_process-0.6.0}/tests/test_release_candidate_boundary.py +0 -0
  175. {engineering_process-0.5.1 → engineering_process-0.6.0}/tests/test_release_completion_identity.py +0 -0
  176. {engineering_process-0.5.1 → engineering_process-0.6.0}/tests/test_release_evidence_restore.py +0 -0
  177. {engineering_process-0.5.1 → engineering_process-0.6.0}/tests/test_release_evidence_selection.py +0 -0
  178. {engineering_process-0.5.1 → engineering_process-0.6.0}/tests/test_release_preparation.py +0 -0
  179. {engineering_process-0.5.1 → engineering_process-0.6.0}/tests/test_release_qualification.py +0 -0
  180. {engineering_process-0.5.1 → engineering_process-0.6.0}/tests/test_runner.py +0 -0
  181. {engineering_process-0.5.1 → engineering_process-0.6.0}/tests/test_runtime.py +0 -0
  182. {engineering_process-0.5.1 → engineering_process-0.6.0}/tests/test_source_checkout.py +0 -0
  183. {engineering_process-0.5.1 → engineering_process-0.6.0}/tests/test_supervision.py +0 -0
  184. {engineering_process-0.5.1 → engineering_process-0.6.0}/tests/test_supplemental.py +0 -0
  185. {engineering_process-0.5.1 → engineering_process-0.6.0}/tests/test_syncing.py +0 -0
  186. {engineering_process-0.5.1 → engineering_process-0.6.0}/tests/test_test_suite.py +0 -0
  187. {engineering_process-0.5.1 → engineering_process-0.6.0}/tests/test_tooling.py +0 -0
  188. {engineering_process-0.5.1 → engineering_process-0.6.0}/tests/test_windows_job.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: engineering-process
3
- Version: 0.5.1
3
+ Version: 0.6.0
4
4
  Summary: Agent-neutral end-to-end engineering lifecycle and deterministic process CLI
5
5
  License-Expression: MIT
6
6
  Project-URL: Homepage, https://github.com/phuongnse/engineering-process
@@ -481,12 +481,77 @@ may authorize installing that policy but never substitutes for a missing policy.
481
481
  When new evidence exposes multiple materially valid directions or would change
482
482
  accepted scope, owner, trust boundary, authority, compatibility, rollout, or
483
483
  lifecycle order, the coordinator stops dependent mutation and asks the project owner.
484
- It presents evidence, the invariant, real options, trade-offs, and a recommendation;
485
- the accepted decision is recorded before work resumes. Bounded implementation details
484
+ Before presenting a material recommendation, it records every hard invariant,
485
+ assumption, and option in a bounded recommendation artifact. `processctl` derives the
486
+ valid, invalid, and unproven sets; cost or minimal-change optimization applies only to
487
+ the complete valid set. A distinct actor and fresh context independently challenge
488
+ assumption evidence, invariant tracing, option classification, and terminal ordering.
489
+ If the exact digest-bound chain is not approved or contains no valid option, the
490
+ result is blocked rather than a recommendation. Bounded implementation details
486
491
  already decided by the contract continue autonomously.
487
492
 
493
+ Validate the recommendation, challenge, and optional owner resolution as one chain:
494
+
495
+ ~~~text
496
+ processctl contract validate --kind recommendation recommendation.json
497
+ processctl recommendation review start --project-root . \
498
+ --recommendation recommendation.json \
499
+ --actor <reviewer> --context <fresh-context> --actor-kind agent \
500
+ --method isolated-context --attested-by <host> \
501
+ --attestation-evidence <bounded-attestation>
502
+ processctl contract validate --kind recommendation-review-assignment \
503
+ .process/runs/recommendations/<decision-id>/review-request-<ids>.json
504
+ processctl contract validate --kind recommendation-review recommendation-review.json
505
+ processctl recommendation validate-chain --project-root . \
506
+ --recommendation recommendation.json \
507
+ --assignment .process/runs/recommendations/<decision-id>/review-request-<ids>.json \
508
+ --review recommendation-review.json
509
+ processctl recommendation resolution --project-root . \
510
+ --recommendation recommendation.json \
511
+ --assignment .process/runs/recommendations/<decision-id>/review-request-<ids>.json \
512
+ --review recommendation-review.json \
513
+ --selected-option <valid-option-id> --owner-id <owner-id> \
514
+ --owner-evidence-sha256 sha256:<digest> \
515
+ --selection-rationale-sha256 sha256:<digest> \
516
+ --output recommendation-resolution.json
517
+ processctl recommendation validate-chain --project-root . \
518
+ --recommendation recommendation.json \
519
+ --assignment .process/runs/recommendations/<decision-id>/review-request-<ids>.json \
520
+ --review recommendation-review.json \
521
+ --resolution recommendation-resolution.json
522
+ ~~~
523
+
524
+ The review-start command reserves the context across lifecycle and recommendation
525
+ reviews before emitting its exact assignment. Resolution creation refuses symlinked,
526
+ existing, or concurrently created output instead of redirecting or replacing it. The
527
+ resolution records a selected valid option but grants no lifecycle completion, merge,
528
+ release, deployment, or adoption authority. Those owning gates remain separate. The
529
+ accepted decision is recorded before dependent work resumes.
530
+
531
+ When a schema-3 change selects a project-owned `requiredEvidence` id, local profiles
532
+ alone do not advance it to review. Create the exact no-authority request, run the
533
+ project adapter, and ingest the complete supplemental set first:
534
+
535
+ ~~~text
536
+ processctl change remote request --project-root . --change-id issue-123 \
537
+ --actor worker --context worker-session --actor-kind agent
538
+ python verification/run_remote_verification.py --project-root . \
539
+ --change-id issue-123 --actor worker --context worker-session \
540
+ --actor-kind agent --repository owner/repository \
541
+ --failure-output /durable/receipts/issue-123-remote-failure.json
542
+ processctl change status --project-root . --change-id issue-123
543
+ ~~~
544
+
545
+ The adapter publishes a uniquely named exact-checkpoint verification tag, never a
546
+ branch or PR, dispatches the protected-base workflow, validates service and bundle
547
+ digests, calls `change remote ingest`, and deletes the tag in every terminal path.
548
+ Downloaded temporary archives are deleted after ingestion; failed evidence is moved
549
+ to the explicit durable failure location before cleanup. Remote artifacts and their
550
+ service ids remain lifecycle evidence, not merge, release, deployment, or adoption
551
+ authority.
552
+
488
553
  The canonical publication order is stricter than a PR-first workflow: implementation
489
- and every required profile pass on a clean checkpoint; a consumer-selected independent
554
+ and every required local and remote profile pass on a clean checkpoint; a consumer-selected independent
490
555
  agent or human semantically reviews that checkpoint; findings repeat implementation,
491
556
  complete verification, and fresh review until approved; `change finish` records
492
557
  completion; only then may automation push and create the PR. Static policy/secret/pin
@@ -718,7 +783,8 @@ fingerprint, source tree, or publication range.
718
783
  exclusively by their hash-locked `requirements/process.txt`. The action invokes the
719
784
  producer-owned installer from its immutable action checkout and never downloads or
720
785
  executes helper source from the consumer branch.
721
- - Versioned JSON schemas define change, plan, verification, review, lifecycle,
786
+ - Versioned JSON schemas define change, plan, verification, review, recommendation,
787
+ independent recommendation assignment and challenge, owner resolution, lifecycle,
722
788
  completion-related artifacts, release-change fragments, and the release
723
789
  classification contract. The generated Release PR gate binds that contract to the
724
790
  exact SemVer increment, package version, latest reachable prior tag, reviewed head,
@@ -71,6 +71,16 @@ are preserved with review evidence. These reports supplement the public N-1
71
71
  lifecycle authority; code under verification never promotes itself to lifecycle
72
72
  authority.
73
73
 
74
+ Projects declare named remote requirements and their exact profile and
75
+ platform/runtime selector sets; change contracts select requirement ids. A lifecycle
76
+ request binds those expanded requirements to one clean checkpoint, comparison base,
77
+ workspace fingerprint, and immutable base-owned workflow checkpoint without granting
78
+ review or delivery authority. Provider adapters remain project-owned and transport
79
+ only the exact request. Core ingests local artifact bytes, verifies service and
80
+ content digests plus one-to-one selector coverage, and keeps the lifecycle
81
+ implementing until every local profile and remote requirement passes. A provider job
82
+ conclusion or later PR check is not lifecycle evidence by itself.
83
+
74
84
  ## Failure to invariant
75
85
 
76
86
  A validated command, gate, release, adoption, or external-integration failure must
@@ -97,6 +107,27 @@ failure. Source, branch, version, credentials, and controls are never changed me
97
107
  to cause another attempt. Independent review treats violation of these ownership and
98
108
  evidence boundaries as completion-blocking.
99
109
 
110
+ ## Recommendation validity
111
+
112
+ A material owner decision derives recommendation eligibility before optimization.
113
+ Every option assesses every governing hard invariant and references only proven or
114
+ explicitly unproven assumptions. Any violated invariant makes the option invalid; any
115
+ unproven invariant or referenced assumption makes it unproven. Only the complete
116
+ derived valid set may enter cost, convenience, minimal-change, rollout, or other
117
+ secondary ranking.
118
+
119
+ High-risk recommendations require a process-created digest-bound review assignment.
120
+ Before review, the reviewer method must match its actor kind, a non-participant host
121
+ must attest independence, and the context is atomically reserved in the same
122
+ project-global registry used by lifecycle review. The assigned independent
123
+ adversarial review covers assumption evidence, invariant tracing, option
124
+ classification, and terminal ordering.
125
+ A missing, stale, incomplete, self-attested, context-reused, changes-requested,
126
+ invalid, or unproven chain cannot produce a recommendation. When no valid option
127
+ exists, the outcome is `decision-required`, not an optimized compromise. Owner
128
+ resolution may select only a valid option and grants no lifecycle completion, merge,
129
+ release, deployment, or adoption authority.
130
+
100
131
  ## Resource and generated-state policy
101
132
 
102
133
  Every operation over repository-controlled or remote input has explicit limits for
@@ -446,12 +446,77 @@ may authorize installing that policy but never substitutes for a missing policy.
446
446
  When new evidence exposes multiple materially valid directions or would change
447
447
  accepted scope, owner, trust boundary, authority, compatibility, rollout, or
448
448
  lifecycle order, the coordinator stops dependent mutation and asks the project owner.
449
- It presents evidence, the invariant, real options, trade-offs, and a recommendation;
450
- the accepted decision is recorded before work resumes. Bounded implementation details
449
+ Before presenting a material recommendation, it records every hard invariant,
450
+ assumption, and option in a bounded recommendation artifact. `processctl` derives the
451
+ valid, invalid, and unproven sets; cost or minimal-change optimization applies only to
452
+ the complete valid set. A distinct actor and fresh context independently challenge
453
+ assumption evidence, invariant tracing, option classification, and terminal ordering.
454
+ If the exact digest-bound chain is not approved or contains no valid option, the
455
+ result is blocked rather than a recommendation. Bounded implementation details
451
456
  already decided by the contract continue autonomously.
452
457
 
458
+ Validate the recommendation, challenge, and optional owner resolution as one chain:
459
+
460
+ ~~~text
461
+ processctl contract validate --kind recommendation recommendation.json
462
+ processctl recommendation review start --project-root . \
463
+ --recommendation recommendation.json \
464
+ --actor <reviewer> --context <fresh-context> --actor-kind agent \
465
+ --method isolated-context --attested-by <host> \
466
+ --attestation-evidence <bounded-attestation>
467
+ processctl contract validate --kind recommendation-review-assignment \
468
+ .process/runs/recommendations/<decision-id>/review-request-<ids>.json
469
+ processctl contract validate --kind recommendation-review recommendation-review.json
470
+ processctl recommendation validate-chain --project-root . \
471
+ --recommendation recommendation.json \
472
+ --assignment .process/runs/recommendations/<decision-id>/review-request-<ids>.json \
473
+ --review recommendation-review.json
474
+ processctl recommendation resolution --project-root . \
475
+ --recommendation recommendation.json \
476
+ --assignment .process/runs/recommendations/<decision-id>/review-request-<ids>.json \
477
+ --review recommendation-review.json \
478
+ --selected-option <valid-option-id> --owner-id <owner-id> \
479
+ --owner-evidence-sha256 sha256:<digest> \
480
+ --selection-rationale-sha256 sha256:<digest> \
481
+ --output recommendation-resolution.json
482
+ processctl recommendation validate-chain --project-root . \
483
+ --recommendation recommendation.json \
484
+ --assignment .process/runs/recommendations/<decision-id>/review-request-<ids>.json \
485
+ --review recommendation-review.json \
486
+ --resolution recommendation-resolution.json
487
+ ~~~
488
+
489
+ The review-start command reserves the context across lifecycle and recommendation
490
+ reviews before emitting its exact assignment. Resolution creation refuses symlinked,
491
+ existing, or concurrently created output instead of redirecting or replacing it. The
492
+ resolution records a selected valid option but grants no lifecycle completion, merge,
493
+ release, deployment, or adoption authority. Those owning gates remain separate. The
494
+ accepted decision is recorded before dependent work resumes.
495
+
496
+ When a schema-3 change selects a project-owned `requiredEvidence` id, local profiles
497
+ alone do not advance it to review. Create the exact no-authority request, run the
498
+ project adapter, and ingest the complete supplemental set first:
499
+
500
+ ~~~text
501
+ processctl change remote request --project-root . --change-id issue-123 \
502
+ --actor worker --context worker-session --actor-kind agent
503
+ python verification/run_remote_verification.py --project-root . \
504
+ --change-id issue-123 --actor worker --context worker-session \
505
+ --actor-kind agent --repository owner/repository \
506
+ --failure-output /durable/receipts/issue-123-remote-failure.json
507
+ processctl change status --project-root . --change-id issue-123
508
+ ~~~
509
+
510
+ The adapter publishes a uniquely named exact-checkpoint verification tag, never a
511
+ branch or PR, dispatches the protected-base workflow, validates service and bundle
512
+ digests, calls `change remote ingest`, and deletes the tag in every terminal path.
513
+ Downloaded temporary archives are deleted after ingestion; failed evidence is moved
514
+ to the explicit durable failure location before cleanup. Remote artifacts and their
515
+ service ids remain lifecycle evidence, not merge, release, deployment, or adoption
516
+ authority.
517
+
453
518
  The canonical publication order is stricter than a PR-first workflow: implementation
454
- and every required profile pass on a clean checkpoint; a consumer-selected independent
519
+ and every required local and remote profile pass on a clean checkpoint; a consumer-selected independent
455
520
  agent or human semantically reviews that checkpoint; findings repeat implementation,
456
521
  complete verification, and fresh review until approved; `change finish` records
457
522
  completion; only then may automation push and create the PR. Static policy/secret/pin
@@ -683,7 +748,8 @@ fingerprint, source tree, or publication range.
683
748
  exclusively by their hash-locked `requirements/process.txt`. The action invokes the
684
749
  producer-owned installer from its immutable action checkout and never downloads or
685
750
  executes helper source from the consumer branch.
686
- - Versioned JSON schemas define change, plan, verification, review, lifecycle,
751
+ - Versioned JSON schemas define change, plan, verification, review, recommendation,
752
+ independent recommendation assignment and challenge, owner resolution, lifecycle,
687
753
  completion-related artifacts, release-change fragments, and the release
688
754
  classification contract. The generated Release PR gate binds that contract to the
689
755
  exact SemVer increment, package version, latest reachable prior tag, reviewed head,
@@ -138,6 +138,31 @@ consumer reproduction after adoption. A read-only pre-release consumer candidate
138
138
  supplemental compatibility evidence only and cannot be committed as an unreleased
139
139
  dependency.
140
140
 
141
+ ## Recommendation-validity capability
142
+
143
+ Recommendation, review-assignment, review, and owner-resolution schema-1 artifacts
144
+ are additive serialized surfaces. Requiring every new material owner decision to use
145
+ their invariant derivation, project-global fresh-context reservation, independent
146
+ challenge, chain validation, and valid resolution changes managed workflow semantics.
147
+ Before 1.0 this is therefore a breaking package change even though `schemaImpact`
148
+ remains additive.
149
+
150
+ After adoption, new material decisions use `recommendation review start` before the
151
+ reviewer acts, validate the exact assignment-bound chain before presenting a
152
+ recommendation, and record the selected valid option before dependent work resumes.
153
+ Completed historical decisions retain their original evidence and require no
154
+ backfill. A recommendation resolution is decision evidence only and never substitutes
155
+ for lifecycle completion or delivery authority.
156
+
157
+ Remote-verification request and evidence-set schema-1 artifacts, optional project
158
+ requirements, optional change selections, lifecycle references, and receipt content
159
+ are additive serialized surfaces. A project does not gain the gate until a separate
160
+ adoption validates the target-version manifest and selects requirement ids. Once
161
+ selected, missing exact remote evidence blocks review and completion; a later PR
162
+ matrix is not a compatibility substitute. Provider transport remains project-owned,
163
+ while request expansion, ingestion, invalidation, and terminal ordering are portable
164
+ process semantics.
165
+
141
166
  ## Release and adoption boundary
142
167
 
143
168
  Release, self-adoption, and consumer adoption are separate changes:
@@ -1,3 +1,3 @@
1
1
  """Agent-neutral engineering process."""
2
2
 
3
- VERSION = "0.5.1"
3
+ VERSION = "0.6.0"
@@ -14,6 +14,7 @@ from .bundles import load_bundles, select_bundles
14
14
  from .bootstrap import initialize_project
15
15
  from .contracts import (
16
16
  ContractError,
17
+ canonical_json_digest,
17
18
  derive_release_version,
18
19
  read_json,
19
20
  validate_adoption_migration,
@@ -29,6 +30,12 @@ from .contracts import (
29
30
  validate_plan,
30
31
  validate_process_lock,
31
32
  validate_project,
33
+ validate_recommendation,
34
+ validate_recommendation_resolution,
35
+ validate_recommendation_review,
36
+ validate_recommendation_review_assignment,
37
+ validate_remote_verification_evidence,
38
+ validate_remote_verification_request,
32
39
  validate_release,
33
40
  validate_release_change,
34
41
  validate_review,
@@ -70,7 +77,9 @@ from .lifecycle import (
70
77
  finish_change,
71
78
  lifecycle_environment_issues,
72
79
  lifecycle_status,
80
+ ingest_remote_verification,
73
81
  register_plan,
82
+ request_remote_verification,
74
83
  start_change,
75
84
  start_review,
76
85
  submit_review,
@@ -89,6 +98,11 @@ from .publication import (
89
98
  validate_evidence_publication,
90
99
  )
91
100
  from .process_graph import load_process_graph, process_root_from_skills
101
+ from .recommendation import (
102
+ create_recommendation_resolution,
103
+ start_recommendation_review,
104
+ validate_recommendation_chain,
105
+ )
92
106
  from .release import validate_release_checkpoint
93
107
  from .release_candidate import prepare_release_candidate, render_release_pull_request
94
108
  from .skills import validate_skills
@@ -281,6 +295,12 @@ def command_contract_validate(args: argparse.Namespace) -> int:
281
295
  "improvement-resolution": validate_improvement_resolution,
282
296
  "improvement-signal": validate_improvement_signal,
283
297
  "plan": validate_plan,
298
+ "recommendation": validate_recommendation,
299
+ "recommendation-resolution": validate_recommendation_resolution,
300
+ "recommendation-review": validate_recommendation_review,
301
+ "recommendation-review-assignment": validate_recommendation_review_assignment,
302
+ "remote-verification-evidence": validate_remote_verification_evidence,
303
+ "remote-verification-request": validate_remote_verification_request,
284
304
  "release": validate_release,
285
305
  "release-change": validate_release_change,
286
306
  "review": validate_review,
@@ -297,6 +317,56 @@ def command_contract_validate(args: argparse.Namespace) -> int:
297
317
  return 0
298
318
 
299
319
 
320
+ def command_recommendation_validate_chain(args: argparse.Namespace) -> int:
321
+ _lifecycle_project(args)
322
+ result = validate_recommendation_chain(
323
+ args.project_root,
324
+ args.recommendation,
325
+ args.assignment,
326
+ args.review,
327
+ args.resolution,
328
+ )
329
+ status = "passed" if result["allowed"] else "blocked"
330
+ _emit(
331
+ args,
332
+ _result("recommendation validate-chain", status=status, **result),
333
+ )
334
+ return 0 if result["allowed"] else 1
335
+
336
+
337
+ def command_recommendation_review_start(args: argparse.Namespace) -> int:
338
+ _lifecycle_project(args)
339
+ result = start_recommendation_review(
340
+ args.project_root,
341
+ args.recommendation,
342
+ actor_id=args.actor,
343
+ context_id=args.context,
344
+ kind=args.actor_kind,
345
+ method=args.method,
346
+ attested_by=args.attested_by,
347
+ evidence=args.attestation_evidence,
348
+ )
349
+ _emit(args, _result("recommendation review start", **result))
350
+ return 0
351
+
352
+
353
+ def command_recommendation_resolution(args: argparse.Namespace) -> int:
354
+ _lifecycle_project(args)
355
+ result = create_recommendation_resolution(
356
+ args.project_root,
357
+ args.recommendation,
358
+ args.assignment,
359
+ args.review,
360
+ selected_option_id=args.selected_option,
361
+ owner_id=args.owner_id,
362
+ owner_evidence_sha256=args.owner_evidence_sha256,
363
+ selection_rationale_sha256=args.selection_rationale_sha256,
364
+ output=args.output,
365
+ )
366
+ _emit(args, _result("recommendation resolution", **result))
367
+ return 0
368
+
369
+
300
370
  def command_improvement_validate_chain(args: argparse.Namespace) -> int:
301
371
  result = validate_improvement_chain(
302
372
  args.signal,
@@ -600,6 +670,53 @@ def command_change_verify(args: argparse.Namespace) -> int:
600
670
  return 0
601
671
 
602
672
 
673
+ def command_change_remote_request(args: argparse.Namespace) -> int:
674
+ project = _lifecycle_project(args)
675
+ state, request = request_remote_verification(
676
+ args.project_root,
677
+ project,
678
+ args.change_id,
679
+ actor_id=args.actor,
680
+ context_id=args.context,
681
+ kind=args.actor_kind,
682
+ )
683
+ _emit(
684
+ args,
685
+ _change_result(
686
+ "change remote request",
687
+ state,
688
+ checkpoint=request["checkpoint"],
689
+ comparisonBase=request["comparisonBase"],
690
+ request=state["remoteVerification"]["request"]["path"],
691
+ requestSha256=canonical_json_digest(request),
692
+ ),
693
+ )
694
+ return 0
695
+
696
+
697
+ def command_change_remote_ingest(args: argparse.Namespace) -> int:
698
+ _lifecycle_project(args)
699
+ state, evidence = ingest_remote_verification(
700
+ args.project_root,
701
+ args.change_id,
702
+ args.evidence,
703
+ actor_id=args.actor,
704
+ context_id=args.context,
705
+ kind=args.actor_kind,
706
+ )
707
+ _emit(
708
+ args,
709
+ _change_result(
710
+ "change remote ingest",
711
+ state,
712
+ checkpoint=evidence["checkpoint"],
713
+ evidence=state["remoteVerification"]["evidence"]["path"],
714
+ artifactCount=len(evidence["artifacts"]),
715
+ ),
716
+ )
717
+ return 0
718
+
719
+
603
720
  def command_change_review_start(args: argparse.Namespace) -> int:
604
721
  _lifecycle_project(args)
605
722
  state, assignment = start_review(
@@ -673,6 +790,7 @@ def command_change_status(args: argparse.Namespace) -> int:
673
790
  plan=state["plan"],
674
791
  implementationActors=state["implementationActors"],
675
792
  verification=state["verification"],
793
+ remoteVerification=state.get("remoteVerification"),
676
794
  pendingFindings=state["pendingFindings"],
677
795
  reviewAssignment=state["reviewAssignment"],
678
796
  review=state["review"],
@@ -1479,6 +1597,12 @@ def build_parser() -> argparse.ArgumentParser:
1479
1597
  "improvement-resolution",
1480
1598
  "improvement-signal",
1481
1599
  "plan",
1600
+ "recommendation",
1601
+ "recommendation-resolution",
1602
+ "recommendation-review",
1603
+ "recommendation-review-assignment",
1604
+ "remote-verification-evidence",
1605
+ "remote-verification-request",
1482
1606
  "release",
1483
1607
  "release-change",
1484
1608
  "review",
@@ -1489,6 +1613,81 @@ def build_parser() -> argparse.ArgumentParser:
1489
1613
  _add_json(contract_validate)
1490
1614
  contract_validate.set_defaults(handler=command_contract_validate)
1491
1615
 
1616
+ recommendation = commands.add_parser(
1617
+ "recommendation",
1618
+ help="Validate evidence-valid recommendations and owner resolutions",
1619
+ )
1620
+ recommendation_commands = recommendation.add_subparsers(
1621
+ dest="recommendation_command", required=True
1622
+ )
1623
+ recommendation_validate = recommendation_commands.add_parser(
1624
+ "validate-chain",
1625
+ help="Validate recommendation validity and its independent challenge",
1626
+ )
1627
+ _add_project_root(recommendation_validate)
1628
+ _add_process_root(recommendation_validate)
1629
+ recommendation_validate.add_argument(
1630
+ "--recommendation", type=Path, required=True
1631
+ )
1632
+ recommendation_validate.add_argument("--assignment", type=Path, required=True)
1633
+ recommendation_validate.add_argument("--review", type=Path, required=True)
1634
+ recommendation_validate.add_argument("--resolution", type=Path)
1635
+ _add_json(recommendation_validate)
1636
+ recommendation_validate.set_defaults(
1637
+ handler=command_recommendation_validate_chain
1638
+ )
1639
+ recommendation_review = recommendation_commands.add_parser(
1640
+ "review", help="Register an independent recommendation reviewer"
1641
+ )
1642
+ recommendation_review_commands = recommendation_review.add_subparsers(
1643
+ dest="recommendation_review_command", required=True
1644
+ )
1645
+ recommendation_review_start = recommendation_review_commands.add_parser(
1646
+ "start",
1647
+ help="Reserve a fresh project-global context and create an assignment",
1648
+ )
1649
+ _add_project_root(recommendation_review_start)
1650
+ _add_process_root(recommendation_review_start)
1651
+ _add_actor(recommendation_review_start)
1652
+ recommendation_review_start.add_argument(
1653
+ "--recommendation", type=Path, required=True
1654
+ )
1655
+ recommendation_review_start.add_argument(
1656
+ "--method", choices=("isolated-context", "separate-person"), required=True
1657
+ )
1658
+ recommendation_review_start.add_argument("--attested-by", required=True)
1659
+ recommendation_review_start.add_argument(
1660
+ "--attestation-evidence", required=True
1661
+ )
1662
+ _add_json(recommendation_review_start)
1663
+ recommendation_review_start.set_defaults(
1664
+ handler=command_recommendation_review_start
1665
+ )
1666
+ recommendation_resolution = recommendation_commands.add_parser(
1667
+ "resolution",
1668
+ help="Create a non-authorizing owner resolution for an approved chain",
1669
+ )
1670
+ _add_project_root(recommendation_resolution)
1671
+ _add_process_root(recommendation_resolution)
1672
+ recommendation_resolution.add_argument(
1673
+ "--recommendation", type=Path, required=True
1674
+ )
1675
+ recommendation_resolution.add_argument("--assignment", type=Path, required=True)
1676
+ recommendation_resolution.add_argument("--review", type=Path, required=True)
1677
+ recommendation_resolution.add_argument("--selected-option", required=True)
1678
+ recommendation_resolution.add_argument("--owner-id", required=True)
1679
+ recommendation_resolution.add_argument(
1680
+ "--owner-evidence-sha256", required=True
1681
+ )
1682
+ recommendation_resolution.add_argument(
1683
+ "--selection-rationale-sha256", required=True
1684
+ )
1685
+ recommendation_resolution.add_argument("--output", type=Path, required=True)
1686
+ _add_json(recommendation_resolution)
1687
+ recommendation_resolution.set_defaults(
1688
+ handler=command_recommendation_resolution
1689
+ )
1690
+
1492
1691
  skills = commands.add_parser("skills", help="Validate portable Agent Skills")
1493
1692
  skills_commands = skills.add_subparsers(dest="skills_command", required=True)
1494
1693
  skills_validate = skills_commands.add_parser("validate")
@@ -2179,6 +2378,29 @@ def build_parser() -> argparse.ArgumentParser:
2179
2378
  change_verify.add_argument("--profile", required=True)
2180
2379
  change_verify.set_defaults(handler=command_change_verify)
2181
2380
 
2381
+ change_remote = change_commands.add_parser(
2382
+ "remote", help="Bind required exact-checkpoint remote verification"
2383
+ )
2384
+ remote_commands = change_remote.add_subparsers(
2385
+ dest="change_remote_command", required=True
2386
+ )
2387
+ remote_request = remote_commands.add_parser(
2388
+ "request", help="Create an exact no-authority remote verification request"
2389
+ )
2390
+ _add_lifecycle_common(remote_request)
2391
+ _add_actor(remote_request)
2392
+ remote_request.add_argument("--change-id", required=True)
2393
+ remote_request.set_defaults(handler=command_change_remote_request)
2394
+
2395
+ remote_ingest = remote_commands.add_parser(
2396
+ "ingest", help="Validate and bind a complete remote evidence set"
2397
+ )
2398
+ _add_lifecycle_common(remote_ingest)
2399
+ _add_actor(remote_ingest)
2400
+ remote_ingest.add_argument("--change-id", required=True)
2401
+ remote_ingest.add_argument("--evidence", type=Path, required=True)
2402
+ remote_ingest.set_defaults(handler=command_change_remote_ingest)
2403
+
2182
2404
  change_review = change_commands.add_parser(
2183
2405
  "review", help="Run the independent-review gate"
2184
2406
  )
@@ -8,6 +8,8 @@ LIFECYCLE_COMMAND_PATHS = frozenset(
8
8
  "change finish",
9
9
  "change implement",
10
10
  "change plan",
11
+ "change remote ingest",
12
+ "change remote request",
11
13
  "change review start",
12
14
  "change review submit",
13
15
  "change start",