Skip to main content

Oliver Backend

The backend service owns the Go API, local hook listener compatibility adapter, Postgres schema, config, and tests for Oliver. Repo-root folders own batch pipelines, docs, scripts, frontend, extensions, and deployment assets.

Stack: Go · PostgreSQL. The current implementation keeps deterministic path-rule classification and digest summaries local; model/S3 knobs are reserved for native Go integrations.

Layout

backend/
├── go.mod
├── go.sum
├── cmd/
│ ├── api/ # HTTP API
│ ├── db-setup/ # schema/roles applier
│ ├── issue-token/ # non-interactive token bootstrap
│ └── agent-hook-listener/ # localhost Claude/Codex hook receiver
├── internal/
│ ├── contextlayer/
│ │ ├── auth/ # Supabase/JWT verification
│ │ ├── domain/ # DTOs, settings, pure business helpers
│ │ ├── http/ # handlers, middleware, JSON helpers, CORS
│ │ ├── rules/ # path-rule parsing/matching
│ │ ├── store/ # Postgres store/query code
│ │ └── summary/ # topic digest generation
│ └── ingestion/ # local hook normalization + backend event client
├── config/
│ └── context.toml
├── database/
│ ├── schema.sql # psql entrypoint that includes schema/*.sql
│ ├── schema/ # ordered schema fragments applied by cmd/db-setup
│ └── roles.sql
├── .dockerignore
└── .env.example

infra/
├── aws/
├── docker/
│ └── backend/Dockerfile
└── local/docker-compose.yml

docs/
├── app/ # Docusaurus site app
├── internal/
│ ├── backend.md
│ ├── context-layer-spec.md
│ ├── deployment.md
│ ├── environment.md
│ └── ingestion.md
└── public/
├── README.md
└── local-agent-hooks.md

frontend/
└── portal/

pipelines/
├── jobs/
└── .env.example

scripts/
├── run-ingestion-job.sh
└── start-local-stack.sh

extensions/
├── agent-hooks/ # npm Claude/Codex hook collector
└── chrome-extension/ # click-to-save Chrome extension

Quickstart

Run these from the repository root:

scripts/start-local-stack.sh

This starts local Postgres, applies the schema, starts the Go API, starts the React frontend, and starts the Docusaurus docs site. The script uses API_PORT=8081, FRONTEND_PORT=5173, and DOCS_PORT=3000 by default. Set API_PORT=8080 if that port is free.

API Smoke

API=http://127.0.0.1:8081

curl "$API/health"

cd backend
go run ./cmd/issue-token \
--kind human \
--display-name "Local Developer" \
--workspace oliver \
--workspace-name "Oliver"
cd ..

TOKEN=usr_...

curl -H "Authorization: Bearer $TOKEN" "$API/workspaces"

curl -X POST "$API/events" \
-H "Authorization: Bearer $TOKEN" \
-H "X-Workspace: oliver" \
-H 'Content-Type: application/json' \
-d '{
"session_id":"s1",
"kind":"agent_task",
"intent":"Add connection pooling to the storage layer",
"output":"Implemented pgx in store.go",
"targets":[{"type":"path","value":"internal/contextlayer/store/store.go"}],
"idempotency_key":"s1:0:1200"
}'

curl -H "Authorization: Bearer $TOKEN" \
-H "X-Workspace: oliver" \
"$API/topics/component:storage"

curl -X POST "$API/ask" \
-H "Authorization: Bearer $TOKEN" \
-H "X-Workspace: oliver" \
-H 'Content-Type: application/json' \
-d '{"query":"What did we change in storage?"}'

Browser users sign up through Supabase in the portal; local bearer-token bootstrap is for non-browser/dev clients. Scoped API requests require Authorization: Bearer <token> and X-Workspace: <workspace-slug>. Slugs are globally unique; owner/workspace is also accepted and validates the owner namespace. actor is the authenticated user; any client-provided actor field is ignored.

Ingestion

Batch pipelines live in repo-root pipelines/ and build normalized events for the running backend API. The agent hook npm collector in extensions/agent-hooks stores local Claude/Codex hook payloads locally. The Go hook listener is a direct-HTTP compatibility adapter that posts normalized events to POST /events with a bearer token and workspace header. Ingestion docs live in ingestion.md; user-facing setup guides live in the public docs, including Claude/Codex hook setup.

cp pipelines/.env.example pipelines/.env
python3 pipelines/run_all.py --dry-run

Environment

Repo-wide env file ownership is documented in environment.md.

VarRequiredDefaultNotes
DATABASE_URLyesnonepostgresql://user:pass@host:5432/db
PORTno8080API listen port
OLIVER_APIpush clientsnoneBackend API URL for ingestion clients.
OLIVER_TOKENpush clientsnoneBearer token for ingestion clients; mint with cmd/issue-token.
OLIVER_WORKSPACEpush clientsnoneGlobally unique workspace slug for ingestion clients.
CONTEXT_TOML_PATHnoconfig/context.tomlpath rules
SUMMARY_MAX_EVENTSno50cap on events fed to a summary
SUMMARY_OUTPUT_HYDRATE_BYTESno8192per-event output text included in LLM search context
CLASSIFIER_VERSIONnov1deterministic classifier version

POST /events accepts JSON request bodies up to 2 MiB, including inline event output up to 1 MiB. Larger agent outputs should use blob storage once output_ref offload is implemented.

Reserved model/blob variables such as ANTHROPIC_API_KEY, CLASSIFIER_MODEL, SUMMARY_MODEL, LLM_MAX_TOKENS, S3_BUCKET, and AWS_REGION stay out of the local backend template until the Go backend actively uses those integrations. Deployment can still pass them later through the ECS task environment or APP_SECRET_JSON.

Tests

scripts/start-local-stack.sh test

Backend tests create and drop context_layer_test using the oliver role from infra/local/docker-compose.yml. Override the admin-capable Postgres base DSN with:

TEST_PG_BASE=postgresql://USER:PASSWORD@HOST:PORT go test ./...

Deploy

Build the API image from the backend module root:

docker build -f infra/docker/backend/Dockerfile backend

Apply the ordered database/schema/*.sql fragments and database/roles.sql once to the target Postgres database, set DATABASE_URL, and run the resulting container on port 8080. For manual psql setup, database/schema.sql includes the fragments in the same order.