Module 8: Capstone The Andes Cargo Genai Extractor

5. What this guide left representative

Description

Each of the seven earlier modules documented, in its own "the exact limit" lesson, which part of its domain fell outside the scope of this $0 lab, with the precise technical reason and the official source backing it. This lesson doesn't uncover any new limit — it gathers, in a single document, every one of those claims, with its exact source lesson, so that no one who wants to cite this guide's work in an interview, a README, or a presentation has to dig through thirty-six lessons to find the complete reason. It's the nutrition label for the entire guide: what it has, what it doesn't have, and why, in a single table.

Connection to the module

Lessons 3 and 4 of this module just demonstrated, with really-run code, exactly where the deterministic path and the escalation path end in executable code and where the representative part begins. This lesson generalizes that same discipline to the entire guide, module by module, from M1 through M7.


Analogy: the nutrition label, not the front-of-package slogan

A food package has two completely different surfaces of text. The front — the slogan, the design, "100% natural" — sells a general promise, with no numbers. The nutrition label, on the back, doesn't sell anything: it lists, with legal precision, exactly how many grams of each thing that specific product contains, never rounding up or down, with a verifiable source if anyone challenges it. This entire guide, since M1.1, behaved like that nutrition label, not like the front-of-package slogan: every claim of "this really ran" or "this is representative" always carried its exact reason right next to it. This lesson is the complete nutrition label, printed once, for the entire product — thirty-six lessons of content, condensed into a table a reader can verify row by row.


The complete ledger, module by module, with the exact reason for each row

#PieceModule · lessonExact technical reason
1Any real invocation of bedrock:InvokeModel/Converse, anywhere in this guideM1.2 (decision), reaffirmed in every moduleAn explicit design decision from the first lesson — this guide teaches how to operate Bedrock, it doesn't replace AI Engineering's prerequisite of knowing how to invoke it; no technical reason prevents it, this is a deliberate pedagogical boundary
2list-foundation-models/any Bedrock API against LocalStackM1.7Bedrock — "Included in Plans: Ultimate," a tier above the free Hobby plan this entire lab runs on (LocalStack Docs — Bedrock)
3tflocal apply/awslocal iam get-role-policy on BedrockManifestExtractorRoleM3.4, M3.7A limit of the writing environment, not of the service — IAM IS on Hobby, but this specific sandbox has no LOCALSTACK_AUTH_TOKEN exported (exit code 55, the same finding as M1.7)
4terraform apply/tflocal apply of the aws_bedrock_guardrail resourceM3.6, M3.7Same reason as row 2 — no token, from any free plan, enables this specific resource
5A real block of a prompt-injection attack, or a real masking of a PII leak, by Bedrock GuardrailsM4.7Requires a real invocation of bedrock:InvokeModel/Converse with the guardrail referenced — the response's schema (ApplyGuardrail) is verified; the content of a real classification is not
6write_shipment_record() really writing to Shipments (DynamoDB), in any lesson of this guideM8.3Same reason as row 3 — DynamoDB IS on Hobby, but this writing environment has no token exported
7The dollar figure Infracost would produce for bedrock.tfM2.5, M2.6Two independent obstacles: Infracost's authentication gate blocks before analyzing anything; and, structurally, no aws_bedrock_* resource exists in Infracost's catalog, nor could it price an inference call without a declared usage file
8Real InvocationLatency/TimeToFirstToken for extract-shipment-manifest-fieldsM7.7Both metrics, published by Bedrock in CloudWatch/AWS/Bedrock, only have a value if a real invocation produced that value — there isn't even a published range from AWS specifically for Nova Lite
9The escalation rate over real production traffic (versus the 12.0% of a fixed test batch)M7.4, M2.8 §712.0% (M7.4) and 0.0% (M8.3) are real measurements, but over hand-built batches — neither is a sample of real traffic, which would only exist with the system deployed and operating
10The semantic quality of a real extraction (did the model understand an ambiguous text's correct nuance?)M1.4, M7.5, M7.6Out of scope by design, not by a technical limitation of the lab — it's explicitly AI Engineering territory; M7.6's harness compares shape, never meaning

Ten rows. Nine depend, directly or indirectly, on a real Bedrock invocation this guide never makes. One — row 1 — is the design decision that makes the other nine, in cascade, inevitable.


The same ledger, grouped by root cause

It's worth seeing these ten rows grouped, not just listed — most of them share one of only three distinct root causes:

   ROOT CAUSE 1: BEDROCK IS NEVER INVOKED (design decision, M1.2)
        │
        ├── Row 1  -- no real invocation, anywhere
        ├── Row 5  -- the guardrail's real block depends on invoking
        ├── Row 7  -- Infracost can't price a call that never happens
        ├── Row 8  -- latency metrics don't exist without an invocation
        ├── Row 9  -- the real escalation rate needs real traffic
        └── Row 10 -- semantic quality depends on a real response

   ROOT CAUSE 2: BEDROCK IS "ULTIMATE-ONLY" IN LOCALSTACK (M1.7)
        │
        ├── Row 2  -- no Bedrock API runs against LocalStack Hobby
        └── Row 4  -- guardrail apply, same obstacle

   ROOT CAUSE 3: THIS SANDBOX HAS NO LOCALSTACK_AUTH_TOKEN (M1.7, M3.4)
        │
        ├── Row 3  -- the IAM role's apply (IS on Hobby, not in this environment)
        └── Row 6  -- real DynamoDB write (same reason)

Notice Root cause 3: it's the only one of the three that's a limit of this specific writing environment, not of the service or of LocalStack's plan — any reader running this guide on their own machine, with their own free Hobby token, would see rows 3 and 6 complete for real, without changing a single line of code. Root cause 1 and 2's rows, on the other hand, would stay representative no matter who runs them or with what token, because they depend on a design decision of this guide or on a real LocalStack licensing limit.


What this table does NOT say

With the same precision every "the exact limit" lesson already applied to its own domain, it's worth saying, out loud, what these ten rows don't mean: they don't mean this guide is, for the most part, theoretical. M8.1 already gave the inverse count — terraform validate/plan over seventeen resources, 34 pytest cases over the custom guardrails, six Rego rules evaluated with conftest against a real plan, a real cosign signature, a cost calculator with twelve test cases, an escalation metric with seven test cases, a smoke test harness with six test cases, and this same module's lessons 3 and 4 walkthroughs, complete. Each of those pieces is real, executed, verifiable code, that anyone who clones this repository and runs the same commands can check. The exact proportion between what was executed and what stayed representative isn't this lesson's point — this guide's DISENO.md already did that accounting, with the approval verdict at the top of the document —; the point is that each of the ten rows above has a specific, cited technical reason, never a generic excuse.


Common mistakes

Citing this table without the "exact technical reason" column, flattening ten different reasons into one (of collapsing ten distinct reasons into one). What happens: someone, summarizing this guide for a README, writes "this guide can't invoke Bedrock due to lab limitations," without distinguishing among the three root causes. How to spot it: if your summary of this lesson fits in a single sentence with none of the three causes named. How to fix it: the "The same ledger, grouped by root cause" section exists exactly for this — a demanding technical reader will ask "why, specifically?", and the correct answer distinguishes a design decision (row 1) from a licensing limit (rows 2 and 4) from a limit of this particular sandbox (rows 3 and 6), because each has a different implication for someone who wanted to run this guide with more resources.

Assuming rows 3 and 6 (writing-environment limit) would also apply on the reader's own machine (of generalizing a limit specific to this sandbox to every environment). What happens: someone, following this guide on their own computer, with a Hobby LocalStack token already exported, assumes they also couldn't apply BedrockManifestExtractorRole or write to Shipments. How to spot it: if your local copy of this guide never tries tflocal apply -target=module.bedrock_manifest_extractor_role, assuming it would fail the same way it did in the guide. How to fix it: Root cause 3 is explicitly about this guide's writing sandbox — it doesn't exist on your own machine if you have a real token exported; M3.4 already said it precisely: "anyone with a free Hobby token, on their own machine, really runs these two commands."

Treating the "What this table does NOT say" section's count of executed pieces as if it compensated for or "canceled out" the ten representative rows (of turning a clarification into a disproportionate defense). What happens: someone reads that section and concludes the ten rows above, deep down, "don't matter that much." How to spot it: if your summary of this lesson is "actually almost everything ran, the ten rows are a minor detail." How to fix it: that section exists to give context, not to minimize — the ledger's ten rows remain exactly what they are: this $0 lab's real and honest limit. No amount of pytest run elsewhere in the guide changes the fact that no real Bedrock invocation ever happened. This lesson's two sections are complementary, not one compensating for the other.


Exercises

Exercise 1 — Without looking at the table, classify, from memory, each of this lesson's ten rows into one of the three root causes. Check your classification against the "The same ledger, grouped by root cause" section.

See solution

Root cause 1 (Bedrock is never invoked, design decision): rows 1, 5, 7, 8, 9, 10. Root cause 2 (Ultimate-only in LocalStack): rows 2, 4. Root cause 3 (this sandbox with no token): rows 3, 6. If your classification matched, you have a clear grasp of the difference between a design decision, a licensing limit, and a specific environment limit — this lesson's central distinction.

Exercise 2 — A technical interviewer asks you: "if you had a real AWS account with Bedrock enabled, how many of these ten rows would still be a problem?" Answer with precision, row by row.

See solution

With a real AWS account and Bedrock enabled, rows 1 through 8 would stop being a technical obstacle — you could really invoke the model, apply the guardrail, write to Shipments, measure real latency, and Bedrock Guardrails would really block or let content through. Row 7 (Infracost) would remain a structural problem, not an account one: Infracost, today, has no aws_bedrock_* resource in its catalog, so a real account doesn't fix it — only an update to the tool itself would. Row 9 would stop being a limit as soon as real traffic existed to measure — the code is already ready for that moment. Row 10, semantic quality, would remain AI Engineering territory by design, not by account limitation — no amount of Bedrock access changes that boundary, which is pedagogical, not technical.

Exercise 3 — Explain why this lesson chose the "exact technical reason with cited source" format, instead of simply writing "REPRESENTATIVE" next to each row, as a shortened version. What would be lost with the shortened version?

See solution

Precisely what would be lost is the ability to distinguish the previous section's three root causes — a table of just "REPRESENTATIVE" with no further context would treat a deliberate design decision (row 1), a licensing limit verified with an official citation (rows 2 and 4), and a limit specific to this writing sandbox, reproducible or not depending on the reader's environment (rows 3 and 6), all the same. Those three categories have completely different practical implications for someone who wanted to reproduce, extend, or audit this guide — the same reason every "the exact limit" lesson across the seven earlier modules, from M1.7 onward, was never satisfied with the word "representative" alone, always with its reason and its source right next to it.


Summary and next step

This lesson consolidated, in a single ten-row table, every "representative" claim from this guide's thirty-six previous lessons, with its exact source lesson and its cited technical reason — never a generic label. You grouped those ten rows into three distinct root causes: a design decision (never invoking Bedrock), a real LocalStack licensing limit (Ultimate-only), and a limit specific to this writing sandbox (no LOCALSTACK_AUTH_TOKEN) — the third, unlike the other two, wouldn't apply on a reader's machine with their own free token.

Before moving on you should be able to: cite, from memory or close to it, the three root causes and which rows belong to each; explain which of the ten rows would stop being an obstacle with a real AWS account, and which wouldn't; and defend why this table uses specific technical reasons, never the word "representative" alone.

Lesson 6 recaps, with the same precision, this guide's other half of honesty: not what was left unexecuted, but what this guide deliberately decided not to teach at all — the boundary with AI Engineering, closed without ambiguity.

Resources

  1. genai-on-aws-production-guide/DISENO.md — the source of this guide's complete honesty accounting and the approval verdict cited in the "What this table does NOT say" section.
  2. Every lesson cited in the main table's "Module · lesson" column — the primary, complete source for each of the ten rows, with its own executed evidence or its own official citation.
  3. LocalStack Docs — Bedrock — the source of Root cause 2, first cited in M1.7 and reconfirmed in M3.6 and M4.7.
  4. Infracost — Supported AWS Resources — the source of row 7, directly confirmed in M2.6.