kairos-chain 3.40.0 → 3.41.1

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.
Files changed (34) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +53 -0
  3. data/bin/kairos-chain +12 -8
  4. data/bin/kairos-plugin-project +34 -9
  5. data/lib/kairos_mcp/plugin_projector.rb +317 -125
  6. data/lib/kairos_mcp/version.rb +1 -1
  7. data/templates/skillsets/agent/config/agent.yml +28 -0
  8. data/templates/skillsets/agent/lib/agent/admission.rb +93 -0
  9. data/templates/skillsets/agent/lib/agent/confinement.rb +280 -0
  10. data/templates/skillsets/agent/lib/agent/mediator.rb +211 -0
  11. data/templates/skillsets/agent/lib/agent/native_body/main.rb +166 -0
  12. data/templates/skillsets/agent/lib/agent/native_body/model_client.rb +135 -0
  13. data/templates/skillsets/agent/lib/agent/native_body/spend_meter.rb +131 -0
  14. data/templates/skillsets/agent/lib/agent/native_body/tool_layer.rb +195 -0
  15. data/templates/skillsets/agent/lib/agent/session.rb +21 -1
  16. data/templates/skillsets/agent/lib/agent/staging.rb +267 -0
  17. data/templates/skillsets/agent/lib/agent/verdict.rb +177 -0
  18. data/templates/skillsets/agent/lib/agent.rb +5 -0
  19. data/templates/skillsets/agent/test/test_agent_admission.rb +112 -0
  20. data/templates/skillsets/agent/test/test_agent_confinement.rb +184 -0
  21. data/templates/skillsets/agent/test/test_agent_guard_integration.rb +218 -0
  22. data/templates/skillsets/agent/test/test_agent_native_body.rb +788 -0
  23. data/templates/skillsets/agent/test/test_agent_verdict.rb +119 -0
  24. data/templates/skillsets/agent/tools/agent_execute.rb +328 -12
  25. data/templates/skillsets/agent/tools/agent_start.rb +22 -0
  26. data/templates/skillsets/agent/tools/agent_step.rb +210 -9
  27. data/templates/skillsets/codex_projection/lib/codex_host_profile.rb +85 -0
  28. data/templates/skillsets/codex_projection/skillset.json +14 -0
  29. data/templates/skillsets/llm_client/lib/llm_client/anthropic_adapter.rb +5 -0
  30. data/templates/skillsets/llm_client/lib/llm_client/openai_adapter.rb +5 -0
  31. data/templates/skillsets/opencode_projection/lib/opencode_host_profile.rb +102 -0
  32. data/templates/skillsets/opencode_projection/skillset.json +14 -0
  33. data/templates/skillsets/plugin_projector/tools/plugin_project.rb +22 -5
  34. metadata +21 -6
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2285b28e2f2954ca10f6da869b7446b4d18fdc0f9174451f20ec8f523142b322
4
- data.tar.gz: 9a14c47fd141de6ff7eaec10d6e56c44f01e96b1cb0b9ab962eedb4baccc8e4b
3
+ metadata.gz: 3e3b999308891ccbf76963cea480730833fc1d13289498ec80b7f11471d78148
4
+ data.tar.gz: 1158b528c37b571283fbf86ea8d16b6feb05604aed70f7ae356961d99e123752
5
5
  SHA512:
6
- metadata.gz: 89a5a8a47b38f8f703283c58d9e402efeab1a2124fa1ad2195c0820edd985301ce68b22dd40012614499d09f9b34410905e473ca33ccad97e8d32d804ba46eb1
7
- data.tar.gz: df15f0d5f6cdb22039840cf780b235cba8194e77da2738478b37dbeb446c25814609887083566388bae2abeb2f067e0aa2ecb24d16b4ca626b75644818d794eb
6
+ metadata.gz: cd647719bd49cd6a66f5836fc3c4acd98c07a5210876a83f4f5ed6cf76c100e801971b84289c515768c44754c5412db177e728c3fc00a0a34bee25b057281af4
7
+ data.tar.gz: 9bbd8eed34dc64daa0fd7265ec6d42ee97e018399f9c090908688c0edbc0afa245782316fb66c02f6e9af4d8a01a9eedfca2ad46d678eda4af92465dc4019bd4
data/CHANGELOG.md CHANGED
@@ -4,6 +4,59 @@ 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.41.1] - 2026-07-13
8
+
9
+ ### Fixed — Meeting Place Caddy healthcheck false-negative (deployment)
10
+
11
+ The production `docker-compose.prod.yml` Caddy healthcheck probed
12
+ `http://localhost:2019/config/`. Inside the `caddy:2-alpine` container
13
+ `localhost` resolves to IPv6 `::1` first (both `127.0.0.1 localhost` and
14
+ `::1 localhost` are in `/etc/hosts`), but the Caddy admin API binds IPv4
15
+ `127.0.0.1` only — so the probe got connection-refused and the container was
16
+ perpetually reported `unhealthy` while actually serving fine. Pinned the probe
17
+ to `http://127.0.0.1:2019/config/`. Deployment-only change; no gem code affected.
18
+
19
+ ## [3.41.0] - 2026-07-11
20
+
21
+ ### Added — Agent SkillSet guard track Slice 2: native executor body (selectable-off)
22
+
23
+ A native, instance-authored executor substrate for the agent SkillSet's
24
+ delegated act route, discharging AGT-8 of the guard track. It coexists with the
25
+ current Claude Code CLI substrate behind one dispatch contract (boundary-owned
26
+ selection); it ships **selectable-off** (`agent_execute.substrate: cli`, and the
27
+ guard itself defaults off in the gem template) and carries no act until its
28
+ acceptance probes are green in an attended run. Substrate substitution only —
29
+ no parent invariant (AGT-1..7) is added, weakened, or re-interpreted.
30
+
31
+ - **`Agent::Staging` (NB-2)** — stages the whole executable closure (body + the
32
+ eligible direct-HTTP adapters + vendored `faraday`) into a read-only region
33
+ outside the work area, pinned by one content address and re-verified before
34
+ launch. A symlink in the staged tree, or a load resolving outside the pinned
35
+ region (RubyGems disabled + restricted load path), halts fail-closed.
36
+ - **`Agent::Mediator` (NB-4)** — a boundary-side loopback forward proxy that
37
+ scopes egress by destination hostname and re-decides on every hop; the SBPL
38
+ profile denies all network except the mediator port, making it the sole
39
+ egress path. Excluded transports (subprocess-CLI adapters, bedrock) are not
40
+ staged, so they cannot load.
41
+ - **`Agent::NativeBody::{Main,ToolLayer,ModelClient,SpendMeter}` (NB-1/3/5)** —
42
+ a separate confined process: value-only stdin intake, a load-bearing tool
43
+ layer over the granted surface (work-area-confined), staged HTTP-transport
44
+ model access with the provider credential env-windowed to the adapter call
45
+ only, and fail-closed ceilings — the per-call spend bound pre-estimates on the
46
+ prompt's **byte** length (a sound upper bound for byte-level BPE) across input
47
+ and output, and missing usage halts.
48
+ - **`Confinement` / `AgentExecute`** — `native_body_profile` (egress-scoped) with
49
+ a self-sound `egress_scoped?` predicate; `execute_confined_native` reuses the
50
+ Slice 1 scratch geometry, manifest, and verdict-gated merge; the per-cycle
51
+ record now persists which executable carried the act (closure digest beside
52
+ the spec hash).
53
+
54
+ Reviewed via a 3-round execution-grounded multi-LLM implementation review
55
+ (R1 found 7 genuine defects, R2 found 2, R3 found 1 — all fixed; the byte-based
56
+ spend bound independently confirmed with a real tokenizer). 97/97 native-body
57
+ probes plus the full Slice 1 guard suite pass. Guard and native substrate both
58
+ remain off by default.
59
+
7
60
  ## [3.40.0] - 2026-07-06
8
61
 
9
62
  ### Added — Optional built-in TLS/HTTPS for the HTTP transport
data/bin/kairos-chain CHANGED
@@ -456,11 +456,14 @@ when 'mode'
456
456
  KAIROS_PROJECT_ROOT env, then cwd if it contains a
457
457
  recognizable project marker (CLAUDE.md, .git/,
458
458
  .claude/, or prior projection manifest).
459
- --host HOST Target host: claude (default) | codex | opencode.
460
- claude writes CLAUDE.md with an @-import pointer;
461
- codex/opencode write AGENTS.md with the mode body
462
- inlined (they do not resolve @-import). Each host
459
+ --host HOST Target host key (default: claude, the bundled host).
460
+ Additional hosts (e.g. codex, opencode) are contributed
461
+ by add-on SkillSets installed under .kairos/skillsets/
462
+ and discovered from the host-profile registry. Each host
463
463
  uses a separate manifest slot, so hosts can coexist.
464
+ claude writes CLAUDE.md with an @-import pointer; hosts
465
+ that do not resolve @-import receive the mode body
466
+ inlined into their context file (e.g. AGENTS.md).
464
467
 
465
468
  Notes:
466
469
  - data_dir and consumer project root are decoupled (design v0.2,
@@ -495,13 +498,14 @@ when 'mode'
495
498
  ARGV.delete_at(idx)
496
499
  end
497
500
 
498
- # 2026-07-02: target host for projection (claude | codex | opencode). Default claude.
499
- # codex/opencode write AGENTS.md with the mode body inlined (they do not resolve @-import).
501
+ # 2026-07-02 (redesigned 2026-07-10): target host for projection. The bundled
502
+ # default is claude; additional hosts come from add-on SkillSets via the
503
+ # host-profile registry (design v0.3 FROZEN).
500
504
  mode_host = 'claude'
501
505
  if (idx = ARGV.index('--host'))
502
506
  mode_host = ARGV[idx + 1]
503
507
  if mode_host.nil? || mode_host.start_with?('--')
504
- warn "ERROR: --host requires a value (claude, codex, or opencode)."
508
+ warn 'ERROR: --host requires a value (a registered host key, e.g. claude).'
505
509
  exit 1
506
510
  end
507
511
  ARGV.delete_at(idx + 1)
@@ -530,8 +534,8 @@ when 'mode'
530
534
  warn " Use --project-root <path> to designate a directory distinct from the data directory."
531
535
  exit 1
532
536
  rescue ArgumentError => e
537
+ # The registry error already lists the registered hosts and the add-on hint.
533
538
  warn "ERROR: #{e.message}"
534
- warn " Valid --host values: claude, codex, opencode."
535
539
  exit 1
536
540
  end
537
541
 
@@ -15,16 +15,32 @@ require_relative '../lib/kairos_mcp'
15
15
  require_relative '../lib/kairos_mcp/plugin_projector'
16
16
  require_relative '../lib/kairos_mcp/skillset_manager'
17
17
 
18
+ # Honor --data-dir before resolving anything: add-on host discovery reads the
19
+ # data dir, so a decoupled data_dir must reach the projector on this path too
20
+ # (INV-H3 — all access paths share one registry).
21
+ if (idx = ARGV.index('--data-dir'))
22
+ val = ARGV[idx + 1]
23
+ if val.nil? || val.start_with?('--')
24
+ warn 'ERROR: --data-dir requires a path value.'
25
+ exit 1
26
+ end
27
+ KairosMcp.data_dir = File.expand_path(val)
28
+ ARGV.delete_at(idx + 1)
29
+ ARGV.delete_at(idx)
30
+ end
31
+
18
32
  project_root = KairosMcp.project_root
19
33
  mode = KairosMcp.projection_mode
20
34
 
21
- # 2026-07-02: target host for projection (claude | codex | opencode). Default claude.
35
+ # 2026-07-02 (redesigned 2026-07-10): target host for projection. The bundled
36
+ # default is claude; additional hosts are contributed by add-on SkillSets and
37
+ # discovered from the host-profile registry (design v0.3 FROZEN).
22
38
  # Used both for manual invocation and by projected re-projection hooks (--host <host>).
23
39
  host = 'claude'
24
40
  if (idx = ARGV.index('--host'))
25
41
  host = ARGV[idx + 1]
26
42
  if host.nil? || host.start_with?('--')
27
- warn "ERROR: --host requires a value (claude, codex, or opencode)."
43
+ warn 'ERROR: --host requires a value (a registered host key, e.g. claude).'
28
44
  exit 1
29
45
  end
30
46
  ARGV.delete_at(idx + 1)
@@ -32,10 +48,13 @@ if (idx = ARGV.index('--host'))
32
48
  end
33
49
 
34
50
  begin
35
- projector = KairosMcp::PluginProjector.new(project_root, mode: mode, host: host)
36
- rescue ArgumentError => e
51
+ # Pass data_dir explicitly so add-on discovery + manifest location match the
52
+ # other access paths (MCP tool, `kairos-chain mode`) under decoupled data dirs.
53
+ projector = KairosMcp::PluginProjector.new(project_root, mode: mode,
54
+ data_dir: KairosMcp.data_dir, host: host)
55
+ rescue ArgumentError, KairosMcp::PluginProjector::DependencyUnsatisfied => e
56
+ # The registry error already lists the registered hosts and the add-on hint.
37
57
  warn "ERROR: #{e.message}"
38
- warn " Valid --host values: claude, codex, opencode."
39
58
  exit 1
40
59
  end
41
60
 
@@ -57,21 +76,27 @@ enabled = manager.enabled_skillsets
57
76
  knowledge_entries = KairosMcp.collect_knowledge_entries
58
77
 
59
78
  json_mode = ARGV.include?('--json')
79
+ # Host-specific reload hint carried as profile data, not a host-name branch (INV-H1).
80
+ reload_hint = projector.host.reload_hint || ''
60
81
 
61
82
  if ARGV.include?('--if-changed')
62
83
  changed = projector.project_if_changed!(enabled, knowledge_entries: knowledge_entries)
63
84
  if changed
85
+ msg = "Plugin projection updated.#{reload_hint}"
64
86
  if json_mode
65
- puts '{"additionalContext": "Plugin projection updated. Run /reload-plugins to activate new skills."}'
87
+ require 'json'
88
+ puts JSON.generate('additionalContext' => msg)
66
89
  else
67
- $stderr.puts "Plugin projection updated. Run /reload-plugins to activate new skills."
90
+ $stderr.puts msg
68
91
  end
69
92
  end
70
93
  else
71
94
  projector.project!(enabled, knowledge_entries: knowledge_entries)
95
+ msg = "Plugin projection complete.#{reload_hint}"
72
96
  if json_mode
73
- puts '{"additionalContext": "Plugin projection complete. Run /reload-plugins to activate."}'
97
+ require 'json'
98
+ puts JSON.generate('additionalContext' => msg)
74
99
  else
75
- $stderr.puts "Plugin projection complete."
100
+ $stderr.puts msg
76
101
  end
77
102
  end