Files
alknet/tasks/architecture/oq-41-stream-operators-use-case.md
T
glm-5.2 df5d04af1d 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
2026-07-06 16:34:01 +00:00

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`.