chat-Claude が 藤本さん 経由で Rei-AIOS の tab 各 session に 出す 指示 (STEP 番号 予約 / 担当 tab / hard constraint) が machine-readable な形で どこにも 残らない ため、 tab を 跨ぐ たびに 二重発注 / 番号衝突 / 不可視性 が 再発。 SAC-4 3 回目 pattern の root cause。
Solution: 事前 registry (data/directives/chat-claude/*.yaml) を repo tree に 保存、 claim-step.ts と commit-msg hook が 起動時に 参照して 違反を 「読まなくても 止まる」 gate として 機械的に refuse/block。 5 STEP arc で 段階的に 実装。
Result: 事前 gate 全 layer 完備 (design → helpers → claim → commit → strict)、 総 実装量 ~475 行 shared + ~1,030 行 test = 132 assertion 全 PASS、 実 repo live gate 動作確認済。
2026-08-26 から 3 回 同 root cause で collision 発生:
| 発生日 | STEP collision | Layer |
|---|---|---|
| 2026-08-26 | STEP 1405/1406 renumber | atomic counter 実装前 |
| 2026-08-26 | STEP 1415/1416 renumber | 同上 |
| 2026-09-06 | STEP 1778 collision | atomic counter 実装後、 chat-Claude 口頭予約 が counter に 反映されず |
STEP 1672 で 「事後検知」 layer (atomic counter + commit-msg hook) 導入済 だが、 collision 発生してから 訂正 コスト継続。 「事前 registry」 layer が 不在 = SAC-4 3 回目 root cause。
藤本さん明示 (2026-09-06): 「私 の 指示 が counter にも file にも 残らない形で 出ていることが 原因で、 tab を 跨ぐ たびに 再発しています。 スコープは 設計と scaffold まで、 実装は 別 STEP で 構いません。 求めたいのは、 私が tab に 出した 指示 が repo 上のどこかに 残って、 claim 時に 照合できる 形です。 d8_verify の regex gate や 1777 spec の assert(c.match === false) と 同じで、 読まなくても 止まる のが 理想です」
YAML file を data/directives/chat-claude/YYYY-MM-DD/*.yaml に配置、 5 kind で分類:
| kind | 目的 | key fields |
|---|---|---|
reserve_step | STEP 番号 N を tab に 予約 | step_number, assignee_tab, arc_slug |
assign_task | arc / task を tab に 割当 | arc_slug, assignee_tab, step_number (nullable) |
hard_constraint | STEP / arc に 制約条件 追加 | target_step / target_arc_slug, constraints[] |
rescind | 既存 directive 撤回 | rescinds (id), reason |
dispatch_scope | 単一 tab 限定 / 複数 tab 協調 明示 | arc_slug, dispatch_mode, authorized_tabs[] |
共通必須 frontmatter: id, kind, issued_at, issued_by, issued_via, expiry, rescinded_by, notes。 詳細 schema: data/directives/chat-claude/schema.yaml。
| STEP | commit | scope | 行数 | test | status |
|---|---|---|---|---|---|
| 1780 | 9be381883 |
design + scaffold + 4 retroactive example | — | — | ✓ land |
| 1782 | 1064a820a |
helpers 3 file (minimal-yaml-parse + detect-current-tab + read-directives) | ~200 | 58/58 PASS | ✓ land |
| 1785 | ff9fd4e5e |
claim-step.ts 統合 (--tab + consultDirectives + refuse format + bypass log) | ~100 | 27/27 PASS | ✓ land |
| 1800 | ab43cb8ad |
commit-msg hook Section D + TS delegate | ~120 | 24/24 PASS | ✓ land |
| 1804 | d432872d0 |
strict mode opt-in (CLAIM_STEP_REQUIRE_TAB=1) |
~55 | 23/23 PASS | ✓ land |
総 実装量: ~475 行 shared code + ~1,030 行 test = ~1,505 行、 test 累計 132/132 全 PASS。
$ REI_TAB_ID=rei-aios-95 npx tsx scripts/claim-step.ts \
--slug dfumt8_cross_impl_drift_claim_ext_a
[claim-step] REFUSED by chat-Claude directive
(kind=dispatch_scope,
id=2026-09-06T02-00_dispatch_scope_dfumt8_ext_a_single_tab_a6)
reason: arc 'dfumt8_cross_impl_drift_claim_ext_a' is single_tab dispatch to
[rei-aios-a6], current tab 'rei-aios-95' not authorized
expiry: 2026-09-13T00:00:00+09:00
source: <full path to directive file>
Detected current tab: 'rei-aios-95' (source: env)
To bypass: DIRECTIVE_BYPASS=1 DIRECTIVE_BYPASS_REASON="..." <command>
Bash hook .githooks/commit-msg Section D が subject-line STEP 番号を 抽出、 TS delegate (scripts/check-commit-directive.ts) で directive check。 reserve_step 違反 → BLOCK exit 1、 hard_constraint match → WARN 印字 (stderr、 not block)。
CLAIM_STEP_REQUIRE_TAB=1 env で REI_TAB_ID unset を fail-open WARN → refuse/block に 昇格。 default は backward compat WARN 維持、 opt-in で SAC-4 4 回目 risk 除去。
DIRECTIVE_BYPASS=1 DIRECTIVE_BYPASS_REASON="..." <command> で 一時 override、 audit log を logs/directive-bypass.log に append。 format: <ISO ts>\t<source>\t<key=value pairs>\n、 claim-step.ts + bash Section D で 統一。
arc land 期間中に 実 repo directive relative で 動作確認:
dfumt8_cross_impl_drift_claim_ext_a slug で claim 試行 → 明確 REFUSE、 counter 未進行process.exit() は 同期 cleanup 停止process.exit() 前 に 明示的 cleanup、 全 exit path で grepexecSync return は stdout のみ、 stderr は 別 stream で 捨てる (stdio: 'pipe' 設定しても)spawnSync default (成功時 stderr 保持必要な case)実装済 (arc 完成):
未実装 (STEP 1806+ candidate):
REI_TAB_ID (strict default 化 前提整備)dist/ build target で cold start 短縮 (~500ms → ~100ms)scripts/issue-directive.ts 対話生成 tool (藤本さん directive 発行 UX)assign_task / dispatch_scope の commit-msg hook 側 gate (現状 claim 段階のみ)本 site page 自体 は retrospective: STEP 1780/1782/1785/1800/1804 は site 化されず land 済 = CLAUDE.md 「全 STEP site 化 default」 protocol 適用漏れ、 STEP 1809 (本 STEP) で 追加 land。 SAC-4 pattern 「default protocol 遵守忘れ」 として dataset 追加。
data/directives/chat-claude/README.md (150 行)data/directives/chat-claude/schema.yaml (110 行)data/directives/chat-claude/2026-09-06/*.yamlscripts/lib/{minimal-yaml-parse,detect-current-tab,read-directives}.tsscripts/claim-step.ts + scripts/check-commit-directive.ts + .githooks/commit-msg Section Dtest/step178{2,5}-*.ts + test/step180{0,4}-*.tsdocs/notepad/2026-09-06T*-STEP-{1780,1782,1785,1800,1804}-*.mdnotes/steps/STEP_{1780,1782,1785,1800,1804}.mdlogs/directive-bypass.log (claim-step + bash Section D 統一 format)