[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill-aws-labs-multi-tenant-isolation":3,"mdc-iewrc3-key":37,"related-repo-aws-labs-multi-tenant-isolation":666,"related-org-aws-labs-multi-tenant-isolation":777},{"slug":4,"name":4,"fn":5,"description":6,"org":7,"tags":12,"stars":26,"repoUrl":27,"updatedAt":28,"license":29,"forks":30,"topics":31,"repo":32,"sourceUrl":35,"mdContent":36},"multi-tenant-isolation","design multi-tenant isolation for SaaS","This skill should be used when designing or fixing tenant isolation for a multi-tenant SaaS on AWS, where a team with no dedicated security engineer must make a cross-tenant leak structurally impossible rather than a code-review responsibility. Covers choosing a silo, pool, or bridge model per layer rather than per application, enforcing isolation in IAM session policies and the database so a forgotten predicate fails closed, partitioning data across DynamoDB, Postgres, and S3, containing noisy neighbors, and attributing cost per tenant in a pooled fleet. It should also be used when hardening an existing pooled deployment against cross-tenant access, or when one large customer demands dedicated infrastructure mid-deal. Not for single-tenant architecture or general IAM policy authoring, which belong to the aws-core skills upstream.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},"aws-labs","AWS Labs","https:\u002F\u002Fpexgzepcugksgbtrxkhf.supabase.co\u002Fstorage\u002Fv1\u002Fobject\u002Fpublic\u002Forg-logos\u002Faws-labs.png","awslabs",[13,17,20,23],{"name":14,"slug":15,"type":16},"Security","security","tag",{"name":18,"slug":19,"type":16},"SaaS","saas",{"name":21,"slug":22,"type":16},"Multi-Tenant","multi-tenant",{"name":24,"slug":25,"type":16},"AWS","aws",16,"https:\u002F\u002Fgithub.com\u002Fawslabs\u002Fstartups","2026-09-02T07:48:10.064573","Apache-2.0",27,[],{"repoUrl":27,"stars":26,"forks":30,"topics":33,"description":34},[],"Official AWS Startups repository that hosts plugins, skills, tools and resources to support startup builders on AWS","https:\u002F\u002Fgithub.com\u002Fawslabs\u002Fstartups\u002Ftree\u002FHEAD\u002Fsolution-architecture\u002Fplugins\u002Faws-startups-solution-architecture\u002Fskills\u002Fmulti-tenant-isolation","---\nname: multi-tenant-isolation\ndescription: \"This skill should be used when designing or fixing tenant isolation for a multi-tenant SaaS on AWS, where a team with no dedicated security engineer must make a cross-tenant leak structurally impossible rather than a code-review responsibility. Covers choosing a silo, pool, or bridge model per layer rather than per application, enforcing isolation in IAM session policies and the database so a forgotten predicate fails closed, partitioning data across DynamoDB, Postgres, and S3, containing noisy neighbors, and attributing cost per tenant in a pooled fleet. It should also be used when hardening an existing pooled deployment against cross-tenant access, or when one large customer demands dedicated infrastructure mid-deal. Not for single-tenant architecture or general IAM policy authoring, which belong to the aws-core skills upstream.\"\nlicense: Apache-2.0\nmetadata:\n  audience: startup\n---\n\n# Multi-Tenant Isolation on AWS\n\nTenant isolation is the architectural decision a SaaS startup is least able to reverse and most likely to get wrong under time pressure. Getting it wrong produces either a cross-tenant data leak, which is an existential incident for a company selling to businesses, or a per-tenant cost floor that makes the unit economics never work.\n\nThe mistake is treating it as one decision. It is a decision **per layer**, and the layers can differ.\n\n## Choose a model per layer, not per application\n\n| Model      | What it means                                    | Isolation                                | Cost per tenant             | Where it fits                                                               |\n| ---------- | ------------------------------------------------ | ---------------------------------------- | --------------------------- | --------------------------------------------------------------------------- |\n| **Silo**   | Dedicated resource per tenant                    | Strongest, enforced by resource boundary | Highest, floors multiply    | Regulated or contractual isolation, or one customer large enough to fund it |\n| **Pool**   | Shared resource, logical separation              | Weakest, depends on your correctness     | Lowest, marginal per tenant | Default for most tenants, especially self-serve                             |\n| **Bridge** | Shared infrastructure, dedicated slice inside it | Middle, enforced by partition            | Low to medium               | Pooled compute with per-tenant schema or table                              |\n\nPick per layer. A common and correct shape: pooled compute, bridge-model database (schema or partition key per tenant), siloed only for the customer whose contract requires it.\n\n**The trap.** Going full silo because it is easier to reason about, then discovering the fixed floors multiply by tenant count. Each dedicated Aurora Serverless v2 cluster carries a floor around 0.5 ACU whether or not the tenant is active. Each OpenSearch Serverless collection carries a substantial monthly minimum. Ten silo tenants on floored services is a large bill for near-zero usage. Verify current minimums with the `aws-billing-and-cost-management` skill in `aws-core` before committing to a silo model, since these change.\n\n**The other trap.** Going full pool and enforcing isolation with a `WHERE tenant_id = ?` clause in application code. That makes every future query a potential cross-tenant leak, and the blast radius of one missing predicate is every customer.\n\n## Enforce isolation below the application, not inside it\n\nIf a developer can write a query that returns another tenant's rows, isolation is a code-review problem forever. Push enforcement into a layer that fails closed.\n\n**Dynamic session policies.** Have the request path assume a role with a scoped-down session policy carrying the tenant identifier, so the credentials themselves cannot reach another tenant's data. The `aws-iam` skill in `aws-core` covers `AssumeRole` and policy authoring mechanics; what matters here is the pattern:\n\n- Derive the tenant identifier from a verified token claim, never from a request header, path parameter, or body field that a client controls.\n- Scope with IAM policy conditions on the resource path (leading keys for DynamoDB, key prefixes for S3), so authorization is evaluated by IAM rather than by your code.\n- Cache assumed credentials per tenant for the session lifetime. Assuming a role on every request adds latency and hits API limits.\n\n**Database-layer enforcement.** For Postgres, row-level security with a session variable set from the verified tenant context means a forgotten predicate returns zero rows instead of another tenant's data. That is the correct failure direction. For DynamoDB, put the tenant identifier in the partition key and use IAM leading-key conditions.\n\n**Test the negative case.** An isolation test that only asserts a tenant sees their own data proves nothing. Assert that tenant A's credentials, used against tenant B's identifier, are **denied**. That test is the isolation guarantee. Without it you have an intention.\n\n## Data partitioning by store\n\n- **DynamoDB.** Tenant identifier as partition key, or as the leading component of a composite key. Enables IAM leading-key conditions, which is the main reason to prefer it. Watch for a hot partition when one tenant is far larger than the rest.\n- **Postgres or Aurora.** Schema per tenant (bridge) reads cleanly and backs up per tenant, but connection and migration overhead grows with tenant count, and thousands of schemas becomes an operations problem. Shared tables with row-level security scale further with less per-tenant overhead. Pick based on expected tenant count and whether per-tenant restore is a requirement.\n- **S3.** Prefix per tenant with IAM conditions on the prefix. Bucket per tenant hits account bucket limits and is rarely worth it.\n- **Search and vector stores.** Check the per-collection or per-index floor before choosing silo. This is the layer where silo cost most often surprises teams.\n\n## Noisy neighbors\n\nPooled compute means one tenant's load degrades everyone. Before it happens:\n\n- Rate-limit per tenant, not just globally. A global limit lets one tenant consume the whole budget.\n- Keep a bulkhead so one tenant's backlog cannot exhaust shared capacity: separate queues or partitioned concurrency for heavy asynchronous work.\n- Know which tenant caused a spike. Emit the tenant identifier as a dimension on your metrics, or attribution after the fact is guesswork.\n\n## Per-tenant cost attribution\n\n\"Which customers are unprofitable\" is unanswerable later if you do not instrument it now, and it is the question that decides pricing.\n\n- Tag siloed resources with the tenant identifier for cost allocation.\n- Pooled resources cannot be split by tags. Attribute with a usage proxy you already emit (requests, storage bytes, compute milliseconds, tokens) and apportion the shared bill against it.\n- Emit that proxy from day one. Retrofitting per-tenant usage data across a pooled fleet is painful and often approximate.\n\n## When a large customer demands dedicated infrastructure\n\nThis is the startup's problem, not the customer's: a prospect big enough to change the\nrunway has asked for something the architecture does not do yet, and the deal is\nwaiting on the answer. It arrives as a sales requirement rather than a technical one,\nusually mid-deal, so the answer should already exist before it is asked.\n\n- If the contract requires physical isolation, silo that tenant only. Do not migrate the whole platform to silo for one customer.\n- A separate AWS account per siloed tenant gives the hardest boundary and the cleanest cost attribution, at the price of account management. See `Skill(\"aws-core:aws-iam\")` for cross-account patterns.\n- Keep one deployment pipeline across both models. Two divergent architectures is the outcome that actually hurts, because every future change ships twice.\n- Price it against the real floor, including the fixed monthly minimums that exist at zero usage.\n\n## Upstream skills to defer to\n\nDo not restate the mechanics these own. Invoke them directly, and spend the reasoning on the tenancy decision:\n\n- **`Skill(\"aws-core:aws-iam\")`**: IAM roles, `AssumeRole`, session policies, and policy conditions.\n- **`Skill(\"aws-core:aws-database\")`**: DynamoDB key design, Aurora and Postgres specifics.\n- **`Skill(\"aws-core:aws-compute\")`**: Compute capacity and scaling.\n- **`Skill(\"aws-core:aws-serverless\")`**: Per-function concurrency and partitioning.\n- **`Skill(\"aws-core:aws-messaging-and-streaming\")`**: Queue isolation and per-tenant bulkheads.\n- **`Skill(\"aws-core:aws-observability\")`**: Metric dimensions and per-tenant attribution.\n- **`Skill(\"aws-core:aws-billing-and-cost-management\")`**: Cost floors, minimums, and allocation tags.\n\n## Anti-patterns\n\n- Isolation enforced only by an application-layer predicate, with no IAM or database boundary behind it.\n- Tenant identity taken from a client-controlled header, path, or body field rather than a verified token claim.\n- Isolation tests that assert only the positive case and never that cross-tenant access is denied.\n- Choosing silo for every tenant without adding up the fixed floors at zero usage.\n- One tenancy model imposed on every layer because it is simpler to describe.\n- Adding the tenant dimension to metrics after the first noisy-neighbor incident.\n- A second architecture forked for one large customer, then maintained in parallel forever.\n",{"data":38,"body":41},{"name":4,"description":6,"license":29,"metadata":39},{"audience":40},"startup",{"type":42,"children":43},"root",[44,53,59,72,79,215,220,247,265,271,276,308,328,338,355,361,404,410,415,433,439,444,462,468,473,504,510,515,622,628],{"type":45,"tag":46,"props":47,"children":49},"element","h1",{"id":48},"multi-tenant-isolation-on-aws",[50],{"type":51,"value":52},"text","Multi-Tenant Isolation on AWS",{"type":45,"tag":54,"props":55,"children":56},"p",{},[57],{"type":51,"value":58},"Tenant isolation is the architectural decision a SaaS startup is least able to reverse and most likely to get wrong under time pressure. Getting it wrong produces either a cross-tenant data leak, which is an existential incident for a company selling to businesses, or a per-tenant cost floor that makes the unit economics never work.",{"type":45,"tag":54,"props":60,"children":61},{},[62,64,70],{"type":51,"value":63},"The mistake is treating it as one decision. It is a decision ",{"type":45,"tag":65,"props":66,"children":67},"strong",{},[68],{"type":51,"value":69},"per layer",{"type":51,"value":71},", and the layers can differ.",{"type":45,"tag":73,"props":74,"children":76},"h2",{"id":75},"choose-a-model-per-layer-not-per-application",[77],{"type":51,"value":78},"Choose a model per layer, not per application",{"type":45,"tag":80,"props":81,"children":82},"table",{},[83,117],{"type":45,"tag":84,"props":85,"children":86},"thead",{},[87],{"type":45,"tag":88,"props":89,"children":90},"tr",{},[91,97,102,107,112],{"type":45,"tag":92,"props":93,"children":94},"th",{},[95],{"type":51,"value":96},"Model",{"type":45,"tag":92,"props":98,"children":99},{},[100],{"type":51,"value":101},"What it means",{"type":45,"tag":92,"props":103,"children":104},{},[105],{"type":51,"value":106},"Isolation",{"type":45,"tag":92,"props":108,"children":109},{},[110],{"type":51,"value":111},"Cost per tenant",{"type":45,"tag":92,"props":113,"children":114},{},[115],{"type":51,"value":116},"Where it fits",{"type":45,"tag":118,"props":119,"children":120},"tbody",{},[121,153,184],{"type":45,"tag":88,"props":122,"children":123},{},[124,133,138,143,148],{"type":45,"tag":125,"props":126,"children":127},"td",{},[128],{"type":45,"tag":65,"props":129,"children":130},{},[131],{"type":51,"value":132},"Silo",{"type":45,"tag":125,"props":134,"children":135},{},[136],{"type":51,"value":137},"Dedicated resource per tenant",{"type":45,"tag":125,"props":139,"children":140},{},[141],{"type":51,"value":142},"Strongest, enforced by resource boundary",{"type":45,"tag":125,"props":144,"children":145},{},[146],{"type":51,"value":147},"Highest, floors multiply",{"type":45,"tag":125,"props":149,"children":150},{},[151],{"type":51,"value":152},"Regulated or contractual isolation, or one customer large enough to fund it",{"type":45,"tag":88,"props":154,"children":155},{},[156,164,169,174,179],{"type":45,"tag":125,"props":157,"children":158},{},[159],{"type":45,"tag":65,"props":160,"children":161},{},[162],{"type":51,"value":163},"Pool",{"type":45,"tag":125,"props":165,"children":166},{},[167],{"type":51,"value":168},"Shared resource, logical separation",{"type":45,"tag":125,"props":170,"children":171},{},[172],{"type":51,"value":173},"Weakest, depends on your correctness",{"type":45,"tag":125,"props":175,"children":176},{},[177],{"type":51,"value":178},"Lowest, marginal per tenant",{"type":45,"tag":125,"props":180,"children":181},{},[182],{"type":51,"value":183},"Default for most tenants, especially self-serve",{"type":45,"tag":88,"props":185,"children":186},{},[187,195,200,205,210],{"type":45,"tag":125,"props":188,"children":189},{},[190],{"type":45,"tag":65,"props":191,"children":192},{},[193],{"type":51,"value":194},"Bridge",{"type":45,"tag":125,"props":196,"children":197},{},[198],{"type":51,"value":199},"Shared infrastructure, dedicated slice inside it",{"type":45,"tag":125,"props":201,"children":202},{},[203],{"type":51,"value":204},"Middle, enforced by partition",{"type":45,"tag":125,"props":206,"children":207},{},[208],{"type":51,"value":209},"Low to medium",{"type":45,"tag":125,"props":211,"children":212},{},[213],{"type":51,"value":214},"Pooled compute with per-tenant schema or table",{"type":45,"tag":54,"props":216,"children":217},{},[218],{"type":51,"value":219},"Pick per layer. A common and correct shape: pooled compute, bridge-model database (schema or partition key per tenant), siloed only for the customer whose contract requires it.",{"type":45,"tag":54,"props":221,"children":222},{},[223,228,230,237,239,245],{"type":45,"tag":65,"props":224,"children":225},{},[226],{"type":51,"value":227},"The trap.",{"type":51,"value":229}," Going full silo because it is easier to reason about, then discovering the fixed floors multiply by tenant count. Each dedicated Aurora Serverless v2 cluster carries a floor around 0.5 ACU whether or not the tenant is active. Each OpenSearch Serverless collection carries a substantial monthly minimum. Ten silo tenants on floored services is a large bill for near-zero usage. Verify current minimums with the ",{"type":45,"tag":231,"props":232,"children":234},"code",{"className":233},[],[235],{"type":51,"value":236},"aws-billing-and-cost-management",{"type":51,"value":238}," skill in ",{"type":45,"tag":231,"props":240,"children":242},{"className":241},[],[243],{"type":51,"value":244},"aws-core",{"type":51,"value":246}," before committing to a silo model, since these change.",{"type":45,"tag":54,"props":248,"children":249},{},[250,255,257,263],{"type":45,"tag":65,"props":251,"children":252},{},[253],{"type":51,"value":254},"The other trap.",{"type":51,"value":256}," Going full pool and enforcing isolation with a ",{"type":45,"tag":231,"props":258,"children":260},{"className":259},[],[261],{"type":51,"value":262},"WHERE tenant_id = ?",{"type":51,"value":264}," clause in application code. That makes every future query a potential cross-tenant leak, and the blast radius of one missing predicate is every customer.",{"type":45,"tag":73,"props":266,"children":268},{"id":267},"enforce-isolation-below-the-application-not-inside-it",[269],{"type":51,"value":270},"Enforce isolation below the application, not inside it",{"type":45,"tag":54,"props":272,"children":273},{},[274],{"type":51,"value":275},"If a developer can write a query that returns another tenant's rows, isolation is a code-review problem forever. Push enforcement into a layer that fails closed.",{"type":45,"tag":54,"props":277,"children":278},{},[279,284,286,292,293,298,300,306],{"type":45,"tag":65,"props":280,"children":281},{},[282],{"type":51,"value":283},"Dynamic session policies.",{"type":51,"value":285}," Have the request path assume a role with a scoped-down session policy carrying the tenant identifier, so the credentials themselves cannot reach another tenant's data. The ",{"type":45,"tag":231,"props":287,"children":289},{"className":288},[],[290],{"type":51,"value":291},"aws-iam",{"type":51,"value":238},{"type":45,"tag":231,"props":294,"children":296},{"className":295},[],[297],{"type":51,"value":244},{"type":51,"value":299}," covers ",{"type":45,"tag":231,"props":301,"children":303},{"className":302},[],[304],{"type":51,"value":305},"AssumeRole",{"type":51,"value":307}," and policy authoring mechanics; what matters here is the pattern:",{"type":45,"tag":309,"props":310,"children":311},"ul",{},[312,318,323],{"type":45,"tag":313,"props":314,"children":315},"li",{},[316],{"type":51,"value":317},"Derive the tenant identifier from a verified token claim, never from a request header, path parameter, or body field that a client controls.",{"type":45,"tag":313,"props":319,"children":320},{},[321],{"type":51,"value":322},"Scope with IAM policy conditions on the resource path (leading keys for DynamoDB, key prefixes for S3), so authorization is evaluated by IAM rather than by your code.",{"type":45,"tag":313,"props":324,"children":325},{},[326],{"type":51,"value":327},"Cache assumed credentials per tenant for the session lifetime. Assuming a role on every request adds latency and hits API limits.",{"type":45,"tag":54,"props":329,"children":330},{},[331,336],{"type":45,"tag":65,"props":332,"children":333},{},[334],{"type":51,"value":335},"Database-layer enforcement.",{"type":51,"value":337}," For Postgres, row-level security with a session variable set from the verified tenant context means a forgotten predicate returns zero rows instead of another tenant's data. That is the correct failure direction. For DynamoDB, put the tenant identifier in the partition key and use IAM leading-key conditions.",{"type":45,"tag":54,"props":339,"children":340},{},[341,346,348,353],{"type":45,"tag":65,"props":342,"children":343},{},[344],{"type":51,"value":345},"Test the negative case.",{"type":51,"value":347}," An isolation test that only asserts a tenant sees their own data proves nothing. Assert that tenant A's credentials, used against tenant B's identifier, are ",{"type":45,"tag":65,"props":349,"children":350},{},[351],{"type":51,"value":352},"denied",{"type":51,"value":354},". That test is the isolation guarantee. Without it you have an intention.",{"type":45,"tag":73,"props":356,"children":358},{"id":357},"data-partitioning-by-store",[359],{"type":51,"value":360},"Data partitioning by store",{"type":45,"tag":309,"props":362,"children":363},{},[364,374,384,394],{"type":45,"tag":313,"props":365,"children":366},{},[367,372],{"type":45,"tag":65,"props":368,"children":369},{},[370],{"type":51,"value":371},"DynamoDB.",{"type":51,"value":373}," Tenant identifier as partition key, or as the leading component of a composite key. Enables IAM leading-key conditions, which is the main reason to prefer it. Watch for a hot partition when one tenant is far larger than the rest.",{"type":45,"tag":313,"props":375,"children":376},{},[377,382],{"type":45,"tag":65,"props":378,"children":379},{},[380],{"type":51,"value":381},"Postgres or Aurora.",{"type":51,"value":383}," Schema per tenant (bridge) reads cleanly and backs up per tenant, but connection and migration overhead grows with tenant count, and thousands of schemas becomes an operations problem. Shared tables with row-level security scale further with less per-tenant overhead. Pick based on expected tenant count and whether per-tenant restore is a requirement.",{"type":45,"tag":313,"props":385,"children":386},{},[387,392],{"type":45,"tag":65,"props":388,"children":389},{},[390],{"type":51,"value":391},"S3.",{"type":51,"value":393}," Prefix per tenant with IAM conditions on the prefix. Bucket per tenant hits account bucket limits and is rarely worth it.",{"type":45,"tag":313,"props":395,"children":396},{},[397,402],{"type":45,"tag":65,"props":398,"children":399},{},[400],{"type":51,"value":401},"Search and vector stores.",{"type":51,"value":403}," Check the per-collection or per-index floor before choosing silo. This is the layer where silo cost most often surprises teams.",{"type":45,"tag":73,"props":405,"children":407},{"id":406},"noisy-neighbors",[408],{"type":51,"value":409},"Noisy neighbors",{"type":45,"tag":54,"props":411,"children":412},{},[413],{"type":51,"value":414},"Pooled compute means one tenant's load degrades everyone. Before it happens:",{"type":45,"tag":309,"props":416,"children":417},{},[418,423,428],{"type":45,"tag":313,"props":419,"children":420},{},[421],{"type":51,"value":422},"Rate-limit per tenant, not just globally. A global limit lets one tenant consume the whole budget.",{"type":45,"tag":313,"props":424,"children":425},{},[426],{"type":51,"value":427},"Keep a bulkhead so one tenant's backlog cannot exhaust shared capacity: separate queues or partitioned concurrency for heavy asynchronous work.",{"type":45,"tag":313,"props":429,"children":430},{},[431],{"type":51,"value":432},"Know which tenant caused a spike. Emit the tenant identifier as a dimension on your metrics, or attribution after the fact is guesswork.",{"type":45,"tag":73,"props":434,"children":436},{"id":435},"per-tenant-cost-attribution",[437],{"type":51,"value":438},"Per-tenant cost attribution",{"type":45,"tag":54,"props":440,"children":441},{},[442],{"type":51,"value":443},"\"Which customers are unprofitable\" is unanswerable later if you do not instrument it now, and it is the question that decides pricing.",{"type":45,"tag":309,"props":445,"children":446},{},[447,452,457],{"type":45,"tag":313,"props":448,"children":449},{},[450],{"type":51,"value":451},"Tag siloed resources with the tenant identifier for cost allocation.",{"type":45,"tag":313,"props":453,"children":454},{},[455],{"type":51,"value":456},"Pooled resources cannot be split by tags. Attribute with a usage proxy you already emit (requests, storage bytes, compute milliseconds, tokens) and apportion the shared bill against it.",{"type":45,"tag":313,"props":458,"children":459},{},[460],{"type":51,"value":461},"Emit that proxy from day one. Retrofitting per-tenant usage data across a pooled fleet is painful and often approximate.",{"type":45,"tag":73,"props":463,"children":465},{"id":464},"when-a-large-customer-demands-dedicated-infrastructure",[466],{"type":51,"value":467},"When a large customer demands dedicated infrastructure",{"type":45,"tag":54,"props":469,"children":470},{},[471],{"type":51,"value":472},"This is the startup's problem, not the customer's: a prospect big enough to change the\nrunway has asked for something the architecture does not do yet, and the deal is\nwaiting on the answer. It arrives as a sales requirement rather than a technical one,\nusually mid-deal, so the answer should already exist before it is asked.",{"type":45,"tag":309,"props":474,"children":475},{},[476,481,494,499],{"type":45,"tag":313,"props":477,"children":478},{},[479],{"type":51,"value":480},"If the contract requires physical isolation, silo that tenant only. Do not migrate the whole platform to silo for one customer.",{"type":45,"tag":313,"props":482,"children":483},{},[484,486,492],{"type":51,"value":485},"A separate AWS account per siloed tenant gives the hardest boundary and the cleanest cost attribution, at the price of account management. See ",{"type":45,"tag":231,"props":487,"children":489},{"className":488},[],[490],{"type":51,"value":491},"Skill(\"aws-core:aws-iam\")",{"type":51,"value":493}," for cross-account patterns.",{"type":45,"tag":313,"props":495,"children":496},{},[497],{"type":51,"value":498},"Keep one deployment pipeline across both models. Two divergent architectures is the outcome that actually hurts, because every future change ships twice.",{"type":45,"tag":313,"props":500,"children":501},{},[502],{"type":51,"value":503},"Price it against the real floor, including the fixed monthly minimums that exist at zero usage.",{"type":45,"tag":73,"props":505,"children":507},{"id":506},"upstream-skills-to-defer-to",[508],{"type":51,"value":509},"Upstream skills to defer to",{"type":45,"tag":54,"props":511,"children":512},{},[513],{"type":51,"value":514},"Do not restate the mechanics these own. Invoke them directly, and spend the reasoning on the tenancy decision:",{"type":45,"tag":309,"props":516,"children":517},{},[518,538,552,566,580,594,608],{"type":45,"tag":313,"props":519,"children":520},{},[521,529,531,536],{"type":45,"tag":65,"props":522,"children":523},{},[524],{"type":45,"tag":231,"props":525,"children":527},{"className":526},[],[528],{"type":51,"value":491},{"type":51,"value":530},": IAM roles, ",{"type":45,"tag":231,"props":532,"children":534},{"className":533},[],[535],{"type":51,"value":305},{"type":51,"value":537},", session policies, and policy conditions.",{"type":45,"tag":313,"props":539,"children":540},{},[541,550],{"type":45,"tag":65,"props":542,"children":543},{},[544],{"type":45,"tag":231,"props":545,"children":547},{"className":546},[],[548],{"type":51,"value":549},"Skill(\"aws-core:aws-database\")",{"type":51,"value":551},": DynamoDB key design, Aurora and Postgres specifics.",{"type":45,"tag":313,"props":553,"children":554},{},[555,564],{"type":45,"tag":65,"props":556,"children":557},{},[558],{"type":45,"tag":231,"props":559,"children":561},{"className":560},[],[562],{"type":51,"value":563},"Skill(\"aws-core:aws-compute\")",{"type":51,"value":565},": Compute capacity and scaling.",{"type":45,"tag":313,"props":567,"children":568},{},[569,578],{"type":45,"tag":65,"props":570,"children":571},{},[572],{"type":45,"tag":231,"props":573,"children":575},{"className":574},[],[576],{"type":51,"value":577},"Skill(\"aws-core:aws-serverless\")",{"type":51,"value":579},": Per-function concurrency and partitioning.",{"type":45,"tag":313,"props":581,"children":582},{},[583,592],{"type":45,"tag":65,"props":584,"children":585},{},[586],{"type":45,"tag":231,"props":587,"children":589},{"className":588},[],[590],{"type":51,"value":591},"Skill(\"aws-core:aws-messaging-and-streaming\")",{"type":51,"value":593},": Queue isolation and per-tenant bulkheads.",{"type":45,"tag":313,"props":595,"children":596},{},[597,606],{"type":45,"tag":65,"props":598,"children":599},{},[600],{"type":45,"tag":231,"props":601,"children":603},{"className":602},[],[604],{"type":51,"value":605},"Skill(\"aws-core:aws-observability\")",{"type":51,"value":607},": Metric dimensions and per-tenant attribution.",{"type":45,"tag":313,"props":609,"children":610},{},[611,620],{"type":45,"tag":65,"props":612,"children":613},{},[614],{"type":45,"tag":231,"props":615,"children":617},{"className":616},[],[618],{"type":51,"value":619},"Skill(\"aws-core:aws-billing-and-cost-management\")",{"type":51,"value":621},": Cost floors, minimums, and allocation tags.",{"type":45,"tag":73,"props":623,"children":625},{"id":624},"anti-patterns",[626],{"type":51,"value":627},"Anti-patterns",{"type":45,"tag":309,"props":629,"children":630},{},[631,636,641,646,651,656,661],{"type":45,"tag":313,"props":632,"children":633},{},[634],{"type":51,"value":635},"Isolation enforced only by an application-layer predicate, with no IAM or database boundary behind it.",{"type":45,"tag":313,"props":637,"children":638},{},[639],{"type":51,"value":640},"Tenant identity taken from a client-controlled header, path, or body field rather than a verified token claim.",{"type":45,"tag":313,"props":642,"children":643},{},[644],{"type":51,"value":645},"Isolation tests that assert only the positive case and never that cross-tenant access is denied.",{"type":45,"tag":313,"props":647,"children":648},{},[649],{"type":51,"value":650},"Choosing silo for every tenant without adding up the fixed floors at zero usage.",{"type":45,"tag":313,"props":652,"children":653},{},[654],{"type":51,"value":655},"One tenancy model imposed on every layer because it is simpler to describe.",{"type":45,"tag":313,"props":657,"children":658},{},[659],{"type":51,"value":660},"Adding the tenant dimension to metrics after the first noisy-neighbor incident.",{"type":45,"tag":313,"props":662,"children":663},{},[664],{"type":51,"value":665},"A second architecture forked for one large customer, then maintained in parallel forever.",{"items":667,"total":776},[668,685,697,711,728,741,758],{"slug":669,"name":669,"fn":670,"description":671,"org":672,"tags":673,"stars":26,"repoUrl":27,"updatedAt":684},"agent-advisor","plan and build AWS AI agents","Unified entry point for AI-agent work on AWS: evaluate and pick a runtime, generate a full migration plan (for existing workloads), and build an executable POC — all in one flow. Triggers on: which runtime for my agent, AgentCore vs ECS vs EKS vs Lambda, AgentCore vs Lambda MicroVMs, deploy an AI agent on AWS, agent architecture on AWS, I have an agent idea what do I build, move my agents to AWS, migrate my agents to AWS with a plan, agent migration plan, add AgentCore services, add memory\u002Fgateway\u002Fidentity\u002Fpolicy to my agent, enable AgentCore Memory, add observability to my agent, I'm already on AWS and want to add agent capabilities, migrate Temporal workers to AWS, Temporal to AWS, run Temporal on AWS, Temporal workers on AWS, we use Temporal and want to move to AWS, our service is orchestrated by Temporal, what do I build on AWS for my Temporal workers, move a Temporal-based service to AWS, Temporal Cloud or self-hosted on AWS. Runs a phased flow: Intake (entry point + technical background), Discover (lightweight code detection), Clarify (adaptive questions), deterministic scoring, Design (runtime + deployment model + services + model), Estimate (coarse cost), Generate (layered recommendation doc + scaffolding), then optional gated stages: Migration Plan (full plan generated in-skill by reusing this plugin's gcp-to-aws engine, with the advisor's decisions carried over) and POC (deployment plan + deployable proof-of-concept on the recommended runtime — AgentCore, ECS, EKS, or Lambda; generated deliverables by default, or assisted build in your account on explicit opt-in). Systems with several workloads (interacting or independent agents, batch jobs, services) are decomposed into workload units, each getting its own verdict with a consolidation option. An add-capabilities branch (for teams already running agents on AWS) recommends which AgentCore services to enable on any runtime — no runtime scoring. Temporal systems dissolve into the same unit flow — worker polling tiers and Activity execution classes become units (rules in the Temporal decision reference); Workflow orchestration code is never rewritten — never a Step Functions translation. Requires at least one agentic component: a purely non-agent system (only plain services \u002F batch jobs \u002F HTTP endpoints, or a Temporal worker whose Activities are all non-agent) is out of scope — Clarify halts it (scope gate) and points to gcp-to-aws \u002F heroku-to-aws \u002F llm-to-bedrock. Not for: pure compute\u002Fdata migration with no AI agent; pure LLM SDK rewrite without agent architecture (use llm-to-bedrock); or detailed per-model pricing.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[674,677,680,681],{"name":675,"slug":676,"type":16},"Agents","agents",{"name":678,"slug":679,"type":16},"AI Infrastructure","ai-infrastructure",{"name":24,"slug":25,"type":16},{"name":682,"slug":683,"type":16},"Engineering","engineering","2026-08-23T03:33:24.455574",{"slug":686,"name":686,"fn":687,"description":688,"org":689,"tags":690,"stars":26,"repoUrl":27,"updatedAt":696},"agentcore-patterns","manage agent identity and attribution","This skill should be used when an automated agent's output is published under its own identity and carries weight in someone else's work, such as a reviewer whose verdict lands on a pull request, and the open question is how much authority it has actually earned. Covers which conclusions such an agent may state as settled and which it must hand to a person, why a verdict that moves between runs on unchanged input cannot be allowed to decide anything, handing an uncertain item to a human rather than discarding it, grounding each claim in something computed rather than recalled, and the published-state and recall behaviour that decides whether people keep reading the output or learn to skim it. It should also be used when such an agent is being ignored, contradicts itself between runs, or reports a state that nothing current supports. Not for measuring or improving an agent's own output quality, which belongs to aws-agents:agents-optimize, nor for building, deploying, or hardening an agent.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[691,692,695],{"name":675,"slug":676,"type":16},{"name":693,"slug":694,"type":16},"Best Practices","best-practices",{"name":682,"slug":683,"type":16},"2026-09-02T07:48:14.446305",{"slug":698,"name":698,"fn":699,"description":700,"org":701,"tags":702,"stars":26,"repoUrl":27,"updatedAt":710},"architect-for-startups","advise on AWS architecture for startups","Startup-tailored AWS architecture advice that adjusts recommendations to the company's stage (pre-revenue through Series B+), team size, runway, and available credits. Use when a founder wants guidance or a recommendation rather than code changes: which services to choose, how to plan or review an architecture, how to stretch credits and control cost, or how to prepare architecture for a fundraise or technical diligence. For an interactive discovery flow that scaffolds and writes the architecture into the codebase, use start-building-for-startups. For AI-agent runtime selection or agentic architecture recommendations specifically, use agent-advisor. Do not use for: writing or scaffolding code, factual AWS Activate \u002F programs \u002F credits lookups (see knowledge-base-for-startups), a single copy-paste prompt (see prompt-library-for-startups), or migration intent such as GCP-to-AWS or Heroku-to-AWS (see the migration skills: `gcp-to-aws`, `heroku-to-aws`, `llm-to-bedrock`).",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[703,706,707],{"name":704,"slug":705,"type":16},"Architecture","architecture",{"name":24,"slug":25,"type":16},{"name":708,"slug":709,"type":16},"Strategy","strategy","2026-08-20T03:27:01.975773",{"slug":712,"name":712,"fn":713,"description":714,"org":715,"tags":716,"stars":26,"repoUrl":27,"updatedAt":727},"gcp-to-aws","migrate workloads from GCP to AWS","Migrate workloads from Google Cloud Platform to AWS — including AI and agentic workloads regardless of cloud provider. Triggers on: migrate from GCP, GCP to AWS, move off Google Cloud, migrate Terraform to AWS, migrate Cloud SQL to RDS, migrate GKE to EKS, migrate Cloud Run to Fargate, migrate App Engine to Elastic Beanstalk, Google Cloud migration, migrate from OpenAI to Bedrock, move off OpenAI, switch from ChatGPT API to AWS, migrate from Gemini to Bedrock, migrate LangChain to Bedrock, migrate LangGraph to AWS, migrate agentic workloads to AWS, move AI workloads to AWS, migrate my AI app to AWS. Runs a 6-phase process: discover GCP resources from Terraform files, app code, or billing exports, clarify migration requirements, design AWS architecture, estimate costs, generate migration artifacts, and collect optional feedback. Clarify must finish before Design, Estimate, or Generate. Includes AI provider migration guidance (for example, OpenAI to Amazon Bedrock) by selecting closest-fit Bedrock model families for required modality, latency\u002Fquality targets, context windows, and cost constraints. Model mapping is compatibility-guided, not 1:1 parity; validate prompts, tool-calling behavior, and eval metrics before cutover. Do not use for: Azure or on-premises migrations to AWS, AWS-to-GCP reverse migration, general AWS architecture advice without migration intent, GCP-to-GCP refactoring, or multi-cloud deployments that do not involve migrating off GCP.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[717,718,721,724],{"name":24,"slug":25,"type":16},{"name":719,"slug":720,"type":16},"Google Cloud","google-cloud",{"name":722,"slug":723,"type":16},"Infrastructure","infrastructure",{"name":725,"slug":726,"type":16},"Migration","migration","2026-08-27T13:05:14.908471",{"slug":729,"name":729,"fn":730,"description":731,"org":732,"tags":733,"stars":26,"repoUrl":27,"updatedAt":740},"heroku-to-aws","migrate workloads from Heroku to AWS","Migrate workloads from Heroku to AWS. Triggers on: migrate from Heroku, Heroku to AWS, move off Heroku, migrate Heroku app, migrate Heroku Postgres to RDS, migrate Heroku Redis to ElastiCache, migrate Heroku Kafka to MSK, migrate dynos to Elastic Beanstalk, migrate dynos to Fargate, Heroku migration, move from Heroku to AWS, migrate Heroku Private Space, Heroku to Elastic Beanstalk, Heroku to ECS, Heroku to Fargate, leave Heroku, migrate off Heroku platform, what-if workshop, reprice Heroku migration, compare migration scenarios, workshop mode. Runs a 6-phase process: discover Heroku resources live via the authenticated Heroku CLI (read-only, consent-gated) and\u002For from Terraform files, Procfile\u002Fapp.json, and optional billing exports, clarify migration requirements, design AWS architecture, estimate costs, generate migration artifacts, and collect optional feedback. After Estimate, an optional what-if workshop can reprice region\u002FHA\u002Fcompute\u002FGraviton scenarios without re-discovery. Clarify must finish before Design, Estimate, or Generate. Uses a flat resource model (no clustering or dependency graphs) with deterministic mapping tables for core services (Dynos → Elastic Beanstalk by default, Postgres → RDS\u002FAurora, Redis → ElastiCache, Kafka → MSK) and a fast-path table for 13+ common add-ons. Cedar\u002FFir generation detection is detect-only in v1. Pipeline\u002FReview Apps are detect-only. Do not use for: GCP or Azure migrations to AWS, AWS-to-Heroku reverse migration, general AWS architecture advice without migration intent, Heroku-to-Heroku refactoring, or multi-cloud deployments that do not involve migrating off Heroku.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[734,735,738,739],{"name":24,"slug":25,"type":16},{"name":736,"slug":737,"type":16},"Heroku","heroku",{"name":722,"slug":723,"type":16},{"name":725,"slug":726,"type":16},"2026-08-27T13:05:14.188572",{"slug":742,"name":742,"fn":743,"description":744,"org":745,"tags":746,"stars":26,"repoUrl":27,"updatedAt":757},"knowledge-base-for-startups","retrieve AWS startup reference content","AWS Startups reference content — Activate FAQ, credits guide, programs, partner offers, sample architectures, and hundreds of learn articles spanning generative AI, cloud architecture, cost optimization, security, fundraising, go-to-market, and real-world startup case studies. Use when the user asks factual questions about AWS Activate (eligibility, credits, programs, providers), wants a sample architecture or solution guide, or needs an AWS-curated learn article on a specific startup topic. For copy-paste AI prompts (RAG chatbot, MVP scaffold, security baseline, GPU quota, etc.), see the prompt-library-for-startups skill. Do not use for: account-specific lookups (credits balance, Activate membership status, application status), real-time event listings beyond the events stub, or content not present in the bundled `references\u002F` tree.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[747,748,751,754],{"name":24,"slug":25,"type":16},{"name":749,"slug":750,"type":16},"Cloud","cloud",{"name":752,"slug":753,"type":16},"Documentation","documentation",{"name":755,"slug":756,"type":16},"Research","research","2026-08-23T03:33:23.478898",{"slug":759,"name":759,"fn":760,"description":761,"org":762,"tags":763,"stars":26,"repoUrl":27,"updatedAt":775},"llm-to-bedrock","migrate LLM calls to Amazon Bedrock","Use when the user wants to migrate code that calls OpenAI, Gemini\u002FGoogle AI, or the Anthropic API to Amazon Bedrock — a pure model\u002FSDK rewrite. End-to-end: assesses the codebase, then rewrites SDK calls, evaluates output quality against Bedrock, and delivers a ready-to-merge git branch. Not for: agent runtime selection, agentic architecture decisions, or agent migration planning — use agent-advisor for those. Not for standalone Bedrock cost estimates or infrastructure-only migration. The Assess phase is handled by this plugin's own gcp-to-aws skill.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[764,765,768,771,772],{"name":24,"slug":25,"type":16},{"name":766,"slug":767,"type":16},"Gemini","gemini",{"name":769,"slug":770,"type":16},"LLM","llm",{"name":725,"slug":726,"type":16},{"name":773,"slug":774,"type":16},"OpenAI","openai","2026-09-02T07:20:20.868971",11,{"items":778,"total":947},[779,798,819,829,840,853,863,873,889,900,920,934],{"slug":780,"name":780,"fn":781,"description":782,"org":783,"tags":784,"stars":795,"repoUrl":796,"updatedAt":797},"agentcore-investigation","investigate Bedrock AgentCore runtime sessions","Investigate Bedrock AgentCore runtime sessions via CloudWatch Logs Insights — resolve session\u002Ftrace IDs, query OTEL spans, filter noise, build timelines. Use when debugging AgentCore agent sessions, tracing tool calls, or analyzing latency.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[785,786,789,792],{"name":24,"slug":25,"type":16},{"name":787,"slug":788,"type":16},"Debugging","debugging",{"name":790,"slug":791,"type":16},"Logs","logs",{"name":793,"slug":794,"type":16},"Observability","observability",9645,"https:\u002F\u002Fgithub.com\u002Fawslabs\u002Fmcp","2026-07-12T08:37:22.601527",{"slug":799,"name":800,"fn":801,"description":802,"org":803,"tags":804,"stars":795,"repoUrl":796,"updatedAt":818},"amazon-aurora-dsql","amazon aurora dsql","build applications with Aurora DSQL","Deprecated compatibility redirect for Aurora DSQL guidance. Use when a request concerns DSQL, Aurora DSQL, distributed SQL, DSQL schemas, migrations, queries, authentication, performance, or application development.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[805,808,809,812,815],{"name":806,"slug":807,"type":16},"Aurora","aurora",{"name":24,"slug":25,"type":16},{"name":810,"slug":811,"type":16},"Database","database",{"name":813,"slug":814,"type":16},"Serverless","serverless",{"name":816,"slug":817,"type":16},"SQL","sql","2026-09-02T07:20:51.53702",{"slug":820,"name":821,"fn":801,"description":802,"org":822,"tags":823,"stars":795,"repoUrl":796,"updatedAt":828},"aurora-dsql","aurora dsql",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[824,825,826,827],{"name":24,"slug":25,"type":16},{"name":810,"slug":811,"type":16},{"name":813,"slug":814,"type":16},{"name":816,"slug":817,"type":16},"2026-09-02T07:20:46.533217",{"slug":830,"name":831,"fn":801,"description":802,"org":832,"tags":833,"stars":795,"repoUrl":796,"updatedAt":839},"aws-dsql","aws dsql",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[834,835,836,837,838],{"name":24,"slug":25,"type":16},{"name":810,"slug":811,"type":16},{"name":725,"slug":726,"type":16},{"name":813,"slug":814,"type":16},{"name":816,"slug":817,"type":16},"2026-09-02T07:20:49.531712",{"slug":841,"name":842,"fn":801,"description":802,"org":843,"tags":844,"stars":795,"repoUrl":796,"updatedAt":852},"distributed-postgres","distributed postgres",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[845,846,847,850,851],{"name":24,"slug":25,"type":16},{"name":810,"slug":811,"type":16},{"name":848,"slug":849,"type":16},"PostgreSQL","postgresql",{"name":813,"slug":814,"type":16},{"name":816,"slug":817,"type":16},"2026-09-02T07:20:47.592534",{"slug":854,"name":855,"fn":801,"description":802,"org":856,"tags":857,"stars":795,"repoUrl":796,"updatedAt":862},"distributed-sql","distributed sql",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[858,859,860,861],{"name":24,"slug":25,"type":16},{"name":810,"slug":811,"type":16},{"name":813,"slug":814,"type":16},{"name":816,"slug":817,"type":16},"2026-09-02T07:20:50.520015",{"slug":864,"name":864,"fn":801,"description":802,"org":865,"tags":866,"stars":795,"repoUrl":796,"updatedAt":872},"dsql",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[867,868,869,870,871],{"name":24,"slug":25,"type":16},{"name":810,"slug":811,"type":16},{"name":725,"slug":726,"type":16},{"name":813,"slug":814,"type":16},{"name":816,"slug":817,"type":16},"2026-09-02T07:20:48.570617",{"slug":874,"name":874,"fn":875,"description":876,"org":877,"tags":878,"stars":886,"repoUrl":887,"updatedAt":888},"aidlc","orchestrate AI-driven development lifecycle workflows","AI-DLC workflow orchestrator. Start, resume, or manage an AI-driven development lifecycle. Scopes are defined one file per scope under `.kiro\u002Fscopes\u002F`; run `bun .kiro\u002Ftools\u002Faidlc-utility.ts help` for the authoritative list and descriptions. Utilities: --status, --doctor, --stage, --phase, --scope, --depth, --test-strategy, --review, --version, --help, plus the intent and space verbs. Or describe what you want to build and the scope will be auto-detected.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[879,880,883],{"name":675,"slug":676,"type":16},{"name":881,"slug":882,"type":16},"Automation","automation",{"name":884,"slug":885,"type":16},"Workflow","workflow",4261,"https:\u002F\u002Fgithub.com\u002Fawslabs\u002Faidlc-workflows","2026-09-02T07:47:34.75815",{"slug":890,"name":890,"fn":891,"description":892,"org":893,"tags":894,"stars":886,"repoUrl":887,"updatedAt":899},"aidlc-jump","navigate AI-DLC workflow stages and phases","Jump the active AI-DLC workflow to a stage or phase. A Cursor-native shortcut for `\u002Faidlc --stage \u003Ctarget>` or `\u002Faidlc --phase \u003Ctarget>`.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[895,896],{"name":881,"slug":882,"type":16},{"name":897,"slug":898,"type":16},"Navigation","navigation","2026-09-02T07:48:09.505949",{"slug":901,"name":901,"fn":902,"description":903,"org":904,"tags":905,"stars":886,"repoUrl":887,"updatedAt":919},"aidlc-knowledge","index documents for AI-DLC agent citation","Index the team's own documents — PDFs, Word files, Markdown, plain text — into a per-space catalog the AI-DLC agents can cite. Wraps `aidlc-knowledge.ts`: onboard, sync, list, show, associate, dissociate, rebind, summarize. Every catalog row is written by the tool under a workspace lock; this skill never edits the catalog by hand and never advances workflow state.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[906,907,910,913,916],{"name":675,"slug":676,"type":16},{"name":908,"slug":909,"type":16},"Documents","documents",{"name":911,"slug":912,"type":16},"Knowledge Management","knowledge-management",{"name":914,"slug":915,"type":16},"Markdown","markdown",{"name":917,"slug":918,"type":16},"PDF","pdf","2026-09-02T07:48:10.614775",{"slug":921,"name":921,"fn":922,"description":923,"org":924,"tags":925,"stars":886,"repoUrl":887,"updatedAt":933},"aidlc-outcomes-pack","generate AI-DLC workflow handover documentation","Generate a comprehensive handover document at workflow close so the team can own, operate, and continue the system without re-running the workflow. Stage\u002Fphase\u002Flearning counts come from `aidlc-runtime.ts summary`; prose comes from the artefacts. Writes OUTCOMES.md but never mutates workflow state or emits audit events.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[926,927,930],{"name":752,"slug":753,"type":16},{"name":928,"slug":929,"type":16},"Process Documentation","process-documentation",{"name":931,"slug":932,"type":16},"Reporting","reporting","2026-09-02T07:47:34.212738",{"slug":935,"name":935,"fn":936,"description":937,"org":938,"tags":939,"stars":886,"repoUrl":887,"updatedAt":946},"aidlc-replay","generate AI-DLC session narrative reports","Print a structured session narrative for stakeholders who weren't in the room. Numbers (stage counts, phase rollup, duration) come from `aidlc-runtime.ts summary`; prose comes from the audit trail and artefacts. Renders to the terminal only — writes no file, never mutates workflow state, never emits audit events.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[940,943,944,945],{"name":941,"slug":942,"type":16},"Audit","audit",{"name":752,"slug":753,"type":16},{"name":682,"slug":683,"type":16},{"name":931,"slug":932,"type":16},"2026-09-02T07:47:45.055994",142]