batch_add
Record multiple code finding observations in one batch, deduplicating each by fingerprint to create or update the corresponding tracker card.
Instructions
Record multiple finding observations at once (deduplicated by fingerprint).
Members are deduplicated exactly like add — including against each other,
so two members sharing a fingerprint yield one insert plus one bump. One
result per input, in input order. Unknown member keys are refused.
Each result carries the same discriminators add returns, and the same
four dedup_action values: "created", "bumped", "reopened" and
"recurrence_of_closed", the last of which reports was_new: true because
it files a NEW row linked to a dismissed twin via meta.recurrence_of.
Each result also carries its OWN attention list — always present, often
empty, never shared between members. Two record forms exist, in this
order and at most once each:
{signal: severity_escalated, from, to} on the bumped and reopened
branches, meaning that member's observation raised the stored finding's
severity; and {signal: category_divergence, observed, stored} on every
branch with a matched row (bumped, reopened, and the recurrence
branch, where the comparison is against the dismissed twin), meaning that
member does not NAME the matched finding's category. Both category sides
are normalized, so a difference of spelling is not a signal; a stored
category that is not text is skipped rather than raising.
Each result also carries its OWN stripped_meta_keys list — always
present, often empty, never shared between members — following the
same discipline: a meta key that is identity machinery OUTPUT (e.g.
occurrences, recurrence_of, category_minted) is stripped from
what gets stored rather than refused, and reported here so a caller
forwarding a fetched card's meta can tell which of its own keys
silently did not land. resolver_errors is refused outright instead
(a FAILURE state, not machinery input), on this path exactly as on
add.
Each result likewise carries its OWN stripped_description_tail
boolean — always present, usually False, meaning "checked, nothing to
cut" rather than "no such channel". A leaked tool-call tail on that
member's description (envelope lines and nothing else after a
</description> marker) is CUT rather than refused, before the
fingerprint is derived so a tailed and a clean report of one defect
collapse onto one card; prose merely quoting the marker is left alone.
True means that member's stored text is not the text you passed.
Args:
findings: List of finding objects, each with keys: severity, category, file, description, and optionally: lines, source, tags, meta, reported_at_commit, reported_at_ref, fingerprint.
linesis per-member and works exactly as it does onadd: it is WHERE IN THE CODE that member is, and the only input that gives its card a durable ANCHOR surviving later edits to the file. A bare number ("1850"), a range ("1850-1870"), a full "path/file.py:1850" token (whose path must name that member's ownfile) or a list of lines. Omit it on a member that describes no place in the code rather than inventing one. It is the same field as that member'smeta.lines, and the two are refused when they disagree.reported_at_commit: Default commit SHA for all findings (auto-detected if omitted). Per-finding values override this.
reported_at_ref: Default version label for all findings. Per-finding values override this.
new_category: Batch-wide permission to MINT categories the tracker does not hold yet (CB-60); the first member introducing a category is stamped meta.category_minted.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| findings | Yes | ||
| new_category | No | ||
| reported_at_ref | No | ||
| reported_at_commit | No |
Output Schema
| Name | Required | Description | Default |
|---|---|---|---|
| result | Yes |