Module: Browserctl::Workflow::PromotionLedger
- Defined in:
- lib/browserctl/workflow/promotion_ledger.rb
Overview
Append-only JSONL ledger of ‘workflow run –check` outcomes per workflow. Used as the gate for `workflow promote`: only workflows with a sufficient streak of clean runs are eligible for promotion to `~/.browserctl/workflows/`.
Record schema (one JSONL line):
{ "ts": "2026-05-10T12:00:00Z", "workflow": "name", "verdict": "clean" }
Constant Summary collapse
- LEDGER_BASENAME =
"check_ledger.jsonl"- DEFAULT_THRESHOLD =
3- VALID_VERDICTS =
%i[clean drift fail].freeze
Class Method Summary collapse
-
.clean_streak(workflow:, path: ledger_path) ⇒ Integer
Count the trailing streak of :clean verdicts for a workflow.
- .ledger_path ⇒ Object
- .parse(line) ⇒ Object
-
.record(workflow:, verdict:, path: ledger_path, at: Time.now.utc) ⇒ Object
Append a verdict for a workflow run.
Class Method Details
.clean_streak(workflow:, path: ledger_path) ⇒ Integer
Count the trailing streak of :clean verdicts for a workflow. A non-clean verdict resets the streak. Drift and fail both break it — the gate is intentionally strict; users can override with –force.
48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
# File 'lib/browserctl/workflow/promotion_ledger.rb', line 48 def clean_streak(workflow:, path: ledger_path) return 0 unless File.exist?(path) streak = 0 File.foreach(path) do |line| entry = parse(line) or next next unless entry["workflow"] == workflow.to_s if entry["verdict"] == "clean" streak += 1 else streak = 0 end end streak end |
.ledger_path ⇒ Object
23 24 25 |
# File 'lib/browserctl/workflow/promotion_ledger.rb', line 23 def ledger_path File.join(Browserctl::BROWSERCTL_DIR, LEDGER_BASENAME) end |
.parse(line) ⇒ Object
65 66 67 68 69 |
# File 'lib/browserctl/workflow/promotion_ledger.rb', line 65 def parse(line) JSON.parse(line) rescue JSON::ParserError nil end |
.record(workflow:, verdict:, path: ledger_path, at: Time.now.utc) ⇒ Object
Append a verdict for a workflow run.
31 32 33 34 35 36 37 38 39 40 41 42 |
# File 'lib/browserctl/workflow/promotion_ledger.rb', line 31 def record(workflow:, verdict:, path: ledger_path, at: Time.now.utc) return unless VALID_VERDICTS.include?(verdict) FileUtils.mkdir_p(File.dirname(path)) File.open(path, "a") do |f| f.puts JSON.generate( ts: at.iso8601, workflow: workflow.to_s, verdict: verdict.to_s ) end end |