Interpret a verdict
Every governed call returns a verdict. Getting this branch right is the single most important thing in your integration, and the polarity is inverted between our SDKs — so this is the one page not to skim.
The polarity table
Section titled “The polarity table”| SDK | Field | true means |
|---|---|---|
| Go | Guidance.Hold | stop |
| TypeScript | guidance.hold | stop |
| Python | GovernanceDecision.proceed | go |
Copying a snippet between languages and flipping it by eye is how an agent ends up proceeding on
every block. Use the interpreter each SDK ships; do not read decision yourself.
// Gog := vectadyne.InterpretContext(assembled)if g.Hold { return g.Reason }# Python — note the inversiond = interpret_verdict(assembled.verdict)if not d.proceed: return d.summary()// TypeScriptconst g = interpretContext(assembled);if (g.hold) return g.reason;The four decisions
Section titled “The four decisions”| Decision | Holds? | What it means |
|---|---|---|
allow | no | Nothing known against it |
warn | no | Something worth knowing, not disqualifying |
block | yes | Recorded knowledge says do not |
require_approval | yes | A human must sign off |
warn proceeds. This is not a detail.
Section titled “warn proceeds. This is not a detail.”A warn is advice — something the corpus knows that your agent did not. Surface it to the model
and carry on.
Treating warn as a stop is the most common integration error, and it is not a cosmetic one: it
converts Vectadyne into the inline gate it is deliberately not, and it will stall your agents on
information that was only ever meant to inform them. See Advisory-first.
d = interpret_verdict(verdict)if not d.proceed: return hold(d.summary())
for w in d.warnings: # a warn lands here messages.append(f"Note from governed memory: {w}")proceed()Unknown decisions hold
Section titled “Unknown decisions hold”If the server returns a decision a client does not recognise, every SDK sets unknown and holds.
This is fail-closed on purpose. A newer server could introduce a decision an older client has never heard of; treating it as “not one of the blocking ones, so proceed” would make every future restriction invisible to old clients. A vocabulary a client cannot interpret is not one it may ignore.
Do not reimplement this with decision not in ("block", "require_approval") — that is exactly the
bug the interpreters exist to prevent.
Read the reasons
Section titled “Read the reasons”A decision alone is not actionable. Each verdict carries reasons with severities and citations:
block violates_policy — "Migrations require a rollback plan" [policy:mig-2, incident:412] fragile_file — "payments/ledger.go caused 3 rollbacks" [pr:881, pr:902, incident:377]Put these in front of the model when you proceed, and in front of the human when you hold. A hold that only says “blocked” makes a person your bottleneck; one that says why, with citations, lets them decide in seconds.
Degraded is not a hold
Section titled “Degraded is not a hold”degraded: true means the server produced a smaller answer under pressure. It is a successful
response carrying a real verdict.
Do not retry it and do not treat it as a hold — retrying adds load to a system already telling you it is under pressure. See Degraded mode.
A worked branch
Section titled “A worked branch”assembled = vd.assemble( action_type="deploy.release", summary="Ship 2.4.0 to production", scope_key="service:checkout", purpose="deploy",)d = interpret_verdict(assembled.verdict)
if d.degraded: log.info("context was degraded — proceeding on a reduced answer")
if not d.proceed: return escalate(reason=d.summary(), citations=d.cited_memory)
for w in d.warnings: messages.append(f"Governed memory notes: {w}")for check in d.required_checks: if not has_run(check): return escalate(reason=f"required check not run: {check}")
deploy()- Handle errors — a fault is not a verdict
- Test your integration — assert that you asked