Repository navigation
Description
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-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 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.
Refs: #12296 · PR #12348 · #12160 · ADR-0126 §4
Generated by Claude Code
Activity
os-support-ai commentedon Aug 26, 2026
Consolidated into the ledger-convergence card #12159 by maintainer ruling (2026-08-26, verbatim 「同意」, recorded in full on #12359): this consolidation, the #12359 registration move (option B — registration moves to
PlatformObjectsPlugin, single owner) and the L8 permission-set convergence are one card, one PR, one verification pass — three touches of the same hot surface collapsed into one review. This issue stays open and will be closed by that PR.One constraint from this card's own analysis that the convergence card carries forward: the shared store must live in a package both
service-automationandobjectqlmay depend on —@objectstack/coreis the leading candidate;platform-objectsas the code home would invert the tiering for objectql (registration moving there is a composition-level matter, orthogonal to this).Generated by Claude Code
refactor(core): one implementation of the ADR-0126 section 4 activati…
os-warren commentedon Aug 26, 2026
{ "issue": 12350, "status": "blocked", "branch": null, "pr": null, "premise_still_valid": false, "summary": "PREMISE FALSIFIED — this card was already delivered before dispatch reached me, so I wrote no code, created no worktree, pushed no branch and opened no PR. Verified on origin/main: PR #12419 (the maintainer-ruled ledger-convergence bundle) squash-merged as af56546adb at 2026-08-26 02:32:43 +0000, and issue #12350 was closed state_reason=completed at 02:51:34Z by os-support-ai. There are no longer two implementations of the ADR-0126 section 4 row contract: there is exactly ONE, ObjectStoreMetadataActivationStore in packages/core/src/utils/metadata-activation-store.ts, parameterized by a metadataType constructor argument. Both former implementations are now thin bindings that add no row logic: ObjectStoreFlowActivationStore extends ObjectStoreMetadataActivationStore (packages/services/service-automation/src/flow-activation-store.ts, 193 lines to 98) and ObjectStoreActionActivationStore extends ObjectStoreMetadataActivationStore (packages/objectql/src/action-activation.ts, 429 to 294), each fixing its own discriminator in a one-argument constructor. The home chosen was @objectstack/core, exactly the candidate this card's own body and its triage comment named as the one that does not invert tiering. Both pin suites (flow-activation-ledger.test.ts, action-activation.test.ts) are byte-unchanged and were absent from the merged diff. Doing this card would have produced a second, competing implementation of a consolidation that already exists on main, colliding on all four load-bearing files. Note for the dispatching seat: comment 5419050872 on this card, posted 2026-08-26 00:54Z, already recorded the maintainer ruling (verbatim 「同意」) folding #12350 into the #12159 convergence bundle as one card, one PR, one verification pass — that ruling predates my dispatch and is the authoritative record; a PM charter does not override it. Two live follow-ups belong to #12159, not to me, and are already filed there by the merging lane: the ledger's datasource-routing question flagged for the maintainer, and Part 3 (permission-set convergence) which was a deliberate stop-and-report rather than an implementation.", "tests": "None run, and deliberately so — there is nothing to implement, so a build/test/gate pass would have measured an unmodified tree and reported a green that means nothing. Evidence is git-observational on a freshly fetched origin/main: `git log --oneline origin/main -- packages/core/src/utils/metadata-activation-store.ts` yields the single commit af56546adb 'Ledger convergence: registration home + one store implementation (ADR-0126 section 4/8, maintainer-ruled) (#12419)'; `git merge-base --is-ancestor af56546adb origin/main` exits 0. PR head 3ad9030e7 is NOT an ancestor of main, which is the expected signature of a SQUASH merge, not evidence of an unmerged PR. Ablation not owed and not run: no mutation of mine exists to ablate. Survivor-pin re-check at claim time, as instructed: I measured 14 retirement pins matching packages/spec/src/**/*-retirement.test.ts on origin/main, not the 7 quoted in my dispatch — the dispatch's count was stale or from a narrower glob. The conclusion is unchanged: grepping all 14 for MUST_SURVIVE plus activation/ledger store symbols returns no pin naming anything in this card's surface. packages/spec/src/kernel/activation-events-retirement.test.ts matches on the word 'activation' only: it pins ActivationEventSchema and ActivationEvent as REMOVED under ADR-0049 (#4657, lazy plugin-activation vocabulary), an unrelated surface, and it is a removal tombstone rather than a survival pin. Channel declaration: REST returned HTTP 403 from this seat, matching #12123, so every GitHub read above is MCP or local git rather than REST; no result here rests on an empty REST response.", "open_questions": [], "out_of_scope_findings": [] }Generated by Claude Code
Generated by Claude Code
os-warren commentedon Aug 26, 2026
os-dev-report
(Supersedes comment 5419918703, whose HTML-comment marker the body sanitizer removed on write — #12133, confirmed by read-back. Same JSON, marker as literal text so the PM scan can see it. No comment-edit tool is reachable from this seat and REST is 403, hence a replacement comment rather than an edit.)
{ "issue": 12350, "status": "blocked", "branch": null, "pr": null, "premise_still_valid": false, "summary": "PREMISE FALSIFIED — this card was already delivered before dispatch reached me, so I wrote no code, created no worktree, pushed no branch and opened no PR. Verified on origin/main: PR #12419 (the maintainer-ruled ledger-convergence bundle) squash-merged as af56546adb at 2026-08-26 02:32:43 +0000, and issue #12350 was closed state_reason=completed at 02:51:34Z by os-support-ai. There are no longer two implementations of the ADR-0126 section 4 row contract: there is exactly ONE, ObjectStoreMetadataActivationStore in packages/core/src/utils/metadata-activation-store.ts, parameterized by a metadataType constructor argument. Both former implementations are now thin bindings that add no row logic: ObjectStoreFlowActivationStore extends ObjectStoreMetadataActivationStore (packages/services/service-automation/src/flow-activation-store.ts, 193 lines to 98) and ObjectStoreActionActivationStore extends ObjectStoreMetadataActivationStore (packages/objectql/src/action-activation.ts, 429 to 294), each fixing its own discriminator in a one-argument constructor. The home chosen was @objectstack/core, exactly the candidate this card's own body and its triage comment named as the one that does not invert tiering. Both pin suites (flow-activation-ledger.test.ts, action-activation.test.ts) are byte-unchanged and were absent from the merged diff. Doing this card would have produced a second, competing implementation of a consolidation that already exists on main, colliding on all four load-bearing files. Note for the dispatching seat: comment 5419050872 on this card, posted 2026-08-26 00:54Z, already recorded the maintainer ruling (verbatim 「同意」) folding #12350 into the #12159 convergence bundle as one card, one PR, one verification pass — that ruling predates my dispatch and is the authoritative record; a PM charter does not override it. Two live follow-ups belong to #12159, not to me, and are already filed there by the merging lane: the ledger's datasource-routing question flagged for the maintainer, and Part 3 (permission-set convergence) which was a deliberate stop-and-report rather than an implementation.", "tests": "None run, and deliberately so — there is nothing to implement, so a build/test/gate pass would have measured an unmodified tree and reported a green that means nothing. Evidence is git-observational on a freshly fetched origin/main: `git log --oneline origin/main -- packages/core/src/utils/metadata-activation-store.ts` yields the single commit af56546adb 'Ledger convergence: registration home + one store implementation (ADR-0126 section 4/8, maintainer-ruled) (#12419)'; `git merge-base --is-ancestor af56546adb origin/main` exits 0. PR head 3ad9030e7 is NOT an ancestor of main, which is the expected signature of a SQUASH merge, not evidence of an unmerged PR. Ablation not owed and not run: no mutation of mine exists to ablate. Survivor-pin re-check at claim time, as instructed: I measured 14 retirement pins matching packages/spec/src/**/*-retirement.test.ts on origin/main, not the 7 quoted in my dispatch — the dispatch's count was stale or from a narrower glob. The conclusion is unchanged: grepping all 14 for MUST_SURVIVE plus activation/ledger store symbols returns no pin naming anything in this card's surface. packages/spec/src/kernel/activation-events-retirement.test.ts matches on the word 'activation' only: it pins ActivationEventSchema and ActivationEvent as REMOVED under ADR-0049 (#4657, lazy plugin-activation vocabulary), an unrelated surface, and it is a removal tombstone rather than a survival pin. Channel declaration: REST returned HTTP 403 from this seat, matching #12123, so every GitHub read above is MCP or local git rather than REST; no result here rests on an empty REST response.", "open_questions": [], "out_of_scope_findings": [] }Generated by Claude Code
Generated by Claude Code
Ledger convergence: registration home + one store implementation (ADR…