Repository / Agent Readiness v1
Repository readiness means sufficient static evidence under this versioned policy. It is not a runtime guarantee, security certification, AI safety score, probability, LLM judgment, recommendation, or authorization to give an agent access.
The independent contracts are apizr.repository-readiness-policy/v1 and
apizr.repository-readiness/v1. They consume Catalog v1, Graph v1 and embedded
local Readiness v1 without changing any of those contracts. Local Readiness remains
authoritative for interface eligibility.
from apizr.repository_readiness import RepositoryReadinessPolicy, assess_repository
report = assess_repository(catalog, graph, policy=RepositoryReadinessPolicy())
This call performs no filesystem discovery, source parsing, AST analysis, import resolution, readiness rerun, source execution, or Docker availability check. It roundtrips both typed documents and the policy through validation, including nested unchecked model copies, and requires:
graph.catalog_digest == catalog_digest(catalog);graph.repository_digest == catalog.repository_digest;- graph capability metadata, module identities and catalog exit evidence agree with the Catalog.
The report binds the repository, catalog, graph and readiness-policy digests. It
introduces no separate source identity. Digests bind content; they do not authenticate
who supplied it or prove that declared evidence is true. validate_report(report,
catalog, graph) re-evaluates and compares every conclusion and snapshot against
its bound inputs. Parsing a standalone report validates its internal invariants;
use validate_report when the original artifacts are available.
Assessment universe and state
There is one assessment for every embedded per-source Readiness assessment,
including declarations rejected from IR. Its original capability_id is unchanged.
local_readiness retains source/module/symbol/span, in_ir, local state,
can_generate_interface, all dimensions, and the original APIZR-READY-* reasons.
in_catalog explicitly indicates trusted catalog membership. Rejected declarations
have unavailable graph evidence and unknown effect facts; no replacement IDs or
capabilities are invented. Sources without inspections have no declarations to
assess: their Catalog diagnostics remain in the report.
State precedence is ambiguous > unsupported > conditional > ready.
| State | Repository meaning |
|---|---|
ready |
Locally interface-eligible; every supplied requirement is satisfied by static evidence and at least one declared mode supports all required controls. |
conditional |
Required evidence is incomplete, or local Readiness is conditional. Unknown information is not a hard failure. |
unsupported |
Local Readiness is unsupported, an effect required false is evidenced true, a hard interface requirement is unmet, or no declared mode supports all controls. |
ambiguous |
Upstream Readiness is ambiguous, or relevant Graph identity/import evidence cannot select a stable unique binding. This is never downgraded. |
ready does not mean every dependency executes, all behavior is known, side effects
are absent, or an agent should receive access. There is no numeric aggregate score
or blanket repository readiness state. Counts include all four states. Catalog and
Graph diagnostics/completeness remain separately visible, even for empty reports.
Policy and effect evidence
Default policy, shown as JSON (the CLI accepts JSON):
{
"schema_version": "apizr.repository-readiness-policy/v1",
"effects": {"require_known": [], "require_false": []},
"relationships": {"require_resolved": true},
"execution": {
"modes": ["local-process", "oci-container"],
"require_controls": []
},
"require_interface": false
}
Local interface eligibility always gates ready. require_interface: true
additionally makes present ineligibility a hard policy failure, so an upstream
conditional interface yields repository unsupported. Its default is false to
preserve the distinction between incomplete evidence and proven local lack of
support. Unknown options, effect/control names and coercible boolean strings are
rejected; set-like policy lists are deduplicated and sorted.
Effects come only from Capability IR embedded in source Inspections. Every effect
retains its value and evidence: filesystem_read, filesystem_write, network,
environment, subprocess, state_mutation, secrets, external_service.
The current source analyzer generally leaves effects unknown. A declaration that
has no IR contributes unknown effects, never false by absence.
| Requirement | Unknown | True | False |
|---|---|---|---|
require_known |
conditional | satisfied as known | satisfied as known |
require_false |
conditional | unsupported | satisfied |
For example, {"require_known": ["network", "filesystem_write"],
"require_false": ["secrets"]} requires three explicit facts. A backend network
control does not turn unknown network effect evidence into false. When both effect
lists name one effect, both requirements apply and one unknown reason is retained.
Graph evidence and exact diagnostic mapping
Each in-Catalog declaration has a resolved, partial, or unavailable
relationship dimension. Graph v1 is the only source of relationships.
- Diagnostics match the declaration's source path. A diagnostic inside its inclusive local Readiness source span affects that declaration. A diagnostic inside another declaration's span does not affect it.
- Diagnostics outside every Readiness declaration span in that module, or without a line, affect all declarations in the module. This conservatively represents module binding/import uncertainty. Graph v1 has no diagnostic scope field; no new lexical analysis is performed.
- A global Graph resource-limit diagnostic (
path == ".") affects all declarations because Graph v1 discards every syntax relationship on aggregate exhaustion. - Missing/unanalysed module evidence, input failure, unavailable analysis, or resource
exhaustion yields
unavailable. Other relevant diagnostics yieldpartial. - Relevant import declarations with
unresolved,starorambiguousnames also make the dimension partial.APIZR-GRAPH-002(unstable/multiple repository import interpretations),APIZR-GRAPH-009(module collision), or an ambiguous import name additionally preserve identity ambiguity as repositoryambiguous. - Dynamic/star imports, rebound imports, unstable calls and unstable callable references therefore remain visible. Resolved external imports are ordinary evidence and do not independently make relationships partial. Their separate local Readiness dependency reasons remain authoritative.
relationships.require_resolved defaults to true. Setting it false removes the
relationship completeness requirement; it does not clear local Readiness or
identity ambiguity. Overall Graph incompleteness from an unrelated module does not
change a declaration's state, but remains visible on the report and CLI exit status.
relationships.direct preserves outgoing capability graph edges, including
calls_capability, references_capability, imports_capability, and any local or
external module imports. module_imports separately preserves module-scope imports
as context; these are not rewritten as capability edges. imports retains relevant
Graph import declarations. dependencies snapshots the IDs, local Readiness and IR
effects of the direct capability targets in those two groups.
These snapshots are context only. A call from A to B does not cause A to inherit B's effects or readiness. A call from B to C does not add C to A's canonical direct relationships. Graph v1 edges describe possible direct static calls, not execution proofs. There is no transitive effect or state propagation in v1.
Execution compatibility: additive v1 completion
Readiness defines its own transport-neutral Control vocabulary; it does not
extend the control enum or alter any execution policy, plan, backend, or generated
bundle contract. The static adapter lives in repository_readiness/execution.py.
It obtains local guarantees from BackendCapabilities without calling the host
availability function. Its explicit OCI additions map to the existing reviewed
network/filesystem controls and Resources.memory_bytes, cpu_millis, and pids.
No runtime behavior or #58 embedded-code hash changes are involved.
Only declared control support is assessed, independently of host OS, environment,
Docker, images or daemon access. Every mode says runtime_availability: not_assessed.
At least one selected mode must support all required controls; support cannot
be assembled from multiple modes. Compatibility is not a recommendation or ranking.
| Readiness control | direct | local-process | OCI-container |
|---|---|---|---|
wall_timeout |
no | yes | yes |
input_limit |
no | yes | yes |
output_limit |
no | yes | yes |
environment (clean/allowlisted) |
no | yes | yes |
working_directory (fresh) |
no | yes | yes |
network_deny |
no | no | yes |
filesystem_sandbox |
no | no | yes |
memory_limit (hard memory limit) |
no | no | yes |
cpu_limit (CPU quota) |
no | no | yes |
pid_limit |
no | no | yes |
subprocess_deny |
no | no | no |
direct represents existing ungoverned invocation, with an empty guarantee set
and backend_version: direct; it does not invent a governed runtime version.
It must be explicitly selected. With no requested controls it is compatible; with
any requested control it is incompatible. The unchanged default modes remain
local-process and oci-container.
Memory, CPU and PID requirements describe support for the existing OCI policy's
configured limits. Readiness does not choose numeric limits or promise a given
allocation. Memory hard limits are distinct from CPU quotas, which constrain CPU
use rather than guaranteeing latency. PID containment does not prohibit creating
subprocesses: subprocess_deny remains unsupported everywhere, and #49 remains open.
Byte compatibility with the original v1
Schemas only add enum values. Old policy defaults, accepted names, semantics and
canonical bytes remain unchanged. The original #59 policy/report goldens are
retained unchanged; additional snapshots capture the default policy and its report
at baseline ebe7af7. Tests cover all 768 combinations of the old control/mode
subsets, and revalidate saved reports against their original inputs.
To avoid changing old report bytes merely by expanding an advertised guarantee
list, supported_controls is a vocabulary projection:
- Policies using only original modes and controls retain the original v1 list.
- Explicit selection of
director any resource control enables the completed vocabulary in every selected mode's list.
This affects the breadth of the reported list, not the meaning of any old control. Compatibility always tests all requested controls against one mode's guarantees. New capabilities are visible only when the input explicitly opts into this additive completion; no default digest is silently changed. To inspect the full matrix in a report, explicitly select all three modes. Old documents remain valid, and new resource requirements are never silently ignored.
Container compatibility is conditional on actual deployment of the existing OCI execution policy, including clean environment, network deny, constrained filesystem and configured resource limits. Assessment does not create a plan, select an image, establish availability or promise invocation success. Docker, its daemon, a worker image, and the necessary Linux controls can all be absent while static compatibility is true.
Human output lists each selected mode's compatible/incompatible result, missing
controls and the number of repository-ready declarations whose control requirements
it satisfies. This is evidence context; it does not select a backend. --details
adds supported controls and expands all declarations.
Repository reason codes
Machine semantics use code and optional typed effect; messages are presentation.
Original local reason codes are retained unchanged in local_readiness.
| Code | Meaning |
|---|---|
| APIZR-REPOREADY-001 | Hard interface generation requirement unmet |
| APIZR-REPOREADY-002 | Required Graph evidence unavailable |
| APIZR-REPOREADY-003 | Required relationships partial |
| APIZR-REPOREADY-004 | Required effect unknown (effect names it) |
| APIZR-REPOREADY-005 | Required-false effect evidenced true (effect names it) |
| APIZR-REPOREADY-006 | No declared execution mode satisfies every required control |
| APIZR-REPOREADY-007 | Relevant identity/binding ambiguity |
| APIZR-REPOREADY-008 | Declaration absent from trusted Catalog |
Canonical UTF-8 JSON has sorted object keys, ordered assessments and a final newline.
policy_bytes, policy_digest, report_bytes, report_digest expose independent
content identities. Published schemas are
policy and
report.
Repository-first orchestration
apizr readiness ROOT calls graph_repository(...) exactly once, then passes that
result's Catalog and Graph to the same assess_repository used by the artifact-first
CLI. The existing discovery manifest feeds both layers: source bytes are not reopened
between Catalog, Graph and readiness. The pure assessment API above is unchanged.
--source-root, --exclude-dir and all Scan/Graph bounds share parsing and policy
construction with apizr scan and apizr graph. --policy FILE selects the readiness
policy; --report and --format json emit the same canonical v1 report, with no
wrapper or progress output on stdout. The root path never enters canonical identity.
--details expands human output beyond its default 20 declarations. The existing
apizr repository-readiness CATALOG GRAPH remains fully supported, including its
complete human output and --format json; it also accepts --report.
Instrumentation tests count exactly one discovery and one read per source, mutate source after Catalog assembly to detect reopening, compare independent Scan/Graph artifacts with repo-first bytes, and check ordering/location/hash-seed invariance. An isolated audit-hook test forbids source execution, source writes, subprocesses, network access, Git/package-install commands and Docker/transport imports; hostile top-level statements, decorators and defaults remain inert.