devrites 3.2.14 → 3.2.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/CHANGELOG.md +12 -0
- package/README.md +1 -1
- package/engine/hooks_agent_dispatch.go +37 -22
- package/engine/tests/hook_test.go +79 -0
- package/pack/.claude/agents/devrites-slice-wright.md +4 -5
- package/pack/.claude/skills/rite-build/reference/one-slice-cycle.md +2 -2
- package/pack/.claude/skills/rite-build/reference/phase-contract.md +14 -4
- package/pack/.claude/skills/rite-build/reference/wright-dispatch.md +5 -5
- package/pack/generated/claude/agents/devrites-slice-wright.md +4 -5
- package/pack/generated/claude/skills/rite-build/reference/one-slice-cycle.md +2 -2
- package/pack/generated/claude/skills/rite-build/reference/phase-contract.md +14 -4
- package/pack/generated/claude/skills/rite-build/reference/wright-dispatch.md +5 -5
- package/pack/generated/codex/agents/devrites-slice-wright.toml +4 -5
- package/pack/generated/codex/skills/rite-build/reference/one-slice-cycle.md +2 -2
- package/pack/generated/codex/skills/rite-build/reference/phase-contract.md +14 -4
- package/pack/generated/codex/skills/rite-build/reference/wright-dispatch.md +5 -5
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,18 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to DevRites are documented here. The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and DevRites adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). Releases are generated automatically by [semantic-release](https://semantic-release.gitbook.io/) from Conventional Commits on `main`.
|
|
4
4
|
|
|
5
|
+
## [3.2.16](https://github.com/ViktorsBaikers/DevRites/compare/v3.2.15...v3.2.16) (2026-07-27)
|
|
6
|
+
|
|
7
|
+
### Fixed
|
|
8
|
+
|
|
9
|
+
* **rite:** run root-owned artifact gates ([7614022](https://github.com/ViktorsBaikers/DevRites/commit/7614022b36cf8c887f148e4d12777e20ee2ea3d4))
|
|
10
|
+
|
|
11
|
+
## [3.2.15](https://github.com/ViktorsBaikers/DevRites/compare/v3.2.14...v3.2.15) (2026-07-27)
|
|
12
|
+
|
|
13
|
+
### Fixed
|
|
14
|
+
|
|
15
|
+
* **agents:** verify hidden V2 child roles ([e80b62b](https://github.com/ViktorsBaikers/DevRites/commit/e80b62bf53cec440cfad54a3d23d8d3cf5b120f3))
|
|
16
|
+
|
|
5
17
|
## [3.2.14](https://github.com/ViktorsBaikers/DevRites/compare/v3.2.13...v3.2.14) (2026-07-26)
|
|
6
18
|
|
|
7
19
|
### Fixed
|
package/README.md
CHANGED
|
@@ -25,7 +25,7 @@ final commit, push, and tag, and it requires a typed `GO` confirmation.
|
|
|
25
25
|
Unattended runs may create local WIP checkpoint commits along the way, but only
|
|
26
26
|
Ship collapses and pushes them.
|
|
27
27
|
|
|
28
|
-
**Status:** [`v3.2.
|
|
28
|
+
**Status:** [`v3.2.16`](https://github.com/ViktorsBaikers/DevRites/releases/tag/v3.2.16): see [`CHANGELOG.md`](CHANGELOG.md) for release notes.
|
|
29
29
|
|
|
30
30
|
## Quick start
|
|
31
31
|
|
|
@@ -495,39 +495,54 @@ func durableCodexV2DispatchAttempts(
|
|
|
495
495
|
}
|
|
496
496
|
var attempts []*agentDispatchAttempt
|
|
497
497
|
for _, spawn := range spawns {
|
|
498
|
-
|
|
498
|
+
role := spawn.Role
|
|
499
|
+
var childPath string
|
|
500
|
+
var childMeta codexRolloutRecord
|
|
501
|
+
if strings.TrimSpace(spawn.Result) != "" {
|
|
502
|
+
childPath, childMeta, err = findCodexV2ChildRollout(
|
|
503
|
+
sessionsDir, parentPath, projectRoot, sessionID, spawn.AgentPath,
|
|
504
|
+
)
|
|
505
|
+
if err != nil {
|
|
506
|
+
return nil, err
|
|
507
|
+
}
|
|
508
|
+
if childPath != "" {
|
|
509
|
+
role = childMeta.Payload.AgentRole
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
if !devritesAgentNameRe.MatchString(role) || role == agentDispatchSkillGuard {
|
|
499
513
|
if strings.TrimSpace(spawn.Result) != "" {
|
|
500
514
|
return nil, fmt.Errorf("codex V2 completed a default or non-DevRites child during a DevRites skill turn; %s", conditionalDispatchInstruction())
|
|
501
515
|
}
|
|
502
516
|
continue
|
|
503
517
|
}
|
|
504
|
-
armed[
|
|
518
|
+
armed[role] = struct{}{}
|
|
505
519
|
attempt := &agentDispatchAttempt{
|
|
506
|
-
Role:
|
|
507
|
-
AgentType:
|
|
520
|
+
Role: role,
|
|
521
|
+
AgentType: role,
|
|
508
522
|
Started: true,
|
|
509
523
|
}
|
|
510
524
|
attempts = append(attempts, attempt)
|
|
511
525
|
if strings.TrimSpace(spawn.Result) == "" || !lineBetween(waitLines, spawn.SpawnLine, spawn.ResultLine) {
|
|
512
526
|
continue
|
|
513
527
|
}
|
|
514
|
-
|
|
528
|
+
if childPath == "" || childMeta.Payload.AgentRole != role {
|
|
529
|
+
continue
|
|
530
|
+
}
|
|
531
|
+
instructions, err := agentRoleDeveloperInstructions(root, role)
|
|
515
532
|
if err != nil {
|
|
516
|
-
return nil, fmt.Errorf("named role %s is not loadable: %w",
|
|
533
|
+
return nil, fmt.Errorf("named role %s is not loadable: %w", role, err)
|
|
517
534
|
}
|
|
518
|
-
|
|
519
|
-
sessionsDir, parentPath, projectRoot, sessionID, spawn.AgentPath, spawn.Role, instructions,
|
|
520
|
-
)
|
|
535
|
+
childResult, err := codexChildResult(childPath, instructions)
|
|
521
536
|
if err != nil {
|
|
522
537
|
return nil, err
|
|
523
538
|
}
|
|
524
|
-
if
|
|
539
|
+
if childMeta.Payload.ID == "" || strings.TrimSpace(childResult) == "" {
|
|
525
540
|
continue
|
|
526
541
|
}
|
|
527
|
-
attempt.AgentID =
|
|
542
|
+
attempt.AgentID = childMeta.Payload.ID
|
|
528
543
|
attempt.Stopped = true
|
|
529
544
|
attempt.Waited = true
|
|
530
|
-
if
|
|
545
|
+
if role == "devrites-slice-wright" {
|
|
531
546
|
attempt.WindowID = currentReconcileWindowID()
|
|
532
547
|
if attempt.WindowID == "" || !reconcileWindowPredates(spawn.SpawnedAt) {
|
|
533
548
|
continue
|
|
@@ -654,10 +669,11 @@ func readCodexV2ParentRollout(
|
|
|
654
669
|
return spawns, waitLines, nil
|
|
655
670
|
}
|
|
656
671
|
|
|
657
|
-
func
|
|
658
|
-
sessionsDir, parentPath, projectRoot, sessionID, agentPath
|
|
659
|
-
) (string,
|
|
660
|
-
var
|
|
672
|
+
func findCodexV2ChildRollout(
|
|
673
|
+
sessionsDir, parentPath, projectRoot, sessionID, agentPath string,
|
|
674
|
+
) (string, codexRolloutRecord, error) {
|
|
675
|
+
var childPath string
|
|
676
|
+
var childMeta codexRolloutRecord
|
|
661
677
|
err := filepath.WalkDir(sessionsDir, func(path string, entry fs.DirEntry, walkErr error) error {
|
|
662
678
|
if walkErr != nil {
|
|
663
679
|
if os.IsNotExist(walkErr) {
|
|
@@ -675,18 +691,17 @@ func findCodexV2ChildResult(
|
|
|
675
691
|
if record.Type != "session_meta" ||
|
|
676
692
|
record.Payload.ParentThreadID != sessionID ||
|
|
677
693
|
record.Payload.AgentPath != agentPath ||
|
|
678
|
-
record.Payload.AgentRole != role ||
|
|
679
694
|
!sameResolvedPath(record.Payload.CWD, projectRoot) {
|
|
680
695
|
return nil
|
|
681
696
|
}
|
|
682
|
-
if
|
|
697
|
+
if childPath != "" {
|
|
683
698
|
return fmt.Errorf("multiple Codex child rollouts match %s", agentPath)
|
|
684
699
|
}
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
return
|
|
700
|
+
childPath = path
|
|
701
|
+
childMeta = record
|
|
702
|
+
return nil
|
|
688
703
|
})
|
|
689
|
-
return
|
|
704
|
+
return childPath, childMeta, err
|
|
690
705
|
}
|
|
691
706
|
|
|
692
707
|
func firstCodexRolloutRecord(path string) (codexRolloutRecord, bool, error) {
|
|
@@ -7,6 +7,7 @@ package main_test
|
|
|
7
7
|
import (
|
|
8
8
|
"bytes"
|
|
9
9
|
"encoding/json"
|
|
10
|
+
"fmt"
|
|
10
11
|
"os"
|
|
11
12
|
"path/filepath"
|
|
12
13
|
"strconv"
|
|
@@ -379,6 +380,40 @@ func TestCodexGenericCompatibilityDoesNotShadowRoot(t *testing.T) {
|
|
|
379
380
|
}
|
|
380
381
|
}
|
|
381
382
|
|
|
383
|
+
func TestCodexRootRunsArtifactGatesInsideActiveWindow(t *testing.T) {
|
|
384
|
+
root := newWorkspace(t)
|
|
385
|
+
writeActive(t, root, "auth-tokens")
|
|
386
|
+
workspace := filepath.Join(root, "features", "auth-tokens")
|
|
387
|
+
if err := os.WriteFile(filepath.Join(workspace, ".reconcile-base"), []byte("snapshot\n"), 0o600); err != nil {
|
|
388
|
+
t.Fatal(err)
|
|
389
|
+
}
|
|
390
|
+
env := []string{
|
|
391
|
+
"DEVRITES_CODEX_GENERIC_AGENT_COMPAT=1",
|
|
392
|
+
"DEVRITES_HOOK_PROFILE=strict",
|
|
393
|
+
}
|
|
394
|
+
for _, command := range []string{
|
|
395
|
+
"npm run build",
|
|
396
|
+
"npm run test:e2e -- tests/admin-locations.e2e.spec.ts",
|
|
397
|
+
} {
|
|
398
|
+
in := fmt.Sprintf(`{"tool_name":"Bash","tool_input":{"command":%q}}`, command)
|
|
399
|
+
out, errOut, code := runDevritesIO(t, root, in, env,
|
|
400
|
+
"hook", "wright-scope", "--harness=codex")
|
|
401
|
+
if code != 0 || strings.TrimSpace(out) != "" {
|
|
402
|
+
t.Fatalf("%q should be root-owned: exit=%d out=%q stderr=%q", command, code, out, errOut)
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
in := `{"tool_name":"Bash","tool_input":{"command":"printf x > src/app.go"}}`
|
|
407
|
+
out, errOut, code := runDevritesIO(t, root, in, env,
|
|
408
|
+
"hook", "wright-scope", "--harness=codex")
|
|
409
|
+
if code != 0 {
|
|
410
|
+
t.Fatalf("source write guard exit=%d stderr=%q", code, errOut)
|
|
411
|
+
}
|
|
412
|
+
if decision, _ := parsePermissionDecision(t, out); decision != "deny" {
|
|
413
|
+
t.Fatalf("root source mutation was not denied: %q", out)
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
|
|
382
417
|
func TestHookReviewerReadonlyActiveLeafDeniesEveryMutationSurface(t *testing.T) {
|
|
383
418
|
root := newWorkspace(t)
|
|
384
419
|
env := []string{
|
|
@@ -1667,6 +1702,50 @@ func TestCodexAgentDispatchConfirmsDurableV2NamedRole(t *testing.T) {
|
|
|
1667
1702
|
}
|
|
1668
1703
|
}
|
|
1669
1704
|
|
|
1705
|
+
func TestCodexAgentDispatchConfirmsDurableV2ChildRoleWhenParentOmitsAgentType(t *testing.T) {
|
|
1706
|
+
root := newWorkspace(t)
|
|
1707
|
+
codeHome := t.TempDir()
|
|
1708
|
+
sessionID, turnID := "session-v2-hidden-role", "turn-v2-hidden-role"
|
|
1709
|
+
role := "devrites-plan-drafter"
|
|
1710
|
+
writeCodexAgentContract(t, root, role)
|
|
1711
|
+
writeCodexSkillContract(t, root, "rite-plan", role)
|
|
1712
|
+
|
|
1713
|
+
runDevritesIO(t, root, hookPayload(t, map[string]any{
|
|
1714
|
+
"hook_event_name": "UserPromptSubmit",
|
|
1715
|
+
"session_id": sessionID,
|
|
1716
|
+
"turn_id": turnID,
|
|
1717
|
+
"prompt": "$rite-plan unblock",
|
|
1718
|
+
}), nil, "hook", "agent-dispatch", "--harness=codex")
|
|
1719
|
+
|
|
1720
|
+
taskName := "devrites_plan_drafter_hidden_role"
|
|
1721
|
+
writeCodexV2Rollouts(
|
|
1722
|
+
t, codeHome, filepath.Dir(root), sessionID, turnID, role,
|
|
1723
|
+
taskName, true, true, true,
|
|
1724
|
+
)
|
|
1725
|
+
parentPath := filepath.Join(codeHome, "sessions", "2026", "07", "25", "rollout-parent-"+sessionID+".jsonl")
|
|
1726
|
+
parent, err := os.ReadFile(parentPath)
|
|
1727
|
+
if err != nil {
|
|
1728
|
+
t.Fatal(err)
|
|
1729
|
+
}
|
|
1730
|
+
hiddenParentRole := bytes.ReplaceAll(parent, []byte(`\"agent_type\":\"`+role+`\"`), []byte(`\"agent_type\":\"\"`))
|
|
1731
|
+
if bytes.Equal(parent, hiddenParentRole) {
|
|
1732
|
+
t.Fatal("fixture did not hide the parent agent_type")
|
|
1733
|
+
}
|
|
1734
|
+
if err := os.WriteFile(parentPath, hiddenParentRole, 0o600); err != nil {
|
|
1735
|
+
t.Fatal(err)
|
|
1736
|
+
}
|
|
1737
|
+
stop := hookPayload(t, map[string]any{
|
|
1738
|
+
"hook_event_name": "Stop",
|
|
1739
|
+
"session_id": sessionID,
|
|
1740
|
+
"turn_id": turnID,
|
|
1741
|
+
})
|
|
1742
|
+
if out, stderr, code := runDevritesIO(t, root, stop,
|
|
1743
|
+
[]string{"CODEX_HOME=" + codeHome},
|
|
1744
|
+
"hook", "agent-dispatch", "--harness=codex"); code != 0 || strings.TrimSpace(out) != "" {
|
|
1745
|
+
t.Fatalf("hidden parent role stop exit=%d out=%s stderr=%s", code, out, stderr)
|
|
1746
|
+
}
|
|
1747
|
+
}
|
|
1748
|
+
|
|
1670
1749
|
func TestCodexAgentDispatchConfirmsConditionalDurableV2NamedRole(t *testing.T) {
|
|
1671
1750
|
root := newWorkspace(t)
|
|
1672
1751
|
codeHome := t.TempDir()
|
|
@@ -105,9 +105,9 @@ an escalation and do not proceed.**
|
|
|
105
105
|
`$devrites-source-driven` on Codex. Verify the fact in installed source,
|
|
106
106
|
official documentation, or context7 for current upstream behavior, then include
|
|
107
107
|
that source in the result. Never invent an API.
|
|
108
|
-
4. **VERIFY (fail-on-red).** Run
|
|
109
|
-
|
|
110
|
-
|
|
108
|
+
4. **VERIFY (fail-on-red).** Run writer-safe tests/types/lint. Report required
|
|
109
|
+
build/browser/E2E as `not-run`: `root-owned artifact-producing gate`; root
|
|
110
|
+
runs them after reconciliation. Fix red gates in your code. **Never weaken a test
|
|
111
111
|
to go green** by deleting it, skipping it with `skip`, `xfail`, or `.only`, or
|
|
112
112
|
loosening an assertion. A test that genuinely must change is an **Escalation**,
|
|
113
113
|
not a quiet edit. The orchestrator runs `devrites-engine test-integrity` on the
|
|
@@ -117,8 +117,7 @@ an escalation and do not proceed.**
|
|
|
117
117
|
`devrites-engine recovery` **three-attempt budget per root cause**. At the limit,
|
|
118
118
|
return the failed gate and reproduction. Reserve `Escalation` for a
|
|
119
119
|
product-contract or irreversible-risk choice, or a user-only credential or
|
|
120
|
-
action.
|
|
121
|
-
question.
|
|
120
|
+
action. Technical failure is a blocker, not a permission question.
|
|
122
121
|
5. **RETURN** the structured artifact (below) and stop. Do not start the next slice.
|
|
123
122
|
|
|
124
123
|
## Code quality: consume the rules, don't reinvent them
|
|
@@ -15,9 +15,9 @@ DISPATCH → hand the slice contract to devrites-slice-wright (fresh context).
|
|
|
15
15
|
ORIENT → load only the files this slice touches; learn the project's idiom; reuse-first
|
|
16
16
|
(RED) → if behavior change: write the failing test first
|
|
17
17
|
IMPLEMENT → smallest complete version; match conventions; devrites-frontend-craft for UI
|
|
18
|
-
VERIFY →
|
|
18
|
+
VERIFY → writer-safe tests/types/lint; return code + tests
|
|
19
19
|
(DOUBT) → orchestrator, on return: devrites-doubt each non-trivial decision the wright stood up
|
|
20
|
-
PROVE →
|
|
20
|
+
PROVE → root: exact required production build/browser/E2E, then final reconcile; fail-on-red
|
|
21
21
|
RECORD → orchestrator: after green verification, Forge cleanup/report if used; then
|
|
22
22
|
state.md, evidence.md, touched-files.md (the canonical writer)
|
|
23
23
|
(CHECKPOINT) → orchestrator: if .devrites/CHECKPOINT is set, commit the proven slice
|
|
@@ -73,13 +73,22 @@ See also [`one-slice-cycle.md`](one-slice-cycle.md).
|
|
|
73
73
|
(reported in its `Principles` field, or that you detect against `.devrites/principles.md`) is
|
|
74
74
|
handled here like an irreversible-risk item: block, route to a human-approved scoped
|
|
75
75
|
exception in the register or stop; never doubt-and-accept a principle violation into the slice.
|
|
76
|
-
5. **Run
|
|
76
|
+
5. **Run retained-baseline integrity and every root-owned proof gate, then recover
|
|
77
|
+
any objective red.**
|
|
77
78
|
```bash
|
|
78
79
|
devrites-engine test-integrity; echo "test-integrity rc=$?"
|
|
79
80
|
```
|
|
81
|
+
Run every exact command reported as `not-run`: `root-owned artifact-producing gate`
|
|
82
|
+
in the wright result. These are root proof commands, not source-edit authority.
|
|
83
|
+
Do not omit, rewrite, or substitute them; a missing command is unverifiable proof.
|
|
84
|
+
After they pass, run `devrites-engine reconcile check` again after the root-owned gates
|
|
85
|
+
and before close, proving their child processes did not change tracked source:
|
|
86
|
+
```bash
|
|
87
|
+
devrites-engine reconcile check; echo "reconcile rc=$?"
|
|
88
|
+
```
|
|
80
89
|
If the wright's `Gates` were red (targeted tests / types / lint), `test-integrity`
|
|
81
|
-
failed,
|
|
82
|
-
fix the code yourself**.
|
|
90
|
+
failed, a root-owned gate failed, the final reconcile failed, or proof could not be
|
|
91
|
+
verified: do **not** mark the slice `built`, and **do not fix the code yourself**.
|
|
83
92
|
Classify each causal fingerprint through
|
|
84
93
|
[`cleanup-and-classify.md`](../../devrites-debug-recovery/reference/cleanup-and-classify.md),
|
|
85
94
|
run `devrites-engine recovery route <class>`, and follow the `recovery-route/v1`
|
|
@@ -105,7 +114,8 @@ See also [`one-slice-cycle.md`](one-slice-cycle.md).
|
|
|
105
114
|
- exhausted objective failure → preserve reproduction/dead ends, set `Status: blocked` and
|
|
106
115
|
`Next step: /rite-plan unblock`, then STOP without a question or `/rite-resolve`.
|
|
107
116
|
6. **Close the retained baseline, then record. You are the canonical writer.**
|
|
108
|
-
Reconciliation ran immediately on return
|
|
117
|
+
Reconciliation ran immediately on return; step 5 ran integrity, root-owned proof,
|
|
118
|
+
and a final clean reconciliation.
|
|
109
119
|
**Exit 3 → hard STOP:** a test was deleted, skipped, or de-asserted since the slice base: the
|
|
110
120
|
slice went green by weakening its tests, a Critical protocol violation. Revert the weakening and
|
|
111
121
|
re-dispatch the wright; do **not** mark the slice `built`.
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
# Slice-wright dispatch
|
|
2
2
|
|
|
3
|
-
`/rite-build` delegates one
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
writer and never invokes
|
|
3
|
+
`/rite-build` delegates one slice or correction to `devrites-slice-wright`.
|
|
4
|
+
The root owns scope, questions, `.devrites/**`, reconciliation, and routing.
|
|
5
|
+
Production builds and browser/E2E runs are root-owned gates.
|
|
6
|
+
The wright only writes source/tests, runs writer-safe proof, and never invokes agents.
|
|
7
7
|
|
|
8
8
|
The universal packet, result, budget, await, retry, and host fallback contract is
|
|
9
9
|
[`standards/agents.md`](../../devrites-lib/reference/standards/agents.md). This file adds
|
|
@@ -108,7 +108,7 @@ failure becomes a technical blocker with its reproduction, not a `rite-resolve`
|
|
|
108
108
|
|
|
109
109
|
## Close and record
|
|
110
110
|
|
|
111
|
-
|
|
111
|
+
Run the root gates and final reconciliation from `phase-contract.md` step 5. Then:
|
|
112
112
|
|
|
113
113
|
```bash
|
|
114
114
|
devrites-engine reconcile close
|
|
@@ -105,9 +105,9 @@ an escalation and do not proceed.**
|
|
|
105
105
|
`$devrites-source-driven` on Codex. Verify the fact in installed source,
|
|
106
106
|
official documentation, or context7 for current upstream behavior, then include
|
|
107
107
|
that source in the result. Never invent an API.
|
|
108
|
-
4. **VERIFY (fail-on-red).** Run
|
|
109
|
-
|
|
110
|
-
|
|
108
|
+
4. **VERIFY (fail-on-red).** Run writer-safe tests/types/lint. Report required
|
|
109
|
+
build/browser/E2E as `not-run`: `root-owned artifact-producing gate`; root
|
|
110
|
+
runs them after reconciliation. Fix red gates in your code. **Never weaken a test
|
|
111
111
|
to go green** by deleting it, skipping it with `skip`, `xfail`, or `.only`, or
|
|
112
112
|
loosening an assertion. A test that genuinely must change is an **Escalation**,
|
|
113
113
|
not a quiet edit. The orchestrator runs `devrites-engine test-integrity` on the
|
|
@@ -117,8 +117,7 @@ an escalation and do not proceed.**
|
|
|
117
117
|
`devrites-engine recovery` **three-attempt budget per root cause**. At the limit,
|
|
118
118
|
return the failed gate and reproduction. Reserve `Escalation` for a
|
|
119
119
|
product-contract or irreversible-risk choice, or a user-only credential or
|
|
120
|
-
action.
|
|
121
|
-
question.
|
|
120
|
+
action. Technical failure is a blocker, not a permission question.
|
|
122
121
|
5. **RETURN** the structured artifact (below) and stop. Do not start the next slice.
|
|
123
122
|
|
|
124
123
|
## Code quality: consume the rules, don't reinvent them
|
|
@@ -15,9 +15,9 @@ DISPATCH → hand the slice contract to devrites-slice-wright (fresh context).
|
|
|
15
15
|
ORIENT → load only the files this slice touches; learn the project's idiom; reuse-first
|
|
16
16
|
(RED) → if behavior change: write the failing test first
|
|
17
17
|
IMPLEMENT → smallest complete version; match conventions; devrites-frontend-craft for UI
|
|
18
|
-
VERIFY →
|
|
18
|
+
VERIFY → writer-safe tests/types/lint; return code + tests
|
|
19
19
|
(DOUBT) → orchestrator, on return: devrites-doubt each non-trivial decision the wright stood up
|
|
20
|
-
PROVE →
|
|
20
|
+
PROVE → root: exact required production build/browser/E2E, then final reconcile; fail-on-red
|
|
21
21
|
RECORD → orchestrator: after green verification, Forge cleanup/report if used; then
|
|
22
22
|
state.md, evidence.md, touched-files.md (the canonical writer)
|
|
23
23
|
(CHECKPOINT) → orchestrator: if .devrites/CHECKPOINT is set, commit the proven slice
|
|
@@ -73,13 +73,22 @@ See also [`one-slice-cycle.md`](one-slice-cycle.md).
|
|
|
73
73
|
(reported in its `Principles` field, or that you detect against `.devrites/principles.md`) is
|
|
74
74
|
handled here like an irreversible-risk item: block, route to a human-approved scoped
|
|
75
75
|
exception in the register or stop; never doubt-and-accept a principle violation into the slice.
|
|
76
|
-
5. **Run
|
|
76
|
+
5. **Run retained-baseline integrity and every root-owned proof gate, then recover
|
|
77
|
+
any objective red.**
|
|
77
78
|
```bash
|
|
78
79
|
devrites-engine test-integrity; echo "test-integrity rc=$?"
|
|
79
80
|
```
|
|
81
|
+
Run every exact command reported as `not-run`: `root-owned artifact-producing gate`
|
|
82
|
+
in the wright result. These are root proof commands, not source-edit authority.
|
|
83
|
+
Do not omit, rewrite, or substitute them; a missing command is unverifiable proof.
|
|
84
|
+
After they pass, run `devrites-engine reconcile check` again after the root-owned gates
|
|
85
|
+
and before close, proving their child processes did not change tracked source:
|
|
86
|
+
```bash
|
|
87
|
+
devrites-engine reconcile check; echo "reconcile rc=$?"
|
|
88
|
+
```
|
|
80
89
|
If the wright's `Gates` were red (targeted tests / types / lint), `test-integrity`
|
|
81
|
-
failed,
|
|
82
|
-
fix the code yourself**.
|
|
90
|
+
failed, a root-owned gate failed, the final reconcile failed, or proof could not be
|
|
91
|
+
verified: do **not** mark the slice `built`, and **do not fix the code yourself**.
|
|
83
92
|
Classify each causal fingerprint through
|
|
84
93
|
[`cleanup-and-classify.md`](../../devrites-debug-recovery/reference/cleanup-and-classify.md),
|
|
85
94
|
run `devrites-engine recovery route <class>`, and follow the `recovery-route/v1`
|
|
@@ -105,7 +114,8 @@ See also [`one-slice-cycle.md`](one-slice-cycle.md).
|
|
|
105
114
|
- exhausted objective failure → preserve reproduction/dead ends, set `Status: blocked` and
|
|
106
115
|
`Next step: /rite-plan unblock`, then STOP without a question or `/rite-resolve`.
|
|
107
116
|
6. **Close the retained baseline, then record. You are the canonical writer.**
|
|
108
|
-
Reconciliation ran immediately on return
|
|
117
|
+
Reconciliation ran immediately on return; step 5 ran integrity, root-owned proof,
|
|
118
|
+
and a final clean reconciliation.
|
|
109
119
|
**Exit 3 → hard STOP:** a test was deleted, skipped, or de-asserted since the slice base: the
|
|
110
120
|
slice went green by weakening its tests, a Critical protocol violation. Revert the weakening and
|
|
111
121
|
re-dispatch the wright; do **not** mark the slice `built`.
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
# Slice-wright dispatch
|
|
2
2
|
|
|
3
|
-
`/rite-build` delegates one
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
writer and never invokes
|
|
3
|
+
`/rite-build` delegates one slice or correction to `devrites-slice-wright`.
|
|
4
|
+
The root owns scope, questions, `.devrites/**`, reconciliation, and routing.
|
|
5
|
+
Production builds and browser/E2E runs are root-owned gates.
|
|
6
|
+
The wright only writes source/tests, runs writer-safe proof, and never invokes agents.
|
|
7
7
|
|
|
8
8
|
The universal packet, result, budget, await, retry, and host fallback contract is
|
|
9
9
|
[`standards/agents.md`](../../devrites-lib/reference/standards/agents.md). This file adds
|
|
@@ -108,7 +108,7 @@ failure becomes a technical blocker with its reproduction, not a `rite-resolve`
|
|
|
108
108
|
|
|
109
109
|
## Close and record
|
|
110
110
|
|
|
111
|
-
|
|
111
|
+
Run the root gates and final reconciliation from `phase-contract.md` step 5. Then:
|
|
112
112
|
|
|
113
113
|
```bash
|
|
114
114
|
devrites-engine reconcile close
|
|
@@ -100,9 +100,9 @@ an escalation and do not proceed.**
|
|
|
100
100
|
`$devrites-source-driven` on Codex. Verify the fact in installed source,
|
|
101
101
|
official documentation, or context7 for current upstream behavior, then include
|
|
102
102
|
that source in the result. Never invent an API.
|
|
103
|
-
4. **VERIFY (fail-on-red).** Run
|
|
104
|
-
|
|
105
|
-
|
|
103
|
+
4. **VERIFY (fail-on-red).** Run writer-safe tests/types/lint. Report required
|
|
104
|
+
build/browser/E2E as `not-run`: `root-owned artifact-producing gate`; root
|
|
105
|
+
runs them after reconciliation. Fix red gates in your code. **Never weaken a test
|
|
106
106
|
to go green** by deleting it, skipping it with `skip`, `xfail`, or `.only`, or
|
|
107
107
|
loosening an assertion. A test that genuinely must change is an **Escalation**,
|
|
108
108
|
not a quiet edit. The orchestrator runs `devrites-engine test-integrity` on the
|
|
@@ -112,8 +112,7 @@ an escalation and do not proceed.**
|
|
|
112
112
|
`devrites-engine recovery` **three-attempt budget per root cause**. At the limit,
|
|
113
113
|
return the failed gate and reproduction. Reserve `Escalation` for a
|
|
114
114
|
product-contract or irreversible-risk choice, or a user-only credential or
|
|
115
|
-
action.
|
|
116
|
-
question.
|
|
115
|
+
action. Technical failure is a blocker, not a permission question.
|
|
117
116
|
5. **RETURN** the structured artifact (below) and stop. Do not start the next slice.
|
|
118
117
|
|
|
119
118
|
## Code quality: consume the rules, don't reinvent them
|
|
@@ -15,9 +15,9 @@ DISPATCH → hand the slice contract to devrites-slice-wright (fresh context).
|
|
|
15
15
|
ORIENT → load only the files this slice touches; learn the project's idiom; reuse-first
|
|
16
16
|
(RED) → if behavior change: write the failing test first
|
|
17
17
|
IMPLEMENT → smallest complete version; match conventions; devrites-frontend-craft for UI
|
|
18
|
-
VERIFY →
|
|
18
|
+
VERIFY → writer-safe tests/types/lint; return code + tests
|
|
19
19
|
(DOUBT) → orchestrator, on return: devrites-doubt each non-trivial decision the wright stood up
|
|
20
|
-
PROVE →
|
|
20
|
+
PROVE → root: exact required production build/browser/E2E, then final reconcile; fail-on-red
|
|
21
21
|
RECORD → orchestrator: after green verification, Forge cleanup/report if used; then
|
|
22
22
|
state.md, evidence.md, touched-files.md (the canonical writer)
|
|
23
23
|
(CHECKPOINT) → orchestrator: if .devrites/CHECKPOINT is set, commit the proven slice
|
|
@@ -73,13 +73,22 @@ See also [`one-slice-cycle.md`](one-slice-cycle.md).
|
|
|
73
73
|
(reported in its `Principles` field, or that you detect against `.devrites/principles.md`) is
|
|
74
74
|
handled here like an irreversible-risk item: block, route to a human-approved scoped
|
|
75
75
|
exception in the register or stop; never doubt-and-accept a principle violation into the slice.
|
|
76
|
-
5. **Run
|
|
76
|
+
5. **Run retained-baseline integrity and every root-owned proof gate, then recover
|
|
77
|
+
any objective red.**
|
|
77
78
|
```bash
|
|
78
79
|
devrites-engine test-integrity; echo "test-integrity rc=$?"
|
|
79
80
|
```
|
|
81
|
+
Run every exact command reported as `not-run`: `root-owned artifact-producing gate`
|
|
82
|
+
in the wright result. These are root proof commands, not source-edit authority.
|
|
83
|
+
Do not omit, rewrite, or substitute them; a missing command is unverifiable proof.
|
|
84
|
+
After they pass, run `devrites-engine reconcile check` again after the root-owned gates
|
|
85
|
+
and before close, proving their child processes did not change tracked source:
|
|
86
|
+
```bash
|
|
87
|
+
devrites-engine reconcile check; echo "reconcile rc=$?"
|
|
88
|
+
```
|
|
80
89
|
If the wright's `Gates` were red (targeted tests / types / lint), `test-integrity`
|
|
81
|
-
failed,
|
|
82
|
-
fix the code yourself**.
|
|
90
|
+
failed, a root-owned gate failed, the final reconcile failed, or proof could not be
|
|
91
|
+
verified: do **not** mark the slice `built`, and **do not fix the code yourself**.
|
|
83
92
|
Classify each causal fingerprint through
|
|
84
93
|
[`cleanup-and-classify.md`](../../devrites-debug-recovery/reference/cleanup-and-classify.md),
|
|
85
94
|
run `devrites-engine recovery route <class>`, and follow the `recovery-route/v1`
|
|
@@ -105,7 +114,8 @@ See also [`one-slice-cycle.md`](one-slice-cycle.md).
|
|
|
105
114
|
- exhausted objective failure → preserve reproduction/dead ends, set `Status: blocked` and
|
|
106
115
|
`Next step: $rite-plan unblock`, then STOP without a question or `$rite-resolve`.
|
|
107
116
|
6. **Close the retained baseline, then record. You are the canonical writer.**
|
|
108
|
-
Reconciliation ran immediately on return
|
|
117
|
+
Reconciliation ran immediately on return; step 5 ran integrity, root-owned proof,
|
|
118
|
+
and a final clean reconciliation.
|
|
109
119
|
**Exit 3 → hard STOP:** a test was deleted, skipped, or de-asserted since the slice base: the
|
|
110
120
|
slice went green by weakening its tests, a Critical protocol violation. Revert the weakening and
|
|
111
121
|
re-dispatch the wright; do **not** mark the slice `built`.
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
# Slice-wright dispatch
|
|
2
2
|
|
|
3
|
-
`$rite-build` delegates one
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
writer and never invokes
|
|
3
|
+
`$rite-build` delegates one slice or correction to `devrites-slice-wright`.
|
|
4
|
+
The root owns scope, questions, `.devrites/**`, reconciliation, and routing.
|
|
5
|
+
Production builds and browser/E2E runs are root-owned gates.
|
|
6
|
+
The wright only writes source/tests, runs writer-safe proof, and never invokes agents.
|
|
7
7
|
|
|
8
8
|
The universal packet, result, budget, await, retry, and host fallback contract is
|
|
9
9
|
[`standards/agents.md`](../../devrites-lib/reference/standards/agents.md). This file adds
|
|
@@ -108,7 +108,7 @@ failure becomes a technical blocker with its reproduction, not a `rite-resolve`
|
|
|
108
108
|
|
|
109
109
|
## Close and record
|
|
110
110
|
|
|
111
|
-
|
|
111
|
+
Run the root gates and final reconciliation from `phase-contract.md` step 5. Then:
|
|
112
112
|
|
|
113
113
|
```bash
|
|
114
114
|
devrites-engine reconcile close
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "devrites",
|
|
3
|
-
"version": "3.2.
|
|
3
|
+
"version": "3.2.16",
|
|
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",
|