agentic-dev-loop 0.15.3__tar.gz → 0.15.4__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 (155) hide show
  1. {agentic_dev_loop-0.15.3/src/agentic_dev_loop.egg-info → agentic_dev_loop-0.15.4}/PKG-INFO +6 -5
  2. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/README.md +5 -4
  3. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/pyproject.toml +1 -1
  4. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/src/agentic_dev_loop/engine/onboarding/templates/dev.agent.md +24 -9
  5. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/src/agentic_dev_loop/engine/stages.py +6 -2
  6. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4/src/agentic_dev_loop.egg-info}/PKG-INFO +6 -5
  7. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/tests/test_unit11.py +38 -1
  8. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/LICENSE +0 -0
  9. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/setup.cfg +0 -0
  10. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/src/agentic_dev_loop/__init__.py +0 -0
  11. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/src/agentic_dev_loop/core/__init__.py +0 -0
  12. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/src/agentic_dev_loop/core/config.py +0 -0
  13. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/src/agentic_dev_loop/core/failure.py +0 -0
  14. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/src/agentic_dev_loop/core/paths.py +0 -0
  15. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/src/agentic_dev_loop/core/profiles/__init__.py +0 -0
  16. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/src/agentic_dev_loop/core/profiles/data/dotnet-node.yaml +0 -0
  17. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/src/agentic_dev_loop/core/profiles/data/python.yaml +0 -0
  18. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/src/agentic_dev_loop/core/results.py +0 -0
  19. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/src/agentic_dev_loop/core/verdict.py +0 -0
  20. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/src/agentic_dev_loop/engine/__init__.py +0 -0
  21. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/src/agentic_dev_loop/engine/actions.py +0 -0
  22. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/src/agentic_dev_loop/engine/agent_error_guide.md +0 -0
  23. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/src/agentic_dev_loop/engine/agent_error_guide.py +0 -0
  24. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/src/agentic_dev_loop/engine/agents.py +0 -0
  25. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/src/agentic_dev_loop/engine/allowlist.py +0 -0
  26. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/src/agentic_dev_loop/engine/brief_coverage.py +0 -0
  27. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/src/agentic_dev_loop/engine/brief_prompt.md +0 -0
  28. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/src/agentic_dev_loop/engine/brief_prompt.py +0 -0
  29. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/src/agentic_dev_loop/engine/cli.py +0 -0
  30. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/src/agentic_dev_loop/engine/completion.py +0 -0
  31. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/src/agentic_dev_loop/engine/containers.py +0 -0
  32. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/src/agentic_dev_loop/engine/copilot_auth.py +0 -0
  33. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/src/agentic_dev_loop/engine/deps.py +0 -0
  34. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/src/agentic_dev_loop/engine/dryrun.py +0 -0
  35. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/src/agentic_dev_loop/engine/egress_policy.py +0 -0
  36. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/src/agentic_dev_loop/engine/egress_proxy.py +0 -0
  37. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/src/agentic_dev_loop/engine/extensions/__init__.py +0 -0
  38. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/src/agentic_dev_loop/engine/extensions/aidlc.py +0 -0
  39. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/src/agentic_dev_loop/engine/forbidden.py +0 -0
  40. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/src/agentic_dev_loop/engine/graph.py +0 -0
  41. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/src/agentic_dev_loop/engine/hostboundary.py +0 -0
  42. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/src/agentic_dev_loop/engine/isolation.py +0 -0
  43. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/src/agentic_dev_loop/engine/llm.py +0 -0
  44. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/src/agentic_dev_loop/engine/loaders.py +0 -0
  45. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/src/agentic_dev_loop/engine/mounts.py +0 -0
  46. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/src/agentic_dev_loop/engine/onboarding/__init__.py +0 -0
  47. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/src/agentic_dev_loop/engine/onboarding/checks.py +0 -0
  48. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/src/agentic_dev_loop/engine/onboarding/doctor.py +0 -0
  49. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/src/agentic_dev_loop/engine/onboarding/init.py +0 -0
  50. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/src/agentic_dev_loop/engine/onboarding/recipes/dotnet-node.yaml +0 -0
  51. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/src/agentic_dev_loop/engine/onboarding/recipes/python.yaml +0 -0
  52. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/src/agentic_dev_loop/engine/onboarding/recipes.py +0 -0
  53. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/src/agentic_dev_loop/engine/onboarding/templates/env.example +0 -0
  54. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/src/agentic_dev_loop/engine/onboarding/templates/qa.agent.md +0 -0
  55. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/src/agentic_dev_loop/engine/onboarding/templates/review.agent.md +0 -0
  56. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/src/agentic_dev_loop/engine/onboarding/templates.py +0 -0
  57. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/src/agentic_dev_loop/engine/onboarding/upgrade.py +0 -0
  58. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/src/agentic_dev_loop/engine/outputs.py +0 -0
  59. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/src/agentic_dev_loop/engine/presets.py +0 -0
  60. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/src/agentic_dev_loop/engine/proc.py +0 -0
  61. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/src/agentic_dev_loop/engine/provider_wire.py +0 -0
  62. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/src/agentic_dev_loop/engine/registry.py +0 -0
  63. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/src/agentic_dev_loop/engine/run_status.py +0 -0
  64. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/src/agentic_dev_loop/engine/run_status_command.md +0 -0
  65. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/src/agentic_dev_loop/engine/seccomp/__init__.py +0 -0
  66. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/src/agentic_dev_loop/engine/seccomp/chromium-userns.json +0 -0
  67. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/src/agentic_dev_loop/engine/secrets.py +0 -0
  68. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/src/agentic_dev_loop/engine/step_workspace.py +0 -0
  69. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/src/agentic_dev_loop/engine/sync_back.py +0 -0
  70. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/src/agentic_dev_loop/py.typed +0 -0
  71. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/src/agentic_dev_loop/reporting/__init__.py +0 -0
  72. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/src/agentic_dev_loop/reporting/metrics.py +0 -0
  73. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/src/agentic_dev_loop/reporting/render.py +0 -0
  74. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/src/agentic_dev_loop/reporting/sources.py +0 -0
  75. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/src/agentic_dev_loop/viz/__init__.py +0 -0
  76. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/src/agentic_dev_loop/viz/layout.py +0 -0
  77. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/src/agentic_dev_loop/viz/page.py +0 -0
  78. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/src/agentic_dev_loop/viz/runs_view.py +0 -0
  79. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/src/agentic_dev_loop/viz/server.py +0 -0
  80. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/src/agentic_dev_loop.egg-info/SOURCES.txt +0 -0
  81. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/src/agentic_dev_loop.egg-info/dependency_links.txt +0 -0
  82. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/src/agentic_dev_loop.egg-info/entry_points.txt +0 -0
  83. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/src/agentic_dev_loop.egg-info/requires.txt +0 -0
  84. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/src/agentic_dev_loop.egg-info/top_level.txt +0 -0
  85. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/tests/test_029_merge_on_conflict.py +0 -0
  86. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/tests/test_033_brief_step.py +0 -0
  87. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/tests/test_035_finalize_nudge.py +0 -0
  88. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/tests/test_036_banned_commands_and_lane_boundary.py +0 -0
  89. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/tests/test_041_brief_coverage.py +0 -0
  90. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/tests/test_046_brief_prompt.py +0 -0
  91. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/tests/test_055_cli.py +0 -0
  92. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/tests/test_055_doctor.py +0 -0
  93. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/tests/test_055_init.py +0 -0
  94. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/tests/test_055_profile_loading.py +0 -0
  95. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/tests/test_055_profiles.py +0 -0
  96. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/tests/test_055_recipes.py +0 -0
  97. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/tests/test_055_schema_lock.py +0 -0
  98. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/tests/test_055_templates.py +0 -0
  99. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/tests/test_055_upgrade.py +0 -0
  100. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/tests/test_actions.py +0 -0
  101. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/tests/test_agent_error_guide.py +0 -0
  102. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/tests/test_agents.py +0 -0
  103. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/tests/test_aidlc.py +0 -0
  104. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/tests/test_build_viz_page.py +0 -0
  105. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/tests/test_cli.py +0 -0
  106. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/tests/test_config.py +0 -0
  107. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/tests/test_containers.py +0 -0
  108. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/tests/test_copilot_auth.py +0 -0
  109. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/tests/test_copilot_cli.py +0 -0
  110. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/tests/test_deps.py +0 -0
  111. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/tests/test_dry_run.py +0 -0
  112. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/tests/test_e2e_fixtures.py +0 -0
  113. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/tests/test_egress_proxy.py +0 -0
  114. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/tests/test_graph.py +0 -0
  115. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/tests/test_hostboundary.py +0 -0
  116. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/tests/test_hostboundary_integration.py +0 -0
  117. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/tests/test_isolation.py +0 -0
  118. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/tests/test_isolation_integration.py +0 -0
  119. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/tests/test_isolation_pbt.py +0 -0
  120. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/tests/test_llm.py +0 -0
  121. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/tests/test_loaders.py +0 -0
  122. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/tests/test_module_contract.py +0 -0
  123. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/tests/test_outputs.py +0 -0
  124. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/tests/test_outputs_pbt.py +0 -0
  125. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/tests/test_proc.py +0 -0
  126. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/tests/test_provider_wire.py +0 -0
  127. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/tests/test_publish.py +0 -0
  128. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/tests/test_qa_prompt.py +0 -0
  129. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/tests/test_registry.py +0 -0
  130. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/tests/test_repo_ascii.py +0 -0
  131. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/tests/test_results.py +0 -0
  132. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/tests/test_run_status.py +0 -0
  133. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/tests/test_runs_js_filters.py +0 -0
  134. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/tests/test_runs_js_key_stats.py +0 -0
  135. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/tests/test_runs_js_metrics.py +0 -0
  136. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/tests/test_runs_layout.py +0 -0
  137. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/tests/test_runs_layout_key_stats.py +0 -0
  138. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/tests/test_sdk_compat.py +0 -0
  139. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/tests/test_secrets.py +0 -0
  140. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/tests/test_secrets_integration.py +0 -0
  141. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/tests/test_secrets_pipeline.py +0 -0
  142. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/tests/test_source_resolution.py +0 -0
  143. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/tests/test_stages.py +0 -0
  144. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/tests/test_step_workspace.py +0 -0
  145. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/tests/test_sync_back.py +0 -0
  146. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/tests/test_unit11_pbt.py +0 -0
  147. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/tests/test_unit12_reporting.py +0 -0
  148. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/tests/test_unit13_runs_viz.py +0 -0
  149. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/tests/test_unit5_config.py +0 -0
  150. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/tests/test_unit5_pbt.py +0 -0
  151. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/tests/test_unit5_pure.py +0 -0
  152. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/tests/test_verdict.py +0 -0
  153. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/tests/test_viz.py +0 -0
  154. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/tests/test_viz_demo.py +0 -0
  155. {agentic_dev_loop-0.15.3 → agentic_dev_loop-0.15.4}/tests/test_viz_layout.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: agentic-dev-loop
3
- Version: 0.15.3
3
+ Version: 0.15.4
4
4
  Summary: Turn an LLM into a gated, sandboxed, resumable construction loop over your codebase.
5
5
  Author: Luke Wilson
6
6
  License-Expression: Apache-2.0
@@ -562,10 +562,11 @@ Conventions that make a good agent file:
562
562
  - **dev enumerates its impossible set and stops at it.** List the commands
563
563
  the sandbox cannot run (offline package fetches, browser downloads), one
564
564
  attempt per command - keeps the productive loop and kills doomed retries.
565
- - **Failure output returns as *Previous attempt feedback*.** Steps route
566
- `on_fail: { goto: dev, retry: true }`, so gate failure output lands in the
567
- dev agent's next context; the dev prompt makes every listed issue a
568
- required fix.
565
+ - **Failure output is a required fix in dev's next context.** Agent verdict
566
+ steps land their failing output under *Previous attempt feedback*; command
567
+ gates (test, restore) land it under *Mechanical gate output*, with the exit
568
+ code under *Verified state*. Steps route `on_fail: { goto: dev, retry: true }`,
569
+ and the dev prompt makes every listed failure a required fix.
569
570
  - **No git mutations, ever.** The `commit` step is the single commit point.
570
571
 
571
572
  ### The pipeline file
@@ -515,10 +515,11 @@ Conventions that make a good agent file:
515
515
  - **dev enumerates its impossible set and stops at it.** List the commands
516
516
  the sandbox cannot run (offline package fetches, browser downloads), one
517
517
  attempt per command - keeps the productive loop and kills doomed retries.
518
- - **Failure output returns as *Previous attempt feedback*.** Steps route
519
- `on_fail: { goto: dev, retry: true }`, so gate failure output lands in the
520
- dev agent's next context; the dev prompt makes every listed issue a
521
- required fix.
518
+ - **Failure output is a required fix in dev's next context.** Agent verdict
519
+ steps land their failing output under *Previous attempt feedback*; command
520
+ gates (test, restore) land it under *Mechanical gate output*, with the exit
521
+ code under *Verified state*. Steps route `on_fail: { goto: dev, retry: true }`,
522
+ and the dev prompt makes every listed failure a required fix.
522
523
  - **No git mutations, ever.** The `commit` step is the single commit point.
523
524
 
524
525
  ### The pipeline file
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "agentic-dev-loop"
7
- version = "0.15.3"
7
+ version = "0.15.4"
8
8
  description = "Turn an LLM into a gated, sandboxed, resumable construction loop over your codebase."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.12"
@@ -10,10 +10,11 @@ opinionated LangGraph + OpenHands SDK pipeline engine written in Python.
10
10
  ## WORKFLOW
11
11
 
12
12
  1. Read the plan documents and README.md in the context below.
13
- 2. If the context contains a *Previous attempt feedback* section, treat every
14
- issue listed there as a required fix from the pipeline's earlier stages -
15
- address each one before anything else, and verify each fix landed (re-read
16
- the edited file) before moving on.
13
+ 2. If the context contains a *Previous attempt feedback* section or a
14
+ *Mechanical gate output* section, treat every issue listed there as a
15
+ required fix from the pipeline's earlier stages - address each one before
16
+ anything else, and verify each fix landed (re-read the edited file) before
17
+ moving on. A mechanical entry names the attempt that produced it.
17
18
  3. Check for prior-attempt residue before implementing. The pipeline syncs
18
19
  every lane's edits back into this repo's working tree after each terminal
19
20
  action, so an earlier attempt that died at a later gate can leave the full
@@ -66,10 +67,23 @@ opinionated LangGraph + OpenHands SDK pipeline engine written in Python.
66
67
  exit code alone.
67
68
  - You do not need to prove anything here: fill in the verification matrix,
68
69
  write your final response, and stop.
69
- - If the gate fails, you are retried with the failing output in your notes
70
- under *Previous attempt feedback*. Find the root cause - a regression in
71
- your change, a stale test pinning old behavior, or a genuine library bug -
72
- and fix it, never the symptom.
70
+ - If the gate fails, you are retried with the failing output under
71
+ *Mechanical gate output* and the exit code under *Verified state* (command
72
+ gates do not write *Previous attempt feedback*). Find the root cause - a
73
+ regression in your change, a stale test pinning old behavior, or a genuine
74
+ library bug - and fix it, never the symptom.
75
+
76
+ ## AUDIT GATE
77
+
78
+ - The restore step re-runs the install and a dependency audit on every pass.
79
+ A failing audit means a pin in the dependency manifest carries known CVEs;
80
+ it is a required fix, never "pre-existing" or "unrelated".
81
+ - Fix it with a manifest edit, never a package-manager command (agent steps
82
+ are offline). Follow the floor-pin pattern: pin the vulnerable resolved
83
+ package to a CVE-free version, or pin the intermediate package to the last
84
+ release that admits it, so a fresh resolve lands on the fixed version.
85
+ - Restore re-audits the bumped pins on the next pass, so the loop
86
+ self-corrects; report the audit as fixed only after that gate passes.
73
87
 
74
88
  ## TEST-FIRST
75
89
 
@@ -81,7 +95,8 @@ opinionated LangGraph + OpenHands SDK pipeline engine written in Python.
81
95
 
82
96
  - The moment your final response is written AND the full suite has passed
83
97
  locally (`.venv-sandbox/bin/python -m pytest tests/ -q` exits 0) AND every
84
- *Previous attempt feedback* item is addressed, the step is COMPLETE. Stop.
98
+ *Previous attempt feedback* and *Mechanical gate output* item is addressed,
99
+ the step is COMPLETE. Stop.
85
100
  - Do not re-read files, re-run checks, or `cat`/`tail`/`grep` files you just
86
101
  wrote to confirm what already passed. A green suite is a green suite:
87
102
  re-running it buys nothing, since the mechanical test gate re-runs the
@@ -446,7 +446,10 @@ def build_context(runtime: Runtime, docs: dict[str, str], subject: str,
446
446
  own mechanical section (process fact, never an agent claim), and only
447
447
  engine-verified facts (command exit codes, brief coverage, commit outcome)
448
448
  appear in the verified section. Nothing in the claims section is ever
449
- routed on."""
449
+ routed on. The mechanical heading binds every failure it carries as a
450
+ required fix: command gates (test, restore) never write the notes channel,
451
+ so without that binding a retried dev agent has no required-fix trigger
452
+ (plan 065)."""
450
453
  parts = [f"You are working on {subject}.\n", guide_section()]
451
454
  for name, content in docs.items():
452
455
  parts.append(f"## {name}\n\n{content}")
@@ -470,7 +473,8 @@ def build_context(runtime: Runtime, docs: dict[str, str], subject: str,
470
473
  parts.extend(claims)
471
474
  if mechanical_notes:
472
475
  parts.append("## Mechanical gate output "
473
- "(pipeline-captured process output, not agent claims)")
476
+ "(pipeline-captured process output, not agent claims; "
477
+ "each failure here is a required fix)")
474
478
  parts.extend(mechanical_notes)
475
479
  verified_lines = [f"- {name}: {fact}" for name, fact in (verified or {}).items()]
476
480
  parts.append(
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: agentic-dev-loop
3
- Version: 0.15.3
3
+ Version: 0.15.4
4
4
  Summary: Turn an LLM into a gated, sandboxed, resumable construction loop over your codebase.
5
5
  Author: Luke Wilson
6
6
  License-Expression: Apache-2.0
@@ -562,10 +562,11 @@ Conventions that make a good agent file:
562
562
  - **dev enumerates its impossible set and stops at it.** List the commands
563
563
  the sandbox cannot run (offline package fetches, browser downloads), one
564
564
  attempt per command - keeps the productive loop and kills doomed retries.
565
- - **Failure output returns as *Previous attempt feedback*.** Steps route
566
- `on_fail: { goto: dev, retry: true }`, so gate failure output lands in the
567
- dev agent's next context; the dev prompt makes every listed issue a
568
- required fix.
565
+ - **Failure output is a required fix in dev's next context.** Agent verdict
566
+ steps land their failing output under *Previous attempt feedback*; command
567
+ gates (test, restore) land it under *Mechanical gate output*, with the exit
568
+ code under *Verified state*. Steps route `on_fail: { goto: dev, retry: true }`,
569
+ and the dev prompt makes every listed failure a required fix.
569
570
  - **No git mutations, ever.** The `commit` step is the single commit point.
570
571
 
571
572
  ### The pipeline file
@@ -8,6 +8,7 @@ instead of reading as a clean pass.
8
8
 
9
9
  import dataclasses
10
10
  import json
11
+ from pathlib import Path
11
12
  from types import SimpleNamespace
12
13
 
13
14
  import pytest
@@ -30,6 +31,7 @@ from agentic_dev_loop.engine.completion import (classify_completion,
30
31
  count_actions)
31
32
  from agentic_dev_loop.engine.dryrun import _validate_agents
32
33
  from agentic_dev_loop.engine.graph import build_graph
34
+ from agentic_dev_loop.engine.onboarding.templates import load_template
33
35
  from agentic_dev_loop.engine.provider_wire import (WireShapeError,
34
36
  merge_choices,
35
37
  validate_finish_shape,
@@ -450,7 +452,8 @@ class TestMechanicalOutputChannel:
450
452
  verified=update["verified_state"])
451
453
  claims = "## Stage artifacts (each agent's own claims, not verified)"
452
454
  mechanical = ("## Mechanical gate output "
453
- "(pipeline-captured process output, not agent claims)")
455
+ "(pipeline-captured process output, not agent claims; "
456
+ "each failure here is a required fix)")
454
457
  verified = "## Verified state (mechanically checked by the pipeline)"
455
458
  assert claims in ctx and mechanical in ctx
456
459
  claims_section = ctx[ctx.index(claims):ctx.index(mechanical)]
@@ -463,6 +466,40 @@ class TestMechanicalOutputChannel:
463
466
  ctx = build_context(runtime, {}, "s", notes=["agent prose note"])
464
467
  assert "## Mechanical gate output" not in ctx
465
468
 
469
+ def test_mechanical_heading_binds_failures_as_required_fixes(self, runtime):
470
+ _rt, update = self._run_failing_command(runtime)
471
+ ctx = build_context(runtime, {}, "s",
472
+ mechanical_notes=update["mechanical_notes"],
473
+ verified=update["verified_state"])
474
+ heading = next(line for line in ctx.splitlines()
475
+ if line.startswith("## Mechanical gate output"))
476
+ assert "required fix" in heading
477
+
478
+
479
+ class TestDevAuditContract:
480
+ """Plan 065: the dev prompt binds a failing mechanical or audit gate to
481
+ dev, and the two copies of the contract stay in sync."""
482
+
483
+ @staticmethod
484
+ def _texts():
485
+ repo = Path(__file__).parent.parent
486
+ return [
487
+ (repo / "agentic-dev-loop" / "sdk_agents" / "dev.agent.md")
488
+ .read_text(encoding="utf-8"),
489
+ load_template("dev.agent.md"),
490
+ ]
491
+
492
+ def test_contract_names_both_required_fix_channels(self):
493
+ for text in self._texts():
494
+ assert "*Mechanical gate output*" in text
495
+ assert "*Previous attempt feedback*" in text
496
+ assert "failing output in your notes" not in text
497
+
498
+ def test_contract_has_an_audit_gate_section(self):
499
+ for text in self._texts():
500
+ assert "## AUDIT GATE" in text
501
+ assert "floor-pin" in text.lower()
502
+
466
503
 
467
504
  class TestVerifiedStateAge:
468
505
  """m4: a verified fact carries the attempt that produced it, so attempt 1's