Skip to content

feat(scope): portable app-scope + function-resolution modules#101

Merged
pyramation merged 1 commit into
mainfrom
feat/app-scope-function-resolution
Jul 17, 2026
Merged

feat(scope): portable app-scope + function-resolution modules#101
pyramation merged 1 commit into
mainfrom
feat/app-scope-function-resolution

Conversation

@pyramation

Copy link
Copy Markdown
Contributor

Summary

Adds two portable pgpm modules for scope-chain resolution, plus the small upstream deltas they depend on. Everything is SELECT-only dynamic SQL (format('%I') + EXECUTE ... USING) — no AST/deparser runtime and no core-metaschema resolver functions — so the closure installs into any provisioned database whose metaschema catalog is populated.

New modules

  • @pgpm/app-scope (schema app_scope) — the reusable primitive. Given (database_id, execution_scope, entity_id) it returns ordered scope frames (scope, lookup_database_id, key_value), most-specific first, for a nearest-wins lookup. Each database climbs its own entity → … → org → app, then falls through to the platform database's database → org → app → platform. The platform database is not a special case — it climbs the identical shape with platform as the terminal global frame. database is a synthetic frame keyed by database_id, bridged to its owning org via metaschema_public.database.owner_id. NULL execution scope raises.

    team exec in a tenant DB → frames:
     0 tenant   team        (team_id)
     1 tenant   department  (department_id)
     2 tenant   org         (org_id)
     3 tenant   app         (NULL)
     4 platform database    (platform_db_id)
     5 platform org         (platform_org_id)
     6 platform app         (NULL)
     7 platform platform    (NULL)
    
  • @pgpm/function-resolution (schema function_resolution, built on app-scope) — resolve, probe, routing, definitions_location, resolve_invocation, and the resolver-aware enqueue. enqueue resolves (or trusts a supplied) definition, stamps (function_definition_id, definition_scope) + queue routing, then delegates the physical insert to app_jobs.add_job. app_jobs stays the generic, resolver-free queue primitive one layer below.

Required upstream deltas (previously unpushed)

  • database-jobs: app_jobs.add_job gains function_definition_id / definition_scope params and app_jobs.jobs gains the matching nullable columns (+ all-or-nothing CHECK), so function_resolution.enqueue can stamp the resolved definition. Purely additive; the existing scheduled-jobs test is unchanged (snapshot only grows the two new null columns).
  • jwt-claims: adds jwt_private.current_graph_execution_id(), a trivial JWT-claim getter matching the existing current_database_id pattern.

Conventions / housekeeping

  • Package metadata matches siblings: npm version on the current 0.32.x line, pgpm devDep ^4.28.7, extension/control/Makefile/sql/ bundle at the module's extension version (app-scope/function-resolution0.15.5). README files follow the sibling badge/overview/usage/testing format.
  • Both modules added to README.md, MODULES.md, and the CI test matrix in .github/workflows/ci.yml.
  • Every deploy/**/*.sql has matching verify/ and revert/ files.

Tests (local, pgsql-test)

  • app-scope 7/7 · function-resolution 22/22 (incl. portability test asserting AST/deparser + old metaschema_private resolvers are absent) · database-jobs 4/4 · jwt-claims 1/1.

Drift audit (not included here — needs a decision)

While checking for unpushed work, the standalone repo is generally ahead of the ConstructiveDB embedded copies (e.g. inflection 0.30.0, metaschema-schema 0.31.0). One entangled item remains: metaschema-modules is bidirectionally diverged — upstream has agent_module/db_preset_module/etc. that ConstructiveDB lacks, while ConstructiveDB has http_route_module. That is too intertwined to auto-sync and is left out pending a decision.

Link to Devin session: https://app.devin.ai/sessions/5ce15e7e50b3454496cf8e613b53280e
Requested by: @pyramation

Port the portable scope-chain resolution modules into the standalone
workspace:

- app-scope: ordered scope frames + platform database lookup. Reusable
  primitive, SELECT-only dynamic SQL (format('%I') + EXECUTE ... USING),
  no AST/deparser runtime.
- function-resolution: cross-scope function-definition resolution and
  resolver-aware enqueue, built on app-scope; delegates the physical
  insert to app_jobs.add_job.

Required dependency delta (previously unpushed upstream):
- database-jobs: add_job gains function_definition_id / definition_scope
  params and the jobs table gains the matching nullable columns so
  function_resolution.enqueue can stamp the resolved definition.
- jwt-claims: add current_graph_execution_id() JWT-claim getter.

Docs + CI: list both modules in README.md / MODULES.md and add them to
the CI test matrix.
@pyramation pyramation self-assigned this Jul 17, 2026
@devin-ai-integration

Copy link
Copy Markdown

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment, CI, and merge conflict monitoring

@pyramation
pyramation merged commit cfc41f3 into main Jul 17, 2026
25 checks passed
@pyramation
pyramation deleted the feat/app-scope-function-resolution branch July 17, 2026 16:53
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