Metadata-Version: 2.5
Name: artefae
Version: 0.1.6
Summary: Artefae - Context-grounded artifacts for professional engagement work
Author: FDE Copilot Team
License: Proprietary
Requires-Python: >=3.11
Requires-Dist: click>=8.1
Requires-Dist: httpx>=0.27
Requires-Dist: pypdf>=4.0
Requires-Dist: python-docx>=1.1
Requires-Dist: truststore>=0.9
Provides-Extra: dev
Requires-Dist: alembic>=1.13; extra == 'dev'
Requires-Dist: anthropic>=0.40; extra == 'dev'
Requires-Dist: bcrypt>=4.1; extra == 'dev'
Requires-Dist: boto3>=1.43.86; extra == 'dev'
Requires-Dist: cryptography>=42.0; extra == 'dev'
Requires-Dist: fastapi>=0.110; extra == 'dev'
Requires-Dist: moto[s3]>=5.2.3; extra == 'dev'
Requires-Dist: mypy>=1.9; extra == 'dev'
Requires-Dist: neo4j>=5.0; extra == 'dev'
Requires-Dist: psycopg[binary]>=3.1; extra == 'dev'
Requires-Dist: pydantic-settings>=2.2; extra == 'dev'
Requires-Dist: pydantic>=2.6; extra == 'dev'
Requires-Dist: pydantic[email]>=2.6; extra == 'dev'
Requires-Dist: pyjwt>=2.8; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
Requires-Dist: pytest>=8.0; extra == 'dev'
Requires-Dist: python-dotenv>=1.0; extra == 'dev'
Requires-Dist: python-multipart>=0.0.9; extra == 'dev'
Requires-Dist: ruff>=0.4; extra == 'dev'
Requires-Dist: sentry-sdk[fastapi]>=2.0; extra == 'dev'
Requires-Dist: sqlalchemy>=2.0; extra == 'dev'
Requires-Dist: uvicorn[standard]>=0.29; extra == 'dev'
Provides-Extra: server
Requires-Dist: alembic>=1.13; extra == 'server'
Requires-Dist: anthropic>=0.40; extra == 'server'
Requires-Dist: bcrypt>=4.1; extra == 'server'
Requires-Dist: boto3>=1.43.86; extra == 'server'
Requires-Dist: cryptography>=42.0; extra == 'server'
Requires-Dist: fastapi>=0.110; extra == 'server'
Requires-Dist: neo4j>=5.0; extra == 'server'
Requires-Dist: psycopg[binary]>=3.1; extra == 'server'
Requires-Dist: pydantic-settings>=2.2; extra == 'server'
Requires-Dist: pydantic>=2.6; extra == 'server'
Requires-Dist: pydantic[email]>=2.6; extra == 'server'
Requires-Dist: pyjwt>=2.8; extra == 'server'
Requires-Dist: python-dotenv>=1.0; extra == 'server'
Requires-Dist: python-multipart>=0.0.9; extra == 'server'
Requires-Dist: sentry-sdk[fastapi]>=2.0; extra == 'server'
Requires-Dist: sqlalchemy>=2.0; extra == 'server'
Requires-Dist: uvicorn[standard]>=0.29; extra == 'server'
Description-Content-Type: text/markdown

# FDE Copilot

Backend API and CLI for the **Forward Deployed Engineering (FDE) Copilot** — a tool that
captures engagement source material, extracts structured entities, and generates delivery
artifacts (SDDs, ADRs, diagrams) backed by a knowledge graph. Supports optional approval
workflows and compliance-grade audit logging for enterprise deployments.

This repository contains the Sprint 1.1 foundation plus Sprint 3.4 governance features
(decision approval workflows, audit user-agent tracking). The FastAPI backend, PostgreSQL schema
(via Alembic), Click-based CLI, and Docker Compose stack support local development.

> **Scope note:** Sprint 1.1 establishes infrastructure. Sprint 3.4 adds decision approval
> workflows and compliance audit logging. Authentication, billing, and AI extraction are
> stubbed or deferred to later sprints. See [COMPLIANCE.md](docs/COMPLIANCE.md) for
> governance and audit-trail architecture.

---

## Tech Stack

| Layer          | Technology                                  |
|----------------|---------------------------------------------|
| **Backend** | |
| Language       | Python 3.11+ (managed with [uv](https://docs.astral.sh/uv/)) |
| Web framework  | FastAPI + Uvicorn (ASGI)                    |
| ORM            | SQLAlchemy 2.x (async)                       |
| Migrations     | Alembic                                     |
| Database       | PostgreSQL 15                               |
| Graph database | Neo4j 5                                      |
| CLI            | Click                                       |
| Config         | Pydantic Settings                           |
| **Frontend** | |
| Language       | TypeScript (compiled to JavaScript)         |
| Runtime        | Bun                                         |
| Web framework  | React 18.x                                   |
| Package manager| Bun (replaces npm/yarn)                     |
| Testing        | Bun test runner + React Testing Library + jest-dom + happy-dom |
| CSS            | Tailwind CSS                                 |

---

## Prerequisites

- [uv](https://docs.astral.sh/uv/) — macOS/Linux: `curl -LsSf https://astral.sh/uv/install.sh | sh`;
  Windows (PowerShell): `powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"`
- Docker with the Compose plugin (`docker compose version`)

> Installing the **published CLI** (not this local dev stack)? See
> [`docs/CLI_REFERENCE.md` → Installation](docs/CLI_REFERENCE.md#installation) for
> the per-OS `uv tool install artefae` steps (macOS + Windows).

---

## Local Development

### 1. Install dependencies

```bash
uv sync --extra dev
```

### 2. Configure environment

```bash
cp .env.example .env
# edit .env and fill in secrets (ANTHROPIC_API_KEY, JWT_SECRET, etc.)
```

### 3. Start the stack

```bash
docker compose up
```

This launches three services:

| Service    | Port(s)        | Description                    |
|------------|----------------|--------------------------------|
| `api`      | 8000           | FastAPI application            |
| `postgres` | 5432           | PostgreSQL 15 (persisted)      |
| `neo4j`    | 7474, 7687     | Neo4j 5 (browser + Bolt)       |

### 4. Verify the API

```bash
curl http://localhost:8000/health
# {"status": "ok", "environment": "development", ...}
```

Interactive API docs are available at http://localhost:8000/docs.

### 5. Run database migrations

Migrations run automatically against the `postgres` service. To run them manually:

```bash
docker compose exec api alembic upgrade head
# verify tables
docker compose exec postgres psql -U fdecopilot -d fdecopilot -c "\dt"
```

---

## Running without Docker

```bash
# start only the databases
docker compose up postgres neo4j

# run migrations and the API against localhost
DATABASE_URL="postgresql+psycopg://fdecopilot:fdecopilot@localhost:5432/fdecopilot" \
  uv run alembic upgrade head

uv run uvicorn backend.main:app --reload
```

---

## CLI

The `artefae` CLI is installed as a console script by `uv sync`.

```bash
uv run artefae --help
```

The CLI is a **thin, authenticated remote client** of the hosted API — it holds
no database or Neo4j credentials and talks to the deployment over HTTPS. (A few
`--local` / operator commands still drive a local stack directly; see
[Self-hosted / operator commands](#self-hosted--operator-commands).)

| Command        | Description                                   |
|----------------|-----------------------------------------------|
| `artefae auth`       | Authenticate with the remote API using a personal access token |
| `artefae status`     | Show identity, reachable workspaces, and local config |
| `artefae engagement` | List / create / select engagements (`list`, `create`, `use`) |
| `artefae init`       | Tie the current directory to an engagement (creates `.artefae/engagement_id`) |
| `artefae capture`    | Upload source documents to the API (auto-extracts entities server-side) |
| `artefae generate`   | Generate artifacts (SDD, ADR, integration spec, RSD) |
| `artefae export`     | Download an artifact (markdown, PDF, DOCX, HTML) |
| `artefae extract`    | *(operator)* Local one-off entity extraction from a file via Claude |
| `artefae seed`       | *(operator)* Seed the Neo4j graph with the demo engagement |

CLI configuration is stored at `~/.artefae/config.json` (personal access token,
API base URL, default engagement) and supports per-directory
`.artefae/engagement_id` files for easy multi-engagement workflows. Point at a
self-hosted or staging deployment with `--api-url <url>` on any command or the
`ARTEFAE_API_URL` environment variable.

### Workflow: Auth → Capture → Generate → Export

**Step 1: Authenticate**

Create a personal access token in the web app under **Settings → API tokens**
(the raw value is shown once — copy it then), and register it with the CLI:

```bash
uv run artefae auth --api-token art_xxxxxxxxxxxxxxxx
# ✓ Authenticated. Reachable workspaces:
#   - Acme (Admin)
uv run artefae status   # confirm identity + live workspace at any time
```

**Step 2: Pick an engagement**

Create one from the CLI (or use the web UI and copy its id):

```bash
uv run artefae engagement create --name "Acme Migration" \
    --client "Acme" --type fde --use     # --use sets it as the config default
uv run artefae engagement list           # engagements in your workspace
uv run artefae engagement purge <id>     # permanently delete one (Admin; asks to confirm)
```

Then tie a working directory to it:

```bash
mkdir my-engagement && cd my-engagement
uv run artefae init --engagement 340e9e1b-57d5-49af-a82a-0abdc5456585
```

**Step 3: Capture source documents**

Captures are uploaded to the API, which auto-extracts entities and populates the
graph. Extraction covers the four core families (decisions, systems, requirements,
constraints) plus the nine Phase 8 families — costs, risks, timelines,
integrations, personnel, security issues, assumptions, business context, and open
questions — so most artifact sections fill deterministically from captured content:

```bash
uv run artefae capture --file architecture.md
# Captured 1 record(s), 350 words total.
# stored: 1 in database, 0 in S3
```

Capture from multiple sources (works from anywhere in the engagement directory):

```bash
cd my-engagement/docs
uv run artefae capture --folder ./specs/
uv run artefae capture --git   # capture recent commits
```

**Step 4: Generate & export artifacts**

```bash
uv run artefae generate                              # SDD (gap-gated), default
uv run artefae generate --artifact adrs              # ADR set
uv run artefae generate --artifact integration       # Integration specs
uv run artefae generate --artifact rsd               # Requirements & Scope Document
uv run artefae generate --artifact sdd -o output.md  # Save to file

uv run artefae export --format pdf -o SDD.pdf        # download latest artifact (md/pdf/docx/html)
```

### Self-hosted / operator commands

These bypass the API and drive a local database / Neo4j directly, so they need
local DB and Neo4j credentials. They are meant for self-hosted operators, not
hosted end users:

```bash
uv run artefae capture --local     # capture straight into the local DB
uv run artefae generate --local    # generate from the local Neo4j graph
uv run artefae seed                # seed the demo graph fixture
uv run artefae extract <file>      # local extraction (needs ANTHROPIC_API_KEY)
```

---

## Neo4j Setup & Usage

Sprint 1.2 adds a Neo4j-backed knowledge graph that models the entities and
relationships of an engagement (systems, stakeholders, requirements, decisions,
and their provenance).

### 1. Start Neo4j

Neo4j ships with the Docker Compose stack:

```bash
docker compose up neo4j        # or `docker compose up` for the full stack
```

| Endpoint       | URL                     | Notes                          |
|----------------|-------------------------|--------------------------------|
| Browser        | http://localhost:7474   | Interactive Cypher UI          |
| Bolt (driver)  | bolt://localhost:7687   | Used by the app (`NEO4J_URI`)  |

Default dev credentials are `neo4j` / `password` (see `.env.example`).

### 2. Configuration

Graph connection settings are read from the environment (see `.env.example`):

```bash
NEO4J_URI=bolt://neo4j:7687
NEO4J_USER=neo4j
NEO4J_PASSWORD=password
NEO4J_ENCRYPTION=false   # set true to enable TLS (production)
```

### 3. Seed demo data

Populate a demo engagement (systems, requirements, constraints, stakeholders,
and a decision plus their relationships):

```bash
uv run fde seed
# Seeded engagement demo-engagement:
#   nodes:         14
#   relationships: 9
```

### 4. Explore the graph

Open the [Neo4j browser](http://localhost:7474) and run Cypher, e.g.:

```cypher
// Everything in the demo engagement
MATCH (n {engagement_id: 'demo-engagement'}) RETURN n;

// A decision and the requirements it affects
MATCH (d:Decision)-[:AFFECTS]->(r:Requirement) RETURN d, r;
```

### Graph schema

**Node labels:** `System`, `Stakeholder`, `Requirement`, `Constraint`,
`Decision`, `OpenQuestion`, `Artifact`, `CaptureRecord`, plus the Phase 8
families `Cost`, `Risk`, `Timeline`, `Integration`, `Personnel`,
`SecurityIssue`, `Assumption`, `BusinessContext`.

**Relationship types:** `DEPENDS_ON`, `AFFECTS`, `INTEGRATES_WITH`, `RESOLVES`,
`SUPERSEDES`, `SOURCED_FROM`, `REPORTS_TO`, `APPROVES`.

The graph layer lives in `backend/graph/`:

| Module              | Responsibility                                        |
|---------------------|-------------------------------------------------------|
| `__init__.py`       | Shared driver lifecycle (`get_driver`/`close_driver`) |
| `graph_service.py`  | CRUD, queries, snapshot, provenance, audit trail      |
| `fixtures.py`       | Demo engagement seeding                               |
| `seed.py`           | Seed orchestration (backs `fde seed`)                 |

---

## API Endpoints

The FastAPI application serves a Swagger UI at `/docs`. Key artifact generation endpoints:

| Method | Path | Purpose |
|--------|------|---------|
| `POST` | `/api/artifacts/generate-sdd` | Generate a Solution Design Document |
| `POST` | `/api/artifacts/generate-adrs` | Generate Architecture Decision Records |

---

## Project Layout

```
.
├── backend/                 # FastAPI application
│   ├── main.py              # App entry point, health endpoint, middleware
│   ├── config.py            # Pydantic Settings (env-driven config)
│   ├── models.py            # SQLAlchemy ORM models (9 tables)
│   ├── api/                 # API endpoints (auth, captures, engagements, artifacts)
│   ├── extraction/          # Claude extraction + graph population
│   ├── capture/             # Source capture (file, folder, git) + extraction flow
│   └── graph/               # Neo4j knowledge graph layer
│       ├── __init__.py      # Driver lifecycle
│       ├── graph_service.py # CRUD, queries, provenance, audit
│       ├── fixtures.py      # Demo engagement seeding
│       └── seed.py          # Seed orchestration (artefae seed)
├── artefae/                 # CLI package
│   └── cli/main.py          # Click command group (init, capture, generate, seed, etc.)
├── frontend/                # React web app (Nextjs + Tailwind)
│   ├── app/                 # Pages (dashboard, engagement detail)
│   ├── components/          # React components (Button, Modal, Form, CaptureUpload, etc.)
│   └── lib/                 # Utilities (API client, auth, color contrast)
├── alembic/                 # Database migrations
│   ├── env.py
│   ├── script.py.mako
│   └── versions/
│       └── 001_initial_schema.py
├── tests/                   # Test suite (pytest + React Testing Library)
├── docker-compose.yml       # Local dev stack (api + postgres + neo4j)
├── pyproject.toml           # Python dependencies and tool config
├── bunfig.toml              # Bun configuration (frontend)
├── biome.json               # Biome linter/formatter config
└── .env.example             # Environment template
```

---

## Development Commands

```bash
# Backend
uv run mypy backend fde                 # type-check
uv run ruff check backend fde tests     # lint
uv run pytest                           # tests

# Frontend
cd frontend
bun run type-check                      # TypeScript check
bun run lint                            # ESLint
bun test                                # tests
bun run build                           # build
```
