Skip to content

Commit 7b1edb0

Browse files
committed
Accept ADR-0007, add ADR-0008: Explicit specialization metadata for language-specific actions
1 parent 6294e8a commit 7b1edb0

File tree

3 files changed

+111
-3
lines changed

3 files changed

+111
-3
lines changed

docs/adr/0007-single-registration-per-action-definition.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# ADR-0007: Single registration per action definition
22

3-
- **Status:** proposed
3+
- **Status:** accepted
44
- **Date:** 2026-03-21
55
- **Deciders:** @Aksem
66
- **Tags:** actions, architecture, languages
@@ -78,7 +78,6 @@ to be expressed as duplicate registrations instead of as explicit architecture.
7878
## Related Decisions
7979

8080
- Refines [ADR-0006](0006-shared-action-types-as-the-action-identity-contract.md)
81-
- Related implementation mechanism: [ADR-0008](0008-class-metadata-for-language-subaction-discovery.md)
8281

8382
## Implementation Notes
8483

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
# ADR-0008: Explicit specialization metadata for language-specific actions
2+
3+
- **Status:** accepted
4+
- **Date:** 2026-03-21
5+
- **Deciders:** @Aksem
6+
- **Tags:** actions, architecture, languages
7+
8+
## Context
9+
10+
After [ADR-0006](0006-shared-action-types-as-the-action-identity-contract.md),
11+
FineCode treats shared action definition types as the architectural identity
12+
contract. After [ADR-0007](0007-single-registration-per-action-definition.md),
13+
projects also cannot model language variants by registering the same generic
14+
action definition multiple times under different names.
15+
16+
Multi-language actions therefore need an explicit way to represent that one
17+
action definition is a language-specific specialization of another. That
18+
relationship must be discoverable without depending on project-local
19+
registration names or naming conventions.
20+
21+
Name-based discovery is too fragile for that role. A project may register a
22+
Python lint action under any project-local name, and the discovery mechanism
23+
must still recognize both:
24+
25+
1. which language the specialized action targets
26+
2. which parent action definition it specializes
27+
28+
Those are intrinsic properties of the action design, not of project
29+
configuration.
30+
31+
## Related ADRs Considered
32+
33+
- [ADR-0006](0006-shared-action-types-as-the-action-identity-contract.md)
34+
establishes action definition types as the identity contract. This ADR
35+
extends that rule to specialization relationships between action definitions.
36+
- [ADR-0007](0007-single-registration-per-action-definition.md)
37+
establishes that a project may register a given action definition at most
38+
once. This ADR defines how language-specific specialization is represented
39+
without relying on duplicate registrations.
40+
41+
## Decision
42+
43+
FineCode will represent language-specific specialization through **explicit
44+
metadata on the shared action definition itself**.
45+
46+
A language-specific action definition must declare:
47+
48+
- the language it targets
49+
- the parent action definition it specializes
50+
51+
This metadata is part of the shared action contract. It must not be inferred
52+
from project-local registration names, and it must not live only in project
53+
configuration.
54+
55+
Discovery and dispatch mechanisms may use that metadata to find specialized
56+
actions, but routing behavior remains a separate concern owned by handlers or
57+
other orchestration logic.
58+
59+
## Consequences
60+
61+
- **Discovery is independent of project-local names.** A project may choose any
62+
registration name for a specialized action without breaking discovery.
63+
- **Specialization becomes part of the contract package.** The relationship
64+
between a specialized action and its parent is expressed alongside the action
65+
definition itself rather than being split across naming conventions or project
66+
configuration.
67+
- **Language alone is not sufficient.** Multiple parent actions may have
68+
specializations for the same language, so discovery needs both the target
69+
language and the parent action definition.
70+
- **Project configuration has a narrower role.** Configuration may control
71+
whether an action is registered or how it is executed, but it does not define
72+
the architectural specialization relationship.
73+
74+
### Alternatives Considered
75+
76+
**Inheritance from the parent action definition.** Rejected because the
77+
specialization relationship does not always imply substitutability. Some
78+
language-specific actions may need payload or contract differences that make
79+
inheritance an unreliable architectural signal.
80+
81+
**Registration-time metadata in project config.** Rejected because it places an
82+
intrinsic property of the shared action contract into project-local
83+
configuration, where it can drift and where callers cannot rely on it across
84+
environments.
85+
86+
**Name conventions.** Rejected because project-local registration names are not a
87+
stable architectural contract.
88+
89+
## Related Decisions
90+
91+
- Refines [ADR-0006](0006-shared-action-types-as-the-action-identity-contract.md)
92+
- Supports [ADR-0007](0007-single-registration-per-action-definition.md)
93+
94+
## Implementation Notes
95+
96+
The current implementation represents this metadata with class-level fields on
97+
the `Action` base class for the target language and the parent action
98+
definition.
99+
100+
Helpers that discover language-specific actions should use that explicit
101+
metadata rather than parsing registration names.
102+
103+
When a specialized action extends its parent payload with ecosystem-specific
104+
fields, dispatch-oriented construction should rely only on values available from
105+
the parent payload. Any specialized fields therefore need defaults that are
106+
meaningful for dispatch-based invocation, while workflows that need non-default
107+
values should invoke the specialized action directly or use a more specific
108+
orchestration path.

docs/adr/README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,4 +57,5 @@ keep the same decision, would the ADR still read correctly?
5757
| 0004 | [Auto-shutdown on disconnect timeout](0004-auto-shutdown-on-disconnect-timeout.md) | accepted | 2026-03-19 | lifecycle, wm-server |
5858
| 0005 | [Zero-based line numbers and ResourceUri fields in action payloads and results](0005-zero-based-lines-and-resourceuri-fields-in-action-payloads-and-results.md) | accepted | 2026-03-20 | actions, conventions |
5959
| 0006 | [Shared action types as the action identity contract](0006-shared-action-types-as-the-action-identity-contract.md) | accepted | 2026-03-21 | actions, api, architecture, environments |
60-
| 0007 | [Single registration per action definition](0007-single-registration-per-action-definition.md) | proposed | 2026-03-21 | actions, architecture |
60+
| 0007 | [Single registration per action definition](0007-single-registration-per-action-definition.md) | accepted | 2026-03-21 | actions, architecture |
61+
| 0008 | [Explicit specialization metadata for language-specific actions](0008-explicit-specialization-metadata-for-language-actions.md) | accepted | 2026-03-21 | actions, architecture, languages |

0 commit comments

Comments
 (0)