docs: target-architecture north-star for the monorepo#395
Conversation
Add docs/target-architecture.md: the repo-wide end-state the monorepo converges on, as a small set of invariants (where a file lives, how it behaves) plus the target directory structure per package. The app packages are thin delivery adapters over the pipefy SDK gateway; they own their delivery concerns but only expose Pipefy surfaces under a delivery-role folder (tools/, commands/), never as root-level domain folders. Reference it from docs/architecture.md (which keeps the rules enforced today and the enforcement machinery), and add index entries in AGENTS.md and docs/README.md.
ecbcfae to
4273ff6
Compare
…escape hatch The MCP server exposes a fixed meta-tool surface (search/describe/execute/ categories) over a hidden, validated tool catalog, plus a raw-GraphQL escape hatch; only those appear in tools/list. This splits the exposed protocol surface (dispatch/) from the Pipefy catalog (tools/), moves the argument-parse boundary into the dispatcher (schema derived from the body signature), and enforces remote default-deny in dispatch. The CLI keeps direct command exposure. Update the Decisions, WHERE-2, HOW-1/HOW-4, the server tree, the CLI note, and the toolsets.py relationship accordingly.
|
suggestion (non-blocking): Two things make the name misfit its contents. First, terminology collision. "Extension" is already loaded in MCP: the protocol has capabilities and capability negotiation, so Second, and more fundamental, the folder groups by "code that touches the MCP SDK", which is a technical dimension rather than a concern. That is the same shape as Each member has an owning concern to go to, which lets the bucket dissolve (consistent with "cross-cutting code lives in its concern, never a pattern bucket"):
If the grouping is deliberate, containing FastMCP private-API coupling ( |
|
Addressed in 226a13e, going with dissolving the bucket plus a narrower replacement rather than a rename.
|
Add an Architectural style section as the reading lens: this is an integration and capability-provider system, so system-scale domain/application/infrastructure layering leaves empty boxes. Name the fitting patterns instead (strategic DDD, SDK as a client-library gateway, MCP server as a microkernel, package-by-feature and concern), and state that the use-case layer is externalized to the caller. Reorganize Decisions around whose use case: a gateway operation is one of Pipefy's own use cases seen from outside, so the SDK exposes Pipefy's use cases and never the consumer's. Fold the composition, sharing, and exposure points into the boundary rule and the two-hop exposure chain. Recast the SDK-internal roles note as the worked example of splitting a package into model, repository, and service, with Pipefy as the authority for the advisory logic the SDK mirrors. Align stray system-scale layer language.
What
Adds
docs/target-architecture.md, the repo-wide north-star for the monorepo, and wires it into the doc map.The doc describes the end-state the packages converge on, not the current code, as a small set of invariants plus the target directory structure per package:
pipefy-mcp-server,pipefy-cli) are thin delivery adapters over thepipefySDK. They own no domain tier and expose Pipefy surfaces but own none of them.pipefySDK is the gateway and the only place the Pipefy domain is modeled, grouped by Pipefy bounded context.The rules answer two questions: where a file lives (concern folders, delivery-role surface folder, center +
wiring/, type ownership) and how it behaves (parse at the boundary, effects built once inwiring/, published-contract DAG with telemetry as a sink, one response-shaping seam over the SDK's typed models).A load-bearing point: an app owns its delivery concerns (
auth,telemetry,response,wiringat the package root) but only carries Pipefy surfaces, which group under one delivery-role folder (tools/on the server,commands/on the CLI). Acards/folder at an app root would be a hollow domain slot that invites SDK domain logic to leak upward and would mirror the SDK's context taxonomy as app structure.Meta-tool surface (server)
The MCP server exposes a fixed meta-tool surface (
search_tools,describe_tool,execute_tool,get_tool_categories) over a hidden, validated tool catalog, plus a raw-GraphQL escape hatch (search_schema,introspect_*,execute_graphql). Only those appear intools/list; the real tool bodies are reached by name throughexecute_tool. This keeps the exposed tool-list small (a context-budget concern) and makes the catalog a runtime artifact rather than a protocol dump.Consequences captured in the doc:
dispatch/is an owned delivery concern andtools/becomes the hidden catalog (WHERE-2); the argument-parse boundary moves into the dispatcher, against a catalog schema derived from each body's typed signature (HOW-1); response shaping happens at the dispatch boundary (HOW-4); telemetry observes each dispatched body rather than the meta-tool boundary; and remote default-deny is enforced in dispatch. The CLI has no such surface (a CLI is discovered by--help), so it keeps direct command exposure. That server/CLI asymmetry is deliberate and stated in the doc.Why here vs
architecture.mddocs/architecture.mdkeeps the rules enforced today and the machinery that enforces them (import-linter contract set, ruffTID251).target-architecture.mdholds only the end-goal; each invariant moves intoarchitecture.mdas the code comes to obey it. The migration is incremental PRs, not a plan recorded in this doc.Changes
docs/target-architecture.md.docs/architecture.md: two pointers to the target doc.AGENTS.md,docs/README.md: index entries.Testing
Docs-only; no code paths touched. Verified the doc is free of em/en dashes and curly quotes, headings are sentence case, and prose is single-line per paragraph.