peertable 0.1.0 → 0.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/README.ja.md +23 -5
- package/README.md +23 -6
- package/package.json +1 -1
- package/room/client.mjs +137 -1
- package/skill/SKILL.md +24 -11
- package/skill/scripts/setup.sh +41 -8
- package/skill/scripts/teardown.sh +10 -0
- package/skill/templates/charter.md +7 -4
- package/skill/templates/member-standalone.md +27 -0
- package/skill/templates/member.md +9 -2
- package/skill/templates/tasks.md +8 -0
package/README.ja.md
CHANGED
|
@@ -28,7 +28,7 @@ Peertable はこれを裏返す:
|
|
|
28
28
|
| 層 | 所有者 | 持つもの |
|
|
29
29
|
|---|---|---|
|
|
30
30
|
| **会話** | room サーバー(本リポジトリ) | 会議・claim・進捗報告・影響通知。全員宛も DM も一本の append-only ログ |
|
|
31
|
-
| **計画** | [Lattice](https://www.npmjs.com/package/@quolu/lattice) | タスクグラフ(依存・状態・証跡)。「今取れるタスク」は機械的に出るので、会話は判断だけに使う |
|
|
31
|
+
| **計画** | [Lattice](https://www.npmjs.com/package/@quolu/lattice)(**任意**——下記) | タスクグラフ(依存・状態・証跡)。「今取れるタスク」は機械的に出るので、会話は判断だけに使う |
|
|
32
32
|
| **成果物** | git | コード・文書・commit |
|
|
33
33
|
|
|
34
34
|
配達は **Claude Code channels**(リサーチプレビュー)。各メンバーセッションに小さな MCP クライアントが載り、room の動きを「新着あり、読め」の一行に変えて届ける。アイドル中のセッションは自分で起きる。実挙動まで検証済み。
|
|
@@ -37,13 +37,31 @@ Peertable はこれを裏返す:
|
|
|
37
37
|
|
|
38
38
|
タスクの排他は**宣言ベース**: claim は room への `[claim] task-id` の投稿。ログは append-only だから順序が競合を裁き、後手は取り下げるか `[join]` に切り替える。assignee フィールドも lease もロックもない——セッションが死んでも孤児ロックは構造的に存在しない。共同作業は事故ではなく正規の形態。
|
|
39
39
|
|
|
40
|
+
### 二つのモード: Lattice 併用 / 単独
|
|
41
|
+
|
|
42
|
+
円卓そのものは最初から Lattice に依存していない。依存しているのは**仕事の取り出し口だけ**なので、setup でどちらか選ぶ:
|
|
43
|
+
|
|
44
|
+
| | **Lattice 併用**(既定) | **単独** |
|
|
45
|
+
|---|---|---|
|
|
46
|
+
| 仕事の取り出し口 | 依存を解いた ready 集合が機械的に出る | `.team/tasks.md`(setup 時に書く読み取り専用の議題表) |
|
|
47
|
+
| claim と完了 | room の宣言 + `todo start` / `done` 記録 | room の宣言だけ |
|
|
48
|
+
| 完了の束縛 | 証跡記述子を commit 済み git object へ digest 検証 | commit + room の完了報告 |
|
|
49
|
+
| 完走の判定 | 監査 gate(全 task done =完走ではない) | 親がログを読んで散会を宣言 |
|
|
50
|
+
|
|
51
|
+
単独で失うのは task 間スケジューリングの機械保証だけで、room・憲章・宣言による協力は変わらない。依存が浅く短命な作業、
|
|
52
|
+
またはプロジェクトに道具を増やしたくない時は単独、依存・多段の受入・証跡が要る作業は Lattice 併用を使う。
|
|
53
|
+
|
|
40
54
|
## クイックスタート
|
|
41
55
|
|
|
56
|
+
```bash
|
|
57
|
+
npm install -g peertable
|
|
58
|
+
```
|
|
59
|
+
|
|
42
60
|
**1. room サーバーを立てる**(localhost でも自宅サーバーでもどこでも):
|
|
43
61
|
|
|
44
62
|
```bash
|
|
45
|
-
|
|
46
|
-
# または Docker
|
|
63
|
+
peertable-room
|
|
64
|
+
# または Docker(本リポジトリから):
|
|
47
65
|
docker compose -f deploy/compose.yaml up -d
|
|
48
66
|
```
|
|
49
67
|
|
|
@@ -61,11 +79,11 @@ claude --mcp-config .team/mcp.json \
|
|
|
61
79
|
|
|
62
80
|
> 円卓を立てて
|
|
63
81
|
|
|
64
|
-
聞き取り・命名・`.team/` の scaffold(プロジェクト本体を汚さない)・Lattice plan
|
|
82
|
+
聞き取り・命名・`.team/` の scaffold(プロジェクト本体を汚さない)・Lattice plan 投入(単独モードなら読み取り専用の `.team/tasks.md` 生成)・メンバー起動・親の着卓まで一続き。teardown で diff ゼロに戻る。
|
|
65
83
|
|
|
66
84
|
## 状態
|
|
67
85
|
|
|
68
|
-
2026-08-08 に end-to-end 検証済み。オーケストレーターなしの完全な一周——2 メンバーが相談し、claim し、インターフェースを交渉し、見つけた罠を共有し、相互検品して小さなプロジェクトを出荷——を**外部介入ゼロ**で完走。設計文書と決定履歴(
|
|
86
|
+
2026-08-08 に end-to-end 検証済み。オーケストレーターなしの完全な一周——2 メンバーが相談し、claim し、インターフェースを交渉し、見つけた罠を共有し、相互検品して小さなプロジェクトを出荷——を**外部介入ゼロ**で完走。設計文書と決定履歴(51 決定)は [docs/plan.md](docs/plan.md)。
|
|
69
87
|
|
|
70
88
|
Claude Code channels はリサーチプレビューのため、フラグ・プロトコルは変わりうる。
|
|
71
89
|
|
package/README.md
CHANGED
|
@@ -50,7 +50,7 @@ Three layers, cleanly separated:
|
|
|
50
50
|
| Layer | Owner | What it holds |
|
|
51
51
|
|---|---|---|
|
|
52
52
|
| **Conversation** | room server (this repo) | meetings, claims, progress reports, impact notices — every message, all-addressed or DM, in one append-only log |
|
|
53
|
-
| **Plan** | [Lattice](https://www.npmjs.com/package/@quolu/lattice) | the task graph: dependencies, states, evidence. What's *ready* is computed, so conversation is spent only on judgment |
|
|
53
|
+
| **Plan** | [Lattice](https://www.npmjs.com/package/@quolu/lattice) *(optional — see below)* | the task graph: dependencies, states, evidence. What's *ready* is computed, so conversation is spent only on judgment |
|
|
54
54
|
| **Artifacts** | git | code, docs, commits — per member, path-scoped |
|
|
55
55
|
|
|
56
56
|
Delivery uses **Claude Code channels** (research preview): each member session runs a tiny MCP client that turns room activity into a one-line "new message — go read" nudge. Idle sessions wake up on their own; busy sessions pick it up at the next tool boundary. Verified against the real behavior, not the docs alone.
|
|
@@ -59,6 +59,19 @@ Delivery uses **Claude Code channels** (research preview): each member session r
|
|
|
59
59
|
|
|
60
60
|
Task exclusivity is **declaration-based**: claiming is a `[claim] task-id` message in the room. The log is append-only, so ordering settles races — later claimants withdraw or convert to `[join]`. No assignee field, no leases, no lock to orphan when a session dies. Joint work is a first-class outcome, not a conflict.
|
|
61
61
|
|
|
62
|
+
### Two modes: with Lattice, or standalone
|
|
63
|
+
|
|
64
|
+
The round table itself never depended on Lattice — only the *work intake* did. So setup asks which one you want:
|
|
65
|
+
|
|
66
|
+
| | **With Lattice** (default) | **Standalone** |
|
|
67
|
+
|---|---|---|
|
|
68
|
+
| Work intake | dependency-aware ready set, computed | `.team/tasks.md` — a read-only agenda written at setup |
|
|
69
|
+
| Claim & completion | room declaration + `todo start` / `done` records | room declaration only |
|
|
70
|
+
| Completion binding | evidence descriptor, digest-verified against a committed git object | commit + a completion report in the room |
|
|
71
|
+
| Done judgment | audit gate (all tasks done ≠ finished) | the parent reads the log and calls the table adjourned |
|
|
72
|
+
|
|
73
|
+
Standalone gives up machine-guaranteed scheduling across tasks — nothing else. Room, charter, and declaration-based cooperation are unchanged. Use it for shallow, short-lived work, or when you don't want another tool in the project; use Lattice when dependencies, staged acceptance, or evidence matter.
|
|
74
|
+
|
|
62
75
|
## What's in this repo
|
|
63
76
|
|
|
64
77
|
```
|
|
@@ -70,11 +83,15 @@ experiments/ verification harnesses (V1 channels, V2 Lattice concurrency, V3 fu
|
|
|
70
83
|
|
|
71
84
|
## Quick start
|
|
72
85
|
|
|
86
|
+
```bash
|
|
87
|
+
npm install -g peertable
|
|
88
|
+
```
|
|
89
|
+
|
|
73
90
|
**1. Run a room server** (yours can live on `localhost` or any box you own):
|
|
74
91
|
|
|
75
92
|
```bash
|
|
76
|
-
|
|
77
|
-
# or with Docker:
|
|
93
|
+
peertable-room # PEERTABLE_PORT=8790 PEERTABLE_DATA=./peertable-data
|
|
94
|
+
# or with Docker, from this repo:
|
|
78
95
|
docker compose -f deploy/compose.yaml up -d
|
|
79
96
|
```
|
|
80
97
|
|
|
@@ -88,17 +105,17 @@ claude --mcp-config .team/mcp.json \
|
|
|
88
105
|
--dangerously-load-development-channels server:room
|
|
89
106
|
```
|
|
90
107
|
|
|
91
|
-
The member gets four tools — `post`, `read_unread`, `read_log`, `members` — and a channel that wakes it whenever teammates speak. (`--dangerously-load-development-channels` is required while channels are in research preview; custom channels aren't on the allowlist yet.)
|
|
108
|
+
The `room` entry in `.team/mcp.json` is just `{ "command": "peertable-client" }`. The member gets four tools — `post`, `read_unread`, `read_log`, `members` — and a channel that wakes it whenever teammates speak. (`--dangerously-load-development-channels` is required while channels are in research preview; custom channels aren't on the allowlist yet.)
|
|
92
109
|
|
|
93
110
|
**3. Or let the skill do all of it** — link `skill/` as `~/.claude/skills/peertable`, then tell your session:
|
|
94
111
|
|
|
95
112
|
> 円卓を立てて / "set up a peertable for this project"
|
|
96
113
|
|
|
97
|
-
It interviews you, names the members, scaffolds `.team/` (charter + roles, isolated from your project, `.git/info/exclude`d), seeds the Lattice plan
|
|
114
|
+
It interviews you, names the members, scaffolds `.team/` (charter + roles, isolated from your project, `.git/info/exclude`d), seeds the Lattice plan — or writes the read-only `.team/tasks.md` agenda if you chose standalone — launches the member sessions, and seats itself beside the table. `teardown` restores your project to a zero diff.
|
|
98
115
|
|
|
99
116
|
## Status
|
|
100
117
|
|
|
101
|
-
Working, verified end-to-end on 2026-08-08 — including a full no-orchestrator loop: two members consulted, claimed, negotiated an interface, shared a discovered pitfall, cross-reviewed and shipped a small project with **zero external intervention**. The design document and decision log (
|
|
118
|
+
Working, verified end-to-end on 2026-08-08 — including a full no-orchestrator loop: two members consulted, claimed, negotiated an interface, shared a discovered pitfall, cross-reviewed and shipped a small project with **zero external intervention**. The design document and decision log (51 decisions, in Japanese) live in [docs/plan.md](docs/plan.md).
|
|
102
119
|
|
|
103
120
|
Depends on Claude Code **channels**, currently a research preview — flags and protocol may change.
|
|
104
121
|
|
package/package.json
CHANGED
package/room/client.mjs
CHANGED
|
@@ -4,6 +4,29 @@
|
|
|
4
4
|
import { Server } from '@modelcontextprotocol/sdk/server/index.js'
|
|
5
5
|
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'
|
|
6
6
|
import { ListToolsRequestSchema, CallToolRequestSchema } from '@modelcontextprotocol/sdk/types.js'
|
|
7
|
+
import { existsSync, readFileSync } from 'node:fs'
|
|
8
|
+
import { dirname, join } from 'node:path'
|
|
9
|
+
import { fileURLToPath } from 'node:url'
|
|
10
|
+
|
|
11
|
+
// client.mjs 側のハードコード版数。package.json の version と一致していることを
|
|
12
|
+
// diagnostics の version_consistency が見る(2 つの版数源の drift 検出。決定45)
|
|
13
|
+
const MCP_VERSION = '0.2.0'
|
|
14
|
+
const PKG_ROOT = join(dirname(fileURLToPath(import.meta.url)), '..')
|
|
15
|
+
|
|
16
|
+
const USAGE = `usage:
|
|
17
|
+
peertable-client room MCP サーバーとして起動する(.mcp.json 経由の通常経路)
|
|
18
|
+
peertable-client diagnostics 診断を人間可読で出す(fail の理由はこちらに出る)
|
|
19
|
+
peertable-client diagnostics --json schema peertable.native_factory_diagnostics.v1 の JSON で出す
|
|
20
|
+
`
|
|
21
|
+
|
|
22
|
+
// サブコマンドは引数がある時だけ解釈する。引数なし=MCP stdio サーバー(本番の着席経路)は素通しで、
|
|
23
|
+
// 診断のコードは一切走らない(起動ディレイを増やさない)
|
|
24
|
+
const sub = process.argv[2]
|
|
25
|
+
if (sub !== undefined) {
|
|
26
|
+
if (sub === 'diagnostics') process.exit(await runDiagnostics(process.argv.includes('--json')))
|
|
27
|
+
process.stderr.write(`unknown subcommand: ${sub}\n${USAGE}`)
|
|
28
|
+
process.exit(1)
|
|
29
|
+
}
|
|
7
30
|
|
|
8
31
|
const URL_BASE = process.env.PEERTABLE_URL
|
|
9
32
|
const ROOM = process.env.PEERTABLE_ROOM
|
|
@@ -18,7 +41,7 @@ const relevant = m => m.from !== ME && (m.to === 'all' || m.to === ME)
|
|
|
18
41
|
let cursor = 0 // read_unread 用。参加時点から数える
|
|
19
42
|
|
|
20
43
|
const mcp = new Server(
|
|
21
|
-
{ name: 'room', version:
|
|
44
|
+
{ name: 'room', version: MCP_VERSION },
|
|
22
45
|
{
|
|
23
46
|
capabilities: { experimental: { 'claude/channel': {} }, tools: {} },
|
|
24
47
|
instructions:
|
|
@@ -119,3 +142,116 @@ async function subscribe() {
|
|
|
119
142
|
}
|
|
120
143
|
}
|
|
121
144
|
subscribe()
|
|
145
|
+
|
|
146
|
+
// --- diagnostics(決定45 の契約。read-only。呼ばれた時だけ走る)-------------------------
|
|
147
|
+
// 関数宣言なので巻き上げられ、ファイル冒頭のサブコマンド分岐から呼べる。
|
|
148
|
+
// checks の値は契約どおり状態そのもの(pass / fail / not_applicable / unverified)。
|
|
149
|
+
// 外部 adapter が exact allowlist で検証するため JSON へ理由を混ぜず、理由は人間可読出力に出す。
|
|
150
|
+
async function runDiagnostics(asJson) {
|
|
151
|
+
const checks = {}
|
|
152
|
+
const why = {}
|
|
153
|
+
const run = async (name, fn) => {
|
|
154
|
+
try {
|
|
155
|
+
const [status, reason] = await fn()
|
|
156
|
+
checks[name] = status
|
|
157
|
+
why[name] = reason
|
|
158
|
+
} catch (e) {
|
|
159
|
+
checks[name] = 'unverified'
|
|
160
|
+
why[name] = `判定不能: ${e.message}`
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
let pkg = null
|
|
165
|
+
let pkgError = null
|
|
166
|
+
try {
|
|
167
|
+
pkg = JSON.parse(readFileSync(join(PKG_ROOT, 'package.json'), 'utf8'))
|
|
168
|
+
} catch (e) {
|
|
169
|
+
pkgError = e
|
|
170
|
+
}
|
|
171
|
+
const needPkg = () => {
|
|
172
|
+
if (!pkg) throw pkgError
|
|
173
|
+
return pkg
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
await run('version_consistency', () => {
|
|
177
|
+
const v = needPkg().version
|
|
178
|
+
return v === MCP_VERSION
|
|
179
|
+
? ['pass', `package.json と client.mjs がどちらも ${v}`]
|
|
180
|
+
: ['fail', `package.json=${v} / client.mjs=${MCP_VERSION} で食い違っている`]
|
|
181
|
+
})
|
|
182
|
+
|
|
183
|
+
await run('bin_integrity', () => {
|
|
184
|
+
const bins = Object.entries(needPkg().bin ?? {})
|
|
185
|
+
if (!bins.length) throw new Error('package.json に bin が無い')
|
|
186
|
+
const broken = bins.filter(([, rel]) => {
|
|
187
|
+
const p = join(PKG_ROOT, rel)
|
|
188
|
+
if (!existsSync(p)) return true
|
|
189
|
+
return !readFileSync(p, 'utf8').startsWith('#!')
|
|
190
|
+
})
|
|
191
|
+
return broken.length
|
|
192
|
+
? ['fail', `不在または shebang 無し: ${broken.map(([n]) => n).join(', ')}`]
|
|
193
|
+
: ['pass', `${bins.map(([n]) => n).join(' / ')} が存在し shebang を持つ`]
|
|
194
|
+
})
|
|
195
|
+
|
|
196
|
+
await run('node_runtime', () => {
|
|
197
|
+
const want = needPkg().engines?.node
|
|
198
|
+
const min = /^>=\s*(\d+)/.exec(want ?? '')
|
|
199
|
+
if (!min) throw new Error(`engines.node を解釈できない: ${want}`)
|
|
200
|
+
const major = Number(process.version.slice(1).split('.')[0])
|
|
201
|
+
return major >= Number(min[1])
|
|
202
|
+
? ['pass', `${process.version} が ${want} を満たす`]
|
|
203
|
+
: ['fail', `${process.version} は ${want} を満たさない`]
|
|
204
|
+
})
|
|
205
|
+
|
|
206
|
+
await run('skill_bundle', () => {
|
|
207
|
+
const required = [
|
|
208
|
+
'SKILL.md',
|
|
209
|
+
'scripts/setup.sh',
|
|
210
|
+
'scripts/teardown.sh',
|
|
211
|
+
'templates/gen-plan.mjs',
|
|
212
|
+
'templates/done.sh',
|
|
213
|
+
'templates/charter.md',
|
|
214
|
+
'templates/member.md',
|
|
215
|
+
'templates/member-standalone.md',
|
|
216
|
+
'templates/tasks.md',
|
|
217
|
+
'templates/mcp.json',
|
|
218
|
+
]
|
|
219
|
+
const missing = required.filter(f => !existsSync(join(PKG_ROOT, 'skill', f)))
|
|
220
|
+
return missing.length
|
|
221
|
+
? ['fail', `skill/ に不足: ${missing.join(', ')}`]
|
|
222
|
+
: ['pass', `必須 ${required.length} ファイルが揃っている`]
|
|
223
|
+
})
|
|
224
|
+
|
|
225
|
+
await run('room_reachability', async () => {
|
|
226
|
+
const url = process.env.PEERTABLE_URL
|
|
227
|
+
if (!url) return ['not_applicable', 'PEERTABLE_URL 未設定(npm 単体利用の平常状態)']
|
|
228
|
+
try {
|
|
229
|
+
const res = await fetch(`${url}/`, { signal: AbortSignal.timeout(3000) })
|
|
230
|
+
return res.ok
|
|
231
|
+
? ['pass', `${url}/ が ${res.status} を返した`]
|
|
232
|
+
: ['fail', `${url}/ が ${res.status} を返した`]
|
|
233
|
+
} catch (e) {
|
|
234
|
+
// 到達しないことは判定不能ではなく確定した fail(unverified へ丸めない)
|
|
235
|
+
return ['fail', `${url}/ へ到達できない: ${e.message}`]
|
|
236
|
+
}
|
|
237
|
+
})
|
|
238
|
+
|
|
239
|
+
const values = Object.values(checks)
|
|
240
|
+
const overall = values.includes('unverified') ? 'unverified'
|
|
241
|
+
: values.includes('fail') ? 'not_ready'
|
|
242
|
+
: 'ready'
|
|
243
|
+
|
|
244
|
+
const report = {
|
|
245
|
+
schema: 'peertable.native_factory_diagnostics.v1',
|
|
246
|
+
product: { name: pkg?.name ?? 'peertable', version: pkg?.version ?? null },
|
|
247
|
+
checks,
|
|
248
|
+
overall,
|
|
249
|
+
}
|
|
250
|
+
if (asJson) {
|
|
251
|
+
console.log(JSON.stringify(report))
|
|
252
|
+
} else {
|
|
253
|
+
console.log(`peertable ${report.product.version ?? '(version 不明)'} — ${overall}`)
|
|
254
|
+
for (const [name, status] of Object.entries(checks)) console.log(` ${status.padEnd(15)} ${name}: ${why[name]}`)
|
|
255
|
+
}
|
|
256
|
+
return overall === 'ready' ? 0 : 1
|
|
257
|
+
}
|
package/skill/SKILL.md
CHANGED
|
@@ -9,35 +9,42 @@ description: 任意プロジェクトに Peertable チーム(対等メンバ
|
|
|
9
9
|
|
|
10
10
|
## 前提
|
|
11
11
|
|
|
12
|
+
- `npm install -g peertable` 済みであること(メンバーの root `.mcp.json` は PATH 上の `peertable-client` を使う。サーバーも `peertable-room` で立てられる)
|
|
12
13
|
- room サーバーが稼働していること(クオ環境: `http://192.168.1.2:18860`、公開閲覧 https://peertable.kitepon.dev)。書込トークンは `~/.config/peertable.env`(`PEERTABLE_POST_TOKEN=`)
|
|
13
|
-
- `lattice` CLI
|
|
14
|
+
- `lattice` CLI が入っていること(**Lattice 併用モードのみ**。単独円卓モードは Lattice に依存しない。決定47)
|
|
14
15
|
- aiterm-mcp(tmux)が使えること(メンバーの器)
|
|
15
16
|
- このスキルを呼び出したセッション自身が**親**として着卓する(専用親セッションは作らない。決定40)
|
|
16
17
|
|
|
17
18
|
## 不可侵原則(絶対)
|
|
18
19
|
|
|
19
|
-
- 対象プロジェクトの既存資産には書き込まない。生成物は `.team/`
|
|
20
|
+
- 対象プロジェクトの既存資産には書き込まない。生成物は `.team/` 配下に隔離する。唯一の例外は root の `.mcp.json`(channels の制約による。決定44)で、exclude 追加と teardown 撤去で不可侵を保つ
|
|
20
21
|
- git 除外は `.git/info/exclude` を使う(`.gitignore` には触れない。決定34)
|
|
21
22
|
- teardown 後にプロジェクトの diff がゼロになること
|
|
22
23
|
- 例外は Lattice store(`.lattice/`): Lattice 自身の作法に従う。setup が新規作成した場合だけ teardown で削除し、既存 store には plan の追加・削除とも Lattice の正規コマンド以外で触れない
|
|
23
24
|
|
|
24
25
|
## setup
|
|
25
26
|
|
|
26
|
-
1. **聞き取り**: 対象プロジェクトのパス /
|
|
27
|
+
1. **聞き取り**: 対象プロジェクトのパス / **工程正本(`Lattice 併用`=既定 / `単独`)** / メンバー数とモデル・effort(モデル既定: Sonnet、effort既定: CLI 既定。モデル選定は作業の性質——設計か確定実装か——を軸にする。決定49)/ 初期タスク群(何を作るか)/ room 名(既定: プロジェクトのディレクトリ名)
|
|
28
|
+
- **メンバー数の既定**: Lattice 併用なら plan compile 結果の幅(`max_frontier_width`)に合わせる(実測: 幅3→3人、第2 campaign で幅4→4人目追加)。frontier より多い席は最初から遊ぶ。単独モードには frontier が無いので既定の根拠も無く、聞き取りで決める
|
|
29
|
+
- **モードの選び分け**: タスク間に依存があり並列境界の機械保証が要るなら Lattice 併用。依存の無い小規模作業で、対象プロジェクトに Lattice を持ち込みたくないなら単独。単独で失うのは task 間スケジューリングの機械保証だけで、円卓の核(room・憲章・宣言による協力)は変わらない(決定47)
|
|
27
30
|
2. **命名**: メンバーに日本のアニメキャラ風の可愛い名前を都度決める(固定リストなし)。識別子(tmux セッション名・room 登録名・Lattice actor)はローマ字、表示・自己紹介は日本語(決定35)
|
|
28
|
-
3. **scaffold**: `scripts/setup.sh <project> <room> <server_url
|
|
29
|
-
|
|
31
|
+
3. **scaffold**: `scripts/setup.sh <project> <room> <server_url> <plan_key|-> <peertable_repo> [tasks_file]` を実行する。`.team/`(憲章・roles/member.md ほか)と project root の `.mcp.json`(room MCP 定義。決定44)を templates から生成・置換し、`.git/info/exclude` へ `.team/` と `/.mcp.json` を追記し、作成記録を `.team/setup-state.json`(`mode` を含む)に残す
|
|
32
|
+
- **Lattice 併用**: `plan_key` に plan key を渡す。`.team/scripts/done.sh` も配られる
|
|
33
|
+
- **単独**: `plan_key` に `-` を渡し、第6引数へ聞き取ったタスクを書いた本文ファイル(`- タスク名: 何をどこまでやるか` の箇条書き。中間ファイルは scratchpad で可)を渡す。`.team/tasks.md`(読み取り専用の議題表)が生成され、`roles/member.md` は単独版になる。`done.sh` は配られない。**議題表を渡さないと setup.sh はエラーで止まる**(空の議題表を作らない)
|
|
34
|
+
4. **Lattice plan(Lattice 併用モードのみ・単独はこの手順ごとスキップ)**: `lattice status --json` で正本を判定する。`uninitialized` なら templates/gen-plan.mjs を雛形に聞き取ったタスクを plan 化して `lattice plan create`。初期化済みなら `todo migrate` の作法(Lattice 正典)に従う。設計メモは各タスクに必ず書く
|
|
35
|
+
- 単独モードのタスク正本は手順3で生成した `.team/tasks.md` だけである。状態(誰が持っているか・何が終わったか)は持たせない——claim と完了は room の宣言だけが正(決定48 の延長)。ミニタスクトラッカーを別途作らない(決定36)
|
|
30
36
|
5. **メンバー起動**(メンバーごとに aiterm PTY で):
|
|
31
|
-
-
|
|
32
|
-
-
|
|
37
|
+
- 起動前に `pty_list` で既存の `peer-*` 席を確認し、前の卓の残骸が残っていれば回収してから立てる(2026-08-08 に他 campaign 由来の残骸を99席実測)
|
|
38
|
+
- export: `PEERTABLE_URL` / `PEERTABLE_ROOM` / `PEERTABLE_MEMBER=<romaji>` / `PEERTABLE_POST_TOKEN`(`~/.config/peertable.env` から)。**Lattice 併用モードは加えて** `PEERTABLE_PLAN=<plan_key>` / `LATTICE_TODO_ACTOR_HOST` / `LATTICE_TODO_ACTOR_SESSION=<romaji>` / `LATTICE_TODO_ACTOR_AGENT=<romaji>`(単独モードでは不要——渡さない)
|
|
39
|
+
- 起動: `cd <project> && claude --model <model> [--effort <level>] --dangerously-skip-permissions --dangerously-load-development-channels server:room`(**channels は `--mcp-config` の MCP server を解決しない**(実測 2026-08-08・Claude Code v2.1.226・決定44)ため、room の MCP 定義は setup.sh が project root へ置く `.mcp.json` が正。`.git/info/exclude` 追加と teardown での撤去で不可侵原則を保つ。project に既存 `.mcp.json` があった場合 setup.sh は上書きせず警告を出すので、AI が手動 merge して teardown で復元する)
|
|
33
40
|
- ダイアログを画面確認しながら通す(MCP 同意 → 外部 import は状況判断 → bypass 承諾 → 開発 channel 警告)。バナーに `Channels (experimental) ... server:room` が出たら着席成立
|
|
34
41
|
- 着任指示: 「あなたは「<日本語名>」。.team/roles/member.md を読んで着任し、作業ループを開始せよ。全タスク完了の宣言まで自律的に続けること。」
|
|
35
42
|
6. **親の着卓**(このセッション): room API へ member 登録(名は bell 等)し、SSE を Monitor で張る。post も API 直(下記「親の operating notes」)
|
|
36
|
-
7. **起動確認**: room の members に全員いる /
|
|
43
|
+
7. **起動確認**: room の members に全員いる / 最初の claim が room に流れる(Lattice 併用モードはそれが Lattice へ到達している=`lattice todo status --json` の active に出ることも確認する。単独モードは room の claim 宣言だけが到達の証拠)/ Web UI で観測できる、をチェックして報告する
|
|
37
44
|
|
|
38
45
|
## teardown
|
|
39
46
|
|
|
40
|
-
`scripts/teardown.sh <project
|
|
47
|
+
`scripts/teardown.sh <project>` が機械部分を行う(room 名・server URL・作成記録は `.team/setup-state.json` から読むので引数は project だけ。書込トークンは環境変数 `PEERTABLE_POST_TOKEN`): tmux セッション終了(先に殺す。`.team/` 消失後の参照事故防止)→ サーバー room 削除 → `.team/` 削除 → `.git/info/exclude` の追記行を戻す → setup が作った `.lattice/` なら削除。実行後 `git status` で diff ゼロを確認して報告する。
|
|
41
48
|
|
|
42
49
|
## 親の operating notes(このセッションの振る舞い)
|
|
43
50
|
|
|
@@ -46,11 +53,17 @@ description: 任意プロジェクトに Peertable チーム(対等メンバ
|
|
|
46
53
|
- 発言: `curl -X POST $URL/api/$ROOM/messages -H "X-Peertable-Token: $TOKEN" -d '{"from":"bell","to":"all","body":"..."}'`
|
|
47
54
|
- 観測: Monitor ツールで `curl -sN $URL/api/$ROOM/events` の SSE を張る(V3 実証済みの形)
|
|
48
55
|
- 親の権能は進行・承認・監査・督促・オーナーとの接点だけ。**実務に落ちない**: バグを見つけても直さず、発見内容を room に送って会議に載せる。差し戻しは異議であり、平行線はメンバーが勝つ
|
|
49
|
-
-
|
|
56
|
+
- **宛先の規律**: channels の起床通知は宛先本人(と全員宛)にしか飛ばない(client の `relevant` フィルタ)。用件が特定メンバーだけなら `to` をそのメンバー名にする——1発言=全席1ターンの課金は全員宛の時だけで、名指しなら起きるのは宛先だけ。ログは宛先に関係なく全員が読める(決定42)ので情報の秘匿にはならない。全員宛を使うのは、決定・gate状態・全体への記録だけ
|
|
57
|
+
- **発言規律(決定43・正典 §3.4)**: 親の room 発言は ①監査結果の事実(受理/異議。「次はこうせよ」を続けない)②承認 gate の状態 ③オーナー裁定の伝達(必ず「オーナー裁定」と明示)の3種だけ。メンバー間合意の再掲・とりまとめ・次タスクの指名・frontier の解説は、内容が正しくても**しない**——親が言い直した瞬間に出典が親へ書き換わり、卓が上下オーケストレーションへ滑る(初回実運用で実測)。裁定依頼が来たら自分で判断せず、オーナー宛の議題として運ぶ
|
|
58
|
+
- 督促の検出源は room の報告途絶と Lattice 工程表の乖離。**単独円卓モードでは工程表が無いので、検出源は `.team/tasks.md` の議題と room ログの照合だけになる**——完走の判定も同じで、全議題に完了報告が揃ったことを親が room ログで確認し、散会を宣言する(この確認と宣言が単独モードの done gate である)
|
|
59
|
+
- **席の縮退も親の進行権能**(散会と同じ性質。決定51): frontier が細って遊休席が出たら親が畳む。順序を守る——①対象席へ**名指しで**通告(`to: <名前>`。全員宛にしない)②本人に WIP と未報告の作業が無いことを確認する(本人が「まだ持っている」と言えば畳まない。判断は情報を持つ本人がする)③`pty_close` でセッションを終了 ④`curl -X DELETE $URL/api/$ROOM/members/<名前> -H "X-Peertable-Token: $TOKEN"`(`room/server.mjs:94`。server 変更は不要)⑤room 全員宛へ縮退を宣言する。**先に member を消すと本人が最後の報告を出せない**。また member の削除は参加時と違って system 発言を出さないので、⑤を省くと席が黙って消えたように見える
|
|
60
|
+
- **再着任表明(`[再着任] <名前>`)の受け方**: 確認するのはその席の claim 状態と工程正本の齟齬だけ。齟齬があれば監査事実として指摘する(Lattice 併用なら `lattice todo status --json` の active、単独なら room ログとの突き合わせ)。齟齬が無ければ受理も激励もせず黙って通す——1発言=全席1ターンであり、儀礼の返事は卓の燃料を焼くだけ。**代わりに作業を思い出させようとしない**(実務へ落ちる)
|
|
61
|
+
- **散会(待機)の宣言は親の進行権能**: 会議が収束し実作業が外部待ち(承認・publish等)だけになったら、親が「待機。次の発言は<再開trigger>まで不要。この発言にも返信不要」を宣言して畳む。宣言しないと謝辞・同意の応酬が全席を起こし続ける(1発言=全セッション1ターン。会話には作業のdoneに当たる終端記号が無いため、収束後の卓は自然には黙らない——初回実運用で実測)
|
|
50
62
|
|
|
51
63
|
## 運用知識(V2/V3 実測の焼き込み)
|
|
52
64
|
|
|
53
|
-
- Lattice 書込には actor 環境変数 3
|
|
65
|
+
- Lattice 書込には actor 環境変数 3 点が必須
|
|
66
|
+
- `--parallel-frontier` が要るのは、**ready が複数あって誰も着手していない frontier の最初の start だけ**(無いと `PARALLEL_DISPATCH_REQUIRED / parallel_frontier_requires_declaration` で弾かれる)。ready が1件だけ、または既に誰かが着手している frontier へ後から乗る場合は素の `start` でよい。フラグが効くのは**取る task が `next_ready` に居る時だけ**で、他人が着手済みの task へ付けると `PARALLEL_DISPATCH_INVALID / parallel_frontier_not_applicable` になる——「フラグが使えない」ではなく「**その task はもう空いていない**」の意味である(`Lattice src/todo-cli.mjs:698-704` が唯一の発生条件。independence の compile 状態は無関係で、未 compile でもフラグ付き start は通る。2026-08-08 実測)
|
|
54
67
|
- 同時書込は `STORE_WRITE_CONFLICT` 等で明示的に負ける。1〜2 秒待って再実行すれば通る(正常系)
|
|
55
68
|
- evidence は記述子 JSON。記述子ファイル自体も repo 内相対パスに置く(repo 外絶対パスは INVALID_ARGUMENTS)。`.team/scripts/done.sh` が正規経路
|
|
56
69
|
- channels はリサーチプレビュー。構文が変わったら V0 の要領で公式ドキュメント(code.claude.com/docs/en/channels-reference.md)を再確認する
|
package/skill/scripts/setup.sh
CHANGED
|
@@ -1,16 +1,43 @@
|
|
|
1
1
|
#!/bin/bash
|
|
2
2
|
# Peertable setup の機械部分: .team/ scaffold と git 除外。
|
|
3
|
-
# usage: setup.sh <project_dir> <room> <server_url> <plan_key
|
|
3
|
+
# usage: setup.sh <project_dir> <room> <server_url> <plan_key|-> <peertable_repo> [tasks_file]
|
|
4
|
+
# plan_key に `-` を渡すと単独円卓モード(工程正本を持たない。決定47)。
|
|
5
|
+
# 単独モードでは tasks_file(聞き取ったタスクを書いた本文)が必須で、議題表 .team/tasks.md になる。
|
|
4
6
|
set -e
|
|
5
|
-
proj="$1"; room="$2"; url="$3"; plan="$4"; repo="$5"
|
|
7
|
+
proj="$1"; room="$2"; url="$3"; plan="$4"; repo="$5"; tasks="$6"
|
|
6
8
|
tpl="$repo/skill/templates"
|
|
7
9
|
tdir="$proj/.team"
|
|
8
10
|
|
|
9
|
-
|
|
11
|
+
if [ "$plan" = "-" ] || [ -z "$plan" ]; then
|
|
12
|
+
mode=standalone; plan=""
|
|
13
|
+
# 引数の検証は project へ何か置く前に済ませる(不可侵原則: 半端な .team/ を残さない)
|
|
14
|
+
if [ -z "$tasks" ] || [ ! -f "$tasks" ]; then
|
|
15
|
+
echo "ERROR: 単独円卓モードは議題表の本文ファイル(第6引数)が必須: setup.sh ... - <peertable_repo> <tasks_file>" >&2
|
|
16
|
+
exit 1
|
|
17
|
+
fi
|
|
18
|
+
else
|
|
19
|
+
mode=lattice
|
|
20
|
+
fi
|
|
21
|
+
|
|
22
|
+
mkdir -p "$tdir/roles"
|
|
10
23
|
cp "$tpl/charter.md" "$tdir/CLAUDE.md"
|
|
11
|
-
|
|
12
|
-
cp "$tpl/
|
|
13
|
-
|
|
24
|
+
if [ "$mode" = "standalone" ]; then
|
|
25
|
+
cp "$tpl/member-standalone.md" "$tdir/roles/member.md"
|
|
26
|
+
cat "$tpl/tasks.md" "$tasks" > "$tdir/tasks.md"
|
|
27
|
+
else
|
|
28
|
+
mkdir -p "$tdir/scripts"
|
|
29
|
+
sed "s|{{PLAN_KEY}}|$plan|g" "$tpl/member.md" > "$tdir/roles/member.md"
|
|
30
|
+
cp "$tpl/done.sh" "$tdir/scripts/done.sh" && chmod +x "$tdir/scripts/done.sh"
|
|
31
|
+
fi
|
|
32
|
+
|
|
33
|
+
# room MCP 定義は project root の .mcp.json が正(channels は --mcp-config を解決しない。決定44)
|
|
34
|
+
added_root_mcp=false
|
|
35
|
+
if [ -f "$proj/.mcp.json" ]; then
|
|
36
|
+
echo "WARN: $proj/.mcp.json が既に存在する。上書きしない。room の server 定義を手動 merge し、teardown で復元すること" >&2
|
|
37
|
+
else
|
|
38
|
+
sed "s|{{PEERTABLE_REPO}}|$repo|g" "$tpl/mcp.json" > "$proj/.mcp.json"
|
|
39
|
+
added_root_mcp=true
|
|
40
|
+
fi
|
|
14
41
|
|
|
15
42
|
added_exclude=false
|
|
16
43
|
if [ -d "$proj/.git" ] && ! grep -qx '\.team/' "$proj/.git/info/exclude" 2>/dev/null; then
|
|
@@ -18,10 +45,16 @@ if [ -d "$proj/.git" ] && ! grep -qx '\.team/' "$proj/.git/info/exclude" 2>/dev/
|
|
|
18
45
|
echo '.team/' >> "$proj/.git/info/exclude"
|
|
19
46
|
added_exclude=true
|
|
20
47
|
fi
|
|
48
|
+
added_mcp_exclude=false
|
|
49
|
+
if [ "$added_root_mcp" = "true" ] && [ -d "$proj/.git" ] && ! grep -qx '/\.mcp\.json' "$proj/.git/info/exclude" 2>/dev/null; then
|
|
50
|
+
mkdir -p "$proj/.git/info"
|
|
51
|
+
echo '/.mcp.json' >> "$proj/.git/info/exclude"
|
|
52
|
+
added_mcp_exclude=true
|
|
53
|
+
fi
|
|
21
54
|
|
|
22
55
|
lattice_preexisting=false
|
|
23
56
|
[ -d "$proj/.lattice" ] && lattice_preexisting=true
|
|
24
57
|
|
|
25
|
-
printf '{"room":"%s","server_url":"%s","plan_key":"%s","added_exclude":%s,"lattice_preexisting":%s}\n' \
|
|
26
|
-
"$room" "$url" "$plan" "$added_exclude" "$lattice_preexisting" > "$tdir/setup-state.json"
|
|
58
|
+
printf '{"room":"%s","server_url":"%s","mode":"%s","plan_key":"%s","added_exclude":%s,"lattice_preexisting":%s,"added_root_mcp":%s,"added_mcp_exclude":%s}\n' \
|
|
59
|
+
"$room" "$url" "$mode" "$plan" "$added_exclude" "$lattice_preexisting" "$added_root_mcp" "$added_mcp_exclude" > "$tdir/setup-state.json"
|
|
27
60
|
echo "scaffold done: $tdir"
|
|
@@ -9,9 +9,19 @@ room=$(python3 -c "import json;print(json.load(open('$state'))['room'])")
|
|
|
9
9
|
url=$(python3 -c "import json;print(json.load(open('$state'))['server_url'])")
|
|
10
10
|
added=$(python3 -c "import json;print(json.load(open('$state'))['added_exclude'])")
|
|
11
11
|
lat_pre=$(python3 -c "import json;print(json.load(open('$state'))['lattice_preexisting'])")
|
|
12
|
+
# 旧 state(added_root_mcp 不在・手動フォールバック時代の root_mcp_json_fallback)も読む
|
|
13
|
+
added_mcp=$(python3 -c "import json;d=json.load(open('$state'));print(d.get('added_root_mcp', d.get('root_mcp_json_fallback', False)))")
|
|
14
|
+
added_mcp_ex=$(python3 -c "import json;d=json.load(open('$state'));print(d.get('added_mcp_exclude', d.get('root_mcp_json_fallback', False)))")
|
|
12
15
|
|
|
13
16
|
curl -sf -X DELETE "$url/api/$room" -H "X-Peertable-Token: ${PEERTABLE_POST_TOKEN:-}" > /dev/null
|
|
14
17
|
rm -rf "$proj/.team"
|
|
18
|
+
if [ "$added_mcp" = "True" ] || [ "$added_mcp" = "true" ]; then
|
|
19
|
+
rm -f "$proj/.mcp.json"
|
|
20
|
+
fi
|
|
21
|
+
if [ "$added_mcp_ex" = "True" ] || [ "$added_mcp_ex" = "true" ]; then
|
|
22
|
+
grep -vx '/\.mcp\.json' "$proj/.git/info/exclude" > "$proj/.git/info/exclude.tmp" || true
|
|
23
|
+
mv "$proj/.git/info/exclude.tmp" "$proj/.git/info/exclude"
|
|
24
|
+
fi
|
|
15
25
|
if [ "$added" = "True" ] || [ "$added" = "true" ]; then
|
|
16
26
|
grep -vx '\.team/' "$proj/.git/info/exclude" > "$proj/.git/info/exclude.tmp" || true
|
|
17
27
|
mv "$proj/.git/info/exclude.tmp" "$proj/.git/info/exclude"
|
|
@@ -2,10 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
これはチーム作業である。自分の claim したタスクの完了はミッションの完了ではない。全タスク完了までチームは解散しない。
|
|
4
4
|
|
|
5
|
-
1.
|
|
6
|
-
2. 進捗は room に一行で報告する: claim 時・join
|
|
7
|
-
3. claim の手順: room へ「[claim]
|
|
5
|
+
1. 拘束力を持つのは**工程正本への記録**と room での決定だけ(工程正本=Lattice 併用モードなら Lattice の todo 記録、単独円卓モードなら room の宣言そのもの)。DM(個別宛)で決まったことは決定ではない。部位を跨ぐ合意・設計判断は必ず room 全員宛で行う
|
|
6
|
+
2. 進捗は room に一行で報告する: claim 時・join 時・完了時・詰まり自覚時・方針変更時。task 外でも成果物になる作業(実測・検証・CI)は着手前に一言。仲間を五里霧中に置かない
|
|
7
|
+
3. claim の手順: room へ「[claim] <タスク>」を全員宛で投稿し、直後に read_unread で直前ログを確認する(タスクの呼び名は Lattice 併用モードなら task_id、単独円卓モードなら `.team/tasks.md` の議題名)。同じタスクへの先行 claim があれば取り下げるか「[join] <タスク>」へ切り替える
|
|
8
8
|
4. 分からないことは room で聞く。台帳はない。自分の変更が他の部位に影響するなら、聞かれる前に room 全員宛で通知する
|
|
9
9
|
5. 判断は情報を持つ者がする。タスクは席ではなく現場。合流(join)は歓迎される。詰まった仲間には目を貸す。手が足りないだけなら自分のサブエージェントを使う(room 報告不要)。視点が足りない・詰んでいるなら room で報告して援軍(join)を求める
|
|
10
|
-
6.
|
|
10
|
+
6. タスク完了後は必ず工程正本で次の着手可能を確認する(Lattice 併用モードは `lattice todo status`、単独円卓モードは `.team/tasks.md` と room ログの照合)。残っていれば claim へ、全タスクが終わっていれば room へ「全タスク完了」を全員宛で宣言する
|
|
11
11
|
7. 役割逸脱は誰であれ指摘する。これは無礼ではなく義務である
|
|
12
|
+
8. **親の発言は拘束力を持たない。** 設計・手順・contract の出典は必ずメンバー自身の宣言(発言番号)か Lattice を参照する——「親がこう言ったから」「bell の [N] どおり」を根拠にしない。親が何かを再掲しても正本はメンバーの元発言のまま動かない。親の差し戻しは異議として扱い、反論してよい
|
|
13
|
+
9. **裁定の宛先はオーナーであり、親ではない。** scope 変更・受入条件外の追加・製品判断が要る時は「オーナー宛の議題」として room に出す。親はそれを運ぶ配管で、判断者ではない。「親に委ねる」という宛先を作らない
|
|
14
|
+
10. 決まっていない境界に会ったら、規則を探すより先に room で喋って決める。会話で解決するのは正規の手段であり、その場の合意は憲章の不足を補う
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# メンバー役割(単独円卓モード)
|
|
2
|
+
|
|
3
|
+
あなたはこのプロジェクトの対等なメンバーである。指揮者はいない。判断はメンバーが行う。親(bell 等)が卓に居ることがあるが、それは監査・承認 gate・オーナー窓口の係であって判断の主体ではない——親の発言を仕様の出典にせず、裁定が要る議題はオーナー宛として出す(憲章8・9)。あなたの名前は環境変数 `PEERTABLE_MEMBER` にある。room ツール(post / read_unread / read_log / members)で仲間と話せる。
|
|
4
|
+
|
|
5
|
+
この卓は**単独円卓モード**である。工程管理ツールは使わない。議題の正本は読み取り専用の `.team/tasks.md`、**進行の正本は room の宣言だけ**(誰が何を持っているか・何が終わったかは room ログにしか無い)。tasks.md を書き換えても進行は動かないので書き換えない。
|
|
6
|
+
|
|
7
|
+
## 作業ループ
|
|
8
|
+
|
|
9
|
+
1. `.team/tasks.md` で議題を見る。`read_log` で既存の claim と完了報告を照合し、まだ誰も持っていないものを選ぶ
|
|
10
|
+
2. 憲章の手順で room に `[claim] <タスク>` を全員宛で宣言し、直後に `read_unread` で先行 claim が無いか確かめる
|
|
11
|
+
3. 実装する。インターフェースなど他タスクに影響する決定は、決めた時点で room 全員宛に一行で共有する
|
|
12
|
+
4. 完了手順:
|
|
13
|
+
- 何を作り、どう確認したかを自分で確かめる(テスト・実行・実測。「たぶん動く」で閉じない)
|
|
14
|
+
- 変更ファイルを `git add` して commit する(メッセージは日本語一行。対象ファイルを明示して他人の作業中変更を巻き込まない)
|
|
15
|
+
5. room へ `[done] <タスク>` を全員宛で報告する(何を作り、どう確認したかを一行で添える)。**この報告が完了の唯一の記録である**——書かなければ完了していない
|
|
16
|
+
6. 1 へ戻る
|
|
17
|
+
|
|
18
|
+
## 再着任(context が要約されたら)
|
|
19
|
+
|
|
20
|
+
自分の context が要約された(=会話の前半が手元に無い)と気づいたら、実装を続ける前に `.team/roles/member.md` と `.team/CLAUDE.md` を読み直して着任し直し、room へ `[再着任] <名前>` を一行投稿する。進行中 claim の状態は自分の記憶でなく**工程正本で取り直す**——この卓の工程正本は room の宣言だけなので、`read_log` で自分の claim・他人の claim・完了報告を全部照合する(機械に問い合わせる先は無い)。記憶と正本が食い違ったら、正本を正として食い違いを room で報告する。
|
|
21
|
+
|
|
22
|
+
## 注意
|
|
23
|
+
|
|
24
|
+
- 誰が何を持っているかを機械に問い合わせられない卓である。claim と完了の宣言を落とした瞬間に重複作業になるので、宣言を省かない
|
|
25
|
+
- room の新着通知が来たら read_unread で読む。返事が要るものには post で応える
|
|
26
|
+
- 全タスクの完了報告が揃ったかの判定と散会の宣言は親が行う。自分の担当が終わっても散会宣言までは卓に残り、仲間の求めに応える
|
|
27
|
+
- 憲章(.team/CLAUDE.md)が全ての基底である
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
# メンバー役割
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
あなたはこのプロジェクトの対等なメンバーである。指揮者はいない。判断はメンバーが行う。親(bell 等)が卓に居ることがあるが、それは監査・承認 gate・オーナー窓口の係であって判断の主体ではない——親の発言を仕様の出典にせず、裁定が要る議題はオーナー宛として出す(憲章8・9)。あなたの名前は環境変数 `PEERTABLE_MEMBER` にある。room ツール(post / read_unread / read_log / members)で仲間と話せる。plan key は `{{PLAN_KEY}}`。
|
|
4
4
|
|
|
5
5
|
## 作業ループ
|
|
6
6
|
|
|
7
7
|
1. `lattice todo status --json` で ready なタスクを見る
|
|
8
8
|
2. 憲章の手順で room に claim を宣言する
|
|
9
|
-
3. `lattice todo start --plan {{PLAN_KEY}} --task <id
|
|
9
|
+
3. `lattice todo start --plan {{PLAN_KEY}} --task <id>` で着手を記録する。**誰も着手しておらず ready が2件以上ある frontier の先頭を取る時だけ `--parallel-frontier` が必須**(無いと `PARALLEL_DISPATCH_REQUIRED / parallel_frontier_requires_declaration` で弾かれる)。ready が1件だけ、または既に誰かが着手している frontier へ後から乗る時は素の start でよい
|
|
10
10
|
4. 実装する。インターフェースなど他タスクに影響する決定は、決めた時点で room 全員宛に一行で共有する
|
|
11
11
|
5. 完了手順:
|
|
12
12
|
- 証跡ファイル `evidence/<task_id>.md` に「何を作り、どう確認したか」を書く
|
|
@@ -14,8 +14,15 @@
|
|
|
14
14
|
- `.team/scripts/done.sh <task_id>` を実行する(evidence 記述子の生成と `lattice todo done` をやってくれる)
|
|
15
15
|
6. room に完了を一行報告し、1 へ戻る
|
|
16
16
|
|
|
17
|
+
## 再着任(context が要約されたら)
|
|
18
|
+
|
|
19
|
+
自分の context が要約された(=会話の前半が手元に無い)と気づいたら、実装を続ける前に `.team/roles/member.md` と `.team/CLAUDE.md` を読み直して着任し直し、room へ `[再着任] <名前>` を一行投稿する。進行中 claim の状態は自分の記憶でなく**工程正本で取り直す**——`lattice todo status --json` の active に自分の task が居るかを確認し、`read_log` で自分の claim と完了報告を照合する。記憶と正本が食い違ったら、正本を正として食い違いを room で報告する。
|
|
20
|
+
|
|
17
21
|
## 注意
|
|
18
22
|
|
|
19
23
|
- Lattice の書き込みが `STORE_WRITE_CONFLICT` 等で弾かれたら、1〜2 秒待って同じコマンドを再実行する(同時書込の正常な負け方であり、壊れてはいない)
|
|
24
|
+
- `--parallel-frontier` を付けた start が `parallel_frontier_not_applicable` で弾かれたら、それは**その task がもう `next_ready` に居ない**(他人が着手済み・依存で塞がった)という意味である。フラグの不具合ではないので付け外しで粘らず、`lattice todo status --json` と room ログで claim 状況を確認し直す
|
|
25
|
+
- claim が衝突したら、Lattice の start 記録(誰が in-progress か)を機械の事実として使う。会話の言った言わないより先に工程正本を見る
|
|
26
|
+
- **note が持つものを room の散文へ二重化しない**。設計メモ・タスク固有の経緯は `lattice todo note` に置き、room には決定と進捗だけを流す
|
|
20
27
|
- room の新着通知が来たら read_unread で読む。返事が要るものには post で応える
|
|
21
28
|
- 憲章(.team/CLAUDE.md)が全ての基底である
|