Comfy-Org / Comfy-Org/ComfyUI_frontend
ECS docs: seven documents including ADR 0008 say slot-mirror writes are ignored; removal writes disconnect links
- Dominant language
- TypeScript
- Stars
- 2k
- Forks
- 699
- Avg merge
- 1d 7h
- Merged PRs (30d)
- 490
Description
Seven documents on `feature/ecs-migration`, including governing ADR 0008, tell extension authors that `input.link` and `output.links` writes are ignored. They are not. A removal write disconnects links.
## The contract, as implemented at `5002fae1b12d44831a21367afa7c0f798f7e7a2c`
- `src/lib/litegraph/src/node/NodeInputSlot.ts:35-41` — `set link(value)` warns, then `if (value === null && slot !== -1) this._node.disconnectInput(slot)`.
- `src/lib/litegraph/src/node/NodeOutputSlot.ts:44-51` — `set links(value)` warns, splices `legacyLinkIds`, then calls `commitLegacyLinks()`.
- `NodeOutputSlot.ts:70-73` — `commitLegacyLinks` disconnects every link not in the assigned array:
```ts
for (const link of outputLinks(graph, this._node.id, slot)) {
if (desired.has(link.id)) continue
graph.getNodeById(link.target_id)?.disconnectInput(link.target_slot)
}
```
- `src/lib/litegraph/src/interfaces.ts:395` — `links?: LinkId[] | null`. #15501 deliberately deleted `readonly` from both `INodeInputSlot.link` and `INodeOutputSlot.links`.
So the rule is **partial**: null and removal writes are authoritative mutations, id-additions are discarded, all four warn. The classes' own JSDoc says exactly this (`NodeInputSlot.ts:24-26`, `NodeOutputSlot.ts:31-34`). Only the documents disagree with the code.
## Where the wrong contract is written
| Document | Line | Text |
| --- | --- | --- |
| `docs/adr/0008-entity-component-system.md` | 197 | "`input.link` / `output.links` properties are deprecated, read-only" |
| `docs/architecture/ecs-target-architecture.md` | 402 | "deprecated, read-only compatibility accessors" |
| `docs/architecture/ecs/ecs-state-authority-audit.md` | 141, 146 | "assignments warn and have no effect"; "Direct legacy mirror writes are ignored" |
| `docs/architecture/ecs/ecs-documentation-audit.md` | 71-80 | Correction 1 asserts read-only accessors and ignored writes |
| `docs/architecture/ecs/ecs-decision-traceability.md` | 36, 64 | "direct slot mirror writes are ignored" |
| `docs/architecture/output-slot-connectivity.md` | 17, 145-149, 150-152 | "read-only"; "writes fire `warnDeprecated` and are otherwise ignored"; "keeps `links` as `@deprecated readonly`" |
| `docs/architecture/link-topology-store.md` | 134-135 | "deprecated warning getters kept as extension migration telemetry" |
`docs/architecture/ecs/ecs-extension-compatibility-audit.md` is the only one that is correct. #15501 updated that one and no other.
## How it happened
This is a routing failure, not carelessness, and it is worth fixing structurally.
1. #15501 (`d001548b3a`, 2026-08-20) inverted the contract in code. Its diff touches exactly one document: `ecs-extension-compatibility-audit.md`.
2. #15443 (`14e82f26cf`, 2026-08-21), the documentation-audit commit, then edited `output-slot-connectivity.md` and **inserted** the words "retaining deprecated, read-only compatibility accessors" into its intro — one day after the code change that made them false.
3. The same commit wrote ADR 0008:197.
A pass whose purpose was to audit the docs made one of them more wrong, and put the false claim into a governing record.
## Why it matters
`output.links = []` disconnects every link on the slot. An extension author who reads any of these seven documents believes it is a no-op. The failure is silent damage to the user's graph, not an exception, and it is the same shape as #15594.
It also blocks a gate. `docs/architecture/ecs/ecs-extension-compatibility-audit.md` §"Required follow-up evidence" makes shim removal conditional on measuring ecosystem use of these accessors. If the docs say the write path is inert, nobody measures the write path.
## Suggested fix
One sentence, applied in all seven places:
> Deprecated compatibility accessors. Reads are store-derived. A null or removal write disconnects through the link store; id additions are discarded. All four warn.
Then, so this does not recur: at PR time, grep `docs/` for every symbol whose behaviour the diff changes. That check would have caught all six misses here, and would also have caught `createGeometryView` (renamed, still cited in `ecs-lifecycle-audit.md:39` and `ecs-state-authority-audit.md:49`) and `AbstractMinimapDataSource` (renamed, still cited in `output-slot-connectivity.md:87`).
## Provenance
Found by a full claim-by-claim verification of the twelve architecture documents this branch adds, against head `5002fae1b12d44831a21367afa7c0f798f7e7a2c`. 633 backticked symbols swept, 29 dead, 5 genuinely false after reading context. Detail and per-document denominators in https://github.com/Comfy-Org/ComfyUI_frontend/pull/14246#pullrequestreview-4998963440
Related: #15552 (same defect class in the agent-facing guides and READMEs), #15587 (`BadgePosition` barrel removal missing from the compat audit), #15594.
Not covered by #15610, which addresses 15 code findings across 30 `src/` files and touches no documentation.
Contributor guide
Assessment
This issue has not been assessed yet.