Record NK-WP-0048 adapter set coordinator review r4 at 1920b13 (all approved; 1.3 successor candidate source)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
33ba28a0ff
commit
4c04e40c26
1 changed files with 137 additions and 0 deletions
|
|
@ -0,0 +1,137 @@
|
|||
{
|
||||
"schema": "custodian.nk48-adapter-set-source-review.v1",
|
||||
"revision": "r4",
|
||||
"reviewed_on": "2026-10-17",
|
||||
"reviewer": "custodian coordinator (Claude Code, new separate session; no context from the authoring session, the r1/fix session, the r2 session or the r3 session; nothing asked of any of them; source read from git archive only)",
|
||||
"scope": "Source review of the changes since r3: 1.3 successor selection in ensure-groups, hand-over, deliver-consumer-secret and the composer; the regenerated 1.2 artifact; the new 1.3 artifact; the proposed 1.3 type package; and the real-kernel 1.3 admission test. Not the owner review, not the founder's acknowledgment of 1.3.",
|
||||
"frozen_target": {
|
||||
"repository": "net-kingdom",
|
||||
"commit": "1920b134e2b577e74aaac6b59db5fd785f505a3d",
|
||||
"r3_target": "ff8f597d5f2f32ce8e82e370c0ad43aa98dc31b7",
|
||||
"commits_since_r3": "9877ee8 (T30 done, workplan only), 835680c (1.3 source support), merge acda26c, 1920b13 (1.3 type package and admission test)",
|
||||
"diff_since_r3_verified": "git diff --stat ff8f597 1920b13 touches only: the 1.3 package (README.md, type.yaml, examples/forgejo.yaml, examples/example-public-portal.yaml, tests/test_source_contract.py, all new); compose-1.2-descriptors.py; ensure-groups, handover and deliver-consumer-secret adapters (.py and .md); both candidate artifacts (1.2 changed, 1.3 new); test_admit_1_3_type.py (new); additive tests in test_compose_1_2_descriptors.py, test_deliver_consumer_secret_adapter.py, test_ensure_groups_adapter.py and test_handover_adapter.py; and the NK-WP-0048 workplan. No change under security-case-types/ (canonical 1.1) or security-case-type-revisions/1.2/, and none to the shared helpers.",
|
||||
"kernel": "ops-warden a45cf47 src (out of scope; used as the admission contract)"
|
||||
},
|
||||
"hashes_verified": {
|
||||
"ensure-groups-adapter.py": "sha256:e631134f20713d441b72ad7a9f49062b48925c4b6051b32bcfe9dadafff89b71",
|
||||
"handover-adapter.py": "sha256:34dcae7ce19f6c7c8c8bb79f6b08e4c11be65269545cf739a9152e3d4dfe9b82",
|
||||
"deliver-consumer-secret-adapter.py": "sha256:fc34f750814bc85616aae158c81a8d9453ecf09ba3acdff0eba1d0eaeab911f5",
|
||||
"compose-1.2-descriptors.py": "sha256:39021cac900b11a59d00c5a1d5491b1ee4c639955cde07d07854c3db8bc04958",
|
||||
"descriptor-composition-1.2.candidate.json": "sha256:da0b8847c4ea343370fc9f86b7f87025a0765a41e4d2d2f73e354a8db2f0077f",
|
||||
"descriptor-composition-1.3.candidate.json": "sha256:64355c314891f7fc951a14e55c197609e892e73628acd43a535974382136961b",
|
||||
"security-case-type-revisions/1.3/oidc-browser-relying-party/type.yaml": "sha256:3c05a749f28fa25df4d72aa1482a21be4ecc53af44ad17762d673588e2b3a947",
|
||||
"test_admit_1_3_type.py": "sha256:1e2667b83398b22e02d73bcda3a2f92bd0d14533e9a2e2d9f7492ad9b1eae387",
|
||||
"keycape-registration-adapter.py": "sha256:021eee262ea5d23d46258ed819da57b331f07b814adcafd60e0941214be02aea",
|
||||
"mint-secret-adapter.py": "sha256:246323c7243ded18229ab063956577e151d56d9be485d3bd44fc38e5af0edf3c",
|
||||
"deliver-secret-adapter.py": "sha256:cd1a515a1ae2def2093660ed2a810a9c66d1d4cf7126f573ee7e9c4c42afb98d",
|
||||
"bind-env-adapter.py": "sha256:800e45ecb68cc782c91aafda4242e0034e4156a54f6729d9f61fb845d4325d50"
|
||||
},
|
||||
"hashes_match": true,
|
||||
"unchanged_files_byte_identical_to_r3": {
|
||||
"result": true,
|
||||
"evidence": "cmp between git archive ff8f597 and git archive 1920b13: identical for keycape-registration-adapter.py, mint-secret-adapter.py, deliver-secret-adapter.py, bind-env-adapter.py and the four shared helpers (keycape-client.py, portal-client-rollout.py, openbao-client-config.py, register-user-engine-portal.py). The four adapter hashes equal r3's hashes_verified values."
|
||||
},
|
||||
"independent_reconstruction_passed": 127,
|
||||
"independent_reconstruction_subtests_passed": 111,
|
||||
"package_tests_passed": {"1.3": 22, "1.2": 22},
|
||||
"reconstruction": "git archive of net-kingdom 1920b13 (full tree) and ops-warden a45cf47 src into scratch. validate-type on the 1.3 package: 'OK oidc-browser-relying-party@1.3 (proposed)' (1.2 and canonical 1.1 also validate OK). README-r4 adapter pytest command: 127 passed, 111 subtests passed, matching the authors. Package tests: 22 passed for 1.3 and 22 passed for 1.2, each run separately, but only after the export was placed in a directory named net-kingdom (see observation O1). Composer rerun from the clean export with the artifacts' own check_config_digest and params (consumer_owner_repo railiance-apps): default, --version 1.2 and --version 1.3 all exit 0; the default and the explicit 1.2 outputs are byte-identical to each other and to the committed 1.2 artifact; the 1.3 output is byte-identical to the committed 1.3 artifact.",
|
||||
"check_1_version_selection": {
|
||||
"result": "confirmed",
|
||||
"evidence": [
|
||||
"ensure-groups: SELECTABLE_TYPES gains '1.3'; the version_root default stays '1.1'; build() refuses an unknown root, and _request refuses unless spec.type equals SELECTABLE_TYPES[version_root] exactly. So a 1.3 case is refused under the default and under '1.2', and accepted only with version_root='1.3' (test_explicit_version_root_selects_1_3).",
|
||||
"hand-over: the same SELECTABLE_TYPES change, with the default '1.1'. OWNER_ROOTS = {'1.2','1.3'}, so a 1.3 case needs a bounded consumer_owner_repo, and build() refuses unless it equals admitted.owner. The 1.2 owner rule therefore applies unchanged to 1.3 (test_1_3_explicit_selection_with_1_2_owner_handling: default refused, missing owner refused, 1.3 case under the 1.2 root refused, admitted owner 'apps' against case owner 'railiance-apps' refused, matching owner SUCCESS).",
|
||||
"deliver-consumer-secret: ACCEPTED_TYPES = frozenset({'oidc-browser-relying-party@1.2', 'oidc-browser-relying-party@1.3'}), matched by exact set membership. 1.1, 1.4 and other@1.3 are refused (test_accepts_exactly_1_2_and_1_3). It has no version root, which is unchanged from r3 and as the request specifies (see O5).",
|
||||
"No --allow-unimplemented path was added. The only diff hunks in the three adapters are the type-acceptance constants and the owner-root condition."
|
||||
]
|
||||
},
|
||||
"check_2_composer": {
|
||||
"result": "confirmed",
|
||||
"evidence": [
|
||||
"1.2 artifact versus r3's ff8f597 artifact (structural diff): only execution_descriptors and the steps[] entries for ensure-groups, deliver-consumer-secret and hand-over changed (candidate_descriptor_digest and descriptor.adapter_source). Nothing else moved: names_confirmed, lanes, owners, actors, the canonical digest and the selection string are all unchanged.",
|
||||
"1.2 versus 1.3 artifact: only 'type' and 'selection' differ. execution_descriptors and every step descriptor are identical, because no adapter descriptor encodes the type version (see O6).",
|
||||
"load_types(version_roots=None) builds {version: security-case-type-revisions/<version>}, requires the roots to be exactly {version}, requires the loaded spec.version to equal the version, and refuses if <version> is reachable through the default root. Scratch probes on a copy of 1920b13: 1.3 with the 1.2 revision directory removed composes byte-identically; 1.2 with that directory removed refuses ('revision directory ... 1.2 absent'); 1.3 with its directory removed refuses, while 1.2 still composes byte-identically; the 1.3 type copied over the default root's type.yaml refuses ('1.3 is reachable by default'); a 1.2 type.yaml placed in the 1.3 root refuses ('1.3 type not loadable through explicit version-root selection'). --version 1.1 and 1.4 are rejected by argparse choices.",
|
||||
"The r1 checks on partial, duplicate, unknown and mismatched maps are unchanged in compose(); only the messages were parameterised. compose() now passes version and version_roots to its post-composition load_types call."
|
||||
]
|
||||
},
|
||||
"check_3_type_1_3": {
|
||||
"result": "confirmed",
|
||||
"evidence": [
|
||||
"diff of 1.2/type.yaml against 1.3/type.yaml: version '1.2'->'1.3', status acknowledged->proposed, plus an appended comment and the execution_descriptors map with seven entries. There are no other differences.",
|
||||
"The map equals descriptor-composition-1.3.candidate.json execution_descriptors and the fresh 1.3 regeneration exactly (seven steps). test_committed_map_is_exactly_the_composed_set also recomputes it from live adapter_descriptors(version='1.3'), which itself refuses any descriptor whose adapter_source differs from the module's source_digest().",
|
||||
"1.2 type.yaml carries no execution_descriptors (checked directly and by test_earlier_versions_carry_no_execution_map). Canonical 1.1 is unchanged (no diff under security-case-types/).",
|
||||
"Package: the examples differ from 1.2 only in the type pin @1.3. tests/test_source_contract.py differs from 1.2's only in the expected status 'proposed'. The decision/ directory (1.2's acknowledgment record) is correctly absent, so 1.2's acknowledgment is not inherited. The README states that 1.3 needs its own Decision Memo and founder acknowledgment."
|
||||
]
|
||||
},
|
||||
"check_4_admission_test": {
|
||||
"result": "confirmed: the test proves its docstring's claims, the pin claim through a pair of tests (see O2)",
|
||||
"evidence": [
|
||||
"Proposed type refused: all seven descriptors refused 'type is not acknowledged' (case_run.py:452), before the map check.",
|
||||
"Acknowledged copy refused by the missing pin: all seven refused 'browser metadata failed exact-version validation' (case_inputs.py:98). That message is a catch-all for BrowserInputs.target, but the next test differs only by mock.patch.dict(PARAMETER_PINS, {'1.3': fingerprint}), and with it all seven are admitted with step, actor and target 'forgejo' as the descriptor states. So the missing 1.3 pin is the only refusal on that path. The same test asserts that the 1.3 parameter fingerprint equals PARAMETER_PINS['1.2'] and that '1.3' is absent from the pins at a45cf47.",
|
||||
"Descriptor outside the map: mint-secret with lane 'other-lane' or retry_safe True is refused 'type has no exact acknowledged machine descriptor' (case_run.py:455-459). The caller lane is taken from the changed descriptor, so the refusal is the map check and not the lane check.",
|
||||
"Mutation probes on scratch copies of 1920b13: changing the bind-env map digest -> 3 tests fail (map equality, and the pinned admission fails at the map check); dropping hand-over from the map -> 3 fail; changing one parameter description in the 1.3 type -> the fingerprint-equality assertion fails; appending a byte to ensure-groups-adapter.py -> 3 fail (composed set differs from the map). The test detects each of these.",
|
||||
"Trust is fixture-only (an evidence lambda), the adapters are unused stubs that raise on dispatch, WARDEN_AGENT_ID is cleared, principal is 'founder', and the 1.3 pin is added in memory only. Nothing is dispatched or pinned."
|
||||
]
|
||||
},
|
||||
"artifact_assessment": {
|
||||
"descriptor-composition-1.2.candidate.json": {"fresh_regeneration_equal": true, "complete_executable_descriptor_set": true, "admitted": false, "dispatch_permitted": false, "owner_review": false},
|
||||
"descriptor-composition-1.3.candidate.json": {"fresh_regeneration_equal": true, "complete_executable_descriptor_set": true, "admitted": false, "dispatch_permitted": false, "owner_review": false},
|
||||
"kernel_admission": "test_admit_1_2_adapter_descriptors.py (reads the regenerated 1.2 artifact) and test_admit_1_3_type.py both pass under a45cf47 within the 127. This is fixture trust only, not owner admission."
|
||||
},
|
||||
"verdicts": {
|
||||
"ensure-groups-adapter.py": {
|
||||
"verdict": "approved",
|
||||
"checks": "1: SOURCE_FILES unchanged; the new source digest is pinned by the regenerated descriptor (adapter_source equals source_digest(), checked by the composer); per-attempt drift refusal is untouched; closure test passes. 2-4, 7: no change to receipts, rollback, revocation or journal code (the diff touches only SELECTABLE_TYPES, a comment and the docstring). 5: case, descriptor and acceptance pins and the target check are unchanged; a 1.3 case under the wrong root refuses. 6: 1.1 stays the default, and 1.2 and 1.3 are each reachable only by their own explicit root. 8: artifact covered above."
|
||||
},
|
||||
"handover-adapter.py": {
|
||||
"verdict": "approved",
|
||||
"checks": "1: as for ensure-groups; the new digest is pinned in both artifacts. 2-4: receipt, removal and revocation code unchanged. 5: the consumer_owner_repo rule now covers 1.3 through OWNER_ROOTS; a missing or unbounded owner refuses, and an admitted owner different from the case owner refuses. 6: 1.1 default; 1.3 only via version_root='1.3'; a 1.3 case under the 1.2 root refuses. 7: n/a. 8: covered above."
|
||||
},
|
||||
"deliver-consumer-secret-adapter.py": {
|
||||
"verdict": "approved",
|
||||
"checks": "1: as above. 2-5: unchanged apart from the type gate; confidential-only and the bound parameters are still required. 6: accepts exactly {1.2, 1.3} by exact membership and refuses canonical 1.1 and any other type; there is no default-version path because 1.1 has no such step. 7: n/a. 8: covered above."
|
||||
},
|
||||
"compose-1.2-descriptors.py": {
|
||||
"verdict": "approved",
|
||||
"checks": "Check 8 and the r4 composer checks hold: explicit version-root-only loading, --version limited to 1.2|1.3 with 1.2 as the default, refusal when the version is reachable by default, and the canonical 1.1 digest re-checked after composition. Partial, duplicate, unknown and mismatched maps are still refused. Both artifacts equal a fresh regeneration. A Refused in main() now exits 3 with a message instead of a traceback. Leftover constants: see O4."
|
||||
},
|
||||
"descriptor-composition-1.2.candidate.json": {
|
||||
"verdict": "approved",
|
||||
"checks": "Byte-identical to a fresh regeneration (default and explicit --version 1.2). It differs from r3's artifact only in the three moved digests (ensure-groups, deliver-consumer-secret, hand-over) and their adapter_source values."
|
||||
},
|
||||
"descriptor-composition-1.3.candidate.json": {
|
||||
"verdict": "approved",
|
||||
"checks": "Byte-identical to a fresh --version 1.3 regeneration. It differs from the 1.2 artifact only in 'type' and 'selection'. Status not_an_admission; admitted, dispatch_permitted and owner_review are false."
|
||||
},
|
||||
"security-case-type-revisions/1.3/oidc-browser-relying-party/type.yaml": {
|
||||
"verdict": "approved (as a proposed source candidate)",
|
||||
"checks": "It differs from 1.2 only in version, status proposed and the execution_descriptors map (plus a comment). The map equals the composed 1.3 set exactly. It passes the owner validator and the 22 package tests. The parameters are byte-equivalent to 1.2's (fingerprint c04385d1...ea6). This approval is of the source, not an acknowledgment."
|
||||
},
|
||||
"test_admit_1_3_type.py": {
|
||||
"verdict": "approved (evidence)",
|
||||
"checks": "It proves what its docstring claims (check 4 above). The mutation probes show that it detects map drift, a missing step, parameter drift and adapter source drift."
|
||||
},
|
||||
"keycape-registration-adapter.py": {"verdict": "approved (unchanged since r3, byte-identical)"},
|
||||
"mint-secret-adapter.py": {"verdict": "approved (unchanged since r3, byte-identical)"},
|
||||
"deliver-secret-adapter.py": {"verdict": "approved (unchanged since r3, byte-identical)"},
|
||||
"bind-env-adapter.py": {"verdict": "approved (unchanged since r3, byte-identical)"}
|
||||
},
|
||||
"findings": [],
|
||||
"observations_not_findings": [
|
||||
"O1 (reproduction recipe, not reviewed source): the README-r4 package-test command extracts net-kingdom into $SCRATCH/nk, but the package tests call discover_declarations(TYPE, NET_KINGDOM_ROOT.parent), which looks for <parent>/net-kingdom/capabilities/playbooks/net-kingdom.keycape-client-registration.yaml. Run as written, both the 1.2 and 1.3 package tests give 6 failed, 16 passed. With the export extracted to a directory named net-kingdom, both give 22 passed. The request document should extract into $SCRATCH/net-kingdom.",
|
||||
"O2: 'browser metadata failed exact-version validation' covers every failure inside BrowserInputs.target (the parameter pin, the target-parameter definition, case parameter classification, validator SOURCE_PINS and the validator subprocess). test_warden_has_no_1_3_parameter_pin_yet alone does not isolate the pin. The claim holds because the admitted test differs from it only by the in-memory 1.3 pin.",
|
||||
"O3: with_status() re-serialises the type through yaml.safe_dump, so the 'acknowledged copy' differs from the committed bytes in formatting, not in content apart from status. Under fixture trust this has no effect. A real acknowledgment binds its own exact bytes (type-machine-seam-acceptance over digest(type_source)).",
|
||||
"O4: in compose-1.2-descriptors.py, TYPE_REF ('...@1.2') is no longer used by the composer, and VERSION_ROOTS ({'1.2': ...}) is used only by the tests. Both are harmless leftovers.",
|
||||
"O5: deliver-consumer-secret has no version root and accepts 1.2 and 1.3 cases directly. mint-secret and deliver-secret do no spec.type check, and registration and bind-env accept any oidc-browser-relying-party@1.x through the helper's CASE_TYPE regex. For these steps version selection rests on the kernel's case/type pin, as r2 and r3 observed. This is unchanged by r4 and is not a defect.",
|
||||
"O6 (source fact for owner review): no descriptor encodes the type version, so the 1.2 and 1.3 compositions produce identical execution_descriptors. A descriptor digest therefore does not bind a type version on its own; the binding comes from the acknowledged type's map together with the case pin."
|
||||
],
|
||||
"open_questions_source_facts": {
|
||||
"q1_ops_warden_1_3_pin": "At a45cf47, case_inputs.PARAMETER_PINS holds only '1.1' and '1.2'. The 1.3 parameter fingerprint equals the '1.2' pin (c04385d176f5f70257fb0fa6fef7e48ab26ed7cf26f6b1c7f14b16237b0ebea6), so the proposed pin value is 1.2's.",
|
||||
"q2_mint_semantics": "Executor.admit refuses effect 'mint' unless actor == 'human' and WARDEN_AGENT_ID is unset (case_run.py, after the evidence checks). The 1.3 artifact's mint-secret descriptor has actor human. The type's warden_executes/attended fields are not read by Executor.admit.",
|
||||
"q3_owner_run_and_attended_steps": "case_run.py never reads warden_executes or attended (grep). Those fields are read by plan.py, case_plan.py, case_type.py, worker.py, cli.py and routing/. Admission is decided by the map, so every step listed in the map is admissible once the type is acknowledged and pinned, whatever its warden_executes value."
|
||||
},
|
||||
"canonical_integration": "not approved",
|
||||
"native_acceptance": false,
|
||||
"grants": "none: no owner admission, pin, acknowledgment or native authority; those stay with NK-WP-0048-T16 owner review and the founder",
|
||||
"hard_limits_observed": "no live or native action, no kubectl, SSH or secret access; net-kingdom and ops-warden not edited (read via git archive into scratch only; probes and mutations ran on scratch copies); nothing fixed during review",
|
||||
"remaining": "Source review r4 is complete at 1920b13 with no findings. Next: the four 1.3 owner reviews under NK-WP-0048-T16 (including open questions 1-3 and O6), an ops-warden owner change adding the 1.3 parameter pin if the owners choose it, a Decision Memo and founder acknowledgment of 1.3, owner pinning, then native acceptance. Separately, README-r4's reproduce recipe should extract into a directory named net-kingdom (O1). This review grants none of these."
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue