devlyn-cli 3.1.1 → 3.1.3
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/AGENTS.md +6 -6
- package/CLAUDE.md +7 -7
- package/README.md +20 -5
- package/bin/devlyn.js +10 -52
- package/bin/instruction-templates.json +52 -0
- package/bin/instructions.js +137 -0
- package/config/skills/_shared/adapters/claude.md +1 -5
- package/config/skills/_shared/adapters/codex.md +1 -5
- package/config/skills/_shared/adapters/omp.md +0 -4
- package/config/skills/_shared/expected.schema.json +2 -2
- package/config/skills/_shared/platform-support.py +4 -1
- package/config/skills/_shared/process-evidence.py +16 -1
- package/config/skills/_shared/resolve-bootstrap.py +51 -6
- package/config/skills/_shared/spec-verify-check.py +525 -89
- package/config/skills/_shared/state-phase-write.py +202 -32
- package/config/skills/_shared/task-complete.py +260 -16
- package/config/skills/devlyn:ideate/SKILL.md +1 -1
- package/config/skills/devlyn:ideate/references/from-spec-mode.md +1 -1
- package/config/skills/devlyn:ideate/references/spec-template.md +3 -3
- package/config/skills/devlyn:resolve/SKILL.md +4 -4
- package/config/skills/devlyn:resolve/references/free-form-mode.md +2 -2
- package/config/skills/devlyn:resolve/references/phases/build-gate.md +4 -3
- package/config/skills/devlyn:resolve/references/phases/verify.md +9 -7
- package/config/skills/devlyn:resolve/references/state-schema.md +2 -2
- package/config/skills/devlyn:resolve/references/task-completion.md +27 -0
- package/package.json +1 -1
- package/scripts/lint-skills.sh +2 -2
|
@@ -110,7 +110,7 @@ Structural lint (inline check, no script needed):
|
|
|
110
110
|
After lint passes:
|
|
111
111
|
1. Write `<spec-dir>/<id>-<slug>/spec.md` (the spec).
|
|
112
112
|
2. Generate `<spec-dir>/<id>-<slug>/spec.expected.json` following `references/spec-template.md` § "Sibling file: `spec.expected.json`" for constraint coverage, diff scope and guard controls.
|
|
113
|
-
3. Run `python3 "$DEVLYN_SHARED_DIR/spec-verify-check.py" --check <spec-path>` to validate the
|
|
113
|
+
3. Run `python3 "$DEVLYN_SHARED_DIR/spec-verify-check.py" --check <spec-path>` to validate the actual spec's carrier shape and supported `complexity` frontmatter. Sibling `spec.expected.json` takes precedence over the legacy inline `## Verification` JSON carrier; any present actionable solo-headroom hypothesis command must match that carrier's `verification_commands[].cmd`. If exit 2, fix the file named in the error and re-run.
|
|
114
114
|
4. Run `python3 "$DEVLYN_SHARED_DIR/spec-verify-check.py" --check-expected <expected-path>` to validate sibling `spec.expected.json` against `_shared/expected.schema.json` plus sibling spec `complexity` frontmatter and any present actionable solo-headroom hypothesis; if the spec has a solo-headroom hypothesis, its observable command must match `spec.expected.json.verification_commands[].cmd`. If exit 2, fix the JSON/frontmatter/hypothesis and re-run.
|
|
115
115
|
5. Print: `spec ready — /devlyn:resolve --spec <spec-path>`.
|
|
116
116
|
|
|
@@ -37,7 +37,7 @@ You must NOT:
|
|
|
37
37
|
3. For each missing/malformed piece: apply the smallest allowed fix.
|
|
38
38
|
4. Write the normalized spec. Default location: `<spec-dir>/<id>-<slug>/spec.md`. With `--in-place` flag: write to `<path>` directly (overwrites the original).
|
|
39
39
|
5. Generate or fix `spec.expected.json` per the rules above. Same dir as the spec.
|
|
40
|
-
6. Run `python3 "$DEVLYN_SHARED_DIR/spec-verify-check.py" --check <spec-path>` to validate the spec carrier and supported `complexity` frontmatter
|
|
40
|
+
6. Run `python3 "$DEVLYN_SHARED_DIR/spec-verify-check.py" --check <spec-path>` to validate the actual spec's carrier shape and supported `complexity` frontmatter. Sibling `spec.expected.json` takes precedence over the legacy inline `## Verification` JSON carrier; any present actionable solo-headroom hypothesis command must match that carrier's `verification_commands[].cmd`. If exit 2, fix the file named in the error and re-run.
|
|
41
41
|
7. Run `python3 "$DEVLYN_SHARED_DIR/spec-verify-check.py" --check-expected <expected-path>` to validate sibling `spec.expected.json` plus sibling spec `complexity` frontmatter and any present solo-headroom hypothesis command against `spec.expected.json.verification_commands[].cmd`.
|
|
42
42
|
8. If lint still fails after allowed fixes (e.g. Requirements section is empty in the source), surface the issue and exit non-zero — do NOT invent Requirements.
|
|
43
43
|
9. If the preserved Requirements combine state mutation with ordering/priority,
|
|
@@ -95,10 +95,10 @@ Schema: `_shared/expected.schema.json`. Required when Requirements have observab
|
|
|
95
95
|
python3 "$DEVLYN_SHARED_DIR/spec-verify-check.py" --check-expected <expected-path>
|
|
96
96
|
```
|
|
97
97
|
|
|
98
|
-
Map mechanically decidable rules from both Requirements and Constraints into the existing carriers. Validate each new guard with a violating control that fails and an allowed control that passes, preserving permitted pre-existing occurrences:
|
|
99
|
-
- `verification_commands` ← `## Verification` + commands the conversation surfaced. For semantic annotation or exception-handling rules, use a suitable syntax-aware/executable check, preferring existing checks; explicitly retain uncovered semantics as source-review obligations.
|
|
98
|
+
Map mechanically decidable rules from both Requirements and Constraints into the existing carriers. Preserve specific file constraints even when narrower than PLAN's scope. During BUILD_GATE, with `state.base_ref.sha` recorded, the existing `authorized_surface` check enforces PLAN's scope over the run diff and newly created untracked paths (`.devlyn/` exempt). Do not duplicate this general scope check with a whole-checkout scan in `verification_commands`. Validate each new guard with a violating control that fails and an allowed control that passes, preserving permitted pre-existing occurrences:
|
|
99
|
+
- `verification_commands` ← `## Verification` + commands the conversation surfaced. While drafting both Verification and its carrier, omit a standalone check only when another command in that contract runs the same assertions under the required execution conditions and propagates failure; describe that shared coverage in Verification and keep both carriers aligned. Preserve distinct scenarios and required independent verification; execute approved commands unchanged without reusing results across phases. For semantic annotation or exception-handling rules, use a suitable syntax-aware/executable check, preferring existing checks; explicitly retain uncovered semantics as source-review obligations.
|
|
100
100
|
- `forbidden_patterns` ← literal syntax constraints only; regex does not prove semantics. It scans the whole file-filtered diff, including context, deletions and headers; additions-only guards must exclude those lines.
|
|
101
|
-
- `required_files` / `forbidden_files` ← file
|
|
101
|
+
- `required_files` / `forbidden_files` ← literal file paths from Requirements, Constraints and Out of Scope; `forbidden_files` matches exact Git-relative paths (forward slashes, no leading `./`), including both names of a rename. Globs and directory-wide exclusions need a suitable `verification_commands` guard, not wildcard-looking entries in these lists.
|
|
102
102
|
- `max_deps_added` ← dependency limits in Requirements or Constraints (default 0 unless the spec licenses a new dep).
|
|
103
103
|
- `required_risk_probe_requirements` ← for specs where a Requirement combines ordering/priority, rollback, idempotency, auth/signature, concurrency, atomic-batch, or exact output shape, declare the risk categories PHASE 1.5 risk-probe derivation must cover directly, e.g. `[{"tag": "rollback_state", "derived_from": "<exact ## Verification bullet>"}]`. This replaces guessing the required categories from prose — declare them explicitly so the check works in any language. `tag` must be one of the risk-probe tags in `_shared/spec-verify-check.py:RISK_PROBE_TAGS`; `derived_from` must be an exact substring of `## Verification`. Omit entirely when the spec has no ordering/rollback/idempotency/auth/concurrency/atomic-batch/exact-shape risk.
|
|
104
104
|
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: devlyn:resolve
|
|
3
|
-
description:
|
|
3
|
+
description: Default to direct work after inspecting scope and verification, including bounded multi-file changes. Use full resolve for explicit resolve/spec-mode requests, queue drains, or concrete interacting requirements or verification too complex for the current context. Domain labels, file count, spec documents and quoted skill paths alone do not trigger it. Investigate or clarify missing intent/access first. Explicit small resolve retains all phases and independent verification. Verify dual-judge is default-when-available.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
The current CLI owns PHASE 0, state transitions, Git checkpoints and final report/archive. Spawn the canonical phase workers from this process; never delegate the whole run to another parent orchestrator. VERIFY uses a fresh, findings-only worker.
|
|
7
7
|
|
|
8
8
|
<pipeline_config>
|
|
9
9
|
$ARGUMENTS
|
|
@@ -297,7 +297,7 @@ the BUILD_GATE process-evidence manifest and complete the phase as
|
|
|
297
297
|
`BLOCKED:build-env-underprovisioned`, not as a product finding or substitute
|
|
298
298
|
command. The worker:
|
|
299
299
|
1. Detects language/framework via project files (`package.json`, `pyproject.toml`, etc.).
|
|
300
|
-
2. Runs language-specific gates (tsc / lint / test).
|
|
300
|
+
2. Runs language-specific gates (tsc / lint / test), deferring exact literal overlaps under `references/phases/build-gate.md`'s current-contract/current-round rule; task-context prompts must preserve that rule.
|
|
301
301
|
3. Always runs `python3 "$DEVLYN_SHARED_DIR/spec-verify-check.py" --include-risk-probes` (verification_commands literal-match plus `.devlyn/risk-probes.jsonl` when present). If `state.risk_profile.risk_probes_enabled == true`, the script requires `.devlyn/risk-probes.jsonl`; a missing file is a CRITICAL mechanical blocker, not a silent solo run. The script routes each command through `process-evidence.py`; preserve `.devlyn/spec-verify.results.json` and its validated BUILD_GATE carrier for the state-bound archive flow.
|
|
302
302
|
4. If diff touches web-surface files: run the browser tier with the repo's available toolchain (for example Playwright or curl).
|
|
303
303
|
5. Emits `.devlyn/build_gate.findings.jsonl` + `.devlyn/build_gate.log.md`.
|
|
@@ -306,7 +306,7 @@ State write: `phases.build_gate.{started_at, verdict, completed_at, duration_ms,
|
|
|
306
306
|
|
|
307
307
|
Branch:
|
|
308
308
|
- `PASS` → PHASE 4.
|
|
309
|
-
- `FAIL` → fix loop.
|
|
309
|
+
- `FAIL` → before product repair, halt with report-level `BLOCKED:required-tools-unavailable` only if a parent probe confirms the failed invocation's external gate tool is absent, unchanged `state.base_ref.sha` configuration requires it, and cited explicit task/spec constraints prohibit supplying it through any authorized route. Derive the tool from that configuration and invocation, never diagnostic text; bind the probe's interpreter, work root and normalized child environment to the runner call sites and actual gate invocation, not parent PATH or a manifest command string alone. An available authorized tool route, product-module/configuration failure, changed tool configuration, permitted or unspecified supply, or uncertain probe/identity/environment retains the fix loop. A confirmed prohibited-tool blocker wins even with other product findings: leave them unrepaired and preserve phase `FAIL`, findings, raw streams and sealed manifests unchanged. Record the probe and constraint citation separately in parent halt evidence; no repair means no round increment. Otherwise spawn IMPLEMENT-engine agent with the build_gate findings as input, then run the common post-fix checkpoint with origin `build_gate`. On second FAIL with `state.rounds.global >= state.rounds.max_rounds` → halt with verdict `BLOCKED:build-gate-exhausted`.
|
|
310
310
|
- `BLOCKED:build-env-underprovisioned` → halt immediately with the denied operation, original command, and process-evidence manifest/id; do not enter the product fix loop.
|
|
311
311
|
|
|
312
312
|
## PHASE 4: CLEANUP
|
|
@@ -75,8 +75,8 @@ When the rules are silent (rare — pathological goal text), default to `medium`
|
|
|
75
75
|
The internal mini-spec written for trivial / medium / large-assumptions paths must satisfy:
|
|
76
76
|
|
|
77
77
|
- `## Requirements` non-empty, each bullet testable (CLI command, test command, observable file change).
|
|
78
|
-
- For generated verification
|
|
79
|
-
- `## Verification` is preceded by a `<!-- devlyn:verification -->` sentinel on its own line directly above the heading — the machine locator `spec-verify-check.py` uses; the heading text itself is decorative and may be any language.
|
|
78
|
+
- For executable generated verification, put one fenced `json` object with `verification_commands` inside the sentinel-marked `## Verification` section. Generated mode reads this inline carrier, not a sibling file. Follow `../../devlyn:ideate/references/spec-template.md` § "Sibling file: `spec.expected.json`" for constraint coverage, diff scope and violating/allowed controls, but express those checks as executable `verification_commands`; sibling-only fields such as `required_files` and `forbidden_patterns` are rejected inline. Preserve uncovered semantics as source-review obligations.
|
|
79
|
+
- `## Verification` is preceded by a `<!-- devlyn:verification -->` sentinel on its own line directly above the heading — the machine locator `spec-verify-check.py` uses; the heading text itself is decorative and may be any language. When all Requirements are pure-design with no runnable acceptance check, put `{"pure_design": true, "verification_commands": []}` in the fenced `json` block and retain semantic source-review obligations. This explicit declaration is required; a missing block, an unmarked empty list, or `pure_design: true` with commands is invalid.
|
|
80
80
|
- If a free-form goal includes pair-evidence intent and already includes an actionable solo-headroom hypothesis, preserve that literal hypothesis in `.devlyn/criteria.generated.md` unchanged enough for VERIFY to detect `solo-headroom hypothesis`, `solo_claude`, `miss`, and the backticked observable command line that itself contains `miss`, emit the canonical `spec.solo_headroom_hypothesis` pair trigger reason, and satisfy regenerated-evidence checks such as `benchmark audit --require-hypothesis-trigger`.
|
|
81
81
|
- If a free-form goal includes unmeasured pair-candidate intent and already includes solo ceiling avoidance, preserve that literal note in `.devlyn/criteria.generated.md` unchanged enough for reviewers to see `solo ceiling avoidance`, `solo_claude`, and the concrete difference from rejected or solo-saturated controls such as `S2`-`S6`.
|
|
82
82
|
- Free-form mode mini-specs are written to `.devlyn/criteria.generated.md` (not to a roadmap path) — this is run-scoped artifact, not a documented spec.
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
Per-engine adapter header is prepended at runtime. BUILD_GATE is mechanical / deterministic — same commands CI / Docker / production run.
|
|
4
4
|
|
|
5
5
|
<role>
|
|
6
|
-
Run language-specific gates and the spec literal-match verification. Emit findings; the orchestrator's fix loop consumes them.
|
|
6
|
+
Run language-specific gates and the spec literal-match verification. Emit findings; the orchestrator's fix loop consumes them. Git staging and commits belong to the parent IMPLEMENT checkpoint; verify any staging prerequisite with read-only Git inspection, never repeat `git add` or forward task staging instructions as worker actions.
|
|
7
7
|
</role>
|
|
8
8
|
|
|
9
9
|
<capability_contract>
|
|
@@ -46,7 +46,7 @@ Detect the project shape from files in `state.base_ref.sha`:
|
|
|
46
46
|
</detection>
|
|
47
47
|
|
|
48
48
|
<gates>
|
|
49
|
-
Run in
|
|
49
|
+
Resolve the concrete commands for steps 1–3; detection examples are not command identities. Run them in order unless step 4's current valid literal contract, using its source precedence and checker defaults, schedules the exact command with the same source/test inputs, working directory and effective environment. Establish the work root and normalized child environment from the checker/runner call sites and the current invocation; a manifest's command string alone does not establish them. The literal must expect exit 0, cover every gate assertion and use the same effective timeout as the planned gate invocation; uncertain matches run normally. Defer a matching gate to step 4 and derive its usual per-error findings and severity from that invocation's validated current BUILD_GATE run/round raw streams, citing the evidence id. A completed nonzero exit still supplies the gate's usual failure findings. If step 4 leaves no validated exit-kind result for a deferred gate, run that gate normally and append its findings, preserving step 4's failures; capability denials retain the stop contract above. Keep every literal invocation and independent post-CLEANUP VERIFY. Each gate emits findings into `.devlyn/build_gate.findings.jsonl`:
|
|
50
50
|
|
|
51
51
|
1. **Type check** (TypeScript / mypy / etc.). Each error → one finding, severity `HIGH`, rule `correctness.type-check`.
|
|
52
52
|
2. **Lint**. Run a recognized configured language linter (for example, ESLint with a config, `ruff`, or `clippy`) and/or the exact `package.json` `scripts.lint` command. A declared specialized `lint:*` script (for example, `lint:json`) is not the general language lint gate on the strength of its declaration alone. If the spec's verification commands explicitly name such a specialized command, step 4 executes it and preserves its real failure severity. If no linter is applicable, log an explicit SKIP in `.devlyn/build_gate.log.md` and emit zero lint findings. Each error → finding, severity `MEDIUM`, rule `quality.lint`. Warnings stay LOW unless the spec elevates them.
|
|
@@ -59,7 +59,8 @@ Append all findings; do not stop on the first failure.
|
|
|
59
59
|
|
|
60
60
|
<output>
|
|
61
61
|
- `.devlyn/build_gate.findings.jsonl` — JSONL stream, one finding per line. Schema: `{id, rule_id, severity, file, line, message, fix_hint, criterion_ref}`.
|
|
62
|
-
- `.devlyn/build_gate.
|
|
62
|
+
- A completed checker preflight rejection writes `spec-verify.results.json` with `preflight_failure` and the original CRITICAL finding's path/digest. Retain that source (default `.devlyn/spec-verify-findings.jsonl`) and append its finding to `.devlyn/build_gate.findings.jsonl`. Earlier gate observations remain bound, but no spec command is claimed to have run. An absent results file still follows the interrupted-observation `BLOCKED` path.
|
|
63
|
+
- `.devlyn/build_gate.log.md` — human-readable gate results with raw output or links to complete raw-output files, using sealed artifacts where available. Retain complete inventories/hash maps in `.devlyn/` files; report their paths, digests and relevant deltas instead of dumping them into the conversation.
|
|
63
64
|
- Report `PASS` if zero CRITICAL/HIGH findings, `FAIL` for genuine product findings, or `BLOCKED:build-env-underprovisioned` only for the evidence-backed capability path above. A capability blocker leaves no product finding. Do not edit `pipeline.state.json` yourself — the orchestrator records it via `state-phase-write.py` from these artifacts.
|
|
64
65
|
</output>
|
|
65
66
|
|
|
@@ -10,11 +10,13 @@ Independent quality layer. You answer one question: did the diff deliver what th
|
|
|
10
10
|
- `spec.md` (or `.devlyn/criteria.generated.md` for free-form mode) — the contract.
|
|
11
11
|
- `spec.expected.json` — the mechanical acceptance contract per `_shared/expected.schema.json`.
|
|
12
12
|
- The cumulative diff against `state.base_ref.sha`.
|
|
13
|
-
- The source hash (`state.source.spec_sha256` for spec mode, `state.source.criteria_sha256` for generated free-form mode) — re-read the source contract from disk and confirm the hash matches; if it does not,
|
|
14
|
-
- `.devlyn/spec-verify.results.json` plus
|
|
13
|
+
- The source hash (`state.source.spec_sha256` for spec mode, `state.source.criteria_sha256` for generated free-form mode) — re-read the source contract from disk and confirm the hash matches; if it does not, emit a verdict-binding finding with reason `source_sha256_mismatch` and terminal verdict `BLOCKED`, then stop reviewing without editing state.
|
|
14
|
+
- `.devlyn/spec-verify.results.json` plus any required validated VERIFY
|
|
15
15
|
process-evidence manifest and raw stdout/stderr streams named by its
|
|
16
16
|
`process_evidence` carrier. These are immutable MECHANICAL results; rehash
|
|
17
|
-
every named byte before JUDGE spawn and again during merge.
|
|
17
|
+
every named byte before JUDGE spawn and again during merge. Valid pure-design
|
|
18
|
+
contracts with no executable obligations have `commands: []` and
|
|
19
|
+
`process_evidence: null`.
|
|
18
20
|
|
|
19
21
|
You do NOT receive: PLAN, IMPLEMENT's reasoning, BUILD_GATE's findings, CLEANUP's allowlist negotiations. Reading those would compromise independence. Inspect authorized source, diff and sealed evidence using native read/search tools or non-mutating shell commands; executable verification belongs exclusively to MECHANICAL.
|
|
20
22
|
</input>
|
|
@@ -40,14 +42,14 @@ On the constrained Windows read route, the orchestrator supplies the complete sp
|
|
|
40
42
|
|
|
41
43
|
Grade the diff against the spec on rubric axes:
|
|
42
44
|
|
|
43
|
-
- **Spec compliance** —
|
|
45
|
+
- **Spec compliance** — does cited evidence show how every applicable Requirement and Constraint is satisfied?
|
|
44
46
|
- **Scope** — does the diff touch only files PLAN listed (or the cleanup allowlist)? Out-of-scope file = HIGH finding `scope.out-of-scope-violation`.
|
|
45
47
|
- **Quality** — does the implementation follow the framework's idiomatic patterns, or are there hand-rolled helpers replacing standard primitives? `design.unidiomatic-pattern` MEDIUM if so.
|
|
46
48
|
- **Consistency** — internal style (naming, error shape, module boundaries) consistent with the surrounding code.
|
|
47
49
|
|
|
48
50
|
**Bounded primary review**: the primary JUDGE makes one broad pass over the
|
|
49
51
|
source contract, sealed MECHANICAL carrier, and cumulative diff, covering all
|
|
50
|
-
four rubric axes and every binding Requirement clause. It then makes one
|
|
52
|
+
four rubric axes and every binding Requirement and Constraint clause. It then makes one
|
|
51
53
|
targeted interaction pass over the clauses the broad pass left unresolved.
|
|
52
54
|
Before any third pass, emit the required terminal result. If R1–R8 or another
|
|
53
55
|
spec axis remains uncovered, emit a verdict-binding BLOCKED coverage finding
|
|
@@ -55,7 +57,7 @@ instead of continuing or assuming PASS.
|
|
|
55
57
|
|
|
56
58
|
For each finding, write file:line evidence. Do not paraphrase code; quote it.
|
|
57
59
|
|
|
58
|
-
**Clause-level check**: split each Requirement into its binding clauses before
|
|
60
|
+
**Clause-level check**: split each Requirement and Constraint into its binding clauses before
|
|
59
61
|
you pass it. Words like `before`, `after`, `once`, `always`, `never`,
|
|
60
62
|
`regardless`, `irrelevant`, `permanent`, `idempotent`, `duplicate`, `raw`, and
|
|
61
63
|
`signature` usually encode a separate invariant. A passing verification command
|
|
@@ -90,7 +92,7 @@ risk probes and present in the sealed MECHANICAL evidence. Missing coverage is
|
|
|
90
92
|
a verdict-binding finding; review the implementation's clause and code order
|
|
91
93
|
without inventing a replacement command.
|
|
92
94
|
|
|
93
|
-
**Coverage check**:
|
|
95
|
+
**Coverage check**: account for every applicable Requirement and Constraint using sealed MECHANICAL evidence for required executable checks and cited source/design evidence for pure-design clauses or explicitly retained source-review obligations. Inspect applicable unchanged code and documentation; absence of a code change alone is not missing coverage. Source review never substitutes for required executable coverage. For any unsupported clause, emit a verdict-binding coverage finding identifying the missing evidence. JUDGE does not run checks or edit state; the orchestrator records `state.verify.coverage_failed: true` from coverage findings before merge.
|
|
94
96
|
|
|
95
97
|
**Verdict-binding check**: a demonstrated violation of an applicable mandatory
|
|
96
98
|
task, public, or existing test contract is binding, including unmet new
|
|
@@ -54,7 +54,7 @@ Single authoritative verdict source for `/devlyn:resolve`. The orchestrator bran
|
|
|
54
54
|
- **engine** — any engine name with a shipped adapter (`_shared/adapters/<name>.md`); `"claude"` and `"codex"` today. A required unavailable engine stops the run with `BLOCKED:<engine>-unavailable`.
|
|
55
55
|
- **engine_source** — `"flag" | "engines.json" | "default"` — provenance of the resolved executor engine (`_shared/engine-preflight.md#role-resolution`). Optional on archived pre-iter-0038 runs; absent means `default`.
|
|
56
56
|
- **source** — downstream contract provenance. Spec/verify-only set `type: "spec"`, `spec_path`, and `spec_sha256`. Free-form sets `type: "generated"`, `goal_path: ".devlyn/goal.raw.txt"` + exact-byte `goal_sha256`, and `criteria_path: ".devlyn/criteria.generated.md"` + raw-byte `criteria_sha256`. VERIFY re-checks its contract hash.
|
|
57
|
-
- **`.devlyn/external-diff.patch` artifact** — verify-only
|
|
57
|
+
- **`.devlyn/external-diff.patch` artifact** — verify-only Git patch with `a/` and `b/` path prefixes (`git diff --binary --src-prefix=a/ --dst-prefix=b/`). A zero-byte file means no changes; file-path checks reject malformed or other-prefix input. File exclusions cover both names in rename/copy headers. The verifier fails closed if the artifact exists outside `"verify-only"` mode.
|
|
58
58
|
- **risk_profile** — PHASE 0 routing state. `high_risk` controls automatic risk probes; `risk_probes_enabled` / `risk_probes_explicit` preserve their current semantics; `pair_default_enabled` is false only for explicit `--no-pair`. `risk_profile` must remain an object with boolean `high_risk`, `risk_probes_enabled`, `risk_probes_explicit`, and `pair_default_enabled` fields when present, plus `reasons` as a string list. Malformed state blocks VERIFY because it can hide required routes.
|
|
59
59
|
- **risk_probes_digest** — top-level sha256 written by PHASE 1.5 after probe validation; BUILD_GATE/VERIFY replay semantics live in `phases/build-gate.md` step 4.
|
|
60
60
|
- **process_evidence** — absent or JSON null for legacy runs and new runs with no captured obligation; otherwise an append-only array of `{phase, round, manifest: {path, sha256}, streams: [{id, stdout: {path, sha256}, stderr: {path, sha256}}]}` carriers. Paths are worktree-relative and live under `.devlyn/process-evidence/<run_id>/<phase>/round-<round>/`. A successful IMPLEMENT completion/transition validates every sibling `spec.expected.json.process_evidence[]` item declared for `phase: "implement"`, rehashes both raw streams (including zero-byte files), and appends the carrier before accepting the checkpoint. Missing, altered, escaping, duplicate-id, or expectation-mismatched evidence blocks without a state mutation. Later phases reuse the same carrier shape; no schema-major bump is required because readers must accept absent/null legacy state.
|
|
@@ -67,7 +67,7 @@ Single authoritative verdict source for `/devlyn:resolve`. The orchestrator bran
|
|
|
67
67
|
- **implement_passed_sha** — captured at end of PHASE 2; null until then. Activates the post-implement invariant for SURFACE_CLOSE, CLEANUP, and VERIFY.
|
|
68
68
|
- **criteria** — generated from spec's `## Requirements` checklist (one per `- [ ]`). `status: pending → implemented` is the legal transition. `failed_by_finding_ids` populates when VERIFY surfaces a finding tied to a criterion.
|
|
69
69
|
- **`.devlyn/untracked.baseline` artifact** — written at PHASE 0 (`spec-verify-check.py --write-untracked-baseline`); BUILD_GATE flags created-during-run unauthorized untracked files against it (`.devlyn/` exempt; semantics in `phases/build-gate.md` step 4).
|
|
70
|
-
- **verify.coverage_failed** — outcome-dependent telemetry set when JUDGE
|
|
70
|
+
- **verify.coverage_failed** — outcome-dependent telemetry set by the orchestrator when JUDGE reports missing clause evidence. It no longer gates pair dispatch: after MECHANICAL passes, `pair.default` dispatches both judges concurrently whenever `pair_default_enabled != false` and the OTHER engine is available. An orchestrator without foreground parallel dispatch runs the same two required judges sequentially; a primary blocker never skips the pair. A verdict-binding MECHANICAL blocker still skips both. Legacy complexity values remain accepted only for archived compatibility.
|
|
71
71
|
- **verify.pair_trigger** — strict decision state: `{ "eligible": boolean, "reasons": string[], "skipped_reason": string|null }`. Schema v3.0 eligible state requires `pair.default` plus every applicable telemetry reason and `skipped_reason: null`; outcome-dependent reasons are appended after both judges return. Canonical reasons are `pair.default`, `mode.verify-only`, `mode.pair-verify`, `complexity.high`, `complexity.large`, `spec.complexity.high`, `spec.complexity.large`, `spec.solo_headroom_hypothesis`, `risk.high`, `risk_probes.enabled`, `risk_probes.present`, `coverage.failed`, `mechanical.warning`, and `judge.warning`. Ineligible new-run state has empty reasons and only `user_no_pair`, `mechanical_blocker`, `auto_pair_other_engine_unavailable`, or null; `primary_judge_blocker` remains parser-recognized only for archived v2.0 replay and retains its existing pre-known-reason rejection. Explicit `mode.pair-verify` cannot use the unavailable-engine skip. Missing, contradictory, incomplete, or unknown trigger state BLOCKs VERIFY.
|
|
72
72
|
|
|
73
73
|
## Per-phase shape
|
|
@@ -24,6 +24,33 @@ names look generated. An interrupted allocation stays blocked for inspection;
|
|
|
24
24
|
do not delete its receipt and enroll the resulting branch. Pre-existing tasks
|
|
25
25
|
remain owner-managed and cannot use this helper retroactively.
|
|
26
26
|
|
|
27
|
+
Allocation also returns a receipt-owned `scratch` directory. Put disposable
|
|
28
|
+
build intermediates there (for example, set
|
|
29
|
+
`CARGO_TARGET_DIR` to `<scratch>/target`). Keep source checkouts, Git data,
|
|
30
|
+
lockfiles, reports and restart evidence outside scratch. Do not create unowned
|
|
31
|
+
temporary build trees or preserve them by copying them into evidence custody.
|
|
32
|
+
Prefer `TemporaryDirectory`/`finally` for short-lived test fixtures.
|
|
33
|
+
|
|
34
|
+
After waiting for task writers, `complete --writers-stopped` empties this
|
|
35
|
+
scratch on delivery returns, including local-only and pending-PR routes. To
|
|
36
|
+
release build caches when parking or after a failed run, use:
|
|
37
|
+
|
|
38
|
+
```sh
|
|
39
|
+
python3 "$DEVLYN_SHARED_DIR/task-complete.py" clean-scratch \
|
|
40
|
+
--receipt '<returned receipt.json>' --writers-stopped
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
This empties only the prospectively owned scratch, preserves its directory
|
|
44
|
+
identity for interrupted cleanup and later builds, checks live users and reports
|
|
45
|
+
the logical byte count separately from actual free disk space. It does not depend on a product PASS or rewrite that verdict.
|
|
46
|
+
Unknown historical roots, source/recovery data, shared caches and terminal
|
|
47
|
+
history are never adopted or swept. A refused cleanup does not block source
|
|
48
|
+
delivery; it stays visible in the handoff with its receipt and retry command
|
|
49
|
+
(`CLEANUP_PENDING` after delivered source). No task is described as cleaned
|
|
50
|
+
while owned disposable files remain. On resumption, finish any pending scratch
|
|
51
|
+
cleanup before allocating more temporary storage. Rebuild from retained inputs
|
|
52
|
+
when needed; cleanup is not an instruction to restart parked work.
|
|
53
|
+
|
|
27
54
|
## Accept a scoped commit
|
|
28
55
|
|
|
29
56
|
Direct work: finish actual decisive checks and diff review, stage only the
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "devlyn-cli",
|
|
3
|
-
"version": "3.1.
|
|
3
|
+
"version": "3.1.3",
|
|
4
4
|
"description": "Loop & harness engineering for AI coding agents (Claude Code, Codex, and any AGENTS.md-driven agent) — take intent to shipped, engineer-quality software hands-free with phase-gated pipelines and agent orchestration",
|
|
5
5
|
"homepage": "https://github.com/fysoul17/devlyn-cli#readme",
|
|
6
6
|
"bin": {
|
package/scripts/lint-skills.sh
CHANGED
|
@@ -356,7 +356,7 @@ PY
|
|
|
356
356
|
|
|
357
357
|
incomplete="$tmp_install_marker/incomplete"
|
|
358
358
|
mkdir -p "$incomplete/package" "$incomplete/home/.codex/skills" "$incomplete/claude/.claude/skills" "$incomplete/codex"
|
|
359
|
-
cp -R bin config package.json "$incomplete/package/"
|
|
359
|
+
cp -R bin config package.json AGENTS.md CLAUDE.md "$incomplete/package/"
|
|
360
360
|
rm -rf "$incomplete/package/config/skills/devlyn:queue"
|
|
361
361
|
printf '{"version":"stale"}\n' > "$incomplete/home/.codex/skills/.devlyn-install.json"
|
|
362
362
|
printf '{"version":"stale"}\n' > "$incomplete/claude/.claude/skills/.devlyn-install.json"
|
|
@@ -1298,7 +1298,7 @@ done
|
|
|
1298
1298
|
for pattern in \
|
|
1299
1299
|
'def stage_from_expected' \
|
|
1300
1300
|
'stage_from_expected(' \
|
|
1301
|
-
'
|
|
1301
|
+
'contract_found, _staged, expected_error, expected_path' \
|
|
1302
1302
|
'def expected_contract_findings' \
|
|
1303
1303
|
'correctness.forbidden-pattern' \
|
|
1304
1304
|
'scope.max-deps-added-exceeded' \
|