kairos-chain 3.53.0 → 3.55.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.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +217 -0
  3. data/lib/kairos_mcp/knowledge_provider.rb +70 -8
  4. data/lib/kairos_mcp/version.rb +1 -1
  5. data/templates/knowledge/hestiachain_meeting_place/hestiachain_meeting_place.md +34 -0
  6. data/templates/knowledge/instance_session_protocol/instance_session_protocol.md +155 -0
  7. data/templates/knowledge/kairoschain_development_pitfalls/kairoschain_development_pitfalls.md +179 -0
  8. data/templates/knowledge/multi_llm_review_workflow/multi_llm_review_workflow.md +296 -54
  9. data/templates/skillsets/hestia/skillset.json +1 -1
  10. data/templates/skillsets/llm_client/config/llm_client.yml +6 -3
  11. data/templates/skillsets/llm_client/lib/llm_client/claude_code_adapter.rb +11 -2
  12. data/templates/skillsets/multi_llm_review/bin/dispatch_worker.rb +2 -10
  13. data/templates/skillsets/multi_llm_review/config/multi_llm_review.yml +98 -32
  14. data/templates/skillsets/multi_llm_review/lib/multi_llm_review/build_review_bundle.rb +7 -1
  15. data/templates/skillsets/multi_llm_review/lib/multi_llm_review/consensus.rb +226 -13
  16. data/templates/skillsets/multi_llm_review/lib/multi_llm_review/dispatcher.rb +26 -3
  17. data/templates/skillsets/multi_llm_review/lib/multi_llm_review/observer_set.rb +236 -0
  18. data/templates/skillsets/multi_llm_review/lib/multi_llm_review/persona_assembly.rb +48 -2
  19. data/templates/skillsets/multi_llm_review/lib/multi_llm_review/review_serializer.rb +59 -0
  20. data/templates/skillsets/multi_llm_review/skillset.json +2 -2
  21. data/templates/skillsets/multi_llm_review/test/test_multi_llm_review.rb +69 -120
  22. data/templates/skillsets/multi_llm_review/test/test_multi_llm_review_bundle.rb +18 -8
  23. data/templates/skillsets/multi_llm_review/test/test_observer_set.rb +412 -0
  24. data/templates/skillsets/multi_llm_review/test/test_observer_set_seams.rb +585 -0
  25. data/templates/skillsets/multi_llm_review/test/test_tool_wiring.rb +599 -0
  26. data/templates/skillsets/multi_llm_review/tools/multi_llm_review.rb +228 -92
  27. data/templates/skillsets/multi_llm_review/tools/multi_llm_review_bundle.rb +42 -11
  28. data/templates/skillsets/multi_llm_review/tools/multi_llm_review_collect.rb +41 -13
  29. data/templates/skillsets/project_manager/config/pm.yml +11 -0
  30. data/templates/skillsets/project_manager/knowledge/project_manager_guide/project_manager_guide.md +41 -0
  31. data/templates/skillsets/project_manager/lib/project_manager/digest.rb +83 -0
  32. data/templates/skillsets/project_manager/lib/project_manager/store.rb +204 -0
  33. data/templates/skillsets/project_manager/lib/project_manager/tool_helpers.rb +22 -0
  34. data/templates/skillsets/project_manager/lib/project_manager.rb +17 -0
  35. data/templates/skillsets/project_manager/plugin/SKILL.md +71 -0
  36. data/templates/skillsets/project_manager/plugin/agents/secretary.md +227 -0
  37. data/templates/skillsets/project_manager/scripts/l2_scan.py +284 -0
  38. data/templates/skillsets/project_manager/skillset.json +37 -0
  39. data/templates/skillsets/project_manager/test/test_project_manager.rb +211 -0
  40. data/templates/skillsets/project_manager/tools/pm_digest.rb +58 -0
  41. data/templates/skillsets/project_manager/tools/pm_item.rb +121 -0
  42. data/templates/skillsets/project_manager/tools/pm_project.rb +75 -0
  43. data/templates/skillsets/project_manager/tools/pm_query.rb +64 -0
  44. data/templates/skillsets/project_manager/tools/pm_record.rb +127 -0
  45. metadata +24 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 31e74313d89bf76d795f74dd21f641fd702a1c186cec186f7425b8af53d2e012
4
- data.tar.gz: 0f325ce8ac8876685f7aa266fabf539e228e8fe5b57cfbfc5b6a395d82a8290c
3
+ metadata.gz: 2291c491a077a0cfdce3d77bdd3709e8e6278fc9eb656a02f3de5508e4f66580
4
+ data.tar.gz: 96fa06b0195df3167b3113c54125a093f31f4bed10955c044a2ef218fe6d9278
5
5
  SHA512:
6
- metadata.gz: 98f7d0763ee115a0380028deedc06a12a022fad0bfec85b89529527b15763cea236ef16a7ec3304ee3f0b6aa8f381f04f71f0cbd1c4ff425c9f76b77598ed2af
7
- data.tar.gz: 7ca21d4ec532094e1b0fd0048ba4d8e1acd5bf0f3e4d35473d36ad751ca6f37b93e9ecb447e681be5a2ecf86694cefb7a7bd8ebce8068c43a0d64b70a797ff5d
6
+ metadata.gz: 72064bd0e1bde0516e8dd2b90adcbb9a85f3d079f71507b9f77210985e2f995fc9a1e8af066eee19835dda664a707f09ae8f6420ecfb6135dec62aa92449b756
7
+ data.tar.gz: 2553da41e8590b33c49f8e0d3526d37ac80bc8f742bab79af45cb5798c7a425ad978e66099a47454f9ca1ade3cbce310a798b7a9d1400eedac7a781d3cfdd745
data/CHANGELOG.md CHANGED
@@ -4,6 +4,223 @@ 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.55.0] - 2026-07-27
8
+
9
+ ### Added
10
+
11
+ - **`project_manager` SkillSet now ships with the gem** (v0.2.0). Previously
12
+ instance-local. Registers projects and work items, answers queries, produces a
13
+ session-start digest with derived dormancy, and records irreversible project
14
+ actions on the attestation chain. Ships a secretary-persona sub-agent under
15
+ `plugin/agents`, so the secretarial disposition runs in its own context under
16
+ any instruction mode rather than replacing the active one.
17
+ - **`scripts/l2_scan.py`** — read-only derivation of activity evidence from the
18
+ L2 context store. Reports, per work item, first and last activity, distinct
19
+ records, distinct active days, the interval against the memo's own marker, and
20
+ the most recent nearby record by name. It matches on a document's name, saved
21
+ path and tags — never its body, which measured roughly 25% precision — and it
22
+ claims no attribution: tags name subjects while items name work that remains,
23
+ so one record sits correctly under several items and the output is evidence for
24
+ the operator to judge. Writes nothing.
25
+
26
+ ### Notes
27
+
28
+ - The operator's own data (the work-item store and the item-to-record mapping)
29
+ stays instance-local under `.kairos/pm/` and is not part of the package.
30
+ - Designs: `docs/drafts/project_manager_plugin_projection_draft_v0.7_FROZEN.md`
31
+ (sub-agent and confinement) and
32
+ `docs/drafts/project_manager_l2_derivation_draft_v0.12.md` (derivation).
33
+ Both state that the SkillSet stays instance-local; that is superseded by this
34
+ release on the operator's decision.
35
+
36
+ ## [3.54.3] - 2026-07-27
37
+
38
+ ### multi_llm_review SkillSet 0.5.2 — the cursor reviewer pins its model
39
+
40
+ The cursor roster entry carried no `model` key, so `cursor_adapter` omitted
41
+ `--model` and the reviewer ran on whatever the cursor CLI had as its default. That
42
+ default lives in `~/.cursor/cli-config.json`, is operator-editable from the
43
+ interactive Cursor client, and had been set to `claude-opus-4-8`.
44
+
45
+ The roster was therefore dispatching three Anthropic slots out of five — the
46
+ orchestrator's own persona team, Opus 4.6 via `claude -p`, and this entry — while
47
+ still labelling this one `cursor_composer2.5`. Both properties the roster exists for
48
+ were lost at once: provider diversity, which is the reason a five-model roster is
49
+ worth its cost, and the correspondence between a recorded `role_label` and the model
50
+ that actually answered, without which per-reviewer calibration accumulates against
51
+ the wrong name. Neither failure is visible from the review output.
52
+
53
+ The entry now names `composer-2.5` explicitly, which makes the roster independent of
54
+ a setting that is not part of this repository. The comment above it records why the
55
+ key is there, so a future edit does not remove it as redundant.
56
+
57
+ Config files stay operator-owned: an instance whose roster is untouched picks the
58
+ pinned model up on upgrade, and an instance that has already tuned its roster keeps
59
+ its own and should apply the same pin by hand.
60
+
61
+ - **`templates/skillsets/multi_llm_review/config/multi_llm_review.yml`**: cursor entry gains `model: composer-2.5`.
62
+ - **`templates/skillsets/multi_llm_review/skillset.json`**: 0.5.1 → 0.5.2.
63
+
64
+ ## [3.54.2] - 2026-07-27
65
+
66
+ ### multi_llm_review SkillSet 0.5.1 — so 3.54.1's changes actually propagate
67
+
68
+ 3.54.1 shipped the roster change without bumping the SkillSet's own version, and
69
+ `skillset upgrade` is gated strictly on `Gem::Version` comparison. An existing
70
+ instance therefore reported `[UNCHANGED] multi_llm_review v0.5.0` and kept its
71
+ `lib/` and `tools/` as they were — the shipped changes reached the gem and stopped
72
+ there.
73
+
74
+ Two things were stranded by that. The `orchestrator_model` description is the one
75
+ that matters: it now states that the identifier must be passed as a bare ID with a
76
+ context suffix such as `[1m]` stripped, because the roster comparison rejects the
77
+ suffixed form and the caller then dispatches a subprocess against itself. That is
78
+ a behavioural instruction an orchestrating model reads at call time, not a comment.
79
+ The dispatcher's per-reviewer effort comment was stranded with it.
80
+
81
+ Nothing about the fix is new content; this release exists so the previous one is
82
+ deliverable. Config files stay operator-owned and are not replaced, so an instance
83
+ that has already tuned its roster keeps it across the upgrade.
84
+
85
+ - **`templates/skillsets/multi_llm_review/skillset.json`**: 0.5.0 → 0.5.1.
86
+
87
+ Lesson recorded for future SkillSet edits: bumping the gem version is not enough.
88
+ A change under `templates/skillsets/<name>/` reaches an existing instance only if
89
+ that SkillSet's own `version` also moves.
90
+
91
+ ## [3.54.1] - 2026-07-27
92
+
93
+ ### Fable 5 retired from the multi-LLM review roster
94
+
95
+ Five consecutive rounds returned nothing substantive from that slot: 85 to 128
96
+ characters in 5 to 7 seconds, each an opening sentence with no findings and no
97
+ verdict text. A slot that does not produce a review still counts toward the
98
+ denominator, so it lowered the achievable numerator without contributing signal —
99
+ with six configured reviewers and one permanently silent, `4/6` could not be
100
+ reached even when every working reviewer approved.
101
+
102
+ The roster is now five and the convergence rule is `3/5` (`3/4` after
103
+ orchestrator exclusion), keeping the same `ceil(N * 0.6)` majority basis. One
104
+ consequence is worth stating: with Opus 5 as orchestrator its own slot is
105
+ delegated to the persona team, so the Claude CLI side is Opus 4.6 alone.
106
+
107
+ Restoring the entry is a config edit plus widening the rule back to a six-reviewer
108
+ basis; the retirement rationale is recorded inline where the roster lives.
109
+
110
+ - **`templates/skillsets/multi_llm_review/config/multi_llm_review.yml`**: entry
111
+ removed, `convergence_rule` and `convergence_rule_after_exclusion` adjusted,
112
+ roster header and the orchestrator-exclusion example updated.
113
+ - **`templates/knowledge/multi_llm_review_workflow/`**: identifier list, retirement
114
+ history, and the two-frontier-entry rationale corrected.
115
+
116
+ Note for operators of an existing instance: `config/` files are operator-owned and
117
+ are not replaced on upgrade, so an instance that already ran the six-reviewer
118
+ roster keeps it until the config is edited by hand.
119
+
120
+ ## [3.54.0] - 2026-07-26
121
+
122
+ ### SkillSet-declared knowledge becomes reachable
123
+
124
+ `knowledge_dirs` in `skillset.json` was a declaration nothing read. Knowledge
125
+ bundled with a SkillSet was therefore write-only: present on disk, declared in
126
+ the manifest, and unreachable by name. Two independent causes, either sufficient
127
+ on its own — no core path consumed the field, and `add_external_dir` mutates a
128
+ single provider instance during SkillSet load while `knowledge_get` builds a
129
+ fresh provider per call, discarding the registration.
130
+
131
+ Resolution moved from imperative load-time mutation to declarative manifest
132
+ reading, which puts `knowledge_dirs` on the same footing as `tool_classes` and
133
+ `config_files`: the manifest is what governs. On a representative instance this
134
+ takes SkillSet-derived L1 entries from 0 to 23 across 16 SkillSets.
135
+
136
+ - **`lib/kairos_mcp/knowledge_provider.rb`**: `#initialize` now registers the
137
+ knowledge directories of every *enabled* SkillSet. Opt out with
138
+ `include_skillset_knowledge: false` for a provider scoped strictly to the main
139
+ knowledge dir.
140
+ - **`add_external_dir` gains `only:`**. The method takes a *container* of
141
+ entries, while `knowledge_dirs` declares *entry* directories; declared entries
142
+ are grouped by container and passed as `only:`. Without it, registering the
143
+ container would expose undeclared siblings — proximity on disk would become a
144
+ declaration. Knowledge a SkillSet ships without declaring stays invisible.
145
+ - **`add_external_dir` is idempotent** by absolute path, so the five SkillSets
146
+ that also register themselves do not produce duplicate `list` entries.
147
+ - **Failure is isolated**: a malformed `skillset.json` degrades to "no SkillSet
148
+ knowledge" with a warning on stderr, never to a broken knowledge layer.
149
+ - **`templates/skillsets/hestia/skillset.json`**: declares
150
+ `knowledge/hestia_chain_migration`, which shipped undeclared since its
151
+ introduction — the only declared-vs-actual mismatch across all SkillSets, and
152
+ how the undeclared-knowledge case was found.
153
+ - **`test_skillset_knowledge_registration.rb`** (new, 15 assertions): retrieval
154
+ by name, `list` source/layer tagging, disabled SkillSets contributing nothing,
155
+ opt-out, idempotency, undeclared siblings staying invisible, and survival of a
156
+ malformed manifest.
157
+
158
+ ### New L1 knowledge
159
+
160
+ - **`kairoschain_development_pitfalls`**: failure modes that cannot be inferred
161
+ from reading the code being touched — the gem ships only `templates/`, so
162
+ entries under the dev-repo `knowledge/` reach nobody; `.kairos/` resolves
163
+ against the current working directory and silently creates a second data
164
+ directory on a wrong resolution; declared-but-undeclared knowledge; a truthy
165
+ return that is not a success (`PlaceRouter#authenticate!`); and an observed but
166
+ unexplained `instructions_mode` revert after upgrade.
167
+ - **`instance_session_protocol`**: the procedural half of an instance's operating
168
+ discipline — session-start calls, layer-state surfacing, continuity, knowledge
169
+ baseline, during-work and session-end tool discipline. Extracted from the
170
+ `masa` instruction mode so norms stay in the mode and the runbook loads on
171
+ demand. Contains no normative content.
172
+ - **`hestiachain_meeting_place`** gains § Interaction Policy: the outbound
173
+ redaction / inbound review / per-operation gate checklist, likewise extracted
174
+ from instruction-mode text.
175
+
176
+ ## [3.53.1] - 2026-07-25
177
+
178
+ ### Multi-LLM Review — Opus 5 enters the roster, Opus 4.8 retires (v3.6.2)
179
+
180
+ Both frontier Claude models (Opus 5, Fable 5) now sit in the reviewer roster at
181
+ once. This is not redundancy: whichever one is the session orchestrator matches
182
+ `orchestrator_model` and is taken by the default `delegate` strategy as the
183
+ persona-team slot, so the other is dispatched as a `claude -p` subprocess. The
184
+ Claude side therefore resolves to "orchestrator persona + other frontier model
185
+ via CLI + Opus 4.6 via CLI" under either orchestrator, with no per-orchestrator
186
+ configuration branch and no dispatcher change.
187
+
188
+ Opus 4.8 retires by the same succession logic that retired 4.7 in 3.51.2 (the
189
+ strictness / systematizing register passes to the direct successor). Roster size
190
+ stays 6, so `convergence_rule` (4/6) and `convergence_rule_after_exclusion`
191
+ (3/5) are unchanged.
192
+
193
+ - **`templates/skillsets/multi_llm_review/config/multi_llm_review.yml`**: roster
194
+ is now `claude-opus-5`, `claude-fable-5`, `claude-opus-4-6`, `gpt-5.6-sol`,
195
+ `gpt-5.5`, cursor default. The two frontier entries carry CLI-neutral
196
+ `role_label`s (`claude_cli_opus5`, `claude_cli_fable5`) because either can
197
+ take either path; the delegated one is relabelled `claude_team_<model>` by
198
+ PersonaAssembly at collect.
199
+ - **`templates/skillsets/llm_client/lib/llm_client/claude_code_adapter.rb`**:
200
+ `DEFAULT_MODEL` `claude-opus-4-8` -> `claude-opus-5`. Fallback only — roster
201
+ entries always pass an explicit model; the constant exists so an unspecified
202
+ call cannot be auto-routed to Haiku.
203
+ - **`templates/knowledge/multi_llm_review_workflow/` v3.6.1 -> v3.6.2**: roster,
204
+ CLI matrix, effort table, and orchestrator self-identification section updated
205
+ for the rotating-frontier arrangement.
206
+
207
+ Two corrections folded into the same knowledge revision:
208
+
209
+ - **`--bare` removed from every `claude -p` example.** The flag skips credential
210
+ loading, so the subprocess returns "Not logged in" (established 2026-07-23)
211
+ while the knowledge entry still mandated it. Project-instruction bias is
212
+ suppressed by `review_context: independent` instead.
213
+ - **`orchestrator_model` must be the bare model ID.** Opus 5 reports itself as
214
+ `claude-opus-5[1m]`; the roster compares by exact string and PersonaAssembly's
215
+ validator rejects `[`, so passing the raw self-report silently defeats
216
+ self-exclusion and lets the orchestrator review its own output.
217
+
218
+ Opus 5's reviewer bias profile is uncalibrated — record (a)/(b)/(c) breakdowns
219
+ per round in `multi_llm_reviewer_evaluation` until a profile accumulates.
220
+
221
+ No dispatcher, tool, or schema changes. Existing suite green (multi_llm_review
222
+ skillset tests: 249 runs, 0 failures).
223
+
7
224
  ## [3.53.0] - 2026-07-24
8
225
 
9
226
  ### SkillSet Web Catalog — anonymous public presentation surface for SkillSet deposits
@@ -4,6 +4,7 @@ require 'digest'
4
4
  require 'fileutils'
5
5
  require 'yaml'
6
6
  require_relative 'anthropic_skill_parser'
7
+ require_relative 'skillset_manager'
7
8
  require_relative 'kairos_chain/chain'
8
9
  require_relative 'vector_search/provider'
9
10
  require_relative '../kairos_mcp'
@@ -39,7 +40,11 @@ module KairosMcp
39
40
  # @param knowledge_dir [String] Path to knowledge directory
40
41
  # @param vector_search_enabled [Boolean] Enable vector search
41
42
  # @param storage_backend [Storage::Backend, nil] Storage backend to use
42
- def initialize(knowledge_dir = nil, vector_search_enabled: true, storage_backend: nil, user_context: nil)
43
+ # @param include_skillset_knowledge [Boolean] Register knowledge dirs declared
44
+ # by enabled SkillSets. Default true; pass false to build a provider scoped
45
+ # strictly to the main knowledge dir.
46
+ def initialize(knowledge_dir = nil, vector_search_enabled: true, storage_backend: nil,
47
+ user_context: nil, include_skillset_knowledge: true)
43
48
  knowledge_dir ||= KairosMcp.knowledge_dir(user_context: user_context)
44
49
  @knowledge_dir = knowledge_dir
45
50
  @user_context = user_context
@@ -49,19 +54,34 @@ module KairosMcp
49
54
  @index_built = false
50
55
  @external_dirs = []
51
56
  FileUtils.mkdir_p(@knowledge_dir)
57
+ register_skillset_knowledge_dirs if include_skillset_knowledge
52
58
  end
53
59
 
54
60
  # Register an external knowledge directory (e.g. from a SkillSet)
55
61
  # Knowledge is read-only from external dirs; no merge into the main dir.
56
62
  #
57
- # @param dir [String] Absolute path to the knowledge directory
63
+ # @param dir [String] Absolute path to the container directory holding entry
64
+ # subdirectories (e.g. `<skillset>/knowledge`), not an entry directory itself
58
65
  # @param source [String] Identifier for the source (e.g. "skillset:mmp")
59
66
  # @param layer [Symbol] Layer governance (:L0, :L1, :L2)
60
67
  # @param index [Boolean] Whether to include in vector search index
61
- def add_external_dir(dir, source:, layer: :L1, index: true)
68
+ # @param only [Array<String>, nil] Entry names to expose. nil exposes every
69
+ # subdirectory. Passing the declared set keeps undeclared knowledge shipped
70
+ # inside a SkillSet from becoming visible as L1 by proximity alone.
71
+ #
72
+ # Idempotent by directory: registering the same dir twice (e.g. once from the
73
+ # SkillSet manifest at construction, once from a SkillSet that also registers
74
+ # itself) keeps the first registration rather than duplicating list entries.
75
+ def add_external_dir(dir, source:, layer: :L1, index: true, only: nil)
62
76
  return unless File.directory?(dir)
63
77
 
64
- @external_dirs << { dir: dir, source: source, layer: layer, index: index }
78
+ absolute = File.expand_path(dir)
79
+ return if @external_dirs.any? { |ext| ext[:dir] == absolute }
80
+
81
+ @external_dirs << {
82
+ dir: absolute, source: source, layer: layer, index: index,
83
+ only: only && Array(only).map { |n| File.basename(n.to_s) }
84
+ }
65
85
  @index_built = false if index # Invalidate index when new indexed dir added
66
86
  end
67
87
 
@@ -92,7 +112,7 @@ module KairosMcp
92
112
 
93
113
  # Include knowledge from external directories (SkillSets)
94
114
  @external_dirs.each do |ext|
95
- external_skill_dirs(ext[:dir]).each do |dir|
115
+ external_skill_dirs(ext[:dir], only: ext[:only]).each do |dir|
96
116
  skill = AnthropicSkillParser.parse(dir)
97
117
  next unless skill
98
118
 
@@ -124,6 +144,8 @@ module KairosMcp
124
144
 
125
145
  # Search external directories
126
146
  @external_dirs.each do |ext|
147
+ next if ext[:only] && !ext[:only].include?(name)
148
+
127
149
  ext_skill_dir = File.join(ext[:dir], name)
128
150
  return AnthropicSkillParser.parse(ext_skill_dir) if File.directory?(ext_skill_dir)
129
151
  end
@@ -327,7 +349,7 @@ module KairosMcp
327
349
 
328
350
  # Include external dirs that have indexing enabled
329
351
  @external_dirs.select { |ext| ext[:index] }.each do |ext|
330
- external_skill_dirs(ext[:dir]).each do |dir|
352
+ external_skill_dirs(ext[:dir], only: ext[:only]).each do |dir|
331
353
  skill = AnthropicSkillParser.parse(dir)
332
354
  next unless skill
333
355
 
@@ -523,6 +545,43 @@ module KairosMcp
523
545
 
524
546
  private
525
547
 
548
+ # Register the knowledge directories declared by every enabled SkillSet.
549
+ #
550
+ # `knowledge_dirs` in skillset.json is the single declaration of what a
551
+ # SkillSet contributes to L1. Resolving it here — instead of relying on each
552
+ # SkillSet to register itself during load! — keeps the declaration
553
+ # load-bearing for every provider instance, including the short-lived ones
554
+ # tools build per call. Without this, knowledge bundled with a SkillSet is
555
+ # write-only: present on disk, declared in the manifest, and unreachable by
556
+ # name.
557
+ #
558
+ # `knowledge_dirs` declares individual entry directories, while an external
559
+ # registration covers a container of entries. Declared entries are therefore
560
+ # grouped by their container and exposed via `only:`, so that knowledge a
561
+ # SkillSet ships but does not declare stays invisible — proximity on disk is
562
+ # not a declaration.
563
+ #
564
+ # Failure is isolated per SkillSet and overall: a malformed manifest or an
565
+ # unreadable directory degrades to "that SkillSet contributes no knowledge",
566
+ # never to a broken knowledge layer.
567
+ def register_skillset_knowledge_dirs
568
+ manager = SkillSetManager.new
569
+
570
+ manager.enabled_skillsets.each do |skillset|
571
+ skillset.knowledge_dirs.group_by { |dir| File.dirname(dir) }.each do |container, entries|
572
+ add_external_dir(container,
573
+ source: "skillset:#{skillset.name}",
574
+ layer: skillset.layer,
575
+ index: skillset.index_knowledge?,
576
+ only: entries.map { |e| File.basename(e) })
577
+ end
578
+ rescue StandardError => e
579
+ warn "[KnowledgeProvider] Skipped knowledge dirs for SkillSet '#{skillset.name}': #{e.message}"
580
+ end
581
+ rescue StandardError => e
582
+ warn "[KnowledgeProvider] SkillSet knowledge registration skipped: #{e.message}"
583
+ end
584
+
526
585
  def vector_search
527
586
  @vector_search ||= VectorSearch.create(index_path: KairosMcp.knowledge_index_path)
528
587
  end
@@ -609,10 +668,13 @@ module KairosMcp
609
668
  end
610
669
 
611
670
  # List subdirectories in an external knowledge dir
612
- def external_skill_dirs(dir)
671
+ def external_skill_dirs(dir, only: nil)
613
672
  return [] unless File.directory?(dir)
614
673
 
615
- Dir[File.join(dir, '*')].select { |f| File.directory?(f) && !backup_dir?(f) }
674
+ dirs = Dir[File.join(dir, '*')].select { |f| File.directory?(f) && !backup_dir?(f) }
675
+ return dirs unless only
676
+
677
+ dirs.select { |f| only.include?(File.basename(f)) }
616
678
  end
617
679
 
618
680
  # Detect upgrade backup directories (`.bak.<timestamp>`, `<name>.bak.<timestamp>`).
@@ -1,4 +1,4 @@
1
1
  module KairosMcp
2
- VERSION = "3.53.0"
2
+ VERSION = "3.55.0"
3
3
  CHANGELOG_URL = "https://github.com/masaomi/KairosChain_2026/blob/main/CHANGELOG.md"
4
4
  end
@@ -167,3 +167,37 @@ kairos.example.com {
167
167
  ```
168
168
 
169
169
  For detailed DEE protocol internals, install the hestia SkillSet and refer to its bundled knowledge (`hestia_meeting_place`).
170
+
171
+ ### Interaction Policy (instance discipline)
172
+
173
+ The procedural checklist an instance follows when interacting with a Meeting
174
+ Place. This is the *how*; whether an instance defaults to openness or to caution
175
+ is a matter for its instruction mode, and a mode that sets a different default
176
+ overrides the outbound bias below without changing the rest.
177
+
178
+ **Outbound (publishing, depositing, sharing)**
179
+
180
+ - Include provenance, version, applicable domain, and intended framing with
181
+ anything shared.
182
+ - Redact user-specific paths, credentials, and institutional details before they
183
+ leave the instance.
184
+ - Never share an L2 session context without explicit operator approval.
185
+ - Flag foreseeable misuse vectors at the moment of sharing, proactively.
186
+
187
+ **Inbound (browsing, acquiring, receiving)**
188
+
189
+ - Treat an external skill as untrusted until reviewed.
190
+ - Review before rejecting: unfamiliar is not the same as unsound.
191
+ - No auto-adoption, and no automatic execution of received code.
192
+
193
+ **Trust boundaries by operation**
194
+
195
+ | Operation | Gate |
196
+ |---|---|
197
+ | Browse, register | low risk — proceed |
198
+ | Deposit, acquire | explicit operator approval |
199
+ | Knowledge-needs publication | explicit opt-in |
200
+
201
+ The asymmetry is deliberate: reading the board changes nothing, while depositing
202
+ publishes to a service where content may be cached or indexed regardless of later
203
+ withdrawal.
@@ -0,0 +1,155 @@
1
+ ---
2
+ title: Instance Session Protocol
3
+ description: Procedural runbook for an instance's session lifecycle — mandatory session-start tool calls, layer-state surfacing, continuity check, knowledge-gap baseline, during-work tool discipline, and session-end handoff. Retrieved on demand by an instruction mode; contains no normative content.
4
+ version: "0.1.0"
5
+ tags:
6
+ - session
7
+ - runbook
8
+ - layer_awareness
9
+ - tool_usage
10
+ - continuity
11
+ ---
12
+
13
+ # Instance Session Protocol
14
+
15
+ ## What this is
16
+
17
+ The procedural half of an instance's operating discipline: *what to call, in what
18
+ order, and what to report*. It was extracted from the `masa` instruction mode so
19
+ that the mode carries only norms and this runbook loads on demand.
20
+
21
+ **This entry contains no norms.** Why an instance should establish ground state,
22
+ what it owes the operator in disclosure, and how it weighs speed against
23
+ deliberation all remain in the active instruction mode. If the two ever conflict,
24
+ the mode wins and this runbook is the thing that gets revised.
25
+
26
+ An instruction mode adopts this protocol by referring to it. A mode that wants a
27
+ different lifecycle should write its own runbook rather than edit this one.
28
+
29
+ ---
30
+
31
+ ## 1. Session start
32
+
33
+ Execute proactively, before responding to the operator's first task. The goal is
34
+ shared ground state, not a diagnostic dump: **report in 4–6 lines total, naming
35
+ issues only if found.**
36
+
37
+ ### 1.1 Required tool calls
38
+
39
+ 1. `chain_status()` — verify system health: blockchain integrity, layer counts,
40
+ last known good state.
41
+ 2. `resource_read(uri: "l0://kairos.md")` — load the propositions into working
42
+ context. They ground every other decision in the session.
43
+ 3. `knowledge_get(name: "kairoschain_self_development")` — load the development
44
+ workflow, when the session works on KairosChain itself.
45
+ 4. `skills_audit(command: "check", layer: "L1")` — verify knowledge-layer health
46
+ and surface drift.
47
+
48
+ **Why step 4 is scoped to L1 deliberately**: L2 contexts are a growing record, so
49
+ age is their normal condition rather than a defect. An unscoped audit reports
50
+ every context older than 14 days as an issue, and the response outgrows the tool's
51
+ own output limit. When L2 needs attention, ask a *state* question — which handoffs
52
+ are still `pending`? — not an age question.
53
+
54
+ ### 1.2 Layer state surface
55
+
56
+ After the calls, surface the operational layer state in 3–5 lines:
57
+
58
+ - Which host features are active this session (hooks, permissions, plugin
59
+ projection, Skill tool, MCP transport).
60
+ - Which MCP server is connected, and its version.
61
+ - How plugin projection has mapped SkillSets to host artefacts — digest from
62
+ `projection_manifest.json`.
63
+ - Any layer-specific constraint in effect: read-only mode, dry-run mode,
64
+ suspended skills.
65
+
66
+ Supplying this is the harness's job, not something the model can obtain by
67
+ introspection. An agent cannot reliably determine which layer it is operating in
68
+ from the inside; the surface exists so that boundary crossings become reasoned
69
+ rather than accidental.
70
+
71
+ ### 1.3 Continuity
72
+
73
+ If recent L2 contexts indicate work this session might continue — handoffs tagged
74
+ `pending`, unresolved revision candidates, paused review cycles — name them
75
+ briefly and offer to resume. **Do not auto-resume.**
76
+
77
+ ### 1.4 Knowledge-gap baseline
78
+
79
+ Check the baseline entries in § 3 against what the instance actually has. Report
80
+ gaps only when they bear on the current task.
81
+
82
+ ### 1.5 Failure mode
83
+
84
+ If any required call fails, surface the failure immediately and pause
85
+ non-essential work. A session whose ground state cannot be confirmed must not
86
+ proceed to autonomous tasks. (Autonomous behaviour lives in dedicated SkillSets
87
+ and is out of scope here.)
88
+
89
+ ---
90
+
91
+ ## 2. During work and at session end
92
+
93
+ Treat KairosChain tools as primary working memory: retrieve before generating.
94
+
95
+ ### 2.1 During work
96
+
97
+ - **Before answering**: check L1 for a relevant convention. When one applies, say
98
+ so — "applying your saved convention X here" — rather than applying it silently.
99
+ - **Multi-LLM review**: follow `multi_llm_review_workflow`.
100
+ - **Design work**: prototype while designing; checkpoint the evolution of the
101
+ design, not only its conclusion.
102
+ - **Steady state**: when system health is good, say so. Do not report only
103
+ problems.
104
+
105
+ ### 2.2 Session end (with operator consent)
106
+
107
+ - Offer `context_save()`.
108
+ - Extract reusable patterns; propose L1 promotion for recurring ones.
109
+ - When the session included design or philosophical work, save the reasoning
110
+ process, not only the conclusion.
111
+
112
+ ### 2.3 Transparency
113
+
114
+ When invoking tools proactively, briefly state what was done and why. Never use a
115
+ tool silently and leave its result unsurfaced.
116
+
117
+ ---
118
+
119
+ ## 3. Knowledge baseline
120
+
121
+ Entries an instance is expected to have available:
122
+
123
+ | Entry | Status |
124
+ |---|---|
125
+ | `multi_llm_review_workflow` | available |
126
+ | `multi_llm_reviewer_evaluation` | available |
127
+ | `design_to_implementation_workflow` | available |
128
+ | `hestiachain_meeting_place` | available |
129
+ | `kairoschain_development_pitfalls` | available |
130
+ | `skillset_implementation_quality_guide` | **not retrievable** — ships only under the dev-repo `knowledge/`, which is absent from the gem |
131
+ | `kairoschain_meta_philosophy` | **not retrievable** — same cause |
132
+
133
+ The two unreachable entries are a known packaging consequence documented in
134
+ `kairoschain_development_pitfalls` § 1. Do not report them as instance-local gaps
135
+ to be authored: the content exists, its distribution path does not. Report them as
136
+ gaps only if a session needs their content, in which case read the file directly
137
+ from the dev repo.
138
+
139
+ `multi_llm_design_review` appears in older mode text as a baseline entry. No such
140
+ entry exists; the correct name is `multi_llm_review_workflow`.
141
+
142
+ ### Behaviour on a genuine gap
143
+
144
+ - Propose creating the missing entry, with a draft outline.
145
+ - Cross-instance, opt-in only: publish knowledge needs via
146
+ `meeting_publish_needs(opt_in: true)`.
147
+
148
+ ---
149
+
150
+ ## Maintenance
151
+
152
+ When a step here stops matching what an instance actually does, change this file
153
+ rather than adding a local exception in the instruction mode. The mode's job is to
154
+ say what the instance owes; this file's job is to say how the instance discharges
155
+ it, and it is expected to churn faster than the mode.