Repository navigation
Epic: packaged-metadata customization (ADR-0126) — flows first, v17 line #12150
Description
Chartered by maintainer, 2026-08-25, live PM chat, verbatim and untranslated: 「v17 ,然后创建一个epic issue,跟进相关的开发。」 — immediately after ADR-0126 merged and was verified on origin/main. Filed by the chartering PM session session_01KWRU3s15AJz7PGW7a7wdCh. Standing autonomy ruling, 2026-08-25, verbatim: 「继续自主完成所有开发」 — the program dispatches, drives to green, and enqueues its own PRs; governed surfaces stay human-merge; ADR-0126 §6 wall conflicts stop-and-report.
What this epic tracks
The implementation program for ADR-0126 (docs/adr/0126-packaged-metadata-customization-model.md, merged 28b47a93, PR #12063; survey: #12049 comment 5406807988): the platform customization model for packaged metadata — three regimes, one activation ledger. Implementation legs consume the ADR's §§4–7 as settled contract; ⛔ no re-litigation of the model on leg cards — a leg that cannot be built inside the ADR's walls (§6) is a stop-and-report back to the maintainer, not a workaround.
Release target — maintainer-ruled
v17 line: ships as a 17.x minor. Grounds on record: the whole program is additive (an empty sys_metadata_activation ledger = packaged default everywhere; no data migration; zero packages/spec surface; smooth upgrade for existing installs), the regime's first instance (#11513 permission sets) already shipped inside the v17 line, and the shipped docs promise this work redeems is live on v17 today.
⛔ Excluded from this epic: #12057 (paper customization-protocol removal) — deleting exported spec surface is breaking; it rides the next major (v18) on its own enforce-or-remove card per ADR-0126 §6.4.
Legs — ALL LANDED (L1–L7 + L6-UI: 2026-08-25 · L8: 2026-08-26)
- L1 — the ledger object (L1:
sys_metadata_activationplatform object — the activation ledger (ADR-0126 §4) #12155 · PR feat(platform-objects): declaresys_metadata_activation, the ADR-0126 §4 activation ledger #12185 · merged428f9b24):sys_metadata_activationinpackages/platform-objects(§4) —(metadata_type, name, package_id, organization_id nullable-reserved, active), uniqueness NULL-collapsed, absence-of-row = active - L2 — disable/enable write path (L2: packaged-flow disable/enable write path — operator gate + subflow guard (ADR-0126 §5, §7.3) #12157 · PR feat(automation): durable packaged-flow disable — activation ledger, execute() consult, operator gate #12296 · merged
15249270, one PR with L3): the flip action writes the durable ledger row; operator-gated (platform_adminposition) ingroup/isolatedpostures (§5); disable refused while any packaged flow references the target as a subflow (subflowANDmapnodes), refusal names the callers (§7.3) - L3 — runtime consult (L3: runtime consult at the execute() seam + trigger unbind + retire the #10243 flowEnabled map (ADR-0126 §7.2) #12158 · PR feat(automation): durable packaged-flow disable — activation ledger, execute() consult, operator gate #12296 · merged
15249270):execute()-seam refusal besideFLOW_DISABLEDreusing its code; install-level row unbinds/rebinds the trigger; a ledger disable survives unregister+re-register (§6 wall 3); the Decide whether POST /api/v1/automation/:name/toggle belongs in the manage_metadata write set — it mutates flow enablement with no authoring capability #10243flowEnabledmap retired, not shaded (§7.2) - L4 — flow clone action (L4: flow clone action — whole-definition copy, mandatory new name, no ancestry (ADR-0126 §7.1) #12156 · PR feat(runtime): flow clone action — whole-definition copy, mandatory new name, no ancestry (ADR-0126 §7.1) #12190 · merged
c68c6708): new machine name mandatory, whole-definition copy, no recorded ancestry (§7.1; Theclone_permission_setaction copies only 2 of the 6 definition facets, so a clone silently drops system permissions, RLS and tab permissions #11703 is the measured counter-example; objectui half follows the The Clone dialog for a permission set now offers five raw JSON blobs as editable inputs —defaultFromRowhas no non-editable carry-over #11753 carried-blob discipline) - L5 — Setup surface (L5: Setup page "packaged automation" — on/off + clone actions for packaged flows (ADR-0126 §7.4) objectui#6301 · PR feat(app-shell): Setup page for packaged automation — on/off + clone (ADR-0126 §7.4) objectui#6382 · merged
b362c1b): new "packaged automation" Setup page, shaped on the Setup permission-set page (nav_permission_setscontribution precedent); per packaged flow: on/off for this scope + clone, server refusals verbatim — ⛔ no drift/ancestry surface (§7.4, §9) - L6 — action disable (L6: action disable — dispatch-time consult on the same ledger (ADR-0126 §8.2, amendment ruling 3) #12160 · PR feat(actions): durable packaged-action disable — same activation ledger, dispatch-time consult #12348 · merged
e5ce2ed0): generalizes the merged L2/L3 machinery to actions (amendment ruling 3, Survey + ADR: the platform customization model for packaged metadata — regimes per type, one activation ledger (chartered on #11665) #12049 comment 5408117664) — same ledger, same write authority, consult at action dispatch (409 ACTION_DISABLEDon both doors, after the capability gate); ⛔ action-clone not chartered - L6-UI — packaged actions on/off on the Setup page (L6-UI: packaged actions on/off on the Setup packaged-automation page (ADR-0126 §8.2, ruling 3 — surface half) objectui#6412 · PR feat(app-shell): packaged actions on/off beside the packaged flows (ADR-0126 §8 item 2) objectui#6415 · merged
9602dc82): completes the L6: action disable — dispatch-time consult on the same ledger (ADR-0126 §8.2, amendment ruling 3) #12160 surface-row deliverable — actions section on the L5 page, switch only, ledger read via the object's own sanctioned data API, refusals verbatim; ⛔ no action clone, no drift surface (§9) - L7 — docs correction (L7: correct the two "customize in Studio" promise pages to per-regime truth (ADR-0126 §8.4) #12161 · PR docs: promise per-regime customization truth on integrations + build-without-code (ADR-0126 §8.4) #12368 · merged
e3430a2):content/docs/capabilities/integrations.mdx+content/docs/build-without-code.mdxnow promise what each regime actually delivers — landed after L5 existed, per the §8.4 timing contract - L8 — ledger convergence (Ledger convergence: registration home + one store implementation + permission-set convergence (ADR-0126 §4/§8, maintainer-ruled bundle) #12159 · PR Ledger convergence: registration home + one store implementation (ADR-0126 §4/§8, maintainer-ruled) #12419 · merged
af56546a, maintainer-ruled bundle closing Ledger convergence: registration home + one store implementation + permission-set convergence (ADR-0126 §4/§8, maintainer-ruled bundle) #12159+Two implementations of the ADR-0126 §4 activation-ledger row contract (flow + action) — consolidate onto one #12350+Packaged-action disable is unavailable without the automation service —sys_metadata_activationhas only one registrant #12359): ①sys_metadata_activationregistration moved toPlatformObjectsPluginunder its own manifest carrying the originalscope/namespace/defaultDatasourcerouting verbatim (Packaged-action disable is unavailable without the automation service —sys_metadata_activationhas only one registrant #12359 option B; double registration measured NOT benign — ADR-0029 D3 throws, so MOVE was the only lawful shape; packaged-action disable now works without the automation service, dogfood-measured on both composition shapes); ② onemetadata_type-parameterized store in@objectstack/corereplaces both row-contract copies (Two implementations of the ADR-0126 §4 activation-ledger row contract (flow + action) — consolidate onto one #12350) — no API break, both pin suites byte-unchanged and ablation-proven to reach the shared code; ③ permission-set convergence concluded by ruling A: decline-and-record, family-wide (permission sets, positions, capabilities keep their ownactivecolumns; ruling record #12159 comment 5419767057) — no code
Recorded en route
- Non-packaged
toggleFlowstays in-process with a loud non-durability warning (option A of the feat(automation): durable packaged-flow disable — activation ledger, execute() consult, operator gate #12296 open question) — deliberately decides nothing; widening the ledger to non-packaged artifacts is a model question for the maintainer if pull appears. DELETE_RESTRICTEDgained its first derivable producer (the §7.3 guard); the error-status baseline was ratcheted down 34→33.- The ledger's datasource home is recorded as an open informational question (PR Ledger convergence: registration home + one store implementation (ADR-0126 §4/§8, maintainer-ruled) #12419 preserves today's routing verbatim, deliberately); revisit only on real pull — moving it later means moving the rows too.
- In-process
ScopedRepo.execute()bypasses the packaged-action activation consult (ADR-0126 §8) #12349 (in-processScopedRepo.execute()bypass) — still open for triage; ⛔ was never part of the L8 bundle. - L6-UI observations (recorded in objectui PR fix(metadata): sys_view_definition 的「活跃行唯一」补运行时 partial UNIQUE 迁移 (#5839) #6415, no cards): actions have no
_status-style read door (the page uses the ledger object's own sanctioned generic read; a future read door would be a drop-in), and a paginated (hasMore) ledger read is treated as load failure rather than rendered — a dropped row would show a switched-off action as armed.
Acceptance testing
- Manual acceptance card for the whole program: 验收测试:包内元数据定制(ADR-0126)——流程/动作的停用+克隆 全链路人工确认 #12438 (17 items, customer-seat, includes the known-boundaries list).
Relationships
- Design: post-install customization of packaged flows — clone-to-customize + org-level takeover (supersedes the org-tunable-parameters framing) #11665 (packaged-flow design card, first consumer) — sub-issue of this epic; closed 2026-08-25: the §7 flow surface works end-to-end (L1–L5 all merged)
- [finding] spec ships a three-layer metadata-customization protocol (MetadataOverlaySchema, field-level change tracking) with zero consumers — published reference docs describe an unimplemented customization architecture #12057 — related, excluded (v18)
- Packaged flow silently replaced by a same-named runtime flow: listItems returns both, the engine keys flows by bare name, and Map order decides the winner #11997 (same-name shadow diagnostics) — independent, not gated on this epic
Activity
sys_metadata_activationplatform object — the activation ledger (ADR-0126 §4) #12155fix(platform-objects): Setup nav entry for the packaged-automation pa…
qa+fix: ADR-0126 scoped checklist sweep (objectstack-ai#12438) + Setu…
docs(adr): ADR-0131 D6 — the unreleased ADR-0126 flow disable/clone m…
docs(adr): ADR-0131 — organization ownership is total: no NULL organi…