Add refactor planning docs (.claude/refactor/)
Platform-wide refactor plan: README, CONVENTIONS, CONTRACTS, MODULE_SPLIT, TASKS, OPEN_QUESTIONS. Source of truth for the phased refactor across all 12 submodules. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
99
.claude/refactor/OPEN_QUESTIONS.md
Normal file
99
.claude/refactor/OPEN_QUESTIONS.md
Normal file
@@ -0,0 +1,99 @@
|
||||
# Open questions
|
||||
|
||||
Things deferred. Append, don't rewrite history. Add a date when you add
|
||||
or resolve an entry. Anyone (human or agent) discovering an unclear
|
||||
decision during refactor work writes it here rather than guessing.
|
||||
|
||||
Format:
|
||||
|
||||
```
|
||||
## YYYY-MM-DD — Short title
|
||||
|
||||
**Context:** what we're trying to do
|
||||
**Question:** what's unresolved
|
||||
**Default chosen:** what we did meanwhile
|
||||
**Decision needed by:** which phase or task
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2026-05-10 — External Port-0 topic naming — RESOLVED
|
||||
|
||||
**Decision (2026-05-10):** Use canonical names (`set.*` / `cmd.*` /
|
||||
`data.*` / `child.*` / `query.*` / `evt.*`) **from Phase 1 onwards**.
|
||||
Each `commands/index.js` declares the canonical name as the topic and
|
||||
lists legacy names in `aliases`. Aliases log a one-time deprecation
|
||||
warning. Phase 7 shrinks to: remove aliases after one release cycle.
|
||||
|
||||
The full prefix glossary (with what each does and why) is now in
|
||||
`CONTRACTS.md §1`. See it before naming a topic.
|
||||
|
||||
---
|
||||
|
||||
## 2026-05-10 — Parent EVOLV repo `development` branch lineage — RESOLVED
|
||||
|
||||
**Decision (2026-05-10):** Rebase parent `development` onto
|
||||
`origin/main` before the refactor proceeds. Done at the start of
|
||||
Phase 1.
|
||||
|
||||
---
|
||||
|
||||
## 2026-05-10 — `generalFunctions` deprecated paths — RESOLVED
|
||||
|
||||
**Decision (2026-05-10):** Tracked as Phase 8.5 in `TASKS.md`. Cleanup
|
||||
runs after promotion to main. The list of paths to remove is captured
|
||||
there so it isn't lost.
|
||||
|
||||
---
|
||||
|
||||
## 2026-05-10 — Two child-storage shapes — RESOLVED
|
||||
|
||||
**Decision (2026-05-10):** Registry-as-truth, **with named getters** that
|
||||
read clearly in code. `domain.machines` keeps working — it's a getter
|
||||
that returns the rotatingMachine slice of `this.child`. Same for
|
||||
`domain.stations`, `domain.machineGroups`, etc. Domain code reads
|
||||
naturally; the registry is the source of truth underneath.
|
||||
|
||||
Named getters are declared by the domain subclass in `configure()`:
|
||||
|
||||
```js
|
||||
configure() {
|
||||
Object.defineProperty(this, 'machines',
|
||||
{ get: () => this.child?.machine?.centrifugal ?? {} });
|
||||
}
|
||||
```
|
||||
|
||||
(`BaseDomain` provides a helper for this pattern.)
|
||||
|
||||
---
|
||||
|
||||
## 2026-05-10 — Async vs sync `tick()` — RESOLVED with redesign
|
||||
|
||||
**Decision (2026-05-10):** Default is **event-driven**. Ticks are
|
||||
opt-in.
|
||||
|
||||
`BaseNodeAdapter` exposes two timers:
|
||||
|
||||
- `static tickInterval = null` — opt-in periodic tick. Default null = no
|
||||
tick. Domain emits `'output-changed'` on `this.emitter` instead, and
|
||||
BaseNodeAdapter subscribes to that event to push outputs.
|
||||
- `static statusInterval = 1000` — always-on status badge poll.
|
||||
Required because Node-RED's editor refresh expects a heartbeat. Set
|
||||
to 0 only in headless test environments.
|
||||
|
||||
When opting into ticks:
|
||||
- Document **why** in a one-line comment above
|
||||
`static tickInterval = ...` (e.g. "needs delta-time for predicted
|
||||
volume integrator").
|
||||
- A node should opt in only when truly time-driven. Examples that need
|
||||
it: `pumpingStation` (predicted volume integrates over time),
|
||||
`measurement` (when simulator is enabled — ticks the random walk).
|
||||
- Examples that DO NOT need it: `MGC` (recomputes on pressure events),
|
||||
`rotatingMachine` (recomputes on measurement events + state changes).
|
||||
|
||||
`tick()` is treated as fire-and-forget (no await). A node that needs
|
||||
serialisation uses `LatestWinsGate` internally.
|
||||
|
||||
See `CONTRACTS.md §2` for the BaseNodeAdapter shape.
|
||||
|
||||
---
|
||||
Reference in New Issue
Block a user