Skip to content

feat(interface-dms-builder): list the database connections a module entry declares - #905

Open
Upd4ting wants to merge 4 commits into
feat/engine-database-connectfrom
feat/list-entry-catalog-connections
Open

Upd4ting wants to merge 4 commits into
feat/engine-database-connectfrom
feat/list-entry-catalog-connections

Conversation

@Upd4ting

@Upd4ting Upd4ting commented Nov 13, 2026 •

Copy link
Copy Markdown
Member

Why

ANT-2045's PR B moves the database connections of a disabled dms-builder or dms-assistant entry onto the DMS's entry in a one-time migration, so upgrading needs no manual step. core's ListModuleDeclarations drops importOverrides, and it cannot see a module that is disabled or not loaded. The migration needs to read those bindings as antelope.config.ts writes them.

Task: ANT-2412, stacked on #891.

⚠ sensitive: reads the external connections' access (permissions), read-only.

Summary

One owner-path, read-only operation on @antelopejs/interface-dms-builder. No MCP tool exposes it.

ListEntryConnections(module: string): Promise<OpResult<EntryConnection[]>>

interface EntryConnection {
  interface: string;            // @antelopejs/interface-database or -catalog
  source: string;               // the providing module
  id?: string;                  // absent for a plain pin
  access?: "read" | "read-write"; // as dms-database reads it; absent for a plain pin
}
ListEntryConnections(module)
  openDraft(antelope.config.ts)          the engine's own parser, any entry, disabled or not
  writtenModules → the entry             none → not_found (refused instead if `modules` hides members)
  entry or importOverrides not literal   → invalid_config "… is held in a way the builder cannot read"
  each binding read from the tree       a non-literal interface, source or id, a shorthand,
                                         a computed key or a spread → invalid_config
  an entry written as a version string   → [] (it holds no binding); the last entry under an id wins
  an unreadable member of modules after it → invalid_config (it may be that id)
  access per id                          #883's connectionAccess, inside withConnectionAccess:
                                         what dms-database receives for the launch environment

It is in Operations (interface and implementation), so the fast-reject map of #896 covers it after its rebase. The connect docs page gains its row.

Evidence

entry-connections.test.ts:

✔ lists a loaded entry's database bindings in order, with each connection's access
✔ lists a disabled entry, a connection dms-database does not register reading as read
✔ refuses an entry, or its importOverrides, written as a variable, naming where
✔ answers not_found for an entry the configuration does not have, and writes nothing
✔ refuses an entry holding a binding it cannot read, naming its importOverrides
✔ answers no binding for an entry written as a version, and ignores a dms-database written so
✔ reads the access from a dms-database keyed by its package, and the last entry written under an id
✔ refuses an entry a later member of modules may override, and reads one written after it
8 passing

With the importOverrides refusal removed, a variable silently reads as no binding:

1) refuses an entry, or its importOverrides, written as a variable, naming where
   AssertionError: expected '' to include 'importOverrides of module "shared" is…'
3 passing, 1 failing

An adversarial review found bindings dropped or downgraded (an id written as a variable read as a plain pin, a shorthand importOverrides read as nothing), access read elsewhere than dms-database reads it, and valid version-string entries refused. Their cases, against the reviewed code:

1) refuses an entry holding a binding it cannot read, naming its importOverrides
   AssertionError: an id written as a variable: expected '' to include 'importOverrides of module "dms-builde…'
2) answers no binding for an entry written as a version, and ignores a dms-database written so
   AssertionError: expected false to deeply equal []
3) reads the access from a dms-database keyed by its package, and the last entry written under an id
   AssertionError: expected [ { …(2) } ] to deeply equal [ { …(4) } ]
4 passing, 3 failing

A second review found that a computed key written after the entry, which overrides it at runtime, was ignored. The reader now refuses when a member of modules that it cannot name comes after the entry, and still reads an entry written after such a member. The case against the previous reader:

1) reading a module entry's bindings exactly as written
   AssertionError: expected '' to include '"modules" in the configuration is hel…'
7 passing, 1 failing

After both fixes, entry-connections has 8 cases, all passing. A binding added only under environments.<env>.modules is not read: the operation answers the entry as written.

operation-map and implement-interface pass with the new operation. backend-checks, oxlint and typecheck pass.

Merge Danger

Door: two-way. A new read-only operation; nothing else changes.

Blast Radius: builder.

It lands with #891's interface-dms-builder 0.5.0 release.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant