Skip to content

Commit f89c5e9

Browse files
committed
ADR-0010 and ADR-0011: progress reporting
1 parent 0c9d966 commit f89c5e9

3 files changed

Lines changed: 196 additions & 0 deletions

File tree

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
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.
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
# ADR-0011: WM aggregates progress for multi-execution requests
2+
3+
- **Status:** accepted
4+
- **Date:** 2026-03-28
5+
- **Deciders:** @Aksem
6+
- **Tags:** actions, progress, architecture, wm-server
7+
8+
## Context
9+
10+
[ADR-0010](0010-progress-reporting-for-actions.md) defines progress as an
11+
explicit action-scoped contract owned by the current handler boundary. That
12+
works cleanly for a single action execution, but some WM-level requests fan out
13+
into multiple executions behind one client-visible operation.
14+
15+
This happens in at least two shapes:
16+
17+
- one action executed across multiple projects
18+
- multiple actions executed as one batch request such as `runBatch`
19+
20+
In both cases, the client still expects one progress stream for the overall
21+
request, while the WM may dispatch work to multiple child executions. Unlike
22+
partial results, multiple progress lifecycles cannot simply be interleaved under
23+
one client token. Competing start, update, and end events would produce erratic
24+
percentages and confusing messages.
25+
26+
FineCode therefore needs an architectural rule for who owns the client-visible
27+
progress stream whenever one request fans out into multiple progress-emitting
28+
executions, and how those child progress streams should be combined without
29+
making handlers aware of WM-level coordination.
30+
31+
## Related ADRs Considered
32+
33+
- [ADR-0009](0009-explicit-partial-result-token-propagation.md) - partial
34+
results can be interleaved across delegated work because each item is result
35+
data. Progress lifecycle events do not have that property.
36+
- [ADR-0010](0010-progress-reporting-for-actions.md) - defines the handler-side
37+
progress contract. This ADR defines how the WM combines multiple project-level
38+
progress streams for one client-visible operation.
39+
40+
## Decision
41+
42+
For any client-visible request that fans out into multiple child executions, the
43+
**WM owns the client-visible progress stream**.
44+
45+
- The WM must not forward multiple child progress lifecycles directly under one
46+
client token.
47+
- The WM must issue distinct internal progress identities for child executions
48+
and aggregate them into the single progress stream expected by the client.
49+
- Handler and ER code remain unaware of WM-level aggregation. They report
50+
progress for their own action scope only.
51+
- This rule applies whether the fan-out dimension is multiple projects,
52+
multiple actions, or both.
53+
- When child progress includes measurable totals, the WM should aggregate
54+
client-visible percentage proportionally to total work across child
55+
executions rather than giving every child equal weight.
56+
- When child progress is indeterminate, the WM may forward narrative updates
57+
without inventing false precision. If no determinate totals are available,
58+
the client-visible progress should remain indeterminate until the work
59+
completes.
60+
61+
## Consequences
62+
63+
- **One client request gets one coherent progress stream.** Clients do not see
64+
conflicting begin/report/end sequences from different child executions.
65+
- **Progress remains accurate across uneven work sizes.** A large project or
66+
action can contribute more of the overall percentage than a small one when
67+
totals are known.
68+
- **Handler contracts stay simple.** Handlers do not need request-level
69+
aggregation logic or awareness of sibling executions.
70+
- **The WM gains aggregation state and protocol responsibilities.** It must
71+
track internal progress identities, combine updates, and normalize what it
72+
forwards.
73+
- **Narrative updates may be richer than percentages.** Some child executions will
74+
contribute messages even when they cannot contribute meaningful percentage
75+
values.
76+
77+
### Alternatives Considered
78+
79+
**Directly interleave child progress under one client token.** Rejected
80+
because progress lifecycle events conflict when multiple executions share one
81+
visible stream.
82+
83+
**Only report coarse completion at the WM level.** Rejected because it throws
84+
away useful progress from within each child execution and makes large fan-out
85+
requests feel artificially coarse.
86+
87+
**Give every child execution an equal slice of the percentage range.** Rejected
88+
because it distorts overall progress when the amount of work differs
89+
substantially.
90+
91+
### Implementation Notes
92+
93+
- A natural implementation is for the WM to mint one internal progress token per
94+
child execution and map those internal streams onto the client-visible token.
95+
- When totals are available, the WM can combine them into a shared total and
96+
derive global completion from per-child completion.
97+
- If FineCode later needs nested or hierarchical progress UI, this ADR should be
98+
revisited before layering additional semantics onto the same stream.

docs/adr/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,3 +60,5 @@ keep the same decision, would the ADR still read correctly?
6060
| 0007 | [Single registration per action definition](0007-single-registration-per-action-definition.md) | accepted | 2026-03-21 | actions, architecture |
6161
| 0008 | [Explicit specialization metadata for language-specific actions](0008-explicit-specialization-metadata-for-language-actions.md) | accepted | 2026-03-21 | actions, architecture, languages |
6262
| 0009 | [Explicit handler mediation of partial results across action boundaries](0009-explicit-partial-result-token-propagation.md) | accepted | 2026-03-24 | actions, partial-results, architecture |
63+
| 0010 | [Explicit action-scoped progress reporting](0010-progress-reporting-for-actions.md) | accepted | 2026-03-27 | actions, progress, architecture |
64+
| 0011 | [WM aggregates progress for multi-execution requests](0011-wm-aggregates-progress-across-multi-project-action-runs.md) | accepted | 2026-03-28 | actions, progress, architecture, wm-server |

0 commit comments

Comments
 (0)