Part 4 of 7 in Specification Factory
Introducing Chronos: A Language for Product Intent
"We Built a New Language. I Know. Stay With Me."
I can already hear the groans. Another domain-specific language? Another thing to learn?
But here's the thing: You already have a requirements language. It's called Jira + Excel + Confluence + tribal knowledge. It's just not a very good one.
Your current "language" has:
- No syntax validation (typos everywhere)
- No type safety (references to things that don't exist)
- No semantic meaning (machines can't understand it)
- No validation (ambiguity discovered at runtime—aka production)
Chronos fixes this. And before you say "I don't want to learn a language," remember: PMs review Chronos, they don't write it. That's the AI's job.
What Makes Chronos Different
Chronos is designed around a simple idea: Product intent is data. If we structure it correctly, we can:
- Validate it (catch ambiguity before code is written)
- Transform it (generate Jira, Gherkin, diagrams, telemetry)
- Track it (trace features back to business outcomes)
- Version it (see how requirements evolved over time)
Let's see what this looks like.
A Complete Example: Insurance Claim Submission
Here's a Chronos definition for the claim submission journey we've been discussing:
namespace com.insurance.claims.submission
// Import existing entities from the data model
use com.insurance.data.policies#Policy
use com.insurance.data.claims#Claim
use com.insurance.data.users#Policyholder
// Define what success looks like
@kpi(metric: "ClaimSubmissionRate", target: ">90%")
@kpi(metric: "AutoApprovalRate", target: ">85%")
@slo(latency: "5s", percentile: 95)
journey SubmitClaim {
actor: Policyholder
// What must be true before this journey starts
preconditions: [
"Actor has active policy",
"Actor is authenticated",
"No claim submitted for this incident already"
]
// The happy path
steps: [
step NavigateToClaimForm {
action: "Clicks 'Submit Claim' from dashboard"
expectation: "Form loads with policy details pre-filled"
@telemetry(event: "ClaimFormStarted", attributes: ["policyId", "userId"])
},
step ProvideIncidentDetails {
action: "Enters incident date, type, and description"
expectation: "System validates incident date is within policy period"
outcome: If("incident date > 30 days ago", TransitionTo(IncidentTooOld))
},
step UploadDocumentation {
action: "Attaches photos/receipts (max 5 files, 10MB each)"
expectation: "System validates file types (jpg, png, pdf) and sizes"
@compliance(policy: "DataRetention", duration: "7years")
@compliance(policy: "HIPAA", applies: "medical claims only")
},
step ReviewAndSubmit {
action: "Reviews claim summary and clicks 'Submit'"
expectation: "System creates Claim entity with status SUBMITTED"
@telemetry(event: "ClaimSubmitted", attributes: ["claimId", "claimAmount", "claimType"])
outcome: If("claimAmount < $1000 AND validPolicy", TransitionTo(AutoApproved),
Else(TransitionTo(ManualReview)))
},
step ReceiveConfirmation {
action: "Views confirmation page with claim number"
expectation: "System sends confirmation email with claim number and next steps"
outcome: TransitionTo(ClaimTrackingAvailable)
}
]
// Error and edge cases
variants: [
variant IncidentTooOld {
trigger: "Incident date is more than 30 days ago"
outcome: "Show error: Claims must be submitted within 30 days of incident"
@telemetry(event: "ClaimRejected", reason: "incident_too_old")
},
variant PolicyExpired {
trigger: "Policy was not active on incident date"
outcome: "Show error: No active coverage for incident date"
},
variant FileTooLarge {
trigger: "Uploaded file exceeds 10MB"
outcome: "Show error: Maximum file size is 10MB. Please compress or resize."
},
variant AutoApproved {
trigger: "Claim amount < $1000 AND policy is valid"
outcome: "Claim status set to APPROVED, payment processed within 2 business days"
@telemetry(event: "ClaimAutoApproved", attributes: ["claimId", "approvalAmount"])
},
variant ManualReview {
trigger: "Claim amount >= $1000 OR requires additional verification"
outcome: "Claim assigned to adjuster, user notified of 3-5 day review period"
@telemetry(event: "ClaimSentToReview", attributes: ["claimId", "assignedAdjuster"])
}
]
// What must be true when this journey completes successfully
postconditions: [
"Claim record exists with valid claim number",
"User received confirmation email",
"Claim telemetry event recorded"
]
}
What Just Happened?
That Chronos definition contains everything needed to build the feature:
Business Logic
- Claim submission rules (30-day window, file size limits)
- Auto-approval criteria (< $1,000 with valid policy)
- Success metrics (>90% submission rate, >85% auto-approval)
Technical Requirements
- Which entities to use (Policy, Claim, Policyholder)
- Performance expectations (5-second p95 latency)
- Data validation rules (file types, date ranges)
Compliance
- HIPAA applies to medical claims
- 7-year data retention required
- Audit trail via telemetry events
Testing Scenarios
- Happy path (all 5 steps)
- Error cases (incident too old, policy expired, file too large)
- Business logic branches (auto-approve vs manual review)
Telemetry
- Which events to track
- Which attributes to capture
- How to measure KPIs
From Chronos to Everything Else
Here's what gets generated from that single Chronos file:
For Product/QA (Jira & Gherkin)
Jira Epic:
# Submit Insurance Claim
## Business Value
- KPI: Claim Submission Rate >90%
- KPI: Auto-Approval Rate >85%
- SLO: 95th percentile latency <5s
## Stories
1. As a policyholder, I want to navigate to claim form from dashboard
2. As a policyholder, I want to provide incident details with date validation
3. As a policyholder, I want to upload supporting documentation
4. As a policyholder, I want to review and submit my claim
5. As a policyholder, I want to receive confirmation of submission
## Edge Cases
- Incident date > 30 days old
- Policy expired on incident date
- File upload exceeds 10MB limit
- Auto-approval for claims < $1000
- Manual review for claims >= $1000
Gherkin Test Scenarios:
Feature: Submit Insurance Claim
Background:
Given a policyholder is authenticated
And the policyholder has an active policy
Scenario: Successfully submit claim under $1000
When the policyholder navigates to the claim form
And enters incident details from 5 days ago
And uploads 2 photos (each 3MB)
And submits a claim for $800
Then the claim is created with status SUBMITTED
And the claim is automatically approved
And a confirmation email is sent
And a "ClaimAutoApproved" event is recorded
Scenario: Claim over $1000 requires manual review
When the policyholder submits a claim for $5000
Then the claim is created with status SUBMITTED
And the claim is assigned to an adjuster
And a "ClaimSentToReview" event is recorded
Scenario: Incident date too old
When the policyholder enters an incident date from 45 days ago
Then the system shows error "Claims must be submitted within 30 days"
And a "ClaimRejected" event is recorded with reason "incident_too_old"
For Engineering (State Diagrams & Telemetry)
Mermaid State Diagram:
stateDiagram-v2
[*] --> FormLoaded
FormLoaded --> IncidentDetailsEntered
IncidentDetailsEntered --> IncidentTooOld : date > 30 days
IncidentDetailsEntered --> DocumentationUploaded : date ok
DocumentationUploaded --> FileTooLarge : file > 10MB
DocumentationUploaded --> ReadyToSubmit : files ok
ReadyToSubmit --> Submitted
Submitted --> AutoApproved : amount < $1000
Submitted --> ManualReview : amount >= $1000
AutoApproved --> [*]
ManualReview --> [*]
IncidentTooOld --> [*]
FileTooLarge --> DocumentationUploaded : retry
OpenTelemetry Schema:
events:
- name: ClaimFormStarted
attributes:
- policyId: string
- userId: string
- name: ClaimSubmitted
attributes:
- claimId: string
- claimAmount: number
- claimType: string
- name: ClaimAutoApproved
attributes:
- claimId: string
- approvalAmount: number
- name: ClaimRejected
attributes:
- claimId: string
- reason: string
The Magic: It's Validated
Before generating anything, Chronos validates:
✅ Entities exist:
Policy,Claim,Policyholderare defined in data model
✅ Transitions are complete:
- Every
TransitionTo(X)has a matching step or variantX
✅ Business rules are feasible:
- Auto-approval references
claimAmount(which must be a Claim field)
✅ Compliance is enforced:
- HIPAA policy applied correctly to medical claims
✅ Telemetry is measurable:
- KPIs reference events that are actually emitted
If any of these fail, you get a validation error before code is written:
Error: Journey 'SubmitClaim' references entity 'Claim.claimAmount'
but field 'claimAmount' does not exist in com.insurance.data.claims#Claim
Suggestion: Add 'claimAmount' to Claim entity or use existing field 'amount'
Why PMs Don't Write This
"But wait," you're thinking, "I still have to learn this syntax!"
No, you don't. Here's the actual workflow:
-
PM describes the journey in a conversation with an AI agent:
"We need to let policyholders submit claims online. They should be able to upload photos. Claims under $1,000 should auto-approve. We need to track submission rates and auto-approval rates. HIPAA applies."
-
AI generates the Chronos definition based on:
- Your company's existing data models
- Your company's compliance policies
- Your company's engineering patterns
- Standard insurance industry practices
-
PM reviews the Chronos file (like a code review):
- "Yes, 30-day window is correct"
- "No, file limit should be 5MB not 10MB"
- "Add a check for suspended policies"
-
AI updates and regenerates
The Chronos file becomes the source of truth. Human-readable for review. Machine-readable for generation.
Next: The Full Stack
Chronos doesn't exist in isolation. It's one layer of a complete software factory:
- Chronos defines what users need to accomplish
- Smithy defines how services communicate
- Capacitor defines how data is structured
- Flux defines how UI is presented
- Fusion defines how infrastructure is deployed
In the next post, The Full Stack of Intent, we'll show how these five languages work together—and why that matters for product managers.
Want to dive deeper?
This is Part 4 of the "Look Up" series exploring how AI is finally freeing product managers to do their best work.
Specification Factory
Part 4 of 7
The Specification Factory: Having Your Cake and Eating It Too

The Full Stack of Intent: From Customer Problem to Production Code
View all posts in this series
- 1.The Best Product Managers Are Looking Down
- 2.The Spec Gap: What Engineering Sees That Product Doesn't
- 3.The Specification Factory: Having Your Cake and Eating It Too
- 4.Introducing Chronos: A Language for Product Intent
- 5.The Full Stack of Intent: From Customer Problem to Production Code
- 6.Starting Small: The 30-Minute Pilot That Sells Itself
- 7.The Strategic PM: What Product Management Looks Like After the Specification Factory
