chat-Claude directive registry

SAC-4 3 回目 pattern (chat-Claude 口頭指示 unreachable) の structural fix — 5 STEP arc + 事前 gate 2 段階 + strict mode opt-in
2026-09-06 / STEP 1780 → 1782 → 1785 → 1800 → 1804 / retrospective site reflection: STEP 1809

TL;DR

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.tscommit-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 動作確認済。

Root cause: SAC-4 3 回目 pattern

2026-08-26 から 3 回 同 root cause で collision 発生:

発生日STEP collisionLayer
2026-08-26STEP 1405/1406 renumberatomic counter 実装前
2026-08-26STEP 1415/1416 renumber同上
2026-09-06STEP 1778 collisionatomic 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) と 同じで、 読まなくても 止まる のが 理想です」

Design: 5 directive kinds (STEP 1780)

YAML file を data/directives/chat-claude/YYYY-MM-DD/*.yaml に配置、 5 kind で分類:

kind目的key fields
reserve_stepSTEP 番号 N を tab に 予約step_number, assignee_tab, arc_slug
assign_taskarc / task を tab に 割当arc_slug, assignee_tab, step_number (nullable)
hard_constraintSTEP / 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

5 STEP arc timeline

STEPcommitscope行数teststatus
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

Gate behavior: 2 段階 + strict opt-in

Claim 時 (STEP 1785)

$ 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>

Commit 時 (STEP 1800)

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)。

Strict mode (STEP 1804、 opt-in)

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 除去。

Bypass path

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 で 統一。

実 repo live gate 実測

arc land 期間中に 実 repo directive relative で 動作確認:

SAC-4 dataset 追加 (実装中 実測発見 2 pattern)

Pattern: Node process.exit() は finally block を skip する

Pattern: execSync success 時 stderr 消失

Pattern: 見出し overreach (2 回)

Honest scope

実装済 (arc 完成):

  • design + scaffold (STEP 1780)
  • helpers 3 file (STEP 1782)
  • claim-step 統合 (STEP 1785)
  • commit-msg hook Section D (STEP 1800)
  • strict mode opt-in (STEP 1804)

未実装 (STEP 1806+ candidate):

  • Tab startup script auto-set REI_TAB_ID (strict default 化 前提整備)
  • dist/ build target で cold start 短縮 (~500ms → ~100ms)
  • scripts/issue-directive.ts 対話生成 tool (藤本さん directive 発行 UX)
  • audit log daily review script + threshold alert
  • 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 追加。

参照