devrites 3.1.0 → 3.2.0
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/CHANGELOG.md +6 -0
- package/README.md +20 -8
- package/docs/adr/0012-semantic-workspace-upgrades.md +77 -0
- package/docs/adr/README.md +1 -0
- package/docs/architecture.md +31 -10
- package/docs/cli.md +10 -4
- package/docs/command-map.md +15 -6
- package/docs/engine/commands.md +6 -0
- package/docs/engine/workspace-schema.md +10 -1
- package/docs/flow.md +12 -7
- package/docs/orchestration.md +2 -2
- package/docs/quick-reference.md +4 -0
- package/docs/skills.md +8 -5
- package/docs/usage.md +31 -5
- package/engine/internal/lib/buildreadiness.go +9 -1
- package/engine/internal/lib/readiness_contract.json +8 -1
- package/engine/internal/lib/readinessartifact.go +28 -5
- package/engine/internal/lib/readinessartifact_test.go +105 -4
- package/engine/testdata/golden/TestParityBuildReadiness/arg=legacycontract.golden +1 -0
- package/engine/tests/parity_buildreadiness_test.go +27 -1
- package/pack/.claude/agents/devrites-plan-drafter.md +3 -1
- package/pack/.claude/agents/devrites-upgrade-planner.md +100 -0
- package/pack/.claude/skills/devrites-lib/SKILL.md +2 -1
- package/pack/.claude/skills/devrites-lib/reference/intent-map.md +1 -0
- package/pack/.claude/skills/devrites-lib/reference/standards/agents.md +3 -1
- package/pack/.claude/skills/devrites-lib/reference/workspace-artifact-schema.md +17 -0
- package/pack/.claude/skills/rite/SKILL.md +2 -0
- package/pack/.claude/skills/rite/reference/menu.md +5 -1
- package/pack/.claude/skills/rite-build/reference/afk-discipline.md +3 -1
- package/pack/.claude/skills/rite-build/reference/phase-contract.md +3 -3
- package/pack/.claude/skills/rite-build/reference/spec-drift-guard.md +10 -4
- package/pack/.claude/skills/rite-clarify/SKILL.md +2 -1
- package/pack/.claude/skills/rite-clarify/reference/decision-coverage.md +3 -1
- package/pack/.claude/skills/rite-define/SKILL.md +2 -1
- package/pack/.claude/skills/rite-define/reference/plan-template.md +3 -1
- package/pack/.claude/skills/rite-plan/SKILL.md +4 -1
- package/pack/.claude/skills/rite-upgrade/SKILL.md +125 -0
- package/pack/.claude/skills/rite-vet/SKILL.md +6 -2
- package/pack/.claude/skills/rite-vet/reference/artifacts.md +9 -1
- package/pack/generated/claude/agents/devrites-plan-drafter.md +3 -1
- package/pack/generated/claude/agents/devrites-upgrade-planner.md +100 -0
- package/pack/generated/claude/skills/devrites-lib/SKILL.md +2 -1
- package/pack/generated/claude/skills/devrites-lib/reference/intent-map.md +1 -0
- package/pack/generated/claude/skills/devrites-lib/reference/standards/agents.md +3 -1
- package/pack/generated/claude/skills/devrites-lib/reference/workspace-artifact-schema.md +17 -0
- package/pack/generated/claude/skills/rite/SKILL.md +2 -0
- package/pack/generated/claude/skills/rite/reference/menu.md +5 -1
- package/pack/generated/claude/skills/rite-build/reference/afk-discipline.md +3 -1
- package/pack/generated/claude/skills/rite-build/reference/phase-contract.md +3 -3
- package/pack/generated/claude/skills/rite-build/reference/spec-drift-guard.md +10 -4
- package/pack/generated/claude/skills/rite-clarify/SKILL.md +2 -1
- package/pack/generated/claude/skills/rite-clarify/reference/decision-coverage.md +3 -1
- package/pack/generated/claude/skills/rite-define/SKILL.md +2 -1
- package/pack/generated/claude/skills/rite-define/reference/plan-template.md +3 -1
- package/pack/generated/claude/skills/rite-plan/SKILL.md +4 -1
- package/pack/generated/claude/skills/rite-upgrade/SKILL.md +125 -0
- package/pack/generated/claude/skills/rite-vet/SKILL.md +6 -2
- package/pack/generated/claude/skills/rite-vet/reference/artifacts.md +9 -1
- package/pack/generated/codex/agents/devrites-plan-drafter.toml +3 -1
- package/pack/generated/codex/agents/devrites-upgrade-planner.toml +106 -0
- package/pack/generated/codex/skills/devrites-lib/SKILL.md +2 -1
- package/pack/generated/codex/skills/devrites-lib/reference/intent-map.md +1 -0
- package/pack/generated/codex/skills/devrites-lib/reference/standards/agents.md +3 -1
- package/pack/generated/codex/skills/devrites-lib/reference/workspace-artifact-schema.md +17 -0
- package/pack/generated/codex/skills/rite/SKILL.md +2 -0
- package/pack/generated/codex/skills/rite/reference/menu.md +5 -1
- package/pack/generated/codex/skills/rite-build/reference/afk-discipline.md +3 -1
- package/pack/generated/codex/skills/rite-build/reference/phase-contract.md +3 -3
- package/pack/generated/codex/skills/rite-build/reference/spec-drift-guard.md +10 -4
- package/pack/generated/codex/skills/rite-clarify/SKILL.md +2 -1
- package/pack/generated/codex/skills/rite-clarify/reference/decision-coverage.md +3 -1
- package/pack/generated/codex/skills/rite-define/SKILL.md +2 -1
- package/pack/generated/codex/skills/rite-define/reference/plan-template.md +3 -1
- package/pack/generated/codex/skills/rite-plan/SKILL.md +4 -1
- package/pack/generated/codex/skills/rite-upgrade/SKILL.md +141 -0
- package/pack/generated/codex/skills/rite-upgrade/agents/openai.yaml +2 -0
- package/pack/generated/codex/skills/rite-vet/SKILL.md +6 -2
- package/pack/generated/codex/skills/rite-vet/reference/artifacts.md +9 -1
- package/package.json +1 -1
- package/scripts/run-outcome-evals.sh +33 -2
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: rite-upgrade
|
|
3
|
+
description: User-invoked semantic upgrade for an active legacy DevRites workspace. Reconciles unfinished planning with the installed workflow contract while preserving completed work and history.
|
|
4
|
+
argument-hint: "[feature-slug]"
|
|
5
|
+
user-invocable: true
|
|
6
|
+
disable-model-invocation: true
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Codex compatibility
|
|
10
|
+
|
|
11
|
+
This is the Codex mirror of a DevRites skill. In Codex:
|
|
12
|
+
|
|
13
|
+
- Load DevRites engineering standards from `.agents/skills/devrites-lib/reference/standards/`. Read `.agents/skills/devrites-lib/reference/standards/core.md` before workflow work, then load the other `.agents/skills/devrites-lib/reference/standards/*.md` files exactly when this skill asks for them.
|
|
14
|
+
- Use the installed `devrites-engine` binary as the canonical runtime helper surface for orientation, gates, and state mutation.
|
|
15
|
+
- **Invocation and dispatch are different:** invoke means run a skill in this context; dispatch means start a fresh agent with `spawn_agent`, await it, and reconcile its result. Never describe inline skill work as a dispatch.
|
|
16
|
+
- For every DevRites specialist or writer dispatch, first call `spawn_agent` with the named `devrites-<role>` custom role. The matching project contract is `.codex/agents/devrites-<role>.toml`.
|
|
17
|
+
- If `spawn_agent` is callable but a named read-only role is unavailable, use generic `explorer` only when the host proves that run has a runtime-enforced read-only sandbox. Tell it to read `.codex/agents/devrites-<role>.toml`, follow its `developer_instructions`, and execute the unchanged packet. A missing read-only custom role is not evidence that spawning is unavailable.
|
|
18
|
+
- Never dispatch generic `worker` for `devrites-slice-wright` unless the host proves that worker run carries exact DevRites identity and the same `.wright-allowlist` enforcement as the named role. Codex reports a generic run as `agent_type=worker`, so the generated global hooks cannot prove that binding. Reject that unsafe rung and use the documented labelled inline wright path with `.reconcile-inline` plus the full reconcile gate.
|
|
19
|
+
- If the host cannot prove the generic explorer is runtime read-only, reject that rung too. Only when no spawn primitive exists or a higher-priority policy rejects a safe spawn may the root run the documented discipline inline. Label it `independence: fallback`, never call it independent, and apply every fallback risk gate. An unbound generic wright or unconfined generic explorer is such a safety rejection, not evidence that no agents exist.
|
|
20
|
+
- Wait for every required fresh-context dispatch before reconciling or advancing. A backgrounded or lost result is incomplete.
|
|
21
|
+
- Codex project hooks are installed in `.codex/hooks.json`; declared-leaf hooks are scoped inside `.codex/agents/devrites-*.toml`. Review and trust them with `/hooks` before relying on hook enforcement.
|
|
22
|
+
- When this skill asks a HITL question via `AskUserQuestion`: Codex's equivalent (`request_user_input`) exists only in Plan mode. Outside Plan mode, render the option set as a plain numbered list in chat and **end the turn** so the human answers: NEVER silently pick an option yourself; auto-picking is AFK's contract, gated by the `.devrites/AFK` sentinel.
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
# $rite-upgrade: bring an active workspace onto the current contract
|
|
26
|
+
|
|
27
|
+
Use this when a workspace created under older DevRites rules cannot safely continue with
|
|
28
|
+
the installed pack. It reconciles the workspace to the current desired state; it does not
|
|
29
|
+
replay a chain of release-specific scripts. Structural `devrites-engine migrate` remains a
|
|
30
|
+
separate first step.
|
|
31
|
+
|
|
32
|
+
Current semantic contract: `devrites.readiness-artifacts.v2`.
|
|
33
|
+
|
|
34
|
+
## Rules consulted
|
|
35
|
+
|
|
36
|
+
Read `devrites-lib/reference/standards/core.md`,
|
|
37
|
+
`devrites-lib/reference/standards/agents.md`,
|
|
38
|
+
`devrites-lib/reference/workspace-artifact-schema.md`, and the current Clarify, Define,
|
|
39
|
+
Plan, Vet, Converge, and Build phase contracts needed by the assessment.
|
|
40
|
+
|
|
41
|
+
## Invariants
|
|
42
|
+
|
|
43
|
+
- Never edit application source, tests, dependencies, Git state, or historical evidence.
|
|
44
|
+
- Preserve completed-slice identity, status, acceptance, dependencies, historical proof,
|
|
45
|
+
answered questions, and `touched-files.md`.
|
|
46
|
+
- Reassess only unfinished planning. Archived or `done` workspaces are a no-op.
|
|
47
|
+
- Never downgrade a workspace that names a future semantic contract.
|
|
48
|
+
- This is a recovery command, not a lifecycle phase; never write `Phase: upgrade`.
|
|
49
|
+
- Durable plans contain portable repository commands, not RTK/local aliases, user-specific
|
|
50
|
+
absolute paths, or temporary proof trees. Runtime packets may name an execution adapter;
|
|
51
|
+
evidence may record both logical and executed forms.
|
|
52
|
+
- Ask at most one coherent question, and only for product, policy, irreversible risk, or
|
|
53
|
+
human-only access/action. Retry and repair authorization is agent-owned.
|
|
54
|
+
- The explicit `$rite-upgrade` invocation authorizes the bounded workspace reconciliation.
|
|
55
|
+
The root remains the only canonical writer.
|
|
56
|
+
|
|
57
|
+
## Workflow
|
|
58
|
+
|
|
59
|
+
0. **Orient and normalize structure.** Read the active slug or `$ARGUMENTS`. Run:
|
|
60
|
+
```bash
|
|
61
|
+
devrites-engine doctor --verbose; echo "doctor rc=$?"
|
|
62
|
+
```
|
|
63
|
+
A binary/pack integrity mismatch stops at `$rite-doctor`; do not run migration or
|
|
64
|
+
mutate semantic artifacts. Once healthy, orient without writing:
|
|
65
|
+
```bash
|
|
66
|
+
devrites-engine preamble [feature-slug]
|
|
67
|
+
devrites-engine snapshot [feature-slug]
|
|
68
|
+
```
|
|
69
|
+
A missing workspace stops at `$rite-spec`; an archived or `Status: done` workspace is
|
|
70
|
+
a no-op. For an active healthy workspace, run:
|
|
71
|
+
```bash
|
|
72
|
+
devrites-engine migrate
|
|
73
|
+
devrites-engine preamble [feature-slug]
|
|
74
|
+
devrites-engine snapshot [feature-slug]
|
|
75
|
+
```
|
|
76
|
+
If every semantic artifact names the current contract and `build-readiness` passes,
|
|
77
|
+
report a no-op.
|
|
78
|
+
1. **Freeze the preservation baseline.** Create the standard orchestrator-controlled
|
|
79
|
+
`agent-packet/v1` baseline. Include exact paths for current phase/artifact contracts,
|
|
80
|
+
`state.md`, `spec.md`, `decision-coverage.md`, `architecture.md`, `plan.md`, `tasks.md`,
|
|
81
|
+
`traceability.md`, `test-plan.md`, `eng-review.md`, `questions.md`, `decisions.md`,
|
|
82
|
+
`assumptions.md`, `drift.md`, `evidence.md`, and `touched-files.md` when present. Record
|
|
83
|
+
the source diff identity plus the protected identity/status/acceptance/dependency
|
|
84
|
+
fields for every completed slice and each preserved artifact identity. Freeze the
|
|
85
|
+
workspace while it is assessed.
|
|
86
|
+
2. **Classify from fresh context.** Dispatch `devrites-upgrade-planner` with objective
|
|
87
|
+
`reconcile this workspace with devrites.readiness-artifacts.v2`, the exact baseline,
|
|
88
|
+
and budgets `25 files / 2,000 loaded lines / 180 result lines`. Require one validated
|
|
89
|
+
`upgrade-assessment`. The agent writes nothing and asks nothing.
|
|
90
|
+
3. **Reconcile ownership.** Reject stale, malformed, or preservation-breaking advice.
|
|
91
|
+
Dispatch `devrites-evidence-scout` only for a bounded missing fact. Drop an open
|
|
92
|
+
retry/tool-repair question with `devrites-engine resolve --drop <qid>
|
|
93
|
+
"superseded by explicit semantic upgrade; agent-owned recovery"` and continue. Keep a
|
|
94
|
+
genuine existing human gate intact; if a newly discovered human-owned choice is
|
|
95
|
+
unavoidable, persist one option packet and stop.
|
|
96
|
+
4. **Apply current desired state in the root.**
|
|
97
|
+
- Remove obsolete old-engine reconstruction, old workflow hashes, temporary proof
|
|
98
|
+
recipes, and host-local wrappers from active `plan.md`, `tasks.md`, and
|
|
99
|
+
`test-plan.md`. Keep historical evidence unchanged.
|
|
100
|
+
- Re-run Clarify against unfinished intent until `Decision coverage: CLEAR`; it writes
|
|
101
|
+
exactly one `DevRites contract: devrites.readiness-artifacts.v2` field. Do not stamp a
|
|
102
|
+
marker over stale content.
|
|
103
|
+
- Re-run Temper only where unfinished scope still needs strategic review.
|
|
104
|
+
- For unstarted planning, use the current Define contract. When active planning needs
|
|
105
|
+
normalization, dispatch `devrites-plan-drafter` in repair mode and reconcile only
|
|
106
|
+
pending slices. Preserve all completed slices without changing their protected fields.
|
|
107
|
+
For all-built active work, normalize only gate-required planning fields. Use Converge
|
|
108
|
+
only when live code and recorded intent genuinely differ.
|
|
109
|
+
- Invalidate stale engineering readiness after any planning edit. Run the full current
|
|
110
|
+
Vet contract, including its fresh plan reviewer, portable proof commands, preflight,
|
|
111
|
+
and digest refresh. Vet writes exactly one current contract field to `test-plan.md`
|
|
112
|
+
and `eng-review.md`.
|
|
113
|
+
5. **Verify preservation and readiness.** Recompute the frozen source diff, every protected
|
|
114
|
+
completed-slice field, `evidence.md`, answered-question records, and `touched-files.md`;
|
|
115
|
+
any mismatch is a hard stop and must be restored before proceeding. Then run:
|
|
116
|
+
```bash
|
|
117
|
+
devrites-engine build-readiness [feature-slug]; echo "readiness rc=$?"
|
|
118
|
+
```
|
|
119
|
+
Follow the gate's current route for `2` through `7`; `8` means the semantic
|
|
120
|
+
reconciliation is still incomplete. Finish only at `0`. Preserve the original active
|
|
121
|
+
build cursor when it still names the next pending slice; otherwise use the current
|
|
122
|
+
deterministic next action.
|
|
123
|
+
6. **STOP.** Do not start Build. A second `$rite-upgrade` must take the current-contract
|
|
124
|
+
no-op path.
|
|
125
|
+
|
|
126
|
+
## Output
|
|
127
|
+
|
|
128
|
+
Run `devrites-engine progress`, then use the shared completion reply contract in
|
|
129
|
+
`devrites-lib/reference/reply-contract.md`:
|
|
130
|
+
|
|
131
|
+
```text
|
|
132
|
+
Done: workspace <slug> upgraded to devrites.readiness-artifacts.v2.
|
|
133
|
+
Changed: <active planning artifacts only | none; already current>
|
|
134
|
+
Evidence: build-readiness rc=0; source/completed slices/history preserved
|
|
135
|
+
Open: <none | one genuine human gate>
|
|
136
|
+
Next: <snapshot next command>
|
|
137
|
+
Record: .devrites/work/<slug>/state.md
|
|
138
|
+
↻ Hygiene: /clear before the next lifecycle step
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
On a no-op, say so and keep the snapshot's current next command.
|
|
@@ -126,7 +126,9 @@ Pull the standard named by the active axis: `principles.md`, `patterns.md`,
|
|
|
126
126
|
```
|
|
127
127
|
Completion: every scenario and acceptance criterion maps to planned proof, every slice is
|
|
128
128
|
one-pass implementable, the Build-entry preflight is green or names an owned prerequisite,
|
|
129
|
-
and developer-facing plans have a predicted `devex.md` scorecard.
|
|
129
|
+
and developer-facing plans have a predicted `devex.md` scorecard. Durable proof commands
|
|
130
|
+
are portable repository commands; host-local wrappers belong only in runtime packets and
|
|
131
|
+
recorded execution evidence.
|
|
130
132
|
4a. **Forge gate.** `$rite-define` leaves `no` / `none` / `none`; Vet alone promotes under
|
|
131
133
|
[`rite-build/reference/forge.md`](../rite-build/reference/forge.md). Require a costly
|
|
132
134
|
unresolved architecture fork, 2–3 distinct complete contiguous `A`–`C` strategies, every
|
|
@@ -149,7 +151,9 @@ Pull the standard named by the active axis: `principles.md`, `patterns.md`,
|
|
|
149
151
|
devrites-engine analyze; echo "final analyze rc=$?"
|
|
150
152
|
```
|
|
151
153
|
Any non-zero result blocks the handoff. Then update `state.md`:
|
|
152
|
-
write one
|
|
154
|
+
write exactly one `DevRites contract: devrites.readiness-artifacts.v2` field to both
|
|
155
|
+
`test-plan.md` and `eng-review.md`, plus one typed field to `eng-review.md`:
|
|
156
|
+
`Implementation readiness: READY`,
|
|
153
157
|
`NEEDS CLARIFICATION`, or `NEEDS REPLAN`. Only READY sets `Phase: vet` and
|
|
154
158
|
`Next step: $rite-build`, after a final sweep leaves no foreseeable human choice except a
|
|
155
159
|
justified action-time checkpoint. Technical failure records its reproduction and
|
|
@@ -10,6 +10,7 @@ clobber.
|
|
|
10
10
|
```markdown
|
|
11
11
|
# Eng review: <slug>
|
|
12
12
|
Vetted: <iso> Cross-model: ran (codex) | off
|
|
13
|
+
DevRites contract: devrites.readiness-artifacts.v2
|
|
13
14
|
Implementation readiness: <READY | NEEDS CLARIFICATION | NEEDS REPLAN>
|
|
14
15
|
Readiness inputs SHA-256: <exact value from `devrites-engine readiness-digest engineering <slug>`>
|
|
15
16
|
|
|
@@ -74,6 +75,7 @@ test and where*, not implementation detail.
|
|
|
74
75
|
```markdown
|
|
75
76
|
# Test plan: <slug>
|
|
76
77
|
From $rite-vet on <iso>. Runner + conventions: <detected framework + command>.
|
|
78
|
+
DevRites contract: devrites.readiness-artifacts.v2
|
|
77
79
|
|
|
78
80
|
## Build-entry preflight
|
|
79
81
|
| Gate | Command | Cwd | Expected | Prerequisites | Provenance to recapture |
|
|
@@ -83,6 +85,10 @@ From $rite-vet on <iso>. Runner + conventions: <detected framework + command>.
|
|
|
83
85
|
Link any disposable parser fixture. Build evidence recomputes every digest; preflight values
|
|
84
86
|
are not post-build proof.
|
|
85
87
|
|
|
88
|
+
Commands in this durable artifact are portable repository commands: no RTK or local shell
|
|
89
|
+
aliases, user-specific absolute paths, or temporary proof trees. A runtime packet may name
|
|
90
|
+
an execution adapter, and evidence may record the portable and executed forms.
|
|
91
|
+
|
|
86
92
|
## Coverage diagram
|
|
87
93
|
<the ASCII code-paths + user-flows diagram from review-axes.md, with COVERAGE / GAPS / REGRESSIONS line>
|
|
88
94
|
|
|
@@ -163,6 +169,8 @@ acceptance/behavior changes route through the **Spec Drift Guard**.
|
|
|
163
169
|
`devrites-engine readiness-digest coverage <slug>` and replace the complete
|
|
164
170
|
`Coverage inputs SHA-256` line in `decision-coverage.md`. Only then run
|
|
165
171
|
`devrites-engine readiness-digest engineering <slug>` and copy its complete
|
|
166
|
-
field line into `eng-review.md`.
|
|
172
|
+
field line into `eng-review.md`. Write
|
|
173
|
+
`DevRites contract: devrites.readiness-artifacts.v2` exactly once in both artifacts
|
|
174
|
+
only after their current-contract review is complete. The build gate rejects a stale digest,
|
|
167
175
|
placeholders, non-passing preflight/readiness rows, empty tables, or an
|
|
168
176
|
acceptance criterion with no test mapping.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "devrites",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.2.0",
|
|
4
4
|
"description": "DevRites: a disciplined senior-engineer workflow pack for Claude Code and Codex",
|
|
5
5
|
"license": "SEE LICENSE IN LICENSE",
|
|
6
6
|
"homepage": "https://github.com/ViktorsBaikers/DevRites#readme",
|
|
@@ -83,11 +83,13 @@ stage_workspace() {
|
|
|
83
83
|
mkdir -p "$ws"
|
|
84
84
|
cp -R "$GOOD/." "$ws/"
|
|
85
85
|
if [ "$mode" = "readiness" ]; then
|
|
86
|
-
python3 - "$ws
|
|
86
|
+
python3 - "$ws" "$READINESS" <<'PY'
|
|
87
87
|
from pathlib import Path
|
|
88
|
+
import json
|
|
88
89
|
import sys
|
|
89
90
|
|
|
90
|
-
|
|
91
|
+
workspace, contract_path = map(Path, sys.argv[1:])
|
|
92
|
+
path = workspace / "state.md"
|
|
91
93
|
text = path.read_text()
|
|
92
94
|
for old, new in (
|
|
93
95
|
("| phase | done |", "| phase | build |"),
|
|
@@ -97,6 +99,35 @@ for old, new in (
|
|
|
97
99
|
raise SystemExit(f"{path}: expected exactly one {old!r}")
|
|
98
100
|
text = text.replace(old, new)
|
|
99
101
|
path.write_text(text)
|
|
102
|
+
|
|
103
|
+
contract = json.loads(contract_path.read_text())
|
|
104
|
+
field = contract["contractField"]
|
|
105
|
+
declaration = f"{field}: {contract['schema']}"
|
|
106
|
+
for name in ("decision-coverage.md", "test-plan.md", "eng-review.md"):
|
|
107
|
+
artifact = workspace / name
|
|
108
|
+
lines = [
|
|
109
|
+
line for line in artifact.read_text().splitlines()
|
|
110
|
+
if not line.startswith(f"{field}:")
|
|
111
|
+
]
|
|
112
|
+
lines[1:1] = ["", declaration]
|
|
113
|
+
artifact.write_text("\n".join(lines) + "\n")
|
|
114
|
+
PY
|
|
115
|
+
local engineering_digest
|
|
116
|
+
engineering_digest="$(
|
|
117
|
+
env DEVRITES_ROOT="$project" "$ENGINE" readiness-digest engineering "$slug"
|
|
118
|
+
)"
|
|
119
|
+
python3 - "$ws/eng-review.md" "$engineering_digest" <<'PY'
|
|
120
|
+
from pathlib import Path
|
|
121
|
+
import sys
|
|
122
|
+
|
|
123
|
+
path = Path(sys.argv[1])
|
|
124
|
+
field = sys.argv[2]
|
|
125
|
+
lines = path.read_text().splitlines()
|
|
126
|
+
matches = [i for i, line in enumerate(lines) if line.startswith("Readiness inputs SHA-256:")]
|
|
127
|
+
if len(matches) != 1:
|
|
128
|
+
raise SystemExit(f"{path}: expected exactly one engineering digest")
|
|
129
|
+
lines[matches[0]] = field
|
|
130
|
+
path.write_text("\n".join(lines) + "\n")
|
|
100
131
|
PY
|
|
101
132
|
fi
|
|
102
133
|
|