# Verifier and policy This page is for services and developers who want to measure PCOCs themselves, or to understand what an admission gate measures. Verifying redoes a sample of the making, checks the PCOC's times against Bitcoin's public record, and writes a measurement record. It never says pass or fail. Conforming verifiers follow the same specification and pass the same conformance vectors, and the Rust, C, Go and Java SDKs are cross-checked against each other, so a PCOC is measured the same way by any conforming verifier. Use the SDK in your language, then apply your policy to the record. Policy is your choice. groundinglab's own settings are in [POLICY.md](https://github.com/groundinglab/pcoc/blob/main/policy/groundinglab-admission/POLICY.md), a recommendation, not part of the specification; [How we set groundinglab's admission policy](/admission-gate/policy/) gives the argument and the evidence. ## SDK verify - **Rust:** [sdk/rust/pcoc-cli/src/main.rs](https://github.com/groundinglab/pcoc/blob/sdk-rust-v2.3.1/sdk/rust/pcoc-cli/src/main.rs) - **Go:** [sdk/go/cmd/pcoc/main.go](https://github.com/groundinglab/pcoc/blob/sdk/go/v2.3.1/sdk/go/cmd/pcoc/main.go) - **Java:** [sdk/java/src/main/java/io/groundinglab/pcoc/cli/Main.java](https://github.com/groundinglab/pcoc/blob/sdk-java-v2.3.1/sdk/java/src/main/java/io/groundinglab/pcoc/cli/Main.java) Assumes: an SDK in your language ([SDKs](sdk.md)) and a PCOC to check ([Integrate a producer](integrate-a-producer.md)). Vectors. The single conformance pack is [spec/conformance/pack](https://github.com/groundinglab/pcoc/tree/spec-2.3.0/spec/conformance/pack). Its status is complete. The manifest SHA-256 is `91ded57e5c05b7cb4cd74d313a51d83d2373fa86dc625df41faed9586e9032af`. The [README](https://github.com/groundinglab/pcoc/blob/spec-2.3.0/spec/conformance/pack/README.md) names the vectors. The admission gate keeps its own test vectors (anchor window, sign-in origins, a three-leg mock object) in [services/admission-gate/tests/vectors](https://github.com/groundinglab/pcoc/tree/main/services/admission-gate/tests/vectors). 1. The split. Section 13 produces the object, section 14 measures it, and section 15 is the admission service (SPEC §2). The verifier writes a measurement record and makes no judgement ([sdk/README.md](https://github.com/groundinglab/pcoc/blob/main/sdk/README.md)). Accept, refuse and revoke are one relying party's decisions, not pass/fail ([services/admission-gate/README.md](https://github.com/groundinglab/pcoc/blob/main/services/admission-gate/README.md)). 2. What verify reads. Each index read is a single lookup; the verifier never scans across many heights (Rule A4, §14). The checkpoint measurement reads GET {index}/index/{beacon_height} (admission-gate [deploy/gate.toml](https://github.com/groundinglab/pcoc/blob/main/services/admission-gate/deploy/gate.toml)). Comparing a plant (the Bitcoin output that timestamps waypoints) uses root, txid, vout, block_hash, block_height, never tree_size (§14.3). `anchored` is recorded only when the inclusion height is in the window, the header is stored, and the plant matches (§14.3, §14.5). 3. Index options, all opt-in. The hosted index is https://index.groundinglab.io. To run your own: `pcoc-index` (default bind 127.0.0.1:38081; GET /index, /index/{h}, /index/since), filled by Bari or by `pcoc-index rebuild --source esplora` / `--source rpc` from a pruned node, which checks header links ([services/index/README.md](https://github.com/groundinglab/pcoc/blob/main/services/index/README.md)). Anyone can skip the service and read Bitcoin directly (SPEC §14). 4. Running it. Each SDK's `pcoc verify` takes a PCOC file ([sdk/README.md](https://github.com/groundinglab/pcoc/blob/main/sdk/README.md)), or call the SDK's verify function from your own code, as the SDK examples above do. How many checkpoint comparisons run at once doesn't change the record (Rule A4.3). 5. Conformance. Compare `record` on each vector in the pack (SPEC §16.1; [spec/conformance/pack/README.md](https://github.com/groundinglab/pcoc/blob/main/spec/conformance/pack/README.md)). 6. The record. One JSON object, with the keys in the order SPEC §14 lists (profile … analysis). No null; tokens are strings; RFC 8785 for verify_record_sha256; one trailing newline. An object of any kind other than `v2.2-pcoc-object` is recorded as `unknown kind`, with the kind text it carried (Rule A5). That is a measurement, not a failure; a gate refuses it with reason `unknown_kind` (Rule B9). The fast record (§15.3) omits checkpoints.legs.result, six_leg and six_leg_runs. Token glossary (§14.1–14.7): - shape: `match` or `mismatch`, with `shape_item` from a closed list of 14. - anchors: `anchored` only when in window, header stored and plant `match`; otherwise `not anchored`. - six_leg: six `match`/`mismatch` results; `not defined` under six legs. - N: checkpoints in stages a…b−1 (A4.7). - S: T(P_b) − T(I_{a−1}), in seconds (A4.8). - delta_h: height_P_b − height_I_a_minus_1, index-confirmed heights only (A4.8). - Shared tokens: `not defined`, `not read`, `n/a`, `not fetched by design`, `unknown kind`. 7. Writing a policy. Part B, §15. Inputs §15.1, outputs and states §15.2: outcomes provisional, accept, refuse, revoke, held; states received, provisional, accepted, refused, revoked, held. `held` is a measurement not yet read, waiting for a retry, not a negative; how often a gate retries is its `held_retry_seconds` setting. A negative after any grant is revoke. Two-phase async §15.3. Every setting a policy chooses is a lever in §15.4, with its unit and allowed range. Version 2.3 gives no lever a default. §15.5 is how to measure a leg-rate floor. A policy sets the values. 8. Example: gl-admit-v12, groundinglab's live policy for this specification. These numbers are one relying party's chosen settings, not part of the specification or the measurement: the record (beat 6) is the same whatever a policy sets. Leg-rate floor 1/10 (0.1 legs/s testing, one leg every 10 s on average over the making); at least 6 of the 16 waypoints W_1 … W_16 anchored, any 6; no tip-versus-last-beacon submission deadline; a held submission retried every 600 s; the deep check redoes 18 legs in 3 rounds of 6; no door-session verify cap; a key caught with a fake leg is ignored at this gate with no expiry. Why these values: [How we set groundinglab's admission policy](/admission-gate/policy/). Changing any number means a new id, and startup refuses a changed number under the same id (policy-bind.json). Another relying party may pick other values under its own policy id. GET /v1/policy shows the gate's ([gl-admit-v12.toml](https://github.com/groundinglab/pcoc/blob/main/policy/groundinglab-admission/gl-admit-v12.toml); [POLICY.md](https://github.com/groundinglab/pcoc/blob/main/policy/groundinglab-admission/POLICY.md)). 9. What not to infer. Log entries are groundinglab's decisions; another party may decide differently. A verify record shows no cost figure; cost is not the verifier's concern. Catch rates and economic security aren't established ([STATUS.md](https://github.com/groundinglab/pcoc/blob/main/STATUS.md)). Next: to present an accepted object to a site, see the sign-in wire ([Sign-in wire](sign-in-wire.md)).