kairos-chain 3.24.9 → 3.25.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 98d111b116bdd82edadfd6b634d551bee42e289698ecf20f4fd4e60d8d0a9b2f
4
- data.tar.gz: 3f4ffc6049f6e5e1be2dc5f8238308b2680f08f7a110218d26b1d1a69d296810
3
+ metadata.gz: 31f36e0972d3b7f0848a2a5334d18e5dce69ca4e9f507d0e8072ca9b263983b8
4
+ data.tar.gz: 3d4c0ff8590721b645088b386e2d3acfc7944fae62b774776a4fd2f4f65887ab
5
5
  SHA512:
6
- metadata.gz: ad44f0bf58d272ff80d7a50e09a0f93634e9496b6e6238f8311838e08109463e614ee05f2356b7f311c6538c1e0511ae44bfe0c122bab828d05e6888de042bfa
7
- data.tar.gz: 4b1995339b02160c87636f520cc33e58667a45d8081092d7fa480ec6b6e300baddd3248ed76483f89253440299a25b60d497b4ed3fc3ac566769fa8d20ed632b
6
+ metadata.gz: 781cc48a6a9e55de327e2ca7cf4bee5d1e195dc9dc4c8f86e7998e36dc2d93ac301bd17c60efcacb0b63d4347d352c83c365d24cc7415e2f319f3a7276741c19
7
+ data.tar.gz: 7f91d5619741e422a6594bddb22a8bfba4bacf31de8681424e46a91c5a7ffa3b71d1d5ecaf21306a66680db0136efe252744e9dc9ae5be3446a8d50916b8e306
data/CHANGELOG.md CHANGED
@@ -4,6 +4,42 @@ All notable changes to the `kairos-chain` gem will be documented in this file.
4
4
 
5
5
  This project follows [Semantic Versioning](https://semver.org/).
6
6
 
7
+ ## [3.25.0] - 2026-05-07
8
+
9
+ ### Added (Instruction mode projection)
10
+
11
+ `plugin_projector` SkillSet に新しい artifact type `instruction_mode` を追加。アクティブな instruction mode 本体(`.kairos/skills/<active_mode>.md`)を `.claude/kairos/instruction_mode.md` に flat 投射し、project-root `CLAUDE.md` にマネージドな `@`-import 領域を merge することで、parent / `claude -p` subprocess / Agent tool sub-agent の 3 surface すべてに mode 本体を配信。
12
+
13
+ 主な動機 (Theme A/A-2/A-3 検証ログ参照):
14
+ - MCP `instructions` channel は Claude Code harness によって途中で truncated され mode 本体の規範部分が届かない
15
+ - Agent tool sub-agent は MCP `instructions` を**一切継承しない**ため、Persona Agent team が masa mode 不在で動作してきた(Prop 5 違反)
16
+ - CLAUDE.md `@`-import は parent + subprocess + sub-agent の 3 surface に対し 107KB まで欠損なく配信することを Opus 4.6 / 4.7 で実証
17
+
18
+ 主な変更:
19
+ - 新 CLI subcommand `kairos-chain mode {project|status|remove}` (`bin/kairos-chain`)
20
+ - `KairosMcp::PluginProjector#project_instruction_mode!` / `#remove_projected_instruction_mode!` / `#instruction_mode_status` 追加 (`lib/kairos_mcp/plugin_projector.rb`)
21
+ - `Protocol#load_instructions` 三状態化:
22
+ - 投射済み → slim identity + pointer payload
23
+ - 未投射 → 既存 full body の冒頭に first-run setup notice を prepend し、LLM がユーザーをセットアップに自動案内できるようにする
24
+ - `mode == 'none'` → nil(既存動作)
25
+ - `.kairos/instruction_mode_manifest.json` で投射状態を track(既存 `projection_manifest.json.outputs` と独立、`verify` への副作用なし)
26
+
27
+ Out of scope (既存 `plugin_projector` と同 scope):
28
+ - 1 プロジェクトに複数の KairosChain インスタンス
29
+ - `.git` 共有の git worktree
30
+ - 並行 projector プロセス
31
+ - 第三者による `CLAUDE.md` 書き換えからの自動回復
32
+ - projector 自身の self-projection(Prop 1 自己言及性、open philosophical question)
33
+
34
+ サイズ policy: 150KB warn / 256KB refuse。
35
+
36
+ 設計 (round 4 multi-LLM review converged):
37
+ - `log/20260506_plugin_projector_instance_mode_extension_v4_accepted_design.md`
38
+ - `log/20260507_plugin_projector_instruction_mode_implementation_plan.md`
39
+
40
+ ### Changed
41
+ - `KairosMcp::VERSION` 3.24.9 → 3.25.0
42
+
7
43
  ## [3.24.9] - 2026-05-05
8
44
 
9
45
  ### Added (L1 knowledge: goal_setting_heuristic)
data/README.md CHANGED
@@ -20,6 +20,7 @@ A self-referential [Model Context Protocol (MCP)](https://modelcontextprotocol.i
20
20
  - **Attestation System (Synoptis)** — Cryptographic attestation and trust scoring
21
21
  - **Dream Mode** — Speculative knowledge proposals with community review
22
22
  - **Claude Code Plugin Projection** — Auto-project SkillSets as Claude Code plugins (hooks, agents, slash commands)
23
+ - **Instruction Mode Projection** — Project the active instruction mode body to project-root `CLAUDE.md` via a managed `@`-import region; reaches Agent tool sub-agents (which do not receive MCP `instructions`) and bypasses the harness truncation cap
23
24
  - **Multi-LLM Review** — Parallel dispatch to heterogeneous LLMs (Claude, Codex, Cursor) via CLI subprocesses; consensus verdict with aggregated findings
24
25
 
25
26
  ## Installation
@@ -61,6 +62,9 @@ kairos-chain skillset list # List installed SkillSets
61
62
  kairos-chain skillset install PATH # Install a SkillSet from path
62
63
  kairos-chain skillset enable NAME # Enable a SkillSet
63
64
  kairos-chain skillset info NAME # Show SkillSet details
65
+ kairos-chain mode project # Project active instruction mode to CLAUDE.md
66
+ kairos-chain mode status # Show instruction mode projection state
67
+ kairos-chain mode remove # Remove instruction mode projection
64
68
  kairos-chain -v # Show version
65
69
  ```
66
70
 
data/bin/kairos-chain CHANGED
@@ -342,6 +342,97 @@ when 'upgrade'
342
342
  puts content[:text] if content[:type] == 'text'
343
343
  end
344
344
  exit
345
+
346
+ when 'mode'
347
+ ARGV.shift # Remove 'mode' from ARGV
348
+
349
+ mode_action = ARGV.shift || 'project'
350
+
351
+ $LOAD_PATH.unshift File.expand_path('../lib', __dir__)
352
+ require 'kairos_mcp'
353
+
354
+ # Honor --data-dir if present anywhere in remaining ARGV
355
+ if (idx = ARGV.index('--data-dir'))
356
+ KairosMcp.data_dir = File.expand_path(ARGV[idx + 1])
357
+ ARGV.delete_at(idx + 1)
358
+ ARGV.delete_at(idx)
359
+ end
360
+
361
+ require 'kairos_mcp/skills_config'
362
+ require 'kairos_mcp/plugin_projector'
363
+
364
+ project_root = KairosMcp.project_root
365
+ projector_mode = KairosMcp.projection_mode
366
+ projector = KairosMcp::PluginProjector.new(project_root, mode: projector_mode)
367
+
368
+ case mode_action
369
+ when 'project'
370
+ instructions_mode = KairosMcp::SkillsConfig.load['instructions_mode']
371
+ if instructions_mode.nil? || instructions_mode == 'none'
372
+ puts "No active instruction mode (config: instructions_mode = #{instructions_mode.inspect})."
373
+ puts "Set instructions_mode in #{KairosMcp.skills_config_path} to project a mode body."
374
+ exit 0
375
+ end
376
+
377
+ body_path = case instructions_mode
378
+ when 'developer' then KairosMcp.md_path
379
+ when 'user' then KairosMcp.quickguide_path
380
+ when 'tutorial' then KairosMcp.tutorial_path
381
+ else File.join(KairosMcp.skills_dir, "#{instructions_mode}.md")
382
+ end
383
+
384
+ unless File.exist?(body_path)
385
+ warn "ERROR: instruction mode body not found: #{body_path}"
386
+ exit 1
387
+ end
388
+
389
+ body = File.read(body_path)
390
+ version = body[/^\*\*Version:\*\*\s*(\S+)/i, 1]
391
+
392
+ begin
393
+ result = projector.project_instruction_mode!(instructions_mode, body, mode_version: version)
394
+ rescue KairosMcp::PluginProjector::InstructionModeTooLarge => e
395
+ warn "ERROR: #{e.message}"
396
+ exit 1
397
+ end
398
+
399
+ puts "Instruction mode projected:"
400
+ puts " mode : #{instructions_mode}#{version ? " v#{version}" : ''}"
401
+ puts " source : #{body_path}"
402
+ puts " artifact : #{result[:artifact_path]}"
403
+ puts " size : #{result[:size_bytes]} bytes"
404
+ puts " CLAUDE.md : region #{result[:region_written] ? 'updated' : 'not updated (host file outside project root or unsafe)'}"
405
+ puts ""
406
+ puts "Restart Claude Code to apply (CLAUDE.md @-imports resolve at session start)."
407
+ exit 0
408
+
409
+ when 'status'
410
+ s = projector.instruction_mode_status
411
+ if s[:active]
412
+ puts "Instruction mode projection: ACTIVE"
413
+ puts " mode : #{s[:mode_name]}#{s[:mode_version] ? " v#{s[:mode_version]}" : ''}"
414
+ puts " artifact : #{s[:artifact_path]} (#{s[:artifact_size]} bytes)"
415
+ puts " region : #{s[:region_present] ? 'present in CLAUDE.md' : 'absent'}"
416
+ puts " projected : #{s[:projected_at]}"
417
+ else
418
+ puts "Instruction mode projection: not active for this project."
419
+ end
420
+ exit 0
421
+
422
+ when 'remove'
423
+ result = projector.remove_projected_instruction_mode!
424
+ puts "Instruction mode projection removed:"
425
+ puts " artifact : #{result[:artifact_removed] ? 'deleted' : 'not present'}"
426
+ puts " CLAUDE.md : #{result[:region_removed] ? 'region removed' : 'region not present'}"
427
+ puts ""
428
+ puts "Restart Claude Code to apply (CLAUDE.md @-imports resolve at session start)."
429
+ exit 0
430
+
431
+ else
432
+ warn "Unknown mode action: #{mode_action.inspect}"
433
+ warn "Usage: kairos-chain mode [project|status|remove] [--data-dir DIR]"
434
+ exit 2
435
+ end
345
436
  end
346
437
 
347
438
  # Parse CLI options
@@ -5,6 +5,7 @@ require 'digest'
5
5
  require 'fileutils'
6
6
  require 'tempfile'
7
7
  require 'time'
8
+ require 'pathname'
8
9
 
9
10
  module KairosMcp
10
11
  # Projects SkillSet plugin artifacts to Claude Code plugin/project structure.
@@ -20,6 +21,12 @@ module KairosMcp
20
21
  SAFE_NAME_PATTERN = /\A[a-zA-Z0-9][a-zA-Z0-9_-]*\z/
21
22
  ALLOWED_HOOK_COMMANDS = /\Akairos-/
22
23
 
24
+ INSTRUCTION_MODE_MARKER_BEGIN = '<!-- BEGIN kairos-chain:instruction-mode _projected_by=kairos-chain -->'
25
+ INSTRUCTION_MODE_MARKER_END = '<!-- END kairos-chain:instruction-mode -->'
26
+ INSTRUCTION_MODE_REL_PATH = 'kairos/instruction_mode.md'
27
+ INSTRUCTION_MODE_SIZE_WARN = 150 * 1024
28
+ INSTRUCTION_MODE_SIZE_REFUSE = 256 * 1024
29
+
23
30
  attr_reader :mode, :project_root, :output_root
24
31
 
25
32
  def initialize(project_root, mode: :auto)
@@ -27,6 +34,7 @@ module KairosMcp
27
34
  @mode = resolve_mode(mode)
28
35
  @output_root = @mode == :plugin ? project_root : File.join(project_root, '.claude')
29
36
  @manifest_path = File.join(project_root, '.kairos', 'projection_manifest.json')
37
+ @instruction_mode_manifest_path = File.join(project_root, '.kairos', 'instruction_mode_manifest.json')
30
38
  end
31
39
 
32
40
  # Main entry: project all SkillSet plugin artifacts + L1 knowledge meta skill
@@ -79,6 +87,96 @@ module KairosMcp
79
87
  { valid: missing.empty? && orphaned.empty?, missing: missing, orphaned: orphaned }
80
88
  end
81
89
 
90
+ # =========================================================================
91
+ # Instruction mode projection
92
+ # See: log/20260507_plugin_projector_instruction_mode_implementation_plan.md
93
+ #
94
+ # Materializes the active instruction mode body to a flat file under
95
+ # <output_root>/<INSTRUCTION_MODE_REL_PATH>, then merges a managed marker
96
+ # region into project-root CLAUDE.md so the harness picks it up via
97
+ # `@`-import at session start. State for this artifact is tracked in a
98
+ # separate manifest (.kairos/instruction_mode_manifest.json) to avoid
99
+ # mixing symbolic region keys into the main projection manifest.
100
+ # =========================================================================
101
+
102
+ # Project the active instruction mode body.
103
+ #
104
+ # @param mode_name [String] active mode name (e.g., 'masa', 'tutorial')
105
+ # @param body [String] flat mode body (no @-imports inside)
106
+ # @param mode_version [String, nil] optional version label for the marker header
107
+ # @return [Hash] result summary { artifact_path:, region_written:, size_bytes: }
108
+ def project_instruction_mode!(mode_name, body, mode_version: nil)
109
+ raise ArgumentError, "unsafe mode name: #{mode_name.inspect}" unless safe_name?(mode_name)
110
+
111
+ size = body.bytesize
112
+ raise InstructionModeTooLarge.new(size, INSTRUCTION_MODE_SIZE_REFUSE) if size > INSTRUCTION_MODE_SIZE_REFUSE
113
+ warn "[PluginProjector] WARNING: instruction mode body is #{size} bytes (warn threshold #{INSTRUCTION_MODE_SIZE_WARN})" if size > INSTRUCTION_MODE_SIZE_WARN
114
+
115
+ artifact_path = File.join(@output_root, INSTRUCTION_MODE_REL_PATH)
116
+ raise "instruction mode artifact path outside output_root: #{artifact_path}" unless safe_path?(artifact_path)
117
+
118
+ FileUtils.mkdir_p(File.dirname(artifact_path))
119
+ atomic_write(artifact_path, body)
120
+
121
+ region_written = merge_instruction_mode_region!(mode_name, mode_version, artifact_path)
122
+
123
+ save_instruction_mode_manifest(
124
+ 'mode_name' => mode_name,
125
+ 'mode_version' => mode_version,
126
+ 'artifact_path' => artifact_path,
127
+ 'artifact_size' => size,
128
+ 'artifact_digest' => Digest::SHA256.hexdigest(body),
129
+ 'region_present' => region_written,
130
+ 'projected_at' => Time.now.utc.iso8601
131
+ )
132
+
133
+ { artifact_path: artifact_path, region_written: region_written, size_bytes: size }
134
+ end
135
+
136
+ # Remove the projected instruction mode artifact and CLAUDE.md region.
137
+ #
138
+ # @return [Hash] result summary { artifact_removed:, region_removed: }
139
+ def remove_projected_instruction_mode!
140
+ manifest = load_instruction_mode_manifest
141
+ artifact_path = manifest['artifact_path'] || File.join(@output_root, INSTRUCTION_MODE_REL_PATH)
142
+
143
+ artifact_removed = false
144
+ if File.exist?(artifact_path) && safe_path?(artifact_path)
145
+ FileUtils.rm_f(artifact_path)
146
+ parent = File.dirname(artifact_path)
147
+ FileUtils.rmdir(parent) if Dir.exist?(parent) && Dir.empty?(parent)
148
+ artifact_removed = true
149
+ end
150
+
151
+ region_removed = remove_instruction_mode_region!
152
+
153
+ save_instruction_mode_manifest(nil) # clear
154
+
155
+ { artifact_removed: artifact_removed, region_removed: region_removed }
156
+ end
157
+
158
+ # Status summary for the instruction mode projection.
159
+ def instruction_mode_status
160
+ manifest = load_instruction_mode_manifest
161
+ {
162
+ mode: @mode,
163
+ active: !manifest.empty?,
164
+ mode_name: manifest['mode_name'],
165
+ mode_version: manifest['mode_version'],
166
+ artifact_path: manifest['artifact_path'],
167
+ artifact_size: manifest['artifact_size'],
168
+ region_present: manifest['region_present'],
169
+ projected_at: manifest['projected_at']
170
+ }
171
+ end
172
+
173
+ # Raised when a mode body exceeds the hard refusal threshold.
174
+ class InstructionModeTooLarge < StandardError
175
+ def initialize(size, limit)
176
+ super("instruction mode body too large: #{size} bytes exceeds limit #{limit}")
177
+ end
178
+ end
179
+
82
180
  private
83
181
 
84
182
  def resolve_mode(mode)
@@ -429,5 +527,94 @@ module KairosMcp
429
527
  template
430
528
  end
431
529
  end
530
+
531
+ # =========================================================================
532
+ # Instruction mode helpers (private)
533
+ # =========================================================================
534
+
535
+ # Merge or insert the managed marker region in project-root CLAUDE.md.
536
+ # Returns true if the region is now present, false otherwise.
537
+ def merge_instruction_mode_region!(mode_name, mode_version, artifact_path)
538
+ claudemd = claudemd_path
539
+ return false unless safe_claudemd_path?(claudemd)
540
+
541
+ import_path = relative_import_path(artifact_path)
542
+ header = "<!-- Active mode: #{mode_name}#{mode_version ? " v#{mode_version}" : ''} | source: .kairos/skills/#{mode_name}.md -->"
543
+ region = [
544
+ INSTRUCTION_MODE_MARKER_BEGIN,
545
+ header,
546
+ "@#{import_path}",
547
+ INSTRUCTION_MODE_MARKER_END
548
+ ].join("\n")
549
+
550
+ existing = File.exist?(claudemd) ? File.read(claudemd) : ''
551
+ stripped = strip_instruction_mode_region(existing)
552
+ separator = stripped.empty? || stripped.end_with?("\n\n") ? '' : (stripped.end_with?("\n") ? "\n" : "\n\n")
553
+ new_content = stripped + separator + region + "\n"
554
+
555
+ atomic_write(claudemd, new_content)
556
+ true
557
+ end
558
+
559
+ # Remove the managed marker region from project-root CLAUDE.md if present.
560
+ # Returns true if a region was removed, false otherwise.
561
+ def remove_instruction_mode_region!
562
+ claudemd = claudemd_path
563
+ return false unless File.exist?(claudemd)
564
+ return false unless safe_claudemd_path?(claudemd)
565
+
566
+ existing = File.read(claudemd)
567
+ stripped = strip_instruction_mode_region(existing)
568
+ return false if stripped == existing
569
+
570
+ atomic_write(claudemd, stripped)
571
+ true
572
+ end
573
+
574
+ # Project-root CLAUDE.md absolute path.
575
+ def claudemd_path
576
+ File.join(@project_root, 'CLAUDE.md')
577
+ end
578
+
579
+ # Path safety for the host file: must be exactly <project_root>/CLAUDE.md.
580
+ # Distinct from safe_path? (which gates output_root-confined paths).
581
+ def safe_claudemd_path?(path)
582
+ canonical = File.expand_path(path)
583
+ expected = File.expand_path(claudemd_path)
584
+ return true if canonical == expected
585
+ warn "[PluginProjector] WARNING: refusing to mutate non-project CLAUDE.md at '#{path}'"
586
+ false
587
+ end
588
+
589
+ # Compute the @-import path used inside the marker region.
590
+ # CLAUDE.md @-imports resolve relative to the project root (where CLAUDE.md lives),
591
+ # so we emit a project-relative path. The artifact lives under output_root,
592
+ # which is .claude/ in :project mode.
593
+ def relative_import_path(artifact_path)
594
+ Pathname.new(artifact_path).relative_path_from(Pathname.new(@project_root)).to_s
595
+ end
596
+
597
+ # Remove an existing marker region (and any blank-line padding directly
598
+ # surrounding it) from CLAUDE.md content. Idempotent.
599
+ def strip_instruction_mode_region(content)
600
+ pattern = /\n*#{Regexp.escape(INSTRUCTION_MODE_MARKER_BEGIN)}.*?#{Regexp.escape(INSTRUCTION_MODE_MARKER_END)}\n*/m
601
+ content.sub(pattern, "\n")
602
+ end
603
+
604
+ def load_instruction_mode_manifest
605
+ return {} unless File.exist?(@instruction_mode_manifest_path)
606
+ JSON.parse(File.read(@instruction_mode_manifest_path))
607
+ rescue JSON::ParserError
608
+ {}
609
+ end
610
+
611
+ def save_instruction_mode_manifest(data)
612
+ FileUtils.mkdir_p(File.dirname(@instruction_mode_manifest_path))
613
+ if data.nil?
614
+ FileUtils.rm_f(@instruction_mode_manifest_path)
615
+ else
616
+ atomic_write(@instruction_mode_manifest_path, JSON.pretty_generate(data))
617
+ end
618
+ end
432
619
  end
433
620
  end
@@ -159,7 +159,17 @@ module KairosMcp
159
159
  KairosMcp.collect_knowledge_entries(user_context: @user_context)
160
160
  end
161
161
 
162
- # Load instructions based on instructions_mode in config.yml
162
+ # Load instructions based on instructions_mode in config.yml.
163
+ #
164
+ # Three states:
165
+ # 1. Projected (manifest present, region in CLAUDE.md): returns a slim
166
+ # identity+pointer payload. Full body reaches the model via CLAUDE.md
167
+ # @-import (the privileged delivery path verified in Theme A).
168
+ # 2. Not yet projected: returns the full body prefixed with a first-run
169
+ # hint that tells the LLM how to complete setup (`kairos-chain mode
170
+ # project` + restart). Backward-compatible — body still reaches the
171
+ # model on this channel, just truncated by the harness as before.
172
+ # 3. mode == 'none': returns nil.
163
173
  #
164
174
  # @return [String, nil] Instructions text or nil
165
175
  def load_instructions
@@ -181,7 +191,73 @@ module KairosMcp
181
191
 
182
192
  return nil unless path
183
193
 
184
- read_if_exists(path)
194
+ if instruction_mode_projected?(mode)
195
+ slim_instructions_payload(mode, path)
196
+ else
197
+ body = read_if_exists(path)
198
+ return nil if body.nil?
199
+ "#{first_run_setup_hint(mode)}\n---\n\n#{body}"
200
+ end
201
+ end
202
+
203
+ # First-run setup hint prepended to instructions when the instruction
204
+ # mode body has not yet been projected. Visible to the LLM in the
205
+ # truncated MCP `instructions` channel; lets the LLM proactively guide
206
+ # the user through one-time setup without needing prior knowledge.
207
+ def first_run_setup_hint(mode)
208
+ <<~HINT.strip
209
+ # kairos-chain first-run setup notice
210
+
211
+ The active instruction mode body ('#{mode}') has NOT been projected to
212
+ this project's CLAUDE.md yet. The MCP `instructions` channel below is
213
+ truncated by the Claude Code harness; Agent tool sub-agents do not
214
+ receive this channel at all.
215
+
216
+ To deliver the full mode body to all surfaces (parent + subprocess +
217
+ sub-agent), run from the project root:
218
+
219
+ kairos-chain mode project
220
+
221
+ Then restart Claude Code (`exit` then `claude`). After projection,
222
+ this notice disappears and this MCP channel switches to a slim
223
+ identity+pointer payload.
224
+
225
+ If you (the LLM) detect this notice in your context, surface this
226
+ setup step to the user with explanation, ask for approval, run the
227
+ command, and instruct them to restart.
228
+ HINT
229
+ end
230
+
231
+ # True if the active instruction mode has been projected for this project.
232
+ def instruction_mode_projected?(mode)
233
+ manifest_path = File.join(KairosMcp.project_root, '.kairos', 'instruction_mode_manifest.json')
234
+ return false unless File.exist?(manifest_path)
235
+ data = JSON.parse(File.read(manifest_path))
236
+ data['mode_name'] == mode && data['region_present']
237
+ rescue StandardError
238
+ false
239
+ end
240
+
241
+ # Identity + pointer payload sent over MCP `instructions` when the body
242
+ # is delivered via CLAUDE.md @-import. Short enough to clear the harness
243
+ # truncation cap. Non-Claude-Code consumers retrieve the body from the
244
+ # registry path directly.
245
+ def slim_instructions_payload(mode, body_path)
246
+ version_line = read_if_exists(body_path).to_s[/^\*\*Version:\*\*\s*\S+/i]
247
+ <<~PAYLOAD
248
+ # Active instruction mode (delivered via CLAUDE.md @-import)
249
+
250
+ - mode_name: #{mode}
251
+ - #{version_line || 'Version: (none recorded)'}
252
+ - source_path: #{body_path}
253
+
254
+ The full mode body is delivered to the model through this project's
255
+ CLAUDE.md `@`-import line and is not duplicated here. Non-Claude-Code
256
+ consumers can retrieve the body from the source_path above.
257
+
258
+ Re-run `kairos-chain mode project` after editing the source body
259
+ and restart Claude Code to apply changes.
260
+ PAYLOAD
185
261
  end
186
262
 
187
263
  # Read file content if it exists
@@ -1,4 +1,4 @@
1
1
  module KairosMcp
2
- VERSION = "3.24.9"
2
+ VERSION = "3.25.0"
3
3
  CHANGELOG_URL = "https://github.com/masaomi/KairosChain_2026/blob/main/CHANGELOG.md"
4
4
  end
@@ -29,6 +29,103 @@ This skill covers:
29
29
  For **WHO** (which LLM is good at what), see: `multi_llm_reviewer_evaluation`
30
30
  For **development lifecycle** (design → implement → verify), see: `design_to_implementation_workflow`
31
31
 
32
+ ## Step 0 — Load reviewer characteristics (mandatory)
33
+
34
+ **Before invoking any reviewer**, fetch `multi_llm_reviewer_evaluation` via
35
+ `knowledge_get`. That knowledge contains:
36
+
37
+ - per-reviewer strengths/weaknesses and verdict biases
38
+ - Codex value-system divergence (3 biases) and (a)/(b)/(c) finding classification
39
+ - convergence rule and reviewer-specific signal interpretation
40
+
41
+ Skipping Step 0 leads to misreading reviewer output — in particular, treating
42
+ Codex (c)-class value-divergent REJECTs as blocking, which causes review loops to
43
+ fail to converge. The cross-reference exists in `related:` frontmatter; this step
44
+ makes it an explicit pre-condition rather than an implicit hint.
45
+
46
+ ## Step 0.5 — Design Direction Block (design / docs reviews only)
47
+
48
+ For **design-phase** and **knowledge/documentation-update** reviews, prepend a
49
+ **Design Direction Block** to every reviewer prompt, in addition to the project
50
+ philosophy briefing (CLAUDE.md § "Multi-LLM Review Philosophy Briefing"). For
51
+ **implementation-phase** reviews this block is optional — implementation review
52
+ is correctness-vs-design, where philosophy divergence has limited impact.
53
+
54
+ ### Why this exists
55
+
56
+ Phase 2 Case A (Context Graph review loop, 4 rounds, 2026-05-04) showed that
57
+ a philosophy briefing alone does not shift Codex/Cursor reviewers from REJECT.
58
+ What shifted Cursor to APPROVE in round 4 was **briefing + explicit design
59
+ direction for this artifact**. Codex remained resistant even with both, but the
60
+ (a)/(b)/(c) classification (see `multi_llm_reviewer_evaluation` § Reviewer
61
+ Value-System Divergence) makes its REJECTs digestible. The combination —
62
+ briefing + direction + classification — is the operational protocol that
63
+ prevents review loops from failing to converge over value-system divergence
64
+ mistaken for genuine defects.
65
+
66
+ ### Block structure (prepend to every reviewer prompt)
67
+
68
+ > **Invariant**: the block declares the artifact's intentional scope so reviewers
69
+ > can distinguish in-scope critique from out-of-scope expectation. The fields below
70
+ > are illustrative facets of that single invariant, not an enumeration of independent
71
+ > requirements; omit fields that do not apply to the artifact rather than forcing
72
+ > content into every slot.
73
+
74
+ ```
75
+ ## Design Direction (this artifact)
76
+
77
+ **Problem this artifact solves**:
78
+ - <one or two sentences>
79
+
80
+ **Problems this artifact does NOT solve** (out of scope):
81
+ - <bullet: explicitly excluded scope>
82
+ - <bullet: deferred to future design — name the future design if known>
83
+
84
+ **Rejected alternatives and reasons**:
85
+ - Alt A: <one line> — rejected because <reason>
86
+ - Alt B: <one line> — rejected because <reason>
87
+
88
+ **Design tradeoffs adopted**:
89
+ - <axis>: chose X over Y because <reason>
90
+ (e.g., "discipline > infrastructure: workflow-level Step 0 hard fetch
91
+ over knowledge-graph auto-load, to avoid premature core change")
92
+ - <axis>: chose X over Y because <reason>
93
+ (e.g., "invariant declaration > mechanism enumeration, per project
94
+ design-by-invariant principle")
95
+
96
+ **Where to register additions/objections**:
97
+ - New mechanisms or scope expansions → §11 backlog of the artifact, not body
98
+ - Style/readability concerns not entailed by project principles → (c)
99
+ value-divergent class, advisory only
100
+ ```
101
+
102
+ ### How to author each field
103
+
104
+ - **Problem solved / not solved**: Should match the artifact's actual scope
105
+ declarations. If you can't fill these in cleanly, the artifact's scope is
106
+ unclear — fix that first, then review.
107
+ - **Rejected alternatives**: List at least 2. If you have only 1, you have not
108
+ considered the design space; design is not yet review-ready.
109
+ - **Tradeoffs**: Name the axis explicitly (X over Y). "We chose X" without an
110
+ alternative axis is a position, not a tradeoff.
111
+
112
+ ### Effect on reviewer instruction
113
+
114
+ After the block, instruct reviewers:
115
+
116
+ > Evaluate against the Design Direction above. Findings inconsistent with the
117
+ > declared scope, rejected alternatives, or tradeoffs are (c) value-divergent
118
+ > by default — record as advisory, not blocking. Findings about the *integrity*
119
+ > of the design (internal contradiction, unrealizable invariant, scope
120
+ > inconsistency) remain (a) deployment-grounded or (b) philosophy-aligned.
121
+
122
+ ### Scope of this step
123
+
124
+ - Design-phase review: **mandatory**
125
+ - Knowledge / documentation update review: **mandatory** (treated as design)
126
+ - Implementation-phase review: optional — use only when implementation makes
127
+ significant design choices not fixed by the design artifact
128
+
32
129
  ## Two Execution Paths (read this first)
33
130
 
34
131
  There are **two distinct execution paths** with the same name "multi-LLM review".
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: multi_llm_reviewer_evaluation
3
- description: "Multi-LLM reviewer performance evaluation — strengths, weaknesses, and recommended workflows based on 185+ reviews"
4
- version: "1.2"
3
+ description: "Multi-LLM reviewer performance evaluation — strengths, weaknesses, value-system biases, and recommended workflows. Based on 185+ reviews (Phase 1, 2026-02 to 03) + Phase 2 Case A 4-round Codex bias study (2026-05-04)."
4
+ version: "1.3"
5
5
  tags:
6
6
  - multi-llm
7
7
  - review
@@ -21,6 +21,7 @@ Based on 185+ review files across KairosChain development (2026-02-24 to 2026-03
21
21
  | Claude Opus 4.6 (Primary) | 15 | 3/18-3/28 | 0% | Designer + reviewer |
22
22
  | Claude Team Opus 4.6 | 53 | 3/18-3/28 | 0% | Persona assembly review |
23
23
  | Codex GPT-5.4 | 49 | 3/19-3/28 | 27% | Auto review |
24
+ | Codex GPT-5.5 | 4 (Phase 2 Case A) | 2026-05-04 | 100% | Auto review |
24
25
  | Cursor Composer-2 | 27 | 3/20-3/28 | 0% | Auto review |
25
26
  | Cursor GPT-5.4 | 16 | 3/21-3/25 | 12% | Manual review (Codex fallback) |
26
27
  | Cursor Premium | 26 | 3/19-3/21 | 12% | Manual review |
@@ -72,6 +73,14 @@ Based on 185+ review files across KairosChain development (2026-02-24 to 2026-03
72
73
  - **Unique findings**: Session Path B authorization re-binding, dead circuit breaker code, plan removal fallback, fail-open content_hash attestation, build_place_client return type mismatch, record_file_usage missing call site
73
74
  - **Convergence signal**: Codex APPROVE = high confidence that all issues are genuinely resolved (see Convergence Behavior)
74
75
 
76
+ ### Codex GPT-5.5
77
+
78
+ - **Strength**: Same axis as GPT-5.4 (state transition, fail-open detection) plus tighter schema-internal-consistency checks. Round 3 of Phase 2 Case A caught a §5 schema internal contradiction that no Anthropic family or Cursor reviewer caught
79
+ - **Weakness**: Shares all 3 value-system biases with GPT-5.4 (see § Reviewer Value-System Divergence below). Even more resistant to philosophy-briefing internalization than 5.4 in Phase 2 Case A round 4
80
+ - **Pattern**: Treat as "stricter sibling" of GPT-5.4. Same evaluative axis, narrower tolerance
81
+ - **Verdict bias**: REJECT-default; convergence behavior similar to GPT-5.4 but slower
82
+ - **Provisional**: Profile based on Phase 2 Case A 4-round data only. Will refine after additional sessions
83
+
75
84
  ### Cursor Composer-2
76
85
 
77
86
  - **Strength**: High-level design coherence, protocol correctness, practical deployability, balanced architecture + pragmatics
@@ -115,6 +124,65 @@ Based on 185+ review files across KairosChain development (2026-02-24 to 2026-03
115
124
  - **Language**: Japanese-primary (matches project philosophy discussions)
116
125
  - **Unique findings**: MerkleTree second preimage attack, Transport Store-and-Forward, challenge expiry penalty automation, `optional` dependency `parsed_depends_on` incompatibility
117
126
 
127
+ ## Reviewer Value-System Divergence (Phase 2 Case A, 2026-05-04)
128
+
129
+ This section documents *why* reviewers reject, not *what* they catch. Phase 1 profiles
130
+ (above) record finding categories; Phase 2 Case A revealed that some REJECTs reflect
131
+ the reviewer's own evaluative frame rather than a defect in the artifact. Treating
132
+ those as blocking signals causes review loops to fail to converge (observed: Context
133
+ Graph v1.0-f-high → v1.1 → v1.2, Codex 24/24 REJECT, new P0 every round).
134
+
135
+ ### Codex (GPT-5.4 / 5.5) — 3 structural biases
136
+
137
+ Both Codex models share these biases against KairosChain's design-by-invariant +
138
+ relational-ontology style. The biases are not bugs in the reviewer; they are a
139
+ different value system that must be classified explicitly.
140
+
141
+ 1. **"Declared behavior must be enforceable."** Industrial-spec-audit frame.
142
+ Any invariant declared without a verify mechanism is read as documentation drift.
143
+ Conflicts with KairosChain's relational ontology (no verify, writer responsibility,
144
+ graceful degradation by design).
145
+ 2. **Honest articulation of limits ≡ unresolved spec gap.** §11 backlog entries
146
+ and ceiling articulations are read as self-reported bugs. The more honest the
147
+ document, the more Codex rejects — an inversion of the intended discipline.
148
+ 3. **"Trust X" + "X is undetectable" = contract contradiction.** A §A "trust X"
149
+ clause combined with a §B "X cannot be verified" clause is read as a defective
150
+ contract. Conflicts with the "uncontracted trust = writer responsibility" model.
151
+
152
+ ### Cursor vs Codex briefing reaction (Phase 2 Case A, 4 rounds)
153
+
154
+ | Round | Briefing | Cursor | Codex 5.4/5.5 |
155
+ |-------|----------|--------|---------------|
156
+ | 1 | none (baseline) | REJECT | REJECT |
157
+ | 2 | philosophy briefing | REJECT | REJECT |
158
+ | 3 | philosophy briefing | REJECT | REJECT |
159
+ | 4 | briefing + design-direction context | **APPROVE** | REJECT (unchanged) |
160
+
161
+ **Insight**: Cursor internalizes the philosophy briefing once design direction is added;
162
+ Codex is structurally resistant. Briefing-internalization compliance differs by reviewer
163
+ family — track separately when evaluating briefing efficacy.
164
+
165
+ ### (a)/(b)/(c) finding classification
166
+
167
+ When a reviewer issues a P0, classify the *cause* — not just the severity:
168
+
169
+ | Class | Definition | Treatment |
170
+ |-------|-----------|-----------|
171
+ | (a) deployment-grounded | Spec violation, runtime bug, data corruption, concurrency hazard. Independent of philosophy. | **Blocking P0** |
172
+ | (b) philosophy-aligned | Deviation from declared design principles (e.g., enumeration where invariant suffices). | **Blocking P0** |
173
+ | (c) value-divergent | Reviewer's own style preference or generic best practice not entailed by project principles. | **Advisory only** (non-blocking) |
174
+
175
+ When uncertain between (b) and (c), default to (c). Convergence rule applies to (a)+(b);
176
+ (c) findings are recorded but do not block.
177
+
178
+ **Codex ↔ classes**: Codex finds genuine (a) bugs (e.g., the §5 schema contradiction).
179
+ Codex also produces many (c) findings driven by the 3 biases above. The skill of using
180
+ Codex effectively is **not** silencing it but classifying its output.
181
+
182
+ > Cross-reference: project CLAUDE.md § "Multi-LLM Review Philosophy Briefing"
183
+ > describes the experimental briefing-prepend protocol that operationalizes this
184
+ > classification. KairosChain_2026 only, experimental.
185
+
118
186
  ## Convergence Behavior (New: 2026-03-28)
119
187
 
120
188
  ### Codex as Convergence Indicator
@@ -134,17 +202,31 @@ Final Review: Codex APPROVE | Composer-2 APPROVE+ | Claude APPROVE+
134
202
  - When Codex finally APPROVEs, all prior FAIL/HIGH issues have been genuinely resolved
135
203
  - **Codex APPROVE = strongest merge-readiness signal** in the 3-LLM configuration
136
204
 
137
- > **Note**: The above convergence data is from the 3-reviewer configuration.
138
- > With the 4-reviewer default (Opus 4.7 added 2026-04-19), the convergence
139
- > pattern may shift. Update this section after accumulating 4-reviewer data.
205
+ > **Note**: The above convergence data is from the 3-reviewer configuration in
206
+ > the Attestation Nudge session. With the 4-reviewer default (Opus 4.7 added
207
+ > 2026-04-19), the convergence pattern may shift. Update this section after
208
+ > accumulating 4-reviewer data.
209
+ >
210
+ > **Caveat (Phase 2 Case A, 2026-05-04)**: "Codex APPROVE = strongest signal" is
211
+ > session- and config-dependent. In Phase 2 Case A, Codex never reached APPROVE
212
+ > across 4 rounds even with philosophy briefing + design direction. Treat
213
+ > "waiting for Codex APPROVE" as not always achievable; rely on (a)/(b)/(c)
214
+ > classification (above) rather than verdict-level convergence when value-system
215
+ > divergence dominates.
140
216
 
141
217
  ### Convergence Rule (Updated)
142
218
 
143
- - 3/4 APPROVE (no REJECT) = proceed to next step (4-reviewer default)
144
- - Any REJECT or FAIL = revise and re-review
219
+ The convergence rule applies **after** orchestrator classifies findings as (a)/(b)/(c)
220
+ per § Reviewer Value-System Divergence. A REJECT whose findings are entirely (c)
221
+ value-divergent is recorded but treated as non-blocking; only (a)+(b) findings count
222
+ toward the rule below.
223
+
224
+ - 3/4 APPROVE (no (a)/(b) REJECT) = proceed to next step (4-reviewer default)
225
+ - Any (a) or (b) REJECT or FAIL = revise and re-review
145
226
  - **4/4 APPROVE (including Codex) = highest confidence, merge-ready**
146
227
  - Legacy 3-reviewer mode: 2/3 APPROVE = proceed
147
- - Codex-only REJECT + others APPROVE = likely real issue, investigate before overriding
228
+ - Codex-only REJECT with (a)/(b) findings + others APPROVE = likely real issue, investigate before overriding
229
+ - Codex REJECT with only (c) findings = expected per Codex value-system divergence; non-blocking
148
230
 
149
231
  ### Bug Category Differentiation Across Rounds
150
232
 
@@ -157,7 +239,10 @@ Final Review: Codex APPROVE | Composer-2 APPROVE+ | Claude APPROVE+
157
239
 
158
240
  **Insight**: Design reviews and implementation reviews find **categorically different bugs**. Design reviews catch "this can't work" (structural). Implementation reviews catch "this doesn't work" (wiring/integration). Both phases are necessary.
159
241
 
160
- ## Cost-Benefit (All 7 Models)
242
+ ## Cost-Benefit (Phase 1 baseline, 5 reviewers, 2026-02 to 03)
243
+
244
+ > Baseline only. Opus 4.7 and Codex GPT-5.5 entered the roster post-Phase 1 and are
245
+ > not yet rated here. Refresh after sufficient data accumulates.
161
246
 
162
247
  | Reviewer | Speed | Security | Impl Quality | Philosophy | Overall ROI |
163
248
  |----------|-------|----------|-------------|-----------|-------------|
@@ -204,3 +289,6 @@ Deployment: Composer-2 or Cursor GPT-5.4
204
289
  in the multi-LLM configuration.
205
290
  4. Design reviews and implementation reviews find categorically different bugs —
206
291
  both phases are necessary for Tier 2+ features.
292
+ 5. Some REJECTs reflect the reviewer's value system, not the artifact. The (a)/(b)/(c)
293
+ classification (see § Reviewer Value-System Divergence) is required to separate
294
+ blocking signal from advisory noise. Codex models in particular require this lens.
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kairos-chain
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.24.9
4
+ version: 3.25.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Masaomi Hatakeyama
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-05-05 00:00:00.000000000 Z
11
+ date: 2026-05-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: minitest