agentic-engineering-harness 0.4.16

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 (280) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +273 -0
  3. package/dist/agents/audit.d.ts +12 -0
  4. package/dist/agents/audit.js +14 -0
  5. package/dist/agents/audit.js.map +1 -0
  6. package/dist/agents/compiler.d.ts +8 -0
  7. package/dist/agents/compiler.js +103 -0
  8. package/dist/agents/compiler.js.map +1 -0
  9. package/dist/agents/config.d.ts +6 -0
  10. package/dist/agents/config.js +161 -0
  11. package/dist/agents/config.js.map +1 -0
  12. package/dist/agents/escalation.d.ts +9 -0
  13. package/dist/agents/escalation.js +75 -0
  14. package/dist/agents/escalation.js.map +1 -0
  15. package/dist/agents/exceptionDetection.d.ts +24 -0
  16. package/dist/agents/exceptionDetection.js +42 -0
  17. package/dist/agents/exceptionDetection.js.map +1 -0
  18. package/dist/agents/findings.d.ts +14 -0
  19. package/dist/agents/findings.js +40 -0
  20. package/dist/agents/findings.js.map +1 -0
  21. package/dist/agents/gitCheckpoint.d.ts +6 -0
  22. package/dist/agents/gitCheckpoint.js +61 -0
  23. package/dist/agents/gitCheckpoint.js.map +1 -0
  24. package/dist/agents/jsonc.d.ts +1 -0
  25. package/dist/agents/jsonc.js +42 -0
  26. package/dist/agents/jsonc.js.map +1 -0
  27. package/dist/agents/outputContracts.d.ts +161 -0
  28. package/dist/agents/outputContracts.js +16 -0
  29. package/dist/agents/outputContracts.js.map +1 -0
  30. package/dist/agents/parallelism.d.ts +14 -0
  31. package/dist/agents/parallelism.js +54 -0
  32. package/dist/agents/parallelism.js.map +1 -0
  33. package/dist/agents/permissions.d.ts +5 -0
  34. package/dist/agents/permissions.js +30 -0
  35. package/dist/agents/permissions.js.map +1 -0
  36. package/dist/agents/qualityConvergence.d.ts +44 -0
  37. package/dist/agents/qualityConvergence.js +77 -0
  38. package/dist/agents/qualityConvergence.js.map +1 -0
  39. package/dist/agents/recovery.d.ts +13 -0
  40. package/dist/agents/recovery.js +35 -0
  41. package/dist/agents/recovery.js.map +1 -0
  42. package/dist/agents/reviewLifecycle.d.ts +30 -0
  43. package/dist/agents/reviewLifecycle.js +233 -0
  44. package/dist/agents/reviewLifecycle.js.map +1 -0
  45. package/dist/agents/routing.d.ts +9 -0
  46. package/dist/agents/routing.js +37 -0
  47. package/dist/agents/routing.js.map +1 -0
  48. package/dist/agents/structuredOutput.d.ts +1 -0
  49. package/dist/agents/structuredOutput.js +54 -0
  50. package/dist/agents/structuredOutput.js.map +1 -0
  51. package/dist/agents/types.d.ts +207 -0
  52. package/dist/agents/types.js +2 -0
  53. package/dist/agents/types.js.map +1 -0
  54. package/dist/cli.d.ts +2 -0
  55. package/dist/cli.js +221 -0
  56. package/dist/cli.js.map +1 -0
  57. package/dist/core/config.d.ts +3 -0
  58. package/dist/core/config.js +59 -0
  59. package/dist/core/config.js.map +1 -0
  60. package/dist/core/doctor.d.ts +8 -0
  61. package/dist/core/doctor.js +59 -0
  62. package/dist/core/doctor.js.map +1 -0
  63. package/dist/core/git.d.ts +8 -0
  64. package/dist/core/git.js +47 -0
  65. package/dist/core/git.js.map +1 -0
  66. package/dist/core/init.d.ts +1 -0
  67. package/dist/core/init.js +52 -0
  68. package/dist/core/init.js.map +1 -0
  69. package/dist/core/quick.d.ts +20 -0
  70. package/dist/core/quick.js +49 -0
  71. package/dist/core/quick.js.map +1 -0
  72. package/dist/core/repair.d.ts +8 -0
  73. package/dist/core/repair.js +7 -0
  74. package/dist/core/repair.js.map +1 -0
  75. package/dist/core/run.d.ts +38 -0
  76. package/dist/core/run.js +165 -0
  77. package/dist/core/run.js.map +1 -0
  78. package/dist/core/sdd.d.ts +10 -0
  79. package/dist/core/sdd.js +88 -0
  80. package/dist/core/sdd.js.map +1 -0
  81. package/dist/core/seal.d.ts +3 -0
  82. package/dist/core/seal.js +74 -0
  83. package/dist/core/seal.js.map +1 -0
  84. package/dist/core/triage.d.ts +22 -0
  85. package/dist/core/triage.js +38 -0
  86. package/dist/core/triage.js.map +1 -0
  87. package/dist/core/types.d.ts +354 -0
  88. package/dist/core/types.js +2 -0
  89. package/dist/core/types.js.map +1 -0
  90. package/dist/core/verify.d.ts +6 -0
  91. package/dist/core/verify.js +51 -0
  92. package/dist/core/verify.js.map +1 -0
  93. package/dist/delivery/finalize.d.ts +17 -0
  94. package/dist/delivery/finalize.js +71 -0
  95. package/dist/delivery/finalize.js.map +1 -0
  96. package/dist/delivery/handoff.d.ts +39 -0
  97. package/dist/delivery/handoff.js +250 -0
  98. package/dist/delivery/handoff.js.map +1 -0
  99. package/dist/entry.d.ts +2 -0
  100. package/dist/entry.js +112 -0
  101. package/dist/entry.js.map +1 -0
  102. package/dist/evals/runner.d.ts +4 -0
  103. package/dist/evals/runner.js +112 -0
  104. package/dist/evals/runner.js.map +1 -0
  105. package/dist/evals/scoring.d.ts +3 -0
  106. package/dist/evals/scoring.js +41 -0
  107. package/dist/evals/scoring.js.map +1 -0
  108. package/dist/evals/types.d.ts +46 -0
  109. package/dist/evals/types.js +2 -0
  110. package/dist/evals/types.js.map +1 -0
  111. package/dist/issues/intake.d.ts +114 -0
  112. package/dist/issues/intake.js +213 -0
  113. package/dist/issues/intake.js.map +1 -0
  114. package/dist/memory/benchmark.d.ts +33 -0
  115. package/dist/memory/benchmark.js +69 -0
  116. package/dist/memory/benchmark.js.map +1 -0
  117. package/dist/metrics/runMetrics.d.ts +9 -0
  118. package/dist/metrics/runMetrics.js +34 -0
  119. package/dist/metrics/runMetrics.js.map +1 -0
  120. package/dist/metrics/usage.d.ts +3 -0
  121. package/dist/metrics/usage.js +53 -0
  122. package/dist/metrics/usage.js.map +1 -0
  123. package/dist/provenance/generate.d.ts +30 -0
  124. package/dist/provenance/generate.js +96 -0
  125. package/dist/provenance/generate.js.map +1 -0
  126. package/dist/providers/engram.d.ts +8 -0
  127. package/dist/providers/engram.js +14 -0
  128. package/dist/providers/engram.js.map +1 -0
  129. package/dist/providers/graphify.d.ts +9 -0
  130. package/dist/providers/graphify.js +28 -0
  131. package/dist/providers/graphify.js.map +1 -0
  132. package/dist/providers/paseo.d.ts +8 -0
  133. package/dist/providers/paseo.js +14 -0
  134. package/dist/providers/paseo.js.map +1 -0
  135. package/dist/providers/types.d.ts +41 -0
  136. package/dist/providers/types.js +2 -0
  137. package/dist/providers/types.js.map +1 -0
  138. package/dist/telemetry/events.d.ts +2 -0
  139. package/dist/telemetry/events.js +29 -0
  140. package/dist/telemetry/events.js.map +1 -0
  141. package/dist/telemetry/otlp.d.ts +3 -0
  142. package/dist/telemetry/otlp.js +57 -0
  143. package/dist/telemetry/otlp.js.map +1 -0
  144. package/dist/toolchain/config.d.ts +10 -0
  145. package/dist/toolchain/config.js +54 -0
  146. package/dist/toolchain/config.js.map +1 -0
  147. package/dist/toolchain/doctor.d.ts +8 -0
  148. package/dist/toolchain/doctor.js +56 -0
  149. package/dist/toolchain/doctor.js.map +1 -0
  150. package/dist/toolchain/mise.d.ts +10 -0
  151. package/dist/toolchain/mise.js +61 -0
  152. package/dist/toolchain/mise.js.map +1 -0
  153. package/dist/toolchain/resolve.d.ts +8 -0
  154. package/dist/toolchain/resolve.js +159 -0
  155. package/dist/toolchain/resolve.js.map +1 -0
  156. package/dist/toolchain/setup.d.ts +7 -0
  157. package/dist/toolchain/setup.js +141 -0
  158. package/dist/toolchain/setup.js.map +1 -0
  159. package/dist/toolchain/types.d.ts +95 -0
  160. package/dist/toolchain/types.js +2 -0
  161. package/dist/toolchain/types.js.map +1 -0
  162. package/dist/utils/process.d.ts +15 -0
  163. package/dist/utils/process.js +94 -0
  164. package/dist/utils/process.js.map +1 -0
  165. package/dist/validators/commands.d.ts +2 -0
  166. package/dist/validators/commands.js +28 -0
  167. package/dist/validators/commands.js.map +1 -0
  168. package/dist/validators/constraints.d.ts +6 -0
  169. package/dist/validators/constraints.js +30 -0
  170. package/dist/validators/constraints.js.map +1 -0
  171. package/dist/validators/diffScope.d.ts +2 -0
  172. package/dist/validators/diffScope.js +36 -0
  173. package/dist/validators/diffScope.js.map +1 -0
  174. package/dist/validators/evidence.d.ts +6 -0
  175. package/dist/validators/evidence.js +8 -0
  176. package/dist/validators/evidence.js.map +1 -0
  177. package/dist/validators/external.d.ts +3 -0
  178. package/dist/validators/external.js +22 -0
  179. package/dist/validators/external.js.map +1 -0
  180. package/dist/validators/gherkin.d.ts +3 -0
  181. package/dist/validators/gherkin.js +59 -0
  182. package/dist/validators/gherkin.js.map +1 -0
  183. package/dist/validators/graphify.d.ts +4 -0
  184. package/dist/validators/graphify.js +108 -0
  185. package/dist/validators/graphify.js.map +1 -0
  186. package/dist/validators/opa.d.ts +3 -0
  187. package/dist/validators/opa.js +43 -0
  188. package/dist/validators/opa.js.map +1 -0
  189. package/dist/validators/openapi.d.ts +25 -0
  190. package/dist/validators/openapi.js +98 -0
  191. package/dist/validators/openapi.js.map +1 -0
  192. package/dist/validators/registry.d.ts +2 -0
  193. package/dist/validators/registry.js +36 -0
  194. package/dist/validators/registry.js.map +1 -0
  195. package/dist/validators/toolCommand.d.ts +5 -0
  196. package/dist/validators/toolCommand.js +33 -0
  197. package/dist/validators/toolCommand.js.map +1 -0
  198. package/dist/validators/types.d.ts +13 -0
  199. package/dist/validators/types.js +2 -0
  200. package/dist/validators/types.js.map +1 -0
  201. package/dist/workers/agentPrompt.d.ts +3 -0
  202. package/dist/workers/agentPrompt.js +84 -0
  203. package/dist/workers/agentPrompt.js.map +1 -0
  204. package/dist/workers/direct.d.ts +13 -0
  205. package/dist/workers/direct.js +30 -0
  206. package/dist/workers/direct.js.map +1 -0
  207. package/dist/workers/factory.d.ts +4 -0
  208. package/dist/workers/factory.js +10 -0
  209. package/dist/workers/factory.js.map +1 -0
  210. package/dist/workers/paseo.d.ts +14 -0
  211. package/dist/workers/paseo.js +29 -0
  212. package/dist/workers/paseo.js.map +1 -0
  213. package/dist/workers/podman.d.ts +13 -0
  214. package/dist/workers/podman.js +22 -0
  215. package/dist/workers/podman.js.map +1 -0
  216. package/dist/workers/prompt.d.ts +4 -0
  217. package/dist/workers/prompt.js +4 -0
  218. package/dist/workers/prompt.js.map +1 -0
  219. package/dist/workers/types.d.ts +11 -0
  220. package/dist/workers/types.js +2 -0
  221. package/dist/workers/types.js.map +1 -0
  222. package/docs/ARCHITECTURE.md +47 -0
  223. package/docs/EVALS.md +28 -0
  224. package/docs/MEMORY.md +28 -0
  225. package/docs/OBSERVABILITY.md +18 -0
  226. package/docs/OSS_STACK.md +27 -0
  227. package/docs/PASEO.md +9 -0
  228. package/docs/PUBLISHING.md +110 -0
  229. package/docs/SDD.md +35 -0
  230. package/docs/SECURITY.md +21 -0
  231. package/docs/V0.2.md +42 -0
  232. package/docs/V0.3.md +40 -0
  233. package/docs/V0.4.11.md +30 -0
  234. package/docs/V0.4.12.md +88 -0
  235. package/docs/V0.4.13.md +203 -0
  236. package/docs/V0.4.14.md +209 -0
  237. package/docs/V0.4.15.md +365 -0
  238. package/docs/V0.4.16.md +229 -0
  239. package/docs/V0.4.md +28 -0
  240. package/docs/VALIDATION.md +23 -0
  241. package/package.json +18 -0
  242. package/policies/core/dependency-policy.rego +12 -0
  243. package/policies/core/schema-policy.rego +12 -0
  244. package/policies/core/trust-boundary.rego +17 -0
  245. package/presets/agents/default.jsonc +80 -0
  246. package/presets/docker.yaml +4 -0
  247. package/presets/dotnet.yaml +12 -0
  248. package/presets/expo.yaml +6 -0
  249. package/presets/generic.yaml +3 -0
  250. package/presets/nextjs.yaml +8 -0
  251. package/presets/node.yaml +6 -0
  252. package/presets/pnpm.yaml +6 -0
  253. package/presets/postgres.yaml +4 -0
  254. package/schemas/agent-output-planner.schema.json +1 -0
  255. package/schemas/agent-topology.schema.json +37 -0
  256. package/schemas/project.schema.json +36 -0
  257. package/schemas/quick-contract.schema.json +17 -0
  258. package/schemas/task-contract.schema.json +18 -0
  259. package/schemas/toolchain.schema.json +70 -0
  260. package/schemas/validation-report.schema.json +15 -0
  261. package/skills/acceptance-traceability/SKILL.md +13 -0
  262. package/skills/deterministic-validation/SKILL.md +15 -0
  263. package/skills/engineering-workflow/SKILL.md +108 -0
  264. package/skills/finding-dedup/SKILL.md +12 -0
  265. package/skills/github-delivery-lifecycle/SKILL.md +16 -0
  266. package/skills/implementation-worker/SKILL.md +17 -0
  267. package/skills/lead-engineer/SKILL.md +30 -0
  268. package/skills/memory-hygiene/SKILL.md +22 -0
  269. package/skills/prompt-drift-audit/SKILL.md +10 -0
  270. package/skills/recovery-classifier/SKILL.md +13 -0
  271. package/skills/routing-normalizer/SKILL.md +17 -0
  272. package/skills/sdd/SKILL.md +21 -0
  273. package/skills/simplify/SKILL.md +16 -0
  274. package/skills/verification-planning/SKILL.md +17 -0
  275. package/skills/worktree-lifecycle/SKILL.md +18 -0
  276. package/templates/AGENTS.md +37 -0
  277. package/templates/agents.source.jsonc +39 -0
  278. package/templates/otel-collector.yaml +21 -0
  279. package/templates/project.yaml +196 -0
  280. package/templates/toolchain.yaml +127 -0
@@ -0,0 +1,365 @@
1
+ # v0.4.15 — Issue-driven execution
2
+
3
+ v0.4.15 makes an **existing GitHub issue** a first-class input to the Harness while preserving the existing trust hierarchy: the remote issue is fetched and frozen, then a sealed QuickContract or SDD/TaskContract becomes normative for the active run.
4
+
5
+ ## Goal
6
+
7
+ A user or Paseo-hosted lead can say:
8
+
9
+ > Implement issue #142.
10
+
11
+ The operational equivalent is:
12
+
13
+ ```bash
14
+ aeh issue implement 142
15
+ ```
16
+
17
+ or:
18
+
19
+ ```bash
20
+ aeh run --issue 142
21
+ ```
22
+
23
+ The user does not need to manually create an SDD, duplicate the issue, create a branch, create a worktree, select implementers, manage the review/remediation loop, or perform accepted delivery writes when deterministic finalization is enabled.
24
+
25
+ ## Lifecycle
26
+
27
+ ```text
28
+ GitHub issue
29
+ |
30
+ v
31
+ fetch + validate issue identity/state
32
+ |
33
+ v
34
+ freeze title/body + SHA-256 snapshot
35
+ |
36
+ v
37
+ intake evidence
38
+ (paths, labels/domains, risk, acceptance, flags)
39
+ |
40
+ v
41
+ read-only planner normalization when non-trivial
42
+ |
43
+ v
44
+ deterministic QUICK/SPEC decision
45
+ |
46
+ +--> QuickContract
47
+ |
48
+ `--> complete SDD + TaskContract + Gherkin
49
+ |
50
+ v
51
+ validate + seal
52
+ |
53
+ v
54
+ bind EXISTING issue to delivery state
55
+ |
56
+ v
57
+ reuse/create issue-linked branch
58
+ |
59
+ v
60
+ optional Paseo worktree
61
+ |
62
+ v
63
+ normal aeh run lifecycle
64
+ |
65
+ v
66
+ deterministic validation -> reviews -> convergence -> lead acceptance
67
+ |
68
+ v
69
+ optional deterministic commit -> push -> draft PR -> Closes #issue
70
+ ```
71
+
72
+ ## CLI
73
+
74
+ ### Inspect
75
+
76
+ ```bash
77
+ aeh issue inspect 142
78
+ ```
79
+
80
+ Fetches the issue and shows preliminary QUICK/SPEC evidence without creating a TaskContract.
81
+
82
+ ### Import/freeze
83
+
84
+ ```bash
85
+ aeh issue import 142
86
+ ```
87
+
88
+ Creates `GH-142` as a sealed task without executing implementation.
89
+
90
+ For explicit issue revision acceptance:
91
+
92
+ ```bash
93
+ aeh issue import 142 --refresh
94
+ ```
95
+
96
+ If an active Paseo delivery workspace already exists, refresh is blocked unless explicitly forced:
97
+
98
+ ```bash
99
+ aeh issue import 142 --refresh --force
100
+ ```
101
+
102
+ ### Complete execution
103
+
104
+ ```bash
105
+ aeh issue implement 142
106
+ ```
107
+
108
+ Equivalent entrypoint:
109
+
110
+ ```bash
111
+ aeh run --issue 142
112
+ ```
113
+
114
+ Optional profile:
115
+
116
+ ```bash
117
+ aeh issue implement 142 --profile maximum-quality
118
+ ```
119
+
120
+ The final CLI summary includes delivery status and the PR URL when finalization creates/reuses a PR.
121
+
122
+ ## Repository resolution
123
+
124
+ The issue repository is resolved from:
125
+
126
+ 1. `delivery.github.repository` when configured;
127
+ 2. otherwise the repository's `origin` remote.
128
+
129
+ The issue endpoint rejects GitHub pull requests returned from `/issues/<number>`; issue-driven execution is intentionally issue-specific.
130
+
131
+ Public issues may be fetched without authentication. Private repositories require a usable token. Token resolution follows the delivery configuration and environment:
132
+
133
+ ```text
134
+ configured tokenEnv
135
+ GH_TOKEN
136
+ GITHUB_TOKEN
137
+ GITHUB_PAT
138
+ ```
139
+
140
+ Tokens are never serialized into the issue snapshot, TaskContract or delivery state.
141
+
142
+ ## Frozen issue source
143
+
144
+ The Harness stores:
145
+
146
+ ```text
147
+ .harness/issues/GH-142.json
148
+ ```
149
+
150
+ with repository, issue number/URL, title/body, state, labels, timestamps and SHA-256 of normalized title/body.
151
+
152
+ The TaskContract records the same source identity and fingerprint.
153
+
154
+ Only **title and body** are treated as normative remote content for the hash. Labels can influence initial routing/triage but changing a label does not silently rewrite requirements. Comments are not incorporated into the active normative contract unless a later intake version explicitly adds that policy.
155
+
156
+ ## Planner normalization
157
+
158
+ Non-trivial issues or issues without directly extractable acceptance statements can be sent to the configured read-only planner:
159
+
160
+ ```yaml
161
+ workflow:
162
+ issueIntake:
163
+ plannerAgent: planner
164
+ ```
165
+
166
+ The planner may inspect repository code/tests/architecture to derive implementation detail and existing invariants. It returns a machine-validated intake structure containing problem/outcome, explicit or repository-derived requirements, acceptance scenarios, scope/domains, risk, constraints, proposed design, implementation tasks/non-goals and unresolved decisions.
167
+
168
+ The planner cannot directly write normative artifacts. The Harness validates its structured output and writes the QuickContract/SDD itself.
169
+
170
+ If the planner runtime fails or returns invalid output, deterministic extraction provides a fallback rather than making the intake dependent on one LLM session.
171
+
172
+ ## Product-decision boundary
173
+
174
+ The planner/intake distinguishes:
175
+
176
+ ```text
177
+ ready
178
+ requires_product_decision
179
+ spec_contradiction
180
+ ```
181
+
182
+ Repository-derived implementation details are allowed when supported by existing evidence. Product/business choices that cannot be determined from the issue/repository are not invented.
183
+
184
+ Those become `REQUIRES_PRODUCT_DECISION`. Contradictory authoritative intent becomes `SPEC_CONTRADICTION`. Both follow the Harness human-on-exception policy.
185
+
186
+ ## QUICK vs SPEC
187
+
188
+ The issue is passed through the same deterministic triage rules used by normal requests.
189
+
190
+ A QUICK result still requires:
191
+
192
+ - explicit **concrete** bounded file scope;
193
+ - low risk;
194
+ - no security/auth/architecture/schema/migration/public API/new-dependency escalation signals;
195
+ - observable acceptance statements.
196
+
197
+ Wildcard scope such as `**`, `src/**`, `src/*.ts` or brace expansion is not accepted as a bounded QUICK scope even if it is represented by one pattern.
198
+
199
+ Anything outside that boundary becomes a full issue-derived SDD.
200
+
201
+ Issue-derived SDD requirement IDs are stable:
202
+
203
+ ```text
204
+ GH-142-R1
205
+ GH-142-R2
206
+ ...
207
+ ```
208
+
209
+ The generated proposal/spec/design/tasks/Gherkin/TaskContract must pass ordinary traceability validation before sealing.
210
+
211
+ ## Existing issue reuse
212
+
213
+ Issue-driven intake seeds the delivery record with the existing issue identity. Therefore downstream handoff **does not create another issue**.
214
+
215
+ ```text
216
+ GitHub #142
217
+ |
218
+ v
219
+ GH-142 delivery record
220
+ |
221
+ v
222
+ handoff sees issueNumber=142
223
+ |
224
+ v
225
+ skip issue creation
226
+ ```
227
+
228
+ Reusing an already-frozen TaskContract also re-seeds the delivery identity, so deleting ephemeral delivery state cannot cause the next issue implementation to create a duplicate issue.
229
+
230
+ ## Branch reuse
231
+
232
+ The configured branch pattern remains:
233
+
234
+ ```yaml
235
+ delivery:
236
+ github:
237
+ branchPattern: feature/gh-{issue}-{slug}
238
+ ```
239
+
240
+ For an existing issue the Harness first checks the exact remote ref. If it already exists, it reuses that branch. Otherwise it creates it from the captured originating/base branch.
241
+
242
+ No force push, amend or rebase is used as part of intake recovery/finalization.
243
+
244
+ ## Paseo worktree
245
+
246
+ When Paseo delivery is enabled, issue-driven handoff reuses the v0.4.14 worktree mechanism:
247
+
248
+ ```text
249
+ issue -> existing/new branch -> Paseo checkout-branch worktree
250
+ ```
251
+
252
+ The sealed task context, including the issue snapshot, is materialized into the worktree. Implementation, deterministic validation, review, remediation and Graphify execute against that workspace while control state remains in the original checkout.
253
+
254
+ ## ISSUE_DRIFT
255
+
256
+ Before each issue-derived run, the Harness re-fetches the issue title/body and recalculates the fingerprint.
257
+
258
+ If the fingerprint differs from the frozen TaskContract:
259
+
260
+ ```text
261
+ ISSUE_DRIFT
262
+ ```
263
+
264
+ The active run is not silently reinterpreted. The user/lead explicitly accepts revised issue intent with `--refresh` when appropriate; an active implementation workspace makes refresh guarded and requires explicit `--force`.
265
+
266
+ ## Accepted GitHub finalization
267
+
268
+ Git writes remain outside agent permissions. When enabled:
269
+
270
+ ```yaml
271
+ delivery:
272
+ github:
273
+ enabled: true
274
+ finalizeOnAcceptance: true
275
+ pullRequestDraft: true
276
+ ```
277
+
278
+ finalization runs only **after** the resulting report is PASS, including configured review/quality/lead gates.
279
+
280
+ The deterministic control plane:
281
+
282
+ 1. verifies that execution is on the exact issue-linked branch;
283
+ 2. stages the accepted work with `git add -A`;
284
+ 3. creates one normal commit (`GH-142: <issue title>`), using repository Git identity when configured and a Harness fallback identity otherwise;
285
+ 4. checks that the branch is actually ahead of the originating/base branch;
286
+ 5. pushes `HEAD` to the exact issue branch without force;
287
+ 6. searches for an existing open PR for that head/base pair;
288
+ 7. reuses it when present, otherwise creates a draft PR by default;
289
+ 8. writes `Closes #142` in the PR body.
290
+
291
+ The worker agents still have `gitWrite: deny`; enabling this feature does not grant them commit/push authority.
292
+
293
+ A push/token/remote permission problem becomes `BLOCKED_EXTERNAL` and marks human intervention required rather than returning a false successful delivery. A local branch/control-plane inconsistency is `SYSTEM_FAILURE` and is not mislabeled as a product decision.
294
+
295
+ If the branch contains no commits beyond the base, finalization returns `NO_CHANGES` instead of manufacturing an empty PR.
296
+
297
+ ## Configuration
298
+
299
+ Default initialized projects include:
300
+
301
+ ```yaml
302
+ workflow:
303
+ issueIntake:
304
+ enabled: true
305
+ snapshotDir: .harness/issues
306
+ verifyDriftOnRun: true
307
+ requireOpen: true
308
+ plannerAgent: planner
309
+ autoHandoff: true
310
+
311
+ delivery:
312
+ github:
313
+ enabled: false
314
+ tokenEnv: GH_TOKEN
315
+ branchPattern: feature/gh-{issue}-{slug}
316
+ finalizeOnAcceptance: true
317
+ pullRequestDraft: true
318
+ paseo:
319
+ enabled: false
320
+ createWorkspace: true
321
+ autoUseWorkspace: true
322
+ ```
323
+
324
+ `autoHandoff` invokes the configured delivery flow automatically when GitHub/Paseo delivery is enabled. It does not turn remote delivery on by itself: the `delivery.*.enabled` flags remain explicit project choices.
325
+
326
+ For automatic issue branch + worktree + PR delivery, enable both GitHub and Paseo delivery. GitHub finalization intentionally refuses to commit a different current branch, protecting the control checkout from accidental delivery writes.
327
+
328
+ ## Trust hierarchy
329
+
330
+ For issue-driven work:
331
+
332
+ ```text
333
+ GitHub issue at intake time
334
+ |
335
+ v
336
+ frozen issue snapshot
337
+ |
338
+ v
339
+ sealed QuickContract / SDD + TaskContract
340
+ |
341
+ v
342
+ implementation and validation
343
+ ```
344
+
345
+ During the active run:
346
+
347
+ ```text
348
+ sealed TaskContract/SDD > mutable remote issue > agent memory/summaries
349
+ ```
350
+
351
+ The remote issue remains provenance and collaboration input; the frozen/sealed contract prevents mutable requirements during execution.
352
+
353
+ ## Natural-language/Paseo behavior
354
+
355
+ The `engineering-workflow` skill recognizes existing-issue implementation intent. A lead started from Paseo mobile should translate:
356
+
357
+ > Implement issue #142.
358
+
359
+ into:
360
+
361
+ ```bash
362
+ aeh issue implement 142
363
+ ```
364
+
365
+ The same command owns intake, freeze, optional handoff/worktree, autonomous implementation/review and configured accepted-delivery finalization. The lead should not ask the user to manually perform intermediate Harness commands unless a genuine human-on-exception state is reached.
@@ -0,0 +1,229 @@
1
+ # v0.4.16 — Toolchain & Bootstrap
2
+
3
+ v0.4.16 makes the Harness distributable as a normal npm development tool while provisioning its external engineering toolchain explicitly and reproducibly.
4
+
5
+ ## Distribution boundary
6
+
7
+ The Harness itself is an npm package and CLI. It is not an application runtime dependency and it does not use npm `postinstall` to mutate the host.
8
+
9
+ Recommended project installation:
10
+
11
+ ```bash
12
+ npm install --save-dev agentic-engineering-harness
13
+ npm exec aeh -- init --setup
14
+ ```
15
+
16
+ For a repository that already declares the Harness but has no local `node_modules`, use a pinned temporary bootstrap invocation and let `aeh setup` install the project dependencies afterwards:
17
+
18
+ ```bash
19
+ npm exec --yes --package=agentic-engineering-harness@0.4.16 -- aeh setup
20
+ ```
21
+
22
+ ## Explicit provisioning
23
+
24
+ `aeh setup` is the host/toolchain mutation boundary. It:
25
+
26
+ 1. loads `.harness/toolchain.yaml`;
27
+ 2. inspects active Harness runtimes, orchestration, validators and project stack;
28
+ 3. computes the minimum required tool closure;
29
+ 4. reuses `.harness/toolchain.lock.json` when it exists;
30
+ 5. provisions missing managed tools through mise;
31
+ 6. optionally provisions heavy validators as immutable OCI images;
32
+ 7. installs detected project dependencies from lockfiles;
33
+ 8. writes machine-local `.harness/toolchain.state.json`;
34
+ 9. makes the provisioned bin paths visible to all subsequent Harness subprocesses;
35
+ 10. leaves verification to `aeh doctor`.
36
+
37
+ There is no requirement to run `mise activate` in the user's interactive shell.
38
+
39
+ ## Source, lock and machine state
40
+
41
+ ```text
42
+ .harness/toolchain.yaml
43
+ |
44
+ | desired tool constraints/capabilities
45
+ v
46
+ AEH resolver
47
+ |
48
+ +--> .config/mise/conf.d/aeh.toml
49
+ | generated mise layer
50
+ |
51
+ +--> .harness/toolchain.lock.json
52
+ | exact logical versions + OCI digests
53
+ |
54
+ `--> .harness/toolchain.state.json
55
+ machine-local bin paths; gitignored
56
+ ```
57
+
58
+ `toolchain.yaml` is authoritative source configuration. `toolchain.lock.json` should normally be committed after the first successful setup. `toolchain.state.json` must not be committed because it contains machine-local paths.
59
+
60
+ When a lock exists, setup uses its exact resolved versions unless `--update-lock` is requested.
61
+
62
+ ## Automatic capability resolution
63
+
64
+ Default auto mode selects tools only when they are needed.
65
+
66
+ Examples:
67
+
68
+ ```text
69
+ runtime:codex -> codex
70
+ runtime:opencode -> opencode
71
+ orchestration:paseo -> paseo
72
+ code-intelligence:graphify -> uv + graphify
73
+ validation:opa -> opa
74
+ security-tool:opengrep -> opengrep
75
+ validator:trivy -> trivy
76
+ project:bun -> bun
77
+ project:dotnet -> dotnet
78
+ ```
79
+
80
+ The resolver also recognizes Node/package-manager files, Python/uv, .NET project files/global.json, Go modules and Cargo projects as capability evidence. The default pack currently provisions the common Harness/Pawra requirements; project overlays can add additional language tools without changing AEH core.
81
+
82
+ ## Project-pinned versions
83
+
84
+ Before creating a new lock, AEH respects existing project version authority where supported:
85
+
86
+ - `.node-version` / `.nvmrc` override the default Node version;
87
+ - `global.json` pins the .NET SDK;
88
+ - `packageManager: bun@...` pins Bun;
89
+ - projects may directly override any default tool definition in `.harness/toolchain.yaml`.
90
+
91
+ A first setup may resolve `latest` declarations; after it succeeds the AEH lock becomes the reproducible resolved environment. `aeh setup --update-lock` is the explicit upgrade operation.
92
+
93
+ ## Mise backend
94
+
95
+ Mise is the default provisioning adapter because it can install tools from multiple ecosystems without making those tools npm dependencies of AEH. Where the mise registry provides an Aqua mapping, the default pack prefers Aqua over raw GitHub release autodetection.
96
+
97
+ The default pack uses:
98
+
99
+ ```text
100
+ node core mise backend
101
+ bun core mise backend
102
+ dotnet core mise backend
103
+ npm:@openai/codex Codex
104
+ npm:@getpaseo/cli Paseo
105
+ aqua:anomalyco/opencode OpenCode
106
+ aqua:open-policy-agent/opa
107
+ aqua:opengrep/opengrep
108
+ aqua:aquasecurity/trivy
109
+ uv
110
+ pipx:graphifyy Graphify CLI
111
+ ```
112
+
113
+ AEH first tries an existing `mise` executable. If it is absent, explicit setup bootstraps the configured minimum mise release through a pinned npm invocation equivalent to:
114
+
115
+ ```bash
116
+ npm exec --yes --package=mise@2026.7.0 -- mise --version
117
+ ```
118
+
119
+ This is an explicit setup action rather than an npm installation side effect. The version is taken from `manager.minimumVersion`, not hard-coded in setup logic.
120
+
121
+ ## OCI validator strategy
122
+
123
+ The toolchain supports:
124
+
125
+ ```yaml
126
+ strategy:
127
+ validators: local
128
+ containerEngine: podman
129
+ ```
130
+
131
+ or:
132
+
133
+ ```yaml
134
+ strategy:
135
+ validators: prefer-container
136
+ containerEngine: podman
137
+ ```
138
+
139
+ If `prefer-container` is selected and the configured engine is available, tools with a container alternative are pulled and locked by immutable RepoDigest. A wrapper is generated under `.harness/bin` so the rest of the Harness still invokes the normal tool command.
140
+
141
+ Default OCI-capable tools currently include OPA and Trivy. If Podman is unavailable, the resolver falls back to the mise/local definition instead of making containers mandatory.
142
+
143
+ ## Project dependencies
144
+
145
+ After tool provisioning, setup detects common project dependency locks:
146
+
147
+ ```text
148
+ package-lock.json -> npm ci
149
+ pnpm-lock.yaml -> corepack pnpm install --frozen-lockfile
150
+ bun.lock/bun.lockb -> bun install --frozen-lockfile
151
+ yarn.lock -> corepack yarn install --immutable
152
+ (Yarn 1 uses --frozen-lockfile)
153
+ uv.lock -> uv sync --frozen
154
+ *.sln/*.slnx/*.csproj/global.json -> dotnet restore
155
+ ```
156
+
157
+ Extra deterministic commands may be declared under `projectDependencies.commands`.
158
+
159
+ Use `--skip-project-deps` when the repository or CI owns that phase separately.
160
+
161
+ ## Commands
162
+
163
+ ```bash
164
+ # Show what auto mode requires
165
+ aeh toolchain show
166
+
167
+ # Compile only the generated mise layer
168
+ aeh toolchain compile
169
+
170
+ # Side-effect-free plan
171
+ aeh setup --dry-run
172
+
173
+ # Provision exactly what the project currently requires
174
+ aeh setup
175
+
176
+ # Deliberately refresh fuzzy/latest versions and rewrite the lock
177
+ aeh setup --update-lock
178
+
179
+ # Prefer OCI alternatives when available
180
+ aeh setup --prefer-containers
181
+
182
+ # Install a named capability profile
183
+ aeh setup --profile agents
184
+ aeh setup --profile validation
185
+ aeh setup --profile full
186
+
187
+ # Bootstrap a repo and immediately provision it
188
+ aeh init --setup
189
+
190
+ # Prove the actual environment satisfies the Harness configuration
191
+ aeh doctor
192
+ ```
193
+
194
+ ## Runtime PATH
195
+
196
+ After setup, mise bin directories and AEH-generated OCI wrappers are written to machine-local state. `runProcess` prepends those paths automatically, including when running from a Git worktree whose control checkout owns the state.
197
+
198
+ This means Codex/OpenCode/Paseo/validators can be launched from Harness code without requiring users to modify `.bashrc`, `.zshrc` or IDE shell activation.
199
+
200
+ ## Packaging and publication
201
+
202
+ `package.json` publishes the CLI entrypoint plus `dist`, templates, presets, policies, schemas, skills and docs. CI runs `npm run release:check`, which includes the complete typecheck/test/build sequence and `npm pack --dry-run`.
203
+
204
+ A GitHub Release publishing workflow is included at `.github/workflows/publish.yml`. It is designed for npm Trusted Publishing through GitHub Actions OIDC rather than a long-lived write token. Because npm requires a package to exist before a trusted publisher can be attached, the **first registry publication is a one-time bootstrap operation**; after that, configure the npm package's trusted publisher to `JamesMorales04/agentic-engineering-harness` + `publish.yml`, then normal GitHub Releases can publish with short-lived OIDC credentials.
205
+
206
+ See `docs/PUBLISHING.md` for the exact bootstrap and steady-state release sequence.
207
+
208
+ ## Trust and installation policy
209
+
210
+ - npm installs AEH only;
211
+ - no `postinstall` performs host mutations;
212
+ - `aeh setup` is explicit and auditable;
213
+ - system prerequisites such as Git are checked, not silently installed with sudo;
214
+ - managed tool versions and OCI digests are locked;
215
+ - machine-local paths are not versioned;
216
+ - project dependency managers use their lock/frozen modes;
217
+ - `aeh doctor` is verification, while `aeh setup` is reconciliation;
218
+ - release CI validates the actual npm tarball before publishing.
219
+
220
+ The intended lifecycle is:
221
+
222
+ ```text
223
+ clone
224
+ -> bootstrap AEH npm package
225
+ -> aeh setup
226
+ -> aeh doctor
227
+ -> Paseo / engineering lead
228
+ -> implement issue #X
229
+ ```
package/docs/V0.4.md ADDED
@@ -0,0 +1,28 @@
1
+ # v0.4 — Agent Topology and Governance
2
+
3
+ ## v0.4.1 — Registry and model aliases
4
+ Agent identity is separated from model identity and runtime. `@brain` and `@workhorse` are aliases, not hard-coded policy in routing logic.
5
+
6
+ ## v0.4.2 — Profiles and JSONC compiler
7
+ `.harness/agents.source.jsonc` is maintained source. `.harness/generated/agents.json` is generated runtime. Prompt paths are hashed and inlined; `aeh agents check` fails on active-profile drift.
8
+
9
+ ## v0.4.3 — Routing and output contracts
10
+ Routing can match intent, domains, file scopes and risk. Planner, implementer, reviewer, validator, recovery and orchestrator outputs have Zod contracts. A normalized delegation task contains `id`, `summary`, `agent`, `scope`, `dependencies`, `acceptance` and `risk`.
11
+
12
+ ## v0.4.4 — Typed recovery
13
+ Failures use the canonical taxonomy: `PATCH_CONTEXT_MISMATCH`, `TOOL_FAILURE`, `MISSING_CONTEXT`, `WRONG_AGENT`, `VALIDATION_FAILURE`, `REVIEW_FAILURE`, `AMBIGUOUS_OUTPUT`, `CONFLICTING_RESULTS`. Recovery actions are versioned data and bounded by the existing repair budget.
14
+
15
+ ## v0.4.5 — Drift gates
16
+ The topology audit checks model/runtime references, prompt files, skills, routing references, output contracts, permission/capability coherence and source-to-generated-runtime drift.
17
+
18
+ ## v0.4.6 — Permissions, capabilities and native agents
19
+ A logical agent resolves to runtime + model + optional runtime-native agent. OpenCode direct/Podman execution maps this to `opencode run --model ... --variant ... --agent ...`. Harness permissions are translated to OpenCode runtime permissions through `OPENCODE_CONFIG_CONTENT` for direct/Podman execution; OpenCode merges inline runtime config with project/global config. `gitWrite` produces explicit deny/ask/allow rules for mutating Git commands. Codex direct execution uses its bare model name. Paseo remains cross-provider transport; native-agent selection through Paseo is only allowed when that runtime explicitly declares `nativeAgentViaPaseo`, and runtime permission enforcement remains the responsibility of the configured Paseo provider.
20
+
21
+ ## v0.4.7 — Graphify-assisted parallelism
22
+ Planner tasks are scheduled into waves. Dependencies and overlapping file scopes are hard conflicts. When a Graphify before-snapshot maps both scopes into the same structural community, the scheduler conservatively keeps them apart. Missing Graphify data falls back to dependency/scope scheduling.
23
+
24
+ ## v0.4.8 — Finding normalization
25
+ Reviewer findings use one schema with severity, category, location, evidence, impact, recommended fix and suggested agent. Findings at the same/adjacent location with compatible categories are merged while preserving the highest severity and merge provenance.
26
+
27
+ ## Compatibility
28
+ `orchestration.worker` remains as a legacy fallback when no agent topology is configured. New projects receive the topology template automatically.
@@ -0,0 +1,23 @@
1
+ # Validation
2
+
3
+ LLM output is an untrusted proposal. Acceptance is based on executable evidence.
4
+
5
+ ## Registry
6
+
7
+ Project and TaskContract validators share a `ValidatorSpec` with `id`, `adapter`, optional `command`, `required`, timeout/working-directory and adapter-specific `options`.
8
+
9
+ Supported v0.2.5 adapters: `gherkin`, `graphify`, `opengrep`, `trivy`, `playwright`, `openapi`, `pact`, `command`.
10
+
11
+ A missing optional external tool returns WARN. A missing required tool returns FAIL. An installed tool that reports defects returns FAIL; `required` controls availability, not whether findings are ignored.
12
+
13
+ ## Requirement mapping
14
+
15
+ Requirements may reference a validator by adapter or validator ID, e.g. `gherkin` or `api-compat`. `aeh sdd validate` rejects unresolved references.
16
+
17
+ ## OPA evidence
18
+
19
+ OPA receives changed dependency-manifest and schema-affecting paths from the Git diff instead of placeholder values. Dependency-manifest changes are treated conservatively as dependency-change evidence.
20
+
21
+ ## OpenAPI
22
+
23
+ The built-in adapter accepts JSON or YAML snapshots and rejects supported breaking changes: removed paths/operations/responses/schemas/properties, newly-required parameters/properties, and schema type changes. Full semantic `$ref` compatibility can be delegated to a dedicated project CLI through `adapter: command` when needed.
package/package.json ADDED
@@ -0,0 +1,18 @@
1
+ {
2
+ "name": "agentic-engineering-harness",
3
+ "version": "0.4.16",
4
+ "description": "OSS-first engineering harness for deterministic, spec-driven and issue-driven multi-agent software delivery.",
5
+ "type": "module",
6
+ "bin": { "engineering-harness": "./dist/entry.js", "aeh": "./dist/entry.js" },
7
+ "files": ["dist", "templates", "presets", "policies", "schemas", "skills", "docs"],
8
+ "scripts": { "build": "tsc -p tsconfig.json", "dev": "tsx src/entry.ts", "test": "vitest run", "test:watch": "vitest", "typecheck": "tsc -p tsconfig.json --noEmit", "check": "npm run typecheck && npm test && npm run build", "release:check": "npm run check && npm pack --dry-run" },
9
+ "engines": { "node": ">=22" },
10
+ "dependencies": { "@opentelemetry/api": "^1.9.0", "commander": "^14.0.1", "minimatch": "^10.0.3", "yaml": "^2.8.1", "zod": "^4.0.17" },
11
+ "devDependencies": { "@types/node": "^24.2.1", "tsx": "^4.20.3", "typescript": "^5.9.2", "vitest": "^3.2.4" },
12
+ "repository": { "type": "git", "url": "git+https://github.com/JamesMorales04/agentic-engineering-harness.git" },
13
+ "homepage": "https://github.com/JamesMorales04/agentic-engineering-harness#readme",
14
+ "bugs": { "url": "https://github.com/JamesMorales04/agentic-engineering-harness/issues" },
15
+ "publishConfig": { "access": "public" },
16
+ "license": "Apache-2.0",
17
+ "keywords": ["ai-agents", "codex", "opencode", "paseo", "sdd", "github-issues", "issue-driven-development", "quick-contract", "gherkin", "agent-routing", "agent-presets", "mcp", "github-delivery", "worktrees", "multi-model", "quality-convergence", "toolchain", "mise", "bootstrap", "human-on-exception", "deterministic-validation", "engineering-harness", "slsa", "opentelemetry"]
18
+ }
@@ -0,0 +1,12 @@
1
+ package harness.dependencies
2
+
3
+ default allow_new_dependencies := false
4
+
5
+ allow_new_dependencies if {
6
+ input.taskContract.constraints.newDependencies == true
7
+ }
8
+
9
+ deny contains "new dependency is not authorized by the TaskContract" if {
10
+ count(input.newDependencies) > 0
11
+ not allow_new_dependencies
12
+ }
@@ -0,0 +1,12 @@
1
+ package harness.schema
2
+
3
+ default allow_schema_changes := false
4
+
5
+ allow_schema_changes if {
6
+ input.taskContract.constraints.schemaChanges == true
7
+ }
8
+
9
+ deny contains "schema change is not authorized by the TaskContract" if {
10
+ input.schemaChanged == true
11
+ not allow_schema_changes
12
+ }