Establishes the tasks/architecture/ blocker-task half of the Safe Exit protocol. Each deferred OQ now has an external-trigger tracker task representing its unblocking condition, and the OQ's Blocked on field names the tracker task ID — closing the gap where the deferral field existed but the task-graph half was unenforced. Changes: - Add 6 external-trigger tracker tasks for the deferred OQs (OQ-09, 10, 32, 41, 44, 46) under tasks/architecture/, tagged [external-trigger, deferred-oq] - Add structured Blocked on field to OQ-09 and OQ-10 (previously used legacy 'deferred' status with the reason in the Resolution prose); index now surfaces all 6 deferred OQs with concrete conditions, no placeholders - Document the architecture-task level mapping (level: implementation for ADRs/specs, decomposition for spec-to-ADR breakdown, planning for backlog seeding, research/review direct fits) and the deferred-OQ blocker-task pattern in docs/sdd_process.md - Mark architecture/safe-exit-blocker-task-mechanism and architecture/oq-09-10-blocking-conditions completed (implemented by this pass) - Fix 4 pre-existing ADR-050 implementation tasks: status: done → completed (taskgraph enum is 'completed', not 'done') — taskgraph validate now passes for all 100 tasks
3.8 KiB
id, name, status, depends_on, scope, risk, impact, level
| id | name | status | depends_on | scope | risk | impact | level |
|---|---|---|---|---|---|---|---|
| call/registry/operation-spec-resource-id-path | Add resource_id_path field to OperationSpec (ADR-050 §2a) | completed | single | low | component | implementation |
Description
Add a resource_id_path: Option<String> field to OperationSpec. This is
a JSON pointer into the operation input that tells the dispatcher where to
find the resource ID for runtime-spawned resource authorization. Per ADR-050
§2a.
The field
pub struct OperationSpec {
pub name: String,
pub namespace: String,
pub op_type: OperationType,
pub visibility: Visibility,
pub input_schema: Value,
pub output_schema: Value,
pub error_schemas: Vec<ErrorDefinition>,
pub access_control: AccessControl,
/// JSON pointer into the input for the resource ID, when
/// `access_control.resource_type` is set and the operation targets a
/// specific runtime-spawned resource (ADR-050). e.g., `"$.containerId"`
/// for `docker/container/exec`. Absent for no-specific-resource
/// operations (the `list` case). `None` for operations with no
/// `resource_type` or with static resource sets.
pub resource_id_path: Option<String>,
}
Construction
OperationSpec::new(...) currently takes 7 arguments (name, op_type,
visibility, input_schema, output_schema, error_schemas, access_control).
This task adds resource_id_path as an 8th argument. Since all
construction sites need to update, consider whether a builder pattern is
worth introducing — but for now, add it as the last positional argument
(defaulting to None at call sites that don't need it).
What this task does NOT do
- Does NOT change
AccessControl::check— that'scall/registry/access-control-ownership-check, which depends oncore/ownership-store-trait. - Does NOT extract the resource ID from input or pass it to
check— that'scall/registry/dispatch-resource-id-extraction, which depends on this task. - This task only adds the field to the struct, updates
new(), and updates all existing construction sites + tests.
Existing construction sites
Search for OperationSpec::new( across the codebase — every call site
needs the new argument added. Most will pass None (no runtime-spawned
resources). The existing tests in spec.rs construct OperationSpec
without resource_id_path — they all need the None argument added.
Acceptance Criteria
OperationSpecstruct hasresource_id_path: Option<String>fieldOperationSpec::new(...)takesresource_id_pathas the 8th argument- All existing
OperationSpec::new(...)call sites updated (most passNone) - All existing tests that construct
OperationSpecupdated - Existing tests still pass (no semantic change —
Nonemeans "no resource ID extraction") - Unit test:
resource_id_pathisNoneby default when not specified cargo test -p alknet-callsucceedscargo clippy -p alknet-callsucceeds with no warnings
References
- docs/architecture/crates/call/operation-registry.md — OperationSpec (updated with
resource_id_path) - docs/architecture/decisions/050-dynamic-resource-ownership-for-runtime-spawned-resources.md — ADR-050 §2a
- crates/alknet-call/src/registry/spec.rs — current OperationSpec struct
Notes
The fit with JSON Schema is load-bearing:
input_schemais already a JSON Schema, soresource_id_pathis a pointer within an existing schema on the same spec. TheOperationSpecbecomes fully self-describing for authorization — what resource type, what action, and which input field drives the resource lookup. This is a single field addition with no semantic change — existing call sites passNoneand behave exactly as before. The field is consumed by the dispatch path incall/registry/dispatch-resource-id-extraction.