Primitive Typist policy#

Gate provides a disabled, deterministic policy for regularizing one complete primitive tool argument against immutable schema metadata supplied by the host adapter. It is a small admission primitive, not a general coercion engine.

from gate.admission import (
    AdmissionKernel,
    PrimitiveKind,
    PrimitiveSchema,
)
from gate.policies import PrimitiveTypistPolicy

count = PrimitiveSchema.create(
    schema_id='example.tool.count',
    version='1.0.0',
    expected=PrimitiveKind.INTEGER,
    minimum=0,
    maximum=100,
)
kernel = AdmissionKernel([PrimitiveTypistPolicy()])

Constructing the schema and kernel activates nothing. An adapter must still prove its lifecycle, target identity, complete candidate, and native effects as described in Action admission. The logical candidate field is argument; native argument names and schema lookup remain host responsibilities.

Pre-execution contract#

Candidate fields must be exact built-in strings, and candidate values must be exact built-in str, int, float, bool, or None values. Behavioral subclasses are rejected both when a candidate is constructed and when an attempt enters admission, before digest identity, field ownership, or policy evaluation can depend on subclass methods.

On a pre tool.call, the policy handles only these cases:

  • An integer schema accepts an exact int within its required finite inclusive bounds. It repairs a canonical decimal string such as 0, 7, or -7 to that integer. It denies signs on positive values, leading zeroes, negative zero, whitespace, decimal or exponent notation, separators, non-ASCII digits, booleans, and out-of-range values.

  • A boolean schema accepts an exact bool. It repairs only the exact strings true and false, and only when the schema explicitly enables lowercase boolean casting. Other spellings and numeric aliases deny.

Canonical integer strings are parsed digit by digit within the policy’s 1,024-byte candidate budget. Python’s process-wide decimal digit setting therefore cannot change an out-of-range denial into evaluator failure or abstention.

Safe repair returns the complete successor candidate. The admission kernel evaluates that value again, so every enacted replacement must be a policy fixed point. When a direct adapter can deny but cannot replace input, a repair request degrades to denial and leaves the original candidate unchanged.

Missing schema metadata, a different candidate field, or a lifecycle mismatch makes the policy abstain. Deep objects, collections, unions, defaults, and arbitrary target annotations are not part of this policy.

Post-failure contract#

On a post tool.failure, the same rules may recognize that a different safe primitive cast was available. The result is an observation with retry=never; it contains no replacement and Gate does not execute or request another tool call. Already-correct, ambiguous, and out-of-bounds values abstain. Even an adapter that advertises retry receives no retry instruction from this policy.

Relationship to my.typing.Typist#

my.typing.Typist is a much broader coercion system. It dispatches across registered transforms, supports nested and generic targets, and offers strict, basic, and flexible cast behavior. my-basis is a Gate dependency, so keeping admission off Typist is a contract decision rather than a dependency one: this policy owns exactly two canonical casts so that its repair set can be enumerated and audited. A Typist-backed adapter may be added once a protocol defines which target annotations, cast flags, failure signals, and nested candidate ownership are safe. It must still return a complete candidate through the same admission kernel; it may not mutate a model call, conceal a retry, or infer schema authority from a failure message.

Bounded, deterministic regularization for host-described primitive arguments.

The host supplies immutable schema metadata and one complete primitive argument. This policy does not inspect native tool schemas, traverse nested inputs, call a model, or retry tools. It owns exactly two canonical casts rather than routing through my.typing.Typist so the admission repair set stays enumerable; a Typist-backed adapter can later build on the same kernel.

class gate.policies.typist.PrimitiveTypistPolicy#

Regularize only canonical bounded integers and opted-in lowercase booleans.

evaluate(attempt: Attempt) → Proposal#

Return one deterministic proposal without native mutation or retry.