Refactor/backend stack split - relocate resolver domains to satellites#43
Open
gibbsie wants to merge 3 commits into
Open
Refactor/backend stack split - relocate resolver domains to satellites#43gibbsie wants to merge 3 commits into
gibbsie wants to merge 3 commits into
Conversation
added 3 commits
July 26, 2026 06:49
Seven gates protect any future movement of resources between stacks: a removals-only template diff proving retained resources stay byte-identical, logical-id pins with deletion-policy assertions on all 39 stateful resources, cross-stack resolver parity (every schema field attached exactly once), IAM privilege equivalence proving relocated roles never broaden beyond their baseline, behavioral equivalence on resolver mapping templates and data-source config, plus the existing doc-claims and infrastructure-lint gates — all runnable as one command against a committed synth baseline. Each gate is proven by negative tests: doctored templates with a removed stateful resource, weakened deletion policy, modified key schema, tampered mapping template, broadened IAM statement, and double-attached field each fail their gate.
…tack Relocates the project, conversation, document, assessment, and design-progress resolver Lambdas — 14 functions, 10 data sources, 23 resolver attachments, 4 event rules, 2 alarms — from the backend stack into a new projects stack that attaches to the same GraphQL API, following the established satellite pattern. The backend stack drops from 500 resources (the CloudFormation ceiling) to 375. Relocated functions carry no pinned names, eliminating recreation collisions; every stateful resource keeps its logical id and policies in place. All seven restructuring gates pass over the populated move manifest: removals-only template diff, 39 stateful logical-id pins, cross-stack resolver parity, IAM privilege equivalence for relocated roles, and byte-level behavioral equivalence of resolver mapping templates. Deploy order is backend first then projects; rollback is the reverse — the choreography is documented in the operator plan.
Relocates the agent registry domain — the 28-field agent-record resolver covering app lifecycle, API keys, access control, and metrics, plus agent import, registry sync, agent code, and fabricator request handling — 97 resources in all — into a new registry stack attached to the same GraphQL API. The backend stack drops from 375 to 278 resources, 44 percent below the CloudFormation ceiling. All seven restructuring gates pass across both relocated domains: template diffs are removals-only, all 39 stateful resources keep their logical ids and policies, every schema field stays attached exactly once, and relocated resolver templates byte-match their baselines. The agent-import role's Secrets Manager and STS statements are proven byte-identical to baseline by dedicated equality tests, not merely subset-equal. App publish and unpublish resolvers stay in the backend stack because they target a gateway-owned function; the agent-config resolver and gateway-registration handler are documented deferrals for a later batch.
|
|
||
| test("no other moved Lambda has functionName pinning (auto-named, invoked via in-stack grantInvoke)", () => { | ||
| const fns = template.findResources("AWS::Lambda::Function"); | ||
| for (const [logicalId, fn] of Object.entries(fns)) { |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The backend stack sat at 500 resources — the hard CloudFormation ceiling — blocking any new resolver, rule, or table. This relocates two resolver domains to dedicated satellite stacks attached to the same GraphQL API, using the pattern already proven by the governance and arbiter stacks. Backend drops to 278 resources (44% headroom). No stateful resource moves.
citadel-projects(14 Lambdas, 10 data sources, 23 resolvers, 4 rules, 2 alarms; 500→375)citadel-registry(97 resources incl. the 28-field agent-record resolver, agent import, registry sync, fabricator handlers; 375→278)What the gates prove (all green, run
npm run split:gates)Deliberate choices
Testing
Full backend suite 4,775 passed / 0 failed; 9-stack synth with cdk-nag clean; doc-claims verifier green; gates green post-rebase onto main.
Deploy (operator — read before merging)
This PR deploys in TWO ordered steps per phase, with a brief dark window per moved domain (those GraphQL fields 5xx between the two deploys):
cdk deploy citadel-backend-<env>(detaches moved resolvers)cdk deploy citadel-projects-<env>thencitadel-registry-<env>Rehearse with the projects stack in dev first; schedule the registry deploy off-peak (hot path). ROLLBACK is the reverse order — destroy/revert the satellite FIRST, then redeploy backend. Nevercdk deploy --allfor rollback: backend-first re-attachment fails on duplicate field resolvers. Smoke checks after each phase: getProject/sendMessage (projects); getApp/importAgent/registry record CRUD (registry).