{"id":49630078,"url":"https://github.com/felixgeelhaar/nous","last_synced_at":"2026-05-05T10:06:09.136Z","repository":{"id":354893254,"uuid":"1225816909","full_name":"felixgeelhaar/nous","owner":"felixgeelhaar","description":"Nous: AI coordination engine that extracts commitments from natural language, evaluates risk of being missed, and intervenes when necessary","archived":false,"fork":false,"pushed_at":"2026-04-30T19:32:09.000Z","size":169,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-30T20:10:15.455Z","etag":null,"topics":["ai","commitment-tracking","coordination-engine","go","grpc","llm","microservice","nous","risk-evaluation"],"latest_commit_sha":null,"homepage":"https://github.com/felixgeelhaar/nous#readme","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/felixgeelhaar.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":"ROADMAP.md","authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-04-30T17:10:10.000Z","updated_at":"2026-04-30T19:32:14.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/felixgeelhaar/nous","commit_stats":null,"previous_names":["felixgeelhaar/nous"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/felixgeelhaar/nous","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/felixgeelhaar%2Fnous","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/felixgeelhaar%2Fnous/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/felixgeelhaar%2Fnous/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/felixgeelhaar%2Fnous/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/felixgeelhaar","download_url":"https://codeload.github.com/felixgeelhaar/nous/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/felixgeelhaar%2Fnous/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32644233,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-04T10:08:07.713Z","status":"online","status_checked_at":"2026-05-05T02:00:06.033Z","response_time":54,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ai","commitment-tracking","coordination-engine","go","grpc","llm","microservice","nous","risk-evaluation"],"created_at":"2026-05-05T10:06:04.991Z","updated_at":"2026-05-05T10:06:09.127Z","avatar_url":"https://github.com/felixgeelhaar.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Nous\n\nNous is an AI coordination engine that extracts commitments from natural language, evaluates their risk of being missed, and intervenes when necessary. It acts as the \"nervous system\" between AI agents and human intent — tracking what was promised, scoring the likelihood of delivery, and surfacing nudges or escalations before deadlines slip.\n\n## Features\n\n- **Commitment Extraction** — Parses text (conversations, emails, notes) into structured commitments with confidence scores.\n- **Risk Evaluation** — Continuously scores active commitments using time-to-deadline, confidence, and external signals.\n- **Intervention Engine** — Automatically creates nudges, suggestions, escalations, or automation requests when risk crosses thresholds.\n- **Multi-Backend Storage** — Supports in-memory, SQLite, and PostgreSQL backends with identical behavior.\n- **gRPC + HTTP APIs** — Primary gRPC API with a lightweight REST gateway for easy integration.\n- **Observability** — Structured JSON logging with correlation IDs, OpenTelemetry tracing, and Prometheus-style metrics.\n\n## Quick Start\n\n### Prerequisites\n\n- Go 1.26+\n- (Optional) PostgreSQL 15+ for production deployments\n\n### Run Locally\n\n```bash\n# SQLite backend (default)\ngo run ./cmd/nous\n\n# With explicit config\nNOUS_DB_TYPE=sqlite NOUS_DB_DSN=nous.db NOUS_GRPC_ADDR=:50051 NOUS_HTTP_ADDR=:8080 go run ./cmd/nous\n\n# PostgreSQL backend\nNOUS_DB_TYPE=postgres NOUS_DB_DSN=postgres://user:pass@localhost/nous?sslmode=disable go run ./cmd/nous\n```\n\n### Docker\n\n```bash\ndocker build -t nous:latest .\ndocker run -p 50051:50051 -p 8080:8080 \\\n  -e NOUS_DB_TYPE=sqlite \\\n  -e NOUS_DB_DSN=/data/nous.db \\\n  -e NOUS_HTTP_ADDR=:8080 \\\n  -v nous-data:/data \\\n  nous:latest\n```\n\nOr use Docker Compose:\n\n```bash\ndocker-compose up\n```\n\n## Configuration\n\nAll configuration is via environment variables:\n\n| Variable | Default | Description |\n|----------|---------|-------------|\n| `NOUS_GRPC_ADDR` | `:50051` | gRPC listen address |\n| `NOUS_HTTP_ADDR` | *(empty)* | HTTP listen address (disabled if empty) |\n| `NOUS_DB_TYPE` | `sqlite` | Database backend: `memory`, `sqlite`, `postgres` |\n| `NOUS_DB_DSN` | `nous.db` | Connection string or file path |\n| `NOUS_TICK_INTERVAL` | `5m` | Evaluation worker tick interval |\n| `NOUS_EXTRACT_MIN_CONFIDENCE` | `0.0` | Minimum confidence to keep extracted commitments |\n| `NOUS_RISK_OVERDUE_WEIGHT` | `0.6` | Risk weight for overdue commitments |\n| `NOUS_RISK_DUE_SOON_WEIGHT` | `0.3` | Risk weight for near-deadline commitments |\n| `NOUS_RISK_DUE_SOON_WINDOW` | `2h` | Window considered \"due soon\" |\n| `NOUS_RISK_CONFIDENCE_WEIGHT` | `0.2` | Risk weight for low confidence |\n| `NOUS_NUDGE_THRESHOLD` | `0.5` | Risk score to trigger a nudge |\n| `NOUS_ESCALATE_THRESHOLD` | `0.85` | Risk score to trigger an escalation |\n| `NOUS_AUTOMATION_CONFIDENCE` | `0.95` | Minimum confidence for automation suggestions |\n| `NOUS_AUTH_TOKEN` | *(empty)* | Static bearer token enforced on HTTP + gRPC. Empty disables inbound auth. |\n| `NOUS_LLM_PROVIDER` | *(empty)* | LLM provider: `anthropic`, `openai`, `gemini`, `bedrock`, or empty (use `ScriptedExtractor`). |\n| `NOUS_LLM_API_KEY` | *(empty)* | API key — required for `anthropic`, `openai`, `gemini`. Bedrock uses the AWS credential chain. |\n| `NOUS_LLM_MODEL` | provider default | Model override (Anthropic `claude-opus-4-7`, OpenAI `gpt-4o-mini`, Gemini `gemini-2.5-flash`, Bedrock `anthropic.claude-opus-4-7-20260201-v1:0`). |\n| `NOUS_LLM_BASE_URL` | provider default | Endpoint override (OpenAI-compatible servers, custom Bedrock region for `bedrock`). |\n| `NOUS_JWT_SECRET` | *(empty)* | Hex-encoded JWT signing key (≥ 32 bytes). When set, JWT auth is enforced alongside any static `NOUS_AUTH_TOKEN`. |\n| `NOUS_JWT_KID` | *(empty)* | Key ID for the active signing key (informational; helps rotation). |\n| `NOUS_JWT_PREV_SECRET` | *(empty)* | Previous-generation signing key during rotation. Tokens issued under it continue to validate until they expire. |\n| `NOUS_JWT_PREV_KID` | *(empty)* | Key ID for the previous key. |\n| `NOUS_JWT_TTL` | `1h` | Default token TTL. |\n| `NOUS_JWT_ROTATE_PERIOD` | *(empty)* | Enable automated rotation. The active signing key regenerates every `period`; the prior key moves to previous for `overlap`. |\n| `NOUS_JWT_ROTATE_OVERLAP` | `NOUS_JWT_TTL` | Window during which the previous key keeps validating after rotation. Should be ≥ longest issued token TTL. |\n| `NOUS_VALIDATION_RULES` | *(empty)* | Comma-separated CEL rules `name=expr`. Each rule must return bool. Variables: `owner_id`, `text`, `text_len`, `source_kinds`. |\n\n## API\n\n### gRPC\n\nThe gRPC service is defined in `api/nous/v1/nous.proto`. Methods include:\n\n- `Extract` — Extract commitments from text\n- `Evaluate` — Run risk evaluation on active commitments\n- `ListCommitments` / `GetCommitment` — Query commitments\n- `ListDecisions` / `GetDecision` — Audit-replay decisions by subject\n- `ListInterventions` / `GetIntervention` — Query interventions\n- `ResolveIntervention` — Accept, reject, or execute an intervention\n\n### HTTP REST\n\nWhen `NOUS_HTTP_ADDR` is set, the following REST endpoints are available:\n\n| Method | Path | Description |\n|--------|------|-------------|\n| POST | `/v1/extract` | Extract commitments from text |\n| POST | `/v1/evaluate` | Trigger evaluation loop |\n| GET | `/v1/commitments` | List commitments |\n| GET | `/v1/commitments/{id}` | Get a commitment |\n| GET | `/v1/decisions?subject=X\u0026limit=N` | List decisions for a subject (audit replay) |\n| GET | `/v1/decisions/{id}` | Get a decision |\n| GET | `/v1/interventions` | List interventions |\n| POST | `/v1/interventions/{id}/resolve` | Resolve an intervention |\n| GET | `/v1/health` | Health/readiness check including downstream adapters |\n| GET | `/metrics` | Prometheus-style metrics snapshot |\n\n## Architecture\n\n```\ncmd/nous              # Application entrypoint\napi/nous/v1           # Protobuf service definitions\ninternal/\n  domain/             # Pure domain types (commitment, intervention, decision)\n  ports/              # Repository and client interfaces\n  store/              # Persistence dispatch + memory/sqlite/postgres backends\n  pipeline/           # Extract and Evaluate workflows\n  risk/               # Risk scoring engine\n  intervention/       # Intervention policy engine\n  coordination/       # Direct and Axi (axi-go) kernels\n  llm/                # LLM extractors (ScriptedExtractor for tests/offline; LLMExtractor + Anthropic/OpenAI providers in progress)\n  circuit/            # Circuit breaker primitives for adapter calls\n  transport/\n    grpc/             # gRPC server implementation\n    http/             # REST gateway\n  worker/             # Background evaluation scheduler\n  observability/      # Logging, tracing, metrics, middleware\n  config/             # Environment-based configuration\n```\n\n## Testing\n\n```bash\n# Run all tests\ngo test ./...\n\n# Run with PostgreSQL (requires running Postgres)\nNOUS_TEST_POSTGRES_DSN=postgres://user:pass@localhost/nous_test?sslmode=disable go test ./internal/store/...\n\n# Run end-to-end smoke test\ngo test ./e2e/... -v\n```\n\n## Production Readiness\n\n- **12-Factor App** — Config via environment, stateless processes, port binding, disposability\n- **Graceful Shutdown** — SIGTERM drains in-flight gRPC/HTTP requests and stops the worker\n- **Health Checks** — `/v1/health` aggregates DB connectivity plus Mnemos/Chronos adapter status\n- **Circuit Breakers** — Mnemos and Chronos adapters wrap calls in `internal/circuit` to fail fast on downstream outage\n- **Structured Logging** — JSON logs to stdout with correlation IDs\n- **Tracing** — OpenTelemetry spans for Extract and Evaluate pipelines\n- **Metrics** — Atomic counters for commitments extracted, evaluations run, interventions created, risk distribution\n- **Alerting** — Prometheus alerting rules in `deploy/prometheus/alerting_rules.yml`; Grafana dashboards in `deploy/grafana/dashboards/`\n- **Security** — Distroless non-root container, no secrets in code; nox baseline tracked in `findings.json`; HTTP + gRPC inbound bearer-token auth via `NOUS_AUTH_TOKEN`\n- **Coverage** — Coverage tracking via `.coverctl.yaml`\n\n## More\n\n- [`api/openapi.yaml`](api/openapi.yaml) — full HTTP REST schema.\n- [`api/nous/v1/nous.proto`](api/nous/v1/nous.proto) — gRPC schema.\n- [`SECURITY.md`](SECURITY.md) — threat model and `findings.json` baseline policy.\n- [`docs/SLOs.md`](docs/SLOs.md) — formal availability, latency, and error-rate targets.\n- [`docs/DEPLOYMENT.md`](docs/DEPLOYMENT.md) — operator runbook for k8s, Prometheus, and Grafana.\n- [`docs/adr/`](docs/adr/) — architecture decisions (006 covers the LLM extractor transition).\n- [`CHANGELOG.md`](CHANGELOG.md) — release history.\n- [`ROADMAP.md`](ROADMAP.md) — pending work prioritised.\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffelixgeelhaar%2Fnous","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffelixgeelhaar%2Fnous","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffelixgeelhaar%2Fnous/lists"}