kairos-chain 3.61.0 → 3.61.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d38191ff3e513822d6183bf4fee4c92e497148978eda3bda064a01b81d0bf95b
4
- data.tar.gz: 97999aa9377a086ea092237ad53605fec24b9e01c9691e7c92c24b6329bd565e
3
+ metadata.gz: c28f2a9c842f5082b555797ea60f24d1435df8fcf80738556c88ffe341358468
4
+ data.tar.gz: 2cc735c1cf6c0cf86599c287cf1e9b095bad22e3de2f0e9055cf2bdf346a6b1c
5
5
  SHA512:
6
- metadata.gz: eacfebd73445ea5e6a503bb34e8978a0a6c649d34a46810140a885f235e3933b01701d45921341b6771caa64c58f4dac61f51233d2741417e8b59be111196109
7
- data.tar.gz: bffb450e4de67e1b3c179de5bd48b86d1d6d3c2bc8e69cd6878fd6d89b6e3346fae29b09cd5ef79ddbb12f16498e0f944da84af4a62b3a36eff0db05ea5b6d96
6
+ metadata.gz: 0e31b37f68c678274b1d3ea35dd5f9ce056971dc3e85f7697ee8203d8100a18261bb87ff425718f8bd7b4ce2c9d0b2c200b2b890aaf14dd6bd9e2367c722fc6e
7
+ data.tar.gz: af1ff31f3b3a8eac300e77b40d33fc8d41fa783be45c1cade91c88259dd9d456cd26a125b477127c869b324129357b0081d8bbfd12ee6b7a9bc73552eeb92f35
data/CHANGELOG.md CHANGED
@@ -4,6 +4,29 @@ 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.61.1] - 2026-08-06
8
+
9
+ ### Fixed
10
+
11
+ - **`multi_llm_review` (SkillSet 0.9.1) — a sandboxed reviewer seat is told it has no file
12
+ access.** The `claude_cli_opus4.6` subprocess seat left four consecutive implementation-review
13
+ rounds as `no_verdict`: launched with all tools disabled in an empty working directory
14
+ (deliberate — it keeps CLAUDE.md out of the reviewer's context), it tried to read the file
15
+ paths the artifact cited, opening two rounds with pseudo-tool-call markup and one with "the
16
+ repository is not accessible" before its verdict line — which the positional verdict reader
17
+ correctly refuses. The same seat counted every round on design artifacts in the same period,
18
+ so the seat was healthy and the prompt was the gap.
19
+
20
+ `PromptBuilder` now emits a `<seat_access>` block beside the inline artifact: a seat that
21
+ cannot read the repository must not attempt tool calls and must not open by saying it will
22
+ read files; it reviews the artifact text alone, marks unverifiable claims `[INFERRED]`, and
23
+ still opens with its verdict line. The wording is conditional because seats differ (codex
24
+ runs `--sandbox read-only` and can read the repository), and the block is not emitted for
25
+ by_reference delivery, whose existing cannot-read instruction it would contradict. One test
26
+ pins both directions. `<seat_access>` is not in `Sanitizer::WRAPPER_TAGS`; it sits in the
27
+ documented unescaped prompt-frame gap alongside `<task>` and `<grounding_rules>` — widening
28
+ that set is a recorded backlog question, not part of this fix.
29
+
7
30
  ## [3.61.0] - 2026-08-06
8
31
 
9
32
  ### Fixed
@@ -1,4 +1,4 @@
1
1
  module KairosMcp
2
- VERSION = "3.61.0"
2
+ VERSION = "3.61.1"
3
3
  CHANGELOG_URL = "https://github.com/masaomi/KairosChain_2026/blob/main/CHANGELOG.md"
4
4
  end
@@ -128,6 +128,8 @@ module KairosMcp
128
128
  parts << "<artifact>"
129
129
  parts << artifact_content
130
130
  parts << "</artifact>"
131
+ parts << ""
132
+ parts << seat_access_note
131
133
  end
132
134
  parts << ""
133
135
  parts << grounding_rules
@@ -173,6 +175,30 @@ module KairosMcp
173
175
  CONTRACT
174
176
  end
175
177
 
178
+ # Why this note exists (2026-08-06): the claude_code subprocess seat
179
+ # runs with tools disabled in an empty working directory, and on
180
+ # implementation artifacts that cite file paths it tried to read the
181
+ # code before judging — two rounds opened with pseudo-tool-call markup
182
+ # and one with "the repository is not accessible", so the verdict
183
+ # header never came first and the seat left the denominator as
184
+ # no_verdict four rounds in a row (the same seat counted every round
185
+ # on design artifacts in the same period). The wording is conditional
186
+ # because seats differ — codex runs `--sandbox read-only` and can
187
+ # verify against the repository — and the note is emitted only with an
188
+ # inline artifact: by_reference delivery already instructs a seat that
189
+ # cannot read the file to say so instead of reviewing.
190
+ def seat_access_note
191
+ <<~NOTE
192
+ <seat_access>
193
+ Your seat may have no file-system or tool access. If you cannot
194
+ read the repository, do not attempt tool calls and do not open by
195
+ saying you will read files: review the artifact text above on its
196
+ own, mark claims you cannot verify as [INFERRED], and still put
197
+ your verdict line first.
198
+ </seat_access>
199
+ NOTE
200
+ end
201
+
176
202
  def grounding_rules
177
203
  <<~RULES
178
204
  <grounding_rules>
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "multi_llm_review",
3
- "version": "0.9.0",
4
- "description": "v0.9.0 (evidence fidelity, frozen 2026-08-06 after six review rounds): a finding reaches the record whole. It used to be cut at 201 bytes by an inclusive Range in aggregation and bounded again by the 500-character display limit, so a downstream instance measured 18 of 21 findings arriving at exactly 201 bytes with reviews[].raw_text empty on every row. Findings are now bounded in BYTES at FINDING_RECORD_MAX_LEN = 8000 for the record, with DEFAULT_MAX_LEN = 500 still applied by every path that takes a finding into a prompt. Deduplication still keys on the first 80 characters — widening it would stop two reviewers describing one defect from merging, moving the finding count and the convergence denominator — but the surviving text is no longer arbitrary: issue comes from a member whose severity equals the merged severity, distinct texts survive in issue_variants (capped at MAX_ISSUE_VARIANTS = 8, with issue_variants_omitted naming what the cap dropped). Every row now carries raw_text_excerpt unconditionally (4096 bytes) and the reviewer's reply in raw_text on request (include_raw_text, 65536 bytes). Both are SANITISED TRANSCRIPTIONS, not verbatim records, and both tool schemas say so: the text is byte-clamped, NFKC-normalised, stripped of invisible characters, tag-escaped, then byte-clamped again. No field states whether they hold the whole reply, because nothing in this SkillSet can know — a completeness flag was implemented, measured wrong in both directions, and removed. On delegated runs the pending-state record keeps each subprocess reply as it arrived; on single-phase runs the returned payload is the only form there is. Findings carried into a later round's prompt are sanitised and folded to one line, a path that previously took reviewer text into a prompt with no sanitisation at all. v0.8.0 (v0.7 record schema, design frozen 2026-08-01): the verdict vocabulary is the three canonical words plus tense forms only (INV-R1); the ratio and threshold are recorded reference values, not the run's conclusion — the top-level verdict field became reference_verdict and the run is closed by the operator's declaration outside the record (INV-R2); the persona team occupies one seat, its derivation rule is recorded, and a submission smaller than convened — including empty — is accepted with the shortfall on the record (INV-R3/R4); every run writes an existence marker at dispatch, completed records are never garbage-collected, and expired runs are reduced to a minimal trace instead of erased (INV-R4); a divergence-excluded tally is carried beside the main one (INV-R5); the record names its pre-declared spec and carries transport diagnostics as state tags (INV-R6); artifact delivery is a per-seat attribute (inline | by_reference) and an unreachable delivery is refused rather than dispatched (INV-R7). Parallel multi-LLM review orchestration. Dispatches review prompts to N LLM backends via llm_client, collects verdicts, and computes consensus. v0.6.0: reserve observers (escalate) and a declarable persona execution model; the observer set is built in one pass with explicit precedence (ObserverSet); every slot must name its model and role_label, and duplicate names — including the persona team's own — are refused. A reply's verdict is no longer inferred from its prose: it is read from a declared field, from the header the reply opens with when that header carries a verdict name and nothing else, or not at all, in which case the reply leaves the denominator with no_verdict recorded beside its name. The record says why every observer did or did not count (denominator_composition, five skip_reason values, observers_reporting), and the per-reviewer row is written by one mapping rather than two. v0.5.2: the cursor reviewer pins model composer-2.5 instead of inheriting the cursor CLI default, which is operator-editable and had silently become an Anthropic model. v0.5.1: Fable 5 retired from the roster (five consecutive silent returns), convergence 3/5; orchestrator_model description now states the bare-ID rule so a caller does not review its own output. v0.5.0: adds multi_llm_review_wait (Phase 1.5) for explicit subprocess completion gating with next_action recovery hints, and Path A/B doc disambiguation. v0.4.0 (Phase 12): feedback_text + schema_version, sanitization contract for prompt-injection defense, and multi_llm_review_bundle tool for human-handoff paths without dispatch.",
3
+ "version": "0.9.1",
4
+ "description": "v0.9.1 (seat access, frozen 2026-08-06 after a one-round review): reviewer prompts carry a <seat_access> block beside the inline artifact — a seat that cannot read the repository must not attempt tool calls and must not open by saying it will read files; it reviews the artifact text alone, marks unverifiable claims [INFERRED], and still opens with its verdict line. The wording is conditional because seats differ (codex runs --sandbox read-only and can read the repository), and the block is not emitted for by_reference delivery, whose existing cannot-read instruction it would contradict. Root cause fixed: the claude subprocess seat runs with tools disabled in an empty working directory, and on implementation artifacts citing file paths it opened with pseudo-tool-call markup or a cannot-access preamble instead of its verdict line, leaving four consecutive rounds as no_verdict while counting every round on design artifacts. v0.9.0 (evidence fidelity, frozen 2026-08-06 after six review rounds): a finding reaches the record whole. It used to be cut at 201 bytes by an inclusive Range in aggregation and bounded again by the 500-character display limit, so a downstream instance measured 18 of 21 findings arriving at exactly 201 bytes with reviews[].raw_text empty on every row. Findings are now bounded in BYTES at FINDING_RECORD_MAX_LEN = 8000 for the record, with DEFAULT_MAX_LEN = 500 still applied by every path that takes a finding into a prompt. Deduplication still keys on the first 80 characters — widening it would stop two reviewers describing one defect from merging, moving the finding count and the convergence denominator — but the surviving text is no longer arbitrary: issue comes from a member whose severity equals the merged severity, distinct texts survive in issue_variants (capped at MAX_ISSUE_VARIANTS = 8, with issue_variants_omitted naming what the cap dropped). Every row now carries raw_text_excerpt unconditionally (4096 bytes) and the reviewer's reply in raw_text on request (include_raw_text, 65536 bytes). Both are SANITISED TRANSCRIPTIONS, not verbatim records, and both tool schemas say so: the text is byte-clamped, NFKC-normalised, stripped of invisible characters, tag-escaped, then byte-clamped again. No field states whether they hold the whole reply, because nothing in this SkillSet can know — a completeness flag was implemented, measured wrong in both directions, and removed. On delegated runs the pending-state record keeps each subprocess reply as it arrived; on single-phase runs the returned payload is the only form there is. Findings carried into a later round's prompt are sanitised and folded to one line, a path that previously took reviewer text into a prompt with no sanitisation at all. v0.8.0 (v0.7 record schema, design frozen 2026-08-01): the verdict vocabulary is the three canonical words plus tense forms only (INV-R1); the ratio and threshold are recorded reference values, not the run's conclusion — the top-level verdict field became reference_verdict and the run is closed by the operator's declaration outside the record (INV-R2); the persona team occupies one seat, its derivation rule is recorded, and a submission smaller than convened — including empty — is accepted with the shortfall on the record (INV-R3/R4); every run writes an existence marker at dispatch, completed records are never garbage-collected, and expired runs are reduced to a minimal trace instead of erased (INV-R4); a divergence-excluded tally is carried beside the main one (INV-R5); the record names its pre-declared spec and carries transport diagnostics as state tags (INV-R6); artifact delivery is a per-seat attribute (inline | by_reference) and an unreachable delivery is refused rather than dispatched (INV-R7). Parallel multi-LLM review orchestration. Dispatches review prompts to N LLM backends via llm_client, collects verdicts, and computes consensus. v0.6.0: reserve observers (escalate) and a declarable persona execution model; the observer set is built in one pass with explicit precedence (ObserverSet); every slot must name its model and role_label, and duplicate names — including the persona team's own — are refused. A reply's verdict is no longer inferred from its prose: it is read from a declared field, from the header the reply opens with when that header carries a verdict name and nothing else, or not at all, in which case the reply leaves the denominator with no_verdict recorded beside its name. The record says why every observer did or did not count (denominator_composition, five skip_reason values, observers_reporting), and the per-reviewer row is written by one mapping rather than two. v0.5.2: the cursor reviewer pins model composer-2.5 instead of inheriting the cursor CLI default, which is operator-editable and had silently become an Anthropic model. v0.5.1: Fable 5 retired from the roster (five consecutive silent returns), convergence 3/5; orchestrator_model description now states the bare-ID rule so a caller does not review its own output. v0.5.0: adds multi_llm_review_wait (Phase 1.5) for explicit subprocess completion gating with next_action recovery hints, and Path A/B doc disambiguation. v0.4.0 (Phase 12): feedback_text + schema_version, sanitization contract for prompt-injection defense, and multi_llm_review_bundle tool for human-handoff paths without dispatch.",
5
5
  "author": "Masaomi Hatakeyama",
6
6
  "layer": "L1",
7
7
  "depends_on": [
@@ -426,6 +426,26 @@ module KairosMcp
426
426
  assert_includes messages[0]['content'], 'Initial review'
427
427
  end
428
428
 
429
+ def test_seat_access_note_inline_only
430
+ inline = PromptBuilder.build_messages(
431
+ artifact_content: 'test code here',
432
+ artifact_name: 'test_artifact',
433
+ review_type: 'implementation',
434
+ review_round: 1
435
+ )
436
+ assert_includes inline[0]['content'], '<seat_access>'
437
+ assert_includes inline[0]['content'], 'verdict line first'
438
+
439
+ by_ref = PromptBuilder.build_messages(
440
+ artifact_name: 'test_artifact',
441
+ review_type: 'implementation',
442
+ review_round: 1,
443
+ artifact_reference: { path: 'log/x.md', sha256: 'a' * 64 }
444
+ )
445
+ refute_includes by_ref[0]['content'], '<seat_access>',
446
+ 'by_reference delivery keeps its own cannot-read instruction; the note must not contradict it'
447
+ end
448
+
429
449
  def test_build_messages_with_prior_findings
430
450
  prior = [
431
451
  { severity: 'P0', issue: 'Missing validation', cited_by: ['r1', 'r2'] }
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kairos-chain
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.61.0
4
+ version: 3.61.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Masaomi Hatakeyama