os-context extract: read_write_profile denominator for read-write sub-tag
Total main-loop Read/Write/Edit calls regardless of adjacency, split into in-flagged-runs vs scattered (with line/target per scattered call), so the rubric's missed-delegation/read-write sub-tag has a deterministic denominator the consecutive-run scan cannot provide. Drops the stale "sequential-dependent work is a valid reason" trailer superseded by ADR-0043. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
930ac6e80d
commit
357d13270f
|
|
@ -14,6 +14,7 @@ require "optparse"
|
|||
module OrchAudit
|
||||
READ_TOOLS = %w[Read Grep Glob Bash].freeze
|
||||
RUN_TOOLS = %w[Read Grep Glob Edit Write].freeze
|
||||
RW_TOOLS = %w[Read Write Edit].freeze
|
||||
|
||||
class Line
|
||||
attr_reader :number, :raw
|
||||
|
|
@ -139,19 +140,23 @@ module OrchAudit
|
|||
@threshold = threshold
|
||||
end
|
||||
|
||||
def candidates
|
||||
runs = []
|
||||
current = []
|
||||
@calls.each do |call|
|
||||
if extend_run?(current, call)
|
||||
current << call
|
||||
else
|
||||
runs << current if qualifying?(current)
|
||||
current = RUN_TOOLS.include?(call.name) ? [call] : []
|
||||
def candidates = runs.map { |r| describe(r) }
|
||||
|
||||
def runs
|
||||
@runs ||= begin
|
||||
found = []
|
||||
current = []
|
||||
@calls.each do |call|
|
||||
if extend_run?(current, call)
|
||||
current << call
|
||||
else
|
||||
found << current if qualifying?(current)
|
||||
current = RUN_TOOLS.include?(call.name) ? [call] : []
|
||||
end
|
||||
end
|
||||
found << current if qualifying?(current)
|
||||
found
|
||||
end
|
||||
runs << current if qualifying?(current)
|
||||
runs.map { |r| describe(r) }
|
||||
end
|
||||
|
||||
private
|
||||
|
|
@ -220,7 +225,16 @@ module OrchAudit
|
|||
m[:targets_sample].each { |t| md << " - `#{t}`\n" }
|
||||
end
|
||||
end
|
||||
md << "\nHeuristic candidates require auditor judgment; sequential-dependent work is a valid reason not to delegate.\n"
|
||||
rw = d[:read_write_profile]
|
||||
md << "\n## Main-loop Read/Write/Edit profile (missed-delegation/read-write denominator)\n\n"
|
||||
counts = rw[:tool_counts].map { |k, v| "#{k}:#{v}" }.join(" ")
|
||||
md << "- Total: #{rw[:total]} (#{counts}); in flagged runs: #{rw[:in_flagged_runs]}; scattered: #{rw[:scattered].size}\n"
|
||||
rw[:scattered].each do |c|
|
||||
md << " - #{c[:tool]} line #{c[:line]} `#{c[:target]}`\n"
|
||||
end
|
||||
md << "\nHeuristic candidates and scattered calls require auditor judgment via the rubric's " \
|
||||
"exemption decision procedure (E-a..E-d); under ADR-0043 there are no validity defenses " \
|
||||
"for direct grunt work, only severity modifiers.\n"
|
||||
md
|
||||
end
|
||||
|
||||
|
|
@ -235,12 +249,31 @@ module OrchAudit
|
|||
attach_rounds(main, agent_spawns)
|
||||
|
||||
orchestrator_calls = calls.values.reject { |c| c.name == "Agent" }
|
||||
scan = MissedDelegationScan.new(orchestrator_calls, @run_threshold)
|
||||
{
|
||||
metadata: metadata(main, agent_spawns),
|
||||
agent_spawns: agent_spawns.map(&:to_h),
|
||||
segments: segments(main).map(&:to_h),
|
||||
missed_delegation_candidates:
|
||||
MissedDelegationScan.new(orchestrator_calls, @run_threshold).candidates
|
||||
missed_delegation_candidates: scan.candidates,
|
||||
read_write_profile: read_write_profile(orchestrator_calls, scan)
|
||||
}
|
||||
end
|
||||
|
||||
# Denominator for the rubric's missed-delegation/read-write sub-tag: total
|
||||
# main-loop Read/Write/Edit calls regardless of adjacency. The run scan only
|
||||
# sees consecutive same-tool runs; "scattered" lists the calls it can't
|
||||
# flag, for per-call exemption judgment by the auditor.
|
||||
def read_write_profile(orchestrator_calls, scan)
|
||||
rw = orchestrator_calls.select { |c| RW_TOOLS.include?(c.name) }
|
||||
in_run = scan.runs.flatten.select { |c| RW_TOOLS.include?(c.name) }
|
||||
scattered = rw - in_run
|
||||
{
|
||||
total: rw.size,
|
||||
tool_counts: rw.map(&:name).tally,
|
||||
in_flagged_runs: in_run.size,
|
||||
scattered: scattered.map do |c|
|
||||
{ tool: c.name, line: c.line.number, target: c.target.to_s[0, 120] }
|
||||
end
|
||||
}
|
||||
end
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue