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.
| Var | Required | Default | Notes |
|---|---|---|---|
DATABASE_URL | yes | none | postgresql://user:pass@host:5432/db |
PORT | no | 8080 | API listen port |
OLIVER_API | push clients | none | Backend API URL for ingestion clients. |
OLIVER_TOKEN | push clients | none | Bearer token for ingestion clients; mint with cmd/issue-token. |
OLIVER_WORKSPACE | push clients | none | Globally unique workspace slug for ingestion clients. |
CONTEXT_TOML_PATH | no | config/context.toml | path rules |
SUMMARY_MAX_EVENTS | no | 50 | cap on events fed to a summary |
SUMMARY_OUTPUT_HYDRATE_BYTES | no | 8192 | per-event output text included in LLM search context |
CLASSIFIER_VERSION | no | v1 | deterministic 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.