SprintFlow architecture#
SprintFlow turns Jira stories into reviewed, verified draft pull/merge requests. People always merge.
1. System context#
flowchart LR
dev([Developers<br/>Managers<br/>Admins]) -->|SSO, browser| console
subgraph SprintFlow
console[Web console<br/>+ API]
workers[Workers]
db[(PostgreSQL<br/>state, queue,<br/>console data)]
s3[(S3 / MinIO<br/>reports, patches,<br/>proof videos)]
console <--> db
workers <--> db
workers --> s3
console -->|signed links| s3
end
jira[Jira] <-->|stories, sprints,<br/>comments, status| workers
jira -. webhooks .-> console
git[GitLab / GitHub /<br/>Bitbucket / Azure DevOps] <-->|clone, draft MR,<br/>review comments, CI| workers
git -. webhooks .-> console
claude[Claude<br/>Anthropic API / Bedrock / Vertex] <-->|redacted prompts| workers
workers -->|alerts| chat[Slack / Teams / email]
workers -->|traces, metrics| obs[Prometheus /<br/>OpenTelemetry]
Everything that leaves SprintFlow is either a draft PR/MR, a Jira comment/status change, or an alert. There is no code path that merges, approves or marks a PR ready — no provider adapter has such a method, and a test enforces it.
2. What happens to one story#
flowchart TD
A[Story assigned / sprint starts<br/>or 'New run'] --> P[Prepare<br/>clone, detect stack]
P --> B[Baseline<br/>build + test untouched code]
B --> U[Understand<br/>goal, acceptance criteria,<br/>questions on Jira if needed]
U --> PL[Plan<br/>files, approach, root cause]
PL --> I[Implement<br/>code + tests]
I --> V{Verify<br/>build + tests vs baseline}
V -- new failures --> F[Fix round] --> V
V -- ok --> R{Independent review<br/>fresh conversation}
R -- changes requested --> F2[Fix round] --> V
R -- approved --> RK{Risky paths?}
RK -- yes --> AP[Person approves] --> E
RK -- no --> E[Browser proof<br/>4K video on Jira]
E --> PR[Draft PR/MR<br/>+ Jira In Review]
PR --> FU[PR follow-up<br/>review comments, failed CI]
FU -.-> PR
Each box is a stage, saved when it completes, so a run survives crashes and restarts: it resumes from the last completed stage. Understand, Plan, Implement, Review, fix rounds and writing the browser-proof test call Claude; preparing, baselining, verifying, recording and publishing are plain code (no tokens).
3. Components#
| Component | Role | Code |
|---|---|---|
| Pipeline | Runs the stages, loops, checkpoints, self-healing, budgets | pipeline.py, steps/ |
| Agent loop | Bounded tool-use conversation with Claude (read/search/edit files) in a sandboxed workspace | agent.py, tools.py |
| Stack & scope | Detects 30+ ecosystems or reads the project's CI config; builds/tests only affected components in monorepos | stack.py, ci_commands.py, scope.py |
| Verify | Baseline vs change comparison per test, flaky-test re-runs, test report parsing (JUnit, TRX, Jest, go, RSpec, cargo) | steps/verify.py, testresults.py |
| Data guard | Reversible redaction of personal data and secrets; withheld files | guard.py |
| Isolation | Each build/test command in a throwaway container, no network | isolation.py |
| Providers | GitHub, GitLab, Bitbucket (Cloud, Server), Azure DevOps, Gitea, generic git | integrations/ |
| Jira | Tickets, comments, attachments, sprints (Agile API), workflow transitions | integrations/jira.py, console/sprint.py |
| Memory | Per-repository lessons from past runs and human reviews | memory.py |
| Console | Web UI + REST API: runs, sprint, team dashboard, settings, users, audit | console/ |
| Supervisor | 24/7 watchdog: stuck runs, reminders, dependency health, disk, housekeeping | supervisor.py |
| Queue & workers | Database job queue; sprintflow worker executes runs on any machine |
jobqueue.py |
| Storage | Files (single host) or PostgreSQL (scale-out); S3 for artifacts | storage.py, db.py, artifacts_s3.py |
| Alerts & telemetry | Slack/Teams/email/webhook alerts; Prometheus, JSON logs, OpenTelemetry | alerts.py, telemetry.py |
4. Deployment topologies#
flowchart TB
subgraph single[Single node - pilot, one team]
c1[Console<br/>runs execute inline] --- pv[(Persistent volume<br/>runs + console data)]
end
subgraph prod[Production - scale-out]
ing[Ingress / TLS] --> c2[Console x2<br/>one leads background work]
c2 --> pg[(PostgreSQL)]
w[Workers x N<br/>autoscaled] --> pg
w --> s[(S3)]
c2 --> s
end
- Single node: one console process; runs execute inside it; state on a persistent volume. No database needed.
- Production: consoles and workers are stateless; PostgreSQL holds run state, events, the job queue and console
data; S3 holds artifacts. Consoles elect a leader (database lease) so background work runs exactly once.
Workers claim jobs with
SELECT … FOR UPDATE SKIP LOCKED; a dead worker's job is retried.
5. Security model#
| Layer | Control |
|---|---|
| Output | Draft PRs only; people merge; risk-based approvals for sensitive paths |
| Model input | Data guard: personal data and secrets become placeholders; credential files withheld; Bedrock in-region |
| Execution | Containers with no network during build/test, non-root, capabilities dropped; fails closed |
| Access | SSO (OIDC) with group-based roles: viewer, operator, manager, admin; audit log of every action |
| Secrets | Encrypted at rest (key from a secrets manager); never returned by the API; secrets-manager references |
| Inbound | Webhooks authenticated (HMAC / tokens); strict CSP, CSRF, secure cookies |
| Cost | Per-run caps, daily/monthly budgets, alerts, stop switch |
Details: security.md.
6. Tenancy — what one installation serves#
One installation = one Jira site + one repository (any number of users, sprint boards, runs and workers). Organisations run one installation per repository or team; they can share one PostgreSQL server (a database each), one S3 bucket (a prefix each) and one SSO application. See deployment.md.