ADR-0126 §4 declares ONE activation ledger for the whole disable+clone family. It now has two independent implementations of the same row contract, and this issue is the record of that, filed by the leg that created the second one rather than left to be found.
| Implementation | Package | Landed |
|---|
ObjectStoreFlowActivationStore (metadata_type: 'flow') | packages/services/service-automation/src/flow-activation-store.ts | #12296 |
ObjectStoreActionActivationStore (metadata_type: 'action') | packages/objectql/src/action-activation.ts | #12348 |
The two agree today on every load-bearing detail — install-level rows only (organization_id never written), rows carrying an organization skipped on read, a driver 0 read as false, read-then-write rather than a blind upsert, no delete in the engine slice because re-enabling rewrites the row. They agree because the second was written from the first and the ADR pins both; nothing structurally holds them together.
Why it was not shared at the time
Neither direction of import exists in the module graph:
@objectstack/service-automation does not depend on @objectstack/objectql (it is a devDependency only), so the flow store cannot import the generic one;@objectstack/objectql must not depend on a service package — the dependency arrow points the other way.
Consolidating means putting a generic metadata_type-parameterized store in a package BOTH may depend on, and moving both consumers onto it. Candidates worth weighing: @objectstack/core (both already depend on it), or @objectstack/platform-objects (it declares the sys_metadata_activation object itself, and service-automation already depends on it — but objectql does not, and adding that edge inverts the tiering, since platform-objects is the catalog the engine serves).
Why it is worth doing, and why it is not urgent
Worth doing: ADR-0126 §8 pre-charts tool, skill and position as later Regime C consumers, and a third and fourth copy of this store is where the row semantics start drifting — the org-row skip and the 0-is-false read are exactly the kind of detail a copy loses quietly.
Not urgent: the two current copies are pinned on both sides (flow-activation-ledger.test.ts, action-activation.test.ts), and a drift would have to survive both.
⚠️ This is a refactor of landed code in two packages, so it wants its own card and its own review — which is why the #12160 leg declared it in the module header and here instead of doing it inline.
Refs: #12296 · PR #12348 · #12160 · ADR-0126 §4
Generated by Claude Code
ADR-0126 §4 declares ONE activation ledger for the whole disable+clone family. It now has two independent implementations of the same row contract, and this issue is the record of that, filed by the leg that created the second one rather than left to be found.
ObjectStoreFlowActivationStore(metadata_type: 'flow')packages/services/service-automation/src/flow-activation-store.tsObjectStoreActionActivationStore(metadata_type: 'action')packages/objectql/src/action-activation.tsThe two agree today on every load-bearing detail — install-level rows only (
organization_idnever written), rows carrying an organization skipped on read, a driver0read as false, read-then-write rather than a blind upsert, nodeletein the engine slice because re-enabling rewrites the row. They agree because the second was written from the first and the ADR pins both; nothing structurally holds them together.Why it was not shared at the time
Neither direction of import exists in the module graph:
@objectstack/service-automationdoes not depend on@objectstack/objectql(it is a devDependency only), so the flow store cannot import the generic one;@objectstack/objectqlmust not depend on a service package — the dependency arrow points the other way.Consolidating means putting a generic
metadata_type-parameterized store in a package BOTH may depend on, and moving both consumers onto it. Candidates worth weighing:@objectstack/core(both already depend on it), or@objectstack/platform-objects(it declares thesys_metadata_activationobject itself, andservice-automationalready depends on it — butobjectqldoes not, and adding that edge inverts the tiering, since platform-objects is the catalog the engine serves).Why it is worth doing, and why it is not urgent
Worth doing: ADR-0126 §8 pre-charts
tool,skillandpositionas later Regime C consumers, and a third and fourth copy of this store is where the row semantics start drifting — the org-row skip and the0-is-false read are exactly the kind of detail a copy loses quietly.Not urgent: the two current copies are pinned on both sides (
flow-activation-ledger.test.ts,action-activation.test.ts), and a drift would have to survive both.Refs: #12296 · PR #12348 · #12160 · ADR-0126 §4
Generated by Claude Code