feat(case): KERNEL-2/3 lane resolution and mode-aware admission; CATALOG-1 draft lanes
nk48 1.3 owner review (owner-review-ops-warden.json): - KERNEL-2: Executor.admit parses catalog_source and resolves descriptor.lane; refuses a missing, non-active, undelegated or ungraded lane, an owner outside owner_repo, and a mint/change effect on a lane not graded risk high. catalog-routing-acceptance still covers the whole catalog digest. - KERNEL-3: dispatch mode is read from the type's follow_through step (warden_executes/attended). The step must declare both booleans and a lane and agree with the descriptor's lane and owner. Attended: human actor, WARDEN_AGENT_ID unset, parent-session revocation scope, caller lane equal to the step lane. Owner: native delegation, owner_repo == descriptor.owner, no Warden-executed lane and no Warden-brokered mint. - CATALOG-1: draft entries keycape-attended-case-change (OW-1.3-C1), platform-secret-delivery, consumer-owner-deployment, apps-consumer-handover. Not promoted; promotion waits for owner confirmation. - Fixture catalogs and type steps in tests; published routing_lanes coverage and the workload-join count follow the four new not-applicable lanes. PARAMETER_PINS untouched (PIN-1 waits for founder acknowledgment). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Assistant: claude-code Assistant-Model: opus Assistant-Process: 903097@bnt-lap001 Assistant-Session: aa320c8f-c3fa-46e7-8541-0b58e1e45d23
This commit is contained in:
parent
117fec9241
commit
a14376cf62
8 changed files with 363 additions and 13 deletions
|
|
@ -12,8 +12,47 @@ from warden.case_receipt_state import Outcome, Refused
|
|||
from warden.case_run import Adapter, Descriptor, Executor, Journal, OwnerResult, digest
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def rig(tmp_path):
|
||||
def lane_entry(lane="issuer-lane", owner="owner", **over):
|
||||
"""Fixture catalog entry (TEST ONLY; never a real routing pointer)."""
|
||||
entry = {
|
||||
"id": lane,
|
||||
"title": "fixture lane",
|
||||
"need_keywords": [lane],
|
||||
"owner_repo": owner,
|
||||
"subsystem": "fixture",
|
||||
"warden_executes": False,
|
||||
"wiki_ref": "wiki/fixture.md",
|
||||
"canon_ref": "fixture/canon.md",
|
||||
"reviewed": "2026-10-17",
|
||||
"status": "active",
|
||||
"risk": "high",
|
||||
"workload_ref": {"applicability": "not-applicable", "reason": "fixture"},
|
||||
"delegation": {
|
||||
"mode": "native",
|
||||
"intended_owner": owner,
|
||||
"reviewed": "2026-10-17",
|
||||
},
|
||||
}
|
||||
entry.update(over)
|
||||
return entry
|
||||
|
||||
|
||||
def fixture_catalog(*entries):
|
||||
return yaml.safe_dump({"entries": list(entries) or [lane_entry()]}).encode()
|
||||
|
||||
|
||||
CATALOG = fixture_catalog()
|
||||
|
||||
MINT_STEP = {
|
||||
"id": "mint-secret",
|
||||
"owner": "owner",
|
||||
"lane": "issuer-lane",
|
||||
"warden_executes": True,
|
||||
"attended": False,
|
||||
}
|
||||
|
||||
|
||||
def make_rig(tmp_path):
|
||||
desc = Descriptor(
|
||||
"warden.case.execution.v1",
|
||||
"mint-secret",
|
||||
|
|
@ -43,6 +82,7 @@ def rig(tmp_path):
|
|||
}
|
||||
],
|
||||
"execution_descriptors": {"mint-secret": digest(descriptor)},
|
||||
"follow_through": [dict(MINT_STEP)],
|
||||
}
|
||||
}
|
||||
).encode()
|
||||
|
|
@ -106,7 +146,7 @@ def rig(tmp_path):
|
|||
("ops-mason-materialization", digest(case), "materialization"),
|
||||
("owner-descriptor-acceptance:owner", digest(descriptor), "descriptor"),
|
||||
("type-machine-seam-acceptance", digest(typ), "descriptor"),
|
||||
("catalog-routing-acceptance", digest(b"catalog"), "descriptor"),
|
||||
("catalog-routing-acceptance", digest(CATALOG), "descriptor"),
|
||||
("caller-session:human:operator:issuer-lane", digest(case), "session"),
|
||||
("session-revocation:issuer-lane", digest(case), "session-revoked"),
|
||||
("grant-revocation:issuer-lane", digest(case), "grant-revoked"),
|
||||
|
|
@ -136,8 +176,13 @@ def rig(tmp_path):
|
|||
descriptor_evidence="descriptor",
|
||||
session_evidence="session",
|
||||
)
|
||||
admitted = executor.admit(case, typ, descriptor, b"catalog", **kwargs)
|
||||
return (executor, admitted, calls, (case, typ, descriptor, b"catalog"), kwargs)
|
||||
admitted = executor.admit(case, typ, descriptor, CATALOG, **kwargs)
|
||||
return (executor, admitted, calls, (case, typ, descriptor, CATALOG), kwargs)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def rig(tmp_path):
|
||||
return make_rig(tmp_path)
|
||||
|
||||
|
||||
def test_commit_running_is_visible_from_separate_connection_before_dispatch(rig):
|
||||
|
|
@ -387,7 +432,7 @@ def test_changed_catalog_pins_cannot_inherit_old_success(rig):
|
|||
executor, args, calls, sources, kwargs = rig
|
||||
executor.run(*args)
|
||||
with pytest.raises(Refused):
|
||||
executor.admit(*sources[:3], b"changed-catalog", **kwargs)
|
||||
executor.admit(*sources[:3], fixture_catalog(lane_entry(title="changed")), **kwargs)
|
||||
assert len(calls) == 1
|
||||
|
||||
|
||||
|
|
@ -601,7 +646,7 @@ def test_attempt_identity_changes_with_exact_catalog_revision_and_new_journal(
|
|||
executor, args, calls, sources, kwargs = rig
|
||||
executor.run(*args)
|
||||
original_attempt = calls[-1].attempt_id
|
||||
new_catalog = b"independently-reviewed-catalog-v2"
|
||||
new_catalog = fixture_catalog(lane_entry(title="independently reviewed v2"))
|
||||
old_verifier = executor.evidence_verifier
|
||||
|
||||
def verifier(purpose, source, evidence):
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue