Repository navigation
Gates: human gate approves the content past agent verdicts; agent-gate budget from maxTokens, cut-off answers escalate - #63
Merged
0design merged 4 commits intoOct 24, 2026
Conversation
…ent-gate answer budget from maxTokens, cut-off answers escalate - A human approval-gate's subject passes over agent gates directly before it, so the person sees and binds (sha256) the step output that goes on to delivery. Agent verdicts are shown beside it as `reviews`, outside the subject and its hash. `subject: previous` keeps the legacy subject; parked runs keep their recorded row. One subject selector serves the gate, its binding and the approve-time check. - An escalated agent gate shows the candidate it judged as `subject` (bound under sha256). - Agent-gate answer budget is `maxTokens` (1..32000, default 1024) instead of a fixed 300. An OUTPUT_LIMIT answer is no verdict: it follows escalateOn like a failed check and keeps its billed usage. Other provider failures still fail. - GATE_SUBJECT_PARTIAL judges a human gate after agent gates against the content. - Docs (SPEC-MANIFEST 5.4, CHANGELOG), schema pin and Core artifact repin. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ails; repin Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…nd child budgets stop an escalation - The output a step goes on from (a delivery without body, an agent gate's candidate, a human gate's subject) is the last one in execution order, not the order of step IDs as object keys. Integer-like IDs such as "0" no longer let a delivery send a text other than the one a person approved. - An agent gate whose call takes the run or an enclosing child workflow over its budgetUsd (or leaves its spend unknown under one) stops the run by budget before any waiting_human state is written or reported, whatever the answer: cut off, objection or unreadable. - Tests fail on the previous head and pass here; repin SPEC-MANIFEST and the Core artifact. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.
Why
Two findings from real runs of the "… Factory" workflows on main:
OUTPUT_LIMIT(completion truncated) and the whole run failed, instead of handing the decision to a person.{pass, reason}without seeing the text that goes on to delivery.What changes
Gate subject
approval-gatenow passes over agent gates directly before it: itssubject(and itsapprovalHashunderbind: sha256) is the content those gates judged.reviews. They are not part of the subject or its hash.q-core approveprints them under the subject.subject: previouskeeps the legacy subject (the output directly before the gate, even an agent verdict). Validation accepts only that value, and only on a human gate.currentSubjectRow/gateSubjectRowinrun.mjs) feeds the gate, its bound row and the approve-time check inwaitingGate. Before this,waitingGatehad its own filter, which also did not skipworkflow-returnrows.boundSubjectRowId, so their existing hash is still accepted.subject, bound undersha256. Before, it showed nothing.GATE_SUBJECT_PARTIALvalidator warning applies the same rule. A human gate after agent gates is judged against the content, where before it was skipped.Agent-gate budget
maxTokens, an integer from 1 to 32000, default 1024. It replaces the fixedMath.min(maxTokens, 300). The Anthropic worst-case reservation uses the same value.maxTokens(OUTPUT_LIMIT, for both providers) is no verdict. Like an unreadable verdict, it followsescalateOn: by default it goes to a person, and it keeps its billed tokens and cost. Every other provider failure still fails: cost cap, HTTP, invalid response, cancellation.Docs and pins
core.schemaSha256updated for the edited SPEC-MANIFEST.registry/catalog*.json,SHA256SUMS), checked withbuild-registry --check.Tests
test/gate-subject-and-verdict-budget.test.mjs, 11 tests. Run against current main, 7 of them fail: subject and hash, escalated subject, maxTokens and default, cut-off escalation and bill, escalateOn for cut-off, validation, warning. The other 4 are compatibility guards and pass on both: the writer fixture,subject: previous, a run parked before the change, and an unreadable verdict escalating.test/anthropic-agent-gate.test.mjs, "…bound uses its actual 300-token completion cap" → "…uses its configured completion cap". A configured800is now sent as-is, and32000is refused by the run budget before any call.comm -23is empty). The shared local failures come from running inside an agent session and do not occur in CI.Not in this PR (open questions)
api-requestwithoutbodysends the gate's output envelope aspayload. That envelope now carries the content assubject.🤖 Generated with Claude Code