| 1 | package evidence |
| 2 | |
| 3 | // DelegationAudit is one completed sub-agent run, recorded as structured data |
| 4 | // so a benchmark can compare orchestration arms without scraping prose. It |
| 5 | // carries what the host observed, never what the child claimed unchecked. |
| 6 | type DelegationAudit struct { |
| 7 | Depth int |
| 8 | // ToolCalls and Mutations are host-recorded receipt counts for this child. |
| 9 | ToolCalls int |
| 10 | Mutations int |
| 11 | // MutationPaths lets an aggregator detect two children touching one file. |
| 12 | MutationPaths []string |
| 13 | // ClaimViolations counts writes the host saw outside the declared claim. |
| 14 | ClaimViolations int |
| 15 | // HasReport is false when the child ended in prose instead of a typed claim. |
| 16 | HasReport bool |
| 17 | // Historical host judgments; retained for old records only. New runs leave |
| 18 | // these unset and display the model's report separately from execution facts. |
| 19 | AdjudicatedStatus string |
| 20 | Downgrades int |
| 21 | // ParentScopeHints counts directories the delegation narrowed the search to. |
| 22 | ParentScopeHints int |
| 23 | // ParentNamedFiles counts specific files the delegation text handed over. |
| 24 | ParentNamedFiles int |
| 25 | // EvidencePaths is every distinct path the child produced a receipt for. |
| 26 | EvidencePaths int |
| 27 | // DiscoveredPaths is the subset of those no named file already covered. |
| 28 | DiscoveredPaths int |
| 29 | } |
| 30 | |
| 31 | // ClassifyEvidenceOrigin scores one run against the text its parent wrote. |
| 32 | // Discovery is judged against named files only: a child sent to a directory |
| 33 | // still had to work out which file in it mattered. Counts only — a rate is a |
| 34 | // ratio of sums across runs, and averaging per-run rates would weight a child |
| 35 | // that read two files like one that read forty. |
| 36 | func (a *DelegationAudit) ClassifyEvidenceOrigin(delegationText string, evidencePaths []string) { |
| 37 | scope, files := SplitNamedPaths(NamedPaths(delegationText)) |
| 38 | a.ParentScopeHints = len(scope) |
| 39 | a.ParentNamedFiles = len(files) |
| 40 | a.EvidencePaths = len(evidencePaths) |
| 41 | a.DiscoveredPaths = 0 |
| 42 | for _, p := range evidencePaths { |
| 43 | if !UnderNamedPath(files, p) { |
| 44 | a.DiscoveredPaths++ |
| 45 | } |
| 46 | } |
| 47 | } |
| 48 | |
| 49 | // FalseCompletion reports a child that claimed more than the host could back. |
| 50 | // It is the count of refused criteria, not a comparison against a claimed |
| 51 | // status the host never independently recorded. |
| 52 | func (a DelegationAudit) FalseCompletion() bool { |
| 53 | return a.HasReport && a.Downgrades > 0 |
| 54 | } |
| 55 |