Skip to content

Operator settings are ceilings a tool argument cannot widen - #840

Merged
irparent merged 2 commits into
mainfrom
fix/operator-limits-are-ceilings
Oct 5, 2026
Merged

irparent merged 2 commits into
mainfrom
fix/operator-limits-are-ceilings

Conversation

@irparent

@irparent irparent commented Oct 5, 2026

Copy link
Copy Markdown
Member

What changes

Three tool arguments could widen limits the operator set, and an agent's arguments can be steered by text it read, including text stored in Iris:

Argument Before Now
verify_citations allow_fetch: true turned fetching on with IRIS_CITATION_ALLOW_FETCH unset can only turn it off; fetching needs IRIS_CITATION_ALLOW_FETCH=1
verify_citations domain_allowlist added to IRIS_CITATION_DOMAINS narrows it; an entry outside it is dropped, and when nothing is left nothing is fetched
evaluate_with_llm_judge max_cost_usd replaced IRIS_LLM_JUDGE_MAX_COST_USD_PER_EVAL with any larger number at most the operator's cap
verify_citations max_cost_usd_total any number at most IRIS_CITATION_MAX_COST_USD_TOTAL, a new setting (default 1 USD, as before)

When an argument asks for more, the operator's setting applies and the call goes on. The response carries an IRIS_ARGUMENT_NARROWED warning naming the argument and the setting that applied. The stored evaluation keeps the same fact in provenance.narrowed, and the composer derives a sentence to the operator from it on every read, so the operator sees it even when the agent does not pass the warning on.

Breaking

A caller that relied on allow_fetch: true to fetch now gets no fetch and the warning; the operator sets IRIS_CITATION_ALLOW_FETCH=1. Entry in CHANGELOG.md under Security.

Tests

  • tests/unit/tools/operator-ceilings.test.ts: each ceiling, case by case, including a host that only ends with an operator entry, and an empty intersection (an empty list means "any domain" to the resolver, so it never stands for "none").
  • tests/unit/tools/operator-ceilings-tools.test.ts: through the real tools over an in-memory MCP transport. Fetching off with allow_fetch: true fetches nothing; an added domain is never fetched; both cost arguments are held to the operator's cap before any spend; the stored row read back carries the operator sentence with configKey naming the setting; an argument within the settings warns nobody.
  • npm run preflight passed on this commit.

🤖 Generated with Claude Code

irparent and others added 2 commits October 5, 2026 07:56
verify_citations fetched cited URLs when a call passed allow_fetch: true on
a server whose operator had not set IRIS_CITATION_ALLOW_FETCH=1; its
domain_allowlist was merged into IRIS_CITATION_DOMAINS rather than
narrowing it; and max_cost_usd / max_cost_usd_total replaced the
operator's cap with any larger number. An agent's arguments can be steered
by text it read, so each is now a ceiling (src/tools/operator-ceilings.ts):
an argument narrows the operator's setting for one call and never widens
it.

When an argument asks for more, the operator's setting applies and the
call goes on. The response carries an IRIS_ARGUMENT_NARROWED warning; the
stored evaluation keeps the fact in provenance.narrowed, and the composer
derives a sentence to the operator from it on every read, so the operator
sees it even when a steered agent does not pass the warning on.

verify_citations' per-call cap becomes an operator setting,
IRIS_CITATION_MAX_COST_USD_TOTAL (default 1 USD, as before).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@vercel

vercel Bot commented Oct 5, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
website Ready Ready Preview Oct 5, 2026 4:29pm UTC

@github-actions

github-actions Bot commented Oct 5, 2026 •

Copy link
Copy Markdown

Iris gate — 1 of 2 tripped --fail-on detector_veto

iris-eval ingest: 3 stored, 1 tripped --fail-on detector_veto (2 of 3 evaluated in dataset "release-gate")

Trace Verdict Basis Rules, classes or missing inputs Evidence
3a6d59f29d178e7c0e1db3d940b824d2 failed detector_veto + risk_over_loss no_pii, pii_leak, credential_leak no_pii: AWS Access Key (output 45–65)
Verdict basis Traces
detector_veto 2
clean 1

Unjudged questions: task_completed (3), tool_use_correct (3) — a trace that did not carry what a rule needs.

tests/fixtures/ci-gate/traces.ndjson · 3 evaluated · dataset release-gate: 2 in the gate · exit 1 · what the bases mean

@github-actions

github-actions Bot commented Oct 5, 2026

Copy link
Copy Markdown

Iris gate — 1 stored, nothing tripped --fail-on any

iris-eval ingest: 1 stored, 0 tripped --fail-on any

Verdict basis Traces
clean 1

Unjudged questions: task_completed (1), tool_use_correct (1) — a trace that did not carry what a rule needs.

tests/fixtures/ci-gate/clean.ndjson · 1 evaluated · exit 0 · what the bases mean

@irparent
irparent merged commit f6187c7 into main Oct 5, 2026
74 checks passed
@irparent
irparent deleted the fix/operator-limits-are-ceilings branch October 5, 2026 17:21

This branch was successfully deployed

1 active deployment
Preview — c2d54181 Deployed Oct 5, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant