Genairus logoGenAI-R-Us
Genairus logoGenAI-R-Us
The Full Stack of Intent: From Customer Problem to Production Code
chronossoftware-factoryintegrationfull-stack
Part 5 of 7 in Specification Factory

The Full Stack of Intent: From Customer Problem to Production Code

Scott Walkinshaw

Six Languages, One Ecosystem

Chronos doesn't exist in isolation. It's one layer in a complete software generation ecosystem:

LayerLanguagePurposeGenerates
RequirementsChronosJourneys, actors, outcomesJira, Gherkin, Telemetry
APIsSmithyServices, operationsServers, Clients, Docs
DataCapacitorEntities, relationshipsSchemas, Repositories, SDKs
UIsFluxComponents, layoutsReact, SwiftUI, Compose
InfrastructureFusionResources, deploymentsTerraform, Helm, Pipelines
ArchitectureLikeC4System topology, boundariesInteractive diagrams, MCP server, React components

Each language works independently. You can use Chronos without Capacitor. You can use Flux without Chronos. But when you use them together, something powerful emerges.

Smithy and LikeC4 are external open-source projects integrated into the Genairus ecosystem. Smithy (by AWS) defines your API contracts; LikeC4 defines your system architecture as code. Both complement the Genairus languages without replacing them.

The Power of Integration (When You Want It)

Let's continue with our insurance claim example. We've defined the journey in Chronos. Now let's see how it connects to the rest of the stack.

Layer 1: Requirements (Chronos)

namespace com.insurance.claims.submission

journey SubmitClaim {
    actor: Policyholder

    steps: [
        step ProvideIncidentDetails {
            action: "Enters incident date, type, and description"
            expectation: "System validates incident date is within policy period"
        },

        step ReviewAndSubmit {
            action: "Reviews claim summary and clicks 'Submit'"
            expectation: "System creates Claim entity with status SUBMITTED"
            @telemetry(event: "ClaimSubmitted")
        }
    ]
}

Layer 2: Data (Capacitor)

The Chronos journey references a "Claim entity." Let's define it:

namespace com.insurance.data.claims

entity Claim {
    @required @id
    id: String

    @required
    policyId: String  // Foreign key to Policy

    @required
    incidentDate: DateTime

    @required
    incidentType: String  // "Auto", "Home", "Medical"

    description: String
    claimAmount: Decimal

    @required
    status: ClaimStatus

    attachments: List<Attachment>

    @required
    createdAt: DateTime

    @required
    updatedAt: DateTime

    @compliance(retention: "7years")
    @compliance(hipaa: true, condition: "incidentType == 'Medical'")
}

enum ClaimStatus {
    DRAFT
    SUBMITTED
    UNDER_REVIEW
    APPROVED
    DENIED
    PAID
}

entity Attachment {
    @required @id
    id: String

    @required
    filename: String

    @required
    fileSize: Integer  // bytes

    @required
    contentType: String  // "image/jpeg", "application/pdf"

    @required
    uploadedAt: DateTime

    @pii
    storagePath: String
}

Layer 3: API (Smithy)

The journey needs an API to submit claims:

namespace com.insurance.api.claims

use com.insurance.data.claims#Claim
use com.insurance.data.claims#ClaimStatus

@http(method: "POST", uri: "/claims")
operation SubmitClaim {
    input: SubmitClaimRequest,
    output: SubmitClaimResponse,
    errors: [
        ValidationException,
        PolicyNotFoundException,
        UnauthorizedException
    ]
}

structure SubmitClaimRequest {
    @required
    policyId: String,

    @required
    incidentDate: DateTime,

    @required
    incidentType: String,

    description: String,
    claimAmount: Decimal,

    attachmentIds: List<String>
}

structure SubmitClaimResponse {
    @required
    claimId: String,

    @required
    status: ClaimStatus,

    @required
    createdAt: DateTime,

    estimatedReviewTime: String  // "2-3 business days"
}

Layer 4: UI (Flux)

The journey needs a UI for claim submission:

namespace com.insurance.ui.claims

use com.insurance.data.claims#Claim
use com.insurance.api.claims#SubmitClaim

component ClaimSubmissionForm {
    props: {
        policyId: String
    }

    state: {
        incidentDate: DateTime?
        incidentType: String?
        description: String?
        claimAmount: Decimal?
        attachments: List<File>
        isSubmitting: Boolean = false
    }

    layout: VStack {
        spacing: 16

        children: [
            DatePicker {
                label: "Incident Date"
                value: state.incidentDate
                maxDate: today()
                required: true
            },

            Dropdown {
                label: "Incident Type"
                options: ["Auto", "Home", "Medical"]
                value: state.incidentType
                required: true
            },

            TextArea {
                label: "Description"
                value: state.description
                maxLength: 500
                placeholder: "Please describe what happened..."
            },

            CurrencyInput {
                label: "Estimated Claim Amount"
                value: state.claimAmount
                currency: "USD"
            },

            FileUpload {
                label: "Attachments"
                accept: ["image/jpeg", "image/png", "application/pdf"]
                maxSize: "10MB"
                maxFiles: 5
                onUpload: (files) => state.attachments = files
            },

            Button {
                label: "Submit Claim"
                style: "primary"
                disabled: !isFormValid() || state.isSubmitting
                onClick: handleSubmit
            }
        ]
    }

    actions: {
        handleSubmit: async () => {
            state.isSubmitting = true
            try {
                let response = await SubmitClaim({
                    policyId: props.policyId,
                    incidentDate: state.incidentDate,
                    incidentType: state.incidentType,
                    description: state.description,
                    claimAmount: state.claimAmount,
                    attachmentIds: state.attachments.map(f => f.id)
                })
                navigate(`/claims/${response.claimId}/confirmation`)
            } catch (error) {
                showError(error.message)
            } finally {
                state.isSubmitting = false
            }
        }
    }
}

Layer 5: Infrastructure (Fusion)

The journey needs infrastructure to run on:

namespace com.insurance.infra.claims

use com.insurance.data.claims#Claim

infrastructure ClaimsService {
    cloud: "aws"
    region: "us-east-1"

    resources: {
        Database claimsDb {
            engine: "postgres"
            version: "15"
            instanceClass: "db.t3.micro"
            storage: 20GB
            backup: {
                enabled: true
                retentionDays: 7
            }
            // Deploy Capacitor Claim schema here
        }

        Compute claimsApi {
            type: "container"
            image: "claims-api:latest"
            replicas: 3
            resources: {
                cpu: "1vCPU"
                memory: "2GB"
            }
            environment: {
                DATABASE_URL: claimsDb.connectionString
                LOG_LEVEL: "info"
            }
            // Deploy Smithy SubmitClaim operation here
        }

        Storage attachmentsBucket {
            type: "s3"
            encryption: true
            lifecycle: {
                transition: {
                    storageClass: "GLACIER"
                    afterDays: 90
                }
            }
            // Claim attachments stored here
        }

        LoadBalancer claimsLb {
            type: "application"
            targets: [claimsApi]
            healthCheck: {
                path: "/health"
                interval: 30s
            }
        }
    }

    monitoring: {
        metrics: [
            "ClaimSubmissionRate",
            "ClaimAutoApprovalRate",
            "ApiLatencyP95"
        ]
        alerts: [
            {
                condition: "ApiLatencyP95 > 5s"
                severity: "high"
                notify: "oncall-engineering"
            }
        ]
    }
}

The Magic: Cross-Layer Validation

Here's where it gets powerful. When you have all five layers defined, the system can validate across the entire stack:

Validation Example 1: Field References

Chronos says:

expectation: "System creates Claim entity with status SUBMITTED"

Validation checks:

  • Claim entity exists in Capacitor? Yes (com.insurance.data.claims#Claim)
  • Claim has a status field? Yes
  • SUBMITTED is a valid ClaimStatus? Yes

If Validation Fails:

Error: Journey 'SubmitClaim' expects Claim.status to be set to 'SUBMITTED'
but ClaimStatus enum does not include 'SUBMITTED'

Available values: DRAFT, UNDER_REVIEW, APPROVED, DENIED, PAID

Suggestion: Add 'SUBMITTED' to ClaimStatus enum or use existing value 'UNDER_REVIEW'

Validation Example 2: API Operations

Chronos journey references submitting a claim. Smithy API defines SubmitClaim operation. Flux component calls SubmitClaim with specific parameters.

Validation checks:

  • ✅ Does SubmitClaim operation exist? Yes
  • ✅ Do the parameters match? Checking...
    • Flux sends policyId: String
    • Flux sends incidentDate: DateTime
    • Flux sends attachmentIds: List<String>
  • ✅ Does Flux handle all error cases?
    • Flux catches ValidationException
    • Flux catches PolicyNotFoundException

Validation Error:

Error: FluxComponent 'ClaimSubmissionForm' calls Smithy operation 'SubmitClaim'
but does not handle error case 'PolicyNotFoundException'

Suggestion: Add error handling for invalid policy IDs

Validation Example 3: Infrastructure Requirements

Chronos journey has SLO: @slo(latency: "5s", percentile: 95) Fusion infrastructure deploys API with specific resources.

Validation checks:

  • ✅ Can db.t3.micro + 1vCPU/2GB meet 5-second p95 latency? Checking...
  • ⚠️ Performance testing suggests this may not meet SLO under load

Warning:

Warning: Journey 'SubmitClaim' requires p95 latency < 5s
but infrastructure spec uses db.t3.micro which may not meet this under expected load

Suggestion: Consider db.t3.small or add read replicas

The Ontology Engine

Behind the scenes, there's an ontology engine that understands the relationships between all six languages:

  • Chronos journeys reference Capacitor entities
  • Smithy operations use Capacitor entities as input/output
  • Flux components call Smithy operations
  • Fusion infrastructure deploys Smithy services and Capacitor databases
  • Chronos telemetry measures Smithy API performance

This creates a knowledge graph of your entire system:

Journey: SubmitClaim
  ├─ creates → Entity: Claim
  ├─ calls → Operation: Smithy.SubmitClaim
  ├─ requires → Component: ClaimSubmissionForm
  ├─ measures → KPI: ClaimSubmissionRate
  └─ deploys to → Infrastructure: ClaimsService

When you change something, the impact ripples through the graph:

Change: Rename Claim.status to Claim.currentStatus

Impact Analysis:

  • 🔴 Chronos: 2 journeys reference Claim.status (must update)
  • 🔴 Smithy: SubmitClaimResponse includes status field (must update)
  • 🔴 Flux: ClaimStatusBadge component reads claim.status (must update)
  • 🟢 Fusion: No impact (infrastructure doesn't reference this field)

The system shows you exactly what breaks before you make the change.

But Wait, I Don't Want All Six Languages

Good news: You don't need all five.

Every language is independently useful:

  • Use Chronos alone to generate Jira stories and test scenarios
  • Use Capacitor alone to generate database schemas and migrations
  • Use Flux alone to generate React and SwiftUI components
  • Use Smithy alone to generate API clients and servers
  • Use Fusion alone to generate Terraform and Helm charts

The integration is optional. It's there when you need it, invisible when you don't.

Why This Matters for PMs

As a product manager, you don't need to master six languages. But you benefit from their integration:

Before (Fragmented World)

  • You write requirements in Jira
  • Engineering defines APIs in one format
  • Data team defines schemas in another format
  • Frontend uses different entity names than backend
  • Nobody's sure if the infrastructure can handle the load
  • Changes ripple unpredictably

After (Integrated World)

  • You define requirements in Chronos
  • System validates against existing data models
  • System checks API compatibility
  • System verifies UI references correct endpoints
  • System warns if infrastructure can't meet SLOs
  • Changes show impact before they're made

You're still making product decisions. But you have infrastructure that prevents bad decisions from making it to production.

Next: Making It Real

"This sounds amazing," you're thinking, "but how do I actually adopt this?"

In the next post, Starting Small, we'll show you the 30-minute pilot that gets stakeholders bought in—no massive investment, no org-wide rollout, just one feature that proves the value.


This is Part 5 of the "Look Up" series exploring how AI is finally freeing product managers to do their best work.