Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Empty file removed .empty
Empty file.
128 changes: 70 additions & 58 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,45 @@
# Norma
<p align="center">
<img src="docs/assets/norma-logo.png" alt="Norma" height="80" />
</p>

Norma is a cloud-agnostic, LLM-agnostic platform that uses [LiteLLM](https://docs.litellm.ai/) to abstract away model providers. Any LLM backend — Vertex AI, OpenAI, Azure, or others — can be swapped without code changes.
<p align="center">
<em>AI compliance, simplified</em>
</p>

<p align="center">
<a href="https://github.com/airbus/norma/actions/workflows/ci.yml"><img src="https://github.com/airbus/norma/actions/workflows/ci.yml/badge.svg" alt="CI" /></a>
<a href="LICENSE"><img src="https://img.shields.io/badge/licence-Apache%202.0-blue" alt="Licence" /></a>
<img src="https://img.shields.io/badge/python-3.13-3776ab" alt="Python 3.13" />
<img src="https://img.shields.io/badge/node-22-339933" alt="Node 22" />
<img src="https://img.shields.io/badge/TypeScript-5-3178c6" alt="TypeScript" />
<img src="https://img.shields.io/badge/docker-compose-2496ed" alt="Docker Compose" />
</p>

---

<p align="center"><img src="docs/assets/screenshot.png" alt="Norma screenshot" width="800" /></p>

## What is Norma?

Norma helps teams achieve **EU AI Act** compliance by combining structured project management with an AI-powered assistant that understands your project context, uploaded documents, codebase, and compliance obligations to guide you through risk classification, evidence gathering, and reporting.

Norma is **cloud-agnostic** and **LLM-agnostic**. It uses [LiteLLM](https://docs.litellm.ai/) to abstract model providers, so any backend (Vertex AI, OpenAI, Azure, or others) can be swapped without code changes.

## Features

**Risk Classification.** Interactive questionnaire following the EU AI Act decision tree to determine your AI system's risk level.

**Compliance Reporting.** Structured checklists with evidence tracking and validation to build your EU AI Act compliance case.

**Document Management.** Upload compliance documents as PDFs. Norma extracts and summarises the content so the AI assistant can reference it in context.

**Norma AI Assistant.** A context-aware chat assistant that understands your project details, uploaded documents, codebase, and reporting progress to provide tailored compliance guidance.

**Codebase Analysis.** Connect a GitHub repository to generate architecture diagrams and technical summaries that feed into compliance assessments.

**Multi-Language Support.** Full interface localisation in English, Spanish, French, and German, with AI responses adapted to the user's preferred language.

**LLM-Agnostic.** Swap between any LLM provider (Vertex AI, OpenAI, Azure, local models) by changing a single environment variable.

## Architecture

Expand All @@ -22,83 +61,56 @@ graph TD
end
```

| Service | Stack | Port |
| ------------ | ------------------------------ | ---- |
| **Frontend** | React + Vite + Tailwind/shadcn | 3000 |
| **Backend** | FastAPI + ADK + LiteLLM | 8000 |
| **Pipelines**| FastAPI + ADK + LiteLLM | 8001 |
| **Database** | PostgreSQL 16 + pgvector | 5432 |
| Service | Stack | Port |
| --- | --- | --- |
| **Frontend** | React 19, Vite, Tailwind CSS, shadcn/ui | 3000 |
| **Backend** | FastAPI, Google ADK, LiteLLM, SQLAlchemy | 8000 |
| **Pipelines** | FastAPI, Google ADK, LiteLLM, PyMuPDF | 8001 |
| **Database** | PostgreSQL 16 + pgvector | 5432 |

## Quick Start

```bash
# 1. Clone the repo
git clone https://github.com/airbus/norma.git
cd norma

# 2. Copy environment config
cp .env.example .env

# 3. Start the full stack
# Edit .env to configure your LLM provider (see .env.example for options)
docker compose up
```

The frontend is available at `http://localhost:3000`, the backend API at `http://localhost:8000`, and the pipelines service at `http://localhost:8001`.
The frontend is available at [localhost:3000](http://localhost:3000), the backend API at [localhost:8000](http://localhost:8000), and the pipelines service at [localhost:8001](http://localhost:8001).

## Development

See [CONTRIBUTING.md](CONTRIBUTING.md) for detailed development setup instructions.

### Frontend
See [CONTRIBUTING.md](CONTRIBUTING.md) for the full development setup, code style, and PR process.

```bash
cd frontend
npm install
npm run dev
```
# Frontend
cd frontend && npm install && npm run dev

### Backend / Pipelines
# Backend or Pipelines
cd backend && uv sync && uv run python main.py

```bash
cd backend # or cd pipelines
uv sync
uv run python main.py
# Database migrations
cd backend && uv run alembic upgrade head
```

### Database Migrations
## Documentation

```bash
cd backend
uv run alembic upgrade head # apply migrations
uv run alembic revision --autogenerate -m "description" # create migration
```
| Document | Description |
| --- | --- |
| [Getting Started](docs/getting-started.md) | Step-by-step guide to setting up Norma and creating your first project |
| [Architecture](docs/architecture.md) | System design, data models, and integration patterns |
| [API Reference](docs/api-reference.md) | REST endpoint documentation |
| [Chat Agent](docs/chat-agent.md) | Norma AI assistant architecture and prompt assembly |
| [Document Processing](docs/document-processing.md) | Document and codebase processing pipelines |
| [Risk Evaluation](docs/risk-evaluation.md) | EU AI Act risk classification decision tree |
| [Deployment](docs/deployment.md) | Docker Compose configuration and production setup |

## Project Structure
## Contributing

```
norma/
├── frontend/ # React + Vite + Tailwind CSS
│ └── src/
├── backend/ # FastAPI + ADK + LiteLLM
│ ├── app/
│ │ ├── api/ # API routes
│ │ ├── agents/ # ADK agents
│ │ ├── core/ # Config, database
│ │ ├── models/ # SQLAlchemy models
│ │ ├── schemas/ # Pydantic schemas
│ │ └── services/ # Business logic
│ └── alembic/ # Database migrations
├── pipelines/ # Data processing service
│ ├── app/
│ │ ├── api/ # API routes
│ │ ├── core/ # Config, database
│ │ ├── models/ # SQLAlchemy models
│ │ ├── services/ # Business logic
│ │ └── tasks/ # Pipeline tasks
│ └── ...
└── docker-compose.yml
```
Contributions are welcome. Please read the [contributing guidelines](CONTRIBUTING.md) and [code of conduct](CODE_OF_CONDUCT.md) before opening a pull request.

## License
## Licence

See [LICENSE](LICENSE) for details.
This project is licensed under the Apache License 2.0. See the [LICENSE](LICENSE) file for details.
6 changes: 3 additions & 3 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ services:
- GOOGLE_APPLICATION_CREDENTIALS=/root/.config/gcloud/application_default_credentials.json
volumes:
- norma-data:/data
- ${GOOGLE_APPLICATION_CREDENTIALS:-.empty}:/root/.config/gcloud/application_default_credentials.json:ro
- ${GOOGLE_APPLICATION_CREDENTIALS:-/dev/null}:/root/.config/gcloud/application_default_credentials.json:ro
depends_on:
db:
condition: service_healthy
Expand All @@ -48,7 +48,7 @@ services:
- GOOGLE_APPLICATION_CREDENTIALS=/root/.config/gcloud/application_default_credentials.json
volumes:
- norma-data:/data
- ${GOOGLE_APPLICATION_CREDENTIALS:-.empty}:/root/.config/gcloud/application_default_credentials.json:ro
- ${GOOGLE_APPLICATION_CREDENTIALS:-/dev/null}:/root/.config/gcloud/application_default_credentials.json:ro
depends_on:
db:
condition: service_healthy
Expand All @@ -71,7 +71,7 @@ services:

secrets:
ca_cert:
file: ${CA_CERT_PATH:-.empty}
file: ${CA_CERT_PATH:-/dev/null}

volumes:
pgdata:
Expand Down
117 changes: 116 additions & 1 deletion docs/api-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,10 @@ Upload a file for a framework document. Accepts `multipart/form-data` with a `fi

Supported file types: PDF, Markdown, TXT, CSV, JSON, XML, HTML.

### `DELETE /api/projects/{project_id}/documents/{document_id}/upload`

Remove an uploaded file from a framework document. Clears the file path, file name, summary, and upload timestamp. The document placeholder remains.

### Custom Documents

Free-form document uploads not tied to any framework definition. Custom document summaries are included in the chat agent and reporting suggestion context.
Expand Down Expand Up @@ -249,7 +253,7 @@ Get a single framework by ID.

### `POST /api/chat/sessions`

Create a new chat session for a project. The system prompt is assembled at creation time from the project's current state (frameworks, questionnaire answers, uploaded document summaries, reporting evidence).
Create a new chat session for a project. The system prompt is assembled at creation time from the project's current state (frameworks, questionnaire answers, uploaded document summaries, reporting evidence, codebase analysis).

**Body:**
```json
Expand Down Expand Up @@ -289,6 +293,117 @@ data: of the response.
data: [DONE]
```

### `GET /api/chat/context`

Fetch the assembled context for a project, optionally filtered by section. Used by the debug context viewer.

**Query parameters:**
- `project_id` (required) — project UUID
- `section` (optional, default `full`) — one of `full`, `overview`, `frameworks`, `documents`, `reporting`, `github`

**Response:**
```json
{
"context": "## Current Project Context\n..."
}
```

Returns `{"context": null}` if the requested section has no content.

---

## Integrations

### `GET /api/projects/{project_id}/integrations`

Get the integration configuration for a project. Returns 404 if no integration is configured.

**Response:**
```json
{
"id": "uuid",
"project_id": "uuid",
"provider": "github",
"repo_owner": "org",
"repo_name": "repo",
"github_project_number": 1,
"summary": "LLM-generated summary or null",
"architecture_mermaid": "graph TD\n...",
"sync_status": "idle",
"last_synced_at": "2026-05-27T10:00:00"
}
```

### `POST /api/projects/{project_id}/integrations`

Create a new integration for a project.

**Body:**
```json
{
"provider": "github",
"github_pat": "ghp_...",
"repo_owner": "org",
"repo_name": "repo",
"github_project_number": 1
}
```

### `PATCH /api/projects/{project_id}/integrations`

Update integration configuration. All fields are optional.

### `DELETE /api/projects/{project_id}/integrations`

Remove the integration and all associated data (tasks, repo files). Returns 204.

### `POST /api/projects/{project_id}/integrations/sync`

Trigger a repository sync. Fetches the repo tree, file contents, issues, and project items from GitHub, then generates an LLM summary and architecture diagram. The sync runs asynchronously; poll the sync status endpoint to check progress.

**Response:**
```json
{
"status": "syncing"
}
```

### `GET /api/projects/{project_id}/integrations/sync-status`

Check the current sync status.

**Response:**
```json
{
"sync_status": "idle"
}
```

Possible values: `idle`, `syncing`, `error`.

### `GET /api/projects/{project_id}/integrations/tasks`

List GitHub tasks (issues and project items) for the integration. Supports optional query filters: `status`, `assignee`, `label`, `milestone`.

### `GET /api/projects/{project_id}/integrations/tasks/{task_id}`

Get a single GitHub task by ID.

### `GET /api/projects/{project_id}/integrations/context-file`

Get the integration's context file content (user-editable supplementary context).

### `PUT /api/projects/{project_id}/integrations/context-file`

Update the integration's context file content.

**Body:**
```json
{
"content": "Additional context about the codebase..."
}
```

---

## Admin
Expand Down
Loading
Loading