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
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,14 @@

### Added

- `warp-core` optic invocation admission now has a narrow BasisResolution v0
boundary. Identity-covered invocations with exact fixture basis bytes
`basis-request:resolved-fixture:v0` progress past basis resolution and still
obstruct at `UnsupportedApertureResolution`; all unsupported non-empty basis
shapes continue to obstruct at `UnsupportedBasisResolution`. This does not
issue admission tickets, law witnesses, scheduler work, execution, aperture
resolution, budget evaluation, runtime support checks, or successful grant
validation.
- `warp-core` optic invocation admission now has a budget/runtime-support
obstruction shell. Empty budget request bytes obstruct as
`MissingBudgetRequest`; `UnsupportedBudgetResolution` and
Expand Down
21 changes: 16 additions & 5 deletions crates/warp-core/src/optic_artifact.rs
Original file line number Diff line number Diff line change
Expand Up @@ -596,6 +596,8 @@ pub struct OpticInvocation {
pub capability_presentation: Option<OpticCapabilityPresentation>,
}

const OPTIC_BASIS_RESOLUTION_V0_FIXTURE_BYTES: &[u8] = b"basis-request:resolved-fixture:v0";

/// Admission obstruction for an optic invocation.
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum OpticInvocationObstruction {
Expand All @@ -609,11 +611,11 @@ pub enum OpticInvocationObstruction {
MissingApertureRequest,
/// The invocation does not name any budget request bytes.
MissingBudgetRequest,
/// The invocation reached basis resolution, but Echo has no basis resolver
/// wired into admission in this slice.
/// The invocation reached basis resolution, but the requested basis shape is
/// outside the narrow deterministic BasisResolution v0 fixture.
UnsupportedBasisResolution,
/// The invocation reached aperture resolution, but Echo has no aperture
/// resolver wired into admission in this slice.
/// The invocation reached aperture resolution after BasisResolution v0, but
/// Echo has no aperture resolver wired into admission in this slice.
UnsupportedApertureResolution,
/// The invocation reached budget resolution, but Echo has no budget
/// evaluator wired into admission in this slice.
Expand Down Expand Up @@ -1183,7 +1185,8 @@ impl OpticArtifactRegistry {
validation,
CapabilityGrantValidationOutcome::IdentityCovered(_)
) {
final_obstruction = OpticInvocationObstruction::UnsupportedBasisResolution;
final_obstruction = Self::resolve_basis_v0(&invocation.basis_request)
.unwrap_or(OpticInvocationObstruction::UnsupportedApertureResolution);
}
}

Expand All @@ -1200,6 +1203,14 @@ impl OpticArtifactRegistry {
None
}

fn resolve_basis_v0(basis_request: &OpticBasisRequest) -> Option<OpticInvocationObstruction> {
if basis_request.bytes == OPTIC_BASIS_RESOLUTION_V0_FIXTURE_BYTES {
return None;
}

Some(OpticInvocationObstruction::UnsupportedBasisResolution)
}

fn classify_aperture_request(
aperture_request: &OpticApertureRequest,
) -> Option<OpticInvocationObstruction> {
Expand Down
61 changes: 61 additions & 0 deletions crates/warp-core/tests/optic_invocation_admission_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,17 @@ fn fixture_invocation(handle: OpticArtifactHandle) -> OpticInvocation {
}
}

fn fixture_invocation_with_resolved_basis_and_presentation(
handle: OpticArtifactHandle,
grant_id: &str,
) -> OpticInvocation {
let mut invocation = fixture_invocation_with_presentation(handle, grant_id);
invocation.basis_request = OpticBasisRequest {
bytes: b"basis-request:resolved-fixture:v0".to_vec(),
};
invocation
}

fn expected_obstructed_posture(
invocation: &OpticInvocation,
obstruction: OpticInvocationObstruction,
Expand Down Expand Up @@ -795,6 +806,56 @@ fn runtime_support_unavailable_is_defined_but_unreachable_until_basis_resolution
Ok(())
}

#[test]
fn unsupported_basis_still_stops_at_unsupported_basis_resolution() -> Result<(), String> {
let (mut registry, handle) = fixture_registry_and_handle()?;
let invocation = fixture_invocation_with_presentation(handle, "grant:covered");
let mut gate = fixture_gate_with_grant(fixture_grant("grant:covered"));

let outcome = registry.admit_optic_invocation_with_capability_validator(&invocation, &mut gate);

assert_eq!(
obstruction_for(&outcome),
OpticInvocationObstruction::UnsupportedBasisResolution
);
assert!(matches!(
latest_invocation_obstruction_fact(&registry)?,
GraphFact::OpticInvocationObstructed {
obstruction,
..
} if *obstruction == InvocationObstructionKind::UnsupportedBasisResolution
));
Ok(())
}

#[test]
fn resolved_basis_still_obstructs_before_aperture_resolution() -> Result<(), String> {
let (mut registry, handle) = fixture_registry_and_handle()?;
let invocation =
fixture_invocation_with_resolved_basis_and_presentation(handle, "grant:covered");
let mut gate = fixture_gate_with_grant(fixture_grant("grant:covered"));

let outcome = registry.admit_optic_invocation_with_capability_validator(&invocation, &mut gate);

assert_eq!(
obstruction_for(&outcome),
OpticInvocationObstruction::UnsupportedApertureResolution
);
assert!(matches!(
latest_invocation_obstruction_fact(&registry)?,
GraphFact::OpticInvocationObstructed {
basis_request_digest,
obstruction,
..
} if *basis_request_digest == digest_invocation_request_bytes(
b"echo.optic-invocation.basis-request.v0",
b"basis-request:resolved-fixture:v0"
)
&& *obstruction == InvocationObstructionKind::UnsupportedApertureResolution
));
Ok(())
}

#[test]
fn invocation_obstruction_fact_is_not_counterfactual_candidate() -> Result<(), String> {
let (mut registry, handle) = fixture_registry_and_handle()?;
Expand Down
97 changes: 56 additions & 41 deletions docs/design/optic-admission-ladder-checkpoint.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,22 @@

# Optic Admission Ladder Checkpoint

Status: checkpoint.
Scope: documentation-only refusal ladder before BasisResolution v0.
Status: BasisResolution v0 boundary checkpoint.
Scope: refusal ladder with one narrow controlled basis-resolution fixture.

## Doctrine

This checkpoint records the optic invocation admission ladder exactly at the
last refusal-only boundary.
This checkpoint records the optic invocation admission ladder at the first
controlled basis-resolution boundary.

Echo can now explain why an optic invocation is refused, but it cannot yet admit
one. There is no successful admission path in this checkpoint.

A registered artifact handle is not authority. A capability presentation slot is
not a validated grant. A basis request is not a resolved basis. An aperture
request is not a resolved scope. A budget request is not spendable runtime
capacity.
not a validated grant. A basis request is not a resolved basis unless it matches
the narrow deterministic BasisResolution v0 fixture. A resolved basis is not
permission to act. An aperture request is not a resolved scope. A budget request
is not spendable runtime capacity.

Refusal is causal evidence. Refusal is not admission, not execution, not a law
witness, and not a counterfactual candidate.
Expand All @@ -34,34 +35,40 @@ The current optic invocation admission path evaluates checks in this order:
6. Require budget request presence.
7. Classify capability presentation posture.
8. Optionally publish grant-validation obstruction evidence.
9. Obstruct identity-covered material at unsupported basis resolution.
10. Publish the invocation obstruction fact.
9. If capability validation returns identity-covered material, resolve the
narrow BasisResolution v0 fixture or obstruct unsupported basis material.
10. If that basis fixture resolves, obstruct before aperture resolution.
11. Publish the invocation obstruction fact.

Presence checks come before resolution checks. Basis resolution gates aperture
resolution. Aperture resolution gates budget evaluation and runtime support
checks.
checks. BasisResolution v0 accepts exactly one deterministic fixture shape:
`basis-request:resolved-fixture:v0`.

## Obstruction reachability

| Obstruction | Reachability | Meaning |
| :-------------------------------- | :---------------- | :--------------------------------------------------------------------------------------------------------- |
| `UnknownHandle` | Reachable today | Echo cannot resolve the runtime-local artifact handle. |
| `OperationMismatch` | Reachable today | The invocation operation does not match registered artifact metadata. |
| `MissingBasisRequest` | Reachable today | The caller did not provide basis request material. |
| `MissingApertureRequest` | Reachable today | Basis material is present, but aperture request material is absent. |
| `MissingBudgetRequest` | Reachable today | Basis and aperture material are present, but budget request material is absent. |
| `MissingCapability` | Reachable today | Required invocation context is present, but no capability presentation was supplied. |
| `MalformedCapabilityPresentation` | Reachable today | Capability presentation material is present but not structurally usable. |
| `UnboundCapabilityPresentation` | Reachable today | Capability presentation material is structurally usable but not bound to the invocation. |
| `CapabilityValidationUnavailable` | Reachable today | Presentation material is identity-covered, but real grant validation does not exist yet. |
| `UnsupportedBasisResolution` | Reachable today | Identity-covered material reaches the resolution boundary, but lawful basis resolution does not exist yet. |
| `UnsupportedApertureResolution` | Future vocabulary | Must remain unreachable until lawful basis resolution exists. |
| `UnsupportedBudgetResolution` | Future vocabulary | Must remain unreachable until lawful basis and aperture resolution exist. |
| `RuntimeSupportUnavailable` | Future vocabulary | Must remain unreachable until lawful basis, aperture, and budget resolution exist. |

`UnsupportedApertureResolution`, `UnsupportedBudgetResolution`, and
`RuntimeSupportUnavailable` are deliberately defined but not lawfully reachable
at this checkpoint.
| Obstruction | Reachability | Meaning |
| :-------------------------------- | :---------------- | :------------------------------------------------------------------------------------------------------- |
| `UnknownHandle` | Reachable today | Echo cannot resolve the runtime-local artifact handle. |
| `OperationMismatch` | Reachable today | The invocation operation does not match registered artifact metadata. |
| `MissingBasisRequest` | Reachable today | The caller did not provide basis request material. |
| `MissingApertureRequest` | Reachable today | Basis material is present, but aperture request material is absent. |
| `MissingBudgetRequest` | Reachable today | Basis and aperture material are present, but budget request material is absent. |
| `MissingCapability` | Reachable today | Required invocation context is present, but no capability presentation was supplied. |
| `MalformedCapabilityPresentation` | Reachable today | Capability presentation material is present but not structurally usable. |
| `UnboundCapabilityPresentation` | Reachable today | Capability presentation material is structurally usable but not bound to the invocation. |
| `CapabilityValidationUnavailable` | Reachable today | A bound presentation exists, but no successful validation or admission has occurred yet. |
| `UnsupportedBasisResolution` | Reachable today | Identity-covered material reaches the basis boundary, but the basis shape is outside BasisResolution v0. |
| `UnsupportedApertureResolution` | Reachable today | BasisResolution v0 succeeded, but aperture resolution does not exist yet. |
| `UnsupportedBudgetResolution` | Future vocabulary | Must remain unreachable until lawful basis and aperture resolution exist. |
| `RuntimeSupportUnavailable` | Future vocabulary | Must remain unreachable until lawful basis, aperture, and budget resolution exist. |

`UnsupportedBudgetResolution` and `RuntimeSupportUnavailable` are deliberately
defined but not lawfully reachable at this checkpoint.

`UnsupportedApertureResolution` is reachable only after the exact
BasisResolution v0 fixture resolves. For identity-covered material, unsupported
basis shapes must still stop at `UnsupportedBasisResolution`.

## Non-behavior

Expand All @@ -79,31 +86,39 @@ This checkpoint does not introduce:
- runtime support enforcement
- budget reservation
- aperture resolution
- basis resolution

The system remains obstruction-first. It records refusal; it does not authorize
work.

## Next transition point
## BasisResolution v0

BasisResolution v0 is not general basis resolution. It recognizes exactly one
deterministic fixture shape:

```text
basis-request:resolved-fixture:v0
```

The next transition point is BasisResolution v0.
Resolving that fixture establishes only the causal state under evaluation. It
does not create authority, admission, aperture scope, budget capacity, runtime
support, scheduler work, or execution.

## Next transition point

BasisResolution v0 is the first controlled resolved-state boundary. It is the
first place where Echo may start saying something stronger than refusal about a
requested invocation context.
The next transition point is ApertureResolution v0.

That transition must be narrow and explicit. It must not imply successful
admission, aperture resolution, budget spendability, runtime support, execution,
or authority validation.
admission, budget spendability, runtime support, execution, or authority
validation.

## Tripwire

If a future slice makes `UnsupportedApertureResolution`,
`UnsupportedBudgetResolution`, or `RuntimeSupportUnavailable` reachable before a
lawful basis resolution boundary exists, the admission ladder is wrong.
If a future slice makes `UnsupportedBudgetResolution` or
`RuntimeSupportUnavailable` reachable before a lawful aperture resolution
boundary exists, the admission ladder is wrong.

If a future slice introduces a successful admission path before a resolved basis,
resolved aperture, evaluated budget, runtime support check, and validated grant
exist, the admission ladder is wrong.

This is the final refusal-only checkpoint before controlled resolved state.
BasisResolution v0 is controlled resolved state, not admission.
Loading