Skip to content

FE-1443: Declare protocol edges for import-invisible boundaries - #9263

Open
kube wants to merge 1 commit into
cf/fe-1414-arch-docs-support-python-packages-layers-and-docstringfrom
cf/fe-1443-arch-docs-declared-protocol-edges-for-import-invisible
Open

FE-1443: Declare protocol edges for import-invisible boundaries#9263
kube wants to merge 1 commit into
cf/fe-1414-arch-docs-support-python-packages-layers-and-docstringfrom
cf/fe-1443-arch-docs-declared-protocol-edges-for-import-invisible

Conversation

@kube

@kube kube commented Aug 21, 2026

Copy link
Copy Markdown
Collaborator

🌟 What is the purpose of this PR?

The architecture graph derives every edge from imports, so a coupling that crosses a process boundary is invisible: the Python bindings spawn the CLI and speak JSON lines with no import in either direction, and the cli layer showed no consumers. This PR adds one annotation for such boundaries, written in the boundary file's doc comment or docstring:

@talksTo cli via JSON lines over stdio (spawned subprocess)

The declaring file's own layer is the edge source. The edge renders dashed with the protocol as its label, and layer pages list it in its own "Declared" table.

In stack #9280, FE-1414 (#9230) sits below and FE-1447 (#9264) above.

🔗 Related links

  • FE-1443 (internal): this PR
  • FE-1415 (internal): complementary. No Python import crosses the subprocess boundary either, so both are needed.

🔍 What does this change?

libs/@local/petrinaut-arch-docs:

  • Tag (tags.ts): @talksTo <layer-id> via <protocol> is collected by the same TypeScript-comment and Python-docstring scan as @layerRoot/@role. The tag is repeatable, and a malformed tag is a diagnostic.
  • Model (model.ts): Edge becomes a discriminated union on provenance ("imports" | "declared"), and declared edges carry a protocol.
  • Graph (graph.ts): declared edges append after import aggregation. The build errors on an unknown target, on a pair the imports already prove, and on a duplicate declaration.
  • Diagrams (d2.ts): declared edges render dashed with the protocol label in all three diagram kinds, and a declared neighbour bypasses the 12-neighbour cap so it cannot be elided.
  • Pages (mdx.ts): a "Declared" table (Layer | Protocol) sits under "Depends on" and "Depended on by", separate from the import tables.
  • Rules (check.ts): forbidden-edge rules apply to import edges only.
  • First use: the bindings package declares its edge to cli, so the bundle gains one edge.
  • Docs: "Declaring a protocol edge" sections in the maintaining guide and the package README; the root AGENTS.md now says the vocabulary is three tags.

Review fixes

  • A @talksTo naming the declaring file's own layer is an error, with a test.
  • The protocol label is the text between via and the end of the line, with a test; prose on the next line stays out of the label.
  • ARCHITECTURE_MODEL_VERSION is bumped to 2 for the new edge shape, and build.ts writes the constant instead of a literal 1.
  • The declared-edge D2 class uses stroke-dash: 2, distinct from the boundary class's stroke-dash: 4, and three inline provenance checks now call isImportEdge.
  • content/optimizer/subprocess-boundary.mdx now says the diagrams draw this boundary as a dashed declared edge; its earlier claim that no diagram shows the edge became false with this PR.

Pre-Merge Checklist 🚀

🚢 Has this modified a publishable library?

This PR:

  • modifies a workspace but not a publishable library

📜 Does this require a change to the docs?

The changes in this PR:

  • require changes to docs which are made as part of this PR

🕸️ Does this require a change to the Turbo Graph?

The changes in this PR:

  • do not affect the execution graph

🛡 What tests cover this?

  • tags.test.ts: parsing in TypeScript comments and Python docstrings, the line-terminated protocol text, malformed tags, and the miscasing suggestion.
  • graph.test.ts (new): resolution, an unknown target, a self-target, a pair the imports already prove, and a duplicate declaration.
  • d2.test.ts / mdx.test.ts: the dashed edge with its protocol label, and the Declared table in both directions.

❓ How to test this?

  1. yarn workspace @local/petrinaut-arch-docs lint:arch-docs passes with the declared edge in place.
  2. turbo run dev --filter @apps/petrinaut-docs: the python-bindings and cli layer pages show the declared edge dashed in their neighbourhood diagrams and in a "Declared" table.

🤖 Generated with Claude Code

@vercel

vercel Bot commented Aug 21, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
hash Ready Ready Preview Aug 22, 2026 3:06am
petrinaut Ready Ready Preview Aug 22, 2026 3:06am
petrinaut-docs Ready Ready Preview Aug 22, 2026 3:06am
1 Skipped Deployment
Project Deployment Actions Updated (UTC)
hashdotdesign-tokens Ignored Ignored Preview Aug 22, 2026 3:06am

@github-actions github-actions Bot added area/infra Relates to version control, CI, CD or IaC (area) area/libs Relates to first-party libraries/crates/packages (area) type/eng > backend Owned by the @backend team labels Aug 21, 2026
@kube
kube marked this pull request as ready for review August 21, 2026 00:14
Copilot AI balanced review requested due to automatic review settings August 21, 2026 00:14
@cursor

cursor Bot commented Aug 21, 2026

Copy link
Copy Markdown

PR Summary

Medium Risk
Breaks the published architecture model shape (version 2) and changes how the graph, diagrams, and layer-rule checks treat edges. Scope is docs generation, not runtime product code.

Overview
Architecture docs can now record couplings that never appear as imports. A new @talksTo <layer-id> via <protocol> tag (TS comments or Python docstrings) draws a declared edge from the file’s own layer, so process/protocol boundaries show up in the graph.

The model bumps to version 2: Edge is a discriminated union (imports vs declared). Declared edges are dashed and protocol-labelled in every diagram, listed in a separate Declared table, and skipped by import-rule checks. The build fails on unknown targets, self-edges, duplicates, or pairs already proven by imports.

First use: Python bindings session.py talks to cli over JSON lines on stdio. Guides and AGENTS.md document the third tag.

Reviewed by Cursor Bugbot for commit 518942e. Bugbot is set up for automated code reviews on this repo. Configure here.

@kube kube changed the title cf/fe 1443 arch docs declared protocol edges for import invisible FE-1443: Declare protocol edges for import-invisible boundaries Aug 21, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

Comment thread libs/@local/petrinaut-arch-docs/src/model.ts

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

Comment thread libs/@local/petrinaut-arch-docs/src/graph.ts

@cursor cursor 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.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 5c86b79. Configure here.

Comment thread libs/@local/petrinaut-arch-docs/src/emit/d2.ts
@kube
kube force-pushed the cf/fe-1443-arch-docs-declared-protocol-edges-for-import-invisible branch from 5c86b79 to bb7c1e8 Compare August 21, 2026 09:57
@kube
kube force-pushed the cf/fe-1443-arch-docs-declared-protocol-edges-for-import-invisible branch from bb7c1e8 to 03b241b Compare August 21, 2026 12:07
@kube
kube force-pushed the cf/fe-1443-arch-docs-declared-protocol-edges-for-import-invisible branch from 03b241b to 75189a9 Compare August 21, 2026 14:52
@kube
kube force-pushed the cf/fe-1443-arch-docs-declared-protocol-edges-for-import-invisible branch from 75189a9 to 9f70a1a Compare August 21, 2026 15:09
@kube
kube force-pushed the cf/fe-1443-arch-docs-declared-protocol-edges-for-import-invisible branch from 9f70a1a to 5503bd8 Compare August 21, 2026 15:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/infra Relates to version control, CI, CD or IaC (area) area/libs Relates to first-party libraries/crates/packages (area) type/eng > backend Owned by the @backend team

Development

Successfully merging this pull request may close these issues.

2 participants