Skip to content

service-datasource: createDatasource / updateDatasource write sys_metadata without the save door, so they can mint or flip a datasource to managed under objects bound external (ADR-0015 §4.2) #25277

Open

Description

@objectstack-fleet

Filing gate ③: a finding of the contract review of PR #25257 (record 6347940824, ③), first reported by its dev as a class-b finding with no carrier, and disposed in the seat's ACCEPT 6348040277 (item 5). It does not block that PR, which merged as bda53bb0b (card #25211).

  • Who acts: domain:services.
  • Dedupe: none found.

What happens on main (at bda53bb0b)

  • Since fix(metadata-protocol, spec)!: the save doors and composeStacks refuse an external binding on a named managed datasource #25257, the metadata-protocol save door refuses a datasource saved or changed to managed (including schemaMode unset) while stored objects bind it with external, naming the bound objects (422 INVALID_METADATA). The rule is one spec predicate, externalBindingDatasourceRefusal (packages/spec/src/data/external-binding-datasource.ts:90, exported).
  • The datasource-admin service does not go through that door. createDatasource (packages/services/service-datasource/src/datasource-admin-service.ts:608) and updateDatasource (:654) write through putDatasourceRecord (datasource-admin-plugin.ts:418), which calls metadata.register(...) and persistDatasourceRow (:152, a direct sys_metadata insert / update). saveMetaItem is never entered.
  • So the admin API (POST, and the PATCH that edits schemaMode) can make a datasource managed under objects already bound external — the pair the save door now refuses.

Wanted

  • createDatasource and updateDatasource judge the MERGED record against the objects bound to it with external, through the exported predicate (one copy of the rule), and refuse with the ADR-0112 envelope this service already uses, naming the bound objects. The service already has listObjects / countBoundObjects.
  • A federated datasource (schemaMode: 'external' or 'validate-only') and a datasource no object binds keep their answers.

Acceptance

  • Pinned: the admin POST and PATCH that would make a bound datasource managed are refused and nothing is stored or registered; the same calls with no external-bound object succeed.
  • Ablation: remove the judgement, the refusal pins go red, the controls stay green.
  • Clause-② / Metadata-protocol declared per AGENTS.md (an admin-API accept set narrows).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions