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
66 lines
2.8 KiB
Markdown
66 lines
2.8 KiB
Markdown
---
|
|
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`. |