Skip to content

docs(design): a node's address is its logical ID on the platform (ADR-0051) - #352

Merged
wmadden merged 3 commits into
mainfrom
docs/logical-id-identity
Oct 9, 2026
Merged

wmadden merged 3 commits into
mainfrom
docs/logical-id-identity

Conversation

@wmadden-electric

Copy link
Copy Markdown
Contributor

Every node's address is its identity on Prisma Cloud. Composer writes it, byte for byte, as the logicalId of the node's platform row and of its node in the branch's application topology:

node address   topology node          platform row
shop           logicalId "shop"       Project   logicalId "shop"
catalog        logicalId "catalog"    Database  logicalId "catalog"   id db_cm3x…
auth.api       logicalId "auth.api"   App       logicalId "auth.api"  id app_7f2…

Console and CI join topology nodes to rows, and one node across branches, by string equality on logicalId. If the two strings differ at all, those reads find nothing.

Why this needs an ADR

The rule existed only in the pdp-control-plane branch topology spec and one line of .drive/projects/build-reporting/plan.md. Composer's own design docs never stated it. As a result, prisma/composer#344 wrote database logicalIds through a separate Composer resource. Upstream alchemy (alchemy-run/alchemy#1849) now has a logicalId prop, but it defaults to Alchemy's resource ID (catalog-db), which is wrong for us.

What the docs now say

  • ADR-0051:
    • The value is the address. It is never an Alchemy resource ID, a display name or a platform id.
    • Only the node's own row carries it: Project, App, Database or Bucket.
    • App, Database and Bucket get it as a prop on the upstream resource that creates them. The Project gets it from container resolution.
    • A provision ID defaults to the node's name, so changing a name changes identity. That is not a rename. A rename changes a display name and nothing else.
  • Amendments:
    • ADR-0006: a node's name is part of its identity.
    • ADR-0024: the Project is found by logicalId. Matching by display name is only a fallback.
  • The same rule in the places readers look:
    • a target-agnostic architectural principle
    • the glossary
    • core-model's "Deployment identity"
    • the PDP data model
    • a new "Platform identity" section in alchemy-lowering, with which resource writes the logicalId for each node kind, and the current status
  • Follow-ups, recorded in the build-reporting plan:
    • With prisma deploy --name, the topology root's logicalId differs from the Project's. pipeline.ts loads the reported graph without the override. This is a code defect.
    • Upgrade alchemy and pass logicalId: id on App, Database and Bucket in the same change.
    • Narrow the Project display-name fallback.
    • Ask pdp to fix its example node catalog-db.

Docs only; no code changes.

Alternatives considered

These are in the ADR: using Alchemy's default, writing the field with a separate resource as #344 does, putting platform ids in the topology, matching on display names, and having Console read Alchemy state.

Agent: moby-95

🤖 Generated with Claude Code

wmadden-electric and others added 3 commits October 9, 2026 11:35
…-0051)

Record that Composer writes each node's address, byte for byte, as the
logicalId of the node's platform row and of its topology node. Add the
rule to the architectural principles, glossary, core model, PDP data
model and Alchemy lowering docs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: willbot <w.a.madden+machine@gmail.com>
Signed-off-by: Will Madden <madden@prisma.io>
State that a node name is its default provision ID, so changing it
changes identity. Amend ADR-0006 and ADR-0024. Scope the single-writer
rule, correct the supporting-row lists, keep the principle
target-agnostic, and record the current status and open follow-ups.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: willbot <w.a.madden+machine@gmail.com>
Signed-off-by: Will Madden <madden@prisma.io>
Root addresses may contain "-". Changing an identity is never a rename.
Changing the root name leaves the old Project in place. Record the
remaining follow-ups in the build-reporting plan.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: willbot <w.a.madden+machine@gmail.com>
Signed-off-by: Will Madden <madden@prisma.io>
@prisma-gizmo

prisma-gizmo Bot commented Oct 9, 2026 •

Copy link
Copy Markdown

✅ Gizmo reviewed f04d98a — posted 1 inline comment(s) this pass.

Open findings: 🟡 1 minor

Change walkthrough

This PR is docs-only: it adds ADR-0051 — every node's address is written byte for byte as the logicalId of its platform row and of its node in the branch's application topology — and threads that rule through the docs a reader would actually consult.

The ADR itself. ADR-0051 states the rule, a worked example mapping addresses → topology nodes → platform rows, the reasoning (the platform joins on string equality), what the value is never (Alchemy resource ID, display name, platform id), which single resource writes each row's logicalId, consequences (name changes re-identify; display-name changes don't), and five rejected alternatives. Every code claim checked out against the checkout: the [A-Za-z0-9] provision-ID charset matches load-module.ts, the resource-ID forms match the descriptors (-svc, -db, -bucket), the POST /v1/projects create-with-logicalId matches container.ts, and the topology endpoint matches application-topology.ts.

Amendments and index. ADR-0006 and ADR-0024 each gain an amendment note, and the ADR index (README.md) gains matching notes plus a new ADR-0051 entry — the established amendment pattern in this repo.

Restating the rule where readers look. A target-agnostic principle lands in architectural-principles.md, a new "Address and logical ID" entry in the glossary (correctly placed under "Core nouns"), a "Deployment identity" tie-in paragraph in core-model, and an "Identity: id, logicalId, displayName" section in the PDP data model, mirroring the ADR's identifier table.

The lowering side. alchemy-lowering.md gains a "Platform identity" section with a per-node-kind table (which resource writes the logicalId), plus a Status block that honestly discloses two gaps: App/Database/Bucket rows lack the prop until the upstream alchemy upgrade ships, and a --name defect (verified real: pipeline.ts:129 vs deploy.ts:578).

Follow-ups. The build-reporting plan records five open items; all five were verified as accurate descriptions of current code, including the resolveProject fallback over-match and the pdp spec's catalog-db example.

@coderabbitai

coderabbitai Bot commented Oct 9, 2026

Copy link
Copy Markdown

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: ASSERTIVE
  • Plan: Advanced
  • Run ID: 6acbfddf-c66d-4495-bb2f-194d41a5c037

  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Comment @coderabbitai help to get the list of available commands.

@prisma-gizmo prisma-gizmo Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New findings: 🟡 3 minor · trace

Findings outside the diff

  • 🟡 Minor · correctness packages/0-framework/3-tooling/cli/src/pipeline.ts — Documented identity invariant is violated by shipped code: prisma deploy --name submits a topology root that matches no Project row
    ADR-0051 declares the root node's topology logicalId and the Project row's logicalId must be byte-identical, but with prisma deploy --name <n> they diverge: deploy.ts:578 loads the deploy graph with Load(root, { id: opts.name }) (so the Project's logicalId is the --name value), while pipeline.ts:129 loads the reported graph with plain Load(entryModule.root) (so the topology root node is submitted under the module's own name). The platform's join on logicalId then finds nothing for the root node. The PR documents this honestly as a defect in alchemy-lowering.md and tracks the fix in plan.md's follow-ups, but the invariant the docs now state is not yet true of the shipped code.
    Recommended fix: Apply the tracked fix: have pipeline.ts load the reported graph with the same id override as the deploy child, e.g. Load(entryModule.root, opts.name ? { id: opts.name } : undefined), in the same change that ships ADR-0051's follow-ups.
  • 🟡 Minor · correctness packages/1-prisma-cloud/0-lowering/lowering/src/container.ts — Project display-name fallback can adopt a Project that already has a different logicalId
    ADR-0051 says identity is logicalId and the display-name path exists only for Projects "created before they carried a logicalId", but container.ts:100-104 matches any Project whose name equals the app name, including Projects that already have a different logicalId — the CLI would then adopt the wrong Project and deploy into it. The PR records this in plan.md's follow-ups, so it is tracked, but until the fallback is narrowed the docs' compatibility-path claim is broader than the code's behavior.
    Recommended fix: Narrow the fallback as plan.md proposes: filter the display-name candidates to p.logicalId == null so a Project that already carries a different logicalId is never adopted by name.

Status:

- The Project carries its `logicalId` when Composer created it. Projects created before that are found by display name and have none.
- App, Database and Bucket need the `logicalId` prop that upstream alchemy added in [alchemy-run/alchemy#1849](https://github.com/alchemy-run/alchemy/pull/1849). Until Composer upgrades to a release that includes it, those rows have no `logicalId` and match no topology node. The upgrade must pass `logicalId: address` in the same change: an upgrade alone would write the Alchemy resource ID (`catalog-db`) onto every existing row.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Minor · consistency — Bucket logicalId writer attributed to upstream alchemy#1849, contradicting the cited ADR-0048

The status bullet says the App, Database and Bucket rows get their logicalId prop from "the upstream Alchemy resource that creates the row", citing ADR-0048 (ADR-0051 states the same at line 49). But ADR-0048 still says Composer "defines its own resources only where the upstream provider has no support yet (buckets, whose routes upstream deferred)". Current code uses upstream Prisma.Bucket/Prisma.BucketProvider() (providers.ts, descriptors/bucket.ts), so this ADR matches the code — but a reader following the citation lands in a document that states the opposite, and unlike ADR-0006/ADR-0024, ADR-0048 got no amendment note for a decision this ADR relies on.

Recommended fix

Add an amendment note to ADR-0048 (and its README index entry) recording that the bucket family now composes upstream's Prisma.Bucket provider, mirroring the ADR-0006/ADR-0024 amendment notes this ADR added — or soften the citation here and in ADR-0051.

@prisma-gizmo prisma-gizmo Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No critical or major Gizmo finding is open and the head commit has been reviewed. Approving.

@wmadden
wmadden merged commit 89cf354 into main Oct 9, 2026
24 checks passed
@wmadden
wmadden deleted the docs/logical-id-identity branch October 9, 2026 11:23
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.

2 participants