in-lockstep 0.1.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 (548) hide show
  1. in_lockstep-0.1.0/.github/CODEOWNERS +28 -0
  2. in_lockstep-0.1.0/.github/workflows/.gitattributes +4 -0
  3. in_lockstep-0.1.0/.github/workflows/ci.yml +20 -0
  4. in_lockstep-0.1.0/.github/workflows/pipeline-ci.yml +86 -0
  5. in_lockstep-0.1.0/.github/workflows/release-actions.yml +96 -0
  6. in_lockstep-0.1.0/.github/workflows/release-exec-image.yml +132 -0
  7. in_lockstep-0.1.0/.github/workflows/release-python.yml +133 -0
  8. in_lockstep-0.1.0/.gitignore +13 -0
  9. in_lockstep-0.1.0/.lockstep/.pipeline/compile-manifest.json +19 -0
  10. in_lockstep-0.1.0/.lockstep/.pipeline/pins.lock +15 -0
  11. in_lockstep-0.1.0/.lockstep/SECRETS.md +10 -0
  12. in_lockstep-0.1.0/.lockstep/pipeline.yaml +27 -0
  13. in_lockstep-0.1.0/.lockstep/profiles/repo.md +7 -0
  14. in_lockstep-0.1.0/LICENSE +201 -0
  15. in_lockstep-0.1.0/Makefile +29 -0
  16. in_lockstep-0.1.0/NOTICE +12 -0
  17. in_lockstep-0.1.0/PKG-INFO +152 -0
  18. in_lockstep-0.1.0/README.md +136 -0
  19. in_lockstep-0.1.0/actions/README.md +28 -0
  20. in_lockstep-0.1.0/actions/command-gate/action.yml +153 -0
  21. in_lockstep-0.1.0/actions/propose-pr/action.yml +174 -0
  22. in_lockstep-0.1.0/actions/publish-history/action.yml +117 -0
  23. in_lockstep-0.1.0/actions/publish-report/action.yml +103 -0
  24. in_lockstep-0.1.0/actions/restore/action.yml +38 -0
  25. in_lockstep-0.1.0/actions/save/action.yml +45 -0
  26. in_lockstep-0.1.0/actions/state/load/action.yml +38 -0
  27. in_lockstep-0.1.0/actions/state/save/action.yml +38 -0
  28. in_lockstep-0.1.0/actions/step-cache/action.yml +127 -0
  29. in_lockstep-0.1.0/actions/step-cache/save/action.yml +58 -0
  30. in_lockstep-0.1.0/conftest.py +31 -0
  31. in_lockstep-0.1.0/docs/adopting-shipped-pipelines.md +256 -0
  32. in_lockstep-0.1.0/docs/adopting.md +413 -0
  33. in_lockstep-0.1.0/docs/evals.md +330 -0
  34. in_lockstep-0.1.0/docs/extending.md +724 -0
  35. in_lockstep-0.1.0/docs/getting-started.md +650 -0
  36. in_lockstep-0.1.0/docs/history-and-retro.md +312 -0
  37. in_lockstep-0.1.0/docs/implementing-issues.md +446 -0
  38. in_lockstep-0.1.0/docs/inheriting.md +584 -0
  39. in_lockstep-0.1.0/docs/layers.md +238 -0
  40. in_lockstep-0.1.0/docs/metering.md +215 -0
  41. in_lockstep-0.1.0/docs/needs.md +246 -0
  42. in_lockstep-0.1.0/docs/publishing-reports.md +408 -0
  43. in_lockstep-0.1.0/docs/reviewing-pull-requests.md +575 -0
  44. in_lockstep-0.1.0/docs/self-hosting.md +126 -0
  45. in_lockstep-0.1.0/docs/sharing.md +752 -0
  46. in_lockstep-0.1.0/docs/status.md +634 -0
  47. in_lockstep-0.1.0/examples/bug-fix/.github/workflows/.gitattributes +18 -0
  48. in_lockstep-0.1.0/examples/bug-fix/.github/workflows/aw-bug-analyst.lock.yml +1826 -0
  49. in_lockstep-0.1.0/examples/bug-fix/.github/workflows/aw-bug-analyst.md +148 -0
  50. in_lockstep-0.1.0/examples/bug-fix/.github/workflows/aw-fix-reviewer.lock.yml +1752 -0
  51. in_lockstep-0.1.0/examples/bug-fix/.github/workflows/aw-fix-reviewer.md +130 -0
  52. in_lockstep-0.1.0/examples/bug-fix/.github/workflows/aw-fix-writer.lock.yml +1790 -0
  53. in_lockstep-0.1.0/examples/bug-fix/.github/workflows/aw-fix-writer.md +152 -0
  54. in_lockstep-0.1.0/examples/bug-fix/.github/workflows/aw-reproducer-writer.lock.yml +1754 -0
  55. in_lockstep-0.1.0/examples/bug-fix/.github/workflows/aw-reproducer-writer.md +109 -0
  56. in_lockstep-0.1.0/examples/bug-fix/.github/workflows/evals.yml +242 -0
  57. in_lockstep-0.1.0/examples/bug-fix/.github/workflows/fix-bugs.yml +569 -0
  58. in_lockstep-0.1.0/examples/bug-fix/.github/workflows/pipeline-ci.yml +87 -0
  59. in_lockstep-0.1.0/examples/bug-fix/.github/workflows/shared/context-target-app.md +16 -0
  60. in_lockstep-0.1.0/examples/bug-fix/.github/workflows/shared/guardrail-baseline.md +22 -0
  61. in_lockstep-0.1.0/examples/bug-fix/.github/workflows/shared/guardrail-common.md +8 -0
  62. in_lockstep-0.1.0/examples/bug-fix/.github/workflows/shared/guardrail-minimal-change.md +18 -0
  63. in_lockstep-0.1.0/examples/bug-fix/.github/workflows/shared/guardrail-review-response.md +18 -0
  64. in_lockstep-0.1.0/examples/bug-fix/.github/workflows/shared/guardrail-source-analysis.md +13 -0
  65. in_lockstep-0.1.0/examples/bug-fix/.github/workflows/shared/skill-codebase-navigation.md +14 -0
  66. in_lockstep-0.1.0/examples/bug-fix/.github/workflows/shared/skill-patch-format.md +21 -0
  67. in_lockstep-0.1.0/examples/bug-fix/.gitignore +3 -0
  68. in_lockstep-0.1.0/examples/bug-fix/.pipeline/compile-manifest.json +129 -0
  69. in_lockstep-0.1.0/examples/bug-fix/.pipeline/pins.lock +26 -0
  70. in_lockstep-0.1.0/examples/bug-fix/.pipeline/step-defs/fix-bugs.assemble-what-passed-review.json +18 -0
  71. in_lockstep-0.1.0/examples/bug-fix/.pipeline/step-defs/fix-bugs.feedback.json +18 -0
  72. in_lockstep-0.1.0/examples/bug-fix/.pipeline/step-defs/fix-bugs.fetch-bugs.json +18 -0
  73. in_lockstep-0.1.0/examples/bug-fix/.pipeline/step-defs/fix-bugs.prove-reproducers.json +18 -0
  74. in_lockstep-0.1.0/examples/bug-fix/.pipeline/step-defs/fix-bugs.validate-fixes.json +18 -0
  75. in_lockstep-0.1.0/examples/bug-fix/README.md +26 -0
  76. in_lockstep-0.1.0/examples/bug-fix/SECRETS.md +37 -0
  77. in_lockstep-0.1.0/examples/bug-fix/agents/bug-analyst.md +24 -0
  78. in_lockstep-0.1.0/examples/bug-fix/agents/fix-reviewer.md +22 -0
  79. in_lockstep-0.1.0/examples/bug-fix/agents/fix-writer.md +24 -0
  80. in_lockstep-0.1.0/examples/bug-fix/agents/reproducer-writer.md +20 -0
  81. in_lockstep-0.1.0/examples/bug-fix/commands/fix-bugs.md +86 -0
  82. in_lockstep-0.1.0/examples/bug-fix/contexts/target-app.md +15 -0
  83. in_lockstep-0.1.0/examples/bug-fix/evals/bug-analyst/cases/example.json +10 -0
  84. in_lockstep-0.1.0/examples/bug-fix/evals/fix-reviewer/cases/example.json +10 -0
  85. in_lockstep-0.1.0/examples/bug-fix/evals/fix-writer/cases/example.json +10 -0
  86. in_lockstep-0.1.0/examples/bug-fix/evals/reproducer-writer/cases/example.json +10 -0
  87. in_lockstep-0.1.0/examples/bug-fix/extensions/actions/setup-target/action.yml +73 -0
  88. in_lockstep-0.1.0/examples/bug-fix/extensions/pyproject.toml +20 -0
  89. in_lockstep-0.1.0/examples/bug-fix/extensions/src/bugfix_ext/__init__.py +3 -0
  90. in_lockstep-0.1.0/examples/bug-fix/extensions/src/bugfix_ext/commands.py +199 -0
  91. in_lockstep-0.1.0/examples/bug-fix/extensions/tests/test_commands.py +150 -0
  92. in_lockstep-0.1.0/examples/bug-fix/extensions/uv.lock +116 -0
  93. in_lockstep-0.1.0/examples/bug-fix/guardrails/common.md +10 -0
  94. in_lockstep-0.1.0/examples/bug-fix/guardrails/minimal-change.md +17 -0
  95. in_lockstep-0.1.0/examples/bug-fix/guardrails/review-response.md +17 -0
  96. in_lockstep-0.1.0/examples/bug-fix/guardrails/source-analysis.md +12 -0
  97. in_lockstep-0.1.0/examples/bug-fix/mcp/servers.json +16 -0
  98. in_lockstep-0.1.0/examples/bug-fix/overlays/github/setup-target.yml +32 -0
  99. in_lockstep-0.1.0/examples/bug-fix/pipeline.yaml +26 -0
  100. in_lockstep-0.1.0/examples/bug-fix/profiles/production.md +20 -0
  101. in_lockstep-0.1.0/examples/bug-fix/scripts/assemble-fixes.py +62 -0
  102. in_lockstep-0.1.0/examples/bug-fix/skills/codebase-navigation.md +13 -0
  103. in_lockstep-0.1.0/examples/bug-fix/skills/patch-format.md +20 -0
  104. in_lockstep-0.1.0/examples/bug-fix/tests/test_assemble_fixes.py +36 -0
  105. in_lockstep-0.1.0/examples/httpbin/.github/workflows/.gitattributes +12 -0
  106. in_lockstep-0.1.0/examples/httpbin/.github/workflows/aw-test-writer.lock.yml +1754 -0
  107. in_lockstep-0.1.0/examples/httpbin/.github/workflows/aw-test-writer.md +107 -0
  108. in_lockstep-0.1.0/examples/httpbin/.github/workflows/evals.yml +77 -0
  109. in_lockstep-0.1.0/examples/httpbin/.github/workflows/pipeline-ci.yml +87 -0
  110. in_lockstep-0.1.0/examples/httpbin/.github/workflows/shared/context-httpbin.md +17 -0
  111. in_lockstep-0.1.0/examples/httpbin/.github/workflows/shared/guardrail-api-tests.md +11 -0
  112. in_lockstep-0.1.0/examples/httpbin/.github/workflows/shared/guardrail-baseline.md +22 -0
  113. in_lockstep-0.1.0/examples/httpbin/.github/workflows/shared/guardrail-common.md +7 -0
  114. in_lockstep-0.1.0/examples/httpbin/.github/workflows/shared/skill-test-script-format.md +40 -0
  115. in_lockstep-0.1.0/examples/httpbin/.github/workflows/validate-api.yml +236 -0
  116. in_lockstep-0.1.0/examples/httpbin/.gitignore +2 -0
  117. in_lockstep-0.1.0/examples/httpbin/.pipeline/compile-manifest.json +64 -0
  118. in_lockstep-0.1.0/examples/httpbin/.pipeline/pins.lock +26 -0
  119. in_lockstep-0.1.0/examples/httpbin/.pipeline/step-defs/validate-api.list-endpoints.json +18 -0
  120. in_lockstep-0.1.0/examples/httpbin/README.md +15 -0
  121. in_lockstep-0.1.0/examples/httpbin/SECRETS.md +28 -0
  122. in_lockstep-0.1.0/examples/httpbin/agents/test-writer.md +21 -0
  123. in_lockstep-0.1.0/examples/httpbin/commands/validate-api.md +45 -0
  124. in_lockstep-0.1.0/examples/httpbin/contexts/httpbin.md +16 -0
  125. in_lockstep-0.1.0/examples/httpbin/evals/test-writer/cases/post-echo.json +16 -0
  126. in_lockstep-0.1.0/examples/httpbin/evals/test-writer/cases/uuid.json +16 -0
  127. in_lockstep-0.1.0/examples/httpbin/guardrails/api-tests.md +10 -0
  128. in_lockstep-0.1.0/examples/httpbin/guardrails/common.md +9 -0
  129. in_lockstep-0.1.0/examples/httpbin/mcp/servers.json +3 -0
  130. in_lockstep-0.1.0/examples/httpbin/pipeline.yaml +19 -0
  131. in_lockstep-0.1.0/examples/httpbin/profiles/httpbin.md +18 -0
  132. in_lockstep-0.1.0/examples/httpbin/scripts/list-endpoints.py +85 -0
  133. in_lockstep-0.1.0/examples/httpbin/tests/test_list_endpoints.py +43 -0
  134. in_lockstep-0.1.0/examples/implement-issue/.github/workflows/.gitattributes +16 -0
  135. in_lockstep-0.1.0/examples/implement-issue/.github/workflows/aw-change-writer.lock.yml +1788 -0
  136. in_lockstep-0.1.0/examples/implement-issue/.github/workflows/aw-change-writer.md +134 -0
  137. in_lockstep-0.1.0/examples/implement-issue/.github/workflows/aw-planner.lock.yml +1826 -0
  138. in_lockstep-0.1.0/examples/implement-issue/.github/workflows/aw-planner.md +139 -0
  139. in_lockstep-0.1.0/examples/implement-issue/.github/workflows/aw-requirements-analyst.lock.yml +1788 -0
  140. in_lockstep-0.1.0/examples/implement-issue/.github/workflows/aw-requirements-analyst.md +125 -0
  141. in_lockstep-0.1.0/examples/implement-issue/.github/workflows/aw-test-writer.lock.yml +1788 -0
  142. in_lockstep-0.1.0/examples/implement-issue/.github/workflows/aw-test-writer.md +124 -0
  143. in_lockstep-0.1.0/examples/implement-issue/.github/workflows/evals.yml +242 -0
  144. in_lockstep-0.1.0/examples/implement-issue/.github/workflows/implement.yml +392 -0
  145. in_lockstep-0.1.0/examples/implement-issue/.github/workflows/pipeline-ci.yml +87 -0
  146. in_lockstep-0.1.0/examples/implement-issue/.github/workflows/shared/context-repository.md +20 -0
  147. in_lockstep-0.1.0/examples/implement-issue/.github/workflows/shared/guardrail-baseline.md +22 -0
  148. in_lockstep-0.1.0/examples/implement-issue/.github/workflows/shared/guardrail-common.md +8 -0
  149. in_lockstep-0.1.0/examples/implement-issue/.github/workflows/shared/guardrail-minimal-change.md +15 -0
  150. in_lockstep-0.1.0/examples/implement-issue/.github/workflows/shared/guardrail-source-analysis.md +13 -0
  151. in_lockstep-0.1.0/examples/implement-issue/.github/workflows/shared/skill-repo-conventions.md +17 -0
  152. in_lockstep-0.1.0/examples/implement-issue/.gitignore +3 -0
  153. in_lockstep-0.1.0/examples/implement-issue/.pipeline/compile-manifest.json +110 -0
  154. in_lockstep-0.1.0/examples/implement-issue/.pipeline/pins.lock +26 -0
  155. in_lockstep-0.1.0/examples/implement-issue/.pipeline/step-defs/implement.feedback.json +18 -0
  156. in_lockstep-0.1.0/examples/implement-issue/.pipeline/step-defs/implement.fetch-issue.json +18 -0
  157. in_lockstep-0.1.0/examples/implement-issue/.pipeline/step-defs/implement.render-the-plan-for-review.json +18 -0
  158. in_lockstep-0.1.0/examples/implement-issue/README.md +19 -0
  159. in_lockstep-0.1.0/examples/implement-issue/SECRETS.md +33 -0
  160. in_lockstep-0.1.0/examples/implement-issue/agents/change-writer.md +24 -0
  161. in_lockstep-0.1.0/examples/implement-issue/agents/planner.md +29 -0
  162. in_lockstep-0.1.0/examples/implement-issue/agents/requirements-analyst.md +26 -0
  163. in_lockstep-0.1.0/examples/implement-issue/agents/test-writer.md +25 -0
  164. in_lockstep-0.1.0/examples/implement-issue/commands/implement.md +65 -0
  165. in_lockstep-0.1.0/examples/implement-issue/contexts/repository.md +19 -0
  166. in_lockstep-0.1.0/examples/implement-issue/evals/change-writer/cases/example.json +14 -0
  167. in_lockstep-0.1.0/examples/implement-issue/evals/planner/cases/example.json +14 -0
  168. in_lockstep-0.1.0/examples/implement-issue/evals/requirements-analyst/cases/example.json +21 -0
  169. in_lockstep-0.1.0/examples/implement-issue/evals/test-writer/cases/example.json +14 -0
  170. in_lockstep-0.1.0/examples/implement-issue/extensions/actions/comment-plan/action.yml +74 -0
  171. in_lockstep-0.1.0/examples/implement-issue/extensions/pyproject.toml +17 -0
  172. in_lockstep-0.1.0/examples/implement-issue/extensions/src/issue_ext/__init__.py +3 -0
  173. in_lockstep-0.1.0/examples/implement-issue/extensions/src/issue_ext/commands.py +139 -0
  174. in_lockstep-0.1.0/examples/implement-issue/extensions/tests/test_commands.py +50 -0
  175. in_lockstep-0.1.0/examples/implement-issue/guardrails/common.md +10 -0
  176. in_lockstep-0.1.0/examples/implement-issue/guardrails/minimal-change.md +14 -0
  177. in_lockstep-0.1.0/examples/implement-issue/guardrails/source-analysis.md +12 -0
  178. in_lockstep-0.1.0/examples/implement-issue/mcp/servers.json +16 -0
  179. in_lockstep-0.1.0/examples/implement-issue/overlays/github/post-pull-request.yml +50 -0
  180. in_lockstep-0.1.0/examples/implement-issue/pipeline.yaml +23 -0
  181. in_lockstep-0.1.0/examples/implement-issue/profiles/main.md +18 -0
  182. in_lockstep-0.1.0/examples/implement-issue/scripts/render-plan.py +66 -0
  183. in_lockstep-0.1.0/examples/implement-issue/skills/repo-conventions.md +16 -0
  184. in_lockstep-0.1.0/examples/implement-issue/tests/test_render_plan.py +51 -0
  185. in_lockstep-0.1.0/examples/pr-review/.github/workflows/.gitattributes +16 -0
  186. in_lockstep-0.1.0/examples/pr-review/.github/workflows/aw-intent-reviewer.lock.yml +1788 -0
  187. in_lockstep-0.1.0/examples/pr-review/.github/workflows/aw-intent-reviewer.md +144 -0
  188. in_lockstep-0.1.0/examples/pr-review/.github/workflows/aw-performance-reviewer.lock.yml +1788 -0
  189. in_lockstep-0.1.0/examples/pr-review/.github/workflows/aw-performance-reviewer.md +142 -0
  190. in_lockstep-0.1.0/examples/pr-review/.github/workflows/aw-security-reviewer.lock.yml +1788 -0
  191. in_lockstep-0.1.0/examples/pr-review/.github/workflows/aw-security-reviewer.md +156 -0
  192. in_lockstep-0.1.0/examples/pr-review/.github/workflows/aw-tests-reviewer.lock.yml +1788 -0
  193. in_lockstep-0.1.0/examples/pr-review/.github/workflows/aw-tests-reviewer.md +142 -0
  194. in_lockstep-0.1.0/examples/pr-review/.github/workflows/evals.yml +242 -0
  195. in_lockstep-0.1.0/examples/pr-review/.github/workflows/pipeline-ci.yml +87 -0
  196. in_lockstep-0.1.0/examples/pr-review/.github/workflows/review.yml +335 -0
  197. in_lockstep-0.1.0/examples/pr-review/.github/workflows/shared/context-repo.md +19 -0
  198. in_lockstep-0.1.0/examples/pr-review/.github/workflows/shared/guardrail-baseline.md +22 -0
  199. in_lockstep-0.1.0/examples/pr-review/.github/workflows/shared/guardrail-common.md +8 -0
  200. in_lockstep-0.1.0/examples/pr-review/.github/workflows/shared/guardrail-reviewing.md +27 -0
  201. in_lockstep-0.1.0/examples/pr-review/.github/workflows/shared/skill-review-revision.md +22 -0
  202. in_lockstep-0.1.0/examples/pr-review/.github/workflows/shared/skill-review-writing.md +33 -0
  203. in_lockstep-0.1.0/examples/pr-review/.gitignore +4 -0
  204. in_lockstep-0.1.0/examples/pr-review/.pipeline/compile-manifest.json +105 -0
  205. in_lockstep-0.1.0/examples/pr-review/.pipeline/pins.lock +34 -0
  206. in_lockstep-0.1.0/examples/pr-review/.pipeline/step-defs/review.diff.json +18 -0
  207. in_lockstep-0.1.0/examples/pr-review/README.md +18 -0
  208. in_lockstep-0.1.0/examples/pr-review/SECRETS.md +33 -0
  209. in_lockstep-0.1.0/examples/pr-review/agents/intent-reviewer.md +32 -0
  210. in_lockstep-0.1.0/examples/pr-review/agents/performance-reviewer.md +30 -0
  211. in_lockstep-0.1.0/examples/pr-review/agents/security-reviewer.md +44 -0
  212. in_lockstep-0.1.0/examples/pr-review/agents/tests-reviewer.md +30 -0
  213. in_lockstep-0.1.0/examples/pr-review/commands/review.md +68 -0
  214. in_lockstep-0.1.0/examples/pr-review/contexts/repo.md +18 -0
  215. in_lockstep-0.1.0/examples/pr-review/evals/intent-reviewer/cases/does-more-than-it-says.json +19 -0
  216. in_lockstep-0.1.0/examples/pr-review/evals/intent-reviewer/cases/does-what-it-says.json +19 -0
  217. in_lockstep-0.1.0/examples/pr-review/evals/performance-reviewer/cases/not-worth-a-comment.json +25 -0
  218. in_lockstep-0.1.0/examples/pr-review/evals/performance-reviewer/cases/query-per-order.json +27 -0
  219. in_lockstep-0.1.0/examples/pr-review/evals/security-reviewer/cases/format-from-the-query.json +39 -0
  220. in_lockstep-0.1.0/examples/pr-review/evals/security-reviewer/cases/nothing-to-find.json +25 -0
  221. in_lockstep-0.1.0/examples/pr-review/evals/security-reviewer/cases/path-traversal.json +38 -0
  222. in_lockstep-0.1.0/examples/pr-review/evals/security-reviewer/cases/query-outside-the-repo-layer.json +19 -0
  223. in_lockstep-0.1.0/examples/pr-review/evals/security-reviewer/cases/revising-a-fixed-finding.json +26 -0
  224. in_lockstep-0.1.0/examples/pr-review/evals/security-reviewer/fixtures/format-from-the-query/src/repo.py +14 -0
  225. in_lockstep-0.1.0/examples/pr-review/evals/security-reviewer/fixtures/format-from-the-query/src/reports/export.py +19 -0
  226. in_lockstep-0.1.0/examples/pr-review/evals/security-reviewer/fixtures/format-from-the-query/src/reports/routes.py +13 -0
  227. in_lockstep-0.1.0/examples/pr-review/evals/security-reviewer/fixtures/format-from-the-query/src/reports/templates/pdf.tmpl +5 -0
  228. in_lockstep-0.1.0/examples/pr-review/evals/tests-reviewer/cases/assertion-that-proves-nothing.json +23 -0
  229. in_lockstep-0.1.0/examples/pr-review/evals/tests-reviewer/cases/new-branch-uncovered.json +23 -0
  230. in_lockstep-0.1.0/examples/pr-review/extensions/pyproject.toml +17 -0
  231. in_lockstep-0.1.0/examples/pr-review/extensions/src/review_ext/__init__.py +3 -0
  232. in_lockstep-0.1.0/examples/pr-review/extensions/src/review_ext/commands.py +130 -0
  233. in_lockstep-0.1.0/examples/pr-review/extensions/src/review_ext/state.py +235 -0
  234. in_lockstep-0.1.0/examples/pr-review/extensions/tests/test_commands.py +80 -0
  235. in_lockstep-0.1.0/examples/pr-review/extensions/tests/test_state.py +223 -0
  236. in_lockstep-0.1.0/examples/pr-review/extensions/uv.lock +35 -0
  237. in_lockstep-0.1.0/examples/pr-review/guardrails/common.md +10 -0
  238. in_lockstep-0.1.0/examples/pr-review/guardrails/reviewing.md +26 -0
  239. in_lockstep-0.1.0/examples/pr-review/mcp/servers.json +1 -0
  240. in_lockstep-0.1.0/examples/pr-review/overlays/github/post-reviews.yml +28 -0
  241. in_lockstep-0.1.0/examples/pr-review/pipeline.yaml +43 -0
  242. in_lockstep-0.1.0/examples/pr-review/profiles/repo.md +15 -0
  243. in_lockstep-0.1.0/examples/pr-review/scripts/post-reviews.sh +74 -0
  244. in_lockstep-0.1.0/examples/pr-review/skills/review-revision.md +21 -0
  245. in_lockstep-0.1.0/examples/pr-review/skills/review-writing.md +32 -0
  246. in_lockstep-0.1.0/examples/pr-review/tests/test_post_reviews.py +140 -0
  247. in_lockstep-0.1.0/examples/pr-review/tests/test_select_aspects.py +119 -0
  248. in_lockstep-0.1.0/examples/triage-report/.github/workflows/.gitattributes +12 -0
  249. in_lockstep-0.1.0/examples/triage-report/.github/workflows/aw-triage-reporter.lock.yml +1754 -0
  250. in_lockstep-0.1.0/examples/triage-report/.github/workflows/aw-triage-reporter.md +120 -0
  251. in_lockstep-0.1.0/examples/triage-report/.github/workflows/evals.yml +77 -0
  252. in_lockstep-0.1.0/examples/triage-report/.github/workflows/pipeline-ci.yml +87 -0
  253. in_lockstep-0.1.0/examples/triage-report/.github/workflows/shared/context-tracker.md +21 -0
  254. in_lockstep-0.1.0/examples/triage-report/.github/workflows/shared/guardrail-baseline.md +22 -0
  255. in_lockstep-0.1.0/examples/triage-report/.github/workflows/shared/guardrail-common.md +11 -0
  256. in_lockstep-0.1.0/examples/triage-report/.github/workflows/shared/guardrail-reporting.md +20 -0
  257. in_lockstep-0.1.0/examples/triage-report/.github/workflows/shared/skill-report-writing.md +34 -0
  258. in_lockstep-0.1.0/examples/triage-report/.github/workflows/triage.yml +198 -0
  259. in_lockstep-0.1.0/examples/triage-report/.gitignore +3 -0
  260. in_lockstep-0.1.0/examples/triage-report/.pipeline/compile-manifest.json +68 -0
  261. in_lockstep-0.1.0/examples/triage-report/.pipeline/pins.lock +26 -0
  262. in_lockstep-0.1.0/examples/triage-report/.pipeline/step-defs/triage.search.json +18 -0
  263. in_lockstep-0.1.0/examples/triage-report/.pipeline/step-defs/triage.summarize.json +18 -0
  264. in_lockstep-0.1.0/examples/triage-report/README.md +17 -0
  265. in_lockstep-0.1.0/examples/triage-report/SECRETS.md +33 -0
  266. in_lockstep-0.1.0/examples/triage-report/agents/triage-reporter.md +21 -0
  267. in_lockstep-0.1.0/examples/triage-report/commands/triage.md +48 -0
  268. in_lockstep-0.1.0/examples/triage-report/contexts/tracker.md +20 -0
  269. in_lockstep-0.1.0/examples/triage-report/evals/triage-reporter/cases/backlog.json +35 -0
  270. in_lockstep-0.1.0/examples/triage-report/extensions/pyproject.toml +16 -0
  271. in_lockstep-0.1.0/examples/triage-report/extensions/src/triage_ext/__init__.py +3 -0
  272. in_lockstep-0.1.0/examples/triage-report/extensions/src/triage_ext/commands.py +95 -0
  273. in_lockstep-0.1.0/examples/triage-report/extensions/tests/test_commands.py +82 -0
  274. in_lockstep-0.1.0/examples/triage-report/guardrails/common.md +13 -0
  275. in_lockstep-0.1.0/examples/triage-report/guardrails/reporting.md +19 -0
  276. in_lockstep-0.1.0/examples/triage-report/mcp/servers.json +1 -0
  277. in_lockstep-0.1.0/examples/triage-report/pipeline.yaml +23 -0
  278. in_lockstep-0.1.0/examples/triage-report/profiles/tracker.md +14 -0
  279. in_lockstep-0.1.0/examples/triage-report/scripts/render-site.py +114 -0
  280. in_lockstep-0.1.0/examples/triage-report/scripts/summarize.py +77 -0
  281. in_lockstep-0.1.0/examples/triage-report/skills/report-writing.md +33 -0
  282. in_lockstep-0.1.0/examples/triage-report/tests/test_render_site.py +73 -0
  283. in_lockstep-0.1.0/examples/triage-report/tests/test_summarize.py +75 -0
  284. in_lockstep-0.1.0/packages/pipeline-exec/LICENSE +201 -0
  285. in_lockstep-0.1.0/packages/pipeline-exec/NOTICE +12 -0
  286. in_lockstep-0.1.0/packages/pipeline-exec/README.md +8 -0
  287. in_lockstep-0.1.0/packages/pipeline-exec/docker/Dockerfile +47 -0
  288. in_lockstep-0.1.0/packages/pipeline-exec/docker/README.md +31 -0
  289. in_lockstep-0.1.0/packages/pipeline-exec/pyproject.toml +38 -0
  290. in_lockstep-0.1.0/packages/pipeline-exec/src/pipeline_exec/__init__.py +3 -0
  291. in_lockstep-0.1.0/packages/pipeline-exec/src/pipeline_exec/builtins/__init__.py +2 -0
  292. in_lockstep-0.1.0/packages/pipeline-exec/src/pipeline_exec/builtins/discovery.py +176 -0
  293. in_lockstep-0.1.0/packages/pipeline-exec/src/pipeline_exec/builtins/test_runner.py +340 -0
  294. in_lockstep-0.1.0/packages/pipeline-exec/src/pipeline_exec/changes.py +122 -0
  295. in_lockstep-0.1.0/packages/pipeline-exec/src/pipeline_exec/cli.py +1924 -0
  296. in_lockstep-0.1.0/packages/pipeline-exec/src/pipeline_exec/command.py +75 -0
  297. in_lockstep-0.1.0/packages/pipeline-exec/src/pipeline_exec/config.py +83 -0
  298. in_lockstep-0.1.0/packages/pipeline-exec/src/pipeline_exec/errors.py +15 -0
  299. in_lockstep-0.1.0/packages/pipeline-exec/src/pipeline_exec/evals.py +592 -0
  300. in_lockstep-0.1.0/packages/pipeline-exec/src/pipeline_exec/executors/__init__.py +19 -0
  301. in_lockstep-0.1.0/packages/pipeline-exec/src/pipeline_exec/executors/api_session.py +230 -0
  302. in_lockstep-0.1.0/packages/pipeline-exec/src/pipeline_exec/executors/browser_session.py +312 -0
  303. in_lockstep-0.1.0/packages/pipeline-exec/src/pipeline_exec/executors/cli_session.py +45 -0
  304. in_lockstep-0.1.0/packages/pipeline-exec/src/pipeline_exec/executors/direct_executor.py +756 -0
  305. in_lockstep-0.1.0/packages/pipeline-exec/src/pipeline_exec/executors/login.py +147 -0
  306. in_lockstep-0.1.0/packages/pipeline-exec/src/pipeline_exec/executors/recovery.py +72 -0
  307. in_lockstep-0.1.0/packages/pipeline-exec/src/pipeline_exec/executors/types.py +64 -0
  308. in_lockstep-0.1.0/packages/pipeline-exec/src/pipeline_exec/feedback.py +82 -0
  309. in_lockstep-0.1.0/packages/pipeline-exec/src/pipeline_exec/history.py +283 -0
  310. in_lockstep-0.1.0/packages/pipeline-exec/src/pipeline_exec/hygiene.py +34 -0
  311. in_lockstep-0.1.0/packages/pipeline-exec/src/pipeline_exec/improvement.py +403 -0
  312. in_lockstep-0.1.0/packages/pipeline-exec/src/pipeline_exec/injection.py +218 -0
  313. in_lockstep-0.1.0/packages/pipeline-exec/src/pipeline_exec/issues.py +254 -0
  314. in_lockstep-0.1.0/packages/pipeline-exec/src/pipeline_exec/items.py +96 -0
  315. in_lockstep-0.1.0/packages/pipeline-exec/src/pipeline_exec/logging.py +22 -0
  316. in_lockstep-0.1.0/packages/pipeline-exec/src/pipeline_exec/otel.py +812 -0
  317. in_lockstep-0.1.0/packages/pipeline-exec/src/pipeline_exec/plugins.py +51 -0
  318. in_lockstep-0.1.0/packages/pipeline-exec/src/pipeline_exec/reports/__init__.py +2 -0
  319. in_lockstep-0.1.0/packages/pipeline-exec/src/pipeline_exec/reports/collect.py +136 -0
  320. in_lockstep-0.1.0/packages/pipeline-exec/src/pipeline_exec/reports/dashboard.py +205 -0
  321. in_lockstep-0.1.0/packages/pipeline-exec/src/pipeline_exec/reports/templates/dashboard.html.j2 +240 -0
  322. in_lockstep-0.1.0/packages/pipeline-exec/src/pipeline_exec/reports/templates/index.html.j2 +116 -0
  323. in_lockstep-0.1.0/packages/pipeline-exec/src/pipeline_exec/reviews.py +290 -0
  324. in_lockstep-0.1.0/packages/pipeline-exec/src/pipeline_exec/sanitize.py +50 -0
  325. in_lockstep-0.1.0/packages/pipeline-exec/tests/test_changes.py +198 -0
  326. in_lockstep-0.1.0/packages/pipeline-exec/tests/test_command.py +103 -0
  327. in_lockstep-0.1.0/packages/pipeline-exec/tests/test_declared_behaviour.py +195 -0
  328. in_lockstep-0.1.0/packages/pipeline-exec/tests/test_discovery.py +189 -0
  329. in_lockstep-0.1.0/packages/pipeline-exec/tests/test_evals.py +720 -0
  330. in_lockstep-0.1.0/packages/pipeline-exec/tests/test_exec_cli.py +374 -0
  331. in_lockstep-0.1.0/packages/pipeline-exec/tests/test_extracted.py +185 -0
  332. in_lockstep-0.1.0/packages/pipeline-exec/tests/test_feedback.py +133 -0
  333. in_lockstep-0.1.0/packages/pipeline-exec/tests/test_history.py +304 -0
  334. in_lockstep-0.1.0/packages/pipeline-exec/tests/test_improvement.py +385 -0
  335. in_lockstep-0.1.0/packages/pipeline-exec/tests/test_injection.py +194 -0
  336. in_lockstep-0.1.0/packages/pipeline-exec/tests/test_integration.py +103 -0
  337. in_lockstep-0.1.0/packages/pipeline-exec/tests/test_issues.py +651 -0
  338. in_lockstep-0.1.0/packages/pipeline-exec/tests/test_items.py +117 -0
  339. in_lockstep-0.1.0/packages/pipeline-exec/tests/test_otel.py +299 -0
  340. in_lockstep-0.1.0/packages/pipeline-exec/tests/test_reports.py +125 -0
  341. in_lockstep-0.1.0/packages/pipeline-exec/tests/test_reviews.py +402 -0
  342. in_lockstep-0.1.0/packages/pipeline-exec/tests/test_test_runner.py +133 -0
  343. in_lockstep-0.1.0/packages/pipeline-exec/tests/test_tls.py +90 -0
  344. in_lockstep-0.1.0/pyproject.toml +139 -0
  345. in_lockstep-0.1.0/src/lockstep/__init__.py +3 -0
  346. in_lockstep-0.1.0/src/lockstep/checks.py +900 -0
  347. in_lockstep-0.1.0/src/lockstep/cli.py +471 -0
  348. in_lockstep-0.1.0/src/lockstep/conformance.py +158 -0
  349. in_lockstep-0.1.0/src/lockstep/emit/__init__.py +4 -0
  350. in_lockstep-0.1.0/src/lockstep/emit/agentic.py +331 -0
  351. in_lockstep-0.1.0/src/lockstep/emit/builtins.py +83 -0
  352. in_lockstep-0.1.0/src/lockstep/emit/caching.py +201 -0
  353. in_lockstep-0.1.0/src/lockstep/emit/ci.py +181 -0
  354. in_lockstep-0.1.0/src/lockstep/emit/context.py +296 -0
  355. in_lockstep-0.1.0/src/lockstep/emit/evals.py +397 -0
  356. in_lockstep-0.1.0/src/lockstep/emit/fragments.py +143 -0
  357. in_lockstep-0.1.0/src/lockstep/emit/mcp.py +66 -0
  358. in_lockstep-0.1.0/src/lockstep/emit/meter.py +154 -0
  359. in_lockstep-0.1.0/src/lockstep/emit/orchestrator.py +1253 -0
  360. in_lockstep-0.1.0/src/lockstep/emit/overlay.py +210 -0
  361. in_lockstep-0.1.0/src/lockstep/emit/plan.py +537 -0
  362. in_lockstep-0.1.0/src/lockstep/emit/profiles.py +66 -0
  363. in_lockstep-0.1.0/src/lockstep/emit/semantic_diff.py +173 -0
  364. in_lockstep-0.1.0/src/lockstep/emit/show_surface.py +135 -0
  365. in_lockstep-0.1.0/src/lockstep/emit/validate.py +104 -0
  366. in_lockstep-0.1.0/src/lockstep/emit/writer.py +117 -0
  367. in_lockstep-0.1.0/src/lockstep/errors.py +67 -0
  368. in_lockstep-0.1.0/src/lockstep/ghaw.py +140 -0
  369. in_lockstep-0.1.0/src/lockstep/library/__init__.py +98 -0
  370. in_lockstep-0.1.0/src/lockstep/library/guardrails/baseline.md +28 -0
  371. in_lockstep-0.1.0/src/lockstep/library/pipelines/fix/agents/bug-analyst.md +30 -0
  372. in_lockstep-0.1.0/src/lockstep/library/pipelines/fix/agents/fix-reviewer.md +29 -0
  373. in_lockstep-0.1.0/src/lockstep/library/pipelines/fix/agents/fix-writer.md +28 -0
  374. in_lockstep-0.1.0/src/lockstep/library/pipelines/fix/agents/reproducer-writer.md +30 -0
  375. in_lockstep-0.1.0/src/lockstep/library/pipelines/fix/commands/fix.md +76 -0
  376. in_lockstep-0.1.0/src/lockstep/library/pipelines/fix/evals/bug-analyst/cases/names-a-mechanism-not-the-symptom.json +36 -0
  377. in_lockstep-0.1.0/src/lockstep/library/pipelines/fix/evals/bug-analyst/cases/not-finding-it-is-an-answer.json +43 -0
  378. in_lockstep-0.1.0/src/lockstep/library/pipelines/fix/evals/fix-reviewer/cases/leads-with-the-evidence.json +36 -0
  379. in_lockstep-0.1.0/src/lockstep/library/pipelines/fix/evals/fix-writer/cases/does-not-edit-the-test.json +32 -0
  380. in_lockstep-0.1.0/src/lockstep/library/pipelines/fix/evals/reproducer-writer/cases/asserts-the-correct-behaviour.json +28 -0
  381. in_lockstep-0.1.0/src/lockstep/library/pipelines/fix/guardrails/fixing.md +22 -0
  382. in_lockstep-0.1.0/src/lockstep/library/pipelines/fix/pipeline.yaml +2 -0
  383. in_lockstep-0.1.0/src/lockstep/library/pipelines/implement/agents/change-writer.md +29 -0
  384. in_lockstep-0.1.0/src/lockstep/library/pipelines/implement/agents/planner.md +28 -0
  385. in_lockstep-0.1.0/src/lockstep/library/pipelines/implement/agents/requirements-analyst.md +29 -0
  386. in_lockstep-0.1.0/src/lockstep/library/pipelines/implement/agents/test-writer.md +28 -0
  387. in_lockstep-0.1.0/src/lockstep/library/pipelines/implement/commands/implement.md +74 -0
  388. in_lockstep-0.1.0/src/lockstep/library/pipelines/implement/evals/change-writer/cases/stays-inside-the-plan.json +31 -0
  389. in_lockstep-0.1.0/src/lockstep/library/pipelines/implement/evals/planner/cases/carries-the-open-question.json +44 -0
  390. in_lockstep-0.1.0/src/lockstep/library/pipelines/implement/evals/requirements-analyst/cases/criteria-a-parser-read-out-of-prose.json +46 -0
  391. in_lockstep-0.1.0/src/lockstep/library/pipelines/implement/evals/requirements-analyst/cases/what-the-issue-does-not-decide.json +39 -0
  392. in_lockstep-0.1.0/src/lockstep/library/pipelines/implement/evals/test-writer/cases/a-test-that-fails-first.json +31 -0
  393. in_lockstep-0.1.0/src/lockstep/library/pipelines/implement/guardrails/implementing.md +25 -0
  394. in_lockstep-0.1.0/src/lockstep/library/pipelines/implement/pipeline.yaml +2 -0
  395. in_lockstep-0.1.0/src/lockstep/library/pipelines/implement/skills/change-format.md +17 -0
  396. in_lockstep-0.1.0/src/lockstep/library/pipelines/retro/agents/retro-analyst.md +90 -0
  397. in_lockstep-0.1.0/src/lockstep/library/pipelines/retro/commands/retro.md +31 -0
  398. in_lockstep-0.1.0/src/lockstep/library/pipelines/retro/evals/retro-analyst/cases/a-real-regression.json +87 -0
  399. in_lockstep-0.1.0/src/lockstep/library/pipelines/retro/evals/retro-analyst/cases/a-window-too-thin-to-read.json +51 -0
  400. in_lockstep-0.1.0/src/lockstep/library/pipelines/retro/evals/retro-analyst/cases/nothing-needs-changing.json +57 -0
  401. in_lockstep-0.1.0/src/lockstep/library/pipelines/retro/evals/retro-analyst/cases/slower-but-not-wrong.json +62 -0
  402. in_lockstep-0.1.0/src/lockstep/library/pipelines/retro/guardrails/retro.md +35 -0
  403. in_lockstep-0.1.0/src/lockstep/library/pipelines/retro/pipeline.yaml +2 -0
  404. in_lockstep-0.1.0/src/lockstep/library/pipelines/review/agents/intent-reviewer.md +31 -0
  405. in_lockstep-0.1.0/src/lockstep/library/pipelines/review/agents/performance-reviewer.md +32 -0
  406. in_lockstep-0.1.0/src/lockstep/library/pipelines/review/agents/security-reviewer.md +37 -0
  407. in_lockstep-0.1.0/src/lockstep/library/pipelines/review/agents/tests-reviewer.md +31 -0
  408. in_lockstep-0.1.0/src/lockstep/library/pipelines/review/commands/review.md +66 -0
  409. in_lockstep-0.1.0/src/lockstep/library/pipelines/review/evals/intent-reviewer/cases/does-more-than-it-says.json +44 -0
  410. in_lockstep-0.1.0/src/lockstep/library/pipelines/review/evals/intent-reviewer/cases/does-what-it-says.json +26 -0
  411. in_lockstep-0.1.0/src/lockstep/library/pipelines/review/evals/performance-reviewer/cases/not-worth-a-comment.json +26 -0
  412. in_lockstep-0.1.0/src/lockstep/library/pipelines/review/evals/performance-reviewer/cases/query-per-order.json +36 -0
  413. in_lockstep-0.1.0/src/lockstep/library/pipelines/review/evals/security-reviewer/cases/names-the-mechanism-not-the-verdict.json +39 -0
  414. in_lockstep-0.1.0/src/lockstep/library/pipelines/review/evals/security-reviewer/cases/nothing-to-find.json +26 -0
  415. in_lockstep-0.1.0/src/lockstep/library/pipelines/review/evals/security-reviewer/cases/path-traversal.json +39 -0
  416. in_lockstep-0.1.0/src/lockstep/library/pipelines/review/evals/tests-reviewer/cases/assertion-that-proves-nothing.json +44 -0
  417. in_lockstep-0.1.0/src/lockstep/library/pipelines/review/evals/tests-reviewer/cases/no-test-needed.json +26 -0
  418. in_lockstep-0.1.0/src/lockstep/library/pipelines/review/guardrails/reviewing.md +32 -0
  419. in_lockstep-0.1.0/src/lockstep/library/pipelines/review/pipeline.yaml +2 -0
  420. in_lockstep-0.1.0/src/lockstep/library/pipelines/review/skills/review-format.md +26 -0
  421. in_lockstep-0.1.0/src/lockstep/library/pipelines/review/skills/review-revision.md +17 -0
  422. in_lockstep-0.1.0/src/lockstep/library/pipelines/triage/agents/triage-analyst.md +45 -0
  423. in_lockstep-0.1.0/src/lockstep/library/pipelines/triage/commands/triage.md +41 -0
  424. in_lockstep-0.1.0/src/lockstep/library/pipelines/triage/evals/triage-analyst/cases/criteria-that-a-parser-guessed.json +43 -0
  425. in_lockstep-0.1.0/src/lockstep/library/pipelines/triage/evals/triage-analyst/cases/feature-request-is-never-urgent.json +36 -0
  426. in_lockstep-0.1.0/src/lockstep/library/pipelines/triage/evals/triage-analyst/cases/missing-the-expected-behaviour.json +37 -0
  427. in_lockstep-0.1.0/src/lockstep/library/pipelines/triage/evals/triage-analyst/cases/production-outage.json +45 -0
  428. in_lockstep-0.1.0/src/lockstep/library/pipelines/triage/guardrails/triage.md +24 -0
  429. in_lockstep-0.1.0/src/lockstep/library/pipelines/triage/pipeline.yaml +6 -0
  430. in_lockstep-0.1.0/src/lockstep/library/pipelines/triage/skills/triage-format.md +32 -0
  431. in_lockstep-0.1.0/src/lockstep/library/skills/test-script-format.md +39 -0
  432. in_lockstep-0.1.0/src/lockstep/lifecycle.py +465 -0
  433. in_lockstep-0.1.0/src/lockstep/scaffold.py +800 -0
  434. in_lockstep-0.1.0/src/lockstep/spec/__init__.py +4 -0
  435. in_lockstep-0.1.0/src/lockstep/spec/load.py +475 -0
  436. in_lockstep-0.1.0/src/lockstep/spec/model.py +760 -0
  437. in_lockstep-0.1.0/src/lockstep/spec/parse.py +504 -0
  438. in_lockstep-0.1.0/src/lockstep/util/__init__.py +0 -0
  439. in_lockstep-0.1.0/src/lockstep/util/hashing.py +31 -0
  440. in_lockstep-0.1.0/src/lockstep/util/text.py +29 -0
  441. in_lockstep-0.1.0/src/lockstep/util/yamlio.py +66 -0
  442. in_lockstep-0.1.0/tests/conftest.py +61 -0
  443. in_lockstep-0.1.0/tests/fixtures/basic/.pipeline/pins.lock +26 -0
  444. in_lockstep-0.1.0/tests/fixtures/basic/agents/story-extractor.md +18 -0
  445. in_lockstep-0.1.0/tests/fixtures/basic/commands/discover.md +22 -0
  446. in_lockstep-0.1.0/tests/fixtures/basic/commands/generate-tests.md +38 -0
  447. in_lockstep-0.1.0/tests/fixtures/basic/commands/repair.md +28 -0
  448. in_lockstep-0.1.0/tests/fixtures/basic/commands/validate.md +23 -0
  449. in_lockstep-0.1.0/tests/fixtures/basic/contexts/my-app-patterns.md +7 -0
  450. in_lockstep-0.1.0/tests/fixtures/basic/evals/story-extractor/cases/one-story.json +13 -0
  451. in_lockstep-0.1.0/tests/fixtures/basic/guardrails/common.md +11 -0
  452. in_lockstep-0.1.0/tests/fixtures/basic/mcp/servers.json +12 -0
  453. in_lockstep-0.1.0/tests/fixtures/basic/overlays/github/fragments/acme.md +2 -0
  454. in_lockstep-0.1.0/tests/fixtures/basic/overlays/github/generate-tests.yml +17 -0
  455. in_lockstep-0.1.0/tests/fixtures/basic/pipeline.yaml +19 -0
  456. in_lockstep-0.1.0/tests/fixtures/basic/profiles/my-app.md +21 -0
  457. in_lockstep-0.1.0/tests/fixtures/basic/scripts/deploy-local.sh +2 -0
  458. in_lockstep-0.1.0/tests/fixtures/basic/scripts/discover-api.py +1 -0
  459. in_lockstep-0.1.0/tests/fixtures/basic/scripts/discover-ui.py +1 -0
  460. in_lockstep-0.1.0/tests/fixtures/basic/scripts/fetch-issues.py +1 -0
  461. in_lockstep-0.1.0/tests/fixtures/basic/scripts/repair-script.py +1 -0
  462. in_lockstep-0.1.0/tests/fixtures/basic/scripts/save-manifest.py +1 -0
  463. in_lockstep-0.1.0/tests/fixtures/basic/skills/test/common.md +7 -0
  464. in_lockstep-0.1.0/tests/fixtures/consumer/.pipeline/pins.lock +26 -0
  465. in_lockstep-0.1.0/tests/fixtures/consumer/agents/changelog-writer.md +15 -0
  466. in_lockstep-0.1.0/tests/fixtures/consumer/commands/changelog.md +12 -0
  467. in_lockstep-0.1.0/tests/fixtures/consumer/contexts/repo.md +9 -0
  468. in_lockstep-0.1.0/tests/fixtures/consumer/evals/changelog-writer/cases/one.json +12 -0
  469. in_lockstep-0.1.0/tests/fixtures/consumer/guardrails/house-style.md +6 -0
  470. in_lockstep-0.1.0/tests/fixtures/consumer/pipeline.yaml +35 -0
  471. in_lockstep-0.1.0/tests/fixtures/consumer/profiles/repo.md +11 -0
  472. in_lockstep-0.1.0/tests/fixtures/upstream-review/.pipeline/pins.lock +14 -0
  473. in_lockstep-0.1.0/tests/fixtures/upstream-review/agents/reviewer.md +14 -0
  474. in_lockstep-0.1.0/tests/fixtures/upstream-review/commands/review.md +18 -0
  475. in_lockstep-0.1.0/tests/fixtures/upstream-review/evals/reviewer/cases/basic.json +8 -0
  476. in_lockstep-0.1.0/tests/fixtures/upstream-review/guardrails/house.md +6 -0
  477. in_lockstep-0.1.0/tests/fixtures/upstream-review/pipeline.yaml +2 -0
  478. in_lockstep-0.1.0/tests/fixtures/upstream-review/scripts/collect-diff.py +2 -0
  479. in_lockstep-0.1.0/tests/fixtures/upstream-review/skills/verdict.md +6 -0
  480. in_lockstep-0.1.0/tests/fixtures/upstream-review/tests/test_collect_diff.py +1 -0
  481. in_lockstep-0.1.0/tests/fixtures/upstream-standards/.github/workflows/notify-consumers.yml +47 -0
  482. in_lockstep-0.1.0/tests/fixtures/upstream-standards/.pipeline/pins.lock +14 -0
  483. in_lockstep-0.1.0/tests/fixtures/upstream-standards/commands/update.md +34 -0
  484. in_lockstep-0.1.0/tests/fixtures/upstream-standards/guardrails/data-handling.md +20 -0
  485. in_lockstep-0.1.0/tests/fixtures/upstream-standards/pipeline.yaml +2 -0
  486. in_lockstep-0.1.0/tests/fixtures/upstream-standards/scripts/recompile.sh +25 -0
  487. in_lockstep-0.1.0/tests/fixtures/upstream-standards/scripts/repin.py +75 -0
  488. in_lockstep-0.1.0/tests/fixtures/upstream-standards/skills/citation-style.md +9 -0
  489. in_lockstep-0.1.0/tests/fixtures/upstream-standards/tests/test_notify.py +40 -0
  490. in_lockstep-0.1.0/tests/fixtures/upstream-standards/tests/test_recompile.py +25 -0
  491. in_lockstep-0.1.0/tests/fixtures/upstream-standards/tests/test_repin.py +57 -0
  492. in_lockstep-0.1.0/tests/golden/basic/.github/workflows/.gitattributes +14 -0
  493. in_lockstep-0.1.0/tests/golden/basic/.github/workflows/aw-story-extractor.md +117 -0
  494. in_lockstep-0.1.0/tests/golden/basic/.github/workflows/discover.yml +142 -0
  495. in_lockstep-0.1.0/tests/golden/basic/.github/workflows/evals.yml +79 -0
  496. in_lockstep-0.1.0/tests/golden/basic/.github/workflows/generate-tests.yml +231 -0
  497. in_lockstep-0.1.0/tests/golden/basic/.github/workflows/pipeline-ci.yml +87 -0
  498. in_lockstep-0.1.0/tests/golden/basic/.github/workflows/repair.yml +163 -0
  499. in_lockstep-0.1.0/tests/golden/basic/.github/workflows/shared/context-my-app-patterns.md +8 -0
  500. in_lockstep-0.1.0/tests/golden/basic/.github/workflows/shared/guardrail-baseline.md +22 -0
  501. in_lockstep-0.1.0/tests/golden/basic/.github/workflows/shared/guardrail-common.md +9 -0
  502. in_lockstep-0.1.0/tests/golden/basic/.github/workflows/shared/skill-test-common.md +8 -0
  503. in_lockstep-0.1.0/tests/golden/basic/.github/workflows/validate.yml +121 -0
  504. in_lockstep-0.1.0/tests/golden/basic/.pipeline/compile-manifest.json +93 -0
  505. in_lockstep-0.1.0/tests/golden/basic/.pipeline/step-defs/discover.discover-api-surface.json +18 -0
  506. in_lockstep-0.1.0/tests/golden/basic/.pipeline/step-defs/discover.discover-ui-structure.json +18 -0
  507. in_lockstep-0.1.0/tests/golden/basic/.pipeline/step-defs/generate-tests.build-test-manifest.json +18 -0
  508. in_lockstep-0.1.0/tests/golden/basic/.pipeline/step-defs/generate-tests.fetch-issues.json +18 -0
  509. in_lockstep-0.1.0/tests/golden/basic/.pipeline/step-defs/repair.collect-failures.json +18 -0
  510. in_lockstep-0.1.0/tests/golden/basic/SECRETS.md +39 -0
  511. in_lockstep-0.1.0/tests/test_adopting.py +162 -0
  512. in_lockstep-0.1.0/tests/test_agentic.py +164 -0
  513. in_lockstep-0.1.0/tests/test_caching.py +173 -0
  514. in_lockstep-0.1.0/tests/test_chatops.py +235 -0
  515. in_lockstep-0.1.0/tests/test_checks.py +402 -0
  516. in_lockstep-0.1.0/tests/test_cli.py +184 -0
  517. in_lockstep-0.1.0/tests/test_compiler_pin.py +165 -0
  518. in_lockstep-0.1.0/tests/test_conditions.py +211 -0
  519. in_lockstep-0.1.0/tests/test_conformance.py +236 -0
  520. in_lockstep-0.1.0/tests/test_contract.py +374 -0
  521. in_lockstep-0.1.0/tests/test_emit_orchestrator.py +218 -0
  522. in_lockstep-0.1.0/tests/test_errors.py +168 -0
  523. in_lockstep-0.1.0/tests/test_evals_workflow.py +470 -0
  524. in_lockstep-0.1.0/tests/test_extensions.py +139 -0
  525. in_lockstep-0.1.0/tests/test_ghaw_seam.py +157 -0
  526. in_lockstep-0.1.0/tests/test_golden.py +65 -0
  527. in_lockstep-0.1.0/tests/test_inherits.py +625 -0
  528. in_lockstep-0.1.0/tests/test_library.py +142 -0
  529. in_lockstep-0.1.0/tests/test_lifecycle.py +312 -0
  530. in_lockstep-0.1.0/tests/test_loops.py +124 -0
  531. in_lockstep-0.1.0/tests/test_metering.py +274 -0
  532. in_lockstep-0.1.0/tests/test_overlay.py +110 -0
  533. in_lockstep-0.1.0/tests/test_pinning.py +235 -0
  534. in_lockstep-0.1.0/tests/test_pr_review.py +200 -0
  535. in_lockstep-0.1.0/tests/test_private_upstreams.py +151 -0
  536. in_lockstep-0.1.0/tests/test_publishing.py +129 -0
  537. in_lockstep-0.1.0/tests/test_sandbox_and_scan.py +164 -0
  538. in_lockstep-0.1.0/tests/test_scaffold.py +159 -0
  539. in_lockstep-0.1.0/tests/test_secrets_doc.py +81 -0
  540. in_lockstep-0.1.0/tests/test_selfhost.py +130 -0
  541. in_lockstep-0.1.0/tests/test_semantic_diff.py +68 -0
  542. in_lockstep-0.1.0/tests/test_shipped_pipelines.py +402 -0
  543. in_lockstep-0.1.0/tests/test_spec_parse.py +129 -0
  544. in_lockstep-0.1.0/tests/test_state.py +98 -0
  545. in_lockstep-0.1.0/tests/test_updater.py +170 -0
  546. in_lockstep-0.1.0/tests/test_validate.py +77 -0
  547. in_lockstep-0.1.0/tests/test_writer.py +82 -0
  548. in_lockstep-0.1.0/uv.lock +950 -0
@@ -0,0 +1,28 @@
1
+ # Who has to approve a change here.
2
+ #
3
+ # This file names owners. It does not require anything on its own — GitHub only asks a code owner
4
+ # for review when a ruleset or branch protection on `main` has "Require review from Code Owners"
5
+ # turned on, with "Dismiss stale approvals" and "Require branches to be up to date" alongside it.
6
+ # Without that, every line below is documentation. The setting lives in repository settings and is
7
+ # not something this repository can grant itself.
8
+
9
+ # Everything, unless something more specific below claims it. The last matching pattern wins.
10
+ * @tpouyer
11
+
12
+ # The parts where a mistake is not a bug but a policy change.
13
+ #
14
+ # `enforce:` compiles to workflow permissions, egress allow-lists, tool deny-lists and the credit
15
+ # ceilings — the half of a guardrail a model cannot talk its way past. `library/` ships the baseline
16
+ # guardrail inlined into every agent in every pipeline. A change to either reaches every consumer of
17
+ # every pipeline built on this framework, which is a different kind of review from a bug fix.
18
+ /src/lockstep/library/ @tpouyer
19
+ /src/lockstep/emit/agentic.py @tpouyer
20
+ /actions/ @tpouyer
21
+
22
+ # Generated, but generated is not the same as unreviewed: these are what actually runs.
23
+ /.github/workflows/ @tpouyer
24
+ /.lockstep/ @tpouyer
25
+
26
+ # Licensing and attribution.
27
+ /LICENSE @tpouyer
28
+ /NOTICE @tpouyer
@@ -0,0 +1,4 @@
1
+ # GENERATED by lockstep — collapses generated files in pull request diffs.
2
+ # Only what the compiler wrote: anything else in this directory belongs to the repository.
3
+ *.lock.yml linguist-generated=true
4
+ pipeline-ci.yml linguist-generated=true
@@ -0,0 +1,20 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+
8
+ permissions:
9
+ contents: read
10
+
11
+ jobs:
12
+ check:
13
+ runs-on: ubuntu-24.04
14
+ steps:
15
+ - uses: actions/checkout@v4
16
+ - uses: astral-sh/setup-uv@v6
17
+ with:
18
+ python-version: '3.11'
19
+ - run: uv sync
20
+ - run: make ci
@@ -0,0 +1,86 @@
1
+ # GENERATED by lockstep 0.1.0 — do not edit.
2
+ # Edit the spec, add an overlay, or run `lockstep eject` on this file.
3
+ # sources: .lockstep/pipeline.yaml@411a460f
4
+ # profile: repo
5
+ name: pipeline-ci
6
+ on:
7
+ pull_request:
8
+ paths:
9
+ - .lockstep/commands/**
10
+ - .lockstep/agents/**
11
+ - .lockstep/guardrails/**
12
+ - .lockstep/skills/**
13
+ - .lockstep/contexts/**
14
+ - .lockstep/profiles/**
15
+ - .lockstep/mcp/**
16
+ - .lockstep/overlays/**
17
+ - .lockstep/scripts/**
18
+ - .lockstep/tests/**
19
+ - .lockstep/pipeline.yaml
20
+ - .lockstep/.pipeline/**
21
+ - .github/workflows/**
22
+ - src/**
23
+ - pyproject.toml
24
+ - uv.lock
25
+ push:
26
+ branches:
27
+ - main
28
+ workflow_dispatch: {}
29
+ permissions:
30
+ contents: read
31
+ concurrency:
32
+ group: pipeline-ci-${{ github.ref }}
33
+ cancel-in-progress: true
34
+ jobs:
35
+ drift:
36
+ name: Drift gate
37
+ runs-on: ubuntu-24.04
38
+ permissions:
39
+ contents: read
40
+ steps:
41
+ - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
42
+ with:
43
+ fetch-depth: 0
44
+ - uses: astral-sh/setup-uv@v6
45
+ - name: Install the pinned compiler
46
+ run: uv tool install "."
47
+ - name: Recompile and compare
48
+ run: lockstep compile --check --semantic-diff --fail-on-blocking --base=origin/${{ github.event.pull_request.base.ref || 'main' }}
49
+ lint:
50
+ name: Spec quality
51
+ runs-on: ubuntu-24.04
52
+ permissions:
53
+ contents: read
54
+ steps:
55
+ - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
56
+ with:
57
+ fetch-depth: 0
58
+ - uses: astral-sh/setup-uv@v6
59
+ - name: Install the pinned compiler
60
+ run: uv tool install "."
61
+ - name: Lint the spec
62
+ run: lockstep lint
63
+ doctor:
64
+ name: Target readiness
65
+ runs-on: ubuntu-24.04
66
+ permissions:
67
+ contents: read
68
+ steps:
69
+ - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
70
+ with:
71
+ fetch-depth: 0
72
+ - uses: astral-sh/setup-uv@v6
73
+ - name: Install the pinned compiler
74
+ run: uv tool install "."
75
+ - name: Check target readiness
76
+ run: lockstep doctor --target=github-agentic
77
+ scripts:
78
+ name: Script tests
79
+ runs-on: ubuntu-24.04
80
+ permissions:
81
+ contents: read
82
+ steps:
83
+ - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
84
+ - uses: astral-sh/setup-uv@v6
85
+ - name: Run the scripts' own tests
86
+ run: if [ -d .lockstep/tests ]; then uv run pytest .lockstep/tests -q; else echo "no .lockstep/tests directory"; fi
@@ -0,0 +1,96 @@
1
+ # Tagging *is* publishing for a composite action.
2
+ #
3
+ # There is nothing to upload: `uses: in-lockstep/lockstep/actions/restore@<sha>` resolves against a
4
+ # commit in this repository. So this workflow's job is not to publish the tag — it is to prove the
5
+ # tag is safe to point at before anyone does, because the moment it exists, every consumer that runs
6
+ # `lockstep pin` can resolve it into their lock file and it becomes what their pipelines execute.
7
+ #
8
+ # Tagged `actions-v*` rather than `v*` deliberately. If the actions shared the compiler's tags, every
9
+ # compiler release would move the pin under consumers who use the actions and never changed them —
10
+ # churn that teaches people to approve pin bumps without reading them, which is the exact habit the
11
+ # drift gate exists to prevent.
12
+ name: release-actions
13
+
14
+ on:
15
+ push:
16
+ tags: ['actions-v*']
17
+ workflow_dispatch:
18
+ inputs:
19
+ ref:
20
+ description: Tag or commit to verify without releasing
21
+ required: false
22
+
23
+ permissions:
24
+ contents: read
25
+
26
+ jobs:
27
+ verify:
28
+ name: Verify the actions
29
+ runs-on: ubuntu-24.04
30
+ steps:
31
+ - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
32
+ with:
33
+ ref: ${{ inputs.ref || github.ref }}
34
+ - uses: astral-sh/setup-uv@v6
35
+ - run: uv sync
36
+
37
+ - name: Every action the compiler references exists and takes what it is given
38
+ # The contract test walks the compiled examples, collects every `uses:` naming a capability
39
+ # action, and checks the inputs against that action's own `action.yml`. A tag that fails
40
+ # this would be a tag whose actions reject the workflows the compiler writes for them.
41
+ run: uv run pytest tests/test_contract.py -q
42
+
43
+ - name: Actions are pinned to commits, not to tags
44
+ # A composite action that itself uses a floating tag hands the mutability straight back.
45
+ run: |
46
+ set -euo pipefail
47
+ floating=$(grep -rnE 'uses:\s+[^@]+@(v[0-9]|main|master)' actions/ || true)
48
+ if [ -n "$floating" ]; then
49
+ echo "these steps reference a movable ref:"; echo "$floating"; exit 1
50
+ fi
51
+ echo "every `uses:` inside actions/ is pinned to a commit"
52
+
53
+ - name: The tag names a version the actions actually changed at
54
+ if: startsWith(github.ref, 'refs/tags/actions-v')
55
+ # Cheap guard against tagging out of habit. If nothing under actions/ changed since the
56
+ # previous actions tag, consumers would take a pin bump that alters nothing they run.
57
+ run: |
58
+ set -euo pipefail
59
+ previous=$(git tag --list 'actions-v*' --sort=-v:refname | sed -n '2p')
60
+ if [ -z "$previous" ]; then echo "first actions tag; nothing to compare"; exit 0; fi
61
+ if git diff --quiet "$previous" HEAD -- actions/; then
62
+ echo "actions/ is unchanged since $previous — this tag would move consumers' pins for nothing"
63
+ exit 1
64
+ fi
65
+ git diff --stat "$previous" HEAD -- actions/
66
+
67
+ release:
68
+ name: Cut the release
69
+ needs: verify
70
+ if: startsWith(github.ref, 'refs/tags/actions-v')
71
+ runs-on: ubuntu-24.04
72
+ permissions:
73
+ contents: write
74
+ steps:
75
+ - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
76
+ with:
77
+ fetch-depth: 0
78
+ - name: Publish the release notes, with the commit consumers will pin
79
+ env:
80
+ GH_TOKEN: ${{ github.token }}
81
+ TAG: ${{ github.ref_name }}
82
+ run: |
83
+ set -euo pipefail
84
+ sha=$(git rev-parse HEAD)
85
+ {
86
+ echo "Composite actions for pipelines compiled by lockstep."
87
+ echo
88
+ echo '```yaml'
89
+ echo "capabilities:"
90
+ echo " actions: github.com/in-lockstep/lockstep/actions@${TAG}"
91
+ echo '```'
92
+ echo
93
+ echo "\`lockstep pin\` resolves that to \`${sha}\`, and every generated workflow"
94
+ echo "references the actions by that commit rather than by the tag."
95
+ } > notes.md
96
+ gh release create "$TAG" --title "actions $TAG" --notes-file notes.md
@@ -0,0 +1,132 @@
1
+ # Building and publishing the image that compiled workflows run their deterministic steps in.
2
+ #
3
+ # Unlike the composite actions, this one really does publish: a `container:` in a generated workflow
4
+ # names a registry, and nothing resolves until something has been pushed there. The output that
5
+ # matters is not the tag — it is the **digest**. `lockstep compile` refuses to emit an image that is
6
+ # not pinned by digest, so a rebuild can never change what an already-reviewed pipeline runs.
7
+ #
8
+ # Tagged `exec-v*`, on its own line from the compiler and from the actions, for the same reason:
9
+ # a pin should move when the thing behind it moved.
10
+ name: release-exec-image
11
+
12
+ on:
13
+ push:
14
+ tags: ['exec-v*']
15
+ workflow_dispatch:
16
+ inputs:
17
+ push:
18
+ description: Push to the registry (otherwise build and test only)
19
+ type: boolean
20
+ default: false
21
+
22
+ permissions:
23
+ contents: read
24
+
25
+ env:
26
+ IMAGE: ghcr.io/in-lockstep/pipeline-exec
27
+
28
+ jobs:
29
+ build:
30
+ name: Build, prove, publish
31
+ runs-on: ubuntu-24.04
32
+ permissions:
33
+ contents: write # the release note carries the digest
34
+ packages: write # ghcr.io
35
+ steps:
36
+ - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
37
+ with:
38
+ fetch-depth: 0
39
+
40
+ - uses: astral-sh/setup-uv@v6
41
+ - name: The package builds and its tests pass
42
+ # The image installs this package. A wheel that does not build is an image that fails at
43
+ # `docker build` after ten minutes of apt, and a package whose tests fail is worse: it
44
+ # builds, publishes, and every consumer's script step runs the regression.
45
+ run: |
46
+ set -euo pipefail
47
+ uv sync
48
+ uv run pytest packages/pipeline-exec -q
49
+ # The distribution is `in-lockstep-exec`, not `pipeline-exec`: the bare name belongs to an
50
+ # unrelated project on PyPI. The import name and the console script stay `pipeline_exec`.
51
+ uv build --package in-lockstep-exec --out-dir dist
52
+ test -f dist/in_lockstep_exec-*.whl
53
+
54
+ - uses: docker/setup-buildx-action@v3
55
+
56
+ - name: Log in to the registry
57
+ if: startsWith(github.ref, 'refs/tags/exec-v') || inputs.push
58
+ uses: docker/login-action@v3
59
+ with:
60
+ registry: ghcr.io
61
+ username: ${{ github.actor }}
62
+ password: ${{ github.token }}
63
+
64
+ - name: Build
65
+ id: build
66
+ uses: docker/build-push-action@v6
67
+ with:
68
+ context: packages/pipeline-exec
69
+ file: packages/pipeline-exec/docker/Dockerfile
70
+ # linux/amd64 only, deliberately: GitHub-hosted runners are x86_64, and a container job
71
+ # runs on the runner's architecture. An arm64 layer nobody pulls doubles the build for
72
+ # nothing. Add it when somebody runs a self-hosted arm64 fleet.
73
+ platforms: linux/amd64
74
+ push: ${{ startsWith(github.ref, 'refs/tags/exec-v') || inputs.push }}
75
+ load: ${{ !(startsWith(github.ref, 'refs/tags/exec-v') || inputs.push) }}
76
+ tags: |
77
+ ${{ env.IMAGE }}:${{ github.ref_name }}
78
+ ${{ env.IMAGE }}:latest
79
+ cache-from: type=gha
80
+ cache-to: type=gha,mode=max
81
+
82
+ - name: The image can actually run a step
83
+ # A published image that cannot execute the commands the compiler writes into workflows is
84
+ # the failure this catches. `list-commands` is the introspection surface: it names every
85
+ # builtin, so a missing entry point fails here rather than in somebody's pipeline.
86
+ env:
87
+ PUBLISHED: ${{ startsWith(github.ref, 'refs/tags/exec-v') || inputs.push }}
88
+ DIGEST: ${{ steps.build.outputs.digest }}
89
+ run: |
90
+ set -euo pipefail
91
+ # Which reference to smoke-test is decided by whether the image was pushed, not by whether
92
+ # a digest exists. `load:` also produces a digest, but it names a manifest that only lives
93
+ # in the registry — so a digest reference is always resolved by pulling, and the dry run
94
+ # neither pushed nor logged in. It has to test the tag it loaded.
95
+ if [ "$PUBLISHED" = "true" ]; then
96
+ ref="${IMAGE}@${DIGEST}"
97
+ else
98
+ ref="${IMAGE}:${GITHUB_REF_NAME}"
99
+ fi
100
+ echo "smoke-testing $ref"
101
+ docker run --rm "$ref" pipeline-exec --version
102
+ docker run --rm "$ref" pipeline-exec list-commands
103
+ # The runtimes a `script:` step dispatches on by file extension.
104
+ docker run --rm --entrypoint sh "$ref" -c 'uv --version && node --version && ruby --version && go version && gh --version'
105
+
106
+ - name: Publish the digest, which is the thing consumers pin
107
+ if: startsWith(github.ref, 'refs/tags/exec-v')
108
+ env:
109
+ GH_TOKEN: ${{ github.token }}
110
+ TAG: ${{ github.ref_name }}
111
+ DIGEST: ${{ steps.build.outputs.digest }}
112
+ run: |
113
+ set -euo pipefail
114
+ {
115
+ echo "The executor image for pipelines compiled by lockstep."
116
+ echo
117
+ echo '```yaml'
118
+ echo "capabilities:"
119
+ echo " exec-image: ${IMAGE}"
120
+ echo '```'
121
+ echo
122
+ echo "Then pin it. The tag above exists for humans; the digest is what runs:"
123
+ echo
124
+ echo '```bash'
125
+ echo "lockstep pin --exec-digest=${DIGEST}"
126
+ echo '```'
127
+ echo
128
+ echo "\`lockstep compile\` refuses to emit an image that is not pinned by digest, so"
129
+ echo "rebuilding \`${TAG}\` cannot change what an already-reviewed pipeline runs."
130
+ } > notes.md
131
+ gh release create "$TAG" --title "executor image $TAG" --notes-file notes.md
132
+ echo "### \`$DIGEST\`" >> "$GITHUB_STEP_SUMMARY"
@@ -0,0 +1,133 @@
1
+ # Publishing the two Python distributions this repository builds.
2
+ #
3
+ # `in-lockstep` is the compiler and `in-lockstep-exec` is the runtime, and a compiled pipeline
4
+ # installs both **by name from a public index**: the drift-gate job runs
5
+ # `uv tool install "in-lockstep=="`, and an eval job that materializes inherited definitions installs
6
+ # the executor alongside it because the exec image deliberately does not carry the compiler. So
7
+ # until these exist on PyPI, a consumer repository can resolve every action and pull the image and
8
+ # still not run.
9
+ #
10
+ # **No API token exists anywhere in this.** Publication is by Trusted Publishing: PyPI verifies a
11
+ # short-lived OIDC credential minted by Actions for this repository, this workflow and this
12
+ # environment. There is no secret to leak, rotate, or scope wrongly — which is the same argument
13
+ # the rest of the framework makes about agents never holding credentials.
14
+ #
15
+ # The environment is **per distribution**, which is not decoration. PyPI identifies a publisher by
16
+ # owner, repository, workflow and environment together, and refuses to register two projects behind
17
+ # an identical configuration — otherwise one credential would speak for both, and a workflow allowed
18
+ # to publish the runtime could publish the compiler. Naming the environment after the project is
19
+ # what keeps each credential scoped to the one thing it may upload.
20
+ #
21
+ # Tagged `v*`, the compiler's own line. `actions-v*` and `exec-v*` stay separate so a pin moves when
22
+ # the thing behind it moved.
23
+ name: release-python
24
+
25
+ on:
26
+ push:
27
+ tags: ['v*']
28
+ workflow_dispatch:
29
+ inputs:
30
+ publish:
31
+ description: Upload to PyPI (otherwise build and prove only)
32
+ type: boolean
33
+ default: false
34
+
35
+ permissions:
36
+ contents: read
37
+
38
+ jobs:
39
+ build:
40
+ name: Build and prove
41
+ runs-on: ubuntu-24.04
42
+ steps:
43
+ - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
44
+ with:
45
+ fetch-depth: 0
46
+ - uses: astral-sh/setup-uv@v6
47
+ with:
48
+ python-version: '3.11'
49
+
50
+ - name: The tag names the version being published
51
+ # A tag and a version that disagree publish something nobody asked for, under a name nobody
52
+ # can withdraw: PyPI never lets a version be reused, even after a delete.
53
+ if: startsWith(github.ref, 'refs/tags/v')
54
+ run: |
55
+ set -euo pipefail
56
+ tag="${GITHUB_REF_NAME#v}"
57
+ for manifest in pyproject.toml packages/pipeline-exec/pyproject.toml; do
58
+ version=$(grep -m1 '^version = ' "$manifest" | cut -d'"' -f2)
59
+ if [ "$version" != "$tag" ]; then
60
+ echo "$manifest is $version, but the tag says $tag"; exit 1
61
+ fi
62
+ done
63
+ echo "both distributions are $tag"
64
+
65
+ - run: uv sync
66
+ - name: The suite passes
67
+ run: uv run pytest -q
68
+
69
+ - name: Build both distributions
70
+ # Into separate directories: each PyPI project is a separate Trusted Publishing exchange, and
71
+ # an upload pointed at a directory would otherwise carry the other project's files with it.
72
+ run: |
73
+ set -euo pipefail
74
+ uv build --package in-lockstep --out-dir dist/in-lockstep
75
+ uv build --package in-lockstep-exec --out-dir dist/in-lockstep-exec
76
+ uvx twine check dist/*/*
77
+
78
+ - name: A clean install carries what is not Python
79
+ # The failure this exists for: the compiler ships five pipelines as markdown under
80
+ # `lockstep/library/`, and the executor ships Jinja report templates. Neither is a `.py`
81
+ # file, so a packaging change can drop them while every test in this repository still passes
82
+ # — they are read from the source tree here and from site-packages everywhere else.
83
+ # `init --adopt all` reads the library, so it fails if the library did not travel.
84
+ run: |
85
+ set -euo pipefail
86
+ python3 -m venv /tmp/proof
87
+ /tmp/proof/bin/pip install -q dist/in-lockstep/*.whl dist/in-lockstep-exec/*.whl
88
+ /tmp/proof/bin/lockstep --version
89
+ /tmp/proof/bin/pipeline-exec --version
90
+ /tmp/proof/bin/pipeline-exec list-commands > /dev/null
91
+ mkdir -p /tmp/proof-repo && cd /tmp/proof-repo
92
+ /tmp/proof/bin/lockstep init --name proof --adopt all
93
+ test -d .lockstep || test -f pipeline.yaml
94
+ /tmp/proof/bin/lockstep fetch
95
+ echo "the shipped library survived packaging"
96
+
97
+ - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
98
+ with:
99
+ name: distributions
100
+ path: dist/
101
+ if-no-files-found: error
102
+
103
+ publish:
104
+ name: Publish ${{ matrix.project }}
105
+ needs: build
106
+ if: startsWith(github.ref, 'refs/tags/v') || inputs.publish
107
+ runs-on: ubuntu-24.04
108
+ # pypi-in-lockstep and pypi-in-lockstep-exec. Each must match the environment recorded in that
109
+ # project's publisher on PyPI, or the exchange is refused.
110
+ environment: pypi-${{ matrix.project }}
111
+ permissions:
112
+ id-token: write # mint the OIDC credential PyPI verifies; nothing else is needed
113
+ strategy:
114
+ fail-fast: false
115
+ matrix:
116
+ project: [in-lockstep, in-lockstep-exec]
117
+ steps:
118
+ - uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4
119
+ with:
120
+ name: distributions
121
+ path: dist
122
+ - name: Upload to PyPI
123
+ # v1.14.2 or newer, and the floor is load-bearing rather than hygiene: it is the first
124
+ # release carrying Twine 7, and Twine below that rejects core metadata 2.5 outright. Both
125
+ # distributions are 2.5, because hatchling emits PEP 639 `License-Expression` for the
126
+ # `license = "Apache-2.0"` these manifests declare.
127
+ uses: pypa/gh-action-pypi-publish@dc37677b2e1c63e2034f94d8a5b11f265b73ba33 # v1.14.2
128
+ with:
129
+ packages-dir: dist/${{ matrix.project }}
130
+ # One tag publishes both distributions, and they do not always both move. A version already
131
+ # on PyPI is the normal case for the one that did not change, not a failure.
132
+ skip-existing: true
133
+ print-hash: true
@@ -0,0 +1,13 @@
1
+ __pycache__/
2
+ *.py[cod]
3
+ .venv/
4
+ .mypy_cache/
5
+ .ruff_cache/
6
+ .pytest_cache/
7
+ dist/
8
+ build/
9
+ *.egg-info/
10
+ .coverage
11
+
12
+ # Fetched by `lockstep fetch` at the commit pins.lock records.
13
+ **/.pipeline/inherited/
@@ -0,0 +1,19 @@
1
+ {
2
+ "compiler": "0.1.0",
3
+ "files": {
4
+ ".github/workflows/.gitattributes": {
5
+ "sha": "8dd12516",
6
+ "sources": []
7
+ },
8
+ ".github/workflows/pipeline-ci.yml": {
9
+ "sha": "0b0c8631",
10
+ "sources": []
11
+ },
12
+ ".lockstep/SECRETS.md": {
13
+ "sha": "3864c66c",
14
+ "sources": []
15
+ }
16
+ },
17
+ "pipeline": "lockstep",
18
+ "spec": 1
19
+ }
@@ -0,0 +1,15 @@
1
+ {
2
+ "capabilities": {
3
+ "exec": {
4
+ "image": "",
5
+ "package": "pipeline-exec"
6
+ }
7
+ },
8
+ "external": {
9
+ "actions/checkout": {
10
+ "sha": "11d5960a326750d5838078e36cf38b85af677262",
11
+ "tag": "v4"
12
+ }
13
+ },
14
+ "inherits": {}
15
+ }
@@ -0,0 +1,10 @@
1
+ <!-- GENERATED by lockstep — do not edit. -->
2
+
3
+ # Secrets and variables
4
+
5
+ Every secret and variable this pipeline needs, by environment.
6
+
7
+ ## Profile `repo` — environment `(repository level)`
8
+
9
+ ```bash
10
+ ```
@@ -0,0 +1,27 @@
1
+ spec: 1
2
+ name: lockstep
3
+
4
+ # This repository compiles its own drift gate.
5
+ #
6
+ # Everything else here is a pipeline repository that installs a released compiler. This one *is* the
7
+ # compiler, which changes exactly one thing and it is the thing that matters: the output is a
8
+ # function of the spec **and** of `src/`. So `compiler` points at the checkout rather than at a
9
+ # release — a gate that installed the published `lockstep` would recompile a pull request's spec
10
+ # with the previous pull request's compiler and pass — and `watch` puts the compiler's own source on
11
+ # the trigger, because a change to the emitter is the change most worth recompiling.
12
+ #
13
+ # No `actions`, `exec` or `exec-image`: this pipeline has no steps, so its output names no composite
14
+ # action and pulls no container. When it grows one, those get declared and pinned like anywhere else.
15
+
16
+ capabilities:
17
+ compiler: "."
18
+
19
+ targets:
20
+ github-agentic:
21
+ out: .github/workflows
22
+ default-runs-on: ubuntu-24.04
23
+ profiles: [repo]
24
+ watch:
25
+ - src/**
26
+ - pyproject.toml
27
+ - uv.lock
@@ -0,0 +1,7 @@
1
+ ---
2
+ name: repo
3
+ description: This repository, checked out by the workflow that runs the gate
4
+ github:
5
+ deploy:
6
+ mode: external
7
+ ---