feat: complete the refusal contract, add assumption-carrying gates, pin git identity - #15
Merged
Conversation
|
All contributors have signed the CLA. ✅ |
Owner
Author
|
I have read the CLA Document and I hereby sign the CLA |
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 subscribe to this conversation on GitHub.
Already have an account?
Sign in.
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.
Completes the refusal contract started in #13, and adds assumption-carrying phase gates. Both came out of public conversations on r/AgentsOfAI.
1. Refusal is now fully terminal (finishes #13)
#13 shipped the structured refusal and the closed intent. Three parts were left open; all three land here.
A third terminal verb. Escalation cards no longer offer Approve/Deny. A refusal renders "Cannot complete — human action required", lists the unmet checks, shows what would have to change, and offers Open chat / Retry with a change / Abandon. Offering "Approve" for a state that approval cannot satisfy is exactly what produced the ~70× re-raise loop.
The prior attempt is passed as structure, not prose. The remediation task now opens by declaring the previous attempt closed rather than narrating that it failed. Prose about a failure invites "try again".
A new attempt must declare what changed. The prompt requires a
CHANGED:line naming what is different and why the last attempt failed, and instructs the agent to say so plainly rather than guess if it cannot name a difference. That makes a no-information retry structurally unjustifiable — the brake a spend cap cannot provide.Credit for the design: the author of Agent Pump, who hit the identical shape against a wallet boundary.
2. Gates carry a falsifiable assumption
Raised by KimLikeJ:
Two verified gaps: Vigil reviews the diff and never the premise, and
assumptionappeared exactly once in the whole engine (a heading in Scout's discovery doc that nothing ever reads again).The checkpoint already existed and was empty — the pipeline pauses before architecture and deploy, but the card said "awaiting your review" with an Approve button. It gated on the phase, not the reasoning.
Now Sensei asks, at each gate, what the phase's work rests on, and the card shows the claim, what's wasted if it's wrong, confidence, and whether the agent read it from the brief or invented it. Low-confidence or invented claims are visually flagged.
Fail-open, always. Provider error, unparseable response, empty response, or a phase with no completed tasks — every path raises the gate without an assumption. A wrong-premise check that could stall the pipeline would be worse than the bug it catches.
No silent spend. Skipped entirely when a phase completed nothing; killable with
KAGEOPS_ASSUMPTION_GATES=0. On by default at roughly six short calls per run.Port method
Curated, not a sync.
phase-gates.ts,command-center.tsandcommand-center.csswere each verified to have zero public-only lines before being copied.sensei.tsdiverges — this repo carrieslast_reopened_athandling the desktop build does not — so the edits were applied to this repo's file instead. Verified after porting: 2 lines removed (both deliberately replaced), 38 added, nothing else touched, all 6 occurrences oflast_reopened_atintact.Test plan
tsc --strictclean · E2E (Playwright + Electron) green🤖 Generated with Claude Code
3. Git committer identity is explicit at every commit
Reported by Crafty_Disk_7026, who read this repo's source. Six code paths shell out to
git commit; only two of them set an identity. The rest inherited the ambient globalconfig — so on a machine with no git identity configured the commit fails outright, and
on a machine that has one, commits written by an agent are attributed to the human.
All six now route through
gitIdentityArgs(), which passes-c user.email -c user.nameon the commit invocation itself (not a mutated global), including the per-task agent
commit — the path that runs most often. Overridable via
KAGEOPS_GIT_AUTHOR_NAME/KAGEOPS_GIT_AUTHOR_EMAIL. 8 tests pin the contract.Ported here from the desktop build (private #414).
burst-workspace.tsis deliberatelyexcluded — cloud burst is commercial and that file does not exist in this repo.