reeve 0.6.0 → 0.8.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 +293 -3
- data/README.md +276 -11
- data/lib/generators/reeve/install/templates/create_audit_entries.rb.tt +52 -5
- data/lib/generators/reeve/install/templates/initializer.rb.tt +10 -0
- data/lib/generators/reeve/upgrade/templates/add_key_epochs_to_reeve_audit_entries.rb.tt +35 -0
- data/lib/generators/reeve/upgrade/templates/add_ledger_retention_to_reeve_audit_entries.rb.tt +37 -0
- data/lib/generators/reeve/upgrade/upgrade_generator.rb +19 -25
- data/lib/generators/reeve/upgrade/upgrade_notes.rb +62 -0
- data/lib/reeve/audit/chain/anchoring.rb +91 -0
- data/lib/reeve/audit/chain/canonical.rb +38 -7
- data/lib/reeve/audit/chain/checkpoint.rb +228 -0
- data/lib/reeve/audit/chain/checkpoint_check.rb +156 -0
- data/lib/reeve/audit/chain/entrypoints.rb +29 -0
- data/lib/reeve/audit/chain/epoch_rules.rb +159 -0
- data/lib/reeve/audit/chain/epochs.rb +83 -0
- data/lib/reeve/audit/chain/head.rb +55 -2
- data/lib/reeve/audit/chain/keyring.rb +6 -0
- data/lib/reeve/audit/chain/report.rb +232 -32
- data/lib/reeve/audit/chain/retention/archive.rb +98 -0
- data/lib/reeve/audit/chain/retention/archive_check.rb +179 -0
- data/lib/reeve/audit/chain/retention/check.rb +94 -0
- data/lib/reeve/audit/chain/retention/connection.rb +65 -0
- data/lib/reeve/audit/chain/retention/digest.rb +29 -0
- data/lib/reeve/audit/chain/retention/plan.rb +100 -0
- data/lib/reeve/audit/chain/retention/preflight.rb +48 -0
- data/lib/reeve/audit/chain/retention/purge.rb +155 -0
- data/lib/reeve/audit/chain/retention/purge_result.rb +134 -0
- data/lib/reeve/audit/chain/retention/records.rb +23 -0
- data/lib/reeve/audit/chain/rotation.rb +124 -0
- data/lib/reeve/audit/chain/schema.rb +59 -0
- data/lib/reeve/audit/chain/verification.rb +53 -10
- data/lib/reeve/audit/chain/verifier.rb +75 -22
- data/lib/reeve/audit/chain/walk.rb +24 -4
- data/lib/reeve/audit/chain.rb +61 -13
- data/lib/reeve/audit/chain_epoch.rb +24 -0
- data/lib/reeve/audit/chain_record.rb +14 -8
- data/lib/reeve/audit/file_anchor.rb +49 -0
- data/lib/reeve/audit/retention_record.rb +24 -0
- data/lib/reeve/audit.rb +30 -3
- data/lib/reeve/configuration.rb +25 -0
- data/lib/reeve/errors.rb +15 -0
- data/lib/reeve/railtie.rb +2 -1
- data/lib/reeve/tasks/descriptions.rb +22 -0
- data/lib/reeve/tasks/purge_options.rb +54 -0
- data/lib/reeve/tasks.rb +104 -7
- data/lib/reeve/testing/checks/contract_version.rb +2 -2
- data/lib/reeve/testing/checks/ledger_chain.rb +56 -2
- data/lib/reeve/testing/ledger.rb +19 -3
- data/lib/reeve/version.rb +1 -1
- metadata +28 -2
|
@@ -20,13 +20,25 @@ module Reeve
|
|
|
20
20
|
# * **nothing to write or read** (no compliance tools, ledger not loaded) — skipped,
|
|
21
21
|
# saying the chain was not verified. Never passed.
|
|
22
22
|
#
|
|
23
|
+
# With `anchored: true` (specs/004 research R8) it also makes a checkpoint after writing,
|
|
24
|
+
# publishes it through config.ledger_anchor, reads the anchor back, and verifies against
|
|
25
|
+
# that checkpoint alone. It passes only when the chain is intact and anchored at it: what
|
|
26
|
+
# a host's CI can prove is that its anchor is configured and round-trips. Whether
|
|
27
|
+
# production's checkpoints match production is the scheduled verify_ledger's job. Without
|
|
28
|
+
# it, the anchor is never read.
|
|
29
|
+
#
|
|
23
30
|
# Reeve::Checks::LedgerChain.new.call
|
|
31
|
+
# Reeve::Checks::LedgerChain.new(anchored: true).call
|
|
24
32
|
class LedgerChain < Base
|
|
25
33
|
NOT_VERIFIED = "the ledger chain was not verified"
|
|
34
|
+
NOT_ANCHORED = "expected the ledger to be anchored"
|
|
35
|
+
NOT_RETURNED = "the checkpoint it published did not come back from config.ledger_anchor"
|
|
26
36
|
|
|
27
|
-
def initialize(tools: nil, principals: nil, arguments: {}, invoke: nil, ledger: nil
|
|
37
|
+
def initialize(tools: nil, principals: nil, arguments: {}, invoke: nil, ledger: nil,
|
|
38
|
+
anchored: false)
|
|
28
39
|
@tools = tools
|
|
29
40
|
@principals = principals
|
|
41
|
+
@anchored = anchored
|
|
30
42
|
super(tool: nil, arguments: arguments, invoke: invoke, ledger: ledger)
|
|
31
43
|
end
|
|
32
44
|
|
|
@@ -37,12 +49,54 @@ module Reeve
|
|
|
37
49
|
|
|
38
50
|
unwritten = write_entries
|
|
39
51
|
return unwritten_entry(unwritten) if unwritten
|
|
52
|
+
return judge(ledger.verify_chain) unless @anchored
|
|
40
53
|
|
|
41
|
-
|
|
54
|
+
anchored
|
|
42
55
|
end
|
|
43
56
|
|
|
44
57
|
private
|
|
45
58
|
|
|
59
|
+
def anchored
|
|
60
|
+
return not_anchored("no anchor is configured: set config.ledger_anchor") if anchor.nil?
|
|
61
|
+
unless ledger.respond_to?(:checkpoint!)
|
|
62
|
+
return skipped("this ledger cannot make a checkpoint")
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
checkpoint, failure = round_trip
|
|
66
|
+
return not_anchored(failure) if failure
|
|
67
|
+
|
|
68
|
+
judge_anchored(ledger.verify_chain(checkpoints: [checkpoint]), checkpoint)
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
# The checkpoint it made and read back from the anchor, or why it could not.
|
|
72
|
+
def round_trip
|
|
73
|
+
made = ledger.checkpoint!
|
|
74
|
+
return [nil, made.to_s.lines.first.chomp] unless made&.made? && made.published?
|
|
75
|
+
unless Array(anchor.checkpoints).include?(made.checkpoint.to_line)
|
|
76
|
+
return [nil,
|
|
77
|
+
NOT_RETURNED]
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
[made.checkpoint, nil]
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def anchor
|
|
84
|
+
Reeve.config.ledger_anchor
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def judge_anchored(verification, checkpoint)
|
|
88
|
+
return judge(verification) unless verification&.intact?
|
|
89
|
+
if verification.anchored_at&.head_sequence == checkpoint.head_sequence
|
|
90
|
+
return judge(verification)
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
not_anchored(verification.to_s.lines.first.chomp)
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def not_anchored(reason)
|
|
97
|
+
failed("#{NOT_ANCHORED}, but #{reason}", coverage: :not_anchored)
|
|
98
|
+
end
|
|
99
|
+
|
|
46
100
|
def subject
|
|
47
101
|
@subject ||= Array(@tools || Testing.compliance_tools).first
|
|
48
102
|
end
|
data/lib/reeve/testing/ledger.rb
CHANGED
|
@@ -71,14 +71,30 @@ module Reeve
|
|
|
71
71
|
# The chain's verification of the whole ledger (specs/002), or nil when the ledger is
|
|
72
72
|
# not loaded. The kit's only way to the chain: it names Reeve::Audit::Chain here, at
|
|
73
73
|
# call time, so `require "reeve/testing"` still loads with no ActiveRecord at all.
|
|
74
|
-
|
|
75
|
-
|
|
74
|
+
#
|
|
75
|
+
# Against `checkpoints` only, never the configured anchor's (specs/004 research R8): a
|
|
76
|
+
# test database is emptied between runs, and every checkpoint an earlier run left names
|
|
77
|
+
# a chain that is gone.
|
|
78
|
+
def verify_chain(checkpoints: [])
|
|
79
|
+
return nil unless chain?
|
|
80
|
+
|
|
81
|
+
Reeve::Audit::Chain.verify(entry_class: entry_class, checkpoints: checkpoints)
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
# A checkpoint of the ledger, published to config.ledger_anchor (specs/004), or nil when
|
|
85
|
+
# the ledger is not loaded.
|
|
86
|
+
def checkpoint!
|
|
87
|
+
return nil unless chain?
|
|
76
88
|
|
|
77
|
-
Reeve::Audit::Chain.
|
|
89
|
+
Reeve::Audit::Chain.checkpoint!(entry_class: entry_class)
|
|
78
90
|
end
|
|
79
91
|
|
|
80
92
|
private
|
|
81
93
|
|
|
94
|
+
def chain?
|
|
95
|
+
available? && Reeve::Audit.const_defined?(:Chain, false)
|
|
96
|
+
end
|
|
97
|
+
|
|
82
98
|
def entry_class
|
|
83
99
|
return @entry_class if defined?(@entry_class)
|
|
84
100
|
|
data/lib/reeve/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: reeve
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.8.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Victor Velazquez
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-10-
|
|
11
|
+
date: 2026-10-25 00:00:00.000000000 Z
|
|
12
12
|
dependencies: []
|
|
13
13
|
description: |
|
|
14
14
|
Reeve makes it safe for a Rails application to expose MCP (Model Context Protocol)
|
|
@@ -31,25 +31,49 @@ files:
|
|
|
31
31
|
- lib/generators/reeve/install/templates/create_audit_entries.rb.tt
|
|
32
32
|
- lib/generators/reeve/install/templates/initializer.rb.tt
|
|
33
33
|
- lib/generators/reeve/upgrade/templates/add_contract_version_to_reeve_audit_entries.rb.tt
|
|
34
|
+
- lib/generators/reeve/upgrade/templates/add_key_epochs_to_reeve_audit_entries.rb.tt
|
|
34
35
|
- lib/generators/reeve/upgrade/templates/add_ledger_chain_to_reeve_audit_entries.rb.tt
|
|
36
|
+
- lib/generators/reeve/upgrade/templates/add_ledger_retention_to_reeve_audit_entries.rb.tt
|
|
35
37
|
- lib/generators/reeve/upgrade/upgrade_generator.rb
|
|
38
|
+
- lib/generators/reeve/upgrade/upgrade_notes.rb
|
|
36
39
|
- lib/reeve.rb
|
|
37
40
|
- lib/reeve/audit.rb
|
|
38
41
|
- lib/reeve/audit/chain.rb
|
|
42
|
+
- lib/reeve/audit/chain/anchoring.rb
|
|
39
43
|
- lib/reeve/audit/chain/canonical.rb
|
|
44
|
+
- lib/reeve/audit/chain/checkpoint.rb
|
|
45
|
+
- lib/reeve/audit/chain/checkpoint_check.rb
|
|
46
|
+
- lib/reeve/audit/chain/entrypoints.rb
|
|
47
|
+
- lib/reeve/audit/chain/epoch_rules.rb
|
|
48
|
+
- lib/reeve/audit/chain/epochs.rb
|
|
40
49
|
- lib/reeve/audit/chain/head.rb
|
|
41
50
|
- lib/reeve/audit/chain/keyring.rb
|
|
42
51
|
- lib/reeve/audit/chain/normalizer.rb
|
|
43
52
|
- lib/reeve/audit/chain/report.rb
|
|
53
|
+
- lib/reeve/audit/chain/retention/archive.rb
|
|
54
|
+
- lib/reeve/audit/chain/retention/archive_check.rb
|
|
55
|
+
- lib/reeve/audit/chain/retention/check.rb
|
|
56
|
+
- lib/reeve/audit/chain/retention/connection.rb
|
|
57
|
+
- lib/reeve/audit/chain/retention/digest.rb
|
|
58
|
+
- lib/reeve/audit/chain/retention/plan.rb
|
|
59
|
+
- lib/reeve/audit/chain/retention/preflight.rb
|
|
60
|
+
- lib/reeve/audit/chain/retention/purge.rb
|
|
61
|
+
- lib/reeve/audit/chain/retention/purge_result.rb
|
|
62
|
+
- lib/reeve/audit/chain/retention/records.rb
|
|
63
|
+
- lib/reeve/audit/chain/rotation.rb
|
|
64
|
+
- lib/reeve/audit/chain/schema.rb
|
|
44
65
|
- lib/reeve/audit/chain/verification.rb
|
|
45
66
|
- lib/reeve/audit/chain/verifier.rb
|
|
46
67
|
- lib/reeve/audit/chain/walk.rb
|
|
68
|
+
- lib/reeve/audit/chain_epoch.rb
|
|
47
69
|
- lib/reeve/audit/chain_record.rb
|
|
48
70
|
- lib/reeve/audit/entry.rb
|
|
71
|
+
- lib/reeve/audit/file_anchor.rb
|
|
49
72
|
- lib/reeve/audit/isolated_recorder.rb
|
|
50
73
|
- lib/reeve/audit/query.rb
|
|
51
74
|
- lib/reeve/audit/recorder.rb
|
|
52
75
|
- lib/reeve/audit/redactor.rb
|
|
76
|
+
- lib/reeve/audit/retention_record.rb
|
|
53
77
|
- lib/reeve/authorization.rb
|
|
54
78
|
- lib/reeve/authorization/adapter.rb
|
|
55
79
|
- lib/reeve/authorization/adapters/plain.rb
|
|
@@ -76,6 +100,8 @@ files:
|
|
|
76
100
|
- lib/reeve/rspec.rb
|
|
77
101
|
- lib/reeve/scope_result.rb
|
|
78
102
|
- lib/reeve/tasks.rb
|
|
103
|
+
- lib/reeve/tasks/descriptions.rb
|
|
104
|
+
- lib/reeve/tasks/purge_options.rb
|
|
79
105
|
- lib/reeve/testing.rb
|
|
80
106
|
- lib/reeve/testing/assertions.rb
|
|
81
107
|
- lib/reeve/testing/checks.rb
|