@bluenyang/reins 0.0.0-stage → 0.1.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/LICENSE +21 -0
- package/README.md +149 -2
- package/cli/dist/commands/check.js +244 -0
- package/cli/dist/commands/install.js +230 -0
- package/cli/dist/commands/migrate.js +122 -0
- package/cli/dist/lib/ask.js +27 -0
- package/cli/dist/lib/blocks.js +93 -0
- package/cli/dist/lib/detect.js +105 -0
- package/cli/dist/lib/fsx.js +36 -0
- package/cli/dist/lib/git.js +30 -0
- package/cli/dist/lib/glob.js +30 -0
- package/cli/dist/lib/harness.js +33 -0
- package/cli/dist/lib/migrate-plan.js +233 -0
- package/cli/dist/lib/schema.js +70 -0
- package/cli/dist/lib/secrets.js +28 -0
- package/cli/dist/lib/skills.js +63 -0
- package/cli/dist/lib/upstream.js +16 -0
- package/cli/dist/lib/verdict.js +15 -0
- package/cli/dist/reins.js +122 -0
- package/docs/README.ko.md +151 -0
- package/harness/CHANGELOG.md +10 -0
- package/harness/VERSION +1 -0
- package/harness/knowledge-seeds/node/2026-10-25_frozen-lockfile.md +24 -0
- package/harness/knowledge-seeds/node/2026-10-25_mutating-lint-is-not-a-gate.md +19 -0
- package/harness/policy/budget.yaml +13 -0
- package/harness/policy/common-red-lines.yaml +25 -0
- package/harness/policy/stops.yaml +29 -0
- package/harness/policy/transitions.yaml +13 -0
- package/harness/roles/advisor.md +15 -0
- package/harness/roles/code-review.md +21 -0
- package/harness/roles/deploy.md +17 -0
- package/harness/roles/docs.md +16 -0
- package/harness/roles/implementer.md +22 -0
- package/harness/roles/lookup.md +19 -0
- package/harness/roles/pl.md +21 -0
- package/harness/roles/planner.md +20 -0
- package/harness/roles/pm.md +23 -0
- package/harness/roles/qa-design.md +19 -0
- package/harness/roles/qa-run.md +16 -0
- package/harness/roles/verify-tool.md +19 -0
- package/harness/schemas/bus-request.schema.json +17 -0
- package/harness/schemas/bus-response.schema.json +14 -0
- package/harness/schemas/intent.schema.json +13 -0
- package/harness/schemas/knowledge.schema.json +16 -0
- package/harness/schemas/plan.schema.json +10 -0
- package/harness/schemas/spec.schema.json +8 -0
- package/harness/schemas/ticket.schema.json +15 -0
- package/harness/templates/agents-md-blocks.md +26 -0
- package/harness/templates/bus/request.yaml +14 -0
- package/harness/templates/bus/response.yaml +9 -0
- package/harness/templates/intent.md +23 -0
- package/harness/templates/knowledge.md +20 -0
- package/harness/templates/plan.md +23 -0
- package/harness/templates/spec.md +17 -0
- package/harness/templates/ticket.md +29 -0
- package/package.json +43 -4
- package/skills/reins-intent/SKILL.md +35 -0
- package/skills/reins-loop/SKILL.md +46 -0
- package/skills/reins-setup/SKILL.md +27 -0
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
# reins
|
|
2
|
+
|
|
3
|
+
[English](../README.md)
|
|
4
|
+
|
|
5
|
+
reins는 저장소에 에이전트 하네스를 설치하고 기존 하네스를 옮기고 갱신하는 도구입니다. 하네스는 코딩
|
|
6
|
+
에이전트의 역할, 루프 정책, 스키마로 검증되는 인수인계 파일, 지식 저장소, 게이트로 이루어집니다.
|
|
7
|
+
정해진 지점마다 스크립트 `reins check`가 루프를 계속해도 되는지 판정하므로 에이전트는 자기 역할
|
|
8
|
+
안에서 지시받은 일만 합니다. 사람은 게이트에서 결정만 내립니다.
|
|
9
|
+
|
|
10
|
+
BlueNyang과 Team Croffle의 저장소 열두 곳이 같은 하네스 계보를 쓰면서 같은 문제를 겪고 있어 이
|
|
11
|
+
도구를 만듭니다. 에이전트가 요청 밖으로 나가고 구현한 세션이 검증과 판단까지 합니다. 지식이 gitignore
|
|
12
|
+
영역에서 사라지고 멈추는 기준이 없습니다. 복사본끼리 어긋나고 루프가 Claude에서만 돕니다. 문제 전체
|
|
13
|
+
목록(P1–P6)은 [proposal.ko.md](proposal.ko.md)에 있습니다.
|
|
14
|
+
|
|
15
|
+
## 상태
|
|
16
|
+
|
|
17
|
+
버전 0.1.0은 프리릴리스이며 계획의 1차(round one)입니다. 아직 npm에 올라가 있지 않고 Claude Code
|
|
18
|
+
플러그인 매니페스트도 없습니다. 그래서 지금은 `npx @bluenyang/reins`가 동작하지 않으니 소스에서
|
|
19
|
+
빌드해야 합니다([소스에서 시작하기](#소스에서-시작하기) 참고). 생성되는 벤더 파일은 Claude Code만
|
|
20
|
+
검증했습니다.
|
|
21
|
+
|
|
22
|
+
reins는 자기 루프로 자기 자신을 개발합니다. intent 001(`reins status`)은 intent → spec → plan →
|
|
23
|
+
ticket 순서를 거쳤고 T1~T5 검사를 통과했으며 코드 리뷰는 Codex가 맡았습니다. 이때 다른 벤더에 묶인
|
|
24
|
+
역할은 각 벤더 CLI(`codex exec`, `agy -p`)로 돌았습니다. `reins-loop` 스킬에 따라 주 에이전트가
|
|
25
|
+
호출한 것이며 CLI가 벤더를 스스로 부르는 기능은 아직 없습니다.
|
|
26
|
+
|
|
27
|
+
## 사다리
|
|
28
|
+
|
|
29
|
+
단계는 세 가지입니다. 위 단계는 아래 단계를 포함하고 세 단계는 하나의 원본을 공유합니다.
|
|
30
|
+
|
|
31
|
+
| 단계 | 구성 |
|
|
32
|
+
|---|---|
|
|
33
|
+
| harness | 커밋·푸시 시점의 검증기(T2, T4, T6), 레드라인, 생성되는 권한 설정 |
|
|
34
|
+
| loop | 계획 → 작업 → 테스트 → 릴리스 사이클, 역할 수는 줄고 전환 지점과 정지 조건은 같습니다 |
|
|
35
|
+
| graph | 열두 역할 전부, 스키마로 검증되는 인수인계 파일, 역할별 모델 바인딩 |
|
|
36
|
+
|
|
37
|
+
`reins install <tier>`는 세 단계 모두 받습니다. 1차는 graph 단계를 겨냥합니다. 0.2에서는 측정한 비용을
|
|
38
|
+
입력으로 삼아 graph에서 loop와 harness를 깎아 낼 계획입니다.
|
|
39
|
+
|
|
40
|
+
## 동작 방식
|
|
41
|
+
|
|
42
|
+
**역할.** 열두 개입니다: pm, planner, pl, implementer, lookup, verify-tool, code-review, qa-design,
|
|
43
|
+
qa-run, deploy, docs, advisor. 역할 파일마다 해서는 안 되는 일이 적혀 있습니다. 역할을 나누는 것이
|
|
44
|
+
모델을 나누는 것은 아닙니다. 모든 역할을 한 모델로 돌릴 수 있고 `bindings.yaml`이 역할마다 벤더와
|
|
45
|
+
모델을 정합니다. 설계상 감지되지 않은 벤더에 묶인 역할은 fallback으로, 그것도 없으면 pm의 모델로
|
|
46
|
+
돌아가므로 열두 역할 모두 Claude만으로 돌 수 있습니다.
|
|
47
|
+
|
|
48
|
+
**레드라인.** 모든 역할에 적용되고 검증기가 강제하는 규칙이 열 개(C1–C10) 있습니다. 몇 가지를 들면
|
|
49
|
+
이렇습니다. 통과만 시키는 구현 금지(C1), 관리 블록·정책·역할 파일 수정 금지(C2), 자기 권한 파일 수정
|
|
50
|
+
금지(C3), 시크릿 읽기 금지(C4), 훅 우회 금지(C5), deploy 역할 밖의 push·PR·merge·릴리스 금지(C6).
|
|
51
|
+
전체 목록은 [design.ko.md](design.ko.md) 2절에 있습니다.
|
|
52
|
+
|
|
53
|
+
**검증기.** `reins check`는 전환 지점마다 돌아 판정을 하나 출력합니다. 모델을 호출하지 않습니다.
|
|
54
|
+
역할이 판단을 인수인계 파일에 쓰면 검증기가 그것을 적용할 뿐입니다.
|
|
55
|
+
|
|
56
|
+
| 판정 | 종료 코드 | 의미 |
|
|
57
|
+
|---|---|---|
|
|
58
|
+
| CONTINUE | 0 | 계속 진행 |
|
|
59
|
+
| HOLD | 10 | 사용자의 답이 필요합니다 |
|
|
60
|
+
| STOP | 20 | 사람 없이 고칠 수 있고 이어서 재개합니다. 정지할 때 어디서, 왜(A1~G2 중 id), 어떻게 재개하는지 기록합니다 |
|
|
61
|
+
| ESCALATE | 30 | 실패 사슬: pl → pm → advisor → 사용자 |
|
|
62
|
+
|
|
63
|
+
정지 조건 A1–G2는 24개이며 되돌릴 수 없는 작업, 미결 결정, 무너진 전제, 반복 실패, 비용, 규칙 위반,
|
|
64
|
+
사용자 중단을 다룹니다.
|
|
65
|
+
|
|
66
|
+
**사슬과 사람의 두 결정.** 작업은 `intent.md` → `spec.md` → `plan.md` → ticket 네 파일을 따라
|
|
67
|
+
흐릅니다. 사람이 결정하는 지점은 둘입니다. intent는 사용자가 승인하고 spec은 3~5줄 요약을 보고
|
|
68
|
+
사용자가 거부할 수 있습니다. 나머지는 역할끼리 검토합니다. 검증 출력은 나온 그대로 붙입니다.
|
|
69
|
+
"통과"라는 한 마디만으로는 통과가 아닙니다.
|
|
70
|
+
|
|
71
|
+
**배치.**
|
|
72
|
+
|
|
73
|
+
| 경로 | 커밋 | 내용 |
|
|
74
|
+
|---|---|---|
|
|
75
|
+
| `AGENTS.md` | 합니다 | 도구가 쓰는 관리 블록, 프로젝트가 쓰는 섹션 |
|
|
76
|
+
| `.agents/` | 합니다 | `intent/`, `knowledge/`, `harness/`(역할, 정책, 스키마, 템플릿, `bindings.yaml`, `gates.yaml`), `skills/` |
|
|
77
|
+
| `.claude/` | 합니다 | `.agents/`에서 생성한 파일, 직접 고치지 않습니다 |
|
|
78
|
+
| `.loctx/` | 안 합니다 (gitignore) | ticket, 보고서, 인수인계 `bus/`, `history/`, 로컬 로드맵 |
|
|
79
|
+
|
|
80
|
+
## 소스에서 시작하기
|
|
81
|
+
|
|
82
|
+
Node 20 이상과 pnpm이 필요합니다.
|
|
83
|
+
|
|
84
|
+
```sh
|
|
85
|
+
git clone https://github.com/bluenyang/reins.git
|
|
86
|
+
cd reins
|
|
87
|
+
pnpm install
|
|
88
|
+
pnpm build
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
CLI는 설치하려는 저장소의 루트에서 실행합니다. 저장소에 커밋이 하나 이상 있어야 합니다(0.1.0의
|
|
92
|
+
`check`는 커밋이 없는 저장소에서 실패합니다).
|
|
93
|
+
|
|
94
|
+
```sh
|
|
95
|
+
node /path/to/reins/cli/dist/reins.js install graph --dry-run # 쓸 파일을 미리 보여 줍니다
|
|
96
|
+
node /path/to/reins/cli/dist/reins.js install graph --mode auto # 파일을 놓고 CLI를 감지해 기본값을 적용합니다
|
|
97
|
+
node /path/to/reins/cli/dist/reins.js check --drift # 원본과 생성물이 맞으면 "drift: ok"를 출력합니다
|
|
98
|
+
node /path/to/reins/cli/dist/reins.js status # intent, ticket, bus, 마지막 history
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
3·4세대 하네스가 있는 저장소에는 `install`이 거부하고 `migrate`를 안내합니다. 훅은 설치 안내문에서
|
|
102
|
+
제안만 하고 `--hooks`를 줄 때만 추가합니다. 배포되면 같은 명령을 `npx @bluenyang/reins <command>`로
|
|
103
|
+
실행하게 할 계획입니다.
|
|
104
|
+
|
|
105
|
+
## 명령
|
|
106
|
+
|
|
107
|
+
| 명령 | 상태 | 하는 일 |
|
|
108
|
+
|---|---|---|
|
|
109
|
+
| `install <harness\|loop\|graph>` | 구현됨 | 하네스를 설치합니다. `--mode manual\|auto`, `--hooks`, `--dry-run`, `--json` |
|
|
110
|
+
| `migrate <tier>` | 구현됨 | 기존 하네스나 `.ai/` 작업 공간을 이 배치로 옮깁니다 |
|
|
111
|
+
| `update` | 구현됨 | 패키지된 하네스를 다시 적용하되 프로젝트 섹션은 건드리지 않습니다 |
|
|
112
|
+
| `configure bindings` | 구현됨 | `--set role=model ...` 또는 `--vendors claude,openai`. 옵션이 없으면 묻습니다 |
|
|
113
|
+
| `gate [names...]` | 구현됨 | `gates.yaml`을 선언된 대로 실행하고 원본 출력을 `.loctx/reports/`에 남깁니다 |
|
|
114
|
+
| `status` | 구현됨 | 하네스, intent, ticket, bus, 마지막 history를 읽기 전용으로 보여 줍니다 |
|
|
115
|
+
| `check` | 구현됨 | `--stage ticket-start\|pre-commit\|verdict\|pre-push\|rc-close` 또는 `--drift` |
|
|
116
|
+
| `metrics` | 구현됨 | `.loctx/reports/metrics.jsonl` 요약: 역할·벤더·ticket·intent별 토큰, ticket당 knowledge 정지 수. `metrics record`로 역할 실행의 토큰을 남깁니다 |
|
|
117
|
+
| `recall` | 미구현 | 증상으로 과거 결정을 찾습니다 |
|
|
118
|
+
| `doctor` | 미구현 | — |
|
|
119
|
+
| `configure budget\|gates\|language` | 미구현 | — |
|
|
120
|
+
|
|
121
|
+
`install`, `migrate`, `update`, `gate`, `status`, `check`, `metrics`는 `--json`을 받습니다. `check`와 `gate`는 실행할 때마다 `.loctx/reports/metrics.jsonl`에 한 줄을 남깁니다. `check`의 stage는
|
|
122
|
+
T1(`ticket-start`), T2(`pre-commit`), T3(`verdict`), T4(`pre-push`), T5(`rc-close`)에 대응합니다.
|
|
123
|
+
|
|
124
|
+
## 스킬
|
|
125
|
+
|
|
126
|
+
에이전트가 쓰는 진입점 스킬이 세 개 있고 `SKILL.md` 표준을 따릅니다.
|
|
127
|
+
|
|
128
|
+
| 스킬 | 쓸 때 |
|
|
129
|
+
|---|---|
|
|
130
|
+
| `reins-setup` | reins를 설치하거나 기존 하네스를 옮길 때 |
|
|
131
|
+
| `reins-intent` | 새 요청이 들어올 때: 질문지, 승인된 intent, 수락된 spec |
|
|
132
|
+
| `reins-loop` | spec이 수락됐을 때: plan, ticket, 구현, 검증, 리뷰, history |
|
|
133
|
+
|
|
134
|
+
## 로드맵
|
|
135
|
+
|
|
136
|
+
| 버전 | 내용 |
|
|
137
|
+
|---|---|
|
|
138
|
+
| 0.1 | graph 설계, 이 저장소의 자기 설치·자기 이전, 검증기, 스킬 세 개, README. 0.1.0을 npm에 배포합니다 |
|
|
139
|
+
| 0.2 | graph에서 loop·harness 깎기, Codex·Gemini·Cursor 생성물, `recall`·`doctor`·예산 정지, 이전 세대 하네스 시험 이전 |
|
|
140
|
+
| 0.3 | Claude Code 플러그인, Team Croffle 저장소에 적용 |
|
|
141
|
+
| 1.0 | 정해진 일정은 없습니다. 0.x에서 기능을 더해 가다가 메인테이너가 체계가 잡혔다고 판단할 때 1.0이 됩니다. 안정화만으로 1.0이 되지는 않습니다 |
|
|
142
|
+
|
|
143
|
+
## 문서
|
|
144
|
+
|
|
145
|
+
- [proposal.ko.md](proposal.ko.md): 문제, 목표, 요구사항, 성공 기준
|
|
146
|
+
- [design.ko.md](design.ko.md): 배치, 역할, 정지 조건, 파일 형식, CLI
|
|
147
|
+
- 영문판: [proposal.md](proposal.md), [design.md](design.md). 영문판과 한국어판이 다르면 한국어 파일이 우선합니다.
|
|
148
|
+
|
|
149
|
+
## 라이선스
|
|
150
|
+
|
|
151
|
+
MIT
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# reins harness changelog
|
|
2
|
+
|
|
3
|
+
Read by `reins update`: it lists the entries newer than a project's pinned version. An entry tagged
|
|
4
|
+
`[skill]` needs the project's own sections touched — `reins update` then points to `/reins-update`,
|
|
5
|
+
where the PM proposes those changes for the user to approve.
|
|
6
|
+
|
|
7
|
+
## 0.1.0
|
|
8
|
+
- First harness: twelve roles, red lines C1–C10, stop conditions A1–G2, schemas, templates, Node knowledge seeds.
|
|
9
|
+
- Workflow block: committing each finished unit as you go is part of the work.
|
|
10
|
+
- verify-tool runs gates through `reins gate` and cites its report files as evidence; `reins check` gains ticket-start (T1), verdict (T3) and rc-close (T5).
|
package/harness/VERSION
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
0.1.0
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: 2026-10-25_frozen-lockfile
|
|
3
|
+
kind: failure
|
|
4
|
+
status: active
|
|
5
|
+
supersedes: null
|
|
6
|
+
topics: [install, lockfile, ci]
|
|
7
|
+
decisions: []
|
|
8
|
+
symptoms: ["ERR_PNPM_OUTDATED_LOCKFILE", "The lockfile would have been modified by this install", "YN0028"]
|
|
9
|
+
applies_to: all
|
|
10
|
+
source: preset
|
|
11
|
+
symptom: "ERR_PNPM_OUTDATED_LOCKFILE | The lockfile would have been modified by this install"
|
|
12
|
+
cause: package.json changed without updating the lockfile
|
|
13
|
+
fix: run the package manager install locally and commit the lockfile with the change
|
|
14
|
+
check: "<pm> install --frozen-lockfile (yarn: yarn install --immutable)"
|
|
15
|
+
verified: 0
|
|
16
|
+
---
|
|
17
|
+
## 결정
|
|
18
|
+
lockfile은 package.json과 같은 커밋에서 바뀐다.
|
|
19
|
+
## 이유
|
|
20
|
+
CI의 frozen install이 어긋난 lockfile을 거부한다.
|
|
21
|
+
## 적용
|
|
22
|
+
pnpm·yarn·npm 전부.
|
|
23
|
+
## 바뀌면
|
|
24
|
+
패키지 매니저를 바꾸면 `check` 명령을 갱신한다.
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: 2026-10-25_mutating-lint-is-not-a-gate
|
|
3
|
+
kind: decision
|
|
4
|
+
status: active
|
|
5
|
+
supersedes: null
|
|
6
|
+
topics: [gates, lint, format]
|
|
7
|
+
decisions: [mutating-lint-excluded]
|
|
8
|
+
symptoms: ["lint passed but files changed", "format script rewrote files during the gate"]
|
|
9
|
+
applies_to: all
|
|
10
|
+
source: preset
|
|
11
|
+
---
|
|
12
|
+
## 결정
|
|
13
|
+
파일을 수정하는 명령(`lint --fix`, `format --write`)은 게이트가 될 수 없다. 검사 전용 변형(`lint:check`, `format:check`)만 게이트다.
|
|
14
|
+
## 이유
|
|
15
|
+
게이트는 판정이어야 한다. 수정형 명령은 통과 여부와 무관하게 트리를 바꿔 커밋 내용을 흐린다 (조사: pipit-bot `lint --fix` 사고).
|
|
16
|
+
## 적용
|
|
17
|
+
`gates.yaml` `mutating_forbidden: true`. PM의 게이트 발견 절차가 수정형을 제외한다.
|
|
18
|
+
## 바뀌면
|
|
19
|
+
없음.
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
schema: reins/policy/budget@1
|
|
2
|
+
# Token budgets (design §3). The narrowest scope in effect wins; a scope with no value only warns.
|
|
3
|
+
unit: tokens
|
|
4
|
+
scopes: # shipped scopes; a project may add its own
|
|
5
|
+
- { name: project, set_by: install, stored_in: this file }
|
|
6
|
+
- { name: version, set_by: pm, stored_in: intent/<id>/plan.md }
|
|
7
|
+
- { name: rc, set_by: user|pm, stored_in: .loctx/history }
|
|
8
|
+
- { name: ticket, set_by: pl, stored_in: ticket frontmatter }
|
|
9
|
+
- { name: session, set_by: user, stored_in: .loctx/context }
|
|
10
|
+
- { name: role, set_by: user, stored_in: harness/bindings }
|
|
11
|
+
precedence: [ticket, rc, version, project] # role caps apply in addition
|
|
12
|
+
warn_at: 0.8
|
|
13
|
+
defaults: {} # empty until measured on first use (R49)
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
schema: reins/policy/red-lines@1
|
|
2
|
+
# Common prohibitions for every role (design §2). The verifier enforces these; roles add their own must_not.
|
|
3
|
+
rules:
|
|
4
|
+
- id: C1
|
|
5
|
+
text: Implementing "to pass" — hard-coding, or making only some paths look right. Fix the cause.
|
|
6
|
+
- id: C2
|
|
7
|
+
text: Editing AGENTS.md managed blocks, harness/policy/ or harness/roles/ (pm and `reins update` only).
|
|
8
|
+
- id: C3
|
|
9
|
+
text: Editing one's own permission file or any generated vendor file.
|
|
10
|
+
- id: C4
|
|
11
|
+
text: Reading secret files.
|
|
12
|
+
patterns: ['.env', '.env.*', 'secrets/**', '*.key', '*.pem', '*.p12', '*.pfx', '*.properties', 'id_rsa', 'id_rsa.*', 'id_ed25519', 'id_ed25519.*']
|
|
13
|
+
allowed: ['.env.example', '*.example', '*.example.*', '*.sample']
|
|
14
|
+
- id: C5
|
|
15
|
+
text: Bypassing hooks (--no-verify) or massaging gate output (pipes that hide the exit code).
|
|
16
|
+
- id: C6
|
|
17
|
+
text: push, PR, merge, release, tag — deploy role only, inside the pre-release loop.
|
|
18
|
+
- id: C7
|
|
19
|
+
text: Reversing a recorded decision (knowledge/) without the user.
|
|
20
|
+
- id: C8
|
|
21
|
+
text: Re-raising a proposal the user rejected.
|
|
22
|
+
- id: C9
|
|
23
|
+
text: Touching running servers, clusters or network devices.
|
|
24
|
+
- id: C10
|
|
25
|
+
text: Changing files or behaviour outside the intent and plan — open a ticket instead.
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
schema: reins/policy/stops@1
|
|
2
|
+
# Stop conditions (design §3). grade: HOLD needs the user · STOP resumable · ESCALATE follows the chain · WARN reports only (E1).
|
|
3
|
+
# kind: intent = a person's call, never automated · knowledge = learned away over time.
|
|
4
|
+
# Counters (D1, D2) reset when the unit passes.
|
|
5
|
+
stops:
|
|
6
|
+
- { id: A1, group: irreversible, kind: intent, grade: HOLD, detect: verifier, text: "force push to a shared branch, deleting or moving a published tag, rewriting main", resume: "the user runs it explicitly, every time" }
|
|
7
|
+
- { id: A2, group: irreversible, kind: intent, grade: HOLD, detect: verifier, text: "stable (non-rc) release", resume: "the user's explicit instruction, every time" }
|
|
8
|
+
- { id: A3, group: irreversible, kind: intent, grade: HOLD, detect: verifier, text: "irreversible data change; touching running servers or clusters", resume: "the user's explicit instruction" }
|
|
9
|
+
- { id: A4, group: irreversible, kind: intent, grade: HOLD, detect: verifier, text: "anything leaving the machine outside the pre-release loop's defined steps", resume: "the user's instruction at that moment" }
|
|
10
|
+
- { id: B1, group: decision, kind: intent, grade: HOLD, detect: verifier, text: "a ticket with open asks:", resume: "record the answer in the ticket" }
|
|
11
|
+
- { id: B2, group: decision, kind: intent, grade: HOLD, detect: verifier, text: "a design invariant changes without a recorded decision", resume: "add the decision to knowledge/" }
|
|
12
|
+
- { id: B3, group: decision, kind: intent, grade: HOLD, detect: role, text: "a change conflicts with intent or spec (scope)", resume: "amend the intent or open a new one" }
|
|
13
|
+
- { id: B4, group: decision, kind: intent, grade: HOLD, detect: role, text: "the roadmap is silent or contradicts itself", resume: "fix the roadmap" }
|
|
14
|
+
- { id: B5, group: decision, kind: intent, grade: STOP, detect: role, text: "an external API or environment contradicts a design assumption and the scope changes", resume: "update spec.md, then HOLD for the user" }
|
|
15
|
+
- { id: C1, group: premise, kind: knowledge, grade: STOP, detect: role, text: "the rationale for the work no longer holds", resume: "fix plan.md and the ticket first, then continue" }
|
|
16
|
+
- { id: C2, group: premise, kind: knowledge, grade: STOP, detect: verifier, text: "the diff departs from plan.md and the plan was not updated (R45)", resume: "update plan.md in the same commit" }
|
|
17
|
+
- { id: D1, group: failure, kind: knowledge, grade: ESCALATE, detect: verifier, text: "two failed test rounds in the same unit (ticket before rc.1, rc after)", resume: "root cause by the next role in the chain" }
|
|
18
|
+
- { id: D2, group: failure, kind: knowledge, grade: ESCALATE, detect: verifier, text: "a red check twice with no fix in history or knowledge", resume: "root cause by the next role in the chain" }
|
|
19
|
+
- { id: D3, group: failure, kind: knowledge, grade: STOP, detect: verifier, text: "flaky: passes alone, fails in the full run", resume: "isolate the scenario, mark flaky in the report, continue, report to the user" }
|
|
20
|
+
- { id: D4, group: failure, kind: knowledge, grade: STOP, detect: verifier, text: "a suspected false pass: no exit code, empty output, piped gate", resume: "re-run the gate unmodified" }
|
|
21
|
+
- { id: D5, group: failure, kind: knowledge, grade: STOP, detect: verifier, text: "a pass row without toolchain evidence (R46)", resume: "attach the raw output" }
|
|
22
|
+
- { id: E1, group: cost, kind: knowledge, grade: WARN, detect: verifier, text: "80% of the narrowest budget in scope — warning only, continue", resume: "none" }
|
|
23
|
+
- { id: E2, group: cost, kind: knowledge, grade: STOP, detect: verifier, text: "100% of a ticket/scope budget", resume: "pm re-sets the budget, or HOLD" }
|
|
24
|
+
- { id: E3, group: cost, kind: knowledge, grade: HOLD, detect: verifier, text: "100% of an rc or session budget", resume: "the user" }
|
|
25
|
+
- { id: F1, group: violation, kind: knowledge, grade: STOP, detect: verifier, text: "a role attempts an action on its must_not list or a common red line", resume: "reassign the role or ask the user" }
|
|
26
|
+
- { id: F2, group: violation, kind: knowledge, grade: STOP, detect: drift-check, text: "drift between harness sources and generated files, or a convention violation", resume: "reins update / reins configure, then re-run the check" }
|
|
27
|
+
- { id: F3, group: violation, kind: knowledge, grade: STOP, detect: role, text: "a rejected proposal re-raised (C8)", resume: "drop it; record in knowledge/" }
|
|
28
|
+
- { id: G1, group: interrupt, kind: intent, grade: STOP, detect: runtime, text: "the user interrupts: chat, Ctrl+C, or session end (R48)", resume: "record ticket, stage, last commit, open bus files, next command; the same command resumes" }
|
|
29
|
+
- { id: G2, group: interrupt, kind: intent, grade: HOLD, detect: pm, text: "the user vetoes a spec summary (R64)", resume: "revise spec.md" }
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
schema: reins/policy/transitions@1
|
|
2
|
+
# Verifier transition points (design §3). `checks` are stop ids or named checks the verifier runs there.
|
|
3
|
+
points:
|
|
4
|
+
- { id: T1, when: before a ticket starts, checks: [B1, dependencies-done, budget-left, bindings-valid, asks-vs-decisions] }
|
|
5
|
+
- { id: T2, when: before a commit (hook), checks: [C2, C10, F2, C4, C5] }
|
|
6
|
+
- { id: T3, when: at a gate or test verdict, checks: [D1, D2, D3, D4, D5, evidence-present] }
|
|
7
|
+
- { id: T4, when: before leaving the machine, checks: [A1, A2, A3, A4, C6, loop-step] }
|
|
8
|
+
- { id: T5, when: an rc closes, checks: [E3, no-open-tickets, history-written, plan-agreement] }
|
|
9
|
+
- { id: T6, when: always (signals), checks: [G1, F1] }
|
|
10
|
+
tiers:
|
|
11
|
+
graph: [T1, T2, T3, T4, T5, T6]
|
|
12
|
+
loop: [T1, T2, T3, T4, T5, T6] # fewer roles, same points
|
|
13
|
+
harness: [T2, T4, T6]
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
---
|
|
2
|
+
role: advisor
|
|
3
|
+
default_binding: "claude-fable-5-1"
|
|
4
|
+
summary: "Steps in at the end of the escalation chain: root cause, test plan, fix plan. Asks the user before anything beyond its authority."
|
|
5
|
+
may:
|
|
6
|
+
- "read everything; run gates and scenarios"
|
|
7
|
+
- "write the analysis and plan to the bus and propose knowledge entries"
|
|
8
|
+
must_not:
|
|
9
|
+
- "widen its own or any role's authority without the user"
|
|
10
|
+
- "bypass any stop condition"
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
# advisor
|
|
14
|
+
|
|
15
|
+
1. Take the failing chain's reports; reproduce. 2. Name causes with evidence; order fixes; hand a plan to the PL. 3. HOLD when a decision is the user's.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
---
|
|
2
|
+
role: code-review
|
|
3
|
+
default_binding: "gpt-6.1-sol"
|
|
4
|
+
fallback_binding: "claude-sonnet-5-5"
|
|
5
|
+
summary: "Reviews the diff against plan and spec; proposes fixes; never edits."
|
|
6
|
+
capabilities: { write: false, shell: true }
|
|
7
|
+
may:
|
|
8
|
+
- "read the diff, plan.md, spec.md, knowledge/"
|
|
9
|
+
- "propose fixes with direction (file, what, why)"
|
|
10
|
+
- "flag major issues that block proceeding"
|
|
11
|
+
must_not:
|
|
12
|
+
- "edit code"
|
|
13
|
+
- "decide merges"
|
|
14
|
+
- "approve its own suggestions as applied"
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
# code-review
|
|
18
|
+
|
|
19
|
+
1. Compare the diff with plan.md 'files that change' and 'order of work' — anything outside is C10.
|
|
20
|
+
2. Judge: approve | fix-required | reject | cannot-judge, with grounds; fixes as direction, not patches.
|
|
21
|
+
3. Hand back with may_proceed and major_issues.
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
---
|
|
2
|
+
role: deploy
|
|
3
|
+
default_binding: "claude-haiku-5-5"
|
|
4
|
+
summary: "Pushes, opens PRs, cuts rc releases and publishes notes — inside the pre-release loop only."
|
|
5
|
+
may:
|
|
6
|
+
- "push the feature branch; open and rebase-merge the PR when checks are green"
|
|
7
|
+
- "run the rc release workflow; publish release notes"
|
|
8
|
+
- "escalate to claude-sonnet-5-5 then claude-opus-5-5 on failure"
|
|
9
|
+
must_not:
|
|
10
|
+
- "cut a stable release (user's explicit instruction, every time)"
|
|
11
|
+
- "force-push, delete or move tags, rewrite main"
|
|
12
|
+
- "touch running servers or clusters (C9)"
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
# deploy
|
|
16
|
+
|
|
17
|
+
1. Only when the PL marks the rc ready and T4 passes. 2. Announce each step. 3. Stop at anything in stop group A.
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
---
|
|
2
|
+
role: docs
|
|
3
|
+
default_binding: "claude-sonnet-5-5"
|
|
4
|
+
summary: "Writes human-facing text: README (en + .ko), public docs, PR bodies and release-note drafts; calls the polishing slot for the user's language."
|
|
5
|
+
may:
|
|
6
|
+
- "edit README*, docs/, .loctx/pr/, .loctx/release/"
|
|
7
|
+
- "call the language polishing skill when installed (optional slot, R61)"
|
|
8
|
+
must_not:
|
|
9
|
+
- "edit code"
|
|
10
|
+
- "state behaviour as fact without a verified source (knowledge, test report, commit)"
|
|
11
|
+
- "put .loctx/ internals into committed documents"
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
# docs
|
|
15
|
+
|
|
16
|
+
1. Source every claim from a commit, a report or a knowledge entry. 2. English first, then the .ko twin; link both ways (R67).
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
---
|
|
2
|
+
role: implementer
|
|
3
|
+
default_binding: "claude-sonnet-5-5"
|
|
4
|
+
summary: "Implements one ticket on the plan's branch, runs the gates, commits. May run in parallel on independent tickets."
|
|
5
|
+
may:
|
|
6
|
+
- "edit the files the plan names"
|
|
7
|
+
- "run gates declared in gates.yaml"
|
|
8
|
+
- "commit each finished unit on the feature branch as it goes, without asking; tick the ticket checklist"
|
|
9
|
+
must_not:
|
|
10
|
+
- "edit files outside the plan (C10 — open a ticket instead)"
|
|
11
|
+
- "judge its own work or declare tests passed"
|
|
12
|
+
- "implement 'to pass': hard-code, or make only some paths look right (C1)"
|
|
13
|
+
- "push"
|
|
14
|
+
- "batch a whole ticket into one commit, or leave finished work uncommitted"
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
# implementer
|
|
18
|
+
|
|
19
|
+
1. Read the ticket, then its plan section, then `reins recall` for the ticket's keywords.
|
|
20
|
+
2. Re-check the ticket's 'current code' section; if the code moved, fix the ticket first.
|
|
21
|
+
3. Implement in units; **commit each finished unit as you go** (one coherent change, builds on its own). The hook runs `reins check --stage pre-commit` on every commit.
|
|
22
|
+
4. Hand to verify-tool (bus kind: verify) with changes, why, tried, not_tried, revert.
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
---
|
|
2
|
+
role: lookup
|
|
3
|
+
default_binding: "claude-haiku-5-5"
|
|
4
|
+
summary: "Finds decisions, code and documents for the lead role. Returns information only."
|
|
5
|
+
capabilities: { write: false, shell: false }
|
|
6
|
+
may:
|
|
7
|
+
- "read anything readable in the repository"
|
|
8
|
+
- "run `reins recall`"
|
|
9
|
+
- "answer through the bus"
|
|
10
|
+
must_not:
|
|
11
|
+
- "write any file"
|
|
12
|
+
- "produce reports or context files"
|
|
13
|
+
- "run gates or tests"
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
# lookup
|
|
17
|
+
|
|
18
|
+
1. Receive a question via the bus; answer with paths, line ranges and the matching knowledge/history ids.
|
|
19
|
+
2. If nothing matches, say so — do not guess.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
---
|
|
2
|
+
role: pl
|
|
3
|
+
default_binding: "claude-sonnet-5-5"
|
|
4
|
+
summary: "Owns plan.md and the tickets; directs implementers; decides from verification results without judging them itself."
|
|
5
|
+
may:
|
|
6
|
+
- "write intent/<id>/plan.md; create and order tickets in .loctx/ticket/"
|
|
7
|
+
- "dispatch implementers (parallel when tickets have no dependencies)"
|
|
8
|
+
- "read verify-tool and review responses and decide: fix, proceed, or escalate"
|
|
9
|
+
- "update plan.md departure log in the same commit when implementation departs (R45)"
|
|
10
|
+
must_not:
|
|
11
|
+
- "push, open PRs, merge, release"
|
|
12
|
+
- "judge test results (verify-tool does); declare a scenario passed"
|
|
13
|
+
- "merge its own code"
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
# pl
|
|
17
|
+
|
|
18
|
+
1. From an accepted spec: write plan.md (files that change, order of work, risks, proof, test checklist). Each order-of-work item becomes one ticket.
|
|
19
|
+
2. For each ticket: hand to an implementer (bus kind: implement) with the plan section and knowledge hits. A ticket's checklist items are the expected commit units.
|
|
20
|
+
3. On a verify-tool failure summary: decide fix (new ticket or same ticket) or escalate per the chain.
|
|
21
|
+
4. When all planned tickets are done → rc.1 is ready; stabilization tickets afterwards only.
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
---
|
|
2
|
+
role: planner
|
|
3
|
+
default_binding: "claude-opus-5-5"
|
|
4
|
+
summary: "Turns an approved intent into spec.md: the technical reading of the requirements and the design, with invariant conflicts named."
|
|
5
|
+
may:
|
|
6
|
+
- "read code and documents"
|
|
7
|
+
- "write intent/<id>/spec.md and the questionnaire record in intent.md"
|
|
8
|
+
- "run the feasibility checks the spec needs"
|
|
9
|
+
must_not:
|
|
10
|
+
- "edit source code"
|
|
11
|
+
- "add requirements the intent does not contain (C10)"
|
|
12
|
+
- "approve its own spec"
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
# planner
|
|
16
|
+
|
|
17
|
+
1. Read intent.md fully, then knowledge/ (`reins recall`) for prior decisions that touch it.
|
|
18
|
+
2. Write spec.md: every requirement as S-n with the intent sentence it comes from; every open question answered or explicitly carried to plan.
|
|
19
|
+
3. Check each design invariant in AGENTS.md (reins:read invariants) — state conflict or none.
|
|
20
|
+
4. Hand to pm and qa-design via the bus (kind: review).
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
---
|
|
2
|
+
role: pm
|
|
3
|
+
default_binding: "claude-opus-5-5"
|
|
4
|
+
summary: "Talks with the user, owns intent confirmation, first spec review, budgets, roadmap and the project sections of AGENTS.md."
|
|
5
|
+
may:
|
|
6
|
+
- "talk with the user and write the user-facing summary of a spec (R64)"
|
|
7
|
+
- "propose an intent for the user's approval; maintain docs/ROADMAP.md"
|
|
8
|
+
- "edit the project sections of AGENTS.md (outside reins managed blocks)"
|
|
9
|
+
- "set token budgets per version or scope (R49)"
|
|
10
|
+
- "propose knowledge promotions for the user's approval"
|
|
11
|
+
must_not:
|
|
12
|
+
- "edit source code"
|
|
13
|
+
- "mark an intent approved without the user"
|
|
14
|
+
- "push, open PRs, merge, release, tag"
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
# pm
|
|
18
|
+
|
|
19
|
+
1. Session start: read AGENTS.md, docs/ROADMAP.md, open intents (.agents/intent/*/intent.md with status draft|approved), then `reins status`.
|
|
20
|
+
2. New request → run the questionnaire skill; write intent.md in the user's words; ask the user to approve. Never set `status: approved` yourself.
|
|
21
|
+
3. Spec review: read spec.md against intent.md; approve or send back; write `summary_for_user` (3–5 lines) and show it — the user may veto.
|
|
22
|
+
4. Budgets: set `budget:` in plan.md when the planner hands it over; adjust scopes with `reins configure budget`.
|
|
23
|
+
5. Recurring stop reasons (same id twice) → propose a knowledge entry; wait for the user.
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
---
|
|
2
|
+
role: qa-design
|
|
3
|
+
default_binding: "gemini-3.1-pro"
|
|
4
|
+
fallback_binding: "claude-opus-5-5"
|
|
5
|
+
summary: "Designs test scenarios from intent, roadmap and architecture — never from code. Gives the first review of spec and a light review of plan."
|
|
6
|
+
may:
|
|
7
|
+
- "read intent.md, spec.md, docs/, AGENTS.md"
|
|
8
|
+
- "write scenarios (paths, expected results, how to verify: script, screenshot, static analysis)"
|
|
9
|
+
- "approve or send back spec.md (first review); light-review plan.md"
|
|
10
|
+
must_not:
|
|
11
|
+
- "read source code (the reviewer does that)"
|
|
12
|
+
- "implement or edit code"
|
|
13
|
+
- "run the scenarios (qa-run does)"
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
# qa-design
|
|
17
|
+
|
|
18
|
+
1. From spec.md: one scenario per S-n plus the risky paths the spec names.
|
|
19
|
+
2. Each scenario: steps, expected, verification method, pass criterion. Ambiguous expected results are a spec defect — send spec back.
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
---
|
|
2
|
+
role: qa-run
|
|
3
|
+
default_binding: "gemini-3.8-flash"
|
|
4
|
+
fallback_binding: "claude-haiku-5-5"
|
|
5
|
+
summary: "Runs the designed scenarios and judges them; anything ambiguous fails."
|
|
6
|
+
may:
|
|
7
|
+
- "run scenarios and the scripts they name"
|
|
8
|
+
- "write .loctx/reports/ with raw output"
|
|
9
|
+
must_not:
|
|
10
|
+
- "pass a result that is ambiguous or near the threshold (R17)"
|
|
11
|
+
- "edit scenarios or code"
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
# qa-run
|
|
15
|
+
|
|
16
|
+
1. Run each scenario as written. 2. Record raw output. 3. pass only when the criterion is met exactly; otherwise fail with the observed value.
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
---
|
|
2
|
+
role: verify-tool
|
|
3
|
+
default_binding: "claude-haiku-5-5"
|
|
4
|
+
summary: "Runs the declared gates and scenarios, attaches raw tool output, summarises failures so the PL can act."
|
|
5
|
+
may:
|
|
6
|
+
- "run gates from gates.yaml and scenarios from the plan's test checklist"
|
|
7
|
+
- "write .loctx/reports/ with raw output (R46)"
|
|
8
|
+
- "summarise a failure in a few lines for the PL (R51)"
|
|
9
|
+
must_not:
|
|
10
|
+
- "edit code"
|
|
11
|
+
- "report a failure as a pass, or summarise away a failure"
|
|
12
|
+
- "claim a run that did not happen; mark a scenario passed without running it"
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
# verify-tool
|
|
16
|
+
|
|
17
|
+
1. Run the gates with `reins gate --ticket <id>` — the declared order, stopping at the first failure (`--all` when asked). Never run a gate through a pipe or a chain; never trim its output (C5).
|
|
18
|
+
2. Evidence is the report file it writes: `.loctx/reports/<ticket>_<gate>.log` (`$ cmd`, raw output, `exit N`). Then one summary per failing gate: signature line, file:line, matching knowledge id if `reins recall` finds one.
|
|
19
|
+
3. Hand back (bus response `<ticket>_<nn>.response.yaml`) with verdict pass|fail, `evidence:` the report path(s), may_proceed. Then run `reins check --stage verdict --ticket <id>` (T3): a pass without raw evidence is D5, a non-zero exit or a massaged gate is D4.
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{ "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "reins/bus/request@1", "type": "object",
|
|
2
|
+
"required": ["schema", "id", "from", "to", "ticket", "intent", "kind", "changes", "why", "revert"],
|
|
3
|
+
"properties": {
|
|
4
|
+
"schema": { "const": "reins/bus/request@1" },
|
|
5
|
+
"id": { "type": "string" }, "from": { "type": "string" }, "to": { "type": "string" },
|
|
6
|
+
"ticket": { "type": "string" }, "intent": { "type": "string" },
|
|
7
|
+
"kind": { "enum": ["review", "verify", "implement", "question", "stop-report"] },
|
|
8
|
+
"changes": { "type": "array", "items": { "type": "object", "required": ["path", "what"] } },
|
|
9
|
+
"why": { "type": "string" },
|
|
10
|
+
"tried": { "type": "array", "items": { "type": "string" } },
|
|
11
|
+
"not_tried": { "type": "array", "items": { "type": "string" } },
|
|
12
|
+
"deadline": { "type": ["string", "null"] },
|
|
13
|
+
"revert": { "type": "string" },
|
|
14
|
+
"errors": { "type": "string" },
|
|
15
|
+
"budget_left": { "type": "object" },
|
|
16
|
+
"notes": { "type": "string" }
|
|
17
|
+
}, "additionalProperties": false }
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{ "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "reins/bus/response@1", "type": "object",
|
|
2
|
+
"required": ["schema", "request", "from", "verdict", "grounds", "may_proceed"],
|
|
3
|
+
"properties": {
|
|
4
|
+
"schema": { "const": "reins/bus/response@1" },
|
|
5
|
+
"request": { "type": "string" }, "from": { "type": "string" },
|
|
6
|
+
"verdict": { "enum": ["approve", "fix-required", "reject", "cannot-judge", "pass", "fail"] },
|
|
7
|
+
"grounds": { "type": "string" },
|
|
8
|
+
"fixes": { "type": "array", "items": { "type": "object", "required": ["path", "what"] } },
|
|
9
|
+
"may_proceed": { "type": "boolean" },
|
|
10
|
+
"major_issues": { "type": "array", "items": { "type": "string" } },
|
|
11
|
+
"evidence": { "type": "string" },
|
|
12
|
+
"suggested_next": { "type": "string" },
|
|
13
|
+
"notes": { "type": "string" }
|
|
14
|
+
}, "additionalProperties": false }
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{ "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "reins/intent@1", "type": "object",
|
|
2
|
+
"required": ["id", "slug", "version", "status", "origin", "approvals"],
|
|
3
|
+
"properties": {
|
|
4
|
+
"id": { "type": "string", "pattern": "^[0-9]{3}$" },
|
|
5
|
+
"slug": { "type": "string", "pattern": "^[a-z0-9]+(-[a-z0-9]+)*$" },
|
|
6
|
+
"version": { "type": "string" },
|
|
7
|
+
"status": { "enum": ["draft", "approved", "superseded"] },
|
|
8
|
+
"origin": { "enum": ["user", "agent", "incident"] },
|
|
9
|
+
"approvals": { "$ref": "#/$defs/approvals" },
|
|
10
|
+
"supersedes": { "type": ["string", "null"] }
|
|
11
|
+
},
|
|
12
|
+
"$defs": { "approvals": { "type": "array", "items": { "type": "object", "required": ["role", "at"],
|
|
13
|
+
"properties": { "role": { "type": "string" }, "at": { "type": "string" }, "kind": { "type": "string" } } } } } }
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{ "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "reins/knowledge@1", "type": "object",
|
|
2
|
+
"required": ["id", "kind", "status", "topics", "decisions", "applies_to", "source"],
|
|
3
|
+
"properties": {
|
|
4
|
+
"id": { "type": "string" },
|
|
5
|
+
"kind": { "enum": ["decision", "failure"] },
|
|
6
|
+
"status": { "enum": ["active", "superseded"] },
|
|
7
|
+
"supersedes": { "type": ["string", "null"] },
|
|
8
|
+
"topics": { "type": "array", "items": { "type": "string" } },
|
|
9
|
+
"decisions": { "type": "array", "items": { "type": "string" } },
|
|
10
|
+
"symptoms": { "type": "array", "items": { "type": "string" } },
|
|
11
|
+
"applies_to": { "oneOf": [{ "const": "all" }, { "type": "array", "items": { "type": "string" } }] },
|
|
12
|
+
"source": { "type": "string" },
|
|
13
|
+
"approved": { "type": "object", "properties": { "by": { "type": "string" }, "at": { "type": "string" } } },
|
|
14
|
+
"symptom": { "type": "string" }, "cause": { "type": "string" }, "fix": { "type": "string" },
|
|
15
|
+
"check": { "type": "string" }, "verified": { "type": "integer", "minimum": 0 }
|
|
16
|
+
} }
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{ "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "reins/plan@1", "type": "object",
|
|
2
|
+
"required": ["intent", "status", "agents"],
|
|
3
|
+
"properties": {
|
|
4
|
+
"intent": { "type": "string", "pattern": "^[0-9]{3}$" },
|
|
5
|
+
"status": { "enum": ["draft", "reviewed", "active", "done"] },
|
|
6
|
+
"approvals": { "$ref": "intent@1#/$defs/approvals" },
|
|
7
|
+
"agents": { "type": "object", "additionalProperties": { "type": "array", "items": { "type": "string" } } },
|
|
8
|
+
"budget": { "type": "object", "properties": { "tokens": { "type": "integer", "minimum": 0 } } },
|
|
9
|
+
"tickets": { "type": "array", "items": { "type": "string", "pattern": "^[0-9]{3}-[0-9]+$" } }
|
|
10
|
+
} }
|