Agent Lease Manifest

What an agent DECLARES it needs before the kernel lets it run. The manifest is the declared half of a two-part record: the agent (or the bridge or harness presenting on its behalf) declares tools, paths, hosts, commands and budget, and the kernel answers with an Agent Lease whose manifest is the GRANTED half, narrowed to what the parent lease and the workspace policy allow. Declared and granted have the same shape on purpose, so the narrowing diff is a plain comparison. Rule 7 of the harness: no manifest, no lease; no lease, no connectivity. A manifest the kernel cannot narrow to a non-empty grant is refused, and the refusal is recorded. Paths are workspace-relative POSIX globs; hosts are lower-case DNS names (IPv4 literals and localhost included) with an optional single leading wildcard label; commands are executable basenames; tools are identifiers of at most 128 characters and never *.

Schema
agent-lease-manifest.schema.json, served as JSON at its $id: https://cognitive-delivery.github.io/contract/1.x/agent-lease-manifest.schema.json
Dialect
http://json-schema.org/draft-07/schema#
Root
object, open (additional properties are carried)
required: schema_version, agent, intent, allow, deny, budget, approvals
Stability
none stated at the root; every declared property carries its own
Properties
39 declared: 9 under the root, 30 in definitions

Properties

Every declared property under the root, in the schema's own order. [] is an array's items, .* the shape of every unnamed member, #name a definition. Objects carry additional properties unless a row says otherwise.

PathTypeRequiredDescriptionConstraintsStability
schema_versionstringyesContract version this record was written against, as major.minor. One rule across every schema (schema set 1.2): a reader compares the major only, and a minor it has not met is additive by the contract's own rule.pattern ^\d+\.\d+$stable
agentobject #agentyesWho is asking. name is a label for the cockpit; kind says how the harness runs it; runtime_agent is the existing closed agent vocabulary so a lease keys to the same identity every audit event already carries.stable
parent_lease_idstringThe lease this manifest is presented under, when it is a child. A root manifest has none and is narrowed against the workspace policy instead.pattern ^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$stable
intentobject #intentyesWhy the agent is running. purpose is required and non-empty: a manifest with no stated purpose is refused.stable
allowobject #allowyesWhat the agent asks to be allowed. Every list is required and may be empty; an empty tools list in a GRANTED manifest is a lease that opens nothing, which is why the kernel refuses rather than grants it. Granted lists are always a subset of the parent's.stable
denyobject #denyyesWhat the agent must not do even if allow would otherwise permit it. Granted deny lists are the UNION of the declared and the parent's, so a child can never shed a parent's refusal.stable
budgetobject #budgetyesCeilings. Every field is optional and non-negative; an absent field means the parent's remaining budget applies. A child's granted budget is clamped to its parent's remaining, depth is decremented per generation and fan_out is decremented on the parent as each child is issued.stable
approvalsarrayyesAction names that need a human before the agent may perform them, under the same identifier rule as tool names. Required and may be empty.stable
approvals[]stringAn action that needs a human first; the same identifier rule as a tool name. At most 128 characters of letters, digits, _, ., :, / and -, so a governed cdf_ name and a <server>/<tool> pair both fit. * is refused: a lease that names every tool has not named one, and SPEC §5.2 R2 exists because a grant must say what it opens. Whitespace is refused.pattern ^[A-Za-z0-9_][A-Za-z0-9_.:/-]{0,127}$
min length 1
attestationobject #attestationWho vouches for the declaration. Optional: an agent presenting its own manifest has nothing to sign with, and the bridge or harness signs on its behalf.stable

Definitions

The named shapes this schema refers to as #name. A row above that links here is not expanded in place; its constraints are the definition's.

#model

PathTypeRequiredDescriptionConstraintsStability
#modelobjectThe model behind the agent, for attribution. Never a prompt, never a key.
#model.vendorstringyesmin length 1stable
#model.familystringyesmin length 1stable
#model.versionstringstable

#agent

PathTypeRequiredDescriptionConstraintsStability
#agentobjectWho is asking. name is a label for the cockpit; kind says how the harness runs it; runtime_agent is the existing closed agent vocabulary so a lease keys to the same identity every audit event already carries.
#agent.namestringyesDisplay label for the cockpit, at most 120 characters: the worker role, the session, the plugin. Not an identity, and never a person's name, email address or git identity; this value is recorded in an audit journal that is retained indefinitely.min length 1
max length 120
stable
#agent.kindstringyesHow the harness runs this agent. native: inside the kernel's own process. delegated-cli: a spawned coding CLI. plugin: loaded into the host. external: presented over a bridge from outside the harness.one of "native", "delegated-cli", "plugin", "external"stable
#agent.runtime_agentstringyesThe closed agent identity vocabulary. unknown is a first-class value, never an error: the kernel looked and could not tell. cdf-native (schema set 1.0, additive) is the harness's own native turn loop: the kernel drives a model provider directly, with no vendor CLI or SDK.one of "codex-cli", "claude-code", "gemini-code-assist", "github-copilot", "cdf-native", "unknown"stable
#agent.providerstringThe organisation or product providing the agent, when it differs from the runtime.stable
#agent.modelobject #modelThe model behind the agent, for attribution. Never a prompt, never a key.stable
#agent.harness_versionstringVersion of the harness that generated or presented this manifest.stable

#intent

PathTypeRequiredDescriptionConstraintsStability
#intentobjectWhy the agent is running. purpose is required and non-empty: a manifest with no stated purpose is refused.
#intent.spec_slugstringThe governed spec this run serves, when there is one.stable
#intent.task_idstringThe task within that spec, when there is one.stable
#intent.purposestringyesOne sentence of intent, at most 500 characters. Recorded in the audit journal, so no prompt and no content.min length 1
max length 500
stable

#allow

PathTypeRequiredDescriptionConstraintsStability
#allowobjectWhat the agent asks to be allowed. Every list is required and may be empty; an empty tools list in a GRANTED manifest is a lease that opens nothing, which is why the kernel refuses rather than grants it. Granted lists are always a subset of the parent's.
#allow.toolsarrayyesGoverned tool names the agent may call. An empty list in a GRANTED manifest is refused (SPEC §5.2 R2).stable
#allow.tools[]stringA governed tool name the agent may call. At most 128 characters of letters, digits, _, ., :, / and -, so a governed cdf_ name and a <server>/<tool> pair both fit. * is refused: a lease that names every tool has not named one, and SPEC §5.2 R2 exists because a grant must say what it opens. Whitespace is refused.pattern ^[A-Za-z0-9_][A-Za-z0-9_.:/-]{0,127}$
min length 1
#allow.read_pathsarrayyesWorkspace-relative POSIX globs the agent may read. Refused here, without lookahead so any RE2-based validator can load the rule: a leading /, any .. segment, a leading ~, a drive-letter prefix and any backslash. The registry re-checks the resolved path against the workspace root.stable
#allow.read_paths[]stringmin length 1
must not match ^/, (^|/)\.\.(/|$), ^~, ^[A-Za-z]:, \\
#allow.write_pathsarrayyesWorkspace-relative POSIX globs the agent may change. Refused here, without lookahead: a leading /, any .. segment, a leading ~, a drive-letter prefix and any backslash. The registry re-checks the resolved path against the workspace root, and a change outside the granted set is a scope violation that revokes the lease.stable
#allow.write_paths[]stringmin length 1
must not match ^/, (^|/)\.\.(/|$), ^~, ^[A-Za-z]:, \\
#allow.hostsarrayyesHosts the agent may reach. *.example.com matches api.example.com and not example.com; matching a bare parent domain requires listing it. Enforced by the egress proxy once it keys off the lease.stable
#allow.hosts[]stringA host the agent may reach. A lower-case DNS name of one or more labels, an IPv4 literal or localhost (both are DNS-name shaped), with an optional single leading *. label, or the bare *. Refused by the pattern, which uses no lookahead or backreference and compiles under RE2: a scheme, a port, a path, whitespace, upper case, a trailing dot and a wildcard anywhere but the first label. A port is not a host: the egress proxy matches hostnames, and a rule nothing enforces is a claim. IP literals are admitted because a local model provider (Ollama, LM Studio) lives at 127.0.0.1 and the root policy derives its hosts from provider URLs.pattern ^(\*|(\*\.)?[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?(\.[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?)*)$
min length 1
max length 253
#allow.commandsarrayyesExecutables the agent may run, by basename.stable
#allow.commands[]stringAn executable the agent may run. The basename of the executable, at most 128 characters: letters, digits, ., _, +, -. No path separator (identity is the resolved executable's basename, not where it was found), no whitespace (an argument is not part of the name) and no shell operator.pattern ^[A-Za-z0-9][A-Za-z0-9._+-]{0,127}$
min length 1
#allow.tool_argsobjectDECLARED argument constraints per tool (schema set 1.2, development stability): tool name to a JSON Schema the agent proposes for its own calls to that tool, after Progent's argument-schema policies. A declaration, not a grant: in 1.x an issuer MAY omit it from the granted manifest and MUST NOT treat it as granted authority, because the reference gate does not yet evaluate argument schemas and a narrowing rule without an enforcing gate is a claim the corpus cannot test. The vector tool-args-dropped shows the reference dropping it. It becomes a rule when a gate enforces it.keys must match ^[A-Za-z0-9_][A-Za-z0-9_.:/-]{0,127}$
additional properties: see #allow.tool_args.*
development
a declaration an issuer MAY omit from the grant (SPEC 4.4); becomes a rule when a gate enforces it
#allow.tool_args.*objectA JSON Schema. Not validated as one here: draft-07 cannot validate a schema as data without a meta-schema $ref, which the self-contained rule forbids.

#deny

PathTypeRequiredDescriptionConstraintsStability
#denyobjectWhat the agent must not do even if allow would otherwise permit it. Granted deny lists are the UNION of the declared and the parent's, so a child can never shed a parent's refusal.
#deny.commandsarrayyesExecutable names refused outright, for example sudo, su, docker, ssh, curl, wget, launchctl, systemctl.stable
#deny.commands[]stringAn executable refused outright. The basename of the executable, at most 128 characters: letters, digits, ., _, +, -. No path separator (identity is the resolved executable's basename, not where it was found), no whitespace (an argument is not part of the name) and no shell operator.pattern ^[A-Za-z0-9][A-Za-z0-9._+-]{0,127}$
min length 1
#deny.pathsarrayyesPOSIX globs the agent must not touch: credentials, governance evidence, the lease journal itself. A denial MAY be home-relative (~/.ssh/**), because refusing a path outside the workspace is meaningful even though no allow could grant it; a leading /, any .. segment and any backslash are refused.stable
#deny.paths[]stringmin length 1
must not match ^/, (^|/)\.\.(/|$), \\
#deny.hostsarrayyesHostnames refused outright.stable
#deny.hosts[]stringA host refused outright. A lower-case DNS name of one or more labels, an IPv4 literal or localhost (both are DNS-name shaped), with an optional single leading *. label, or the bare *. Refused by the pattern, which uses no lookahead or backreference and compiles under RE2: a scheme, a port, a path, whitespace, upper case, a trailing dot and a wildcard anywhere but the first label. A port is not a host: the egress proxy matches hostnames, and a rule nothing enforces is a claim. IP literals are admitted because a local model provider (Ollama, LM Studio) lives at 127.0.0.1 and the root policy derives its hosts from provider URLs.pattern ^(\*|(\*\.)?[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?(\.[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?)*)$
min length 1
max length 253

#budget

PathTypeRequiredDescriptionConstraintsStability
#budgetobjectCeilings. Every field is optional and non-negative; an absent field means the parent's remaining budget applies. A child's granted budget is clamped to its parent's remaining, depth is decremented per generation and fan_out is decremented on the parent as each child is issued.
#budget.stepsintegerMaximum tool calls or turns.min 0
max 9007199254740991
stable
#budget.wall_clock_msintegerMaximum lifetime in milliseconds; the lease expires when it is spent.min 0
max 9007199254740991
stable
#budget.tokensintegerMaximum model tokens, input plus output.min 0
max 9007199254740991
stable
#budget.cost_usdnumberMaximum spend in US dollars.min 0stable
#budget.depthintegerHow many generations of child lease may be issued beneath this one. Zero means no children. At most 16: the reference root policy allows 4, and a declaration above the ceiling is nonsense rather than something to clamp.min 0
max 16
stable
#budget.fan_outintegerHow many child leases may be live under this one at once. At most 256: the reference root policy allows 8.min 0
max 256
stable

#attestation

PathTypeRequiredDescriptionConstraintsStability
#attestationobjectWho vouches for the declaration. Optional: an agent presenting its own manifest has nothing to sign with, and the bridge or harness signs on its behalf.
#attestation.issuerstringyesWhich party produced the declaration.one of "agent", "bridge", "harness", "plugin"stable
#attestation.signaturestringLower-case hex signature over the canonical bytes of the manifest, when the issuer can sign: 64 hex characters, which is HMAC-SHA256 like the lease's own signature. An odd-length or longer value is not a signature this contract defines.pattern ^[0-9a-f]{64}$stable
#attestation.key_fingerprintstringFingerprint of the key that produced signature. Never the key.min length 1stable