ForgeStack LATAM Business Stack

Build Feasibility Assessment

A module-by-module review of what we can fully ship — covering every third-party connection, external dependency, and build risk before we make any customer promises.

Reviewed: 2026-06-24
Modules: 11
Team: Ruben + Alfredo · 20h/wk combined · ~7 weeks to ship
Bottom line: Every module is fully implementable on current technology, with a public API or sandbox available for every third-party connection. The core PHP work — CFDI signing, billing logic, gateway drivers, webhook handling, event systems — is well-specced and uses standard, available libraries. A distribution infrastructure prerequisite precedes Phase 1: forgestack/license-kernel (bundled into every paid package) and the License API server (built inside the hosted Symfony app) must be live before any package ships to buyers. Both are fully buildable now — no external dependencies, no unresolved gates. Three items carry real pre-build risk you must resolve before starting those modules: (1) Verify OVH KMS can sign with an imported RSA key before building H03 (credential vault). (2) Confirm ContPAQi/Aspel póliza import format against a live install before the connectors A-hard tier. (3) Get Mexican counsel sign-off on the CSD custody model before hosted goes live. Everything else can be built and tested today. No module depends on technology that doesn't exist.
Time estimates assume Claude Code AI-assisted development

All plans are structured for agentic execution — each task has exact test-first code, file paths, and commit steps. AI (Claude Code subagents) generates 70–80% of the code; human time is direction, review, sandbox integration testing, and debugging edge cases. Hours shown per module are human oversight hours, not raw typing time.

~560h Raw code output
~155h Human oversight (with AI)
3.5× AI speedup
~7 wks To ship everything (2 devs × 10h/wk)

All modules at a glance

Pre-Phase 0 · Dist
forgestack/license-kernel
✓ Fully Buildable
~3h human
Pre-Phase 0 · Dist
License API Server
✓ Fully Buildable
~12h human
Phase 0
forgestack/support
✓ Fully Buildable
~2h human
Phase 0.5
forgestack/mx-geo
✓ Fully Buildable
~3h human
Phase 1
forgestack/cfdi-mexico
✓ Buildable — 3 hard parts
~22h human
Phase 1.5
forgestack/sat
✓ Fully Buildable
~5h human
Phase 2
forgestack/latam-pay
✓ Fully Buildable
~20h human
Phase 3
forgestack/billing
✓ Fully Buildable
~20h human
Phase 3.5
forgestack/whatsapp
~ Buildable — Meta approval caveat
~9h human
Phase 4
Hosted Platform
~ Buildable — verify OVH O1 first
~42h human
Phase 5
forgestack/connectors
~ A-cheap: OK / A-hard: Task 00 gate
~17h human

Projected timeline — starting July 2026, Ruben + Alfredo at 10h/wk each

Weeks 1–2 · Jul 2026
Dist infra + Packages live (Pre-0 + Phases 0–1.5)
~49h combined
license-kernel + License API (parallel w/ support) · support, mx-geo, sat, cfdi-mexico — first revenue
Weeks 3–4 · Aug 2026
Payment stack live (Phases 2–3)
+~40h combined
latam-pay, billing — OXXO/SPEI/Pix subscriptions
Weeks 5–7 · Aug – Sep 2026
WhatsApp + Hosted launch (3.5–4)
+~51h combined
Multi-tenant SaaS, credential vault, dashboard
Week 8+ · Oct 2026
ERP Connectors (Phase 5)
+~17h combined
ContPAQi/Aspel integration (after Task 00 gate)

Pre-Phase 0 — Distribution Infrastructure

Prerequisite · Must ship before Phase 1
forgestack/license-kernel Dist · Bundled into every paid package
~3h human / ~20h AI code Fully Buildable

Framework-agnostic PHP 8.2+ package that authenticates the license token at app boot, calls the ForgeStack License API, caches responses (PSR-6 + file fallback), checks domain binding, and applies a graduated enforcement policy. Ships as a require dependency inside every paid ForgeStack package. Buyers never install it directly — it arrives automatically when they install any paid package. Thin Symfony 7.4 + Laravel 11/12 bridges wire the boot check automatically.

External connections
  • ForgeStack License API https://api.forgestack.build (prod), https://api-staging.forgestack.build (staging). One call per 24h (cached). Dev environments (localhost, *.test, *.ddev.site, *.local) bypass all network calls automatically.
Key design decisions
  • Graduated enforcement: expired tokens get 30 days of warnings before hard-blocking; unreachable API gets 7 days of grace — legitimate customers with billing issues are never locked out unexpectedly.
  • FORGESTACK_LICENSE_FORCE_STATE env var bypasses all network calls in CI and test environments. Set to valid, expired:5, revoked, etc.
  • Buyer fingerprint (Owner.php) is injected into the ZIP by Satis download middleware at install time — the source repo contains only a placeholder stub. Buyers cannot redistribute the kernel with another buyer's fingerprint.
License API Server Dist · Lives inside forgestack.build Symfony app
~12h human / ~50h AI code Fully Buildable

Symfony 7.4 controller group inside the main forgestack.build application that validates license tokens, manages revocation, serves SAT catalog snapshots (for cfdi-mexico update notifications), and handles buyer domain self-service. Also provides the Satis auth_request endpoint that gates private package downloads. Three background jobs handle expiry cron, anomaly detection (no auto-revoke), and SAT catalog sync. Nginx + Lua handles rate limiting at the edge.

Endpoint groups (4 auth zones)
  • No-auth: POST /api/v1/license/verify — token in body is the credential. Rate-limited by Nginx (10 req/min per token).
  • Bearer token: GET /api/v1/catalog/* — SAT catalog snapshots for active licenses.
  • Admin secret: POST/PATCH /api/v1/admin/* — token creation + revocation (internal only).
  • Session cookie: POST /api/v1/dashboard/* — buyer domain self-service.
Build notes
  • Depends on H01 scaffold — the forgestack.build Symfony app must exist first. However, the License API tasks (01–10) are a Phase 0 prerequisite, not a Phase 4 deliverable — build them immediately after H01.
  • Wire contract is non-negotiable — JSON field names in the verify response must match LicenseResponse::fromValidPayload() exactly. A single typo in a field name silently breaks every installed license-kernel across all buyer environments.
  • Nginx + Lua required for rate limiting (extracts token from JSON body). OpenResty or Nginx with ngx_http_lua_module. The /internal/ routes (Satis auth) must be blocked from the public internet via Nginx deny all.

Phase 0 — Kernel & Free Utility

Foundation
forgestack/support Kernel · No deps
~2h human / ~8h AI code Fully Buildable

Pure PHP 8.2+ value objects: Money (integer minor units, currency-scaled), Currency enum (MXN/BRL/ARS/CLP/COP/USD), Country. Every other module depends on this; it depends on nothing. No external APIs, no runtime network calls, no third-party accounts of any kind.

  • Integer arithmetic only — zero floats anywhere. CLP is zero-decimal; COP has two decimal places. allocateByRatios handles lossless splitting used in billing proration and connector pólizas.
  • AI builds this end-to-end. Human time is one review pass and running the test suite. No integration testing needed — pure unit tests.
forgestack/mx-geo Free · Acquisition hook
~3h human / ~12h AI code Fully Buildable

Mexico postal code → colonia/municipio/estado lookup. Powered by an embedded SQLite database (~10–15 MB) compiled from SEPOMEX's public CSV data. Zero runtime network calls. Ships free; drives high download volume as an acquisition funnel.

Data sources
  • SEPOMEX CSV — Correos de México, public, free. The bin/compile-db.php script compiles it into the SQLite file. Primary URL can be unstable; community GitHub mirror is the reliable fallback. Updated ~1–2×/year.
Build notes
  • Human time: 3h. Download SEPOMEX CSV, run compile script, verify a few postcodes, review AI-generated code. ext-sqlite3 is built-in on PHP's official Docker images — no install needed.

Phase 1 & 1.5 — Mexico Compliance

Revenue module #1
forgestack/cfdi-mexico Phase 1 · Revenue
~22h human / ~80h AI code Buildable — 3 hard parts, all solvable

Generates, signs, stamps (timbra), cancels, and audits SAT-compliant CFDI 4.0 documents. Ships with offline-bundled SAT XSD/XSLT schemas, two PAC drivers (Facturapi REST, Finkok SOAP), DomPDF/TcPDF for receipts, and Carta Porte 3.1 + Pagos 2.0 complements. No runtime SAT server dependency — schemas are bundled.

Third-party connections
  • Facturapi — PAC (REST/JSON). Free sandbox at sandbox.facturapi.io. Customers provide their own API key. No reseller agreement needed for dev-sold packages.
  • Finkok — PAC (SOAP/WSDL). Free sandbox at demo-facturacion.finkok.com. Same model — customer credentials.
  • SAT XSD/XSLT schemas — Bundled offline at build time. No runtime SAT server call. Updated ~1–2×/year when SAT publishes new versions.
  • SAT test CSD — RFC AAA010101AAA, password 12345678a. Publicly available from SAT's developer portal. For integration tests only.
The 3 hard parts (plan calls these out explicitly)
  • Offline XSLT resolution — SAT's cadenaoriginal_4_0.xslt has live SAT URL includes that must be intercepted and redirected to bundled files. Hardest single piece in the whole stack. Solved pattern in PHP community (phpcfdi does this). Full implementation is pre-written in the plan. Human time: ~3h debugging until XSLT resolves cleanly.
  • DER→PEM key decryption — SAT .key files are DER-encoded PKCS#8. Full CsdLoader.php code is already in the plan. AI generates it; human verifies against SAT test CSD.
  • Confirmation codes — When Total > ~$8.6M MXN, PAC returns CFDI40145/CFDI40146. Rare. Service layer handles with $confirmacion retry. No human time beyond review.
Where the 22h human time goes
  • ~3h: XSLT offline resolver debugging + SAT schema bundling. ~5h: PAC sandbox integration tests (real stamp + cancel cycle with Facturapi and Finkok). ~4h: CSD signing validation against SAT test vectors. ~10h: reviewing 14 AI-generated tasks, running PHPStan, CI setup.
forgestack/sat Phase 1.5 · Companion · $29 standalone
~5h human / ~18h AI code Fully Buildable

RFC format validation (Modulo-11 check digit), SAT catalog lookups compiled to static PHP arrays, and CSD certificate metadata parsing via ext-openssl. Zero runtime HTTP calls. Bundled free with cfdi-mexico, sold at $29 standalone.

Data sources (build-time only)
  • SAT catCFDI.xsd — Official XSD enumerations for all 6 catalogs (~52K entries in c_ClaveProdServ). bin/compile-catalogs.php generates static PHP arrays — compiled once, committed to repo.
  • phpcfdi/rfc — Reference implementation for SAT RFC check digit algorithm. Cross-check only; no library dependency needed.
Build notes
  • Human time: 5h. AI generates all code. Human validates RFC check digit algo against SAT's own validator, verifies 2–3 catalog lookups, reviews CSD cert parsing. Builds and tests completely offline.
  • RFC XAXX010101000 and XEXX010101000 are always valid — hard-coded as isGeneric(): bool. CFDI uses them constantly — never reject them.

Phase 2 — Payment Gateways

Revenue module #2
forgestack/latam-pay Phase 2 · 4 complete drivers + 2 stubs
~20h human / ~75h AI code Fully Buildable

Single PaymentGatewayInterface over 4 complete gateway drivers plus stubs for PlaceToPay and Transbank. Covers OXXO, SPEI, Pix, Boleto, and card payments. Webhook signatures are verified before body parsing on all drivers. Task 14 adds payment-method tokenization (vault) needed by billing's card-on-file path.

Third-party connections — all have free public sandboxes
  • MercadoPago — MXN + BRL + ARS + CLP. OXXO, SPEI, PIX, card. Webhook: signed template + HMAC-SHA256 via x-signature header (verified against live docs). Sandbox at developer.mercadopago.com — free, immediate credentials.
  • Conekta — MXN only (Mexico). OXXO, SPEI, card. Webhook: RSA signature via POST /webhook_keys endpoint (not HMAC — confirmed and corrected in SPEC). Sandbox at developers.conekta.com — free.
  • Pagar.me — BRL (Brazil). Pix, Boleto, card. Webhook: IP allowlist only — no signature header (confirmed). Sandbox at dashboard.pagar.me — free.
  • OpenPay — MXN (Mexico). OXXO, SPEI, card. REST API at documents.openpay.mx. Sandbox available.
  • PlaceToPay / Transbank — Phase 5 stubs only. Throw DriverNotImplementedException. No work until Colombia/Chile market validates.
Async payment methods (OXXO/SPEI/Pix)
  • Customer receives a reference/barcode/CLABE and pays offline. Gateway webhook fires when payment clears. Billing's awaiting_payment → paid state machine handles reconciliation. These flows are first-class in all 4 complete drivers.
  • OXXO voucher delivery is essential — a subscription is unpayable if the reference never reaches the customer. The WhatsApp module's fs_oxxo_voucher template is the primary delivery channel.
Where the 20h human time goes
  • ~4h per gateway sandbox integration test (4 gateways = ~16h). ~4h reviewing AI code for security layer (PCI guards, webhook verifiers). Vault testing adds ~2h in sandbox. The stubs require zero human time.

Phase 3 — Billing Engine

Revenue module #3
forgestack/billing Phase 3 · Revenue
~20h human / ~68h AI code Fully Buildable

Subscription & metered billing engine — plans, subscriptions, invoicing, Mexican IVA (16%/8%/0%/exento with retenciones), proration, dunning, and payment reconciliation. Works standalone with a ManualPaymentAdapter and auto-wires with latam-pay and cfdi-mexico when present. No external API connections of its own — it orchestrates the other two modules.

Internal complexity (no external accounts needed)
  • BillingRunner idempotency — three layers: advisory lock + unique (subscription_id, period_start) constraint + deterministic charge idempotency key. Highest-risk code in the package. AI generates it; human writes the failing tests first and validates the edge cases.
  • Stamp-before-charge invariant — invoice must be stamped before any charge. Compliance failure aborts the cycle without taking money. Encoded at the service layer.
  • Mexican IVA — 16%/8%/0%/exento, inclusive vs. exclusive, retenciones ISR/IVA. BCMath at scale=6. Well-specified with test vectors; AI generates correctly from the spec.
Where the 20h human time goes
  • ~6h: idempotency edge cases and advisory-lock testing. ~5h: full-stack bundle test (Billing + latam-pay sandbox + CFDI sandbox: subscribe → stamp → charge → reconcile). ~5h: reviewing 13 AI-generated tasks. ~4h: voucher path e2e (OXXO reference delivery via simulated webhook).

Phase 3.5 — WhatsApp Notifications

Standalone + event listener
forgestack/whatsapp Phase 3.5 · $59
~9h human / ~32h AI code Buildable — Meta template approval is external

Sends WhatsApp Business messages via Meta Cloud API or Twilio behind a single WhatsAppClientInterface. Ships with 6 pre-built billing lifecycle templates × 2 languages = 12 template definitions. Templates wire automatically to billing and latam-pay events via PSR-14 listeners.

Third-party connections
  • Meta Cloud API — Need a WABA, System User with permanent access token (not a user token, which expires in 60 days), and a verified phone in Business Manager.
  • Twilio WhatsApp — AccountSid + AuthToken. Excellent sandbox, no template approval. This is the dev/test path and a valid production fallback.
The one caveat — Meta template approval
  • We cannot pre-approve templates on customers' behalf. Each customer has their own WABA; templates are submitted per-WABA and reviewed by Meta (24–48h). The forgestack:whatsapp:register-templates CLI command automates submission. Customers run it once during onboarding, not at first use.
  • Human time: 9h. ~3h Twilio sandbox testing. ~3h Meta WABA setup + template submission flow testing. ~3h reviewing AI code. The code itself is straightforward; the friction is Meta's external process.

Phase 4 — Hosted Platform

Multi-tenant SaaS · $1M ARR driver
Hosted Platform (Symfony 7) Phase 4 · H01–H09
~42h human / ~128h AI code Buildable — H03 has one must-verify item first

Symfony 7 application that assembles all packages and adds row-level multi-tenancy, a per-tenant credential vault (CSD keys, PAC/gateway secrets), EasyAdminBundle 4.x dashboard, and Symfony Messenger-backed multi-tenant billing orchestration. The platform is itself tenant zero — it bills its own customers through the same engine.

H01–H02, H04–H09 — Standard Symfony work
  • Tenancy (H02): Row-level scoping via Doctrine SQLFilter. AI generates the filter and tenant resolution listener. Human writes and runs the cross-tenant isolation test — a cross-tenant read is a P0 defect.
  • Dashboard (H05): EasyAdminBundle 4.x CRUD. AI generates the controllers; human reviews the bilingual (ES/EN) UI and validates the cross-module row view (invoice → CFDI UUID → payment status).
  • Orchestration (H07): Messenger-backed multi-tenant run. Human validates per-tenant advisory lock behavior and that one tenant's failure doesn't block others.
  • Security review (H09): ~8h of manual pen-test, threat model sign-off, CSD key backup/DR drill, access audit review. This is irreducibly human work.
H03 — Credential vault (the security centerpiece)
  • Open Item O1 — must verify before building H03: Can OVH KMS sign with an imported RSA key (RSASSA-PKCS1-v1.5 + SHA-256)? Run a ~1-day PoC against the live OVH KMS API. If it fails, use Azure/AWS KMS for the CSD signing key only — that's the named fallback.
  • Open Item O2 — Mexican counsel: CSD custody model + data-protection sign-off. Run in parallel with Phases 0–3.5 development. Does not block package shipping.
  • H03 is where most of the 42h human time concentrates: vault design review (~4h), encryption testing (~4h), H09 security review (~8h), and multi-tenant isolation verification across all module tables (~6h).

Phase 5 — ERP Connectors

Post-core · LATAM expansion
forgestack/connectors Phase 5 · Two tiers
~17h human / ~68h AI code A-cheap: Buildable / A-hard: Needs live install first

Syncs billing/CFDI/payment activity into customers' accounting ledgers. Two desktop ERPs (ContPAQi, Aspel COI) via file export; REST connectors (Siigo) as designed stubs. Split into two tiers: A-cheap (CFDI XML delivery to ContPAQi ADD folder — zero account mapping) and A-hard (póliza posting with double-entry mapping).

A-cheap tier — CFDI XML delivery (buildable now)
  • ContPAQi ADD monitors a folder and auto-imports CFDI XML files. Folder structure is documented: {addPath}/{year}/{month}/{RFC}/{uuid}.xml. No póliza mapping, no account chart, no ERP-side complexity. AI generates this completely.
  • Ship and validate A-cheap first. It delivers real value (automated CFDI filing) and requires no access to a live ERP install.
A-hard tier — póliza posting (Task 00 gate)
  • Task 00 is a business task, not a code task. ContPAQi Contabilidad and Aspel COI are Windows desktop ERPs. Their póliza XML import format is version-sensitive and not fully public. Must be confirmed against a live install or friendly despacho before the AI builds the mappers — otherwise it produces files the ERP silently rejects.
  • Path to Task 00: Many accounting firms (despachos) in Mexico use ContPAQi. One friendly contact with a real install resolves this. ~4h of human time to document the golden format and run a live test.
  • The framework (Tasks 01–06: DTOs, ports, orchestrator, file transport) and REST stubs build without Task 00. Total human time including Task 00: ~17h.

External accounts & data you need before each module ships

Non-code prerequisites — sandbox accounts, public data, legal reviews. All sandbox accounts are free and take under an hour to create.

Before any package ships (dist infra)
H01 scaffold live — forgestack.build Symfony 7.4 app deployed to staging with Doctrine ORM + Scheduler
License API deployedapi.forgestack.build staging live; POST /api/v1/license/verify responding; at least one fsk_test_* token created for dev testing
Satis repo configuredsatis.forgestack.build with Nginx auth_request → /internal/verify-token; private repo credential working end-to-end
Nginx + Lua module — OpenResty or ngx_http_lua_module installed on the server for rate limiting + body-based token extraction
Before cfdi-mexico ships
Facturapi sandbox account — free, immediate at facturapi.io
Finkok sandbox account — free at finkok.com
SAT test CSD filesAAA010101AAA.cer + .key, password 12345678a, from SAT developer portal (public)
SAT XSD/XSLT schemas — download from SAT or phpcfdi/sat-catalogos mirror; bundle into resources/schemas/
Before latam-pay ships
MercadoPago dev account — free sandbox at developer.mercadopago.com
Conekta dev account — free sandbox at developers.conekta.com
Pagar.me dev account — free sandbox at dashboard.pagar.me
OpenPay dev account — free sandbox at documents.openpay.mx
Before whatsapp ships
Twilio account — free trial, covers all sandbox/dev testing
Meta Business Manager + WABA — needed for customer-facing testing and real template submission. Not needed to build or test the package itself.
Before hosted H03 starts
OVH KMS O1 PoC — verify RSA Sign with imported key. ~1-day technical experiment.
Mexican counsel sign-off (O2) — CSD custody model + data-protection reading. Run parallel with Phases 0–3.5; must be done before hosted goes live.
Before connectors A-hard tier
Live ContPAQi Contabilidad install — or a friendly despacho. Needed to document the póliza XML format and ADD behavior (Task 00 golden fixtures).
Live Aspel COI install — same requirement for the Aspel connector mapper.

3 critical items — resolve these before building those modules

The only items where "we can't build this as planned" is a real scenario. All three have explicit fallbacks or mitigation paths.

Critical Risk Register All 3 have fallbacks
O1
H03
OVH KMS: verify RSA Sign with imported key

The Model B design for CSD signing requires OVH KMS to accept an imported RSA key and sign RSASSA-PKCS1-v1.5 + SHA-256. The plan documents this as unverified and requires a ~1-day PoC against the live OVH KMS API before building H03. If it fails, the explicit fallback is Azure/AWS KMS for the CSD signing key only — Model A (envelope encryption for gateway/PAC/ERP secrets) works with OVH KMS regardless, since it only needs encrypt/decrypt.

Fallback:
Azure/AWS KMS
for CSD key only
O2
H03
Mexican counsel: CSD custody sign-off

The CSD server-side custody model and the "the .key is not personal data" reading under the new 2025 federal data protection law need Mexican fiscal/data-protection counsel sign-off before hosted goes live. Research is done and documented. This does not block the dev-sold packages at all — customers hold their own CSD on the standalone track. Can run in parallel with all of Phases 0–3.5.

Parallel path:
Run during
Phases 0–3.5
T00
Phase 5
ContPAQi/Aspel: live install validation for póliza A-hard tier

The póliza posting format for ContPAQi and Aspel COI is version-sensitive and not fully public. The plan's Task 00 gate requires confirming exact formats against a live install before writing the mappers — building against assumptions produces files the ERP silently rejects. This blocks Tasks 07–08 A-hard only; the full framework (Tasks 01–06), the A-cheap CFDI delivery tier, and all REST stubs build without it. Path: one friendly despacho with a ContPAQi install.

A-cheap tier
ships without
Task 00