Repository navigation
Conversation
scute.harness is the Python counterpart of @scute/harness and Scute::Harness: guards decide on every tool call an agent makes, backed by Scute's engine for who may do what (the agent's roles, the person it works for, and the task). - Harness(agent, guards=, tools=, mode=, store=, on_decision=, on_alert=) with app_id / secret / base_url or a Scute client. Tool names map to permissions (refund_invoice -> invoice:refund, the object from invoice_id), overridable per tool. - harness.run(acts_for=, actions=, resources=, ttl=, ...) mints the task with the secret on first use; harness.run(token=) runs on a task token your backend minted, without the secret. - run.check(tool, args) returns a Verdict (proceed, transform, approve, verify, guide, redirect, deny) with a message for the model and a say line for the person; run.after, run.wrap (also a decorator). - Guards: permissions, verify_person, approval, requester_only, grounding, args, budget, content, define; enforce / monitor / observe modes. - Human steps with the task token: start_verification, submit_code, verification_status, complete_verification; reviewer approvals filed for the exact call and approval_status; run.confirm; run.human_tools() as callables with JSON Schema parameters. - run.property, run.sign, run.whoami, run.complete, run.revoke. The run closes for good on task_closed, budget_exceeded or a dead token. Checks go one at a time per run. Tokens never appear in reprs, snapshots or errors. scute.agents: register agents, start, complete and revoke tasks, suspend and resume, delegation assertions (secret key). authz decisions carry the say line from agent checks. Unit tests against a fake agent API (ported from the Ruby specs, regressions included) and a live module (tests/live/test_08_harness.py): 63 live tests pass against scute-api-v2.
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.
What this adds
scute.harnessis the agent harness for Python (RB-41, step 6), the counterpart of@scute/harness(TypeScript) andScute::Harness(Ruby). Guards decide on every tool call an agent makes, backed by Scute's engine for who may do what: the agent's roles, the person it works for, and the task.refund_invoiceneedsinvoice:refundon the invoice named byinvoice_id(orinvoiceId, orid). You can override that per tool: permission, key, tier, attributes, resource, orFalsefor no check.harness.run(token=...)runs on a task token your backend minted, without the secret.get/set).task_closed,budget_exceededor a dead token, and never quietly re-mints.permissions(Scute's engine),verify_person,approval,requester_only,grounding,args,budgetandcontent(credentials, PII, injection), plusdefinefor your own. Each runs inenforce,monitororobservemode, withon_decisionandon_alerthooks. A guard that raises counts as deny.start_verification,submit_code,verification_status,complete_verification(a challenge your backend started). The run's session carries the verification into the next check.approval_status.run.confirmfor a person's confirmation.run.human_tools()gives the model thescute_*tools, as callables with JSON Schema parameters.run.property(name)andrun.sign(name, claims=... | data=...), plusrun.whoami(),run.complete(),run.revoke(),run.wrap(tool)(also a decorator),run.after,run.allowed_tools.scute.agents(secret key):create,get,list,update,delete,suspend,resume,tasks,start_task,complete_task,revoke_task,assertion.Authz decisions now also carry the
sayline the agent check answers with.Compared with TypeScript and Ruby
Same as Ruby:
context.args, per-person run state, budgets reserved under a lock, linear-time content patterns, token-boundary groundingFrom TypeScript: the run also closes on
budget_exceeded.Not in this PR:
run.wrapandrun.human_tools()are framework-neutral.AgentSession#trust!), but no route sets them. The harness passes the session on every check and records verification on it, but can't producetrusted_in_session.Tests
Unit (fake agent API, ported from the Ruby specs including the regressions): 51 new tests. Full unit suite: 192 passed.
ruff,
mypy src,mypy --strict src tests/liveand the new test files: clean.Live (
tests/live/test_08_harness.py, against scute-api-v2), with an agent registered throughscute.agentsand a run for a test identity:outside_task, with the say line)verified)approved); other arguments file a request of their ownscute_whoamifrom the human toolsbudget_exceeded, the run is closed and the agent paused, and later checks fail closedpytest -m live: 63 passed. It adds no sign-ins (it reuses the suite's signed-in test identity). After the run the app has no users, roles, resources, agents or properties.Run the live suite with
pytest -m live(setup in the README's "Live suite" section).