From 685cd692a47020ea795d85c22f335ec577d1f431 Mon Sep 17 00:00:00 2001 From: tommy-ca <140900186+tommy-ca@users.noreply.github.com> Date: Tue, 20 Oct 2026 21:11:34 +0200 Subject: [PATCH 01/10] docs: source-pin harness adapter and Jev decision contract to 0.15.29 --- .../harness-adapters-and-jev-2026-10-20.md | 153 ++++++++++++++++++ 1 file changed, 153 insertions(+) create mode 100644 docs/architecture/harness-adapters-and-jev-2026-10-20.md diff --git a/docs/architecture/harness-adapters-and-jev-2026-10-20.md b/docs/architecture/harness-adapters-and-jev-2026-10-20.md new file mode 100644 index 00000000..0ec180a8 --- /dev/null +++ b/docs/architecture/harness-adapters-and-jev-2026-10-20.md @@ -0,0 +1,153 @@ +# Harness adapter and JEV decision contracts — implementation map + +> **Status:** implementation-derived documentation (2026-10-20; audited at `tommy-ca/pstack@dea54d5cd723e06aa6a3afb78f9c3a79e82abb32`). A source-level audit is **not** a fresh native-host conformance run or an authenticated Jev call. Follow-up graph: [#657](https://github.com/tommy-ca/pstack/issues/657), egress [#658](https://github.com/tommy-ca/pstack/issues/658), evidence [#659](https://github.com/tommy-ca/pstack/issues/659), response/budget [#660](https://github.com/tommy-ca/pstack/issues/660), docs [#661](https://github.com/tommy-ca/pstack/issues/661). + +## Authority and architecture + +- **Canonical behavior:** [cursor/plugins/pstack](https://github.com/cursor/plugins/tree/main/pstack), as pinned in `UPSTREAM` and `pstack.package.json#upstream_pin` (`88d47514b82e7c44f00f2b2a72ff6dd12158038c`, upstream plugin 0.15.29). +- **Portability implementation:** this repository. `skills/` owns shared semantic intent; `profiles/`, `scripts/drivers/`, host tool references, projected native manifests and receipts own host-specific mechanics. +- **Role identity:** `pstack.package.json#/roles` is the unique shipped role ID/tier registry. `examples/portability/model-role-policy.example.json` demonstrates typed host choices, **not** an independent role registry or a live availability claim. +- **Execution/control:** host runtime owns spawn/join/cancel, workspaces, session persistence and durable orchestration. Do not introduce a pstack scheduler, generic agent gateway, workflow DSL, role database or second model registry. +- **Domain overlays:** domain rules (for example QStack) apply after the shared routing boundary. They cannot authorize a blocked harness/JEV action or override human gates. + +```text + canonical skills / principles / playbooks / poteto-mode + | + pstack.package.json#/roles + | + host profile + capability bindings + model-role policy + | | + route resolver pure model planner + | | + native adapter / projected package & host driver + | + host-owned execution + settlement + | + scenario evidence + version-bound receipt + + optional Jev side path (NOT a host executor) + deterministic route -> explicit bypass + egress eligibility + -> closed-set Choice -> Jev provider observation + -> class-specific admission / durable evidence / no-change fallback +``` + +### Atomic ownership boundaries + +| Block | Canonical implementation | Contract | +| --- | --- | --- | +| Semantic skills, principle policies, playbooks | `skills/`; `skills/poteto-mode/` | Reuse upstream intent; never embed another host's tool ID in shared semantics | +| Package & role registry | `pstack.package.json` | `roles[]`, `host_targets[]`, `host_adapters`; static metadata only | +| Host identity | `scripts/host_identity.py`; `host-id.schema.json` | Six built-in IDs; namespaced declarations are candidate by default | +| Capability/profile schema & models | `schemas/portability/`; `scripts/portability_types.py` | Descriptive claims validated independently from observed live proof | +| Host role resolution | `scripts/model_role_policy.py`, `scripts/model_role_resolver.py` | Pure planning; model catalog != observed dispatch; no JEV model-choice authority | +| Native projection | `scripts/project-package.py` | Generate host manifests/roles from descriptor; avoid hand-maintained duplicates | +| Native execution and conformance | `scripts/drivers/*.py`, `scripts/verify-portable.py` | Live host-specific scenarios and honest BLOCKED/UNTESTED outcomes | +| Evidence and staleness | `scripts/evidence_*.py`, `scripts/surface_revisions.py`, `.audit/evidence/` | Receipt is bounded to identified source surfaces; no inference from prose | +| Optional semantic decision | `scripts/decision_adapter.py`, `scripts/route_resolver.py` | Default-OFF, opt-in bounded classifier only; baseline always precomputed | + +## Schema registry (current checked-in shapes) + +All schemas are under `schemas/portability/`, Draft 2020-12. JSON-schema validation is supplemented by cross-document Python checks; standalone JSON Schema does not prove role/catalog/host/receipt consistency. + +| Schema | Important data shape / invariant | +| --- | --- | +| `host-id.schema.json` | Built-ins `grok`, `codex`, `omp`, `opencode`, `antigravity`, `droid`; compatibility aliases `claude`, `custom`; external ID `namespace:name`. Host identity alone grants no capability | +| `capability.schema.json` | Semantic capability ID and nonempty `required_postconditions` | +| `binding.schema.json` | `host`, `capability`, `implementation_status` (`native|shim|version-gated|gap`), `enforcement` (`hard|soft|advisory`), `verification_status` (`verified|static-only|unverified|stale`), optional `primitive` and scenario-pinned `evidence_ref` | +| `profile.schema.json` | `host`, `support_state`, `bindings`, `skills_dir`, `plugin_manifest`; optional `plugins_dir`, `tool_mappings`, `skill_order`, `runtime_conventions`, `evidence_ledger` | +| `tool-mapping.schema.json` | Host-native names for reading/writing, shell, agent spawn/join, plan update and user question, with optional fanout/message/background/search | +| `runtime-conventions.schema.json` | Per-host execution/isolation/model spawn conventions; do not interpret as cross-host guarantees | +| `skill-order.schema.json` | Ordered pstack/user/builtin skill resolution rows and fallbacks | +| `package-descriptor.schema.json` | Static descriptor, role/tier and host targets, never durable task or scheduler state | +| `model-role-policy.schema.json` | `version`, `role_source='pstack.package.json#/roles'`, `hosts`, optional role constraints; host catalog, per-tier/role choices, fallback, effort and selection topology | +| `model-plan.schema.json` | Selected seat(s), role, host, selection, reason and `PLANNED|DEGRADED|BLOCKED` result; **not** execution proof | +| `evidence.schema.json` | Proof/observation claim with declared source and level | +| `receipt.schema.json` | Run, host/version, canonical/adapter/package/runtime planes, source revisions and scenario-level `static|offline|observed_live|legacy` evidence; **current** receipt contract explicitly does not bind all model-catalog hashes | + +### Host support snapshot (source at audited commit) + +| Profile ID | Built-in shipped target? | Declared support state | Binding-level live claim | +| --- | --- | --- | --- | +| `grok` | Yes | `packaged` | No `verified` binding | +| `codex` | Yes | `packaged` | No `verified` binding | +| `omp` | Yes | `packaged` | `agent.spawn`, `agent.join`, `agent.cancel`, `workspace.isolated` individually pinned to an OMP live receipt | +| `opencode` | Yes | `packaged` | No `verified` binding | +| `antigravity` | Yes | `packaged` | No `verified` binding | +| `droid` | Yes | `candidate` | No bindings / no live claim | +| `claude` | No — compatibility identity/candidate profile | `candidate` | No `verified` binding | +| `github:copilot` | No — namespaced candidate profile | `candidate` | No `verified` binding | + +Eight profile files and eight Python driver modules do **not** imply eight fully instantiated native host packages. `verify-portable.py --host` currently enumerates the six built-ins; candidate profiles can be inspected/validated without being runnable through that entrypoint. Historical five-host `PASS` claims from earlier docs do not override current receipt state. OMP's four `verified` bindings are limited to specific observed scenarios; they do not imply complete harness support, multi-model independence, arbitrary nested spawning or durable scheduling. + +### Role/model resolution + +1. Resolve canonical role ID and tier from `pstack.package.json#/roles`. +2. Resolve model precedence: **explicit invocation > project override > user override > host-role override > host tier default > inherit-parent/fail-closed**. +3. Validate configured model IDs, requested effort, required capability enforcement and selection topology against typed host policy. Check model catalog discovery freshness; an unproven catalog yields a `DEGRADED` plan. +4. For a panel, make distinct **seats**; separate model-family diversity is an independently checked requirement. Cross-judge cannot label same-family evaluation as independent. +5. Translate the plan to native spawn arguments only in the respective host adapter; collect runtime settlement, model identity, workspace proof and a receipt. `PLANNED` never means `VERIFIED`. + +Refer to [ADR-0021](../../adr/0021-harness-neutral-model-role-policy.md), [design](../../openspec/changes/2026-10-15-harness-neutral-role-policy/design.md), and [porting guide](../guide/12-porting.md). + +## JEV / System One: exact present behavior vs accepted contract + +JEV is a *decision model*, not a generative coding worker, model-role catalog, reviewer family or execution harness. Current neutral data classes are `SafeContext`, `ChoiceOption`, `ChoiceRequest`, `ScoreRequest`, `BooleanRequest`, `DecisionOutcome`, `ProviderObservation` and `SemanticDecisionProvider.decide` in `scripts/decision_adapter.py`. The wire implementation is **Choice-only**; score and boolean return abstention at phase one. + +**Feature controls:** `PSTACK_JEV_ENABLED` defaults OFF; `PSTACK_JEV_MODE` is `none|shadow|advisory` and defaults to shadow only when a provider is supplied to the wrapper; `PSTACK_JEV_PROFILE` selects an allowlisted endpoint profile. `PSTACK_JEV_ALLOW_PAID` is a paid-consent switch, **not** a measured or enforced spend budget. + +**Transport implementation at audit SHA:** `JevDecisionAdapter` builds `{model,state,questions:[{id,type:'choice',options}]}` and uses `urllib.request` (or injected test transport) to POST to the configured `.../v1/systemone` endpoint. It does **not** currently import or instantiate `typesafe-sdk`, despite the preferred SDK wording in [provider options](../../references/jev-provider-options.md) and historical issue #515. Supported configuration rows in code are `opencode-zen`, `opencode-console`, `openrouter`, `typesafe-direct`; configuration and tests do not prove entitlement, live authenticated exchange, price or model quality. + +**Existing path** (`scripts/route_resolver.py:resolve_skill_order_with_shadow`): compute deterministic route; load `references/decision-routing.json`; build a closed-set `ChoiceRequest`; collect provider observation; in `shadow` return the baseline; in `advisory` check candidate ID, per-class threshold, optional probability margin and a freshly computed receipt's staleness, otherwise fall back. The provider response status is `decided|abstain|unavailable|invalid`. + +**Open gaps — do not confuse present code with the intended security contract:** + +- **[#658, P0] Egress/bypass ordering:** the wrapper currently asserts `SAFE_TO_SEND` for the **raw user query** and calls the provider before excluding slash/direct/system-two routes. The living spec prohibits assuming raw task prompts are public; regex-based secret blocking is not a positive privacy classification. +- **[#659, P1] Admission freshness:** an in-memory decision receipt made from the same observation and immediately compared against itself is **not** preexisting persisted calibration/eval proof and must not grant controlling authority. +- **[#660, P1] Response/paid controls:** confidence and probabilities need finite bounded validation; missing actual provider/model response fields and response question ID are not adequately proven; `max_spend_usd` metadata is not an enforced budget. Closed historical JEV provider tasks do not settle these new negative cases. +- **[#517] Scope:** model/fast-worker/leaf-skill selection remains research. No JEV model routing or autonomous execution authority is accepted. + +**Required safe data flow (target, not a claim about current execution):** + +```text +query + -> deterministic baseline / policy gate + -> if explicit, direct, system-two or risky: return baseline; ZERO provider call + -> approved public summary or fixture? if no: return baseline + -> strict bounded closed-set Choice + -> default-OFF / optional shadow observation + -> validate finite probabilities, exact question ID and true provider/model evidence + -> preexisting durable calibration/eval/freshness and explicit promotion policy? + NO: baseline + YES: only preapproved low-risk advisory playbook hint + -> native host routing/verification/human gates remain authoritative +``` + +No private code, file contents, diffs, transcripts, secrets, repository or quant risk state may be inferred safe from a short length or absence of regex matches. Explicit consent to billing is distinct from consent to transfer task data. Follow [living JEV spec](../../openspec/specs/pstack-jev-decisions/spec.md). + +## Thermo-Nuclear review / SOLID-KISS-DRY-YAGNI dispositions + +| Concern | Disposition | +| --- | --- | +| Side effects before route/egress gates | Fix narrowly in the JEV decision boundary, not inside every harness driver; prove `provider.decide` was never invoked on bypass | +| Synthetic evidence used as authorization | Separate observation from prior accepted promotion evidence; forbid self-approving receipts | +| Repeated model/host defaults | Keep role IDs in descriptor, host identity in shared registry and model tier policy in one validator; no copied per-host role registries | +| Structural expansion | Avoid adding TypeScript/PydanticAI runtime, separate per-provider clients, general schedulers and new workflow engine without measured value | +| Large or branching code | Prefer pure preflight decision, bounded provider call and pure admission predicate instead of extra booleans in `route_resolver.py` | +| Compatibility | Keep OFF/shadow byte-for-byte route equivalent, keep legacy aliases candidate, and do not change generated manifests just to update docs | + +The upstream [Thermo Nuclear Review](https://github.com/cursor/plugins/tree/main/thermos/skills/thermo-nuclear-review) limits diff findings to actual modified code. [Thermo Nuclear Code Quality Review](https://github.com/cursor/plugins/tree/main/thermos/skills/thermo-nuclear-code-quality-review) looks for structural simplification and non-atomic updates. The observations above are a **baseline audit**, not a claim of a completed multi-model / native-host Thermos run. + +## Reproducibility and next evidence + +Run on the **candidate PR SHA** with dependencies installed; do not copy a PASS from the audited base SHA: + +```sh +python3 scripts/project-package.py --check +python3 scripts/verify-portable.py doctor --host all +python3 scripts/verify-decision-contract.py --help +python3 -m pytest -q tests/test_decision_adapter.py tests/test_jev_transport_and_profiles.py tests/test_advisory_promotion.py tests/test_model_role_policy.py tests/test_portability_schemas.py +# explicitly opt-in live driver only with native CLI/configured credentials, +# isolated harmless fixture, declared scope and a durable observed_live receipt. +``` + +Recursive work: documentation [#661](https://github.com/tommy-ca/pstack/issues/661) can land alone; safety [#658](https://github.com/tommy-ca/pstack/issues/658) blocks any live JEV use; evidence [#659](https://github.com/tommy-ca/pstack/issues/659) and transport [#660](https://github.com/tommy-ca/pstack/issues/660) must independently pass negative fixtures before any advisory-promotion gate. [#517](https://github.com/tommy-ca/pstack/issues/517) remains research-only. Exact-head **Swarm** partitions tests/review by adapter versus JEV, **Arena** compares baseline-only/shadow/advisory with predeclared rubric, **Interrogate** checks privacy, false PASS, model-family independence and rollback. Mark these BLOCKED when only source inspection or one reviewer is available. From 9d2515910d4bf131567e8f72dc5a2a3870da3c47 Mon Sep 17 00:00:00 2001 From: tommy-ca <140900186+tommy-ca@users.noreply.github.com> Date: Tue, 20 Oct 2026 21:12:02 +0200 Subject: [PATCH 02/10] docs: link current adapter contract and label historical 5-host evidence --- docs/guide/12-porting.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/guide/12-porting.md b/docs/guide/12-porting.md index c4fb1ea2..9caeaa7e 100644 --- a/docs/guide/12-porting.md +++ b/docs/guide/12-porting.md @@ -4,6 +4,8 @@ Official pstack at the immutable pin in [`UPSTREAM`](../../UPSTREAM) is canonica The host map is the primary adapter document, defined under the cross-harness contract [`pstack-portability`](../../openspec/specs/pstack-portability/spec.md). +**Current implementation snapshot (2026-10-20):** [Harness adapter schemas, model-role resolution, JEV decision boundary and issue-level safety gaps](../architecture/harness-adapters-and-jev-2026-10-20.md). This source-pinned map complements the historical porting evidence below; only scenario-pinned native receipts establish a live capability. + ## Keep the pstack meaning Preserve the canonical principles, skills, router behavior, playbook intent, role boundaries, ordering, and verification rules. Focus on less code, not loc. Port host-dependent mechanisms only. @@ -163,7 +165,7 @@ Evidence gathered during the Codex pilot reconciled core contract expectations: A port that copies another port's host calls is not portable pstack. A thin adapter with strong evidence is. -## Batch 2 acceptance matrix (5 harnesses) +## Historical Batch 2 acceptance matrix (5 harnesses; not current proof) Batch 2 expanded the host matrix to 5 harnesses across 3 verification planes (Canonical, Adapter, Runtime): 1. **Grok Build** (`grok`): Reference host. Subagent tree with depth 2 and shared workspace. From 3e744d732d2ac0bcc4674af48dff7a5b53bcf0bc Mon Sep 17 00:00:00 2001 From: tommy-ca <140900186+tommy-ca@users.noreply.github.com> Date: Tue, 20 Oct 2026 21:12:05 +0200 Subject: [PATCH 03/10] docs: surface current harness/JEV implementation map in README --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index d1b72298..be196eb2 100644 --- a/README.md +++ b/README.md @@ -63,6 +63,8 @@ Two steps. New here? The [pstack guide](./docs/guide/README.md) walks through a first real task, from setup and prompting through verification and overnight runs. +For the **current harness adapter schemas, native support/evidence status, model-role planning, and optional JEV decision integration**, see the [2026-10-20 implementation map](./docs/architecture/harness-adapters-and-jev-2026-10-20.md). It distinguishes source/fixture validation from actual observed host execution and tracks remaining privacy/promotion gates. + The other skills are situational. The mode skill uses them when a step needs them. ## Defaults From 8351e1582d84ec740606b4d8f21d432cb3ca2316 Mon Sep 17 00:00:00 2001 From: tommy-ca <140900186+tommy-ca@users.noreply.github.com> Date: Tue, 20 Oct 2026 21:15:24 +0200 Subject: [PATCH 04/10] docs: record proven 18-playbook JEV registry drift from canonical 0.15.29 --- docs/architecture/harness-adapters-and-jev-2026-10-20.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/architecture/harness-adapters-and-jev-2026-10-20.md b/docs/architecture/harness-adapters-and-jev-2026-10-20.md index 0ec180a8..148a7311 100644 --- a/docs/architecture/harness-adapters-and-jev-2026-10-20.md +++ b/docs/architecture/harness-adapters-and-jev-2026-10-20.md @@ -104,6 +104,7 @@ JEV is a *decision model*, not a generative coding worker, model-role catalog, r - **[#658, P0] Egress/bypass ordering:** the wrapper currently asserts `SAFE_TO_SEND` for the **raw user query** and calls the provider before excluding slash/direct/system-two routes. The living spec prohibits assuming raw task prompts are public; regex-based secret blocking is not a positive privacy classification. - **[#659, P1] Admission freshness:** an in-memory decision receipt made from the same observation and immediately compared against itself is **not** preexisting persisted calibration/eval proof and must not grant controlling authority. - **[#660, P1] Response/paid controls:** confidence and probabilities need finite bounded validation; missing actual provider/model response fields and response question ID are not adequately proven; `max_spend_usd` metadata is not an enforced budget. Closed historical JEV provider tasks do not settle these new negative cases. +- **[#663, P1] Canonical mapping revision drift:** the applied 0.15.29 pin is `88d47514...`, but `references/decision-routing.json#source.revision` remains `d0ef80d8...`. Comparing the pinned upstream Git tree with the mapping finds the same 23 playbook IDs but **18 different canonical playbook blob SHAs** and a different poteto-mode router blob (`21993f54...` vs stored `de51c561...`). The runtime reads semantic eligibility from this map without first validating it against the applied pin. Same inventory count is not version or policy equivalence. Until #663 reconciles classifications and gates freshness, advisory mapping authority is unproven. - **[#517] Scope:** model/fast-worker/leaf-skill selection remains research. No JEV model routing or autonomous execution authority is accepted. **Required safe data flow (target, not a claim about current execution):** @@ -150,4 +151,4 @@ python3 -m pytest -q tests/test_decision_adapter.py tests/test_jev_transport_and # isolated harmless fixture, declared scope and a durable observed_live receipt. ``` -Recursive work: documentation [#661](https://github.com/tommy-ca/pstack/issues/661) can land alone; safety [#658](https://github.com/tommy-ca/pstack/issues/658) blocks any live JEV use; evidence [#659](https://github.com/tommy-ca/pstack/issues/659) and transport [#660](https://github.com/tommy-ca/pstack/issues/660) must independently pass negative fixtures before any advisory-promotion gate. [#517](https://github.com/tommy-ca/pstack/issues/517) remains research-only. Exact-head **Swarm** partitions tests/review by adapter versus JEV, **Arena** compares baseline-only/shadow/advisory with predeclared rubric, **Interrogate** checks privacy, false PASS, model-family independence and rollback. Mark these BLOCKED when only source inspection or one reviewer is available. +Recursive work: documentation [#661](https://github.com/tommy-ca/pstack/issues/661) can land alone; safety [#658](https://github.com/tommy-ca/pstack/issues/658) blocks any live JEV use; mapping freshness [#663](https://github.com/tommy-ca/pstack/issues/663), evidence [#659](https://github.com/tommy-ca/pstack/issues/659) and transport [#660](https://github.com/tommy-ca/pstack/issues/660) must independently pass negative fixtures before any advisory-promotion gate. [#517](https://github.com/tommy-ca/pstack/issues/517) remains research-only. Exact-head **Swarm** partitions tests/review by adapter versus JEV, **Arena** compares baseline-only/shadow/advisory with predeclared rubric, **Interrogate** checks privacy, false PASS, model-family independence and rollback. Mark these BLOCKED when only source inspection or one reviewer is available. From 2a6387cdf051ef4c465f20179dafe333c01f44cf Mon Sep 17 00:00:00 2001 From: tommy-ca <140900186+tommy-ca@users.noreply.github.com> Date: Tue, 20 Oct 2026 21:21:25 +0200 Subject: [PATCH 05/10] test(docs): check adapter schema, host status and JEV navigation contracts --- tests/test_architecture_documentation.py | 88 ++++++++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 tests/test_architecture_documentation.py diff --git a/tests/test_architecture_documentation.py b/tests/test_architecture_documentation.py new file mode 100644 index 00000000..03bcbeda --- /dev/null +++ b/tests/test_architecture_documentation.py @@ -0,0 +1,88 @@ +"""Pin the architecture guide to the current schema/profile/transport contract. + +These tests are intentionally small and source-derived. They check that a reader +can find the current guide and that its factual, enumerable claims agree with +the files checked out on this exact PR head. They do NOT certify native execution, +JEV privacy, live API support, or the correctness of advisory admission. +""" + +from __future__ import annotations + +import json +import re +from pathlib import Path + +ROOT = Path(__file__).resolve().parents[1] +ARCH = ROOT / "docs" / "architecture" / "harness-adapters-and-jev-2026-10-20.md" + + +def _doc() -> str: + return ARCH.read_text(encoding="utf-8") + + +def test_architecture_is_linked_from_readme_and_porting_guide() -> None: + root_readme = (ROOT / "README.md").read_text(encoding="utf-8") + porting = (ROOT / "docs" / "guide" / "12-porting.md").read_text(encoding="utf-8") + assert "./docs/architecture/harness-adapters-and-jev-2026-10-20.md" in root_readme + assert "../architecture/harness-adapters-and-jev-2026-10-20.md" in porting + assert "Historical Batch 2 acceptance matrix" in porting + + +def test_current_schema_inventory_matches_documented_schema_names() -> None: + discovered = {p.name for p in (ROOT / "schemas" / "portability").glob("*.schema.json")} + documented = set(re.findall(r"`([a-z-]+\.schema\.json)`", _doc())) + assert discovered == documented, ( + f"documented schema inventory drift: missing={discovered - documented}, " + f"not shipped={documented - discovered}" + ) + + +def test_host_support_table_reflects_actual_profiles() -> None: + table = dict(re.findall( + r"^\|\s*`([a-z][a-z0-9:-]*)`\s*\|[^\n]*?\|\s*" + r"`(candidate|mapped|packaged|verified|supported)`\s*\|", + _doc(), + re.MULTILINE, + )) + profiles = { + json.loads(path.read_text(encoding="utf-8"))["host"]: + json.loads(path.read_text(encoding="utf-8"))["support_state"] + for path in (ROOT / "profiles").glob("*.json") + } + assert table == profiles, f"documented host states must match live profile declarations: {table=} {profiles=}" + package = json.loads((ROOT / "pstack.package.json").read_text(encoding="utf-8")) + assert set(package["host_targets"]) <= set(table), "shipped targets missing from host table" + + +def test_upstream_source_of_truth_matches_package_pin() -> None: + desc = json.loads((ROOT / "pstack.package.json").read_text(encoding="utf-8")) + canonical = (ROOT / "UPSTREAM").read_text(encoding="utf-8") + assert f"tree {desc['upstream_pin']}" in canonical + assert desc["upstream_pin"] in _doc() + assert desc["version"] in _doc() + + +def test_documented_relative_links_resolve_within_repository() -> None: + text = _doc() + for match in re.findall(r"\]\(([^)]+)\)", text): + if match.startswith(("http://", "https://", "mailto:", "#")): + continue + relative = match.split("#", 1)[0] + if not relative: + continue + target = (ARCH.parent / relative).resolve() + assert target.is_relative_to(ROOT.resolve()), f"documentation path escapes repository: {match}" + assert target.exists(), f"architecture documentation references missing path: {match}" + + +def test_jev_implementation_caveats_remain_explicit() -> None: + decision_source = (ROOT / "scripts" / "decision_adapter.py").read_text(encoding="utf-8") + doc = _doc() + assert "import urllib.request" in decision_source + assert "urllib" in doc + assert "default" in doc.lower() and "OFF" in doc + assert "Choice-only" in doc + # Every current high-risk JEV caveat must have an owner, rather than appearing + # to be solved by this documentation change or by a historical closed issue. + for issue in ("#658", "#659", "#660", "#663"): + assert issue in doc From 084315b98eca377c61a54e5c20261be4601f3e2c Mon Sep 17 00:00:00 2001 From: tommy-ca <140900186+tommy-ca@users.noreply.github.com> Date: Tue, 20 Oct 2026 21:21:45 +0200 Subject: [PATCH 06/10] docs: expose projected package version as distinct from canonical pin --- docs/architecture/harness-adapters-and-jev-2026-10-20.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/architecture/harness-adapters-and-jev-2026-10-20.md b/docs/architecture/harness-adapters-and-jev-2026-10-20.md index 148a7311..a8ad4c9c 100644 --- a/docs/architecture/harness-adapters-and-jev-2026-10-20.md +++ b/docs/architecture/harness-adapters-and-jev-2026-10-20.md @@ -5,6 +5,7 @@ ## Authority and architecture - **Canonical behavior:** [cursor/plugins/pstack](https://github.com/cursor/plugins/tree/main/pstack), as pinned in `UPSTREAM` and `pstack.package.json#upstream_pin` (`88d47514b82e7c44f00f2b2a72ff6dd12158038c`, upstream plugin 0.15.29). +- **Port release:** `pstack.package.json#version = 0.15.29-grokbuild.0`; that suffix denotes a portability release, not a newer upstream canonical contract. - **Portability implementation:** this repository. `skills/` owns shared semantic intent; `profiles/`, `scripts/drivers/`, host tool references, projected native manifests and receipts own host-specific mechanics. - **Role identity:** `pstack.package.json#/roles` is the unique shipped role ID/tier registry. `examples/portability/model-role-policy.example.json` demonstrates typed host choices, **not** an independent role registry or a live availability claim. - **Execution/control:** host runtime owns spawn/join/cancel, workspaces, session persistence and durable orchestration. Do not introduce a pstack scheduler, generic agent gateway, workflow DSL, role database or second model registry. From c2a319426b8f21cd55ec0b8621d943592bfe5d24 Mon Sep 17 00:00:00 2001 From: tommy-ca <140900186+tommy-ca@users.noreply.github.com> Date: Tue, 20 Oct 2026 21:22:14 +0200 Subject: [PATCH 07/10] ci: exercise architecture docs sync and hermetic JEV contracts in PR checks --- .github/workflows/portability-offline.yml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/.github/workflows/portability-offline.yml b/.github/workflows/portability-offline.yml index ef763bb6..0fdcfbd8 100644 --- a/.github/workflows/portability-offline.yml +++ b/.github/workflows/portability-offline.yml @@ -55,6 +55,18 @@ jobs: tests/test_eval_blinded_pstack_dsh_candidate.py \ tests/test_eval_blinded_pstack_dsh.py \ tests/test_canonical_index.py + - name: Validate documentation and offline JEV decision contracts + run: | + python -m pytest -q \ + tests/test_architecture_documentation.py \ + tests/test_decision_adapter.py \ + tests/test_jev_transport_and_profiles.py \ + tests/test_advisory_promotion.py \ + tests/test_shadow_routing.py \ + tests/test_class_calibration_policy.py \ + tests/test_rollback_equivalence.py \ + tests/test_verify_decision_contract.py \ + tests/test_eval_decision_routing.py - name: Validate checked-in model policy against canonical role registry run: python -m scripts.model_role_policy # Native host spawn/join/isolation are intentionally NOT covered here. From c6ac6038ea35cf11b35d3d570af3d9ccde442b01 Mon Sep 17 00:00:00 2001 From: tommy-ca <140900186+tommy-ca@users.noreply.github.com> Date: Tue, 20 Oct 2026 21:24:55 +0200 Subject: [PATCH 08/10] test: update diff-scoped JEV check tier after CI gate promotion --- tests/test_select_checks.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/test_select_checks.py b/tests/test_select_checks.py index b424276a..5d37bc47 100644 --- a/tests/test_select_checks.py +++ b/tests/test_select_checks.py @@ -98,7 +98,9 @@ def test_tests_only_selects_only_the_changed_module(self) -> None: result = vp.select_checks(["tests/test_shadow_routing.py"]) assert _commands(result) == [[PY, "-m", "pytest", "-q", "tests/test_shadow_routing.py"]] - assert result["checks"][0]["tier"] == "outside_gate" + # The JEV offline suite is now required by the PR workflow, not an + # out-of-gate opt-in. Check selection must mirror that live policy. + assert result["checks"][0]["tier"] == "offline" def test_offline_listed_module_keeps_the_offline_tier_without_opt_in(self) -> None: result = vp.select_checks(["tests/test_route_resolver.py"]) From 6d967bc05e15d679ff8967a4138696ee6f32e684 Mon Sep 17 00:00:00 2001 From: tommy-ca <140900186+tommy-ca@users.noreply.github.com> Date: Tue, 20 Oct 2026 21:25:25 +0200 Subject: [PATCH 09/10] docs: reconcile JEV mock transport with official System One wire and custom-profile scope --- docs/architecture/harness-adapters-and-jev-2026-10-20.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/docs/architecture/harness-adapters-and-jev-2026-10-20.md b/docs/architecture/harness-adapters-and-jev-2026-10-20.md index a8ad4c9c..8e9e5abd 100644 --- a/docs/architecture/harness-adapters-and-jev-2026-10-20.md +++ b/docs/architecture/harness-adapters-and-jev-2026-10-20.md @@ -96,7 +96,9 @@ JEV is a *decision model*, not a generative coding worker, model-role catalog, r **Feature controls:** `PSTACK_JEV_ENABLED` defaults OFF; `PSTACK_JEV_MODE` is `none|shadow|advisory` and defaults to shadow only when a provider is supplied to the wrapper; `PSTACK_JEV_PROFILE` selects an allowlisted endpoint profile. `PSTACK_JEV_ALLOW_PAID` is a paid-consent switch, **not** a measured or enforced spend budget. -**Transport implementation at audit SHA:** `JevDecisionAdapter` builds `{model,state,questions:[{id,type:'choice',options}]}` and uses `urllib.request` (or injected test transport) to POST to the configured `.../v1/systemone` endpoint. It does **not** currently import or instantiate `typesafe-sdk`, despite the preferred SDK wording in [provider options](../../references/jev-provider-options.md) and historical issue #515. Supported configuration rows in code are `opencode-zen`, `opencode-console`, `openrouter`, `typesafe-direct`; configuration and tests do not prove entitlement, live authenticated exchange, price or model quality. +**Transport implementation at audit SHA:** `JevDecisionAdapter` builds `{model,state,questions:[{id,type:'choice',options}]}` and uses `urllib.request` (or injected test transport) to POST to the configured `.../v1/systemone` endpoint. It does **not** currently import or instantiate `typesafe-sdk`, despite the preferred SDK wording in [provider options](../../references/jev-provider-options.md) and historical issue #515. Built-in configuration rows in code are `opencode-zen`, `opencode-console`, `openrouter`, `typesafe-direct`; configuration and tests do not prove entitlement, live authenticated exchange, price or model quality. The constructor also accepts a caller-provided `JevProviderProfile` object with an arbitrary `api_root`, so **the endpoint allowlist applies only to built-in string profiles**, not to all possible `JevDecisionAdapter` instances. + +**Wire-contract discrepancy (verified against current provider documentation):** the official [OpenCode Zen System One example](https://docs.opencode.ai/docs/zen/) and [OpenRouter's official TypeSafe SDK guide](https://openrouter.ai/docs/guides/community/typesafe-sdk) specify `questions` as a **name-keyed object** containing `type`, `instructions` and `criteria`; the response contains an `answers` object indexed by question name. The current adapter instead sends `questions: []` and expects `results: []`, which are the shapes constructed by its local mocked tests, **not the documented wire contract**. This source-level mismatch is tracked by [#664](https://github.com/tommy-ca/pstack/issues/664). Exact provider behavior remains unverified without an opt-in live fixture; do not infer a successful live request from mocks. **Existing path** (`scripts/route_resolver.py:resolve_skill_order_with_shadow`): compute deterministic route; load `references/decision-routing.json`; build a closed-set `ChoiceRequest`; collect provider observation; in `shadow` return the baseline; in `advisory` check candidate ID, per-class threshold, optional probability margin and a freshly computed receipt's staleness, otherwise fall back. The provider response status is `decided|abstain|unavailable|invalid`. @@ -105,6 +107,7 @@ JEV is a *decision model*, not a generative coding worker, model-role catalog, r - **[#658, P0] Egress/bypass ordering:** the wrapper currently asserts `SAFE_TO_SEND` for the **raw user query** and calls the provider before excluding slash/direct/system-two routes. The living spec prohibits assuming raw task prompts are public; regex-based secret blocking is not a positive privacy classification. - **[#659, P1] Admission freshness:** an in-memory decision receipt made from the same observation and immediately compared against itself is **not** preexisting persisted calibration/eval proof and must not grant controlling authority. - **[#660, P1] Response/paid controls:** confidence and probabilities need finite bounded validation; missing actual provider/model response fields and response question ID are not adequately proven; `max_spend_usd` metadata is not an enforced budget. Closed historical JEV provider tasks do not settle these new negative cases. +- **[#664, P1] Official System One wire parity:** the serializer and response parser disagree with documented questions/answers DTOs, and unit mocks embed the same nonconformant dialect. Correct via one SDK or one small transport, not a parallel implementation. - **[#663, P1] Canonical mapping revision drift:** the applied 0.15.29 pin is `88d47514...`, but `references/decision-routing.json#source.revision` remains `d0ef80d8...`. Comparing the pinned upstream Git tree with the mapping finds the same 23 playbook IDs but **18 different canonical playbook blob SHAs** and a different poteto-mode router blob (`21993f54...` vs stored `de51c561...`). The runtime reads semantic eligibility from this map without first validating it against the applied pin. Same inventory count is not version or policy equivalence. Until #663 reconciles classifications and gates freshness, advisory mapping authority is unproven. - **[#517] Scope:** model/fast-worker/leaf-skill selection remains research. No JEV model routing or autonomous execution authority is accepted. @@ -152,4 +155,4 @@ python3 -m pytest -q tests/test_decision_adapter.py tests/test_jev_transport_and # isolated harmless fixture, declared scope and a durable observed_live receipt. ``` -Recursive work: documentation [#661](https://github.com/tommy-ca/pstack/issues/661) can land alone; safety [#658](https://github.com/tommy-ca/pstack/issues/658) blocks any live JEV use; mapping freshness [#663](https://github.com/tommy-ca/pstack/issues/663), evidence [#659](https://github.com/tommy-ca/pstack/issues/659) and transport [#660](https://github.com/tommy-ca/pstack/issues/660) must independently pass negative fixtures before any advisory-promotion gate. [#517](https://github.com/tommy-ca/pstack/issues/517) remains research-only. Exact-head **Swarm** partitions tests/review by adapter versus JEV, **Arena** compares baseline-only/shadow/advisory with predeclared rubric, **Interrogate** checks privacy, false PASS, model-family independence and rollback. Mark these BLOCKED when only source inspection or one reviewer is available. +Recursive work: documentation [#661](https://github.com/tommy-ca/pstack/issues/661) can land alone; safety [#658](https://github.com/tommy-ca/pstack/issues/658) blocks any live JEV use; mapping freshness [#663](https://github.com/tommy-ca/pstack/issues/663), wire contract [#664](https://github.com/tommy-ca/pstack/issues/664), evidence [#659](https://github.com/tommy-ca/pstack/issues/659) and transport [#660](https://github.com/tommy-ca/pstack/issues/660) must independently pass negative fixtures before any advisory-promotion gate. [#517](https://github.com/tommy-ca/pstack/issues/517) remains research-only. Exact-head **Swarm** partitions tests/review by adapter versus JEV, **Arena** compares baseline-only/shadow/advisory with predeclared rubric, **Interrogate** checks privacy, false PASS, model-family independence and rollback. Mark these BLOCKED when only source inspection or one reviewer is available. From d6352cb5940b8f319d025caa54db1088266a7c0c Mon Sep 17 00:00:00 2001 From: tommy-ca <140900186+tommy-ca@users.noreply.github.com> Date: Tue, 20 Oct 2026 21:25:38 +0200 Subject: [PATCH 10/10] test(docs): require System One protocol mismatch caveat in architecture contract --- tests/test_architecture_documentation.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_architecture_documentation.py b/tests/test_architecture_documentation.py index 03bcbeda..91f1959e 100644 --- a/tests/test_architecture_documentation.py +++ b/tests/test_architecture_documentation.py @@ -84,5 +84,5 @@ def test_jev_implementation_caveats_remain_explicit() -> None: assert "Choice-only" in doc # Every current high-risk JEV caveat must have an owner, rather than appearing # to be solved by this documentation change or by a historical closed issue. - for issue in ("#658", "#659", "#660", "#663"): + for issue in ("#658", "#659", "#660", "#663", "#664"): assert issue in doc