kairos-chain 3.94.0 → 3.96.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 +4 -4
- data/CHANGELOG.md +153 -0
- data/bin/kairos-chain +2 -0
- data/lib/kairos_mcp/capability.rb +20 -4
- data/lib/kairos_mcp/skillset.rb +21 -0
- data/lib/kairos_mcp/skillset_manager.rb +58 -13
- data/lib/kairos_mcp/tools/capability_status.rb +3 -1
- data/lib/kairos_mcp/tools/system_upgrade.rb +2 -0
- data/lib/kairos_mcp/version.rb +1 -1
- data/templates/knowledge/design_to_implementation_workflow/design_to_implementation_workflow.md +4 -1
- data/templates/knowledge/multi_llm_review_workflow/multi_llm_review_workflow.md +155 -31
- data/templates/skillsets/agent/bin/agent_harvest.rb +28 -0
- data/templates/skillsets/agent/bin/agent_policy_report.rb +26 -0
- data/templates/skillsets/agent/config/policies/default_2026_10_20.rb +34 -0
- data/templates/skillsets/agent/hooks/agent_hook.rb +139 -0
- data/templates/skillsets/agent/lib/agent/confinement.rb +107 -239
- data/templates/skillsets/agent/lib/agent/dsl.rb +219 -0
- data/templates/skillsets/agent/lib/agent/guard.rb +799 -0
- data/templates/skillsets/agent/lib/agent/harvest.rb +145 -0
- data/templates/skillsets/agent/lib/agent/hooks.rb +785 -0
- data/templates/skillsets/agent/lib/agent/journal.rb +118 -0
- data/templates/skillsets/agent/lib/agent/policies.rb +153 -0
- data/templates/skillsets/agent/lib/agent/policy_report.rb +665 -0
- data/templates/skillsets/agent/lib/agent/precedents.rb +154 -0
- data/templates/skillsets/agent/lib/agent/review.rb +507 -0
- data/templates/skillsets/agent/lib/agent/run.rb +497 -0
- data/templates/skillsets/agent/lib/agent/service.rb +1661 -0
- data/templates/skillsets/agent/lib/agent/stand_in.rb +274 -0
- data/templates/skillsets/agent/lib/agent/templates.rb +131 -0
- data/templates/skillsets/agent/lib/agent/transcript.rb +134 -0
- data/templates/skillsets/agent/lib/agent.rb +34 -22
- data/templates/skillsets/agent/plugin/SKILL.md +150 -171
- data/templates/skillsets/agent/plugin/hooks.json +94 -0
- data/templates/skillsets/agent/report_kit/KIT_SHA256.txt +5 -0
- data/templates/skillsets/agent/report_kit/check.py +23 -0
- data/templates/skillsets/agent/report_kit/kit.py +364 -0
- data/templates/skillsets/agent/report_kit/make_report_deck.py +159 -0
- data/templates/skillsets/agent/report_kit/render.py +19 -0
- data/templates/skillsets/agent/report_kit/viz.py +203 -0
- data/templates/skillsets/agent/skillset.json +99 -14
- data/templates/skillsets/agent/test/test_agent1_dsl.rb +89 -0
- data/templates/skillsets/agent/test/test_agent1_guard.rb +127 -0
- data/templates/skillsets/agent/test/test_agent1_hooks_service.rb +401 -0
- data/templates/skillsets/agent/test/test_agent1_journal_run.rb +93 -0
- data/templates/skillsets/agent/test/test_agent1_policy_report.rb +475 -0
- data/templates/skillsets/agent/test/test_agent1_r1_check.rb +571 -0
- data/templates/skillsets/agent/test/test_agent1_r1_guard.rb +475 -0
- data/templates/skillsets/agent/test/test_agent1_r1_hookscript.rb +410 -0
- data/templates/skillsets/agent/test/test_agent1_r1_lifecycle.rb +556 -0
- data/templates/skillsets/agent/test/test_agent1_r1_report.rb +588 -0
- data/templates/skillsets/agent/test/test_agent1_r1_review.rb +689 -0
- data/templates/skillsets/agent/test/test_agent1_r1_words.rb +614 -0
- data/templates/skillsets/agent/test/test_agent1_r1b_fixes.rb +258 -0
- data/templates/skillsets/agent/test/test_agent1_r2_guard.rb +565 -0
- data/templates/skillsets/agent/test/test_agent1_r2_words.rb +349 -0
- data/templates/skillsets/agent/test/test_agent1_r2v_checkreview.rb +725 -0
- data/templates/skillsets/agent/test/test_agent1_r2v_decisions.rb +756 -0
- data/templates/skillsets/agent/test/test_agent1_r2v_progress.rb +539 -0
- data/templates/skillsets/agent/test/test_agent1_r2v_sessions.rb +770 -0
- data/templates/skillsets/agent/test/test_agent1_r3_guard.rb +354 -0
- data/templates/skillsets/agent/test/test_agent1_r3_words.rb +367 -0
- data/templates/skillsets/agent/test/test_agent1_r3v_checkreview.rb +854 -0
- data/templates/skillsets/agent/test/test_agent1_r3v_guardwords.rb +730 -0
- data/templates/skillsets/agent/test/test_agent1_r3v_lifecycle.rb +1096 -0
- data/templates/skillsets/agent/test/test_agent1_selfreview_fixes.rb +75 -0
- data/templates/skillsets/agent/test/test_agent1_stand_in_precedents.rb +113 -0
- data/templates/skillsets/agent/test/test_agent1_v06.rb +1154 -0
- data/templates/skillsets/agent/tools/agent_advance.rb +51 -0
- data/templates/skillsets/agent/tools/agent_finish.rb +50 -0
- data/templates/skillsets/agent/tools/agent_items.rb +56 -0
- data/templates/skillsets/agent/tools/agent_start.rb +17 -224
- data/templates/skillsets/agent/tools/agent_status.rb +9 -89
- data/templates/skillsets/agent/tools/agent_stop.rb +8 -122
- data/templates/skillsets/introspection/lib/introspection/safety_inspector.rb +28 -14
- data/templates/skillsets/llm_client/lib/llm_client/adapter.rb +7 -2
- data/templates/skillsets/llm_client/lib/llm_client/call_router.rb +8 -2
- data/templates/skillsets/llm_client/lib/llm_client/claude_code_adapter.rb +30 -5
- data/templates/skillsets/llm_client/lib/llm_client/cli_failure.rb +123 -0
- data/templates/skillsets/llm_client/lib/llm_client/codex_adapter.rb +6 -3
- data/templates/skillsets/llm_client/lib/llm_client/cursor_adapter.rb +5 -3
- data/templates/skillsets/llm_client/skillset.json +1 -1
- data/templates/skillsets/llm_client/test/test_cli_failure.rb +263 -0
- data/templates/skillsets/llm_client/test/test_no_fallback_and_isolation.rb +113 -0
- data/templates/skillsets/llm_client/tools/llm_call.rb +21 -3
- data/templates/skillsets/multi_llm_review/config/multi_llm_review.yml +19 -0
- data/templates/skillsets/multi_llm_review/lib/multi_llm_review/build_review_bundle.rb +8 -1
- data/templates/skillsets/multi_llm_review/lib/multi_llm_review/consensus.rb +20 -4
- data/templates/skillsets/multi_llm_review/lib/multi_llm_review/dispatcher.rb +5 -1
- data/templates/skillsets/multi_llm_review/lib/multi_llm_review/feedback_formatter.rb +119 -1
- data/templates/skillsets/multi_llm_review/lib/multi_llm_review/observer_set.rb +7 -3
- data/templates/skillsets/multi_llm_review/lib/multi_llm_review/persona_assembly.rb +26 -7
- data/templates/skillsets/multi_llm_review/lib/multi_llm_review/roster_health.rb +127 -0
- data/templates/skillsets/multi_llm_review/skillset.json +3 -3
- data/templates/skillsets/multi_llm_review/test/test_feedback_formatter.rb +1 -1
- data/templates/skillsets/multi_llm_review/test/test_non_claude_host.rb +455 -0
- data/templates/skillsets/multi_llm_review/test/test_tool_wiring.rb +1 -1
- data/templates/skillsets/multi_llm_review/tools/multi_llm_review.rb +103 -34
- data/templates/skillsets/multi_llm_review/tools/multi_llm_review_collect.rb +16 -11
- data/templates/skillsets/multi_llm_review/tools/multi_llm_review_wait.rb +24 -4
- metadata +61 -62
- data/templates/skillsets/agent/bin/agent_distill.rb +0 -124
- data/templates/skillsets/agent/bin/agent_rule.rb +0 -215
- data/templates/skillsets/agent/bin/agent_shadow_judge.rb +0 -70
- data/templates/skillsets/agent/bin/agent_step_worker.rb +0 -321
- data/templates/skillsets/agent/config/agent.yml +0 -171
- data/templates/skillsets/agent/lib/agent/act_classification.rb +0 -336
- data/templates/skillsets/agent/lib/agent/act_classification.yml +0 -54
- data/templates/skillsets/agent/lib/agent/admission.rb +0 -384
- data/templates/skillsets/agent/lib/agent/adoption.rb +0 -340
- data/templates/skillsets/agent/lib/agent/advance_gate.rb +0 -357
- data/templates/skillsets/agent/lib/agent/answer_ruling.rb +0 -491
- data/templates/skillsets/agent/lib/agent/cognitive_loop.rb +0 -452
- data/templates/skillsets/agent/lib/agent/delegation.rb +0 -372
- data/templates/skillsets/agent/lib/agent/delegation_table.yml +0 -44
- data/templates/skillsets/agent/lib/agent/distill_run.rb +0 -197
- data/templates/skillsets/agent/lib/agent/distiller.rb +0 -313
- data/templates/skillsets/agent/lib/agent/distiller_prompt.rb +0 -130
- data/templates/skillsets/agent/lib/agent/mandate_adapter.rb +0 -69
- data/templates/skillsets/agent/lib/agent/mediator.rb +0 -211
- data/templates/skillsets/agent/lib/agent/message_format.rb +0 -33
- data/templates/skillsets/agent/lib/agent/native_body/main.rb +0 -166
- data/templates/skillsets/agent/lib/agent/native_body/model_client.rb +0 -135
- data/templates/skillsets/agent/lib/agent/native_body/spend_meter.rb +0 -131
- data/templates/skillsets/agent/lib/agent/native_body/tool_layer.rb +0 -195
- data/templates/skillsets/agent/lib/agent/point_facts.rb +0 -231
- data/templates/skillsets/agent/lib/agent/review_hint.rb +0 -84
- data/templates/skillsets/agent/lib/agent/session.rb +0 -282
- data/templates/skillsets/agent/lib/agent/shadow_judge.rb +0 -564
- data/templates/skillsets/agent/lib/agent/staging.rb +0 -267
- data/templates/skillsets/agent/lib/agent/step_delegation.rb +0 -450
- data/templates/skillsets/agent/lib/agent/trigger_validator.rb +0 -69
- data/templates/skillsets/agent/lib/agent/verdict.rb +0 -177
- data/templates/skillsets/agent/plugin/agents/monitor.md +0 -24
- data/templates/skillsets/agent/test/test_agent_act_hardening.rb +0 -488
- data/templates/skillsets/agent/test/test_agent_admission.rb +0 -112
- data/templates/skillsets/agent/test/test_agent_allowlist.rb +0 -724
- data/templates/skillsets/agent/test/test_agent_answer_rulings.rb +0 -949
- data/templates/skillsets/agent/test/test_agent_capability_discovery.rb +0 -307
- data/templates/skillsets/agent/test/test_agent_complexity_review.rb +0 -852
- data/templates/skillsets/agent/test/test_agent_confinement.rb +0 -184
- data/templates/skillsets/agent/test/test_agent_distillation.rb +0 -539
- data/templates/skillsets/agent/test/test_agent_guard_integration.rb +0 -218
- data/templates/skillsets/agent/test/test_agent_guard_verdict_record.rb +0 -446
- data/templates/skillsets/agent/test/test_agent_halt_semantics.rb +0 -370
- data/templates/skillsets/agent/test/test_agent_human_mark_gate.rb +0 -486
- data/templates/skillsets/agent/test/test_agent_interruption_resilience.rb +0 -729
- data/templates/skillsets/agent/test/test_agent_m1.rb +0 -329
- data/templates/skillsets/agent/test/test_agent_m2.rb +0 -625
- data/templates/skillsets/agent/test/test_agent_m3.rb +0 -719
- data/templates/skillsets/agent/test/test_agent_m4.rb +0 -545
- data/templates/skillsets/agent/test/test_agent_native_body.rb +0 -788
- data/templates/skillsets/agent/test/test_agent_shadow_judge.rb +0 -1233
- data/templates/skillsets/agent/test/test_agent_verdict.rb +0 -119
- data/templates/skillsets/agent/test/test_agent_worker_exit_and_review_parse.rb +0 -622
- data/templates/skillsets/agent/test/test_agent_worker_process.rb +0 -386
- data/templates/skillsets/agent/test/test_decide_prompt_contract.rb +0 -158
- data/templates/skillsets/agent/test/test_review_hint.rb +0 -168
- data/templates/skillsets/agent/tools/agent_execute.rb +0 -627
- data/templates/skillsets/agent/tools/agent_step.rb +0 -3909
- data/templates/skillsets/agent/tools/agent_wait.rb +0 -195
- data/templates/skillsets/agent/tools/operator_report.rb +0 -130
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: d9378e59ddbeb6127f907b009d5c74f362932d3ded7669e75975d9e4e000285b
|
|
4
|
+
data.tar.gz: f5153b3a2034f5ad9f68d1ee5d31f4a7295e8b4e1cdf48cf90283744886d0355
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 2a9ca012c529a7523e68bb0dde4fd08b20bda1e08a540d98714ae169efc1268946faeb6d16ad1a0926382a480177c60c736a383f8747b2dbcf0225bac5ad522a
|
|
7
|
+
data.tar.gz: 9e39c4801fef0169431db7c23e6f1e45099b11b0a482b12254fef0a90cf7de7787f6d3b6414824fddb86c0f04c246a2b488cda4741e450366841ee7d2f706b52
|
data/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,159 @@ This project follows [Semantic Versioning](https://semver.org/).
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
+
## [3.96.0] - 2026-10-21
|
|
10
|
+
|
|
11
|
+
### Changed — multi_llm_review says what the roster was when a result is read (multi_llm_review 0.12.0, llm_client 0.4.0)
|
|
12
|
+
|
|
13
|
+
A seat whose reviewer CLI was missing, logged out or refused by codex used to leave the count as `transport`, and
|
|
14
|
+
an APPROVE carried no feedback at all, so a review decided by two Anthropic seats read like one decided by four
|
|
15
|
+
seats from three makers. A Codex host's persona team was recorded as Claude's.
|
|
16
|
+
|
|
17
|
+
- A failed seat's reason is the cause its CLI adapter established: `cli_missing` (the binary is not on the PATH the
|
|
18
|
+
server searched), `cli_unauthenticated` (the CLI, asked after the failure with its own status command, says it
|
|
19
|
+
holds no credential), `workspace_refused` (codex refused a working directory outside a git repository) or
|
|
20
|
+
`cli_timeout`. Anything else stays `transport`, which now means an error with no established cause. Nothing the
|
|
21
|
+
CLI printed is read for this: codex prints the prompt and the files it read.
|
|
22
|
+
- `vote_tally.roster_health` states the seats, how many counted, each seat that did not count with its reason, and
|
|
23
|
+
each counted seat's maker with where it comes from (observed, configured, or declared by the caller). When a seat
|
|
24
|
+
did not count or maker diversity is not established, `feedback_text` starts with one line, on APPROVE too:
|
|
25
|
+
`Roster: 2 of 4 seats counted (1 caller-declared) — not counted: cli_missing: codex_gpt6-astra, cursor_composer2.5; maker diversity not established.`
|
|
26
|
+
- INSUFFICIENT says how many seats counted and how many were needed, that a seat can be added in config, and the
|
|
27
|
+
action that restores each lost seat where one exists. The tool advises no strategy.
|
|
28
|
+
- Every seat is dispatched with `no_fallback`: an API-key seat whose key is unset fails on its own provider instead
|
|
29
|
+
of being re-run on claude_code under its own name.
|
|
30
|
+
- New optional argument `orchestrator_host` (`claude_code`, `codex_cli`, `cursor`, `other`). `claude_code` or none
|
|
31
|
+
keeps `claude_team_<model>`; `codex_cli` records the persona seat as `codex_team_<model>` with provider
|
|
32
|
+
`codex_cli_host`. Records carry `orchestrator_host` and the server's own `host_detected`.
|
|
33
|
+
- `multi_llm_review_wait` reports answered and failed seats separately.
|
|
34
|
+
- The verdict and the quorum are unchanged. VERDICT_SCHEMA_VERSION 3, feedback_text_schema_version 2;
|
|
35
|
+
multi_llm_review's min_core_version is 3.24.9.
|
|
36
|
+
- config gains a commented second codex seat for a machine with only the codex CLI. Upgrades never rewrite an
|
|
37
|
+
instance's config; add it by hand.
|
|
38
|
+
- llm_client 0.4.0: `ApiError` carries the `code`, and `CallRouter` and `llm_call` return it as `error['code']`.
|
|
39
|
+
After a failed CLI call one status command runs (never when the dispatcher ended the call; at most about 19 s).
|
|
40
|
+
The error message and its ErrorTaxonomy type are unchanged, so every other llm_client caller sees only the added
|
|
41
|
+
key and that pause.
|
|
42
|
+
|
|
43
|
+
Design: `log/mlr_non_claude_host_design_v0.3.3_20261021.md`, frozen after four review rounds; implementation
|
|
44
|
+
reviewed in two (records `log/mlr_non_claude_host_*`).
|
|
45
|
+
|
|
46
|
+
### Changed — L1 `multi_llm_review_workflow` 3.17.0
|
|
47
|
+
|
|
48
|
+
§ Auto Mode vs Manual Mode sent a missing CLI to a "Manual mode" the runbook never described. It is replaced by
|
|
49
|
+
§ Execution Environment / Reduced rosters and non-Claude hosts: what each failure reason means and what restores
|
|
50
|
+
the seat, the roster line, what a Claude-only, a non-Claude-host and a codex-only setup count under each strategy,
|
|
51
|
+
and how a host's per-call time limit meets a long review call.
|
|
52
|
+
|
|
53
|
+
### Fixed — `capability_status` reported installed reviewer CLIs as missing
|
|
54
|
+
|
|
55
|
+
It searched PATH for files named `claude_cli`, `codex_cli` and `cursor_cli`. It now probes the binaries the
|
|
56
|
+
adapters spawn (`claude`, `codex`, `agent`), runs `--version` without a shell, and names the binary it searched for.
|
|
57
|
+
|
|
58
|
+
## [3.95.1] - 2026-10-21
|
|
59
|
+
|
|
60
|
+
### Changed — the agent SkillSet ships a sample policy, `default_2026_10_20`, instead of `masa_2026_10_20` (agent 1.0.1)
|
|
61
|
+
|
|
62
|
+
`masa_2026_10_20.rb` named its author and cited a record that exists only in the author's instance.
|
|
63
|
+
`default_2026_10_20.rb` carries the same rules (the stand-in may answer from the operator's recorded words, from
|
|
64
|
+
the instruction mode, and reversible questions no recorded word covers; review consent; no project exempt from the
|
|
65
|
+
data check; 10 rounds per review; 300 stand-in calls), with comments that say what each rule does. The stand-in
|
|
66
|
+
reads the policy file, comments included. Adopt it with `adopt policy default_2026_10_20 ac4ae89b`; adopting it
|
|
67
|
+
consents to sending the run's artifacts to the reviewers configured in multi_llm_review.
|
|
68
|
+
|
|
69
|
+
`masa_2026_10_20.rb` is no longer shipped and is not listed in `removed_files`, so upgrade leaves an installed copy
|
|
70
|
+
and a forced reinstall keeps the installed copy: an instance that has it keeps it, and an adoption of it stays valid. It is another operator's sample with the same
|
|
71
|
+
rules: an instance that never adopted it may delete it, and one that did may adopt `default_2026_10_20` instead. A
|
|
72
|
+
shipped policy is never changed in place; a changed rule ships under a new policy name in a new file. Design:
|
|
73
|
+
`log/agent_policy_default_and_proposal_design_v0.7.2_20261021.md`.
|
|
74
|
+
|
|
75
|
+
### Changed — personal material out of the shipped agent tree
|
|
76
|
+
|
|
77
|
+
Home paths, a person's project and course names, answers typed in a real course and a third party's name are
|
|
78
|
+
replaced by synthetic ones in the agent SkillSet's tests and one code comment. The published 3.95.0 gem and the
|
|
79
|
+
repository history keep them.
|
|
80
|
+
|
|
81
|
+
### Added — `bin/agent_policy_report.rb`
|
|
82
|
+
|
|
83
|
+
An operator-run script that reports, for each rule of the adopted policy, what the runs the chain records as ended
|
|
84
|
+
hold against it: stand-in answers by class and their corrections, review rounds and cap hits, stand-in calls and
|
|
85
|
+
grants, data checks, with counts, denominators and the operator's words. It moves no rule, evaluates no file
|
|
86
|
+
from a run directory, and writes only its report, under `storage/agent/policy_reports/` (and
|
|
87
|
+
`storage/agent/.gitignore` when absent; no report is written unless that file is a regular file holding exactly the line `*`). Every act it counts is recorded on the actor's reading of the
|
|
88
|
+
operator's words, and the report says so. A policy changes only by the operator's own copy, edit and typed
|
|
89
|
+
adoption.
|
|
90
|
+
|
|
91
|
+
## [3.95.0] - 2026-10-21
|
|
92
|
+
|
|
93
|
+
### Changed — the `agent` SkillSet is rebuilt (1.0): long runs in the host session, a stand-in instead of terminal approvals
|
|
94
|
+
|
|
95
|
+
The 0.x agent could not carry the operator's ordinary request (design → design review → implement →
|
|
96
|
+
implementation review): its act route wrote only `docs/drafts/draft_*`, could not reach multi-LLM review or
|
|
97
|
+
tests, and counted only terminal-attested answers (0 counted pairs). Design:
|
|
98
|
+
`log/agent_skillset_rebuild_design_v0.5.1_20261020.md` (five review rounds, frozen as the author's proposal)
|
|
99
|
+
and its delta `log/agent_skillset_rebuild_design_v0.6.3_20261020.md`.
|
|
100
|
+
|
|
101
|
+
- The host session (Claude Code) is the only body. The SkillSet supplies a plan from a Ruby-DSL template, a
|
|
102
|
+
stand-in (isolated `claude -p --safe-mode --tools ""`, Opus 5.5) that answers decision points from the
|
|
103
|
+
operator's own words and the instruction mode, a guard (host hooks: `PreToolUse` on every tool, fail-closed)
|
|
104
|
+
that lets through only what the run created or its worktree and branch hold, a hash-chained journal, and a
|
|
105
|
+
report check. Six tools: `agent_start`, `agent_status`, `agent_advance`, `agent_items`, `agent_finish`,
|
|
106
|
+
`agent_stop`.
|
|
107
|
+
- Runs need an adopted policy (the operator's mandate, `config/policies/*.rb`), adopted by the operator's own
|
|
108
|
+
typed words naming its digest; the adoption is recorded on the chain.
|
|
109
|
+
- Templates: `dev_cycle`, `impl_cycle`, `design_only`, `doc_cycle` (a document kept in git, revised in place,
|
|
110
|
+
optional build check), `survey` (versioned survey files from local sources), `general`.
|
|
111
|
+
- A review closes only when no (a)/(b) P0 is open. Each review may take the policy's `review_rounds`
|
|
112
|
+
(10), counted for that review alone; at the cap it waits for the operator, who grants more rounds or
|
|
113
|
+
freezes it. Revisions follow L1 multi_llm_review_workflow § Revision
|
|
114
|
+
Discipline: each round says which new P0s the actor's last addition drew, and the next step is to undo it.
|
|
115
|
+
Design reviews stay at the design level; implementation-only findings are deferred to the implementation
|
|
116
|
+
review and are operator items at once.
|
|
117
|
+
- Every run ends with a layered-deck report (`report_kit/`, the kit of L1 `layered_visual_pitch_deck`).
|
|
118
|
+
- `bin/agent_harvest.rb` harvests the operator's own answers from host transcripts (hook output, peer
|
|
119
|
+
messages and pasted host output excluded).
|
|
120
|
+
- Removed: the in-server OODA loop, act-route table and terminal rulings, shadow judge, distillation,
|
|
121
|
+
native body, `agent_execute`, `agent_step`, `agent_wait`, `operator_report`, the `agent-monitor` subagent.
|
|
122
|
+
- `agent` is no longer installed automatically in new instances (it needs a policy and projects hooks).
|
|
123
|
+
An installed 0.x agent becomes 1.0 on upgrade. 1.0 needs `multi_llm_review` and `llm_client` >= 0.3.0 in
|
|
124
|
+
the same instance; upgrade does not install a missing one (`kairos-chain skillset install multi_llm_review`).
|
|
125
|
+
|
|
126
|
+
### Added — `removed_files` in `skillset.json`; `system_upgrade` archives them
|
|
127
|
+
|
|
128
|
+
`upgrade_apply` copied changed files and never deleted one, so a SkillSet that dropped files left them to be
|
|
129
|
+
loaded. A template may now list `removed_files`; upgrade moves each from the installed copy to
|
|
130
|
+
`storage/skillset_removed/<name>/<time>/`, and a forced reinstall no longer restores a retired config file.
|
|
131
|
+
|
|
132
|
+
### Added — `llm_call` options `no_fallback` and `isolated`
|
|
133
|
+
|
|
134
|
+
`no_fallback` makes an authentication failure on the configured provider a failure instead of a silent switch
|
|
135
|
+
to `claude_code`. `isolated` (claude_code) runs `claude -p --safe-mode --tools ""` in an empty directory, so
|
|
136
|
+
no CLAUDE.md, skills, plugins, hooks, memory or MCP servers reach the call. An isolated call's payload carries
|
|
137
|
+
`isolation` (`safe_mode`, `tools`, `cwd`, as `claude -p` was spawned); llm_client is 0.3.0. The agent's
|
|
138
|
+
stand-in refuses any reply without that evidence (and refuses to call an llm_client too old to isolate), and the
|
|
139
|
+
agent SkillSet declares `llm_client >= 0.3.0`; upgrade both together.
|
|
140
|
+
|
|
141
|
+
### Added — `user_level_conflicts` in `skillset.json`; install and upgrade report them
|
|
142
|
+
|
|
143
|
+
A SkillSet may list files an earlier version left at user level that it cannot remove itself (e.g. a personal
|
|
144
|
+
skill that shadows the project's). `install`, `upgrade_apply`, `system_upgrade` and `kairos-chain skillset
|
|
145
|
+
install/upgrade` print the ones present as warnings, with a command that moves them to a timestamped backup.
|
|
146
|
+
agent 1.0 lists the 0.x personal skill `~/.claude/skills/agent/SKILL.md` and `~/.claude/agents/agent-monitor.md`.
|
|
147
|
+
|
|
148
|
+
### Changed — the shipped agent policy needs a new adoption
|
|
149
|
+
|
|
150
|
+
`masa_2026_10_20.rb` sets `review_rounds` to 10 rounds for each review (counted apart, no longer shared by a
|
|
151
|
+
run's reviews) and drops the lookup consent comment (runs never look things up on the web). Its digest
|
|
152
|
+
changed: adopt it with `adopt policy masa_2026_10_20 8846b67e`.
|
|
153
|
+
|
|
154
|
+
### Changed — L1 `multi_llm_review_workflow` 3.16.0 and `design_to_implementation_workflow` 1.3
|
|
155
|
+
|
|
156
|
+
A new entry-level clause, § Provisional delegation under a mandate: under a pinned, journaled operator policy a
|
|
157
|
+
named delegate — never the context whose work is judged — answers reserved judgments provisionally, and nothing
|
|
158
|
+
resolves, closes, freezes or demotes beyond the run until the operator confirms it in their own words. Pointers
|
|
159
|
+
from INV-U2, INV-U4, INV-U5, Step 0.25 and § Convergence Rules, and from the merge criteria of
|
|
160
|
+
`design_to_implementation_workflow`. An instance's own L1 copy is not rewritten by upgrade.
|
|
161
|
+
|
|
9
162
|
## [3.94.0] - 2026-10-20
|
|
10
163
|
|
|
11
164
|
### Added — L0 changes proposed for later approval, L0 restores on the record, L1 body history
|
data/bin/kairos-chain
CHANGED
|
@@ -102,6 +102,7 @@ when 'skillset'
|
|
|
102
102
|
result = manager.install(source, layer_override: layer_override, force: force)
|
|
103
103
|
puts "Installed SkillSet '#{result[:name]}' v#{result[:version]} [#{result[:layer]}]"
|
|
104
104
|
puts "Path: #{result[:path]}"
|
|
105
|
+
manager.user_level_conflicts(KairosMcp::Skillset.new(result[:path])).each { |w| puts " [WARNING] #{w}" }
|
|
105
106
|
|
|
106
107
|
when 'enable'
|
|
107
108
|
name = ARGV.shift
|
|
@@ -162,6 +163,7 @@ when 'skillset'
|
|
|
162
163
|
puts "## SkillSets"
|
|
163
164
|
results.each do |r|
|
|
164
165
|
puts " [UPGRADED] #{r[:name].ljust(22)} v#{r[:from]} -> v#{r[:to]} (#{r[:files_updated]} files)"
|
|
166
|
+
Array(r[:warnings]).each { |w| puts " [WARNING] #{w}" }
|
|
165
167
|
end
|
|
166
168
|
checkable.reject { |ss| upgraded_names.include?(ss.name) }.each do |ss|
|
|
167
169
|
puts " [UNCHANGED] #{ss.name.ljust(22)} v#{ss.version}"
|
|
@@ -98,11 +98,25 @@ module KairosMcp
|
|
|
98
98
|
declaration_errors: errors }
|
|
99
99
|
end
|
|
100
100
|
|
|
101
|
+
# The binary each declared external names: the one the llm_client
|
|
102
|
+
# adapter spawns for it (claude_code_adapter, codex_adapter,
|
|
103
|
+
# cursor_adapter). Probing the symbol itself searched PATH for a file
|
|
104
|
+
# called "codex_cli" and reported every installed CLI as missing.
|
|
105
|
+
EXTERNAL_BINARIES = {
|
|
106
|
+
claude_cli: 'claude',
|
|
107
|
+
codex_cli: 'codex',
|
|
108
|
+
cursor_cli: 'agent'
|
|
109
|
+
}.freeze
|
|
110
|
+
|
|
111
|
+
def binary_for(name)
|
|
112
|
+
EXTERNAL_BINARIES.fetch(name.to_s.to_sym, name.to_s)
|
|
113
|
+
end
|
|
114
|
+
|
|
101
115
|
# which-style PATH check using only filesystem (no subprocess).
|
|
102
116
|
# Returns true/false.
|
|
103
117
|
def cli_in_path?(name)
|
|
104
118
|
return false unless name.is_a?(Symbol) || name.is_a?(String)
|
|
105
|
-
bin = name
|
|
119
|
+
bin = binary_for(name)
|
|
106
120
|
ENV.fetch('PATH', '').split(File::PATH_SEPARATOR).any? do |dir|
|
|
107
121
|
full = File.join(dir, bin)
|
|
108
122
|
File.executable?(full) && !File.directory?(full)
|
|
@@ -110,11 +124,13 @@ module KairosMcp
|
|
|
110
124
|
end
|
|
111
125
|
|
|
112
126
|
# Get version of a CLI by spawning subprocess (only when probe_versions: true).
|
|
113
|
-
# Returns nil on any failure (Honest unknown).
|
|
127
|
+
# Returns nil on any failure (Honest unknown). Spawned as an argv, not
|
|
128
|
+
# through a shell.
|
|
114
129
|
def cli_version(name)
|
|
115
130
|
return nil unless cli_in_path?(name)
|
|
116
|
-
|
|
117
|
-
|
|
131
|
+
require 'open3'
|
|
132
|
+
out, status = Open3.capture2e(binary_for(name), '--version')
|
|
133
|
+
status.success? ? out.strip.lines.first&.strip : nil
|
|
118
134
|
rescue StandardError
|
|
119
135
|
nil
|
|
120
136
|
end
|
data/lib/kairos_mcp/skillset.rb
CHANGED
|
@@ -87,6 +87,27 @@ module KairosMcp
|
|
|
87
87
|
@metadata['config_files'] || []
|
|
88
88
|
end
|
|
89
89
|
|
|
90
|
+
# Files a release takes out of an installed copy (relative paths). An
|
|
91
|
+
# upgrade copies changed files and never deletes; a SkillSet that drops
|
|
92
|
+
# files names them here so system_upgrade archives them instead of
|
|
93
|
+
# leaving them to be loaded (Skillset#load requires every tools/*.rb).
|
|
94
|
+
def removed_files
|
|
95
|
+
Array(@metadata['removed_files']).select do |rel|
|
|
96
|
+
rel.is_a?(String) && !rel.empty? && !rel.start_with?('/') && !rel.split('/').include?('..')
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
# Files outside the instance that an earlier version left at user level
|
|
101
|
+
# and that this version cannot remove itself (e.g. a personal skill that
|
|
102
|
+
# shadows the project's): each { "path": "~/...", "pattern": "regex",
|
|
103
|
+
# "note": "..." }. Upgrade reports the ones present; the operator moves
|
|
104
|
+
# them.
|
|
105
|
+
def user_level_conflicts
|
|
106
|
+
Array(@metadata['user_level_conflicts']).select do |c|
|
|
107
|
+
c.is_a?(Hash) && c['path'].is_a?(String) && c['path'].start_with?('~/') && !c['path'].split('/').include?('..')
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
|
|
90
111
|
# Optional fail-closed activation hook: a fully-qualified class name
|
|
91
112
|
# whose `activate_on_load!` runs at skillset-load time, independent of
|
|
92
113
|
# whether any of the SkillSet's tools are instantiated. Used by
|
|
@@ -89,12 +89,14 @@ module KairosMcp
|
|
|
89
89
|
dest = File.join(@skillsets_dir, temp_skillset.name)
|
|
90
90
|
if File.directory?(dest)
|
|
91
91
|
if force
|
|
92
|
-
# Preserve user config files before replacing
|
|
92
|
+
# Preserve user config files (subdirectories included) before replacing
|
|
93
93
|
config_dir = File.join(dest, 'config')
|
|
94
94
|
saved_configs = {}
|
|
95
95
|
if File.directory?(config_dir)
|
|
96
|
-
Dir.glob(File.join(config_dir, '*')).each do |f|
|
|
97
|
-
|
|
96
|
+
Dir.glob(File.join(config_dir, '**', '*')).each do |f|
|
|
97
|
+
next unless File.file?(f)
|
|
98
|
+
|
|
99
|
+
saved_configs[f.sub("#{config_dir}/", '')] = File.read(f)
|
|
98
100
|
end
|
|
99
101
|
end
|
|
100
102
|
|
|
@@ -103,12 +105,13 @@ module KairosMcp
|
|
|
103
105
|
# Copy new version
|
|
104
106
|
FileUtils.cp_r(source_path, dest)
|
|
105
107
|
|
|
106
|
-
# Restore user configs
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
108
|
+
# Restore user configs, except those the new version retired
|
|
109
|
+
retired = temp_skillset.removed_files.select { |r| r.start_with?('config/') }.map { |r| r.sub('config/', '') }
|
|
110
|
+
saved_configs.reject! { |rel, _| retired.include?(rel) }
|
|
111
|
+
saved_configs.each do |rel, content|
|
|
112
|
+
path = File.join(dest, 'config', rel)
|
|
113
|
+
FileUtils.mkdir_p(File.dirname(path))
|
|
114
|
+
File.write(path, content)
|
|
112
115
|
end
|
|
113
116
|
else
|
|
114
117
|
raise ArgumentError, "SkillSet '#{temp_skillset.name}' already installed at #{dest}. Use --force to reinstall."
|
|
@@ -154,14 +157,16 @@ module KairosMcp
|
|
|
154
157
|
template_ver = Gem::Version.new(template_ss.version)
|
|
155
158
|
|
|
156
159
|
changed_files = diff_files(template_path, installed.path)
|
|
160
|
+
removals = template_ss.removed_files.select { |rel| File.exist?(File.join(installed.path, rel)) }
|
|
157
161
|
|
|
158
|
-
if template_ver > installed_ver || changed_files.any?
|
|
162
|
+
if template_ver > installed_ver || changed_files.any? || removals.any?
|
|
159
163
|
results << {
|
|
160
164
|
name: installed.name,
|
|
161
165
|
installed_version: installed.version,
|
|
162
166
|
available_version: template_ss.version,
|
|
163
167
|
version_bump: template_ver > installed_ver,
|
|
164
168
|
changed_files: changed_files,
|
|
169
|
+
removed_files: removals,
|
|
165
170
|
new_skillset: false
|
|
166
171
|
}
|
|
167
172
|
end
|
|
@@ -194,7 +199,7 @@ module KairosMcp
|
|
|
194
199
|
# Others (multiuser, service_grant, hestia, mmp, skillset_exchange, mcp_client)
|
|
195
200
|
# require PostgreSQL or networking and must be installed explicitly.
|
|
196
201
|
CORE_SKILLSETS = %w[
|
|
197
|
-
plugin_projector
|
|
202
|
+
plugin_projector llm_client autoexec autonomos
|
|
198
203
|
skillset_creator knowledge_creator introspection dream
|
|
199
204
|
document_authoring synoptis
|
|
200
205
|
].freeze
|
|
@@ -223,7 +228,8 @@ module KairosMcp
|
|
|
223
228
|
# Install new SkillSet from template
|
|
224
229
|
result = install(template_path)
|
|
225
230
|
results << { name: info[:name], from: nil, to: info[:available_version],
|
|
226
|
-
action: 'installed', files_updated: 0
|
|
231
|
+
action: 'installed', files_updated: 0,
|
|
232
|
+
warnings: user_level_conflicts(Skillset.new(File.join(@skillsets_dir, info[:name]))) }.reject { |_, v| v == [] }
|
|
227
233
|
else
|
|
228
234
|
# Upgrade existing: copy changed files
|
|
229
235
|
dest = File.join(@skillsets_dir, info[:name])
|
|
@@ -233,11 +239,13 @@ module KairosMcp
|
|
|
233
239
|
FileUtils.mkdir_p(File.dirname(dst))
|
|
234
240
|
FileUtils.cp(src, dst) if File.exist?(src)
|
|
235
241
|
end
|
|
242
|
+
archived = archive_removed_files(info[:name], dest, Array(info[:removed_files]))
|
|
236
243
|
|
|
237
244
|
installed = Skillset.new(dest)
|
|
238
245
|
record_skillset_event(installed, 'upgrade')
|
|
239
246
|
results << { name: info[:name], from: info[:installed_version], to: info[:available_version],
|
|
240
|
-
action: 'upgraded', files_updated: info[:changed_files].size
|
|
247
|
+
action: 'upgraded', files_updated: info[:changed_files].size, files_archived: archived.size,
|
|
248
|
+
warnings: user_level_conflicts(installed) }.reject { |_, v| v == [] }
|
|
241
249
|
end
|
|
242
250
|
end
|
|
243
251
|
|
|
@@ -445,8 +453,45 @@ module KairosMcp
|
|
|
445
453
|
all_skillsets.find { |ss| ss.name == name.to_s }
|
|
446
454
|
end
|
|
447
455
|
|
|
456
|
+
# The user-level leftovers a SkillSet declares that are present now, as
|
|
457
|
+
# warnings with the command that moves them aside (a timestamped backup,
|
|
458
|
+
# so a second move never overwrites the first).
|
|
459
|
+
def user_level_conflicts(skillset)
|
|
460
|
+
skillset.user_level_conflicts.filter_map do |c|
|
|
461
|
+
path = File.expand_path(c['path'])
|
|
462
|
+
next unless File.exist?(path)
|
|
463
|
+
next if c['pattern'] && !File.read(path, encoding: 'UTF-8').match?(Regexp.new(c['pattern']))
|
|
464
|
+
|
|
465
|
+
backup = File.expand_path("~/.claude/#{skillset.name}_previous_version_backup/#{Time.now.strftime('%Y%m%d_%H%M%S')}")
|
|
466
|
+
"#{path}: #{c['note'] || 'left by an earlier version'} (move it aside: mkdir -p #{backup} && mv #{path} #{backup}/)"
|
|
467
|
+
end
|
|
468
|
+
rescue StandardError
|
|
469
|
+
[]
|
|
470
|
+
end
|
|
471
|
+
|
|
448
472
|
private
|
|
449
473
|
|
|
474
|
+
# Move files a release dropped out of the installed copy, into
|
|
475
|
+
# storage/skillset_removed/<name>/<time>/ (kept, not deleted, so the
|
|
476
|
+
# operator can read back what the upgrade took out). Paths are checked to
|
|
477
|
+
# stay inside the installed SkillSet.
|
|
478
|
+
def archive_removed_files(name, dest, rels)
|
|
479
|
+
return [] if rels.empty?
|
|
480
|
+
|
|
481
|
+
root = File.realpath(dest)
|
|
482
|
+
stamp = Time.now.utc.strftime('%Y%m%dT%H%M%SZ')
|
|
483
|
+
archive = File.join(KairosMcp.storage_dir, 'skillset_removed', name.to_s, stamp)
|
|
484
|
+
rels.filter_map do |rel|
|
|
485
|
+
src = File.join(root, rel)
|
|
486
|
+
next unless File.exist?(src) && File.expand_path(src).start_with?("#{root}/")
|
|
487
|
+
|
|
488
|
+
to = File.join(archive, rel)
|
|
489
|
+
FileUtils.mkdir_p(File.dirname(to))
|
|
490
|
+
FileUtils.mv(src, to)
|
|
491
|
+
rel
|
|
492
|
+
end
|
|
493
|
+
end
|
|
494
|
+
|
|
450
495
|
# Compare files between template and installed SkillSet
|
|
451
496
|
def diff_files(template_path, installed_path)
|
|
452
497
|
changed = []
|
|
@@ -152,7 +152,9 @@ module KairosMcp
|
|
|
152
152
|
|
|
153
153
|
externals.each do |ext|
|
|
154
154
|
present = Capability.cli_in_path?(ext)
|
|
155
|
-
|
|
155
|
+
# The binary searched for, so a reader can tell which file was
|
|
156
|
+
# missing (claude_cli is the `claude` binary, and so on).
|
|
157
|
+
entry = { available: present, binary: Capability.binary_for(ext) }
|
|
156
158
|
entry[:reason] = 'not found in PATH' unless present
|
|
157
159
|
if present && probe_versions
|
|
158
160
|
ver = Capability.cli_version(ext)
|
|
@@ -361,6 +361,7 @@ module KairosMcp
|
|
|
361
361
|
actions[:skillsets_upgraded] = (actions[:skillsets_upgraded] || []) << r[:name]
|
|
362
362
|
output += " [UPGRADED] #{r[:name]} v#{r[:from]} → v#{r[:to]} (#{r[:files_updated]} files)\n"
|
|
363
363
|
end
|
|
364
|
+
Array(r[:warnings]).each { |w| output += " [WARNING] #{w}\n" }
|
|
364
365
|
end
|
|
365
366
|
end
|
|
366
367
|
rescue => e
|
|
@@ -487,6 +488,7 @@ module KairosMcp
|
|
|
487
488
|
else
|
|
488
489
|
output += " [UPGRADED] #{r[:name]} v#{r[:from]} → v#{r[:to]} (#{r[:files_updated]} files)\n"
|
|
489
490
|
end
|
|
491
|
+
Array(r[:warnings]).each { |w| output += " [WARNING] #{w}\n" }
|
|
490
492
|
end
|
|
491
493
|
output += "\nNo L0 template changes needed.\n"
|
|
492
494
|
output += "Restart the MCP server to load new SkillSet tools.\n"
|
data/lib/kairos_mcp/version.rb
CHANGED
data/templates/knowledge/design_to_implementation_workflow/design_to_implementation_workflow.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: design_to_implementation_workflow
|
|
3
3
|
description: "Full-lifecycle workflow for complex features: design review, self-review, implementation review, and final merge gate. Derived from Service Grant + Attestation Nudge experiments."
|
|
4
|
-
version: "1.
|
|
4
|
+
version: "1.3"
|
|
5
5
|
tags:
|
|
6
6
|
- workflow
|
|
7
7
|
- implementation
|
|
@@ -157,6 +157,9 @@ Claude Persona Assembly (4 personas):
|
|
|
157
157
|
- NOT for intermediate rounds (diminishing returns)
|
|
158
158
|
|
|
159
159
|
**Merge criteria**: new (a)+(b) P0 = 0, with the freeze declared by the operator.
|
|
160
|
+
Inside an agent run a review closes provisionally (`multi_llm_review_workflow`
|
|
161
|
+
§ Provisional delegation under a mandate) and only the operator freezes one; the
|
|
162
|
+
operator's word at merge settles the merge and confirms only the closures it names.
|
|
160
163
|
A Codex APPROVE is the strongest *reference* signal (see
|
|
161
164
|
`multi_llm_reviewer_evaluation`), and it is not a gate: Codex went 24 of 24
|
|
162
165
|
reviews without reaching APPROVE on one design loop, so a merge waiting on it
|