|
| 1 | +# ADR-0010: Explicit action-scoped progress reporting |
| 2 | + |
| 3 | +- **Status:** accepted |
| 4 | +- **Date:** 2026-03-27 |
| 5 | +- **Deciders:** @Aksem |
| 6 | +- **Tags:** actions, progress, architecture |
| 7 | + |
| 8 | +## Context |
| 9 | + |
| 10 | +FineCode actions can already stream **partial results**: incremental result data |
| 11 | +that reaches the client before the action fully completes. However, there is no |
| 12 | +corresponding way for an action to report **progress**: status metadata such as |
| 13 | +what it is doing, how far along it is, or whether it can be cancelled. |
| 14 | + |
| 15 | +That gap matters most for long-running actions such as workspace linting, test |
| 16 | +discovery, or dependency installation. Today those actions may appear silent |
| 17 | +even when they are working correctly. |
| 18 | + |
| 19 | +Progress is a separate concern from partial results: |
| 20 | + |
| 21 | +- Partial results are part of the action's result contract. |
| 22 | +- Progress is metadata about the action's execution. |
| 23 | + |
| 24 | +FineCode also needs one rule that still works when an action orchestrates other |
| 25 | +actions, runs work concurrently, or is invoked from different client |
| 26 | +environments. Handlers should not need environment-specific branches just to |
| 27 | +report progress. |
| 28 | + |
| 29 | +## Related ADRs Considered |
| 30 | + |
| 31 | +- [ADR-0009](0009-explicit-partial-result-token-propagation.md) - defines how |
| 32 | + partial results behave across action boundaries. This ADR applies the same |
| 33 | + boundary and ownership thinking to progress, which is metadata rather than |
| 34 | + result data. |
| 35 | + |
| 36 | +## Decision |
| 37 | + |
| 38 | +FineCode will support **progress as an explicit, action-scoped channel of |
| 39 | +metadata**, separate from partial results. |
| 40 | + |
| 41 | +- A handler may report progress for the action contract it owns. |
| 42 | +- Progress does not implicitly flow across action boundaries. If a parent action |
| 43 | + delegates work and wants client-visible progress, the parent handler owns that |
| 44 | + progress narrative. |
| 45 | +- The framework must provide a single handler-facing progress mechanism that |
| 46 | + works in sequential and concurrent code and degrades to a no-op when the |
| 47 | + caller did not request progress. |
| 48 | +- The handler-facing mechanism must make correct progress lifecycle management |
| 49 | + the default, so handlers do not need ad hoc begin/report/end coordination on |
| 50 | + every code path. |
| 51 | +- Progress remains transport-agnostic at the handler boundary. Different |
| 52 | + FineCode clients may render or transport the same progress events differently |
| 53 | + without changing handler logic. |
| 54 | +- Progress and partial results remain orthogonal. An action may use either, both, |
| 55 | + or neither. |
| 56 | + |
| 57 | +## Consequences |
| 58 | + |
| 59 | +- **Long-running actions become observable.** Clients can show live status for |
| 60 | + operations that would otherwise appear stalled. |
| 61 | +- **Handler ownership stays explicit.** Parent actions keep control of the |
| 62 | + client-visible progress contract at their own boundary. |
| 63 | +- **Handler code stays mode-agnostic.** The same handler logic works whether or |
| 64 | + not progress was requested by the caller. |
| 65 | +- **The handler-facing API grows.** FineCode needs a public progress mechanism |
| 66 | + for action authors, even though simple handlers may ignore it. |
| 67 | +- **Cancellation remains forward-compatible.** Progress may expose whether an |
| 68 | + action is cancellable, but end-to-end cancellation semantics should be |
| 69 | + revisited when client-originated cancellation is wired through to handlers. |
| 70 | +- **Request-level aggregation is a separate concern.** How FineCode combines |
| 71 | + multiple child progress streams into one client-visible stream will be addressed |
| 72 | + separately in further ADRs. |
| 73 | + |
| 74 | +### Alternatives Considered |
| 75 | + |
| 76 | +**Standalone progress calls without lifecycle mediation.** Rejected because |
| 77 | +progress protocols generally require start, update, and end events in the right |
| 78 | +order, including on error paths. FineCode should make the correct lifecycle the |
| 79 | +default rather than relying on every handler to coordinate it manually. |
| 80 | + |
| 81 | +**Reuse the partial-result channel for progress updates.** Rejected because it |
| 82 | +mixes result data and execution metadata into one stream and weakens the action |
| 83 | +boundary that [ADR-0009](0009-explicit-partial-result-token-propagation.md) |
| 84 | +made explicit. |
| 85 | + |
| 86 | +**Automatic framework-generated progress.** Rejected because the framework |
| 87 | +cannot reliably infer meaningful status messages or units of work for arbitrary |
| 88 | +actions. Progress needs explicit handler ownership. |
| 89 | + |
| 90 | +### Implementation Notes |
| 91 | + |
| 92 | +- The current handler-facing API uses `ProgressSender`, `ProgressContext`, and |
| 93 | + `RunActionContext.progress()`. |
| 94 | +- Progress uses a token distinct from `partial_result_token`. |
| 95 | +- Current transports may adapt the same progress events for LSP, CLI, MCP, or |
| 96 | + other clients without changing the architectural rule in this ADR. |
0 commit comments