@codyswann/lisa 4.84.10 → 4.85.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.
- package/dist/core/lisa-owned-hash-ledger.d.ts.map +1 -1
- package/dist/core/lisa-owned-hash-ledger.js +34 -0
- package/dist/core/lisa-owned-hash-ledger.js.map +1 -1
- package/dist/core/nightly-e2e-guard-behavior-certificate.js +2 -2
- package/dist/core/nightly-e2e-guard-behavior-certificate.js.map +1 -1
- package/dist/core/upstream-evidence-manifest.d.ts.map +1 -1
- package/dist/core/upstream-evidence-manifest.js +20 -4
- package/dist/core/upstream-evidence-manifest.js.map +1 -1
- package/package.json +4 -4
- package/plugins/lisa/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa/.codex-plugin/skills/lisa-parity-code-review/SKILL.md +28 -3
- package/plugins/lisa/skills/lisa-parity-code-review/SKILL.md +28 -3
- package/plugins/lisa-agy/plugin.json +1 -1
- package/plugins/lisa-agy/skills/lisa-parity-code-review/SKILL.md +28 -3
- package/plugins/lisa-cdk/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk-agy/plugin.json +1 -1
- package/plugins/lisa-cdk-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk-devin/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk-devin/.devin-plugin/plugin.json +1 -1
- package/plugins/lisa-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-copilot/skills/lisa-parity-code-review/SKILL.md +28 -3
- package/plugins/lisa-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cursor/skills/lisa-parity-code-review/SKILL.md +28 -3
- package/plugins/lisa-devin/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-devin/.devin-plugin/plugin.json +1 -1
- package/plugins/lisa-devin/skills/lisa-parity-code-review/SKILL.md +28 -3
- package/plugins/lisa-expo/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-expo/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-expo-agy/plugin.json +1 -1
- package/plugins/lisa-expo-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-expo-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-expo-devin/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-expo-devin/.devin-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-agy/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-devin/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-devin/.devin-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs-agy/plugin.json +1 -1
- package/plugins/lisa-nestjs-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs-devin/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs-devin/.devin-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw-agy/plugin.json +1 -1
- package/plugins/lisa-openclaw-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw-devin/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw-devin/.devin-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser-agy/plugin.json +1 -1
- package/plugins/lisa-phaser-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser-devin/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser-devin/.devin-plugin/plugin.json +1 -1
- package/plugins/lisa-rails/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-rails-agy/plugin.json +1 -1
- package/plugins/lisa-rails-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails-devin/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails-devin/.devin-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript-agy/plugin.json +1 -1
- package/plugins/lisa-typescript-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript-devin/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript-devin/.devin-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki-agy/plugin.json +1 -1
- package/plugins/lisa-wiki-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki-devin/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki-devin/.devin-plugin/plugin.json +1 -1
- package/plugins/src/base/skills/lisa-parity-code-review/SKILL.md +28 -3
- package/rails/copy-overwrite/scripts/lisa-rspec-shards.mjs +747 -0
- package/rails/copy-overwrite/scripts/lisa_rspec_shard_recorder.rb +143 -0
- package/rails/copy-overwrite/scripts/lisa_simplecov_collate.rb +51 -0
- package/rails/create-only/.github/workflows/ci.yml +4 -0
- package/scripts/two-channel-couplings.json +89 -7
- package/typescript/copy-overwrite/.prettierignore +1 -0
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# This file is managed by Lisa and IS replaced on each `lisa` run.
|
|
4
|
+
# Do not edit directly — durable changes belong upstream in Lisa.
|
|
5
|
+
# -----------------------------------------------------------------------------
|
|
6
|
+
# RSpec shard recorder for `quality-rails.yml` `test_shards`.
|
|
7
|
+
#
|
|
8
|
+
# Loaded into one shard leg with `rspec --require`. It does two things, both at
|
|
9
|
+
# `before(:suite)`, when the project's own spec_helper / rails_helper has
|
|
10
|
+
# already required SimpleCov and loaded `.simplecov`:
|
|
11
|
+
#
|
|
12
|
+
# 1. Hands coverage off to the aggregate. `SimpleCov.finalize_merge false`
|
|
13
|
+
# makes this process store its `.resultset.json` and stop there: no
|
|
14
|
+
# report, and no minimum-coverage check against a slice of the suite,
|
|
15
|
+
# which would fail any project whose floor is above what one shard
|
|
16
|
+
# reaches. The aggregate job collates every shard and enforces the
|
|
17
|
+
# project's thresholds once, on the merged result.
|
|
18
|
+
# 2. Writes a run record at the reporter's `close`: the files RSpec itself
|
|
19
|
+
# loaded (`files_to_run`), each example's run time, and where SimpleCov
|
|
20
|
+
# writes. The aggregate proves from these records that every spec file
|
|
21
|
+
# ran exactly once, and folds the timings into the next run's plan.
|
|
22
|
+
#
|
|
23
|
+
# ENVIRONMENT
|
|
24
|
+
# LISA_RSPEC_SHARD "K/N" — this leg's shard. Required.
|
|
25
|
+
# LISA_RSPEC_SHARD_RECORD Path of the run record to write. Required.
|
|
26
|
+
# -----------------------------------------------------------------------------
|
|
27
|
+
|
|
28
|
+
require 'fileutils'
|
|
29
|
+
require 'json'
|
|
30
|
+
require 'pathname'
|
|
31
|
+
|
|
32
|
+
# Hands a shard's coverage to the aggregate and records what RSpec ran.
|
|
33
|
+
module LisaRspecShardRecorder
|
|
34
|
+
SCHEMA_VERSION = 1
|
|
35
|
+
|
|
36
|
+
# Collects example timings and writes the record when the reporter closes.
|
|
37
|
+
class Listener
|
|
38
|
+
def initialize(path:, shard:, configuration:)
|
|
39
|
+
@path = path
|
|
40
|
+
@shard = shard
|
|
41
|
+
@configuration = configuration
|
|
42
|
+
@examples = []
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def example_finished(notification)
|
|
46
|
+
example = notification.example
|
|
47
|
+
@examples << {
|
|
48
|
+
'file' => LisaRspecShardRecorder.relative(example.metadata[:rerun_file_path] || example.file_path),
|
|
49
|
+
'run_time' => example.execution_result.run_time.to_f,
|
|
50
|
+
'status' => example.execution_result.status.to_s
|
|
51
|
+
}
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def close(_notification)
|
|
55
|
+
FileUtils.mkdir_p(File.dirname(@path))
|
|
56
|
+
File.write(@path, "#{JSON.pretty_generate(record)}\n")
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def record
|
|
60
|
+
{
|
|
61
|
+
'version' => SCHEMA_VERSION,
|
|
62
|
+
'shard' => @shard,
|
|
63
|
+
'files_to_run' => @configuration.files_to_run.map { |file| LisaRspecShardRecorder.relative(file) }.sort,
|
|
64
|
+
'examples' => @examples,
|
|
65
|
+
'simplecov' => LisaRspecShardRecorder.simplecov_state
|
|
66
|
+
}
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
module_function
|
|
71
|
+
|
|
72
|
+
def fetch_env(name)
|
|
73
|
+
value = ENV.fetch(name, '')
|
|
74
|
+
raise ArgumentError, "lisa-rspec-shard-recorder: #{name} is not set" if value.empty?
|
|
75
|
+
|
|
76
|
+
value
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
# Repo-relative, forward-slashed, with no leading "./" and no ":line" suffix.
|
|
80
|
+
def relative(path)
|
|
81
|
+
text = path.to_s.sub(/:\d+(?::\d+)*\z/, '')
|
|
82
|
+
absolute = Pathname.new(File.expand_path(text))
|
|
83
|
+
absolute.relative_path_from(Pathname.new(Dir.pwd)).to_s
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def measuring?
|
|
87
|
+
defined?(::SimpleCov) && defined?(::Coverage) && ::Coverage.running?
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def simplecov_state
|
|
91
|
+
return { 'active' => false } unless measuring?
|
|
92
|
+
|
|
93
|
+
{ 'active' => true, 'coverage_path' => ::SimpleCov.coverage_path }
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
# A shard that enforced the project's floor against its own slice would fail
|
|
97
|
+
# every project whose floor is above one shard's reach, and a shard that does
|
|
98
|
+
# not store its resultset leaves the aggregate nothing to merge. Both are
|
|
99
|
+
# refused loudly rather than worked around.
|
|
100
|
+
def hand_off_coverage(shard)
|
|
101
|
+
return unless measuring?
|
|
102
|
+
|
|
103
|
+
refuse_unsupported_simplecov
|
|
104
|
+
refuse_measured_recorder
|
|
105
|
+
::SimpleCov.finalize_merge(false)
|
|
106
|
+
::SimpleCov.command_name("RSpec shard #{shard}")
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def refuse_unsupported_simplecov
|
|
110
|
+
unless ::SimpleCov.respond_to?(:finalize_merge)
|
|
111
|
+
raise 'lisa-rspec-shard-recorder: this SimpleCov has no `finalize_merge`, so a shard cannot store its ' \
|
|
112
|
+
'coverage without also checking the minimum against its own slice. test_shards above 1 needs ' \
|
|
113
|
+
"simplecov >= 1.0 (Lisa's Gemfile.lisa pins it); upgrade it, or leave test_shards at 1."
|
|
114
|
+
end
|
|
115
|
+
return if ::SimpleCov.merging
|
|
116
|
+
|
|
117
|
+
raise 'lisa-rspec-shard-recorder: SimpleCov merging is off (`merging false`), so this shard would write no ' \
|
|
118
|
+
'.resultset.json for the aggregate to collate. Remove that setting, or leave test_shards at 1.'
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
# Loaded from inside the project, this file is itself measured and lands in
|
|
122
|
+
# the shard's resultset as application code the unsharded run never had,
|
|
123
|
+
# moving the merged percentage. The workflow copies it out first.
|
|
124
|
+
def refuse_measured_recorder
|
|
125
|
+
return unless File.expand_path(__FILE__).start_with?("#{File.expand_path(::SimpleCov.root)}/")
|
|
126
|
+
|
|
127
|
+
raise 'lisa-rspec-shard-recorder: loaded from inside the project root, so SimpleCov would measure it as ' \
|
|
128
|
+
'application code. Copy it outside the project (the workflow uses $RUNNER_TEMP) and --require that copy.'
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
def arm!(configuration)
|
|
132
|
+
shard = fetch_env('LISA_RSPEC_SHARD')
|
|
133
|
+
path = File.expand_path(fetch_env('LISA_RSPEC_SHARD_RECORD'))
|
|
134
|
+
hand_off_coverage(shard)
|
|
135
|
+
listener = Listener.new(path: path, shard: shard, configuration: configuration)
|
|
136
|
+
configuration.reporter.register_listener(listener, :example_finished, :close)
|
|
137
|
+
listener
|
|
138
|
+
end
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
RSpec.configure do |config|
|
|
142
|
+
config.before(:suite) { LisaRspecShardRecorder.arm!(config) }
|
|
143
|
+
end
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# This file is managed by Lisa and IS replaced on each `lisa` run.
|
|
4
|
+
# Do not edit directly — durable changes belong upstream in Lisa.
|
|
5
|
+
# -----------------------------------------------------------------------------
|
|
6
|
+
# Merge the RSpec shards' SimpleCov resultsets and enforce the project's
|
|
7
|
+
# coverage thresholds once, on the whole suite.
|
|
8
|
+
#
|
|
9
|
+
# bundle exec ruby scripts/lisa_simplecov_collate.rb <resultset.json>...
|
|
10
|
+
#
|
|
11
|
+
# `require 'simplecov'` loads the project's own `.simplecov`, so the merged
|
|
12
|
+
# result is filtered, grouped and checked exactly as an unsharded run would
|
|
13
|
+
# be: the same `minimum_coverage` / `coverage ..., minimum:` and every other
|
|
14
|
+
# limit it sets. This file sets no threshold of its own. `SimpleCov.collate`
|
|
15
|
+
# exits non-zero when a threshold fails.
|
|
16
|
+
# -----------------------------------------------------------------------------
|
|
17
|
+
|
|
18
|
+
require 'simplecov'
|
|
19
|
+
|
|
20
|
+
# Collates shard resultsets and lets SimpleCov's threshold verdict decide.
|
|
21
|
+
module LisaSimplecovCollate
|
|
22
|
+
module_function
|
|
23
|
+
|
|
24
|
+
def resultsets(argv)
|
|
25
|
+
abort 'lisa-simplecov-collate: no resultsets given; nothing to collate.' if argv.empty?
|
|
26
|
+
|
|
27
|
+
missing = argv.reject { |path| File.file?(path) }
|
|
28
|
+
abort "lisa-simplecov-collate: resultset(s) not found: #{missing.join(', ')}" unless missing.empty?
|
|
29
|
+
|
|
30
|
+
argv.map { |path| File.expand_path(path) }
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# A `.simplecov` that calls `SimpleCov.start` itself has also started
|
|
34
|
+
# measuring THIS process. Left running, SimpleCov's own at_exit would format
|
|
35
|
+
# and check a second time. Stopping it and dropping the result leaves
|
|
36
|
+
# `collate` the only verdict.
|
|
37
|
+
def stand_down_own_measurement
|
|
38
|
+
::Coverage.result(stop: true, clear: true) if defined?(::Coverage) && ::Coverage.running?
|
|
39
|
+
::SimpleCov.clear_result if ::SimpleCov.respond_to?(:clear_result)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def run(argv)
|
|
43
|
+
files = resultsets(argv)
|
|
44
|
+
puts "Collating #{files.length} SimpleCov resultset(s)."
|
|
45
|
+
::SimpleCov.collate(files)
|
|
46
|
+
ensure
|
|
47
|
+
stand_down_own_measurement
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
LisaSimplecovCollate.run(ARGV) if $PROGRAM_NAME == __FILE__
|
|
@@ -36,6 +36,10 @@ jobs:
|
|
|
36
36
|
# Rails projects default to PostgreSQL. For a MySQL app, uncomment:
|
|
37
37
|
# with:
|
|
38
38
|
# database_type: 'mysql'
|
|
39
|
+
# To split a slow RSpec suite across parallel runners, add
|
|
40
|
+
# `test_shards: 4` (1-20) to the `with:` block. The legs' SimpleCov
|
|
41
|
+
# coverage is merged and checked once, and the required `Test (...)`
|
|
42
|
+
# check keeps its name.
|
|
39
43
|
secrets:
|
|
40
44
|
GITGUARDIAN_API_KEY: ${{ secrets.GITGUARDIAN_API_KEY }}
|
|
41
45
|
FOSSA_API_KEY: ${{ secrets.FOSSA_API_KEY }}
|
|
@@ -63,6 +63,18 @@
|
|
|
63
63
|
"decision": "not-needed",
|
|
64
64
|
"reason": "A runner, not a judge. The gate's verdict is mutant's exit code, and what it runs is read from the project's own `mutation.gate.yml` and `.mutant.yml`; this script's own logic decides whether the gate is enabled and what ref to diff against, both of which come from configuration it does not own. A superseded copy runs the wrong subjects loudly rather than returning a wrong verdict quietly."
|
|
65
65
|
},
|
|
66
|
+
"quality-rails.yml::scripts/lisa_rspec_shard_recorder.rb": {
|
|
67
|
+
"decision": "not-needed",
|
|
68
|
+
"reason": "A reporter, not a judge. It hands SimpleCov's merge finalization to the aggregate and writes a run record; the verdict on that record is `lisa-rspec-shards.mjs verify`, which refuses any record not at the schema version it speaks. A superseded recorder either leaves a record verify rejects or leaves the shard's own minimum check armed, and both are loud reds, never a believed green."
|
|
69
|
+
},
|
|
70
|
+
"quality-rails.yml::scripts/lisa-rspec-shards.mjs": {
|
|
71
|
+
"decision": "warranted",
|
|
72
|
+
"reason": "Verdict-bearing when test_shards is above 1: its `verify` subcommand is what turns a dropped or duplicated spec file into a red `Test (MySQL)` / `Test (PostgreSQL)`, and its `plan` decides which files each leg runs. Plan and record documents carry a schema version that `verify` refuses on mismatch, and an unknown subcommand or flag fails loudly, so a copy too old to speak this workflow's interface is red rather than green. What that does not cover is a copy at the same schema whose partition check is weaker than the current one; the script exports no contract version the workflow could compare, so the obligation is recorded rather than claimed closed."
|
|
73
|
+
},
|
|
74
|
+
"quality-rails.yml::scripts/lisa_simplecov_collate.rb": {
|
|
75
|
+
"decision": "not-needed",
|
|
76
|
+
"reason": "A runner, not a judge. It forwards the shards' resultsets to `SimpleCov.collate`, and the threshold verdict is SimpleCov's own, read from the project's `.simplecov` and `simplecov.thresholds.json`; the script sets no threshold. A superseded copy can fail to collate, which is red, but cannot change what the thresholds are."
|
|
77
|
+
},
|
|
66
78
|
"quality-rails.yml::scripts/lisa-scratch-run.sh": {
|
|
67
79
|
"decision": "not-needed",
|
|
68
80
|
"reason": "A supervisor that hosts a verdict rather than computing one: it owns run-scoped scratch and cleanup around whatever it wraps. Nothing it does can turn a passing suite red or a failing one green — a superseded copy misplaces or fails to reap a scratch directory, which surfaces as its own visible failure rather than as a believed verdict."
|
|
@@ -108,13 +120,13 @@
|
|
|
108
120
|
},
|
|
109
121
|
"inspected": {
|
|
110
122
|
"workflows": 26,
|
|
111
|
-
"steps":
|
|
112
|
-
"couplings":
|
|
113
|
-
"inventory":
|
|
123
|
+
"steps": 823,
|
|
124
|
+
"couplings": 40,
|
|
125
|
+
"inventory": 207
|
|
114
126
|
},
|
|
115
127
|
"counts": {
|
|
116
128
|
"package-backed": 11,
|
|
117
|
-
"apply-lagged":
|
|
129
|
+
"apply-lagged": 26,
|
|
118
130
|
"never-delivered": 0,
|
|
119
131
|
"undelivered": 3
|
|
120
132
|
},
|
|
@@ -122,13 +134,13 @@
|
|
|
122
134
|
"version-handshake": 4,
|
|
123
135
|
"capability-probe": 0,
|
|
124
136
|
"existence-only": 5,
|
|
125
|
-
"no-probe":
|
|
137
|
+
"no-probe": 17,
|
|
126
138
|
"unchecked": 3
|
|
127
139
|
},
|
|
128
140
|
"decisionCounts": {
|
|
129
141
|
"handshake": 4,
|
|
130
|
-
"not-needed":
|
|
131
|
-
"warranted":
|
|
142
|
+
"not-needed": 14,
|
|
143
|
+
"warranted": 11
|
|
132
144
|
},
|
|
133
145
|
"couplings": [
|
|
134
146
|
{
|
|
@@ -411,6 +423,53 @@
|
|
|
411
423
|
],
|
|
412
424
|
"detail": "`quality-rails.yml` is delivered at `@main`, so this step is live in every consumer on their next run. It reads `scripts/check-threshold-ratchet.mjs` from the CALLER's tree with no package-relative candidate, and Lisa delivers that path on the `lisa apply` channel (all/copy-overwrite, rails/copy-overwrite, typescript/copy-overwrite). The two halves land in the wrong order: this step is live everywhere immediately, the file it needs is live only where somebody applied. No existence test guards the read, which is ALL this scan examined of the step's control flow: it did not read anything that could absorb the failure. An absent path most likely fails the job loudly — the better of the two failures, because it is visible — but that is inferred from the missing guard, NOT MEASURED. The step's text does carry `else-branch`, `exit-zero`, `exit-nonzero`, `error-annotation` — located in the step, deliberately NOT related to this read, and enough to make \"it skips silently\" a claim to check rather than assume. STALENESS (a separate dimension from the delivery verdict above): `no-probe`. Neither an existence test nor a version probe bears on this read, so nothing here distinguishes a current artifact from an absent or a superseded one. Tokens found: `workflow-requests-version`. `workflow-requests-version` is workflow-scoped — it does not say THIS step asks."
|
|
413
425
|
},
|
|
426
|
+
{
|
|
427
|
+
"key": "quality-rails.yml::scripts/lisa_rspec_shard_recorder.rb",
|
|
428
|
+
"workflow": "quality-rails.yml",
|
|
429
|
+
"path": "scripts/lisa_rspec_shard_recorder.rb",
|
|
430
|
+
"channel": "apply",
|
|
431
|
+
"verdict": "apply-lagged",
|
|
432
|
+
"remedy": "run-lisa-apply",
|
|
433
|
+
"guarded": false,
|
|
434
|
+
"handling": [
|
|
435
|
+
"exit-nonzero",
|
|
436
|
+
"error-annotation"
|
|
437
|
+
],
|
|
438
|
+
"detection": "no-probe",
|
|
439
|
+
"stalenessSignals": [
|
|
440
|
+
"workflow-requests-version"
|
|
441
|
+
],
|
|
442
|
+
"decision": "not-needed",
|
|
443
|
+
"reason": "A reporter, not a judge. It hands SimpleCov's merge finalization to the aggregate and writes a run record; the verdict on that record is `lisa-rspec-shards.mjs verify`, which refuses any record not at the schema version it speaks. A superseded recorder either leaves a record verify rejects or leaves the shard's own minimum check armed, and both are loud reds, never a believed green.",
|
|
444
|
+
"lanes": [
|
|
445
|
+
"rails/copy-overwrite"
|
|
446
|
+
],
|
|
447
|
+
"detail": "`quality-rails.yml` is delivered at `@main`, so this step is live in every consumer on their next run. It reads `scripts/lisa_rspec_shard_recorder.rb` from the CALLER's tree with no package-relative candidate, and Lisa delivers that path on the `lisa apply` channel (rails/copy-overwrite). The two halves land in the wrong order: this step is live everywhere immediately, the file it needs is live only where somebody applied. No existence test guards the read, which is ALL this scan examined of the step's control flow: it did not read anything that could absorb the failure. An absent path most likely fails the job loudly — the better of the two failures, because it is visible — but that is inferred from the missing guard, NOT MEASURED. The step's text does carry `exit-nonzero`, `error-annotation` — located in the step, deliberately NOT related to this read, and enough to make \"it skips silently\" a claim to check rather than assume. STALENESS (a separate dimension from the delivery verdict above): `no-probe`. Neither an existence test nor a version probe bears on this read, so nothing here distinguishes a current artifact from an absent or a superseded one. Tokens found: `workflow-requests-version`. `workflow-requests-version` is workflow-scoped — it does not say THIS step asks."
|
|
448
|
+
},
|
|
449
|
+
{
|
|
450
|
+
"key": "quality-rails.yml::scripts/lisa_simplecov_collate.rb",
|
|
451
|
+
"workflow": "quality-rails.yml",
|
|
452
|
+
"path": "scripts/lisa_simplecov_collate.rb",
|
|
453
|
+
"channel": "apply",
|
|
454
|
+
"verdict": "apply-lagged",
|
|
455
|
+
"remedy": "run-lisa-apply",
|
|
456
|
+
"guarded": false,
|
|
457
|
+
"handling": [
|
|
458
|
+
"exit-zero",
|
|
459
|
+
"exit-nonzero",
|
|
460
|
+
"error-annotation"
|
|
461
|
+
],
|
|
462
|
+
"detection": "no-probe",
|
|
463
|
+
"stalenessSignals": [
|
|
464
|
+
"workflow-requests-version"
|
|
465
|
+
],
|
|
466
|
+
"decision": "not-needed",
|
|
467
|
+
"reason": "A runner, not a judge. It forwards the shards' resultsets to `SimpleCov.collate`, and the threshold verdict is SimpleCov's own, read from the project's `.simplecov` and `simplecov.thresholds.json`; the script sets no threshold. A superseded copy can fail to collate, which is red, but cannot change what the thresholds are.",
|
|
468
|
+
"lanes": [
|
|
469
|
+
"rails/copy-overwrite"
|
|
470
|
+
],
|
|
471
|
+
"detail": "`quality-rails.yml` is delivered at `@main`, so this step is live in every consumer on their next run. It reads `scripts/lisa_simplecov_collate.rb` from the CALLER's tree with no package-relative candidate, and Lisa delivers that path on the `lisa apply` channel (rails/copy-overwrite). The two halves land in the wrong order: this step is live everywhere immediately, the file it needs is live only where somebody applied. No existence test guards the read, which is ALL this scan examined of the step's control flow: it did not read anything that could absorb the failure. An absent path most likely fails the job loudly — the better of the two failures, because it is visible — but that is inferred from the missing guard, NOT MEASURED. The step's text does carry `exit-zero`, `exit-nonzero`, `error-annotation` — located in the step, deliberately NOT related to this read, and enough to make \"it skips silently\" a claim to check rather than assume. STALENESS (a separate dimension from the delivery verdict above): `no-probe`. Neither an existence test nor a version probe bears on this read, so nothing here distinguishes a current artifact from an absent or a superseded one. Tokens found: `workflow-requests-version`. `workflow-requests-version` is workflow-scoped — it does not say THIS step asks."
|
|
472
|
+
},
|
|
414
473
|
{
|
|
415
474
|
"key": "quality-rails.yml::scripts/lisa-mutation.sh",
|
|
416
475
|
"workflow": "quality-rails.yml",
|
|
@@ -435,6 +494,29 @@
|
|
|
435
494
|
],
|
|
436
495
|
"detail": "`quality-rails.yml` is delivered at `@main`, so this step is live in every consumer on their next run. It reads `scripts/lisa-mutation.sh` from the CALLER's tree with no package-relative candidate, and Lisa delivers that path on the `lisa apply` channel (all/copy-contents). The two halves land in the wrong order: this step is live everywhere immediately, the file it needs is live only where somebody applied. The read sits behind an existence test, which is ALL this scan examined of the step's control flow: it did not read the test's other branch, any fallback, any explicit `exit`, or any verification of the step's output. Whether an absent path skips quietly, falls back, or fails loudly is therefore NOT MEASURED — read the step before concluding it proves nothing. The shape worth ruling out is the silent one, where a skip posts no context and an absent required context is not a red one. The step's text does carry `exit-zero`, `exit-nonzero`, `error-annotation` — located in the step, deliberately NOT related to this read, and enough to make \"it skips silently\" a claim to check rather than assume. STALENESS (a separate dimension from the delivery verdict above): `existence-only`. An existence test and no version probe: this coupling can see that the artifact is MISSING and cannot see that it is OLD. A present copy of any vintage runs, and its verdict is believed. Tokens found: `workflow-requests-version`. `workflow-requests-version` is workflow-scoped — it does not say THIS step asks."
|
|
437
496
|
},
|
|
497
|
+
{
|
|
498
|
+
"key": "quality-rails.yml::scripts/lisa-rspec-shards.mjs",
|
|
499
|
+
"workflow": "quality-rails.yml",
|
|
500
|
+
"path": "scripts/lisa-rspec-shards.mjs",
|
|
501
|
+
"channel": "apply",
|
|
502
|
+
"verdict": "apply-lagged",
|
|
503
|
+
"remedy": "run-lisa-apply",
|
|
504
|
+
"guarded": false,
|
|
505
|
+
"handling": [
|
|
506
|
+
"exit-nonzero",
|
|
507
|
+
"error-annotation"
|
|
508
|
+
],
|
|
509
|
+
"detection": "no-probe",
|
|
510
|
+
"stalenessSignals": [
|
|
511
|
+
"workflow-requests-version"
|
|
512
|
+
],
|
|
513
|
+
"decision": "warranted",
|
|
514
|
+
"reason": "Verdict-bearing when test_shards is above 1: its `verify` subcommand is what turns a dropped or duplicated spec file into a red `Test (MySQL)` / `Test (PostgreSQL)`, and its `plan` decides which files each leg runs. Plan and record documents carry a schema version that `verify` refuses on mismatch, and an unknown subcommand or flag fails loudly, so a copy too old to speak this workflow's interface is red rather than green. What that does not cover is a copy at the same schema whose partition check is weaker than the current one; the script exports no contract version the workflow could compare, so the obligation is recorded rather than claimed closed.",
|
|
515
|
+
"lanes": [
|
|
516
|
+
"rails/copy-overwrite"
|
|
517
|
+
],
|
|
518
|
+
"detail": "`quality-rails.yml` is delivered at `@main`, so this step is live in every consumer on their next run. It reads `scripts/lisa-rspec-shards.mjs` from the CALLER's tree with no package-relative candidate, and Lisa delivers that path on the `lisa apply` channel (rails/copy-overwrite). The two halves land in the wrong order: this step is live everywhere immediately, the file it needs is live only where somebody applied. No existence test guards the read, which is ALL this scan examined of the step's control flow: it did not read anything that could absorb the failure. An absent path most likely fails the job loudly — the better of the two failures, because it is visible — but that is inferred from the missing guard, NOT MEASURED. The step's text does carry `exit-nonzero`, `error-annotation` — located in the step, deliberately NOT related to this read, and enough to make \"it skips silently\" a claim to check rather than assume. STALENESS (a separate dimension from the delivery verdict above): `no-probe`. Neither an existence test nor a version probe bears on this read, so nothing here distinguishes a current artifact from an absent or a superseded one. Tokens found: `workflow-requests-version`. `workflow-requests-version` is workflow-scoped — it does not say THIS step asks."
|
|
519
|
+
},
|
|
438
520
|
{
|
|
439
521
|
"key": "quality-rails.yml::scripts/lisa-scratch-run.sh",
|
|
440
522
|
"workflow": "quality-rails.yml",
|
|
@@ -95,6 +95,7 @@ scripts/lisa-npm-updater.mjs
|
|
|
95
95
|
scripts/lisa-postinstall.mjs
|
|
96
96
|
scripts/lisa-rails-prepush.mjs
|
|
97
97
|
scripts/lisa-reconcile-policy.mjs
|
|
98
|
+
scripts/lisa-rspec-shards.mjs
|
|
98
99
|
scripts/lisa-run-gates.mjs
|
|
99
100
|
scripts/lisa-schema-validate.mjs
|
|
100
101
|
scripts/lisa-test-node.mjs
|