agentic-dev-loop 1.0.0a12__tar.gz → 1.0.0a14__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.

Potentially problematic release.


This version of agentic-dev-loop might be problematic. Click here for more details.

Files changed (75) hide show
  1. {agentic_dev_loop-1.0.0a12 → agentic_dev_loop-1.0.0a14}/PKG-INFO +59 -57
  2. {agentic_dev_loop-1.0.0a12 → agentic_dev_loop-1.0.0a14}/README.md +56 -56
  3. {agentic_dev_loop-1.0.0a12 → agentic_dev_loop-1.0.0a14}/pyproject.toml +7 -1
  4. {agentic_dev_loop-1.0.0a12 → agentic_dev_loop-1.0.0a14}/src/agentic_dev_loop/core/config.py +15 -9
  5. {agentic_dev_loop-1.0.0a12 → agentic_dev_loop-1.0.0a14}/src/agentic_dev_loop/core/results.py +1 -1
  6. {agentic_dev_loop-1.0.0a12 → agentic_dev_loop-1.0.0a14}/src/agentic_dev_loop/core/verdict.py +7 -7
  7. agentic_dev_loop-1.0.0a14/src/agentic_dev_loop/engine/__init__.py +2 -0
  8. {agentic_dev_loop-1.0.0a12 → agentic_dev_loop-1.0.0a14}/src/agentic_dev_loop/engine/actions.py +13 -13
  9. {agentic_dev_loop-1.0.0a12 → agentic_dev_loop-1.0.0a14}/src/agentic_dev_loop/engine/agents.py +8 -8
  10. {agentic_dev_loop-1.0.0a12 → agentic_dev_loop-1.0.0a14}/src/agentic_dev_loop/engine/cli.py +13 -8
  11. {agentic_dev_loop-1.0.0a12 → agentic_dev_loop-1.0.0a14}/src/agentic_dev_loop/engine/deps.py +5 -5
  12. {agentic_dev_loop-1.0.0a12 → agentic_dev_loop-1.0.0a14}/src/agentic_dev_loop/engine/dryrun.py +5 -5
  13. {agentic_dev_loop-1.0.0a12 → agentic_dev_loop-1.0.0a14}/src/agentic_dev_loop/engine/extensions/aidlc.py +10 -10
  14. {agentic_dev_loop-1.0.0a12 → agentic_dev_loop-1.0.0a14}/src/agentic_dev_loop/engine/graph.py +11 -11
  15. {agentic_dev_loop-1.0.0a12 → agentic_dev_loop-1.0.0a14}/src/agentic_dev_loop/engine/hostboundary.py +10 -10
  16. {agentic_dev_loop-1.0.0a12 → agentic_dev_loop-1.0.0a14}/src/agentic_dev_loop/engine/isolation.py +97 -54
  17. {agentic_dev_loop-1.0.0a12 → agentic_dev_loop-1.0.0a14}/src/agentic_dev_loop/engine/llm.py +1 -1
  18. {agentic_dev_loop-1.0.0a12 → agentic_dev_loop-1.0.0a14}/src/agentic_dev_loop/engine/loaders.py +47 -6
  19. {agentic_dev_loop-1.0.0a12 → agentic_dev_loop-1.0.0a14}/src/agentic_dev_loop/engine/outputs.py +2 -2
  20. {agentic_dev_loop-1.0.0a12 → agentic_dev_loop-1.0.0a14}/src/agentic_dev_loop/engine/proc.py +5 -5
  21. {agentic_dev_loop-1.0.0a12 → agentic_dev_loop-1.0.0a14}/src/agentic_dev_loop/engine/registry.py +21 -21
  22. agentic_dev_loop-1.0.0a14/src/agentic_dev_loop/engine/seccomp/__init__.py +27 -0
  23. agentic_dev_loop-1.0.0a14/src/agentic_dev_loop/engine/seccomp/chromium-userns.json +190 -0
  24. {agentic_dev_loop-1.0.0a12 → agentic_dev_loop-1.0.0a14}/src/agentic_dev_loop/engine/secrets.py +4 -4
  25. {agentic_dev_loop-1.0.0a12 → agentic_dev_loop-1.0.0a14}/src/agentic_dev_loop/engine/stages.py +21 -21
  26. {agentic_dev_loop-1.0.0a12 → agentic_dev_loop-1.0.0a14}/src/agentic_dev_loop/viz/__init__.py +1 -1
  27. {agentic_dev_loop-1.0.0a12 → agentic_dev_loop-1.0.0a14}/src/agentic_dev_loop/viz/__main__.py +1 -1
  28. {agentic_dev_loop-1.0.0a12 → agentic_dev_loop-1.0.0a14}/src/agentic_dev_loop/viz/server.py +11 -11
  29. {agentic_dev_loop-1.0.0a12 → agentic_dev_loop-1.0.0a14}/src/agentic_dev_loop.egg-info/PKG-INFO +59 -57
  30. {agentic_dev_loop-1.0.0a12 → agentic_dev_loop-1.0.0a14}/src/agentic_dev_loop.egg-info/SOURCES.txt +3 -0
  31. {agentic_dev_loop-1.0.0a12 → agentic_dev_loop-1.0.0a14}/src/agentic_dev_loop.egg-info/requires.txt +2 -0
  32. {agentic_dev_loop-1.0.0a12 → agentic_dev_loop-1.0.0a14}/tests/test_actions.py +15 -15
  33. {agentic_dev_loop-1.0.0a12 → agentic_dev_loop-1.0.0a14}/tests/test_agents.py +4 -4
  34. {agentic_dev_loop-1.0.0a12 → agentic_dev_loop-1.0.0a14}/tests/test_aidlc.py +23 -19
  35. {agentic_dev_loop-1.0.0a12 → agentic_dev_loop-1.0.0a14}/tests/test_cli.py +53 -4
  36. {agentic_dev_loop-1.0.0a12 → agentic_dev_loop-1.0.0a14}/tests/test_config.py +14 -3
  37. {agentic_dev_loop-1.0.0a12 → agentic_dev_loop-1.0.0a14}/tests/test_deps.py +1 -1
  38. {agentic_dev_loop-1.0.0a12 → agentic_dev_loop-1.0.0a14}/tests/test_dry_run.py +3 -3
  39. {agentic_dev_loop-1.0.0a12 → agentic_dev_loop-1.0.0a14}/tests/test_e2e_fixtures.py +13 -13
  40. {agentic_dev_loop-1.0.0a12 → agentic_dev_loop-1.0.0a14}/tests/test_graph.py +7 -7
  41. {agentic_dev_loop-1.0.0a12 → agentic_dev_loop-1.0.0a14}/tests/test_hostboundary_integration.py +1 -1
  42. {agentic_dev_loop-1.0.0a12 → agentic_dev_loop-1.0.0a14}/tests/test_isolation.py +129 -15
  43. {agentic_dev_loop-1.0.0a12 → agentic_dev_loop-1.0.0a14}/tests/test_isolation_integration.py +13 -6
  44. {agentic_dev_loop-1.0.0a12 → agentic_dev_loop-1.0.0a14}/tests/test_isolation_pbt.py +1 -1
  45. {agentic_dev_loop-1.0.0a12 → agentic_dev_loop-1.0.0a14}/tests/test_llm.py +4 -4
  46. agentic_dev_loop-1.0.0a14/tests/test_loaders.py +227 -0
  47. {agentic_dev_loop-1.0.0a12 → agentic_dev_loop-1.0.0a14}/tests/test_outputs.py +5 -5
  48. {agentic_dev_loop-1.0.0a12 → agentic_dev_loop-1.0.0a14}/tests/test_outputs_pbt.py +2 -2
  49. {agentic_dev_loop-1.0.0a12 → agentic_dev_loop-1.0.0a14}/tests/test_proc.py +5 -5
  50. {agentic_dev_loop-1.0.0a12 → agentic_dev_loop-1.0.0a14}/tests/test_publish.py +1 -1
  51. {agentic_dev_loop-1.0.0a12 → agentic_dev_loop-1.0.0a14}/tests/test_registry.py +1 -1
  52. agentic_dev_loop-1.0.0a14/tests/test_repo_ascii.py +56 -0
  53. {agentic_dev_loop-1.0.0a12 → agentic_dev_loop-1.0.0a14}/tests/test_sdk_compat.py +7 -7
  54. {agentic_dev_loop-1.0.0a12 → agentic_dev_loop-1.0.0a14}/tests/test_secrets_pipeline.py +1 -1
  55. {agentic_dev_loop-1.0.0a12 → agentic_dev_loop-1.0.0a14}/tests/test_source_resolution.py +2 -2
  56. {agentic_dev_loop-1.0.0a12 → agentic_dev_loop-1.0.0a14}/tests/test_stages.py +6 -6
  57. {agentic_dev_loop-1.0.0a12 → agentic_dev_loop-1.0.0a14}/tests/test_trigger_script.py +81 -1
  58. {agentic_dev_loop-1.0.0a12 → agentic_dev_loop-1.0.0a14}/tests/test_verdict.py +12 -12
  59. {agentic_dev_loop-1.0.0a12 → agentic_dev_loop-1.0.0a14}/tests/test_viz.py +4 -4
  60. agentic_dev_loop-1.0.0a12/src/agentic_dev_loop/engine/__init__.py +0 -2
  61. agentic_dev_loop-1.0.0a12/tests/test_loaders.py +0 -118
  62. {agentic_dev_loop-1.0.0a12 → agentic_dev_loop-1.0.0a14}/LICENSE +0 -0
  63. {agentic_dev_loop-1.0.0a12 → agentic_dev_loop-1.0.0a14}/setup.cfg +0 -0
  64. {agentic_dev_loop-1.0.0a12 → agentic_dev_loop-1.0.0a14}/src/agentic_dev_loop/__init__.py +0 -0
  65. {agentic_dev_loop-1.0.0a12 → agentic_dev_loop-1.0.0a14}/src/agentic_dev_loop/core/__init__.py +0 -0
  66. {agentic_dev_loop-1.0.0a12 → agentic_dev_loop-1.0.0a14}/src/agentic_dev_loop/engine/extensions/__init__.py +0 -0
  67. {agentic_dev_loop-1.0.0a12 → agentic_dev_loop-1.0.0a14}/src/agentic_dev_loop/py.typed +0 -0
  68. {agentic_dev_loop-1.0.0a12 → agentic_dev_loop-1.0.0a14}/src/agentic_dev_loop.egg-info/dependency_links.txt +0 -0
  69. {agentic_dev_loop-1.0.0a12 → agentic_dev_loop-1.0.0a14}/src/agentic_dev_loop.egg-info/entry_points.txt +0 -0
  70. {agentic_dev_loop-1.0.0a12 → agentic_dev_loop-1.0.0a14}/src/agentic_dev_loop.egg-info/top_level.txt +0 -0
  71. {agentic_dev_loop-1.0.0a12 → agentic_dev_loop-1.0.0a14}/tests/test_hostboundary.py +0 -0
  72. {agentic_dev_loop-1.0.0a12 → agentic_dev_loop-1.0.0a14}/tests/test_module_contract.py +0 -0
  73. {agentic_dev_loop-1.0.0a12 → agentic_dev_loop-1.0.0a14}/tests/test_results.py +0 -0
  74. {agentic_dev_loop-1.0.0a12 → agentic_dev_loop-1.0.0a14}/tests/test_secrets.py +0 -0
  75. {agentic_dev_loop-1.0.0a12 → agentic_dev_loop-1.0.0a14}/tests/test_secrets_integration.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: agentic-dev-loop
3
- Version: 1.0.0a12
3
+ Version: 1.0.0a14
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
@@ -32,18 +32,20 @@ Requires-Dist: openhands-tools~=1.17.0
32
32
  Requires-Dist: agent-client-protocol<1.0.0
33
33
  Requires-Dist: langgraph>=1.2
34
34
  Requires-Dist: langgraph-checkpoint-sqlite>=3.0
35
+ Requires-Dist: filelock>=4.2.1
35
36
  Provides-Extra: dev
36
37
  Requires-Dist: hypothesis>=6.0; extra == "dev"
37
38
  Requires-Dist: pytest>=8.0; extra == "dev"
38
39
  Requires-Dist: pip-audit>=2.0; extra == "dev"
40
+ Requires-Dist: pre-commit>=3.0; extra == "dev"
39
41
  Dynamic: license-file
40
42
 
41
43
  # agentic-dev-loop
42
44
 
43
45
  > **Turn an LLM into a gated, sandboxed, resumable construction loop over your codebase.**
44
46
 
45
- Describe your pipeline in one YAML file — agent steps, mechanical test gates, and
46
- trusted actions — and `agentic-dev-loop` runs it end to end: agent and command steps get
47
+ Describe your pipeline in one YAML file - agent steps, mechanical test gates, and
48
+ trusted actions - and `agentic-dev-loop` runs it end to end: agent and command steps get
47
49
  kernel-level sandboxing via Docker, verdicts route the graph, every boundary is
48
50
  checkpointed, and nothing gets committed until every gate passes.
49
51
 
@@ -56,7 +58,7 @@ flowchart LR
56
58
  ```
57
59
 
58
60
  - **A tool, not a wiring project.** One CLI entry point, opinionated defaults,
59
- fixed safety policies. You write the pipeline and the agent definitions —
61
+ fixed safety policies. You write the pipeline and the agent definitions -
60
62
  nothing else.
61
63
  - **Deterministic.** Same pipeline + same state → same routing. Verdicts are
62
64
  parsed from files, retries are bounded, nothing is best-effort.
@@ -69,9 +71,9 @@ flowchart LR
69
71
 
70
72
  | Feature | What it gives you |
71
73
  | --- | --- |
72
- | **Stage-gated agent loop** | Agents do the work, test stages verify it, and the pipeline only advances when each stage passes its gates — looping back with full context when one fails. |
73
- | **Kernel-level sandboxing** | Agent work and command stages run isolated from your machine: [no network access **by default** — authors opt specific stages in](#per-stage-networking), no writes outside your workspace. No sandbox available → the run stops instead of degrading. |
74
- | **Crash-safe resume** | Interrupt a run at any time and pick it up later — finished stages stay finished, and you resume from exactly where it stopped. |
74
+ | **Stage-gated agent loop** | Agents do the work, test stages verify it, and the pipeline only advances when each stage passes its gates - looping back with full context when one fails. |
75
+ | **Kernel-level sandboxing** | Agent work and command stages run isolated from your machine: [no network access **by default** - authors opt specific stages in](#per-stage-networking), no writes outside your workspace. No sandbox available → the run stops instead of degrading. |
76
+ | **Crash-safe resume** | Interrupt a run at any time and pick it up later - finished stages stay finished, and you resume from exactly where it stopped. |
75
77
  | **Live graph visualisation** | Follow every run in the browser: stage status, pass/fail verdicts, retry cycles, and live console output as it happens. |
76
78
  | **Extensible** | Plug in your own actions, tools, and document loaders to adapt the loop to your projects. |
77
79
 
@@ -87,8 +89,8 @@ LLM timeout (agent runs are long).
87
89
  | Requirement | Detail |
88
90
  | --- | --- |
89
91
  | Python | ≥ 3.12 |
90
- | Docker engine | Engine API ≥ 1.43 (Engine 24). Any compliant engine works — Docker Desktop, OrbStack, Colima, Rancher Desktop, podman docker-compat. On Windows, Linux-containers mode is required. |
91
- | LLM API key | The env var named by your pipeline's `api_key_env` (e.g. `OPENAI_API_KEY`) must be set — a missing key fails fast, naming it. |
92
+ | Docker engine | Engine API ≥ 1.43 (Engine 24). Any compliant engine works - Docker Desktop, OrbStack, Colima, Rancher Desktop, podman docker-compat. On Windows, Linux-containers mode is required. |
93
+ | LLM API key | The env var named by your pipeline's `api_key_env` (e.g. `OPENAI_API_KEY`) must be set - a missing key fails fast, naming it. |
92
94
 
93
95
  ```bash
94
96
  pip install "agentic-dev-loop==1.0.0a9"
@@ -96,14 +98,14 @@ agentic-dev-loop --version
96
98
  ```
97
99
 
98
100
  The canonical consumer install is **pipx**, which puts the engine's venv
99
- *outside* the workspace — the sandbox mount set is exactly `{workspace}`, so an
101
+ *outside* the workspace - the sandbox mount set is exactly `{workspace}`, so an
100
102
  out-of-workspace install is unmounted and never agent-writable:
101
103
 
102
104
  ```bash
103
105
  pipx install "agentic-dev-loop==1.0.0a9"
104
106
  ```
105
107
 
106
- If you install with `uv` shortly after a release, pass `--refresh` — PyPI
108
+ If you install with `uv` shortly after a release, pass `--refresh` - PyPI
107
109
  serves the package index with `Cache-Control: max-age=600`, and uv otherwise
108
110
  reuses a pre-upload snapshot of the index for up to 10 minutes, reporting
109
111
  "no version of agentic-dev-loop==X.Y.Z" for a version that is already live:
@@ -113,7 +115,7 @@ uv pip install --refresh "agentic-dev-loop==1.0.0a9"
113
115
  ```
114
116
 
115
117
  On the first run the engine pulls the **digest-pinned** dev image
116
- (`ghcr.io/lukedawilson/agentic-dev-loop/dev`) and verifies its digest — the
118
+ (`ghcr.io/lukedawilson/agentic-dev-loop/dev`) and verifies its digest - the
117
119
  supply-chain check refuses to continue on a mismatch. If you're running
118
120
  pre-publish tooling, point `AGENTIC_DEV_LOOP_DEV_IMAGE` at your locally built
119
121
  image. Engine setup, first-run details, the full `pipeline.yaml` contract, and
@@ -125,7 +127,7 @@ troubleshooting for every fail-fast code live in
125
127
  ```bash
126
128
  export OPENAI_API_KEY=... # whatever api_key_env names
127
129
  agentic-dev-loop pipeline.yaml # run it
128
- agentic-dev-loop pipeline.yaml --dry-run # validate first — no LLM, no Docker
130
+ agentic-dev-loop pipeline.yaml --dry-run # validate first - no LLM, no Docker
129
131
  agentic-dev-loop pipeline.yaml --resume <thread-id> --max-attempts 5
130
132
  ```
131
133
 
@@ -137,23 +139,23 @@ agentic-dev-loop pipeline.yaml --resume <thread-id> --max-attempts 5
137
139
  | `--refresh` | Force re-provision of every `setup:` hook (bypasses the stamp cache). |
138
140
  | `--clean-stamps` | Delete cached provision stamps and exit. |
139
141
  | `--no-viz` / `--viz-port <port>` | Suppress the live graph view / set a preferred port (default 8321; falls back to a free port when busy). |
140
- | extension flags | Document-loader flags (e.g. `--plan`, `--aidlc-unit`) appear once the pipeline's extensions are loaded — `agentic-dev-loop PIPELINE --help` shows them. |
142
+ | extension flags | Document-loader flags (e.g. `--plan`, `--aidlc-unit`) appear once the pipeline's extensions are loaded - `agentic-dev-loop PIPELINE --help` shows them. |
141
143
 
142
144
  Exit code is `0` on pipeline success, `1` otherwise.
143
145
 
144
146
  **What a run looks like** (the shipped self-loop example):
145
147
 
146
- ![The live graph view — pipeline stages with verdict badges, retry cycles, and per-stage consoles](docs/viz-screenshot.png)
148
+ ![The live graph view - pipeline stages with verdict badges, retry cycles, and per-stage consoles](docs/viz-screenshot.png)
147
149
 
148
- 1. **dev** — the dev agent works with full context (loaded docs + shared files).
150
+ 1. **dev** - the dev agent works with full context (loaded docs + shared files).
149
151
  Its edits are untracked; only declared `produces:` files are hygiene-tracked.
150
- 2. **test** — a mechanical command step runs the suite inside the sandbox.
152
+ 2. **test** - a mechanical command step runs the suite inside the sandbox.
151
153
  Exit 0 moves on; anything else rewinds to `dev` with the failing output.
152
- 3. **review / qa** — verdict agents write artifacts whose `VERDICT:` lines route
154
+ 3. **review / qa** - verdict agents write artifacts whose `VERDICT:` lines route
153
155
  the graph. `fail` rewinds to `dev` and consumes an attempt.
154
- 4. **commit** — the single commit point fires only when all gates passed and
156
+ 4. **commit** - the single commit point fires only when all gates passed and
155
157
  the worktree was clean at start.
156
- 5. **success** — committed; or **failure** when attempts are exhausted.
158
+ 5. **success** - committed; or **failure** when attempts are exhausted.
157
159
 
158
160
  ### pipeline.yaml reference
159
161
 
@@ -209,21 +211,21 @@ steps:
209
211
  | `agent:` / `command:` / `action:` | Exactly one per step. Agents live in `agents_dir` as `<name>.agent.md`; commands run sandboxed (mechanical, never an LLM call). `commit` is the sole host-side built-in action; consumer actions are sandbox-executed, command-shaped scripts (see [Host boundary](#host-boundary-security-model)). |
210
212
  | `produces:` / `artifact:` + `verdicts:` | Hygiene-tracked outputs vs verdict-parsed routing. The **last** `VERDICT:` line wins; stale artifacts are deleted at each attempt start. |
211
213
  | `on_pass:` / `on_fail:` | A step name, terminal `success`/`failure`, or `{goto: X, retry: true}`. No loops happen unless you write them. |
212
- | `env:` / `setup:` / `network:` | `env:` declares step vars (fixed safe base + declared vars only); `setup:` provisions the sandbox (command steps, network ON, stamp-cached); `network: true` grants egress to a command or agent step (default off) — see [Per-stage networking](#per-stage-networking). |
213
- | `secrets:` (top-level) / step `secrets:` | Declares secret **refs only — never values**; each step opts in to the refs it needs. Resolved host-side and injected into that step's exec env only. See [Secrets](#secrets--refs-only-never-values). |
214
- | `isolation:` (optional) | Configures the sandbox — image override, resource caps, `allow_git_mutations`. It can never disable it. |
215
- | `state_dir` | Defaults to `~/.agentic-dev-loop/runs/<pipeline-hash>/` — artifacts and checkpoints live outside the sandbox mount. |
216
- | `extensions_dir` | Where consumer `extensions:` modules resolve — defaults to `~/.agentic-dev-loop/extensions`, **outside** the workspace. Workspace-resident extension/tool modules are refused at load. |
214
+ | `env:` / `setup:` / `network:` | `env:` declares step vars (fixed safe base + declared vars only); `setup:` provisions the sandbox (command steps, network ON, stamp-cached); `network: true` grants egress to a command or agent step (default off) - see [Per-stage networking](#per-stage-networking). |
215
+ | `secrets:` (top-level) / step `secrets:` | Declares secret **refs only - never values**; each step opts in to the refs it needs. Resolved host-side and injected into that step's exec env only. See [Secrets](#secrets--refs-only-never-values). |
216
+ | `isolation:` (optional) | Configures the sandbox - image override, resource caps, `allow_git_mutations`. It can never disable it. |
217
+ | `state_dir` | Defaults to `~/.agentic-dev-loop/runs/<pipeline-hash>/` - artifacts and checkpoints live outside the sandbox mount. |
218
+ | `extensions_dir` | Where consumer `extensions:` modules resolve - defaults to `~/.agentic-dev-loop/extensions`, **outside** the workspace. Workspace-resident extension/tool modules are refused at load. |
217
219
  | `deps_policy` | `locked` (default) or `open`. `locked` = the human-owned lockfile is the source of truth and the agent may not add dependencies; `open` = the bootstrap protocol (the agent may add exact-pinned manifest entries). See [Dependency policy](#dependency-policy-locked-by-default). |
218
- | `lockfiles` | The pipeline's declared lockfile names (workspace-relative), injected into agent context and named by the missing-dependency fail-fast. Required (non-empty) when `deps_policy: locked` — a `locked` pipeline with no lockfiles fails fast at load. |
220
+ | `lockfiles` | The pipeline's declared lockfile names (workspace-relative), injected into agent context and named by the missing-dependency fail-fast. Required (non-empty) when `deps_policy: locked` - a `locked` pipeline with no lockfiles fails fast at load. |
219
221
 
220
- ### Secrets (`secrets:`) — refs only, never values
222
+ ### Secrets (`secrets:`) - refs only, never values
221
223
 
222
224
  Secret values never belong in the pipeline yaml, the workspace, or `state_dir`.
223
225
  Declare the refs at the top level and opt each step into the refs it needs:
224
226
 
225
227
  ```yaml
226
- secrets: # refs only — never values
228
+ secrets: # refs only - never values
227
229
  kinde-client-secret: # ref name (arbitrary)
228
230
  from: env # provider name
229
231
  key: KINDIE_CLIENT_SECRET # provider-specific locator
@@ -239,10 +241,10 @@ steps:
239
241
 
240
242
  - The engine resolves every declared ref **host-side at run start** (the `env`
241
243
  provider reads the named host environment variable). A missing variable, an
242
- unknown provider, or a ref a step lists without declaring it fails fast —
244
+ unknown provider, or a ref a step lists without declaring it fails fast -
243
245
  naming the ref, the step, and the provider error. No silent fallback.
244
246
  - A resolved secret is injected into a step's exec env **only when that step
245
- lists the ref** — the same path step `env:` uses, no new channel. The secret
247
+ lists the ref** - the same path step `env:` uses, no new channel. The secret
246
248
  never reaches the provision container, `state_dir`, or any other step.
247
249
  - Prefer a mechanical `command` step for secret-consuming work (a script runs
248
250
  the app with creds) so the LLM and the secret never meet; an `agent` step
@@ -252,15 +254,15 @@ steps:
252
254
  convention fixtures `.env.example`, `.env.template`, and `.env.sample` are
253
255
  whitelisted. This applies regardless of `network:` flags.
254
256
  - **Output scrubbing.** Resolved secret values are scrubbed from every
255
- engine-written output — captured step output, retry notes, artifacts, and
257
+ engine-written output - captured step output, retry notes, artifacts, and
256
258
  `state_dir` files. (Hygiene: the declaring step's agent has already seen
257
259
  the value in its own env.)
258
260
 
259
261
  ### Per-stage networking
260
262
 
261
- The sandbox is network-off by default. A step that legitimately needs egress —
263
+ The sandbox is network-off by default. A step that legitimately needs egress -
262
264
  a QA step that curls a service it booted, an agent that must hit an API or
263
- fetch package metadata mid-conversation — declares it explicitly:
265
+ fetch package metadata mid-conversation - declares it explicitly:
264
266
 
265
267
  ```yaml
266
268
  steps:
@@ -272,7 +274,7 @@ steps:
272
274
  - **Default off.** Every step runs with `--network none` unless it declares
273
275
  `network: true`. A networked step runs in a second, otherwise-identical
274
276
  sandbox container (`--read-only`, `--cap-drop ALL`, single workspace mount)
275
- on the Docker bridge network — the default network-none container is always
277
+ on the Docker bridge network - the default network-none container is always
276
278
  created too, so no infrastructure work happens mid-run.
277
279
  - **Command, agent, and sandbox-action steps** may declare it. The host-side
278
280
  built-in `commit` action never takes it (refused once the registry is known).
@@ -284,7 +286,7 @@ steps:
284
286
  ## Dependency policy (locked by default)
285
287
 
286
288
  The supply-chain dial is a pipeline-level `deps_policy:` field, **locked by
287
- default**. The engine injects the policy into every agent step's context —
289
+ default**. The engine injects the policy into every agent step's context -
288
290
  the rule lives in the engine, not in hand-authored `dev.agent.md` prose (the
289
291
  class of rule that deadlocked the NuGet cache).
290
292
 
@@ -293,17 +295,17 @@ deps_policy: locked # or: open (default: locked)
293
295
  lockfiles: [uv.lock] # or: [packages.lock.json, package-lock.json]
294
296
  ```
295
297
 
296
- - **`locked`** — the human-owned lockfile is the source of truth; the agent
298
+ - **`locked`** - the human-owned lockfile is the source of truth; the agent
297
299
  may not add dependencies. The injected rule says *"You may only use
298
300
  dependencies already present in `<lockfile>`. If the design requires a
299
301
  dependency that is not present, declare it in your final response under the
300
302
  fixed header `## Missing dependencies` (one `name==version` per line) and
301
303
  finish what you can. Do not add it to the manifest."* A non-empty
302
304
  `## Missing dependencies` declaration **fails the run fast** with
303
- `Extend <lockfile> with these pins and re-run: …` — one human lockfile edit,
305
+ `Extend <lockfile> with these pins and re-run: …` - one human lockfile edit,
304
306
  not a retry loop. The declaration is advisory to the human; the engine never
305
307
  auto-fetches the declared packages.
306
- - **`open`** — the bootstrap protocol (018): the agent may add exact-pinned
308
+ - **`open`** - the bootstrap protocol (018): the agent may add exact-pinned
307
309
  manifest entries directly (never a package-manager `add` command); the
308
310
  network-on restore step fetches them. The engine injects the same rule
309
311
  canonically. Nothing about `open` is default.
@@ -315,7 +317,7 @@ manifest and lockfile disagree:
315
317
  | --- | --- | --- |
316
318
  | .NET | `dotnet restore --locked-mode` | `packages.lock.json` (set `RestorePackagesWithLockFile=true`) |
317
319
  | node | `npm ci` | `package-lock.json` |
318
- | python | `uv sync --locked` (or pip-tools `pip-sync requirements.lock`) | `uv.lock` — pip has no native lockfile; `uv` is the canonical locked-install tool |
320
+ | python | `uv sync --locked` (or pip-tools `pip-sync requirements.lock`) | `uv.lock` - pip has no native lockfile; `uv` is the canonical locked-install tool |
319
321
 
320
322
  ### Audit escalation in the restore step
321
323
 
@@ -324,27 +326,27 @@ threshold:
324
326
 
325
327
  | Toolchain | Audit (fails the step) |
326
328
  | --- | --- |
327
- | .NET | `NuGetAudit` at `error` — any audit finding fails the restore |
329
+ | .NET | `NuGetAudit` at `error` - any audit finding fails the restore |
328
330
  | node | `npm audit --audit-level=high` |
329
- | python | `pip-audit` — any finding fails |
331
+ | python | `pip-audit` - any finding fails |
330
332
 
331
333
  Under `locked`, a failing audit means the lockfile pins a vulnerable version:
332
334
  the run fails and the human regenerates the lockfile at a patched version.
333
- Under `open`, the failure routes to `dev` like any restore failure — the dev
335
+ Under `open`, the failure routes to `dev` like any restore failure - the dev
334
336
  agent can bump the pin, but that pin is audited again on the next pass, so
335
337
  the loop self-corrects.
336
338
 
337
339
  ### Generating a lockfile
338
340
 
339
- A human generates the lockfile once, on a network machine, and commits it —
341
+ A human generates the lockfile once, on a network machine, and commits it -
340
342
  the engine never fetches on the agent's behalf:
341
343
 
342
344
  ```bash
343
- uv lock # python — writes uv.lock from pyproject.toml
345
+ uv lock # python - writes uv.lock from pyproject.toml
344
346
  uv sync --locked # installs exactly uv.lock; fails on any drift
345
- npm install --package-lock-only # node — writes package-lock.json
347
+ npm install --package-lock-only # node - writes package-lock.json
346
348
  npm ci # installs exactly package-lock.json
347
- dotnet restore --use-lock-file # .NET — writes packages.lock.json
349
+ dotnet restore --use-lock-file # .NET - writes packages.lock.json
348
350
  dotnet restore --locked-mode # installs exactly packages.lock.json
349
351
  ```
350
352
 
@@ -354,12 +356,12 @@ to prove it holds from a clean cache before setting `deps_policy: locked`.
354
356
  ## Host boundary (security model)
355
357
 
356
358
  The orchestrator, tool layer, and the `commit` action run in the **host
357
- process** — they hold your credentials and your full user account, so the
359
+ process** - they hold your credentials and your full user account, so the
358
360
  engine keeps anything agent-writable out of that process:
359
361
 
360
362
  - **Consumer actions are sandbox-executed.** An action you register via an
361
363
  extension is a command-shaped script (`script + params`), run through the
362
- same sandbox path as command steps — the exit code is the verdict, and the
364
+ same sandbox path as command steps - the exit code is the verdict, and the
363
365
  code never runs in the host. Only the engine's trusted built-ins (`commit`,
364
366
  document loaders) run host-side.
365
367
  - **Extensions load from outside the workspace.** `extensions_dir` defaults to
@@ -372,7 +374,7 @@ engine keeps anything agent-writable out of that process:
372
374
  everything).
373
375
  - **Tooling is read-only by the loop.** At run start the pipeline file,
374
376
  `agents_dir`, `additional_files`, `aidlc-docs/`, and `tools/` must be
375
- git-clean relative to HEAD — otherwise the run refuses, naming the dirty
377
+ git-clean relative to HEAD - otherwise the run refuses, naming the dirty
376
378
  files. The `commit` action excludes those paths from its sweep, so the loop
377
379
  never commits its own tooling.
378
380
  - **`commit` stays host-side, deliberately.** It holds push credentials; moving
@@ -387,16 +389,16 @@ the loop is building.
387
389
 
388
390
  ### Consumer migration notes
389
391
 
390
- - **Actions** — replace a host-side `fn` registration with
392
+ - **Actions** - replace a host-side `fn` registration with
391
393
  `registry.add_sandbox_action(name, script)`. `script` is a command string
392
394
  rendered with the step's `params:` plus `{subject}`; the exit code is the
393
395
  verdict. `add_action` (host-side) is now engine-built-in-only and is refused
394
396
  from extensions.
395
- - **Extensions** — move workspace-resident extension modules (e.g.
397
+ - **Extensions** - move workspace-resident extension modules (e.g.
396
398
  `extensions/*.py`) into `~/.agentic-dev-loop/extensions/` (or whatever
397
399
  `extensions_dir:` names), and reinstall the engine via pipx so it is not
398
400
  editable/in-workspace.
399
- - **Tooling** — commit the pipeline, agent defs, shared `additional_files`,
401
+ - **Tooling** - commit the pipeline, agent defs, shared `additional_files`,
400
402
  `aidlc-docs/`, and `tools/` before running: the run refuses dirty tooling,
401
403
  and `commit` never commits it.
402
404
 
@@ -410,16 +412,16 @@ export OPENAI_API_KEY=... # set your LLM key in the host env (no .env
410
412
  python -m pytest tests/ -q # fast suite (in-repo .venv is for tests only)
411
413
  python -m pytest tests/ -q -m "not docker" # skip engine-dependent tests
412
414
  agentic-dev-loop agentic-dev-loop/pipeline.yaml --dry-run # run the shipped pipeline
413
- ./run-demo.sh # viz demo — scripted run replay, no pipeline needed
415
+ ./run-demo.sh # viz demo - scripted run replay, no pipeline needed
414
416
  ```
415
417
 
416
418
  - `setup-venv.sh` builds the throwaway `.venv` for local `pytest` runs (the
417
419
  pipeline's `test` step provisions its own `.venv-sandbox` inside the
418
- sandbox). The loop itself must run from the pipx install — never an
420
+ sandbox). The loop itself must run from the pipx install - never an
419
421
  in-workspace `.venv`, which the startup self-check refuses.
420
422
  - Docker-marked integration tests need a local daemon; CI runs them on Linux.
421
423
  - The shipped pipeline (`agentic-dev-loop/pipeline.yaml`) **dogfoods the tool on
422
- its own repo** — dev → test → review → qa → commit, with the engine's own
424
+ its own repo** - dev → test → review → qa → commit, with the engine's own
423
425
  three agent definitions in `sdk_agents/`.
424
426
  - CI: `ci.yml` (unit + integration suite, ubuntu + windows),
425
427
  `publish-image.yml` (multi-arch dev image, amd64 + arm64), `release.yml`
@@ -427,10 +429,10 @@ agentic-dev-loop agentic-dev-loop/pipeline.yaml --dry-run # run the shipped pi
427
429
 
428
430
  ## Contributing
429
431
 
430
- - **Read [AGENTS.md](AGENTS.md) first** — it is the instruction set for both
432
+ - **Read [AGENTS.md](AGENTS.md) first** - it is the instruction set for both
431
433
  human and agent contributors (default mode: the user drives, ask before
432
434
  coding, TDD, no silent fallbacks).
433
- - Development is structured by **AI-DLC** — the lifecycle workflow in
435
+ - Development is structured by **AI-DLC** - the lifecycle workflow in
434
436
  `.aidlc/aidlc-rules/aws-aidlc-rules/` with working docs (plans, units, state)
435
437
  in `aidlc-docs/`. The bundled document loader autodetects the current unit
436
438
  from `aidlc-state.md` via `--aidlc-unit`, or load any plan with `--plan`.