Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,8 @@ internal/dialect/testdata/** -text
# Pinned policy prototype files have exact upstream checksums.
internal/policy/prototype/** -text

# Candidate schemas, provenance, examples and vectors also retain exact bytes.
internal/policy/candidate/** -text

# The served authoring schema has a byte digest on every platform.
internal/dialect/version2.schema.json -text
7 changes: 7 additions & 0 deletions NOTICE
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,10 @@ the evaluation corpus, its manifest schema, and the pack fixtures it names.

The exact embedded revision and per-file SHA-256 digests are recorded in
internal/artifacts/jps/<version>/lock.json.

The experimental offline Policy tools also embed unmodified nonnormative RFC
0023 prototype and proposed-draft contract candidate artifacts from that same
Apache-2.0 specification repository. Their separate exact source revisions,
per-file SHA-256 digests, upstream LICENSE and NOTICE are retained under
internal/policy/prototype/ and internal/policy/candidate/. The candidate is not
an adopted specification artifact or a conformance class.
59 changes: 59 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1136,3 +1136,62 @@ in [MCP clients](docs/mcp-clients.md#experimental-policy-prototype-tools).
The RFC, prototype schemas and synthetic fixtures are bundled from specification
revision `8a56a95d555c17640d2db4984363b779536b3c2a`, with per-file digests and
licensing provenance. They are never fetched at runtime.

### Proposed draft Policy contract candidate

The same experimental commands additionally support the **unadopted,
proposed-draft** candidate `formatVersion: "1.0.0"`
([ADR-0060](docs/adr/0060-explicit-policy-candidate-format.md)). It is a review
candidate for RFC 0023, not a stable format, adopted standard or conformance
class. Its artifacts are pinned separately to Spec commit
`0852c5fa7726e51b36e574a5b110e7f5e012e03d` in
[the candidate provenance manifest](internal/policy/candidate/provenance.json).

Default `contract` output and all prototype reports keep their existing shape
for strict clients. Explicit discovery returns a separate `registryVersion: "1"`
report; selecting one contract returns that format's provenance and capabilities:

```bash
jpack experimental policy contract --all-formats --format json
jpack experimental policy contract --format-version 1.0.0 --format json
jpack experimental policy init --kind policy --format-version 1.0.0 --id urn:example:candidate --version 7.3.42
jpack experimental policy schema --kind governing-adoption --format-version 1.0.0
jpack experimental policy check candidate-adoption.json --materials retained-materials.json --format json
```

`--all-formats` and contract `--format-version` are mutually exclusive. Documents
with `formatVersion` select the candidate grammar explicitly; supported prototype
inputs continue using their exact wrapper. An optional `--format-version 1.0.0`
on canonicalize/digest/validate/check also selects candidate refusal handling for
malformed or selector-less input. It does not insert a missing selector, rewrite
an artifact or migrate bytes. Candidate Policies use `workspace-managed` or
`externally-managed`; `desk-managed` is refused. Artifact `version` remains
independent of the format selector. Candidate adoption requires retained
candidate Policy bytes; prototype Policies cannot satisfy those references.

Candidate reports identify `formatVersion`, `proposed-draft` maturity, their
exact source pin and `candidateCapabilities`. Only a full candidate `check`
includes `candidateResult`, whose complete value is one of:

```json
{"status":"valid","formatVersion":"1.0.0","maturity":"proposed-draft"}
{"status":"refused","code":"invalid-selector"}
```

The finite refusal codes and phase ordering are defined by the
[pinned candidate contract](internal/policy/candidate/README.md#5-resource-limits-and-refusal-classifications).
Runtime retains exit 0 for success, 1 for invalid content and 2 for unsupported
input; the nested result supplies the portable candidate classification.
Environment failures are operational errors and provide no candidate result.
Canonicalize/digest establish encoding and identity only; validate checks closed
document forms and local references, with retained materials unchecked. Their
reports omit `candidateResult`.

The Go harness compares all 124 exact portable result objects, acquiring vector
sources lazily and preserving raw Pack numbers and every retained-byte identity.
It uses the shared registration/checking engine directly: valid distinct-byte
bundles can exceed the private 24 MiB JSON/base64 carrier or MCP's 16 MiB request
limit, especially when identical bytes are registered under multiple media
types. Those transport ceilings are unchanged. Agreement with these vectors
supplies no independently authored implementation evidence, approval, current
authority or permission.
135 changes: 135 additions & 0 deletions docs/adr/0060-explicit-policy-candidate-format.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
---
status: accepted
date: 2026-10-18
deciders: maintainer
---

# Add an explicit Policy contract candidate without changing prototype clients

## Context and problem statement

The RFC 0023 Policy contract candidate introduces `formatVersion: "1.0.0"` and
`workspace-managed` ownership intent. It remains proposed at draft maturity,
outside adopted specification and conformance artifacts. Existing Runtime
consumers strictly decode prototype reports; even an additive default field
would break their discovery and authoring flows.

## Decision drivers

- Preserve prototype 0.0.2 source bytes, provenance, reports and default discovery.
- Share exact-byte, anchor, material and typed Pack checks across both formats.
- Follow the candidate's finite result codes and ordered refusal phases.
- Keep current authority, source acquisition, signatures and evaluation outside Runtime.

## Considered options

- Replace the prototype grammar or silently migrate candidate bytes to it.
- Duplicate the Policy checking engine for the candidate.
- Add explicit dispatch and optional discovery around the shared offline engine.

## Decision outcome

Chosen option: explicit format dispatch around the shared engine. Candidate
artifacts are separately vendored from immutable Spec commit
`0852c5fa7726e51b36e574a5b110e7f5e012e03d`, with a complete per-file provenance
manifest and independent manifest digest test. Prototype files and ADR-0059
remain unchanged. This record adopts no normative Policy format.

The no-argument CLI/MCP contract remains exactly the prototype contract.
`contract --all-formats` and MCP `{allFormats:true}` explicitly request a separate
`registryVersion: "1"` report. An optional exact format selector requests a
single contract; the two discovery selectors are mutually exclusive. Init/schema
continue requiring explicit kind and format. Supplied documents dispatch by
their selector; an optional operation selector permits candidate classification
of malformed or missing document selectors without changing legacy refusals.
No document is silently migrated or tried against an older grammar.

Candidate reports identify their own provenance and `proposed-draft` maturity,
carry the exact candidate capability artifact, and add `formatVersion`.
Candidate full checks alone add `candidateResult`: exactly the portable valid or
refusal object. Canonicalize/digest check encoding and identity; validate checks
document forms and local references. Neither narrower operation claims a full
retained-material check. Runtime retains invalid exit 1 and unsupported exit 2;
the nested candidate result supplies the portable code. Environment failures
produce no candidate result.

Full checks measure/parse/select/canonicalize the root before registration count
and ordered material registration, then check its kind/schema and semantics.
Retained Policy references require the adopting candidate's exact format.
Resolution checks original raw bytes before parsing or optional canonical
identity, and Core structural validation receives the original Pack bytes.
Source and narrative bytes, registrations under distinct media types, consuming
role bounds and typed Pack references remain shared checks.

Candidate URI assertions use the RFC 3986 `URI` production: a scheme is required
and a fragment is permitted. Component grammar distinguishes authority, IP
literals, user information, paths, queries and fragments; percent-encoded host
characters and IPvFuture literals are valid without network interpretation.
Generic ports remain digit strings without a network port-range restriction.
Only candidate schemas/init and candidate-consuming Pack structural checks opt
into this assertion. The structural engine validates the same raw Pack bytes and
bundled schema with a per-call URI format override; default Core and prototype
URI behavior and their cached schemas remain unchanged.

The private Runtime base64 material transport remains separate from portable raw
vector inputs. Its 24 MiB material JSON ceiling and MCP's 16 MiB request-line
ceiling remain unchanged. Repeated registrations of identical large bytes can
fit the candidate's distinct-byte budget while exceeding an encoded transport
ceiling. The portable harness therefore uses the same shared post-parse checks
and raw registration function, acquires sources lazily in declaration order and
stops on the first failure. Passing all 124 vectors promises no larger wire
envelope, authority, conformance or independent implementation agreement.

### Consequences

- Existing strict prototype clients retain their default contract and reports.
- Candidate users opt into a proposed contract with explicit provenance and refusal scope.
- Shared checks must preserve format-specific phase ordering as well as byte identity.
- Revisit when RFC review adopts or replaces this candidate and the owning host contracts settle publication and current admission.

## Material decision and review

Material-decision impact categories: `public-surface`, `documented-claim`,
`security`, `dependency`. The candidate selector, explicit discovery and typed
results extend a public surface; vendored candidate artifacts add a dependency
boundary; ordered bounded input handling concerns the security posture.

The maintainer authorized a temporary different-vendor review waiver for this
current Policy work. The recorded clean-room review of Runtime commit
`558df435bbc50fc872b14aceecae1d482b45898d`, performed by OpenAI/Codex
`gpt-6.1-sol` at `xhigh`, found two P2 issues and no P1 issue. The maintainer
accepted both findings: candidate URI assertions and private-carrier registration
phase ordering. The [review and dispositions on PR 296](https://github.com/Judgment-Pack/judgment-pack-runtime/pull/296#issuecomment-6254960095)
identify that reviewed commit and the bounded review's actual evidence.

Commits `6dd003e29cccf7808227b98157e55cebce4b231b` and
`2e158c5105046594749139c955839a041331a106` implement those accepted findings,
including candidate-consuming Pack URI checks over unchanged bytes and schema.
The coordinator reports that the reviewer closed both findings at `2e158c5`.
Commit `38b06043283d2ae294653ca8f25c8c5db415dd9e` additionally preserves the
vendored candidate's exact bytes under Windows checkout conversion, addressing
the third P2 finding. The [final Runtime correction review](https://github.com/Judgment-Pack/judgment-pack-runtime/pull/296#issuecomment-6254971185)
closes all three findings through that commit. Focused
verification covers the 124 portable vectors, 62 standalone and 62 consuming
Pack URI probes, ordered private-wire refusals, schema/init parity and unchanged
Core/prototype URI behavior. Checkout verification with `core.autocrlf=true`
checks every vendored source digest/length and the independent provenance pin.

The URI source correction is pinned to the exact candidate commit above and is
recorded in [Spec PR 217's clean-room review](https://github.com/Judgment-Pack/judgment-pack-spec/pull/217#issuecomment-6254970472).
That exact `0852c5f` source passed review without P1/P2 findings, 13 focused
tests, 124 portable vectors and 99 additional URI probes, and merged as
`a74a440cfc31d0e135cdc8035f3474b17f27f320` after repository CI passed. Runtime
retains the immutable reviewed source pin; its merge also requires repository CI. This
accepted status records the maintainer-authorized merge-ready procedural
transition; it does not adopt a normative Policy format or change the RFC's
Review status. All implementation, review and agreement evidence described here
is same-vendor work under the temporary waiver, never different-vendor review
or independently authored interoperability evidence. The waiver changes no
standing repository requirement.

## More information

- [Prototype decision](0059-experimental-offline-policy-tools.md)
- [Offline Policy architecture](../architecture.md#experimental-offline-policy-prototype)
- [Candidate source and provenance](../../internal/policy/candidate/provenance.json)
1 change: 1 addition & 0 deletions docs/adr/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -155,3 +155,4 @@ authority, and following it confers no conformance status on anything.
| [0056](0056-version-3-dialect-authoring.md) | Check supported version-3 Dialect declarations through shared authoring tools | accepted |
| [0057](0057-named-dialect-artifact-identity.md) | Share offline tools for named Dialect artifacts | accepted |
| [0059](0059-experimental-offline-policy-tools.md) | Prototype Policy document and retained-reference checks offline | accepted |
| [0060](0060-explicit-policy-candidate-format.md) | Add an explicit Policy contract candidate without changing prototype clients | accepted |
20 changes: 20 additions & 0 deletions docs/architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,26 @@ number domain. Source/schema/example provenance pins specification revision
resource is fetched at runtime. The shared 16 MiB stdio line bound is unchanged,
so JSON/base64 overhead reduces the maximum retained material a call can carry.

The proposed-draft, unadopted Policy contract candidate `1.0.0` is an additional
explicit format ([ADR-0060](adr/0060-explicit-policy-candidate-format.md)). Its
schemas, prose, examples and 124 portable vectors are pinned separately to Spec
commit `0852c5fa7726e51b36e574a5b110e7f5e012e03d`. Format selection, schema and
provenance differ; material identity, UTF-8 anchors and typed Pack coverage use
the same engine. Candidate adoption cannot consume prototype Policy bytes.
No-argument contract discovery and prototype reports retain their exact prior
shape for strict clients. All-format discovery requires explicit CLI
`--all-formats` or MCP `allFormats:true` and returns registry version 1.

Candidate full checks return a bounded `candidateResult` with exactly the
portable status/code object, separate from Runtime diagnostics and exit status.
Root physical bounds, strict JSON, selection and canonical numeric domain precede
ordered registration; root schema and semantic checks follow registration.
Portable tests defer source acquisition to its phase and use shared raw
registration directly. Duplicate media registrations count bytes once but may
repeat base64 on the wire, so candidate agreement never widens the private
24 MiB material JSON or 16 MiB MCP ceiling. No candidate result establishes
current authority, permission, publication, review trust or independent agreement.

## Artifact version arithmetic

`internal/artifactversion` owns exact three-component parsing, comparison and
Expand Down
39 changes: 39 additions & 0 deletions docs/mcp-clients.md
Original file line number Diff line number Diff line change
Expand Up @@ -499,3 +499,42 @@ limit: base64 expands retained bytes and JSON string escaping, document text and
RPC framing consume more space. Consequently, not every bundle under the 16 MiB
retained-byte limit fits a single MCP request. A client must bound the complete
encoded request; CLI named-file input supports the larger material JSON envelope.

### Explicit proposed-draft candidate selection

The seven existing tools also serve the unadopted Policy contract candidate
`1.0.0`, at `proposed-draft` maturity, pinned to Spec commit
`0852c5fa7726e51b36e574a5b110e7f5e012e03d`
([ADR-0060](adr/0060-explicit-policy-candidate-format.md)). Calling contract
without arguments or with `{}` returns the exact existing prototype report.
`{allFormats:true}` explicitly requests the separate registry version 1;
`{formatVersion:"1.0.0"}` selects the candidate contract. These two arguments
are mutually exclusive. `{formatVersion:"0.0.2"}` selects the prototype contract.

Init/schema require the exact selected `formatVersion` as before. Document tools
accept an optional `formatVersion` string for explicit dispatch, including
candidate classification of malformed or selector-less bytes. The document
still must carry its own exact selector; no tool inserts or rewrites it.
Without an operation selector, a document carrying `formatVersion` dispatches
to the candidate; existing prototype documents retain their behavior. Candidate
Policies use `workspace-managed` or `externally-managed`, never an alias of the
prototype's `desk-managed`. Candidate adoption requires candidate Policy bytes.

Candidate reports include their own `formatVersion`, source provenance, maturity
and exact `candidateCapabilities` artifact. Only full candidate checks add
`candidateResult`, exactly the portable valid object
`{status:"valid",formatVersion:"1.0.0",maturity:"proposed-draft"}` or refusal
`{status:"refused",code:"…"}`. Their bounded finite codes follow the
[pinned candidate contract](../internal/policy/candidate/README.md#5-resource-limits-and-refusal-classifications).
Encoding/local validation omit that field; operational failures supply no
candidate result. MCP sets `isError:true` on refusals. Neither result format
asserts current authority, permission, trusted review or standard conformance.

Candidate physical bounds and strict JSON parsing precede selector/canonical
checks, then ordered registration precedes document schema and reference checks.
Retained artifact byte pins are checked before parsing and optional canonical
identity. Pack bytes go unchanged to Core structural validation. The private
material carrier and the 16 MiB stdio request ceiling remain unchanged; duplicate
base64 registrations can exceed a transport ceiling even when their distinct
retained bytes fit the candidate. Passing portable raw-input vectors therefore
promises no larger encoded envelope or independent interoperability evidence.
Loading
Loading