Adding consequences to the schema

N17Q extended argument schemas with effect class, idempotency, queryability, compensation, authority, sensitivity, timeout, and replay contracts the harness needed to act safely.

Two N17Q tools had nearly identical schemas:

create_request({ title, body, target })

One fixture accepted a caller-provided idempotency key and could query status after a timeout. The other could create duplicates, offered no lookup by request identity, and returned success before its downstream work was durable.

To a schema validator, they were equivalent. To an agent recovering from a lost response, they required opposite behavior.

Argument shape was only the first page of a tool contract. N17Q needed the semantics of the effect around it.

Shape still mattered

The JSON-shaped schema remained valuable. It rejected missing fields, unknown enum values, malformed identifiers, and invalid nesting before execution. It gave the model a bounded vocabulary and made generated arguments inspectable.

I kept the schema narrow. Unknown fields failed rather than passing through. Product defaults were explicit. Strings with path, URL, or identifier meaning received semantic parsers after structural validation.

The mistake had been expecting shape to answer temporal and authority questions it could not represent.

A request can be perfectly well formed and still be unsafe to execute, repeat, expose, or replay.

Effect class established the first boundary

Every reviewed capability received one effect class:

  • Read-only observation.
  • Local transformation without canonical mutation.
  • Local reversible mutation.
  • External reversible mutation with stated limits.
  • Consequential external mutation.

The classes were not a universal risk score. They selected stricter defaults for policy, approval, budgets, isolation, recovery, and replay.

A read could still expose sensitive data or trigger cost. A reversible mutation could leave audit traces or fail to compensate. The detailed contract refined the class.

Starting with consequence prevented every callable function from entering the same orchestration path.

N17Q recorded whether the underlying system accepted a caller key, what arguments that key covered, how long it remained effective, and what response a duplicate received.

A local request identity alone did not make a remote tool idempotent. If the adapter could not transmit the identity or the server did not honor it, the contract said unsupported.

Fixtures sent the same normalized consequence twice, varied nonsemantic transport fields, and changed meaning-bearing fields under one key. The expected behavior was explicit.

The agent saw a concise statement such as “safe to retry with the same effect identity.” The runtime supplied and enforced the identity.

Queryability defined recovery after uncertainty

A timeout after request send created an unknown outcome unless authoritative evidence said otherwise. A query capability could reduce that uncertainty.

The contract named query key, consistency expectations, possible statuses, not-found meaning, and how long results might lag. “Not found” immediately after a write did not necessarily prove non-execution.

The orchestrator knew which delay or repeated observation the fixture required before another mutation became eligible. The model could propose a status check; it could not reinterpret an inconclusive response as permission.

Queryability was a recovery property, not merely another tool in the catalogue.

Compensation was not rollback

Some tools offered a delete, cancel, restore, or supersede operation. I first marked them reversible and moved on.

The contract needed more: which states allowed compensation, who could authorize it, whether it produced another external effect, which information remained, whether third parties might already have observed the original, and what failure left behind.

N17Q represented compensation as a new intent with its own approval, attempts, receipt, and unknown outcomes. The original effect remained in history.

“Compensable within ten minutes before processing” was useful. “Reversible” without limits was misleading.

A connection credential could technically invoke several tools. A run did not inherit all of them.

The contract named required requester role or delegation, eligible task states, resource scope, data classification, approval policy, and execution-time checks. Product policy joined those fields with current run and world state.

The model received only eligible tools. A manually crafted request still passed the same deterministic gate. Tool self-description and provider permission did not substitute for local authority.

This kept capability—the ability to call—from becoming authority—the right for this run to cause the effect now.

A read tool could accept a harmless query and return private material. A write tool could embed a secret in a public destination. The schema type string described neither risk.

N17Q classified fields and result channels by data sensitivity, allowed provider and destination classes, redaction rules, logging treatment, and retention. Dynamic classification could inspect the referenced artifact before execution.

If safe redaction changed meaning, policy denied rather than silently sending altered work. The approval view disclosed what data would cross the boundary.

Tool contracts governed information flow in both directions.

Timeout had stages

A single duration value concealed whether timeout applied to queueing, connection, server acknowledgement, effect completion, or result delivery.

The contract described observable stages and the inference permitted at each one. Failure before send could be safe to attempt again. Interruption after server acknowledgement might require query. Loss after a durable receipt could be recovered locally.

Adapter events preserved the strongest known stage. The harness injected failure at each boundary and checked recovery.

This turned “the tool timed out” from an error string into evidence with operational meaning.

The tool contract recorded limit scope, retry-after semantics, concurrency, and whether rejected calls could still consume a quota. Rate-limit observations updated the run scheduler.

The agent did not need to guess a sleep duration or issue probing calls. N17Q checkpointed next eligibility and let unrelated work continue.

For external mutations, a rate-limit response after ambiguous acknowledgement still followed effect recovery before rescheduling. The label did not prove that no effect occurred.

Cumulative run budgets remained separate from provider limits. Being permitted by one did not grant capacity under the other.

Replay behavior was declared

Every tool mapping named its replay strategy: deterministic pure function, recorded observation fixture, simulated world mutation, sandbox operation against a snapshot, or unsupported.

Replay mode never inferred that read-only meant safe to call live. A read can change, cost money, expose private data, or identify the run to a server.

The fixture key included scenario, normalized request identity, tool contract revision, and relevant world state. Missing fixtures failed closed.

The contract made replay an explicit implementation obligation before a tool could enter N17Q evaluation.

Normalization belonged to the product adapter

The model might supply a friendly repository name, relative file path, destination alias, or optional format. The adapter resolved these into canonical product arguments before policy and approval.

Normalization rejected ambiguous aliases, traversal, unknown fields, and locale-dependent values. It recorded both proposed and normalized forms where useful.

Effect identity derived from normalized consequence, not raw spelling. Approval bound the same representation. A later default change could not alter an old authorized request.

Schema validation happened before normalization and again against the final remote shape. The two checks guarded different boundaries.

A patch tool required an exact base tree digest. A request-creation tool required one prepared artifact and an absent existing effect for the semantic intent. A deletion tool required the resource to remain in an allowed state.

The contract expressed which preconditions the harness could test immediately before execution and what stale outcome meant. Policy never assumed a check performed during planning remained current.

Changing world state invalidated approval where it changed consequence. Replanning produced a new request rather than quietly rebasing an effect.

Temporal correctness became part of the tool boundary.

Success responses were not enough. The contract named what durable observation established completion: new resource identity, artifact digest at destination, repository tree digest, or receipt status.

After execution, N17Q verified postconditions where possible and stored the observation. A nominal success with a missing or mismatched result became unresolved or failed according to semantics.

For eventually consistent systems, the contract described an observation window and intermediate states. It did not display committed until the required evidence existed.

Postconditions connected a tool call to world state rather than trusting a green response.

Error categories were effect-aware

Invalid, forbidden, rate limited, unavailable, conflict, refused, interrupted, and unknown were product categories. Adapters mapped remote evidence conservatively.

Free-form error text could enrich diagnostics but could not determine retry policy. An error after remote acceptance remained unknown despite a message that sounded temporary. A conflict could include current resource evidence and a safe replan path.

Expected outcomes returned typed state. Unexpected adapter bugs raised operational failures with safe request references.

The contract prevented generic exception handling from becoming accidental workflow design.

A search tool could tolerate several parallel reads. A patch tool against one repository needed serialization by base digest. An external create tool allowed only one in-flight attempt per semantic intent.

N17Q recorded global, connection, resource, and intent-level concurrency rules. The scheduler applied all relevant limits before execution.

Provider ability to receive parallel tool calls did not expand these constraints. The model could propose several candidates; the orchestrator queued or denied according to consequence.

Concurrency policy protected identity and world preconditions, not only infrastructure capacity.

Cancellation described guarantees

The contract distinguished cancel request sent, server acknowledged, local process terminated, effect prevented, and result no longer observed.

A cancel button could stop a sandbox process reliably and still leave partial files in its overlay. It could close a remote connection without proving an external create had stopped. N17Q recorded the strongest evidence and evaluated postconditions.

Cancellation never converted unknown outcome into canceled effect automatically.

The interface used plain language while preserving these differences in the recovery view.

Human review saw recovery limits

Before approving a consequential tool, a reviewer saw exact normalized arguments, expected effect, idempotency support, query path, compensation limits, expiry, and what would happen after lost acknowledgement.

This changed the quality of consent. Approving an action with reliable status lookup was different from approving one that could become permanently uncertain.

Technical contract detail became short product copy: “If delivery is interrupted, the system can check this destination by request identity,” or “A lost response may require manual inspection before retry.”

Approval included the risk of recovery, not only the hoped-for success.

The agent received only decision-relevant semantics

Dumping the full contract into every prompt consumed context and exposed implementation detail. N17Q compiled a concise tool description based on task and current state.

It included consequence class, important preconditions, whether retry was safe under the same identity, available status check, and approval need. Sensitive policy and credential details stayed server-side.

After a denial or unknown outcome, the next context included the bounded recovery rule. It did not rely on the model remembering a paragraph from the start of the run.

Progressive disclosure applied to operational semantics too.

Changing timeout mapping, effect class, normalization, query behavior, or replay strategy could change run behavior without changing the tool schema.

Every mapping had a contract revision and digest. Requests, policy decisions, approvals, fixtures, and executions linked to it. In-flight work stayed pinned or paused for migration.

A replay loaded the historical contract with its fixtures. A comparison run could deliberately use a newer revision and record that as the controlled difference.

Versioning made semantic change reviewable rather than hiding it behind the same function name.

The suite covered duplicate requests, changed arguments under one key, response lost before and after effect, delayed query visibility, compensation failure, stale preconditions, scope denial, oversized output, schema drift, cancellation, and missing replay fixture.

Assertions checked run state and simulated world, not merely adapter return values. A timeout fixture failed if policy permitted a second effect before reconciliation. A read fixture failed if sensitive output reached an unapproved provider context.

The contract did not become trusted because it was documented. It earned support through executable cases.

Preview and dry run were separate capabilities

Some tools offered a dry_run Boolean. Its guarantee varied from full validation without commitment to a rough estimate that skipped authorization or used stale state.

N17Q never inferred safety from the flag. A reviewed adapter could expose Prepare, Preview, or Validate as a distinct product capability only when the returned artifact and limitations were clear. The later execution still rechecked current world preconditions.

A preview receipt named inputs, configuration, observation time, and whether the provider promised equivalence with execution. Approval could reference it without assuming the future effect was frozen.

If dry run could itself create logs, reserve capacity, or expose data, the contract classified those consequences too.

Policy could suggest narrowing a tool request from an entire repository to one file or from a public destination to a local preview. It did not mutate and execute the original proposal invisibly.

N17Q returned a structured denial with an eligible narrower capability or argument boundary. The agent or user proposed a new normalized request. That request received its own policy decision, approval when needed, and trace identity.

This preserved what had been asked and what was ultimately allowed. It also prevented a policy engine from becoming an unreviewed co-author of tool arguments.

Constraint was deterministic; changed intention stayed visible.

Discovery did not activate a contract

MCP and provider catalogues could make new schemas appear automatically. N17Q stored them as discovered candidates with server identity and digest.

Effect semantics did not come from discovery. A person or reviewed package had to supply the local mapping, behavioral fixtures, authority class, sensitivity, and replay strategy. Unknown tools remained disabled and absent from model context.

A changed remote schema paused the mapping. A similarly named replacement did not inherit the old contract.

The easier it became to discover tools, the more important this activation boundary became.

Contract ownership remained local

Remote documentation informed the adapter and could improve over time. V0M3's and N17Q's promises belonged to the local contract revision I could inspect and test.

The registry named who reviewed the mapping, its known assumptions, unsupported behaviors, last fixture run, and residual risks. A provider claim could be cited as evidence without becoming an executable rule automatically.

High-consequence tools could remain disabled even with valid schemas and successful conformance tests if query, idempotency, data handling, or authority remained unclear.

Mature capability design included the ability to decline integration.

N17Q displayed tool contracts in a registry organized by product capability, adapter, revision, effect class, authority, and recovery properties.

Two create_request mappings could be compared without pretending they were interchangeable. One might be eligible for bounded automatic retry; another might require human approval and manual recovery after uncertainty.

The selector chose only among mappings that satisfied the scenario's requirements. Fallback re-evaluated privacy and semantics instead of swapping endpoints under the same spinner.

Interoperability benefited from exposing meaningful difference.

Disabling a tool mapping removed it from new model contexts, policy eligibility, pending retries, scheduled jobs, and recovery actions that depended on live invocation. Existing unknown outcomes remained visible until reconciled or explicitly abandoned.

Credentials were revoked under connection policy. Fixtures and historical contract revisions remained for replay and audit according to retention.

Removing the display name alone was not retirement. A stale checkpoint could not regain the capability by rediscovery.

Lifecycle semantics completed the contract around use.

The schema regained its proper importance

Adding effect semantics did not make JSON schemas less valuable. It let them be precise about the problem they actually solved.

Shape validation protected parsers, improved generation, supported inspection, and reduced malformed calls. Effect contracts protected the trajectory: who could act, what would change, how attempts related to consequences, what uncertainty meant, and whether replay was safe.

N17Q needed both. Combining them into one giant remote description would have weakened local control and made provider claims authoritative.

A tool is not merely a function with typed arguments. It is a capability crossing time, state, authority, and often another system.

The schema tells us how to ask. The effect contract tells the product what it would mean to proceed.