enclave-ontos 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- enclave_ontos-0.1.0/.env.example +118 -0
- enclave_ontos-0.1.0/.github/ISSUE_TEMPLATE/bug_report.yml +88 -0
- enclave_ontos-0.1.0/.github/ISSUE_TEMPLATE/config.yml +11 -0
- enclave_ontos-0.1.0/.github/ISSUE_TEMPLATE/feature_request.yml +74 -0
- enclave_ontos-0.1.0/.github/PULL_REQUEST_TEMPLATE.md +60 -0
- enclave_ontos-0.1.0/.github/workflows/ci.yml +67 -0
- enclave_ontos-0.1.0/.github/workflows/release.yml +173 -0
- enclave_ontos-0.1.0/.gitignore +24 -0
- enclave_ontos-0.1.0/.python-version +1 -0
- enclave_ontos-0.1.0/CHANGELOG.md +79 -0
- enclave_ontos-0.1.0/CLAUDE.md +53 -0
- enclave_ontos-0.1.0/CODE_OF_CONDUCT.md +13 -0
- enclave_ontos-0.1.0/CONTRIBUTING.md +113 -0
- enclave_ontos-0.1.0/PKG-INFO +133 -0
- enclave_ontos-0.1.0/README.md +89 -0
- enclave_ontos-0.1.0/RELEASING.md +99 -0
- enclave_ontos-0.1.0/SECURITY.md +55 -0
- enclave_ontos-0.1.0/deploy/Dockerfile +28 -0
- enclave_ontos-0.1.0/deploy/docker-compose.yml +15 -0
- enclave_ontos-0.1.0/deploy/helm/README.md +50 -0
- enclave_ontos-0.1.0/deploy/helm/ontos/Chart.yaml +22 -0
- enclave_ontos-0.1.0/deploy/helm/ontos/templates/_helpers.tpl +33 -0
- enclave_ontos-0.1.0/deploy/helm/ontos/templates/configmap.yaml +20 -0
- enclave_ontos-0.1.0/deploy/helm/ontos/templates/deployment.yaml +108 -0
- enclave_ontos-0.1.0/deploy/helm/ontos/templates/networkpolicy.yaml +45 -0
- enclave_ontos-0.1.0/deploy/helm/ontos/templates/service.yaml +15 -0
- enclave_ontos-0.1.0/deploy/helm/ontos/templates/serviceaccount.yaml +12 -0
- enclave_ontos-0.1.0/deploy/helm/ontos/values.yaml +124 -0
- enclave_ontos-0.1.0/docs/architecture.md +61 -0
- enclave_ontos-0.1.0/docs/compliance/eu-ai-act-article-12.md +35 -0
- enclave_ontos-0.1.0/docs/design/m1.md +237 -0
- enclave_ontos-0.1.0/docs/design/m2.md +161 -0
- enclave_ontos-0.1.0/docs/design/m3.md +133 -0
- enclave_ontos-0.1.0/docs/design/m4.md +188 -0
- enclave_ontos-0.1.0/docs/design/m5.md +136 -0
- enclave_ontos-0.1.0/docs/design/m6.md +110 -0
- enclave_ontos-0.1.0/docs/ontology/examples/starter.yaml +64 -0
- enclave_ontos-0.1.0/ontos/__init__.py +5 -0
- enclave_ontos-0.1.0/ontos/_version.py +16 -0
- enclave_ontos-0.1.0/ontos/audit/__init__.py +22 -0
- enclave_ontos-0.1.0/ontos/audit/base.py +38 -0
- enclave_ontos-0.1.0/ontos/audit/emitter.py +115 -0
- enclave_ontos-0.1.0/ontos/audit/postgres.py +298 -0
- enclave_ontos-0.1.0/ontos/authz/__init__.py +16 -0
- enclave_ontos-0.1.0/ontos/authz/base.py +53 -0
- enclave_ontos-0.1.0/ontos/authz/inmemory.py +37 -0
- enclave_ontos-0.1.0/ontos/authz/openfga.py +106 -0
- enclave_ontos-0.1.0/ontos/cli/__init__.py +5 -0
- enclave_ontos-0.1.0/ontos/cli/main.py +244 -0
- enclave_ontos-0.1.0/ontos/executor/__init__.py +16 -0
- enclave_ontos-0.1.0/ontos/executor/base.py +65 -0
- enclave_ontos-0.1.0/ontos/executor/deterministic.py +240 -0
- enclave_ontos-0.1.0/ontos/extraction/__init__.py +28 -0
- enclave_ontos-0.1.0/ontos/extraction/base.py +107 -0
- enclave_ontos-0.1.0/ontos/extraction/llm_extractor.py +208 -0
- enclave_ontos-0.1.0/ontos/ingest/__init__.py +16 -0
- enclave_ontos-0.1.0/ontos/ingest/base.py +53 -0
- enclave_ontos-0.1.0/ontos/ingest/slack.py +49 -0
- enclave_ontos-0.1.0/ontos/ingest/text.py +41 -0
- enclave_ontos-0.1.0/ontos/llm/__init__.py +18 -0
- enclave_ontos-0.1.0/ontos/llm/ollama.py +196 -0
- enclave_ontos-0.1.0/ontos/llm/openai.py +145 -0
- enclave_ontos-0.1.0/ontos/llm/prompts.py +69 -0
- enclave_ontos-0.1.0/ontos/ontology/__init__.py +25 -0
- enclave_ontos-0.1.0/ontos/ontology/loader.py +198 -0
- enclave_ontos-0.1.0/ontos/pipeline/__init__.py +19 -0
- enclave_ontos-0.1.0/ontos/pipeline/ingest.py +128 -0
- enclave_ontos-0.1.0/ontos/planner/__init__.py +33 -0
- enclave_ontos-0.1.0/ontos/planner/base.py +49 -0
- enclave_ontos-0.1.0/ontos/planner/llm_planner.py +98 -0
- enclave_ontos-0.1.0/ontos/planner/plan.py +102 -0
- enclave_ontos-0.1.0/ontos/resolver/__init__.py +24 -0
- enclave_ontos-0.1.0/ontos/resolver/base.py +77 -0
- enclave_ontos-0.1.0/ontos/resolver/cascade.py +57 -0
- enclave_ontos-0.1.0/ontos/resolver/rules.py +78 -0
- enclave_ontos-0.1.0/ontos/runtime/__init__.py +1 -0
- enclave_ontos-0.1.0/ontos/runtime/config.py +38 -0
- enclave_ontos-0.1.0/ontos/runtime/models.py +117 -0
- enclave_ontos-0.1.0/ontos/runtime/server.py +464 -0
- enclave_ontos-0.1.0/ontos/storage/__init__.py +1 -0
- enclave_ontos-0.1.0/ontos/storage/base.py +78 -0
- enclave_ontos-0.1.0/ontos/storage/neo4j_store.py +312 -0
- enclave_ontos-0.1.0/ontos/storage/networkx_store.py +170 -0
- enclave_ontos-0.1.0/pyproject.toml +79 -0
- enclave_ontos-0.1.0/tests/__init__.py +0 -0
- enclave_ontos-0.1.0/tests/benchmarks/__init__.py +0 -0
- enclave_ontos-0.1.0/tests/benchmarks/harness.py +108 -0
- enclave_ontos-0.1.0/tests/benchmarks/test_synthetic.py +135 -0
- enclave_ontos-0.1.0/tests/compliance/__init__.py +0 -0
- enclave_ontos-0.1.0/tests/compliance/test_article_twelve.py +114 -0
- enclave_ontos-0.1.0/tests/conftest.py +43 -0
- enclave_ontos-0.1.0/tests/integration/__init__.py +0 -0
- enclave_ontos-0.1.0/tests/integration/test_m1_end_to_end.py +409 -0
- enclave_ontos-0.1.0/tests/integration/test_m2_end_to_end.py +379 -0
- enclave_ontos-0.1.0/tests/integration/test_m3_end_to_end.py +301 -0
- enclave_ontos-0.1.0/tests/integration/test_neo4j_store.py +222 -0
- enclave_ontos-0.1.0/tests/integration/test_postgres_audit.py +215 -0
- enclave_ontos-0.1.0/tests/unit/__init__.py +0 -0
- enclave_ontos-0.1.0/tests/unit/test_authz.py +177 -0
- enclave_ontos-0.1.0/tests/unit/test_cli.py +100 -0
- enclave_ontos-0.1.0/tests/unit/test_executor.py +248 -0
- enclave_ontos-0.1.0/tests/unit/test_extraction_base.py +211 -0
- enclave_ontos-0.1.0/tests/unit/test_ingest.py +85 -0
- enclave_ontos-0.1.0/tests/unit/test_llm_adapters.py +240 -0
- enclave_ontos-0.1.0/tests/unit/test_llm_extractor.py +258 -0
- enclave_ontos-0.1.0/tests/unit/test_ontology_loader.py +201 -0
- enclave_ontos-0.1.0/tests/unit/test_pipeline.py +265 -0
- enclave_ontos-0.1.0/tests/unit/test_planner.py +163 -0
- enclave_ontos-0.1.0/tests/unit/test_resolver.py +208 -0
- enclave_ontos-0.1.0/tests/unit/test_smoke.py +36 -0
- enclave_ontos-0.1.0/tests/unit/test_storage.py +110 -0
- enclave_ontos-0.1.0/uv.lock +4488 -0
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
# Ontos environment configuration
|
|
2
|
+
#
|
|
3
|
+
# Copy to `.env` (git-ignored) and fill in the values you actually need.
|
|
4
|
+
# Values are grouped by milestone so you only set what your target
|
|
5
|
+
# milestone requires. M0 needs almost nothing.
|
|
6
|
+
#
|
|
7
|
+
# Sovereignty rule: any variable marked [BRIDGE] sends data outside the
|
|
8
|
+
# customer VPC and is a temporary dev convenience. Production deploys
|
|
9
|
+
# resolve every [BRIDGE] to a customer-controlled endpoint (Ollama /
|
|
10
|
+
# Bedrock / Azure OpenAI / Vertex) or to Enclave Scribe once Scribe
|
|
11
|
+
# passes benchmarks.
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
# ────────────────────────────────────────────────────────────────
|
|
15
|
+
# M0 — running today
|
|
16
|
+
# ────────────────────────────────────────────────────────────────
|
|
17
|
+
|
|
18
|
+
# Required in prod. In dev (ONTOS_ENV != "prod") the runtime auto-defaults
|
|
19
|
+
# to a loud placeholder — do NOT ship that placeholder to a customer.
|
|
20
|
+
# In prod, derive this from KMS (or the customer's key vault) at boot.
|
|
21
|
+
ONTOS_AUDIT_SIGNING_KEY=dev-only-signing-key-do-not-use
|
|
22
|
+
|
|
23
|
+
# Set to "prod" to make the runtime refuse to boot without a real
|
|
24
|
+
# signing key. Anything else (or unset) is dev mode.
|
|
25
|
+
ONTOS_ENV=dev
|
|
26
|
+
|
|
27
|
+
# Where the MCP server binds. 127.0.0.1 for local dev; 0.0.0.0 in a
|
|
28
|
+
# container behind a reverse proxy.
|
|
29
|
+
ONTOS_LISTEN_HOST=127.0.0.1
|
|
30
|
+
ONTOS_LISTEN_PORT=8765
|
|
31
|
+
|
|
32
|
+
# Which storage backend to use. M0 only supports "networkx" (in-memory).
|
|
33
|
+
# M1 adds "neo4j"; M2 adds "kuzu" (LadybugDB) and "neptune".
|
|
34
|
+
ONTOS_STORAGE_BACKEND=networkx
|
|
35
|
+
|
|
36
|
+
# Where the audit chain persists. SQLite default is fine for dev.
|
|
37
|
+
# M2 swaps to Postgres for regulated deploys (6+ month retention).
|
|
38
|
+
ONTOS_AUDIT_DB_URL=sqlite+pysqlite:///./audit-logs/audit.sqlite
|
|
39
|
+
|
|
40
|
+
# Name of the env var the runtime reads for the signing key.
|
|
41
|
+
# You almost never need to change this — it exists so a deploy can
|
|
42
|
+
# rename the concrete env var (e.g. to match a k8s secret's key).
|
|
43
|
+
ONTOS_AUDIT_SIGNING_KEY_ENV=ONTOS_AUDIT_SIGNING_KEY
|
|
44
|
+
|
|
45
|
+
# Optional: path to a YAML/LinkML ontology file. If unset, the runtime
|
|
46
|
+
# runs schemaless (M0 default).
|
|
47
|
+
# ONTOS_ONTOLOGY_PATH=./docs/ontology/examples/fintech.yaml
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
# ────────────────────────────────────────────────────────────────
|
|
51
|
+
# M1 — Neo4j storage + first extraction wrappers
|
|
52
|
+
# ────────────────────────────────────────────────────────────────
|
|
53
|
+
|
|
54
|
+
# Neo4j — self-hosted, Aura, or in-VPC cluster the customer runs.
|
|
55
|
+
# NEO4J_URI=bolt://localhost:7687
|
|
56
|
+
# NEO4J_USER=neo4j
|
|
57
|
+
# NEO4J_PASSWORD=
|
|
58
|
+
|
|
59
|
+
# LLM for extraction — pick exactly ONE of the three blocks below.
|
|
60
|
+
|
|
61
|
+
# Option A [BRIDGE]: OpenAI. Fastest to test; violates in-VPC promise.
|
|
62
|
+
# OPENAI_API_KEY=sk-...
|
|
63
|
+
# OPENAI_MODEL=gpt-4o-mini
|
|
64
|
+
|
|
65
|
+
# Option B [BRIDGE]: Anthropic. Better structured extraction than OpenAI.
|
|
66
|
+
# ANTHROPIC_API_KEY=sk-ant-...
|
|
67
|
+
# ANTHROPIC_MODEL=claude-sonnet-5
|
|
68
|
+
|
|
69
|
+
# Option C: Ollama (fully local, no key). This is the sovereignty-preserving
|
|
70
|
+
# path and the shape Scribe eventually replaces.
|
|
71
|
+
# OLLAMA_HOST=http://localhost:11434
|
|
72
|
+
# OLLAMA_MODEL=llama3.1:8b
|
|
73
|
+
|
|
74
|
+
# Embedding model. BGE-m3 runs locally via sentence-transformers.
|
|
75
|
+
# EMBEDDING_MODEL=BAAI/bge-m3
|
|
76
|
+
|
|
77
|
+
# When Enclave Scribe is ready and beats frontier benchmarks, these
|
|
78
|
+
# replace every extraction key above:
|
|
79
|
+
# SCRIBE_ENDPOINT=http://scribe.ontos.svc.cluster.local:9000
|
|
80
|
+
# SCRIBE_MODEL=scribe-v1
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
# ────────────────────────────────────────────────────────────────
|
|
84
|
+
# M2 — permission-aware traversal + persistent audit
|
|
85
|
+
# ────────────────────────────────────────────────────────────────
|
|
86
|
+
|
|
87
|
+
# OpenFGA (default authz backend). Self-host in-VPC, or point at
|
|
88
|
+
# openfga.dev's hosted plane for dev.
|
|
89
|
+
# FGA_API_URL=http://localhost:8080
|
|
90
|
+
# FGA_STORE_ID=
|
|
91
|
+
# FGA_API_TOKEN=
|
|
92
|
+
|
|
93
|
+
# Alternative: SpiceDB (Authzed). Pick one, not both.
|
|
94
|
+
# SPICEDB_ENDPOINT=localhost:50051
|
|
95
|
+
# SPICEDB_TOKEN=
|
|
96
|
+
|
|
97
|
+
# Postgres for the persistent hash-chained audit log (replaces the M0
|
|
98
|
+
# SQLite default). Regulated deploys must retain ≥6 months.
|
|
99
|
+
# ONTOS_AUDIT_DB_URL=postgresql+psycopg://ontos:changeme@postgres:5432/ontos_audit
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
# ────────────────────────────────────────────────────────────────
|
|
103
|
+
# M4 — real source connectors (per customer, per tenant, not global)
|
|
104
|
+
# ────────────────────────────────────────────────────────────────
|
|
105
|
+
#
|
|
106
|
+
# These are examples of what a connector config will look like — the
|
|
107
|
+
# real system will load per-tenant credentials from a secure store,
|
|
108
|
+
# not from process env. Do not put customer credentials here.
|
|
109
|
+
#
|
|
110
|
+
# SLACK_BOT_TOKEN=xoxb-...
|
|
111
|
+
# GOOGLE_DRIVE_CLIENT_ID=
|
|
112
|
+
# GOOGLE_DRIVE_CLIENT_SECRET=
|
|
113
|
+
# CONFLUENCE_API_TOKEN=
|
|
114
|
+
# JIRA_API_TOKEN=
|
|
115
|
+
# SALESFORCE_CLIENT_ID=
|
|
116
|
+
# SALESFORCE_CLIENT_SECRET=
|
|
117
|
+
# GITHUB_APP_ID=
|
|
118
|
+
# GITHUB_PRIVATE_KEY=
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
name: Bug report
|
|
2
|
+
description: Something in Ontos doesn't work as documented.
|
|
3
|
+
title: "[bug] "
|
|
4
|
+
labels: ["bug", "triage"]
|
|
5
|
+
body:
|
|
6
|
+
- type: markdown
|
|
7
|
+
attributes:
|
|
8
|
+
value: |
|
|
9
|
+
Thanks for the report. Please fill in what you can — every field
|
|
10
|
+
makes triage faster.
|
|
11
|
+
|
|
12
|
+
**Do NOT file a security vulnerability here.** See
|
|
13
|
+
[SECURITY.md](../blob/main/SECURITY.md) for the private
|
|
14
|
+
disclosure path.
|
|
15
|
+
|
|
16
|
+
- type: textarea
|
|
17
|
+
id: what-happened
|
|
18
|
+
attributes:
|
|
19
|
+
label: What happened
|
|
20
|
+
description: What you saw, and what you expected instead.
|
|
21
|
+
validations:
|
|
22
|
+
required: true
|
|
23
|
+
|
|
24
|
+
- type: textarea
|
|
25
|
+
id: reproduction
|
|
26
|
+
attributes:
|
|
27
|
+
label: Minimal reproduction
|
|
28
|
+
description: |
|
|
29
|
+
The smallest snippet, commands, or steps that reliably reproduce
|
|
30
|
+
the issue. If you can't produce a MRE, describe the shape of what
|
|
31
|
+
you were doing instead.
|
|
32
|
+
render: bash
|
|
33
|
+
validations:
|
|
34
|
+
required: true
|
|
35
|
+
|
|
36
|
+
- type: input
|
|
37
|
+
id: version
|
|
38
|
+
attributes:
|
|
39
|
+
label: Ontos version / commit
|
|
40
|
+
description: Output of `uv pip show ontos` or the commit SHA you're on.
|
|
41
|
+
validations:
|
|
42
|
+
required: true
|
|
43
|
+
|
|
44
|
+
- type: input
|
|
45
|
+
id: python
|
|
46
|
+
attributes:
|
|
47
|
+
label: Python version
|
|
48
|
+
description: Output of `python --version`.
|
|
49
|
+
validations:
|
|
50
|
+
required: true
|
|
51
|
+
|
|
52
|
+
- type: dropdown
|
|
53
|
+
id: storage-backend
|
|
54
|
+
attributes:
|
|
55
|
+
label: Storage backend
|
|
56
|
+
options:
|
|
57
|
+
- networkx (M0 in-memory)
|
|
58
|
+
- neo4j
|
|
59
|
+
- kuzu / ladybugdb
|
|
60
|
+
- neptune
|
|
61
|
+
- other / n/a
|
|
62
|
+
validations:
|
|
63
|
+
required: true
|
|
64
|
+
|
|
65
|
+
- type: textarea
|
|
66
|
+
id: logs
|
|
67
|
+
attributes:
|
|
68
|
+
label: Relevant logs / stack trace
|
|
69
|
+
description: |
|
|
70
|
+
Paste any relevant structured log output or a stack trace. Redact
|
|
71
|
+
anything that looks like a customer identifier, credential, or
|
|
72
|
+
piece of regulated data before pasting.
|
|
73
|
+
render: text
|
|
74
|
+
validations:
|
|
75
|
+
required: false
|
|
76
|
+
|
|
77
|
+
- type: checkboxes
|
|
78
|
+
id: touches-compliance
|
|
79
|
+
attributes:
|
|
80
|
+
label: Does this touch a compliance property?
|
|
81
|
+
description: Tick every one that applies. This routes the bug to the right reviewer.
|
|
82
|
+
options:
|
|
83
|
+
- label: Audit chain (Article 12)
|
|
84
|
+
- label: Permission-aware traversal / node-existence leaks
|
|
85
|
+
- label: Bitemporal correctness (`as_of` returns wrong facts)
|
|
86
|
+
- label: Provenance metadata (missing / forged / dropped)
|
|
87
|
+
- label: Sovereignty (unexpected outbound network call)
|
|
88
|
+
- label: None of the above
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
blank_issues_enabled: false
|
|
2
|
+
contact_links:
|
|
3
|
+
- name: Security vulnerability
|
|
4
|
+
url: https://github.com/getenclave/ontos/blob/main/SECURITY.md
|
|
5
|
+
about: Do NOT open a public issue. Follow the private disclosure path in SECURITY.md.
|
|
6
|
+
- name: Question / help / design discussion
|
|
7
|
+
url: https://github.com/getenclave/ontos/discussions
|
|
8
|
+
about: Use GitHub Discussions for questions and open-ended design conversation.
|
|
9
|
+
- name: Enclave (the parent product)
|
|
10
|
+
url: https://getenclave.ai
|
|
11
|
+
about: Ontos is a subset of Enclave. For anything about the wider Enclave platform, start here.
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
name: Feature / proposal
|
|
2
|
+
description: Suggest a new capability, connector, backend, or design change.
|
|
3
|
+
title: "[proposal] "
|
|
4
|
+
labels: ["proposal", "triage"]
|
|
5
|
+
body:
|
|
6
|
+
- type: markdown
|
|
7
|
+
attributes:
|
|
8
|
+
value: |
|
|
9
|
+
Thanks for the idea. Before you start writing code for anything
|
|
10
|
+
architectural (new module, new storage backend, new authz backend,
|
|
11
|
+
new extractor family), please open this issue first so we can
|
|
12
|
+
align on the design.
|
|
13
|
+
|
|
14
|
+
Small fixes, docs, tests, and connector adapters don't need a
|
|
15
|
+
proposal issue — just open a PR.
|
|
16
|
+
|
|
17
|
+
- type: textarea
|
|
18
|
+
id: problem
|
|
19
|
+
attributes:
|
|
20
|
+
label: What problem does this solve
|
|
21
|
+
description: |
|
|
22
|
+
Describe the user or operational pain first. Do NOT lead with a
|
|
23
|
+
proposed solution — the shape of the fix follows from the shape
|
|
24
|
+
of the problem.
|
|
25
|
+
validations:
|
|
26
|
+
required: true
|
|
27
|
+
|
|
28
|
+
- type: textarea
|
|
29
|
+
id: proposed
|
|
30
|
+
attributes:
|
|
31
|
+
label: Proposed approach
|
|
32
|
+
description: |
|
|
33
|
+
Rough sketch of the change. Modules touched, new data shapes,
|
|
34
|
+
MCP surface changes, config surface changes. Details welcome
|
|
35
|
+
but not required.
|
|
36
|
+
validations:
|
|
37
|
+
required: true
|
|
38
|
+
|
|
39
|
+
- type: textarea
|
|
40
|
+
id: alternatives
|
|
41
|
+
attributes:
|
|
42
|
+
label: Alternatives you considered
|
|
43
|
+
description: What else could solve this, and why the proposed approach wins.
|
|
44
|
+
validations:
|
|
45
|
+
required: false
|
|
46
|
+
|
|
47
|
+
- type: checkboxes
|
|
48
|
+
id: invariants
|
|
49
|
+
attributes:
|
|
50
|
+
label: Which invariants does this touch?
|
|
51
|
+
description: Tick every one this proposal changes or has to preserve.
|
|
52
|
+
options:
|
|
53
|
+
- label: Provenance on every fact
|
|
54
|
+
- label: Audit-first (every request path emits an `AuditRecord`)
|
|
55
|
+
- label: Permission-aware traversal (no node-existence leaks)
|
|
56
|
+
- label: Bitemporal immutability
|
|
57
|
+
- label: Sovereignty (no outbound calls to non-configured hosts)
|
|
58
|
+
- label: Extractor interface stays a drop-in for enclave-scribe
|
|
59
|
+
- label: None of the above
|
|
60
|
+
|
|
61
|
+
- type: dropdown
|
|
62
|
+
id: milestone
|
|
63
|
+
attributes:
|
|
64
|
+
label: Which milestone does this target
|
|
65
|
+
options:
|
|
66
|
+
- "M0 (scaffolding, in-memory storage)"
|
|
67
|
+
- "M1 (Neo4j + extraction wrappers)"
|
|
68
|
+
- "M2 (OpenFGA / persistent audit)"
|
|
69
|
+
- "M3 (planner/executor split, PPR, PathRAG-style pruning)"
|
|
70
|
+
- "M4 (bitemporal writes, ER cascade, connectors)"
|
|
71
|
+
- "v0 GA (design partner ready)"
|
|
72
|
+
- "Not sure — you tell me"
|
|
73
|
+
validations:
|
|
74
|
+
required: true
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
Thanks for contributing to Ontos!
|
|
3
|
+
|
|
4
|
+
Please fill in every section below. If a section genuinely doesn't apply,
|
|
5
|
+
write "n/a" and one line saying why — don't delete it.
|
|
6
|
+
|
|
7
|
+
Compliance-critical PRs (anything touching authz, audit, or provenance)
|
|
8
|
+
must include tests under tests/compliance/.
|
|
9
|
+
-->
|
|
10
|
+
|
|
11
|
+
## Why
|
|
12
|
+
|
|
13
|
+
<!-- The problem this PR solves. Link the issue if one exists (Fixes #NNN). -->
|
|
14
|
+
|
|
15
|
+
## What
|
|
16
|
+
|
|
17
|
+
<!-- The change, in 3–5 bullets. Reviewers should not have to read the
|
|
18
|
+
diff to know the shape of what changed. -->
|
|
19
|
+
|
|
20
|
+
## Non-negotiables checklist
|
|
21
|
+
|
|
22
|
+
<!-- Tick every box that applies. If you had to weaken any invariant,
|
|
23
|
+
explain in "Notes for reviewer" below. -->
|
|
24
|
+
|
|
25
|
+
- [ ] Every new `Fact` written to the store carries full `Provenance`.
|
|
26
|
+
- [ ] Every code path that returns data to an agent emits an `AuditRecord` before returning.
|
|
27
|
+
- [ ] No permission post-filtering added; traversal-time checks preserved; no node-existence leaks.
|
|
28
|
+
- [ ] No in-place `Fact` mutation; corrections use `close_fact(...)` supersession.
|
|
29
|
+
- [ ] No outbound network calls to hosts the operator did not configure; no telemetry to Enclave-operated services.
|
|
30
|
+
- [ ] Extractor interface remains a drop-in for `enclave-scribe` — no LlamaIndex/LangChain-specific types leak past `ontos/extraction/`.
|
|
31
|
+
|
|
32
|
+
## Tests
|
|
33
|
+
|
|
34
|
+
<!-- List what you added/changed under tests/. Compliance-critical PRs
|
|
35
|
+
MUST land with matching tests under tests/compliance/. -->
|
|
36
|
+
|
|
37
|
+
- [ ] Unit tests added / updated
|
|
38
|
+
- [ ] Compliance tests added / updated (required if this touches authz, audit, or provenance)
|
|
39
|
+
- [ ] Integration tests added / updated
|
|
40
|
+
- [ ] Benchmarks updated (if this changes retrieval quality or latency)
|
|
41
|
+
|
|
42
|
+
## Verification
|
|
43
|
+
|
|
44
|
+
<!-- The exact commands you ran to convince yourself this works. -->
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
uv run ruff check ontos tests
|
|
48
|
+
uv run mypy ontos
|
|
49
|
+
uv run pytest -q
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Notes for reviewer
|
|
53
|
+
|
|
54
|
+
<!-- Anything the reviewer needs to know that isn't obvious from the diff:
|
|
55
|
+
tradeoffs you considered, alternatives you rejected, follow-ups you
|
|
56
|
+
plan for a later PR. -->
|
|
57
|
+
|
|
58
|
+
## DCO
|
|
59
|
+
|
|
60
|
+
- [ ] I have signed off every commit (`git commit -s`) per the [DCO](https://developercertificate.org/).
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
pull_request:
|
|
5
|
+
branches: [main]
|
|
6
|
+
push:
|
|
7
|
+
branches: [main]
|
|
8
|
+
workflow_dispatch:
|
|
9
|
+
|
|
10
|
+
# Cancel superseded runs on the same branch/PR so a fast rebase doesn't
|
|
11
|
+
# leave a stale run consuming a runner.
|
|
12
|
+
concurrency:
|
|
13
|
+
group: ci-${{ github.workflow }}-${{ github.head_ref || github.ref }}
|
|
14
|
+
cancel-in-progress: true
|
|
15
|
+
|
|
16
|
+
permissions:
|
|
17
|
+
contents: read
|
|
18
|
+
|
|
19
|
+
jobs:
|
|
20
|
+
test:
|
|
21
|
+
name: lint · type-check · test
|
|
22
|
+
runs-on: ubuntu-latest
|
|
23
|
+
timeout-minutes: 15
|
|
24
|
+
|
|
25
|
+
steps:
|
|
26
|
+
- name: Checkout
|
|
27
|
+
uses: actions/checkout@v4
|
|
28
|
+
|
|
29
|
+
- name: Install uv
|
|
30
|
+
uses: astral-sh/setup-uv@v3
|
|
31
|
+
with:
|
|
32
|
+
# Cache the uv download index + wheel cache across runs on the
|
|
33
|
+
# same branch. Cache key is derived from uv.lock so a lock
|
|
34
|
+
# change forces a clean install.
|
|
35
|
+
enable-cache: true
|
|
36
|
+
cache-dependency-glob: "uv.lock"
|
|
37
|
+
|
|
38
|
+
- name: Set up Python (from .python-version)
|
|
39
|
+
run: uv python install
|
|
40
|
+
|
|
41
|
+
- name: Install dependencies
|
|
42
|
+
run: uv sync --extra dev --frozen
|
|
43
|
+
|
|
44
|
+
- name: Ruff (lint)
|
|
45
|
+
run: uv run ruff check ontos tests
|
|
46
|
+
|
|
47
|
+
- name: Mypy (strict type-check)
|
|
48
|
+
run: uv run mypy ontos
|
|
49
|
+
|
|
50
|
+
- name: Pytest (unit + compliance)
|
|
51
|
+
run: uv run pytest -q -m "not integration and not benchmark"
|
|
52
|
+
|
|
53
|
+
- name: Pytest (integration — Neo4j via Testcontainers)
|
|
54
|
+
run: uv run pytest -q -m "integration and not benchmark"
|
|
55
|
+
|
|
56
|
+
- name: Set up Helm
|
|
57
|
+
uses: azure/setup-helm@v4
|
|
58
|
+
with:
|
|
59
|
+
version: v3.16.0
|
|
60
|
+
|
|
61
|
+
- name: Helm lint (deploy/helm/ontos)
|
|
62
|
+
run: helm lint deploy/helm/ontos
|
|
63
|
+
|
|
64
|
+
- name: Helm template renders (deploy/helm/ontos)
|
|
65
|
+
# `--dry-run=client` skips the API server; we just want to
|
|
66
|
+
# prove every template compiles into valid YAML.
|
|
67
|
+
run: helm template ontos deploy/helm/ontos > /dev/null
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- "v*"
|
|
7
|
+
workflow_dispatch:
|
|
8
|
+
inputs:
|
|
9
|
+
dry_run:
|
|
10
|
+
description: "Build and validate everything; skip PyPI + GHCR pushes."
|
|
11
|
+
type: boolean
|
|
12
|
+
default: true
|
|
13
|
+
|
|
14
|
+
permissions:
|
|
15
|
+
contents: write # for creating the GitHub Release
|
|
16
|
+
packages: write # for pushing to GHCR
|
|
17
|
+
id-token: write # for PyPI trusted publishing (OIDC)
|
|
18
|
+
|
|
19
|
+
concurrency:
|
|
20
|
+
group: release-${{ github.ref }}
|
|
21
|
+
cancel-in-progress: false
|
|
22
|
+
|
|
23
|
+
jobs:
|
|
24
|
+
build:
|
|
25
|
+
name: Build wheels + verify version
|
|
26
|
+
runs-on: ubuntu-latest
|
|
27
|
+
timeout-minutes: 15
|
|
28
|
+
outputs:
|
|
29
|
+
version: ${{ steps.version.outputs.version }}
|
|
30
|
+
steps:
|
|
31
|
+
- name: Checkout
|
|
32
|
+
uses: actions/checkout@v4
|
|
33
|
+
|
|
34
|
+
- name: Install uv
|
|
35
|
+
uses: astral-sh/setup-uv@v3
|
|
36
|
+
with:
|
|
37
|
+
enable-cache: true
|
|
38
|
+
cache-dependency-glob: uv.lock
|
|
39
|
+
|
|
40
|
+
- name: Set up Python
|
|
41
|
+
run: uv python install
|
|
42
|
+
|
|
43
|
+
- name: Extract version from tag
|
|
44
|
+
id: version
|
|
45
|
+
run: |
|
|
46
|
+
if [[ "${{ github.ref }}" == refs/tags/v* ]]; then
|
|
47
|
+
VERSION="${GITHUB_REF#refs/tags/v}"
|
|
48
|
+
else
|
|
49
|
+
# workflow_dispatch: dry-run; use whatever's in _version.py
|
|
50
|
+
VERSION="$(python -c "import runpy; print(runpy.run_path('ontos/_version.py')['__version__'])")"
|
|
51
|
+
fi
|
|
52
|
+
echo "version=${VERSION}" >> "$GITHUB_OUTPUT"
|
|
53
|
+
echo "Building Ontos v${VERSION}"
|
|
54
|
+
|
|
55
|
+
- name: Verify tag matches ontos/_version.py
|
|
56
|
+
if: startsWith(github.ref, 'refs/tags/v')
|
|
57
|
+
run: |
|
|
58
|
+
FILE_VERSION="$(python -c "import runpy; print(runpy.run_path('ontos/_version.py')['__version__'])")"
|
|
59
|
+
TAG_VERSION="${{ steps.version.outputs.version }}"
|
|
60
|
+
if [[ "$FILE_VERSION" != "$TAG_VERSION" ]]; then
|
|
61
|
+
echo "ERROR: git tag v${TAG_VERSION} does not match ontos/_version.py (${FILE_VERSION})"
|
|
62
|
+
exit 1
|
|
63
|
+
fi
|
|
64
|
+
|
|
65
|
+
- name: Build sdist + wheel
|
|
66
|
+
run: uv build
|
|
67
|
+
|
|
68
|
+
- name: Upload build artifacts
|
|
69
|
+
uses: actions/upload-artifact@v4
|
|
70
|
+
with:
|
|
71
|
+
name: dist
|
|
72
|
+
path: dist/
|
|
73
|
+
retention-days: 7
|
|
74
|
+
|
|
75
|
+
publish-pypi:
|
|
76
|
+
name: Publish to PyPI
|
|
77
|
+
needs: build
|
|
78
|
+
runs-on: ubuntu-latest
|
|
79
|
+
if: startsWith(github.ref, 'refs/tags/v') && !inputs.dry_run
|
|
80
|
+
environment:
|
|
81
|
+
name: pypi
|
|
82
|
+
url: https://pypi.org/project/enclave-ontos/${{ needs.build.outputs.version }}
|
|
83
|
+
steps:
|
|
84
|
+
- name: Download build artifacts
|
|
85
|
+
uses: actions/download-artifact@v4
|
|
86
|
+
with:
|
|
87
|
+
name: dist
|
|
88
|
+
path: dist/
|
|
89
|
+
|
|
90
|
+
- name: Publish to PyPI via trusted publishing
|
|
91
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
92
|
+
# No password / API token: uses OIDC trusted publishing. Set up
|
|
93
|
+
# the PyPI project once at pypi.org → Manage → Publishing →
|
|
94
|
+
# Add a new publisher, GitHub, this repo, workflow=release.yml,
|
|
95
|
+
# environment=pypi. See RELEASING.md.
|
|
96
|
+
|
|
97
|
+
publish-ghcr:
|
|
98
|
+
name: Build + push container to GHCR
|
|
99
|
+
needs: build
|
|
100
|
+
runs-on: ubuntu-latest
|
|
101
|
+
if: startsWith(github.ref, 'refs/tags/v') && !inputs.dry_run
|
|
102
|
+
steps:
|
|
103
|
+
- name: Checkout
|
|
104
|
+
uses: actions/checkout@v4
|
|
105
|
+
|
|
106
|
+
- name: Log in to GHCR
|
|
107
|
+
uses: docker/login-action@v3
|
|
108
|
+
with:
|
|
109
|
+
registry: ghcr.io
|
|
110
|
+
username: ${{ github.actor }}
|
|
111
|
+
password: ${{ secrets.GITHUB_TOKEN }}
|
|
112
|
+
|
|
113
|
+
- name: Compute image tags
|
|
114
|
+
id: meta
|
|
115
|
+
run: |
|
|
116
|
+
VERSION="${{ needs.build.outputs.version }}"
|
|
117
|
+
IMAGE="ghcr.io/${{ github.repository_owner }}/ontos"
|
|
118
|
+
# Force lowercase — GHCR requires lowercase image names.
|
|
119
|
+
IMAGE="${IMAGE,,}"
|
|
120
|
+
echo "image=${IMAGE}" >> "$GITHUB_OUTPUT"
|
|
121
|
+
echo "tag_version=${IMAGE}:${VERSION}" >> "$GITHUB_OUTPUT"
|
|
122
|
+
echo "tag_latest=${IMAGE}:latest" >> "$GITHUB_OUTPUT"
|
|
123
|
+
|
|
124
|
+
- name: Build + push image
|
|
125
|
+
uses: docker/build-push-action@v6
|
|
126
|
+
with:
|
|
127
|
+
context: .
|
|
128
|
+
file: deploy/Dockerfile
|
|
129
|
+
push: true
|
|
130
|
+
tags: |
|
|
131
|
+
${{ steps.meta.outputs.tag_version }}
|
|
132
|
+
${{ steps.meta.outputs.tag_latest }}
|
|
133
|
+
labels: |
|
|
134
|
+
org.opencontainers.image.source=https://github.com/${{ github.repository }}
|
|
135
|
+
org.opencontainers.image.version=${{ needs.build.outputs.version }}
|
|
136
|
+
org.opencontainers.image.revision=${{ github.sha }}
|
|
137
|
+
|
|
138
|
+
gh-release:
|
|
139
|
+
name: Create GitHub Release
|
|
140
|
+
needs: [build, publish-pypi, publish-ghcr]
|
|
141
|
+
runs-on: ubuntu-latest
|
|
142
|
+
if: startsWith(github.ref, 'refs/tags/v') && !inputs.dry_run
|
|
143
|
+
steps:
|
|
144
|
+
- name: Checkout
|
|
145
|
+
uses: actions/checkout@v4
|
|
146
|
+
|
|
147
|
+
- name: Extract CHANGELOG section for this version
|
|
148
|
+
id: notes
|
|
149
|
+
run: |
|
|
150
|
+
VERSION="${{ needs.build.outputs.version }}"
|
|
151
|
+
# Extract the section between `## [VERSION]` and the next `## [`.
|
|
152
|
+
awk -v v="[$VERSION]" '
|
|
153
|
+
$0 ~ "^## " v { flag=1; next }
|
|
154
|
+
flag && /^## \[/ { flag=0 }
|
|
155
|
+
flag { print }
|
|
156
|
+
' CHANGELOG.md > release_notes.md
|
|
157
|
+
if [[ ! -s release_notes.md ]]; then
|
|
158
|
+
echo "WARNING: no CHANGELOG section for v${VERSION}; using a stub" >&2
|
|
159
|
+
echo "See CHANGELOG.md for details." > release_notes.md
|
|
160
|
+
fi
|
|
161
|
+
|
|
162
|
+
- name: Download build artifacts
|
|
163
|
+
uses: actions/download-artifact@v4
|
|
164
|
+
with:
|
|
165
|
+
name: dist
|
|
166
|
+
path: dist/
|
|
167
|
+
|
|
168
|
+
- name: Publish GitHub Release
|
|
169
|
+
uses: softprops/action-gh-release@v2
|
|
170
|
+
with:
|
|
171
|
+
body_path: release_notes.md
|
|
172
|
+
files: dist/*
|
|
173
|
+
fail_on_unmatched_files: true
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
__pycache__/
|
|
2
|
+
*.py[cod]
|
|
3
|
+
*$py.class
|
|
4
|
+
*.egg-info/
|
|
5
|
+
.pytest_cache/
|
|
6
|
+
.mypy_cache/
|
|
7
|
+
.ruff_cache/
|
|
8
|
+
.coverage
|
|
9
|
+
htmlcov/
|
|
10
|
+
.venv/
|
|
11
|
+
venv/
|
|
12
|
+
.env
|
|
13
|
+
.env.*
|
|
14
|
+
!.env.example
|
|
15
|
+
*.db
|
|
16
|
+
*.sqlite
|
|
17
|
+
*.sqlite3
|
|
18
|
+
runtime-data/
|
|
19
|
+
audit-logs/
|
|
20
|
+
.DS_Store
|
|
21
|
+
.idea/
|
|
22
|
+
.vscode/
|
|
23
|
+
dist/
|
|
24
|
+
build/
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
3.12
|