Open-source AI platform for end-to-end specification change management β idea, design documents, partner distribution, code generation, and certification β with AI agents at every stage and an evaluation gate between them.
AtOM β Agentic Task Orchestration & Management β is a full-stack, production-grade platform for the whole life of a specification change: an idea becomes research, design documents and schemas; those go out to the organisations that must implement them; their questions come back; code is generated against a real repository; and the result is certified. Each stage is an AI agent, and each hands to the next only after an evaluation gate passes.
- π Authoring pipeline β one prompt becomes deep research, a product canvas, a requirements document, a technical specification, XSD schemas, an explainer deck and certification test cases
- π€ Partner distribution over A2A β artifacts ship to registered partners on Google's Agent-to-Agent protocol, with a negotiation loop and per-partner implementation status
- π§ Retrieval-grounded generation β hybrid BM25 + pgvector search over an ingested corpus and over the target codebase, so agents cite files they actually read
- π οΈ Code generation against a real repo β plan, edit, review, repair and a real Maven build, with a human opening the merge request
- π Governance review stages β uploaded skill bundles run as review agents in a sandbox, producing a must-fix gate before code advances
- β Certification β an A2A conversation with a partner's bank agent, driving switch-level test cases through simulators
- π Eight independent security layers on the A2A boundary β TLS, JWT, HMAC envelopes, mTLS, CIDR allow-lists, rate limits, audit trail and key lifecycle
The platform was built for a payments ecosystem, where a central body publishes
a change and many banks and payment providers must implement it. Domain
vocabulary is being moved behind a pluggable domain pack (DOMAIN_PACK,
default network) so other ecosystems can use it. Until that work lands, some
generated prose is payments-specific β see backend/app/packs/ for the
interface and CONTRIBUTING.md for how to add a pack.
Eight services in the default stack, behind a single nginx front door:
flowchart TB
Browser(["Browser"])
NX["<b>nginx</b> Β· :80<br/>the only entry point"]
BE["<b>Platform Backend</b><br/>FastAPI Β· :8000<br/>agents Β· retrieval<br/>docgen Β· evaluation gate"]
PP["<b>Partner Platform</b><br/>separate repo & stack"]
subgraph data [" Data plane "]
direction LR
PG[("<b>Postgres 16</b><br/>relational + pgvector")]
RD[("<b>Redis</b><br/>broker Β· nonces Β· limits")]
OL(["<b>Ollama</b><br/>local embeddings"])
end
CEL["<b>Celery + Beat</b><br/>background agents<br/>retries Β· scheduled sweeps"]
Browser --> NX --> BE
BE --> PG
BE --> RD
BE --> OL
RD --> CEL
CEL --> PG
BE <-. " <b>A2A</b> " .-> PP
classDef entry fill:#E7ECF6,stroke:#2E4E8F,stroke-width:1.5px,color:#16233D
classDef core fill:#C9DBF5,stroke:#2E4E8F,stroke-width:2px,color:#16233D
classDef store fill:#E4F2EA,stroke:#1F6B45,stroke-width:1.5px,color:#123322
classDef worker fill:#FBF0DC,stroke:#8A5A00,stroke-width:1.5px,color:#3A2703
classDef ext fill:#F2F3F5,stroke:#8B929C,stroke-width:1.5px,stroke-dasharray:5 4,color:#3D444F
class Browser,NX entry
class BE core
class PG,RD,OL store
class CEL worker
class PP ext
style data fill:#FAFBFC,stroke:#C6CCD6,stroke-dasharray:3 3,color:#5C636E
The partner platform β the receiving side of every change β lives in its own repository and runs as its own stack: https://github.com/npci/atom-partner-platform. It connects to this platform as an authenticated A2A client, so nothing about it needs to be deployed here.
A2A traffic across that boundary is signed and authenticated: HMAC envelope + Bearer JWT + CIDR allow-list, with mTLS in the production overlay.
Certification simulators (certagent/, precert/) are separate stacks with
their own compose files and are not started by the quickstart.
- Docker with Compose v2 β the only supported way to run the full stack
- Roughly 15 GB of free disk, and 10β20 minutes for the first build
- Datastore passwords.
POSTGRES_PASSWORD,REDIS_PASSWORDandCERTSIM_INTERNAL_TOKENhave no defaults. Compose declares them as${VAR:?...}and refuses to start without them β a datastore password with a published default is a datastore with no password. Step 1 below sets all three. - An LLM provider key. The stack starts without one, but every AI feature
fails on authentication. One of
ANTHROPIC_API_KEY,OPENAI_API_KEY, or an internal gateway key. Step 2.
Nothing else. There are no certificates or partner credentials to obtain for a local stack.
1. Clone and configure
git clone <this-repo> && cd atom-network-platform
# Root .env β datastore credentials, read by docker-compose.yml
cp .env.example .env # then edit: set POSTGRES_PASSWORD and REDIS_PASSWORD
# Backend .env β the ~100 application settings
cp backend/.env.example backend/.envTwo env files, and both are needed. The root .env is what Compose
interpolates into docker-compose.yml; backend/.env is handed to the
backend, celery and celery_beat containers as their environment.
2. Add an LLM key
# backend/.env
LLM_PROVIDER=claude # claude | openai | ainxt | ollama
ANTHROPIC_API_KEY=sk-ant-...3. Create the shared docker network
docker network create certagent_cert-netThe backend, celery and celery_beat services attach to this network so they can
reach a certification agent when one is deployed. It is declared external, so
Compose expects it to already exist and will refuse to start with
"network certagent_cert-net declared as external, but could not be found".
Creating it empty is enough for a local stack.
4. Start the stack
docker compose up -d --buildEight services. The first build takes 10β20 minutes. Migrations run
automatically β the backend's command is alembic upgrade head followed by
uvicorn.
5. Create the first admin user
docker compose exec backend python seed.pyPrints the generated password once. Set ADMIN_EMAIL and ADMIN_PASSWORD
beforehand to choose your own; re-running is a no-op if the user exists.
6. Open the apps
| App | URL |
|---|---|
| Platform | http://localhost/a2a/ |
The partner platform is a separate stack from its own repository and is not started here. To exercise a full change round-trip, clone https://github.com/npci/atom-partner-platform, bring it up, and point it at this instance from its Settings UI.
7. Log in
Use the credentials printed by step 5. The login shows a CAPTCHA; for a local
loop set CAPTCHA_ENABLED=false in backend/.env and restart the backend β
leave it on anywhere others can reach.
Six roles exist β product_owner, product_manager, tech_lead,
infosec_reviewer, risk_reviewer and admin. Create further users from
Admin β User Management.
Change the seeded password.
docker compose run --rm -v "$(pwd)/backend/scripts:/app/bscripts" backend \
python /app/bscripts/reset_password.py <admin-email> --password '<new>'8. Run the tests
docker compose run --rm backend pytest # platform (~3,500 tests)
bash scripts/ci/sync-a2a-core.sh --check # vendored wire code matches canonical
bash scripts/ci/hygiene-check.sh # secrets, internal hosts, marks, linksCI runs the same three on every push β see .github/workflows/. The hygiene
gate currently reports broken documentation links and is advisory there; the
other two are blocking.
backend/ Platform backend (FastAPI)
app/agents/ ~100 LLM agents, one module per agent
app/prompts/ Externalised prompt text (.md), loaded not hardcoded
app/rag/ Hybrid retrieval: BM25 + pgvector, code + document ingest
app/docgen/ LangGraph .docx pipeline
app/a2a_common/ A2A wire code β GENERATED, see packages/a2a-core
app/packs/ Domain packs (vocabulary behind an interface)
frontend/ Platform UI (React 19 + Vite)
packages/a2a-core/ Canonical A2A wire code, vendored into each service
scripts/ci/ Hygiene, dependency-audit and sync gates
docs/ Setup guides, runbooks, plans, design records
| Repository | What it is |
|---|---|
| atom-partner-platform | The receiving side β reference base code partners fork to consume changes over A2A and plug in their own agents |
docker compose up -d --build backend # after dependency changes
docker compose restart nginx # after recreating any backend
docker compose run --rm backend alembic upgrade headLive-editing backend/app/** requires a local docker-compose.override.yml
bind mount β it is gitignored and absent by default.
Dependencies are hash-locked: images install from
requirements.<arch>.lock with --require-hashes, so editing
requirements.txt alone changes nothing until the lock is regenerated. Each
lock's header carries the command.
wiki/β architecture, workflow phases, retrieval, the evaluation gate and the A2A wire, each with a verified-at stamp β conventions, build patterns, and a gotcha indexdocs/β setup guides, runbooks, and the genericization plan
Stated plainly, because a platform that generates code invites assumptions:
- It does not deploy.
PHASE_B_RUNNER_MODE=buildcompiles the target repository and stops, reporting the artifacts the build actually produced.ssh/localrun an operator-supplied deploy script.demois fully simulated and labelled as such in every log line it emits. - Prompt injection is mitigated, not solved. Ingested specifications and
uploaded documents are untrusted input. See
SECURITY.md. - Output quality is measured, not assumed β but the golden-output suite
ships with two captured cases, covering two of the 125 tracked prompts. The
harness lives in
backend/tests/golden/. - The sandboxed
bashtool requires Docker. Where no daemon is reachable it refuses rather than falling back to an unisolated subprocess.
| Symptom | Cause and fix |
|---|---|
network certagent_cert-net ... not found |
The certagent stack owns that network. docker compose -f certagent/docker-compose.yml up -d first. |
502 Bad Gateway after rebuilding a backend |
nginx caches upstream DNS at startup. docker compose restart nginx. |
| Every AI feature returns an auth error | No LLM key. See Quick Start step 2. |
A backend/app/** edit has no effect |
app/ is baked into the image unless you add the override bind mount |
| A test edit has no effect | backend/tests/ is baked, not mounted. Rebuild, or docker cp the file in. |
pip ... hashes do not match on build |
The lockfile is stale, or you are building a different architecture. Regenerate β see the lock header. |
| Retrieval scores 0 for everything | The corpus is empty, or the embedding model was never pulled: docker exec atom_ollama ollama pull nomic-embed-text. |
| Document | What it covers |
|---|---|
USER_GUIDE.md |
Using the platform, role by role, from idea to certification |
DEPLOYMENT_GUIDE.md |
Installation, Docker and native, and production hardening |
CONFIGURATION.md |
How configuration works, and which layer wins |
FAQ.md |
Why questions the Troubleshooting table does not answer |
CHANGELOG.md |
Release history |
wiki/ |
Architecture, workflow phases, retrieval, the evaluation gate, the A2A wire |
CONTRIBUTING.md |
How to contribute, DCO sign-off, coding standards |
SECURITY.md |
Reporting a vulnerability, and the security posture |
We welcome contributions! Please read the following before submitting a pull request:
- CONTRIBUTING.md β how to get started, commit guidelines, DCO sign-off, and coding standards
- CODE_OF_CONDUCT.md β our community standards
- GOVERNANCE.md β how decisions are made and who the maintainers are
- SECURITY.md β how to report a vulnerability
Every change must pass bash scripts/ci/hygiene-check.sh, which gates secrets,
personal data, third-party marks, generated-file drift and dependency-lock
freshness.
All contributors are listed in AUTHORS.md.
MIT License β see LICENSE.
NOTICE is not required by MIT and is kept anyway: it is where this
project discharges the attribution its own dependencies require.
The licence covers code, not trademarks: see TRADEMARKS.md.
Third-party dependency licences are recorded in NOTICE.
AtOM is a single-vendor open-source project sponsored by the National Payments Corporation of India (the Authority). See GOVERNANCE.md for the full governance model, maintainer list, and decision-making process.