tasks(arch): adopt taskgraph for architecture work — blocker tasks for deferred OQs, level mapping, status fixes
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
This commit is contained in:
1 parent
e6062230f9
commit
df5d04af1d
16 files changed
+440
-14
No files matched your search
@@ -160,13 +160,13 @@ filtering the tables above.
|
||||
|
||||
### OQ-09: WASM Target Boundaries
|
||||
|
||||
- **Blocked on**: _(no explicit blocking condition recorded — see full file)_
|
||||
- **Blocked on**: A concrete server-side WASM use case, or a deliberate confirmation that WASM stays a client-side design constraint. Tracked as `architecture/oq-09-wasm-server-use-case` in `tasks/architecture/`.
|
||||
- **Priority**: low
|
||||
- **Full file**: [OQ-09](questions/009-wasm-target-boundaries.md)
|
||||
|
||||
### OQ-10: Git Adapter Scope — Smart Protocol Only or Full Server?
|
||||
|
||||
- **Blocked on**: _(no explicit blocking condition recorded — see full file)_
|
||||
- **Blocked on**: Speccing the alknet-git crate — resolve this when that crate is specified, not deferred past it. Tracked as `architecture/oq-10-git-adapter-spec` in `tasks/architecture/`.
|
||||
- **Priority**: low
|
||||
- **Full file**: [OQ-10](questions/010-git-adapter-scope-smart-protocol-only-or-full-server.md)
|
||||
|
||||
|
||||
@@ -4,5 +4,6 @@
|
||||
- **Status**: deferred
|
||||
- **Door type**: One-way (when applicable)
|
||||
- **Priority**: low
|
||||
- **Blocked on**: A concrete server-side WASM use case, or a deliberate confirmation that WASM stays a client-side design constraint. Tracked as `architecture/oq-09-wasm-server-use-case` in `tasks/architecture/`.
|
||||
- **Resolution**: Not an active question — WASM compatibility is a design constraint (see ADR-009, overview.md design principles), not a deliverable. Specific WASM targeting decisions will be made when individual crates are implemented. **BiStream being a trait preserves the *client-side* stream door** — a browser can implement BiStream over WebTransport streams. **The *server-side* dispatch door is NOT preserved by ADR-007 and is a known, accepted closure**: `Connection` is a concrete quinn-bound struct (not a trait), the accept loop uses `tokio::spawn` (tokio does not run on WASM), and the call-protocol dispatch internals (`PendingRequestMap`, `CallAdapter`) use tokio `oneshot`/`mpsc` channels. A WASM server-side peer would require a `Connection` trait and a runtime-abstracted accept loop — not planned. The browser path is client-side via a JS SDK, not server-side Rust-to-WASM. This is an explicit one-way door, not an oversight.
|
||||
- **Cross-references**: ADR-007, ADR-009
|
||||
+1
@@ -4,5 +4,6 @@
|
||||
- **Status**: deferred
|
||||
- **Door type**: Two-way
|
||||
- **Priority**: low
|
||||
- **Blocked on**: Speccing the alknet-git crate — resolve this when that crate is specified, not deferred past it. Tracked as `architecture/oq-10-git-adapter-spec` in `tasks/architecture/`.
|
||||
- **Resolution**: Deferred per the cleanup plan. Start with git smart protocol over QUIC streams. ERC721 integration and full server capabilities are additive. **Composability fork (review #002 W18)**: whether git operations are registered in the `OperationRegistry` and callable via `env.invoke()`, or only available as raw smart protocol on `alknet/git`, is a separate decision from ERC721 scope. The path of least resistance (raw smart protocol only) forecloses agent composition of git operations — an agent handler that wants to compose `git/clone` cannot, because there's no `OperationSpec`, no `Handler`, no registration. To make git composable, a call-protocol projection (a set of `HandlerRegistration` bundles wrapping git operations behind the registry) must be built alongside or instead of the raw handler. Resolve this when speccing alknet-git, not deferred past it.
|
||||
- **Cross-references**: ADR-001
|
||||
@@ -420,6 +420,27 @@ cost-benefit framework in taskgraph's framework docs for the reasoning.
|
||||
2. Fills in `## Summary` section
|
||||
3. Commits changes to worktree branch
|
||||
|
||||
### Architecture work and the `level` field
|
||||
|
||||
Architecture work uses the same taskgraph format as implementation work —
|
||||
there is no separate `architecture` level. The `level` enum
|
||||
(`planning, decomposition, implementation, review, research`) already covers
|
||||
architecture activities:
|
||||
|
||||
| Architecture activity | `level` | Rationale |
|
||||
|---|---|---|
|
||||
| Writing an ADR (the decision) | `implementation` | The ADR *is* the deliverable — the implementation of an architecture decision. Calling it `planning` would mislabel the artifact. |
|
||||
| Decomposing a spec into ADRs + OQs | `decomposition` | Direct fit — breaking a large architecture area into decideable units. |
|
||||
| Architecture review pass | `review` | Direct fit. |
|
||||
| Research / POC before a decision | `research` | Direct fit. |
|
||||
| Spec writing (overview, component spec) | `implementation` | The spec is the deliverable. |
|
||||
| Seeding a backlog of OQs/ADRs for a crate | `planning` | The upfront graph-shaping pass. |
|
||||
|
||||
Architecture tasks live under `tasks/architecture/` and use the standard
|
||||
task body sections (`## Description`, `## Work`, `## Verification`,
|
||||
`## Out of scope`). The `## Summary` section is filled on completion, same as
|
||||
implementation tasks.
|
||||
|
||||
## Safe Exit Protocol
|
||||
|
||||
When a task becomes untendable:
|
||||
@@ -445,6 +466,33 @@ When a task becomes untendable:
|
||||
3. Document in task notes
|
||||
4. Notify coordinator
|
||||
|
||||
### Deferred OQs and the blocker-task half
|
||||
|
||||
The Safe Exit protocol applies to architecture decisions too, not just
|
||||
implementation tasks. When an open question (OQ) is marked `deferred(scope)`,
|
||||
the deferral has two halves that must stay in sync:
|
||||
|
||||
1. **The visibility half** (in `docs/architecture/`): the OQ's `Blocked on:`
|
||||
field names the concrete blocking condition, and the `open-questions.md`
|
||||
index surfaces it in the cross-theme **Deferred / Blocked** section so
|
||||
"what's currently parked and why" is answerable at a glance. This is the
|
||||
human-readable surface for the architect.
|
||||
2. **The machine-readable half** (in `tasks/architecture/`): an
|
||||
external-trigger tracker task represents the unblocking condition. It is
|
||||
tagged `[external-trigger, deferred-oq]`, has `risk: trivial` and
|
||||
`level: research` (it is not actionable work — it tracks whether the
|
||||
external condition has arrived), and its `id` is referenced from the OQ's
|
||||
`Blocked on:` text. This is the surface for the task graph: `taskgraph`
|
||||
tools can reason about it, and downstream work that depends on the
|
||||
decision can declare `depends_on: [architecture/oq-NN-...]`.
|
||||
|
||||
When the unblocking condition arrives (a use case materializes, a crate is
|
||||
specced), the tracker task is marked `completed` and the OQ transitions from
|
||||
`deferred(scope)` to `open` (or directly to `resolved` if no architecture
|
||||
decision remains). The two halves serve different audiences and use one edge
|
||||
type (`depends_on`) — the reverse lookup uses `taskgraph dependents`. Do not
|
||||
add a `blocks:` field; it duplicates the edge and creates a sync hazard.
|
||||
|
||||
## Review Injection
|
||||
|
||||
Use graph analysis to determine where reviews should happen:
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
---
|
||||
id: architecture/oq-09-10-blocking-conditions
|
||||
name: Add explicit Blocked on conditions to OQ-09 (WASM) and OQ-10 (Git Adapter)
|
||||
status: pending
|
||||
status: completed
|
||||
depends_on: []
|
||||
scope: narrow
|
||||
risk: low
|
||||
impact: component
|
||||
level: decomposition
|
||||
tags: [convention]
|
||||
---
|
||||
|
||||
## Description
|
||||
@@ -39,8 +40,20 @@ Either:
|
||||
The decision content stays unchanged — this is a metadata-structure fix, not a
|
||||
re-resolution.
|
||||
|
||||
## Summary
|
||||
|
||||
Completed alongside `architecture/safe-exit-blocker-task-mechanism`. Added a
|
||||
structured `Blocked on:` field to both OQ-09 and OQ-10 in their per-OQ files,
|
||||
each pointing at its new external-trigger tracker task
|
||||
(`architecture/oq-09-wasm-server-use-case`,
|
||||
`architecture/oq-10-git-adapter-spec`). Kept the legacy `deferred` status
|
||||
rather than reframing to `deferred(scope)` — the distinction is no longer
|
||||
load-bearing now that both have explicit blocking conditions and tracker
|
||||
tasks. The `open-questions.md` Deferred/Blocked section now surfaces all six
|
||||
deferred OQs with concrete conditions inline — no placeholders remain.
|
||||
|
||||
## Verification
|
||||
|
||||
The "Deferred / Blocked" section of `docs/architecture/open-questions.md` should
|
||||
show a concrete blocking condition for OQ-09 and OQ-10 instead of the "no
|
||||
The "Deferred / Blocked" section of `docs/architecture/open-questions.md`
|
||||
shows a concrete blocking condition for OQ-09 and OQ-10 instead of the "no
|
||||
explicit blocking condition recorded" placeholder.
|
||||
@@ -0,0 +1,58 @@
|
||||
---
|
||||
id: architecture/oq-09-wasm-server-use-case
|
||||
name: External trigger — a concrete server-side WASM use case (or confirmation it stays a client-side constraint)
|
||||
status: pending
|
||||
depends_on: []
|
||||
scope: single
|
||||
risk: trivial
|
||||
impact: component
|
||||
level: research
|
||||
tags: [external-trigger, deferred-oq]
|
||||
---
|
||||
|
||||
## Description
|
||||
|
||||
External-trigger tracker for [OQ-09](../docs/architecture/questions/009-wasm-target-boundaries.md)
|
||||
(WASM Target Boundaries). This is **not actionable work** — it tracks whether
|
||||
a concrete server-side WASM use case has emerged, or whether the project
|
||||
confirms that WASM compatibility remains a *client-side* design constraint
|
||||
only (a browser can implement BiStream over WebTransport streams; the
|
||||
server-side dispatch door is a known, accepted closure per ADR-007/009).
|
||||
|
||||
## Trigger condition
|
||||
|
||||
Either:
|
||||
- **A concrete server-side WASM use case arrives** (a deployment that wants
|
||||
to run an alknet server peer compiled to WASM, which would require a
|
||||
`Connection` trait and a runtime-abstracted accept loop — currently not
|
||||
planned), or
|
||||
- **A deliberate confirmation** that WASM stays a client-side design
|
||||
constraint, at which point OQ-09 transitions from `deferred` to `resolved`
|
||||
with the accepted-closure framing already in its Resolution text.
|
||||
|
||||
The second path is the more likely one — the OQ exists mainly so the
|
||||
server-side WASM door closure is documented rather than implicit.
|
||||
|
||||
## What unblocking looks like
|
||||
|
||||
When a decision is made (either direction):
|
||||
|
||||
1. Mark this task `status: completed`.
|
||||
2. Move [OQ-09](../docs/architecture/questions/009-wasm-target-boundaries.md)
|
||||
from `deferred` to either `resolved` (client-side-only confirmed) or `open`
|
||||
(server-side use case arrives, requiring a Connection trait + WASM runtime
|
||||
abstraction ADR).
|
||||
|
||||
## Why this is a task, not just an OQ field
|
||||
|
||||
OQ-09 predates the formalized `deferred(scope)` + blocking-condition pattern
|
||||
and lacked a structured `Blocked on:` field (it used the legacy `deferred`
|
||||
status with the deferral reason in the Resolution prose). This task
|
||||
formalizes the blocking condition and gives the OQ a machine-readable
|
||||
presence in the task graph.
|
||||
|
||||
## Verification
|
||||
|
||||
This task is "completed" when either a server-side WASM use case arrives
|
||||
(move OQ-09 to `open`) or the client-side-only constraint is confirmed
|
||||
(move OQ-09 to `resolved`).
|
||||
@@ -0,0 +1,56 @@
|
||||
---
|
||||
id: architecture/oq-10-git-adapter-spec
|
||||
name: External trigger — speccing alknet-git (resolve OQ-10 when that crate is specified, not deferred past it)
|
||||
status: pending
|
||||
depends_on: []
|
||||
scope: single
|
||||
risk: trivial
|
||||
impact: component
|
||||
level: research
|
||||
tags: [external-trigger, deferred-oq]
|
||||
---
|
||||
|
||||
## Description
|
||||
|
||||
External-trigger tracker for [OQ-10](../docs/architecture/questions/010-git-adapter-scope-smart-protocol-only-or-full-server.md)
|
||||
(Git Adapter Scope — Smart Protocol Only or Full Server?). This is **not
|
||||
actionable work** — it tracks when the alknet-git crate is being specified,
|
||||
at which point OQ-10 must be resolved (not deferred past it).
|
||||
|
||||
## Trigger condition
|
||||
|
||||
The alknet-git crate is being specified. The OQ's Resolution text already
|
||||
states: "Resolve this when speccing alknet-git, not deferred past it." The
|
||||
two sub-questions:
|
||||
|
||||
1. **Git adapter scope** — start with git smart protocol over QUIC streams;
|
||||
ERC721 integration and full server capabilities are additive.
|
||||
2. **Composability fork** — whether git operations are registered in the
|
||||
`OperationRegistry` and callable via `env.invoke()`, or only available as
|
||||
raw smart protocol on `alknet/git`. The path of least resistance (raw
|
||||
smart protocol only) forecloses agent composition of git operations; to
|
||||
make git composable, a call-protocol projection (a set of
|
||||
`HandlerRegistration` bundles wrapping git operations behind the
|
||||
registry) must be built alongside or instead of the raw handler.
|
||||
|
||||
## What unblocking looks like
|
||||
|
||||
When alknet-git is specced:
|
||||
|
||||
1. Mark this task `status: completed`.
|
||||
2. Move [OQ-10](../docs/architecture/questions/010-git-adapter-scope-smart-protocol-only-or-full-server.md)
|
||||
from `deferred` to `open`, then resolve it as part of the alknet-git spec
|
||||
pass (the Resolution text is explicit: do not defer past the spec).
|
||||
|
||||
## Why this is a task, not just an OQ field
|
||||
|
||||
OQ-10 predates the formalized `deferred(scope)` + blocking-condition pattern
|
||||
and lacked a structured `Blocked on:` field (it used the legacy `deferred`
|
||||
status with the deferral reason in the Resolution prose). This task
|
||||
formalizes the blocking condition and gives the OQ a machine-readable
|
||||
presence in the task graph.
|
||||
|
||||
## Verification
|
||||
|
||||
This task is "completed" when alknet-git is being specced and OQ-10 has been
|
||||
moved to `open` (then resolved as part of that spec pass).
|
||||
@@ -0,0 +1,53 @@
|
||||
---
|
||||
id: architecture/oq-32-multihop-use-case
|
||||
name: External trigger — a concrete multi-hop federation use case
|
||||
status: pending
|
||||
depends_on: []
|
||||
scope: single
|
||||
risk: trivial
|
||||
impact: component
|
||||
level: research
|
||||
tags: [external-trigger, deferred-oq]
|
||||
---
|
||||
|
||||
## Description
|
||||
|
||||
External-trigger tracker for [OQ-32](../docs/architecture/questions/032-multi-hop-federation.md)
|
||||
(Multi-Hop Federation). This is **not actionable work** — it tracks whether a
|
||||
concrete use case for multi-hop federation has arrived. When it does, mark this
|
||||
task `completed` and the OQ moves from `deferred(scope)` to `open`.
|
||||
|
||||
## Trigger condition
|
||||
|
||||
A concrete deployment or use case that requires transitive op discovery across
|
||||
more than one hop — i.e., worker A needs to reach worker B's ops *through* the
|
||||
head, where the head is not explicitly re-exporting them. The one-hop model
|
||||
(head→worker, runner→hub) covers all current use cases.
|
||||
|
||||
## What unblocking looks like
|
||||
|
||||
When a use case arrives:
|
||||
|
||||
1. Mark this task `status: completed`.
|
||||
2. Move [OQ-32](../docs/architecture/questions/032-multi-hop-federation.md)
|
||||
from `deferred(scope)` to `open` (update the Status field + the
|
||||
`open-questions.md` index tables + Deferred/Blocked section).
|
||||
3. Create an architecture task to write the multi-hop federation ADR — the
|
||||
peer-keyed overlay model extends to multi-hop without redesign (ADR-029 §3.7),
|
||||
but path-finding (which peer reaches which op transitively) is where the
|
||||
design work lives. A graph library (petgraph) may pay off for multi-hop; for
|
||||
one-hop, a nested `HashMap<PeerId, HashMap<String, ...>>` suffices.
|
||||
|
||||
## Why this is a task, not just an OQ field
|
||||
|
||||
The OQ's `Blocked on:` field in `open-questions.md` is the human-readable
|
||||
visibility surface ("what's parked and why"). This task is the machine-readable
|
||||
half: it lives in the task graph so `taskgraph` tools can reason about it, and
|
||||
so downstream work that depends on multi-hop being resolved can declare
|
||||
`depends_on: [architecture/oq-32-multihop-use-case]`.
|
||||
|
||||
## Verification
|
||||
|
||||
This task is "completed" when a concrete multi-hop use case is documented
|
||||
(e.g., in a research finding or deployment note) and OQ-32 has been moved to
|
||||
`open`.
|
||||
@@ -0,0 +1,66 @@
|
||||
---
|
||||
id: architecture/oq-41-stream-operators-use-case
|
||||
name: External trigger — a handler that needs stream operators beyond existing combinators
|
||||
status: pending
|
||||
depends_on: []
|
||||
scope: single
|
||||
risk: trivial
|
||||
impact: component
|
||||
level: research
|
||||
tags: [external-trigger, deferred-oq]
|
||||
---
|
||||
|
||||
## Description
|
||||
|
||||
External-trigger tracker for [OQ-41](../docs/architecture/questions/041-stream-operators-library.md)
|
||||
(Stream Operators Library). This is **not actionable work** — it tracks
|
||||
whether a handler has emerged that needs stream operators (filter, map, batch,
|
||||
dedupe, window, etc. on `BoxStream<T>`) and finds the existing combinators
|
||||
insufficient. The operators library is a convenience, not a prerequisite for
|
||||
any handler.
|
||||
|
||||
## Trigger condition
|
||||
|
||||
A handler that transforms subscription streams (`BoxStream<ResponseEnvelope>`)
|
||||
and finds `Box::pin(stream::iter(...))`, `async_stream::stream!`, and
|
||||
`futures::stream` combinators insufficient — i.e., the handler code is
|
||||
demonstrably boilerplate-heavy for stream manipulation that the operators
|
||||
library would collapse. The architectural decision (stream composition is
|
||||
handler-level, not protocol-level) is already made in ADR-049; this tracks the
|
||||
*implementation* of the utility library.
|
||||
|
||||
## What unblocking looks like
|
||||
|
||||
When a handler needs the operators:
|
||||
|
||||
1. Mark this task `status: completed`.
|
||||
2. Move [OQ-41](../docs/architecture/questions/041-stream-operators-library.md)
|
||||
from `deferred(scope)` to `resolved` (the architectural decision is already
|
||||
made — ADR-049; what remains is the implementation, which is scheduling
|
||||
work). The OQ may transition directly to `resolved` rather than `open`,
|
||||
since no architecture decision remains.
|
||||
3. Implement the operators library (no ADR needed — internal utility code
|
||||
that doesn't cross crate boundaries as a contract; an ADR would be
|
||||
warranted only if the operators become part of a public API surface, e.g.,
|
||||
a handler-registration DSL that references operator names).
|
||||
|
||||
## Why this is a task, not just an OQ field
|
||||
|
||||
The OQ's `Blocked on:` field in `open-questions.md` is the human-readable
|
||||
visibility surface. This task is the machine-readable half: it lives in the
|
||||
task graph so `taskgraph` tools can reason about it, and so a handler that
|
||||
needs the operators can declare `depends_on:
|
||||
[architecture/oq-41-stream-operators-use-case]`.
|
||||
|
||||
## Prior art
|
||||
|
||||
`@alkdev/pubsub/src/operators.ts` — 13 operators (`filter`, `map`, `take`,
|
||||
`batch`, `dedupe`, `window`, `chain`, `join`, `reduce`, `groupBy`, `flat`,
|
||||
`pipe`, `toArray`) on `AsyncIterable<T>`, forked from graphql-yoga's
|
||||
subscription implementation. The Rust analogue would provide the same set on
|
||||
`BoxStream<T>` / `impl Stream<Item = T>`.
|
||||
|
||||
## Verification
|
||||
|
||||
This task is "completed" when a handler is identified that needs the operators
|
||||
and OQ-41 has been moved to `resolved`.
|
||||
@@ -0,0 +1,51 @@
|
||||
---
|
||||
id: architecture/oq-44-tty-modes-use-case
|
||||
name: External trigger — a concrete TTY mode-control use case
|
||||
status: pending
|
||||
depends_on: []
|
||||
scope: single
|
||||
risk: trivial
|
||||
impact: component
|
||||
level: research
|
||||
tags: [external-trigger, deferred-oq]
|
||||
---
|
||||
|
||||
## Description
|
||||
|
||||
External-trigger tracker for [OQ-44](../docs/architecture/questions/044-terminal-modes-tty-modes.md)
|
||||
(Terminal Modes / TTY modes). This is **not actionable work** — it tracks
|
||||
whether a concrete deployment has emerged that needs to set TTY modes (echo,
|
||||
raw, canonical, etc.) on a PTY beyond the backend's defaults.
|
||||
|
||||
## Trigger condition
|
||||
|
||||
A concrete deployment that needs to control TTY modes beyond the defaults the
|
||||
backends already provide (`portable_pty`, docker `tty: true`, russh
|
||||
`pty_request` all have defaults that work for the common terminal case). The
|
||||
`modes` field in `TerminalParams` is `serde_json::Value` (reserved as `{}` in
|
||||
v1) for when this arrives.
|
||||
|
||||
## What unblocking looks like
|
||||
|
||||
When a mode-control use case arrives:
|
||||
|
||||
1. Mark this task `status: completed`.
|
||||
2. Move [OQ-44](../docs/architecture/questions/044-terminal-modes-tty-modes.md)
|
||||
from `deferred(scope)` to `open`.
|
||||
3. Specify the `modes` JSON shape (SSH's `pty_request` carries TTY modes as a
|
||||
packed bitmask; the Rust analogue extends the `modes` field). Adding mode
|
||||
control is additive (extend the `modes` JSON shape) and does not break
|
||||
downstream — the architectural commitment is two-way-door.
|
||||
|
||||
## Why this is a task, not just an OQ field
|
||||
|
||||
The OQ's `Blocked on:` field in `open-questions.md` is the human-readable
|
||||
visibility surface. This task is the machine-readable half: it lives in the
|
||||
task graph so `taskgraph` tools can reason about it, and so downstream work
|
||||
that depends on TTY mode control can declare `depends_on:
|
||||
[architecture/oq-44-tty-modes-use-case]`.
|
||||
|
||||
## Verification
|
||||
|
||||
This task is "completed" when a concrete mode-control use case is documented
|
||||
and OQ-44 has been moved to `open`.
|
||||
@@ -0,0 +1,52 @@
|
||||
---
|
||||
id: architecture/oq-46-runner-policy-use-case
|
||||
name: External trigger — a concrete runner-policy use case that forces the API surface
|
||||
status: pending
|
||||
depends_on: []
|
||||
scope: single
|
||||
risk: trivial
|
||||
impact: component
|
||||
level: research
|
||||
tags: [external-trigger, deferred-oq]
|
||||
---
|
||||
|
||||
## Description
|
||||
|
||||
External-trigger tracker for [OQ-46](../docs/architecture/questions/046-runner-api-surface.md)
|
||||
(Runner API Surface). This is **not actionable work** — it tracks whether a
|
||||
concrete runner-policy use case has emerged that forces the API surface (job
|
||||
management, log persistence, task graph integration). The runner *mechanism*
|
||||
(pipe mode) is already in alknet-tty (ADR-054); the runner *policy* is a
|
||||
downstream crate's job.
|
||||
|
||||
## Trigger condition
|
||||
|
||||
A concrete deployment that needs runner *policy* — job management, log
|
||||
persistence, task graph integration — on top of the pipe-mode mechanism
|
||||
(`TtyParams.terminal = None` → `std::process::Command` with piped stdio →
|
||||
framed byte stream + exit code) that alknet-tty already provides.
|
||||
|
||||
## What unblocking looks like
|
||||
|
||||
When a runner-policy use case arrives:
|
||||
|
||||
1. Mark this task `status: completed`.
|
||||
2. Move [OQ-46](../docs/architecture/questions/046-runner-api-surface.md)
|
||||
from `deferred(scope)` to `open`.
|
||||
3. Decide whether a runner-policy crate (e.g., an `alknet-runner` crate that
|
||||
builds on the pipe mode + the wire format to provide job management) is
|
||||
needed, and what its API surface would be. The mechanism is preserved
|
||||
regardless of the policy decision.
|
||||
|
||||
## Why this is a task, not just an OQ field
|
||||
|
||||
The OQ's `Blocked on:` field in `open-questions.md` is the human-readable
|
||||
visibility surface. This task is the machine-readable half: it lives in the
|
||||
task graph so `taskgraph` tools can reason about it, and so downstream work
|
||||
that depends on runner policy can declare `depends_on:
|
||||
[architecture/oq-46-runner-policy-use-case]`.
|
||||
|
||||
## Verification
|
||||
|
||||
This task is "completed" when a concrete runner-policy use case is documented
|
||||
and OQ-46 has been moved to `open`.
|
||||
@@ -1,12 +1,13 @@
|
||||
---
|
||||
id: architecture/safe-exit-blocker-task-mechanism
|
||||
name: Establish the tasks/architecture/ blocker-task half of the Safe Exit protocol
|
||||
status: pending
|
||||
status: completed
|
||||
depends_on: []
|
||||
scope: moderate
|
||||
risk: low
|
||||
impact: project
|
||||
level: planning
|
||||
tags: [convention]
|
||||
---
|
||||
|
||||
## Description
|
||||
@@ -58,6 +59,30 @@ it").
|
||||
role spec) so future deferrals create the blocker task as part of the Safe
|
||||
Exit step.
|
||||
|
||||
## Summary
|
||||
|
||||
Completed in the July 2026 architecture-task pass. Decisions:
|
||||
|
||||
- **Format**: adopted the existing taskgraph frontmatter verbatim — no new
|
||||
`blocks:` field. One edge type (`depends_on`) keeps the graph simple; the
|
||||
reverse lookup uses `taskgraph dependents`. The OQ's `Blocked on:` text is
|
||||
the human-readable pointer; the task `depends_on` is the machine-readable
|
||||
edge. They serve different audiences (architect vs. planner/agent).
|
||||
- **External-trigger tasks**: the four `deferred(scope)` OQs (32, 41, 44, 46)
|
||||
plus the two legacy `deferred` OQs (09, 10) each got an external-trigger
|
||||
tracker task under `tasks/architecture/` tagged `[external-trigger,
|
||||
deferred-oq]`. These represent the external condition (a use case arriving,
|
||||
a crate being specced) that would unblock the OQ — they are not actionable
|
||||
work, so `risk: trivial` and `level: research`.
|
||||
- **OQ-09/10 backfill**: added a structured `Blocked on:` field to both
|
||||
(previously they used legacy `deferred` status with the reason in the
|
||||
Resolution prose). The `open-questions.md` index now surfaces all six
|
||||
deferred OQs with concrete blocking conditions in the Deferred/Blocked
|
||||
section — no more "_(no explicit blocking condition recorded)_" placeholders.
|
||||
- **Convention doc**: the `docs/sdd_process.md` Task File Format section is
|
||||
updated with the architecture-task level mapping and the Safe Exit
|
||||
blocker-task pattern (separate edit).
|
||||
|
||||
## Out of scope
|
||||
|
||||
- The DB-backed backend (no manual links, vector/text search) — that's a future
|
||||
@@ -67,7 +92,9 @@ it").
|
||||
|
||||
## Verification
|
||||
|
||||
- `tasks/architecture/` contains one blocker task per `deferred(scope)` OQ
|
||||
- Each blocker task's `depends_on` names the concrete unblocking condition (or
|
||||
a task that represents it)
|
||||
- `docs/sdd_process.md` (or equivalent) references the convention
|
||||
- `tasks/architecture/` contains one external-trigger task per deferred OQ
|
||||
(six total: OQ-09, 10, 32, 41, 44, 46).
|
||||
- Each OQ's `Blocked on:` field names its tracker task ID, and the
|
||||
`open-questions.md` Deferred/Blocked section surfaces the condition inline.
|
||||
- `taskgraph validate` passes for `tasks/architecture/`.
|
||||
- `docs/sdd_process.md` references the convention.
|
||||
@@ -1,7 +1,7 @@
|
||||
---
|
||||
id: call/registry/access-control-ownership-check
|
||||
name: Update AccessControl::check to consult OwnershipProvider for dynamic resource ownership (ADR-050 §2)
|
||||
status: done
|
||||
status: completed
|
||||
depends_on: [core/ownership-store-trait]
|
||||
scope: moderate
|
||||
risk: medium
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
---
|
||||
id: call/registry/dispatch-resource-id-extraction
|
||||
name: Wire dispatch path to extract resource_id from input and thread OwnershipProvider to AccessControl::check (ADR-050 §2a, §4a)
|
||||
status: done
|
||||
status: completed
|
||||
depends_on: [call/registry/operation-spec-resource-id-path, call/registry/access-control-ownership-check]
|
||||
scope: moderate
|
||||
risk: medium
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
---
|
||||
id: call/registry/operation-spec-resource-id-path
|
||||
name: Add resource_id_path field to OperationSpec (ADR-050 §2a)
|
||||
status: done
|
||||
status: completed
|
||||
depends_on: []
|
||||
scope: single
|
||||
risk: low
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
---
|
||||
id: core/ownership-store-trait
|
||||
name: Add OwnershipProvider (sync read) + OwnershipStore (async write) traits and InMemoryOwnershipStore (ADR-050)
|
||||
status: done
|
||||
status: completed
|
||||
depends_on: []
|
||||
scope: moderate
|
||||
risk: low
|
||||
|
||||
Reference in new issue
Block a user