kairos-chain 3.80.0 → 3.81.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 +38 -0
- data/lib/kairos_mcp/version.rb +1 -1
- data/templates/skillsets/project_manager/plugin/SKILL.md +27 -15
- data/templates/skillsets/project_manager/plugin/hooks.json +19 -2
- data/templates/skillsets/project_manager/scripts/l2_scan.rb +510 -0
- data/templates/skillsets/project_manager/scripts/pm_l2_report.rb +655 -0
- data/templates/skillsets/project_manager/skillset.json +2 -2
- data/templates/skillsets/project_manager/test/test_pm_l2_report.rb +1496 -0
- metadata +4 -4
- data/templates/skillsets/project_manager/scripts/l2_scan.py +0 -284
- data/templates/skillsets/project_manager/scripts/pm_l2_report.py +0 -597
- data/templates/skillsets/project_manager/test/test_pm_l2_report.py +0 -685
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 0bc251869ebf7ce64e94fbae5baf21ef0eea655b6d1c42d55dfb2f7ee7c2ccc0
|
|
4
|
+
data.tar.gz: aea009fc75974ff42a05e2bc54a352c19b1192157b9fe8eefa311ae9fd096c65
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 498212b88feb4e563e745be00467f8e206aff2c2103761c12d21695a1829201f2edae98295f61e2aaf6695f9d5e82be4f9f24a2c3ff10e868965a8cc1f1eae91
|
|
7
|
+
data.tar.gz: efe4a6d07531e77648bd175452e72036a0261d0bfb3b426b5f571b54b14a1f3f1695acc3b7d0136b64f04c33eac0e9c04dcebfb58481373af0ddbed355a8d1c4
|
data/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,44 @@ 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.81.0] - 2026-08-27
|
|
8
|
+
|
|
9
|
+
### Changed
|
|
10
|
+
|
|
11
|
+
- **`project_manager` ships its L2 comparison in Ruby, 0.7.0 -> 0.8.0.** The
|
|
12
|
+
three hook-side scripts move from Python to Ruby (`pm_l2_report.rb`,
|
|
13
|
+
`l2_scan.rb`, and the ported test), and the SessionStart hook it contributes
|
|
14
|
+
now invokes `ruby` rather than `python3`. python3 was never guaranteed on a
|
|
15
|
+
host the gem ships to; the interpreter the rest of the SkillSet already runs
|
|
16
|
+
on is. The port itself was committed before this release (`1ec9bd5`) and is
|
|
17
|
+
unchanged here — 505 execution comparisons over 101 input classes with zero
|
|
18
|
+
undeclared differences, 100 unit runs / 485 assertions green, 6/6 mutations
|
|
19
|
+
killed.
|
|
20
|
+
|
|
21
|
+
The version move is the load-bearing part of this release. Without it
|
|
22
|
+
`skillset upgrade` compares versions, finds them equal, reports UNCHANGED and
|
|
23
|
+
copies nothing, so an instance would take the new gem and keep the Python
|
|
24
|
+
scripts while the projected hook still names them.
|
|
25
|
+
|
|
26
|
+
- **`project_manager/plugin/hooks.json`: the bare `ruby` is now a ruling, not
|
|
27
|
+
an open question.** The comment block previously said the resolution was
|
|
28
|
+
undecided and named two candidates — the projector embedding an absolute
|
|
29
|
+
interpreter path, or this file checking `RUBY_VERSION`. Neither ships
|
|
30
|
+
(operator ruling, 2026-08-27). The comment now records why each was declined:
|
|
31
|
+
an embedded path has to be written by the projector, which turns an
|
|
32
|
+
interpreter choice into a core change and pins every host to one machine's
|
|
33
|
+
layout; a version check in this file trades the loud failure for a quiet one;
|
|
34
|
+
and `rbenv exec` fails outright wherever rbenv is absent — a Docker ruby
|
|
35
|
+
image, a homebrew install, asdf — which is strictly worse than the bare form,
|
|
36
|
+
since those hosts run the bare form fine.
|
|
37
|
+
|
|
38
|
+
Resolution therefore stays with the host's PATH, and the residual risk is
|
|
39
|
+
stated rather than hidden: `/usr/bin/ruby` 2.6.10 fails this script at parse
|
|
40
|
+
time with a 43-line syntax error and writes no page (measured). That failure
|
|
41
|
+
is visible at session start rather than silent, and the visibility is what
|
|
42
|
+
makes the bare form acceptable rather than merely convenient. The command
|
|
43
|
+
string is unchanged by this release; only the comment moved.
|
|
44
|
+
|
|
7
45
|
## [3.80.0] - 2026-08-27
|
|
8
46
|
|
|
9
47
|
### Changed
|
data/lib/kairos_mcp/version.rb
CHANGED
|
@@ -64,7 +64,7 @@ Prefer the sub-agent for "what needs attention?", at session start, and for sche
|
|
|
64
64
|
|
|
65
65
|
## The session-start L2 comparison
|
|
66
66
|
|
|
67
|
-
`scripts/pm_l2_report.
|
|
67
|
+
`scripts/pm_l2_report.rb` compares the memo against the L2 context store and writes one HTML page,
|
|
68
68
|
to `<data dir>/log/pm_l2_report.html`. `plugin/hooks.json` declares it as a `SessionStart` hook.
|
|
69
69
|
|
|
70
70
|
**Read-only by having no aim, not by checking one.** There is no output-path argument, so nothing
|
|
@@ -72,14 +72,11 @@ can point a write at the memo, the mapping, an L2 context, or `config/pm.yml`. A
|
|
|
72
72
|
took `-o` and guarded it by comparing resolved paths; that guard failed three ways — a case-only
|
|
73
73
|
difference on a case-insensitive filesystem, a hardlink, and any read input it did not know about —
|
|
74
74
|
and each failure destroyed the memo while the run printed that nothing had been written to it.
|
|
75
|
-
Deleting the argument closed all three.
|
|
76
|
-
import for the same reason a second guard was not added: a `.pyc` inside the SkillSet sits inside
|
|
77
|
-
`Skillset#all_file_hashes` and therefore inside `content_hash`, the value recorded on chain.
|
|
75
|
+
Deleting the argument closed all three.
|
|
78
76
|
|
|
79
|
-
**Paths come from
|
|
80
|
-
`.kairos`.
|
|
81
|
-
|
|
82
|
-
re-pointed after import.
|
|
77
|
+
**Paths come from each file's own location**, three levels up from `scripts/`, not from the name
|
|
78
|
+
`.kairos`. Both files derive their own; appending that literal reported a populated instance as
|
|
79
|
+
empty on every session whenever the data dir had been relocated under another name.
|
|
83
80
|
|
|
84
81
|
**Nothing is trusted to have a type.** `pm_item` writes `due` and `touched_at` through with no check
|
|
85
82
|
beyond a JSON type, and this SkillSet's own Ruby suite writes the integer `20260701` to both. Dates
|
|
@@ -140,13 +137,28 @@ the headline figures shrank without saying so.
|
|
|
140
137
|
|
|
141
138
|
### Tests
|
|
142
139
|
|
|
143
|
-
`test/test_pm_l2_report.
|
|
144
|
-
guard by one line must make the suite red.
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
140
|
+
`test/test_pm_l2_report.rb` (minitest, 75 cases). The bar is mutation, not redness against an older
|
|
141
|
+
commit: breaking a guard by one line must make the suite red. Guards are exercised through `main` in
|
|
142
|
+
a subprocess, fixtures are checked not to satisfy their own assertion, aggregation is tested with
|
|
143
|
+
several items, and messages and exit codes are asserted by content.
|
|
144
|
+
|
|
145
|
+
The 2026-08-20 port to Ruby was audited that way twice, and the second audit is the one worth
|
|
146
|
+
recording. The author's own harness ran 36 mutations and killed 36. Reviewers then ran 12 chosen to
|
|
147
|
+
be disjoint from it and **11 survived** — the harness was not wrong, it was self-authored and
|
|
148
|
+
therefore blind in exactly the places its author was. Ten distinct guards were unheld. The
|
|
149
|
+
structural cause: `L2Scan.derive`, `report` and `main` — 112 of `l2_scan.rb`'s lines — had never
|
|
150
|
+
been called by either suite, so every mutation there survived by construction, and three real
|
|
151
|
+
defects were hiding in that region. All ten are now killed, and `derive`, `report` and
|
|
152
|
+
`marker_string` have their own cases.
|
|
153
|
+
|
|
154
|
+
Some cases pin measured Ruby/Python differences rather than a design constraint, and each names the
|
|
155
|
+
measurement in place. `\w` is ASCII-only in Ruby, which dropped a Japanese tag out of the haystack.
|
|
156
|
+
`String#split`'s limit counts parts where Python's `maxsplit` counted splits, which made a whole
|
|
157
|
+
document its own frontmatter. `File.read(encoding:)` tags an encoding without validating it, where
|
|
158
|
+
Python's `open(encoding=)` decoded and raised — so a memo with one bad byte could write a page that
|
|
159
|
+
was not valid UTF-8 at exit 0. `sort_by` is unstable where Python's `sorted` is stable, and only
|
|
160
|
+
once two distinct key values are present: a first attempt at that case used forty rows of one delta
|
|
161
|
+
and passed against an unstable sort.
|
|
150
162
|
|
|
151
163
|
Nothing runs this suite automatically — `rake test` collects Ruby files only.
|
|
152
164
|
|
|
@@ -23,7 +23,24 @@
|
|
|
23
23
|
"into exit 0 with empty output, which is indistinguishable from a session",
|
|
24
24
|
"where nothing had drifted. The script now handles its own absences and",
|
|
25
25
|
"reports each in one line on stdout, so what is left uncaught is a genuine",
|
|
26
|
-
"defect and should be visible. Measured at 0.
|
|
26
|
+
"defect and should be visible. Measured at 0.27s over 1192 contexts.",
|
|
27
|
+
"",
|
|
28
|
+
"ruby, not python3. python3 was not guaranteed on any host the gem ships",
|
|
29
|
+
"to. The bare `ruby` is not guaranteed either, and saying otherwise here",
|
|
30
|
+
"would be false: /usr/bin/ruby 2.6.10 fails on this script with a 43-line",
|
|
31
|
+
"syntax error and writes no page (measured). The bare form ships anyway,",
|
|
32
|
+
"ruled 2026-08-27 after both alternatives were measured and each costs",
|
|
33
|
+
"more than it buys. An embedded absolute path has to be written by the",
|
|
34
|
+
"projector, which turns an interpreter choice into a core change and pins",
|
|
35
|
+
"every host to the layout this one happens to have. A version check in",
|
|
36
|
+
"this file trades the loud failure above for a quiet one. `rbenv exec`",
|
|
37
|
+
"fails outright wherever rbenv is absent -- a Docker ruby image, a",
|
|
38
|
+
"homebrew install, asdf -- which is strictly worse than the bare form,",
|
|
39
|
+
"since those hosts run the bare form fine. So resolution stays with the",
|
|
40
|
+
"host's PATH. When a host resolves it wrong the result is a visible",
|
|
41
|
+
"syntax error at session start, not a silent empty page, and that",
|
|
42
|
+
"visibility is what makes the bare form acceptable rather than merely",
|
|
43
|
+
"convenient. Ported 2026-08-20, ruled 2026-08-27.",
|
|
27
44
|
"",
|
|
28
45
|
"The command does not begin with kairos-, so projection prints one",
|
|
29
46
|
"non-standard-command warning. That is the projector asking a human to look,",
|
|
@@ -36,7 +53,7 @@
|
|
|
36
53
|
"hooks": [
|
|
37
54
|
{
|
|
38
55
|
"type": "command",
|
|
39
|
-
"command": "
|
|
56
|
+
"command": "ruby \"${KAIROS_DATA_DIR:-$CLAUDE_PROJECT_DIR/.kairos}/skillsets/project_manager/scripts/pm_l2_report.rb\" --quiet",
|
|
40
57
|
"timeout": 20
|
|
41
58
|
}
|
|
42
59
|
]
|