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.
- package/LICENSE +201 -0
- package/README.md +273 -0
- package/dist/agents/audit.d.ts +12 -0
- package/dist/agents/audit.js +14 -0
- package/dist/agents/audit.js.map +1 -0
- package/dist/agents/compiler.d.ts +8 -0
- package/dist/agents/compiler.js +103 -0
- package/dist/agents/compiler.js.map +1 -0
- package/dist/agents/config.d.ts +6 -0
- package/dist/agents/config.js +161 -0
- package/dist/agents/config.js.map +1 -0
- package/dist/agents/escalation.d.ts +9 -0
- package/dist/agents/escalation.js +75 -0
- package/dist/agents/escalation.js.map +1 -0
- package/dist/agents/exceptionDetection.d.ts +24 -0
- package/dist/agents/exceptionDetection.js +42 -0
- package/dist/agents/exceptionDetection.js.map +1 -0
- package/dist/agents/findings.d.ts +14 -0
- package/dist/agents/findings.js +40 -0
- package/dist/agents/findings.js.map +1 -0
- package/dist/agents/gitCheckpoint.d.ts +6 -0
- package/dist/agents/gitCheckpoint.js +61 -0
- package/dist/agents/gitCheckpoint.js.map +1 -0
- package/dist/agents/jsonc.d.ts +1 -0
- package/dist/agents/jsonc.js +42 -0
- package/dist/agents/jsonc.js.map +1 -0
- package/dist/agents/outputContracts.d.ts +161 -0
- package/dist/agents/outputContracts.js +16 -0
- package/dist/agents/outputContracts.js.map +1 -0
- package/dist/agents/parallelism.d.ts +14 -0
- package/dist/agents/parallelism.js +54 -0
- package/dist/agents/parallelism.js.map +1 -0
- package/dist/agents/permissions.d.ts +5 -0
- package/dist/agents/permissions.js +30 -0
- package/dist/agents/permissions.js.map +1 -0
- package/dist/agents/qualityConvergence.d.ts +44 -0
- package/dist/agents/qualityConvergence.js +77 -0
- package/dist/agents/qualityConvergence.js.map +1 -0
- package/dist/agents/recovery.d.ts +13 -0
- package/dist/agents/recovery.js +35 -0
- package/dist/agents/recovery.js.map +1 -0
- package/dist/agents/reviewLifecycle.d.ts +30 -0
- package/dist/agents/reviewLifecycle.js +233 -0
- package/dist/agents/reviewLifecycle.js.map +1 -0
- package/dist/agents/routing.d.ts +9 -0
- package/dist/agents/routing.js +37 -0
- package/dist/agents/routing.js.map +1 -0
- package/dist/agents/structuredOutput.d.ts +1 -0
- package/dist/agents/structuredOutput.js +54 -0
- package/dist/agents/structuredOutput.js.map +1 -0
- package/dist/agents/types.d.ts +207 -0
- package/dist/agents/types.js +2 -0
- package/dist/agents/types.js.map +1 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +221 -0
- package/dist/cli.js.map +1 -0
- package/dist/core/config.d.ts +3 -0
- package/dist/core/config.js +59 -0
- package/dist/core/config.js.map +1 -0
- package/dist/core/doctor.d.ts +8 -0
- package/dist/core/doctor.js +59 -0
- package/dist/core/doctor.js.map +1 -0
- package/dist/core/git.d.ts +8 -0
- package/dist/core/git.js +47 -0
- package/dist/core/git.js.map +1 -0
- package/dist/core/init.d.ts +1 -0
- package/dist/core/init.js +52 -0
- package/dist/core/init.js.map +1 -0
- package/dist/core/quick.d.ts +20 -0
- package/dist/core/quick.js +49 -0
- package/dist/core/quick.js.map +1 -0
- package/dist/core/repair.d.ts +8 -0
- package/dist/core/repair.js +7 -0
- package/dist/core/repair.js.map +1 -0
- package/dist/core/run.d.ts +38 -0
- package/dist/core/run.js +165 -0
- package/dist/core/run.js.map +1 -0
- package/dist/core/sdd.d.ts +10 -0
- package/dist/core/sdd.js +88 -0
- package/dist/core/sdd.js.map +1 -0
- package/dist/core/seal.d.ts +3 -0
- package/dist/core/seal.js +74 -0
- package/dist/core/seal.js.map +1 -0
- package/dist/core/triage.d.ts +22 -0
- package/dist/core/triage.js +38 -0
- package/dist/core/triage.js.map +1 -0
- package/dist/core/types.d.ts +354 -0
- package/dist/core/types.js +2 -0
- package/dist/core/types.js.map +1 -0
- package/dist/core/verify.d.ts +6 -0
- package/dist/core/verify.js +51 -0
- package/dist/core/verify.js.map +1 -0
- package/dist/delivery/finalize.d.ts +17 -0
- package/dist/delivery/finalize.js +71 -0
- package/dist/delivery/finalize.js.map +1 -0
- package/dist/delivery/handoff.d.ts +39 -0
- package/dist/delivery/handoff.js +250 -0
- package/dist/delivery/handoff.js.map +1 -0
- package/dist/entry.d.ts +2 -0
- package/dist/entry.js +112 -0
- package/dist/entry.js.map +1 -0
- package/dist/evals/runner.d.ts +4 -0
- package/dist/evals/runner.js +112 -0
- package/dist/evals/runner.js.map +1 -0
- package/dist/evals/scoring.d.ts +3 -0
- package/dist/evals/scoring.js +41 -0
- package/dist/evals/scoring.js.map +1 -0
- package/dist/evals/types.d.ts +46 -0
- package/dist/evals/types.js +2 -0
- package/dist/evals/types.js.map +1 -0
- package/dist/issues/intake.d.ts +114 -0
- package/dist/issues/intake.js +213 -0
- package/dist/issues/intake.js.map +1 -0
- package/dist/memory/benchmark.d.ts +33 -0
- package/dist/memory/benchmark.js +69 -0
- package/dist/memory/benchmark.js.map +1 -0
- package/dist/metrics/runMetrics.d.ts +9 -0
- package/dist/metrics/runMetrics.js +34 -0
- package/dist/metrics/runMetrics.js.map +1 -0
- package/dist/metrics/usage.d.ts +3 -0
- package/dist/metrics/usage.js +53 -0
- package/dist/metrics/usage.js.map +1 -0
- package/dist/provenance/generate.d.ts +30 -0
- package/dist/provenance/generate.js +96 -0
- package/dist/provenance/generate.js.map +1 -0
- package/dist/providers/engram.d.ts +8 -0
- package/dist/providers/engram.js +14 -0
- package/dist/providers/engram.js.map +1 -0
- package/dist/providers/graphify.d.ts +9 -0
- package/dist/providers/graphify.js +28 -0
- package/dist/providers/graphify.js.map +1 -0
- package/dist/providers/paseo.d.ts +8 -0
- package/dist/providers/paseo.js +14 -0
- package/dist/providers/paseo.js.map +1 -0
- package/dist/providers/types.d.ts +41 -0
- package/dist/providers/types.js +2 -0
- package/dist/providers/types.js.map +1 -0
- package/dist/telemetry/events.d.ts +2 -0
- package/dist/telemetry/events.js +29 -0
- package/dist/telemetry/events.js.map +1 -0
- package/dist/telemetry/otlp.d.ts +3 -0
- package/dist/telemetry/otlp.js +57 -0
- package/dist/telemetry/otlp.js.map +1 -0
- package/dist/toolchain/config.d.ts +10 -0
- package/dist/toolchain/config.js +54 -0
- package/dist/toolchain/config.js.map +1 -0
- package/dist/toolchain/doctor.d.ts +8 -0
- package/dist/toolchain/doctor.js +56 -0
- package/dist/toolchain/doctor.js.map +1 -0
- package/dist/toolchain/mise.d.ts +10 -0
- package/dist/toolchain/mise.js +61 -0
- package/dist/toolchain/mise.js.map +1 -0
- package/dist/toolchain/resolve.d.ts +8 -0
- package/dist/toolchain/resolve.js +159 -0
- package/dist/toolchain/resolve.js.map +1 -0
- package/dist/toolchain/setup.d.ts +7 -0
- package/dist/toolchain/setup.js +141 -0
- package/dist/toolchain/setup.js.map +1 -0
- package/dist/toolchain/types.d.ts +95 -0
- package/dist/toolchain/types.js +2 -0
- package/dist/toolchain/types.js.map +1 -0
- package/dist/utils/process.d.ts +15 -0
- package/dist/utils/process.js +94 -0
- package/dist/utils/process.js.map +1 -0
- package/dist/validators/commands.d.ts +2 -0
- package/dist/validators/commands.js +28 -0
- package/dist/validators/commands.js.map +1 -0
- package/dist/validators/constraints.d.ts +6 -0
- package/dist/validators/constraints.js +30 -0
- package/dist/validators/constraints.js.map +1 -0
- package/dist/validators/diffScope.d.ts +2 -0
- package/dist/validators/diffScope.js +36 -0
- package/dist/validators/diffScope.js.map +1 -0
- package/dist/validators/evidence.d.ts +6 -0
- package/dist/validators/evidence.js +8 -0
- package/dist/validators/evidence.js.map +1 -0
- package/dist/validators/external.d.ts +3 -0
- package/dist/validators/external.js +22 -0
- package/dist/validators/external.js.map +1 -0
- package/dist/validators/gherkin.d.ts +3 -0
- package/dist/validators/gherkin.js +59 -0
- package/dist/validators/gherkin.js.map +1 -0
- package/dist/validators/graphify.d.ts +4 -0
- package/dist/validators/graphify.js +108 -0
- package/dist/validators/graphify.js.map +1 -0
- package/dist/validators/opa.d.ts +3 -0
- package/dist/validators/opa.js +43 -0
- package/dist/validators/opa.js.map +1 -0
- package/dist/validators/openapi.d.ts +25 -0
- package/dist/validators/openapi.js +98 -0
- package/dist/validators/openapi.js.map +1 -0
- package/dist/validators/registry.d.ts +2 -0
- package/dist/validators/registry.js +36 -0
- package/dist/validators/registry.js.map +1 -0
- package/dist/validators/toolCommand.d.ts +5 -0
- package/dist/validators/toolCommand.js +33 -0
- package/dist/validators/toolCommand.js.map +1 -0
- package/dist/validators/types.d.ts +13 -0
- package/dist/validators/types.js +2 -0
- package/dist/validators/types.js.map +1 -0
- package/dist/workers/agentPrompt.d.ts +3 -0
- package/dist/workers/agentPrompt.js +84 -0
- package/dist/workers/agentPrompt.js.map +1 -0
- package/dist/workers/direct.d.ts +13 -0
- package/dist/workers/direct.js +30 -0
- package/dist/workers/direct.js.map +1 -0
- package/dist/workers/factory.d.ts +4 -0
- package/dist/workers/factory.js +10 -0
- package/dist/workers/factory.js.map +1 -0
- package/dist/workers/paseo.d.ts +14 -0
- package/dist/workers/paseo.js +29 -0
- package/dist/workers/paseo.js.map +1 -0
- package/dist/workers/podman.d.ts +13 -0
- package/dist/workers/podman.js +22 -0
- package/dist/workers/podman.js.map +1 -0
- package/dist/workers/prompt.d.ts +4 -0
- package/dist/workers/prompt.js +4 -0
- package/dist/workers/prompt.js.map +1 -0
- package/dist/workers/types.d.ts +11 -0
- package/dist/workers/types.js +2 -0
- package/dist/workers/types.js.map +1 -0
- package/docs/ARCHITECTURE.md +47 -0
- package/docs/EVALS.md +28 -0
- package/docs/MEMORY.md +28 -0
- package/docs/OBSERVABILITY.md +18 -0
- package/docs/OSS_STACK.md +27 -0
- package/docs/PASEO.md +9 -0
- package/docs/PUBLISHING.md +110 -0
- package/docs/SDD.md +35 -0
- package/docs/SECURITY.md +21 -0
- package/docs/V0.2.md +42 -0
- package/docs/V0.3.md +40 -0
- package/docs/V0.4.11.md +30 -0
- package/docs/V0.4.12.md +88 -0
- package/docs/V0.4.13.md +203 -0
- package/docs/V0.4.14.md +209 -0
- package/docs/V0.4.15.md +365 -0
- package/docs/V0.4.16.md +229 -0
- package/docs/V0.4.md +28 -0
- package/docs/VALIDATION.md +23 -0
- package/package.json +18 -0
- package/policies/core/dependency-policy.rego +12 -0
- package/policies/core/schema-policy.rego +12 -0
- package/policies/core/trust-boundary.rego +17 -0
- package/presets/agents/default.jsonc +80 -0
- package/presets/docker.yaml +4 -0
- package/presets/dotnet.yaml +12 -0
- package/presets/expo.yaml +6 -0
- package/presets/generic.yaml +3 -0
- package/presets/nextjs.yaml +8 -0
- package/presets/node.yaml +6 -0
- package/presets/pnpm.yaml +6 -0
- package/presets/postgres.yaml +4 -0
- package/schemas/agent-output-planner.schema.json +1 -0
- package/schemas/agent-topology.schema.json +37 -0
- package/schemas/project.schema.json +36 -0
- package/schemas/quick-contract.schema.json +17 -0
- package/schemas/task-contract.schema.json +18 -0
- package/schemas/toolchain.schema.json +70 -0
- package/schemas/validation-report.schema.json +15 -0
- package/skills/acceptance-traceability/SKILL.md +13 -0
- package/skills/deterministic-validation/SKILL.md +15 -0
- package/skills/engineering-workflow/SKILL.md +108 -0
- package/skills/finding-dedup/SKILL.md +12 -0
- package/skills/github-delivery-lifecycle/SKILL.md +16 -0
- package/skills/implementation-worker/SKILL.md +17 -0
- package/skills/lead-engineer/SKILL.md +30 -0
- package/skills/memory-hygiene/SKILL.md +22 -0
- package/skills/prompt-drift-audit/SKILL.md +10 -0
- package/skills/recovery-classifier/SKILL.md +13 -0
- package/skills/routing-normalizer/SKILL.md +17 -0
- package/skills/sdd/SKILL.md +21 -0
- package/skills/simplify/SKILL.md +16 -0
- package/skills/verification-planning/SKILL.md +17 -0
- package/skills/worktree-lifecycle/SKILL.md +18 -0
- package/templates/AGENTS.md +37 -0
- package/templates/agents.source.jsonc +39 -0
- package/templates/otel-collector.yaml +21 -0
- package/templates/project.yaml +196 -0
- package/templates/toolchain.yaml +127 -0
package/docs/V0.4.15.md
ADDED
|
@@ -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.
|
package/docs/V0.4.16.md
ADDED
|
@@ -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
|
+
}
|