Prune the description to the declared operations at packing time - #40
Merged
Conversation
Published descriptions are big - hundreds of paths, components for all
of them - and an agent declares a handful of operations. The size alone
is not the problem: operations is required, so the runtime offers only
what was declared however much the file holds. The problem is what
people do about the size. Cutting a description down by hand breaks
quietly, twice over: flattening a $ref takes the arguments it carried,
and dropping a path item's own parameters entry takes the same
arguments another way. Both mistakes validate cleanly - the operations
are still there, they just cannot say which record they address - and
nothing notices until someone counts the arguments on the deployed
tools. If pruning is worth doing, the only place it is safe is where
read_operations already knows what a path item contributes and where
every reference leads.
gete archive now packs a pruned description: the declared operations
with their whole path items - path-level parameters included - and
every node they reference, grafted transitively at its original
pointer. The vendor's original stays untouched in the repo; the
runtime and a cold start read only what the agent declared. A file two
blocks share keeps the union of their choices, and the bytes stay
deterministic, as everything in an archive must.
validate separately learned to report a {placeholder} in a path
template that no path parameter declares - the exact shape a hand-cut
description ends up in, said early and by name, for descriptions gete
did not produce.
🤖 Generated with Claude Code
validate reads the repo's file; the runtime reads the archive. Between the two sits pruning, and one thing pruning deliberately breaks: a reference into another path's subtree resolves in the repo and dangles once that path is left out. Such a declaration packed cleanly and then failed at the deployed agent's cold start, when the runtime held it against the pruned description. The packing now runs the same check against the pruned document, so the miss is refused before anything deploys. 🤖 Generated with Claude Code
🤖 Generated with Claude Code
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
gete archivenow prunes the OpenAPI description to the declaredoperations, and
validatereports a path template placeholder no pathparameter declares.
Why gete does the cutting
A published description holds far more than an agent declares, and
operationsbeing required already keeps the runtime honest — the model isoffered only what was declared however much the file holds. The tempting
next step is to keep a hand-trimmed copy of the description in the repo,
and that step breaks quietly, in at least two ways:
$refdrops the parameters it carried;parametersentry drops the same parametersanother way — OpenAPI lets path-level parameters live outside the
operation, and by reference at that.
Both mistakes validate cleanly: the operations are still there, they just
can no longer say which record they address. Nothing notices until someone
counts the arguments on the deployed tools. If pruning is worth doing, the
only safe place is where
read_operationsalready knows what a path itemcontributes and where every reference leads.
What archive packs now
parameters included — so nothing an operation inherits is lost.
pointer, transitively, so
$refkeeps resolving; unreferencedcomponents stay behind. A pointer into
pathsis deliberately notgrafted — it would re-select what pruning just left out.
serversstay behind too; nothing ever reads them(request URLs come from the connection's
base_url).keeps the union of their operations.
Terraform decides deployment by the archive hash.
running against it. Only what travels — and what a cold start reads —
shrinks.
The validate rule
For descriptions gete did not produce (hand-written or hand-trimmed),
validatenow reports the resulting shape early and by name:A runtime-equivalence test holds the two paths together: the tools built
from a pruned description carry declarations identical to those built from
the whole one.