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
|
module OrchAudit
|
||||||
READ_TOOLS = %w[Read Grep Glob Bash].freeze
|
READ_TOOLS = %w[Read Grep Glob Bash].freeze
|
||||||
RUN_TOOLS = %w[Read Grep Glob Edit Write].freeze
|
RUN_TOOLS = %w[Read Grep Glob Edit Write].freeze
|
||||||
|
RW_TOOLS = %w[Read Write Edit].freeze
|
||||||
|
|
||||||
class Line
|
class Line
|
||||||
attr_reader :number, :raw
|
attr_reader :number, :raw
|
||||||
|
|
@ -139,19 +140,23 @@ module OrchAudit
|
||||||
@threshold = threshold
|
@threshold = threshold
|
||||||
end
|
end
|
||||||
|
|
||||||
def candidates
|
def candidates = runs.map { |r| describe(r) }
|
||||||
runs = []
|
|
||||||
current = []
|
def runs
|
||||||
@calls.each do |call|
|
@runs ||= begin
|
||||||
if extend_run?(current, call)
|
found = []
|
||||||
current << call
|
current = []
|
||||||
else
|
@calls.each do |call|
|
||||||
runs << current if qualifying?(current)
|
if extend_run?(current, call)
|
||||||
current = RUN_TOOLS.include?(call.name) ? [call] : []
|
current << call
|
||||||
|
else
|
||||||
|
found << current if qualifying?(current)
|
||||||
|
current = RUN_TOOLS.include?(call.name) ? [call] : []
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
found << current if qualifying?(current)
|
||||||
|
found
|
||||||
end
|
end
|
||||||
runs << current if qualifying?(current)
|
|
||||||
runs.map { |r| describe(r) }
|
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
@ -220,7 +225,16 @@ module OrchAudit
|
||||||
m[:targets_sample].each { |t| md << " - `#{t}`\n" }
|
m[:targets_sample].each { |t| md << " - `#{t}`\n" }
|
||||||
end
|
end
|
||||||
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
|
md
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -235,12 +249,31 @@ module OrchAudit
|
||||||
attach_rounds(main, agent_spawns)
|
attach_rounds(main, agent_spawns)
|
||||||
|
|
||||||
orchestrator_calls = calls.values.reject { |c| c.name == "Agent" }
|
orchestrator_calls = calls.values.reject { |c| c.name == "Agent" }
|
||||||
|
scan = MissedDelegationScan.new(orchestrator_calls, @run_threshold)
|
||||||
{
|
{
|
||||||
metadata: metadata(main, agent_spawns),
|
metadata: metadata(main, agent_spawns),
|
||||||
agent_spawns: agent_spawns.map(&:to_h),
|
agent_spawns: agent_spawns.map(&:to_h),
|
||||||
segments: segments(main).map(&:to_h),
|
segments: segments(main).map(&:to_h),
|
||||||
missed_delegation_candidates:
|
missed_delegation_candidates: scan.candidates,
|
||||||
MissedDelegationScan.new(orchestrator_calls, @run_threshold).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
|
end
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue