kairos-chain 3.93.0 → 3.95.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 +97 -0
- data/bin/kairos-chain +2 -0
- data/lib/kairos_mcp/kairos_chain/landed_probe.rb +62 -0
- data/lib/kairos_mcp/knowledge_provider.rb +473 -15
- data/lib/kairos_mcp/l0_proposal_store.rb +82 -0
- data/lib/kairos_mcp/l1_history.rb +257 -0
- data/lib/kairos_mcp/safe_evolver.rb +399 -126
- data/lib/kairos_mcp/skillset.rb +21 -0
- data/lib/kairos_mcp/skillset_manager.rb +58 -13
- data/lib/kairos_mcp/storage/importer.rb +50 -0
- data/lib/kairos_mcp/tools/chain_import.rb +15 -3
- data/lib/kairos_mcp/tools/knowledge_update.rb +37 -3
- data/lib/kairos_mcp/tools/skills_evolve.rb +34 -8
- data/lib/kairos_mcp/tools/skills_rollback.rb +94 -6
- data/lib/kairos_mcp/tools/system_upgrade.rb +2 -0
- data/lib/kairos_mcp/version.rb +1 -1
- data/lib/kairos_mcp/version_manager.rb +29 -14
- 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 +40 -5
- data/templates/skillsets/agent/bin/agent_harvest.rb +28 -0
- data/templates/skillsets/agent/config/policies/masa_2026_10_20.rb +17 -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/precedents.rb +151 -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 +138 -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_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 +1129 -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/call_router.rb +7 -1
- data/templates/skillsets/llm_client/lib/llm_client/claude_code_adapter.rb +21 -2
- data/templates/skillsets/llm_client/skillset.json +1 -1
- data/templates/skillsets/llm_client/test/test_no_fallback_and_isolation.rb +113 -0
- data/templates/skillsets/llm_client/tools/llm_call.rb +20 -2
- metadata +57 -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: 3bce3f299f0bb91ecbb6199e464a2ea24602ede6e9d4e972c1a7b5905ec447c5
|
|
4
|
+
data.tar.gz: 4986b9e4f8c87ff233b67586791d8b3068aed4decaecb1319f5c0553b4a5445c
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: a4af517774c9e5e90299d4877190d83659932acf7851bf04275d5c3066298411ca628084a490cfef6348b327d550c05d5cc4f96cab086e5c297e2a169e1f72b3
|
|
7
|
+
data.tar.gz: ba67dc90461e4350615a4ba9e232702efc27b241fa853a2934a80714bb5753c2aa1ebba06921ebe58e4db7145d8f3fb5d747be4ab37f8ad5da25150ab8c7ce8d
|
data/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,103 @@ This project follows [Semantic Versioning](https://semver.org/).
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
+
## [3.95.0] - 2026-10-21
|
|
10
|
+
|
|
11
|
+
### Changed — the `agent` SkillSet is rebuilt (1.0): long runs in the host session, a stand-in instead of terminal approvals
|
|
12
|
+
|
|
13
|
+
The 0.x agent could not carry the operator's ordinary request (design → design review → implement →
|
|
14
|
+
implementation review): its act route wrote only `docs/drafts/draft_*`, could not reach multi-LLM review or
|
|
15
|
+
tests, and counted only terminal-attested answers (0 counted pairs). Design:
|
|
16
|
+
`log/agent_skillset_rebuild_design_v0.5.1_20261020.md` (five review rounds, frozen as the author's proposal)
|
|
17
|
+
and its delta `log/agent_skillset_rebuild_design_v0.6.3_20261020.md`.
|
|
18
|
+
|
|
19
|
+
- The host session (Claude Code) is the only body. The SkillSet supplies a plan from a Ruby-DSL template, a
|
|
20
|
+
stand-in (isolated `claude -p --safe-mode --tools ""`, Opus 5.5) that answers decision points from the
|
|
21
|
+
operator's own words and the instruction mode, a guard (host hooks: `PreToolUse` on every tool, fail-closed)
|
|
22
|
+
that lets through only what the run created or its worktree and branch hold, a hash-chained journal, and a
|
|
23
|
+
report check. Six tools: `agent_start`, `agent_status`, `agent_advance`, `agent_items`, `agent_finish`,
|
|
24
|
+
`agent_stop`.
|
|
25
|
+
- Runs need an adopted policy (the operator's mandate, `config/policies/*.rb`), adopted by the operator's own
|
|
26
|
+
typed words naming its digest; the adoption is recorded on the chain.
|
|
27
|
+
- Templates: `dev_cycle`, `impl_cycle`, `design_only`, `doc_cycle` (a document kept in git, revised in place,
|
|
28
|
+
optional build check), `survey` (versioned survey files from local sources), `general`.
|
|
29
|
+
- A review closes only when no (a)/(b) P0 is open. Each review may take the policy's `review_rounds`
|
|
30
|
+
(10), counted for that review alone; at the cap it waits for the operator, who grants more rounds or
|
|
31
|
+
freezes it. Revisions follow L1 multi_llm_review_workflow § Revision
|
|
32
|
+
Discipline: each round says which new P0s the actor's last addition drew, and the next step is to undo it.
|
|
33
|
+
Design reviews stay at the design level; implementation-only findings are deferred to the implementation
|
|
34
|
+
review and are operator items at once.
|
|
35
|
+
- Every run ends with a layered-deck report (`report_kit/`, the kit of L1 `layered_visual_pitch_deck`).
|
|
36
|
+
- `bin/agent_harvest.rb` harvests the operator's own answers from host transcripts (hook output, peer
|
|
37
|
+
messages and pasted host output excluded).
|
|
38
|
+
- Removed: the in-server OODA loop, act-route table and terminal rulings, shadow judge, distillation,
|
|
39
|
+
native body, `agent_execute`, `agent_step`, `agent_wait`, `operator_report`, the `agent-monitor` subagent.
|
|
40
|
+
- `agent` is no longer installed automatically in new instances (it needs a policy and projects hooks).
|
|
41
|
+
An installed 0.x agent becomes 1.0 on upgrade. 1.0 needs `multi_llm_review` and `llm_client` >= 0.3.0 in
|
|
42
|
+
the same instance; upgrade does not install a missing one (`kairos-chain skillset install multi_llm_review`).
|
|
43
|
+
|
|
44
|
+
### Added — `removed_files` in `skillset.json`; `system_upgrade` archives them
|
|
45
|
+
|
|
46
|
+
`upgrade_apply` copied changed files and never deleted one, so a SkillSet that dropped files left them to be
|
|
47
|
+
loaded. A template may now list `removed_files`; upgrade moves each from the installed copy to
|
|
48
|
+
`storage/skillset_removed/<name>/<time>/`, and a forced reinstall no longer restores a retired config file.
|
|
49
|
+
|
|
50
|
+
### Added — `llm_call` options `no_fallback` and `isolated`
|
|
51
|
+
|
|
52
|
+
`no_fallback` makes an authentication failure on the configured provider a failure instead of a silent switch
|
|
53
|
+
to `claude_code`. `isolated` (claude_code) runs `claude -p --safe-mode --tools ""` in an empty directory, so
|
|
54
|
+
no CLAUDE.md, skills, plugins, hooks, memory or MCP servers reach the call. An isolated call's payload carries
|
|
55
|
+
`isolation` (`safe_mode`, `tools`, `cwd`, as `claude -p` was spawned); llm_client is 0.3.0. The agent's
|
|
56
|
+
stand-in refuses any reply without that evidence (and refuses to call an llm_client too old to isolate), and the
|
|
57
|
+
agent SkillSet declares `llm_client >= 0.3.0`; upgrade both together.
|
|
58
|
+
|
|
59
|
+
### Added — `user_level_conflicts` in `skillset.json`; install and upgrade report them
|
|
60
|
+
|
|
61
|
+
A SkillSet may list files an earlier version left at user level that it cannot remove itself (e.g. a personal
|
|
62
|
+
skill that shadows the project's). `install`, `upgrade_apply`, `system_upgrade` and `kairos-chain skillset
|
|
63
|
+
install/upgrade` print the ones present as warnings, with a command that moves them to a timestamped backup.
|
|
64
|
+
agent 1.0 lists the 0.x personal skill `~/.claude/skills/agent/SKILL.md` and `~/.claude/agents/agent-monitor.md`.
|
|
65
|
+
|
|
66
|
+
### Changed — the shipped agent policy needs a new adoption
|
|
67
|
+
|
|
68
|
+
`masa_2026_10_20.rb` sets `review_rounds` to 10 rounds for each review (counted apart, no longer shared by a
|
|
69
|
+
run's reviews) and drops the lookup consent comment (runs never look things up on the web). Its digest
|
|
70
|
+
changed: adopt it with `adopt policy masa_2026_10_20 8846b67e`.
|
|
71
|
+
|
|
72
|
+
### Changed — L1 `multi_llm_review_workflow` 3.16.0 and `design_to_implementation_workflow` 1.3
|
|
73
|
+
|
|
74
|
+
A new entry-level clause, § Provisional delegation under a mandate: under a pinned, journaled operator policy a
|
|
75
|
+
named delegate — never the context whose work is judged — answers reserved judgments provisionally, and nothing
|
|
76
|
+
resolves, closes, freezes or demotes beyond the run until the operator confirms it in their own words. Pointers
|
|
77
|
+
from INV-U2, INV-U4, INV-U5, Step 0.25 and § Convergence Rules, and from the merge criteria of
|
|
78
|
+
`design_to_implementation_workflow`. An instance's own L1 copy is not rewritten by upgrade.
|
|
79
|
+
|
|
80
|
+
## [3.94.0] - 2026-10-20
|
|
81
|
+
|
|
82
|
+
### Added — L0 changes proposed for later approval, L0 restores on the record, L1 body history
|
|
83
|
+
|
|
84
|
+
- **L0 proposals.** `skills_evolve` keeps a pending L0 change as (base, result,
|
|
85
|
+
content) without evaluating it; `command: "pending"` lists the proposals and
|
|
86
|
+
`apply` takes a `proposal_id`. Applying writes exactly the stored bytes under
|
|
87
|
+
an exclusive lock, only while the base is still the L0 in force and the
|
|
88
|
+
content hashes to its result. A failed load, an interrupt or a killed thread
|
|
89
|
+
never leaves an unrecorded L0 on disk.
|
|
90
|
+
- **L0 restore on the record.** `skills_rollback` restores a snapshot only if
|
|
91
|
+
its hash appears in a transition recorded on the chain. Without
|
|
92
|
+
`approved: true` it writes nothing and returns a pending proposal; with
|
|
93
|
+
`proposal_id` the approval applies exactly the proposal that was shown.
|
|
94
|
+
- **L1 body history.** `knowledge_update` gains `history`, `restore` and
|
|
95
|
+
`erase_body` (the last is irreversible and needs `approved: true`). Bodies
|
|
96
|
+
are kept by content address from a recorded activation point, and restore and
|
|
97
|
+
erasure decide from the chain whether their record landed.
|
|
98
|
+
|
|
99
|
+
### Changed — read before upgrading
|
|
100
|
+
|
|
101
|
+
- `VersionManager.rollback` is removed; nothing shipped calls it. Code that
|
|
102
|
+
called it should use `skills_rollback` with a `proposal_id`.
|
|
103
|
+
- `chain_import` never overwrites an existing chain: it is refused when the
|
|
104
|
+
target already holds chain data. Import into a new data directory instead.
|
|
105
|
+
|
|
9
106
|
## [3.93.0] - 2026-10-19
|
|
10
107
|
|
|
11
108
|
### Added — `proactive_tutorial`, an opt-in mode that suggests KairosChain's own workflow
|
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}"
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'json'
|
|
4
|
+
require_relative 'chain'
|
|
5
|
+
|
|
6
|
+
module KairosMcp
|
|
7
|
+
module KairosChain
|
|
8
|
+
# Answers "did this exact entry reach the ledger?" after an append did not
|
|
9
|
+
# return normally.
|
|
10
|
+
#
|
|
11
|
+
# Chain#add_block raises Storage::Error when it cannot tell whether the
|
|
12
|
+
# write landed, and a thread can be interrupted after the write but before
|
|
13
|
+
# add_block returns. Either way the caller holds a change it must keep
|
|
14
|
+
# (the record is on the chain) or undo (it is not). Looking only at the last
|
|
15
|
+
# block answers wrongly once anything else has been appended since, so the
|
|
16
|
+
# caller takes a mark before appending and the probe scans every block after
|
|
17
|
+
# that mark for an entry equal to the one the caller tried to append.
|
|
18
|
+
module LandedProbe
|
|
19
|
+
# The ledger length now, i.e. the index from which the caller's block can
|
|
20
|
+
# appear. nil when the ledger cannot be read; every later status is then
|
|
21
|
+
# :unknown.
|
|
22
|
+
def self.mark(storage_backend: nil)
|
|
23
|
+
chain = Chain.new(storage_backend: storage_backend)
|
|
24
|
+
case chain.load_state
|
|
25
|
+
when :readable then chain.chain.length
|
|
26
|
+
when :absent then 0
|
|
27
|
+
end
|
|
28
|
+
rescue StandardError
|
|
29
|
+
nil
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# :landed -- a block after the mark carries an entry equal to entry_json
|
|
33
|
+
# :absent -- the ledger is readable (or absent) and no such entry is there
|
|
34
|
+
# :unknown -- the mark or the ledger could not be read
|
|
35
|
+
#
|
|
36
|
+
# Equality is on the parsed entry, so a backend that re-serialises the JSON
|
|
37
|
+
# still matches. Only StandardError is absorbed: an interrupt during the
|
|
38
|
+
# probe propagates, and callers run their undo in an ensure for that case.
|
|
39
|
+
def self.status(mark, entry_json, storage_backend: nil)
|
|
40
|
+
return :unknown if mark.nil?
|
|
41
|
+
|
|
42
|
+
expected = JSON.parse(entry_json)
|
|
43
|
+
chain = Chain.new(storage_backend: storage_backend)
|
|
44
|
+
return :absent if chain.load_state == :absent
|
|
45
|
+
return :unknown unless chain.load_state == :readable
|
|
46
|
+
|
|
47
|
+
found = chain.chain.drop(mark).any? do |block|
|
|
48
|
+
Array(block.data).any? do |raw|
|
|
49
|
+
begin
|
|
50
|
+
JSON.parse(raw.to_s) == expected
|
|
51
|
+
rescue JSON::ParserError
|
|
52
|
+
false
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
found ? :landed : :absent
|
|
57
|
+
rescue StandardError
|
|
58
|
+
:unknown
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|