The module header says a signature or permission tightening requires a
schema/version bump, and the ADOPTION ABI-1 row calls the per-version
fingerprints "fail-closed both directions". The digest hashed method NAMES
and RuntimeInfo KEYS only, so the whole class it was written to catch went
through unnoticed: reordering a parameter, dropping a default, tightening
Sequence[str] to List[str], or changing server_port from int to str all
break a reviewed register() while leaving the recorded digest byte-identical.
The payload now carries each public method's inspect.signature text and each
RuntimeInfo key's annotation. `from __future__ import annotations` is active
in the module, so both halves are the annotation SOURCE text (the TypedDict's
ForwardRef arg, the stringified annotations inside str(signature)) — stable
across interpreter versions and exactly what a reviewer reads. The 2.0
fingerprint is re-recorded for the wider payload; no other surface stored the
old digest.
Red-first: with the pre-fix payload restored, both new mutants (a parameter
annotation, a RuntimeInfo value type) produce the IDENTICAL digest and
negotiate happily — the two parametrized cases fail on exactly that equality.
Green after, together with test_contracts, test_plugin_api_admission,
test_oop_extension_parity and the extension loader/API suites.
Owner-sanctioned protected-file edit (ouroboros/contracts/plugin_api.py) as
part of the ABI-1 package: the gap was in the implementation, not in the
contract's intent.
PLUGIN_API_VERSION=2.0 with full manifest negotiation (major strict, minor
minimum, closed-set capabilities, typed educational refusals) checked before
any plugin import or out-of-process catalog; an absent plugin_api field binds
the LEGACY 1.3 generation by construction and keeps loading on its existing
hash-bound review PASS (grandfather), while a NEW PASS is refused at issuance
by one admission predicate shared by LLM review (a $0 refusal before the
paid panel dispatches), owner attestation, and native-seed trust (native_seed
closed; bundled telegram/unix_computer_use declare the field with version
bumps). Repeat review of grandfathered bytes never clobbers the live PASS,
and the persisted admission finding re-aggregates to PENDING under every
enforcement mode. The deterministic preflight now fails closed (infra
failures refuse without persisting). Frozen RuntimeInfo TypedDict with the
negotiated generation; per-version surface fingerprints fail closed in both
directions; FORBIDDEN_EXTENSION_SETTINGS alias collapsed; legacy
PluginAPIImpl kwargs removed; iframe_raw desync healed by re-deriving
VALID_EXTENSION_PERMISSIONS from skill_manifest (single carrier); the
negotiated generation rides the registration bundle and dispatch-surface
stamps (ABI-9 seam). Owner-A grant resync: a native re-seed with unchanged
requested key/permission sets carries grants to the new content hash.
Owner 6.2=A: declarative dependency fingerprint — .ouroboros_env bytes stay
outside the review hash, declared dependency names are hash-covered, and a
state-plane/payload declaration desync is a typed load refusal.
ADOPTION: ABI-1 -> done. ARCHITECTURE + CREATING_SKILLS deltas same-commit.
(cherry picked from commit 8f3fb629c7b51a2ebd6933cc8742697199206068)