Data Flow
Queue Messages
Section titled “Queue Messages”Each queue carries a specific message schema validated with Zod at both the producer and consumer.
errors-detected
Section titled “errors-detected”Sent by LogTailer when a new (or reopened) error is detected:
{ fingerprint: string, // SHA-256 hex incidentId: string, // ULID serviceName: string, triggerRoute: string, errorClass: "client_4xx" | "server_5xx" | "unhandled_exception", sampleEvent: ObservabilityEvent, occurrenceCount: number, firstSeen: string, // ISO 8601 lastSeen: string}triage-ready
Section titled “triage-ready”Sent by TestGen after reproduction testing:
{ incidentId: string, fingerprint: string, serviceName: string, repoUrl: string, testCaseR2Key: string, // R2 path to test-case.ts testResultR2Key: string, // R2 path to test-result.json reproductionConfirmed: boolean, sampleEvent: ObservabilityEvent}fix-ready
Section titled “fix-ready”Sent by CodeTriage after root cause analysis:
{ incidentId: string, fingerprint: string, serviceName: string, repoUrl: string, commitSha: string, testCaseR2Key: string, triageResult: { rootCauseFile: string, rootCauseLines: [number, number], rootCauseExplanation: string, fixStrategy: string, confidence: "high" | "medium" | "low", affectedFiles: string[] }, githubIssueNumber: number}completed
Section titled “completed”Sent by FixAgent after PR creation:
{ incidentId: string, fingerprint: string, serviceName: string, status: "resolved" | "wontfix" | "needs_human", githubPrNumber?: number, githubPrUrl?: string}Error Fingerprinting
Section titled “Error Fingerprinting”The fingerprint algorithm normalizes dynamic values before hashing:
| Pattern | Replacement |
|---|---|
UUIDs (xxxxxxxx-xxxx-...) | {uuid} |
| ISO timestamps | {timestamp} |
JWTs (eyJ...) | {token} |
| Email addresses | {email} |
| Numeric IDs (4+ digits) | {id} |
The fingerprint input is: "{serviceName}|{normalizedMessage}|{triggerRoute}|{topFrames}"
This means two errors with different request IDs but the same root cause produce the same fingerprint.
R2 Artifact Layout
Section titled “R2 Artifact Layout”sentinel-artifacts/ incidents/{incidentId}/ test-case.ts # Generated bun:test reproduction test test-result.json # { reproductionConfirmed, generatedAt } sample-event.json # Original observability event patch.diff # Git diff of the fix (added by FixAgent) pr-body.md # PR description markdown (added by FixAgent)D1 Database Flow
Section titled “D1 Database Flow”Write Path
Section titled “Write Path”- LogTailer →
INSERT INTO incidents(new error detected) - Each agent →
INSERT INTO agent_runs(audit trail) - LLM calls →
INSERT INTO llm_calls(cost tracking) - TestGen/FixAgent →
INSERT INTO artifacts(R2 references) - FixAgent →
INSERT INTO github_artifacts(PR/issue references)
Read Path
Section titled “Read Path”- LogTailer →
SELECT FROM service_configs(which services to poll) - LogTailer →
SELECT FROM incidents WHERE fingerprint = ?(dedup check) - Orchestrator →
SELECT FROM incidentswith filters (dashboard) - Orchestrator →
SELECT FROM artifacts WHERE incident_id = ?(detail view)