ontolith 1.0.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.
- ontolith-1.0.0/.github/workflows/ci.yml +221 -0
- ontolith-1.0.0/.github/workflows/security.yml +86 -0
- ontolith-1.0.0/.gitignore +51 -0
- ontolith-1.0.0/.pre-commit-config.yaml +24 -0
- ontolith-1.0.0/CHANGELOG.md +1756 -0
- ontolith-1.0.0/CLAUDE.md +490 -0
- ontolith-1.0.0/CODE_OF_CONDUCT.md +26 -0
- ontolith-1.0.0/CONTRIBUTING.md +295 -0
- ontolith-1.0.0/LICENSE +201 -0
- ontolith-1.0.0/PKG-INFO +137 -0
- ontolith-1.0.0/README.md +60 -0
- ontolith-1.0.0/SECURITY.md +36 -0
- ontolith-1.0.0/conformance/__init__.py +0 -0
- ontolith-1.0.0/conformance/conftest.py +112 -0
- ontolith-1.0.0/conformance/test_accountable_owner.py +250 -0
- ontolith-1.0.0/conformance/test_admin_audit_trail.py +220 -0
- ontolith-1.0.0/conformance/test_append_only.py +142 -0
- ontolith-1.0.0/conformance/test_append_only_properties.py +189 -0
- ontolith-1.0.0/conformance/test_assertion_audit_log.py +228 -0
- ontolith-1.0.0/conformance/test_audit_table_immutability.py +486 -0
- ontolith-1.0.0/conformance/test_basic_assertion.py +108 -0
- ontolith-1.0.0/conformance/test_bitemporal.py +1089 -0
- ontolith-1.0.0/conformance/test_composite_policy.py +274 -0
- ontolith-1.0.0/conformance/test_confidence_threshold_policy.py +122 -0
- ontolith-1.0.0/conformance/test_confidence_trust_filters.py +988 -0
- ontolith-1.0.0/conformance/test_conflict.py +1825 -0
- ontolith-1.0.0/conformance/test_conflict_routing_properties.py +247 -0
- ontolith-1.0.0/conformance/test_contradiction_resolution.py +1775 -0
- ontolith-1.0.0/conformance/test_include_flagged_history.py +331 -0
- ontolith-1.0.0/conformance/test_plugin_contract.py +204 -0
- ontolith-1.0.0/conformance/test_policy_injection.py +126 -0
- ontolith-1.0.0/conformance/test_proposal_policy.py +159 -0
- ontolith-1.0.0/conformance/test_proposal_workflow.py +364 -0
- ontolith-1.0.0/conformance/test_require_review_by_role_policy.py +128 -0
- ontolith-1.0.0/conformance/test_require_review_for_ai_policy.py +188 -0
- ontolith-1.0.0/conformance/test_review_workflow.py +1487 -0
- ontolith-1.0.0/conformance/test_source_quorum_policy.py +347 -0
- ontolith-1.0.0/conformance/test_source_required_policy.py +114 -0
- ontolith-1.0.0/conformance/test_trust_delegation.py +465 -0
- ontolith-1.0.0/conformance/test_trust_delegation_properties.py +97 -0
- ontolith-1.0.0/conformance/test_vector_search.py +93 -0
- ontolith-1.0.0/conformance/test_where_lookup_operators.py +202 -0
- ontolith-1.0.0/conftest.py +19 -0
- ontolith-1.0.0/docs/Ontolith_Implementation_Plan.md +376 -0
- ontolith-1.0.0/docs/Ontolith_PRD.md +391 -0
- ontolith-1.0.0/docs/Ontolith_SPEC.md +688 -0
- ontolith-1.0.0/docs/Ontolith_UseCases_and_Interfaces.md +236 -0
- ontolith-1.0.0/docs/adr/ADR-0001-storage-default.md +215 -0
- ontolith-1.0.0/docs/adr/ADR-0002-schema-definition.md +101 -0
- ontolith-1.0.0/docs/adr/ADR-0003-agent-identity.md +95 -0
- ontolith-1.0.0/docs/adr/ADR-0004-confidence-semantics.md +94 -0
- ontolith-1.0.0/docs/adr/ADR-0005-conflict-model.md +104 -0
- ontolith-1.0.0/docs/adr/ADR-0006-licensing-and-business.md +110 -0
- ontolith-1.0.0/docs/adr/ADR-0007-interop-priority.md +94 -0
- ontolith-1.0.0/docs/adr/ADR-0008-mcp-surface.md +180 -0
- ontolith-1.0.0/docs/adr/ADR-0009-trust-level-range.md +124 -0
- ontolith-1.0.0/docs/adr/ADR-0010-sqlite-transaction-model.md +166 -0
- ontolith-1.0.0/docs/adr/ADR-0011-provenance-fk-enforcement.md +108 -0
- ontolith-1.0.0/docs/adr/ADR-0012-class-dsl-compiler.md +74 -0
- ontolith-1.0.0/docs/adr/ADR-0013-linkml-dialect-coverage.md +109 -0
- ontolith-1.0.0/docs/adr/ADR-0014-mcp-authentication.md +338 -0
- ontolith-1.0.0/docs/adr/ADR-0015-plugin-capability-isolation.md +212 -0
- ontolith-1.0.0/docs/adr/ADR-0016-duckdb-second-backend.md +95 -0
- ontolith-1.0.0/docs/adr/ADR-0017-cardinality-conflict-semantics.md +74 -0
- ontolith-1.0.0/docs/adr/ADR-0018-policy-strategy-injection.md +71 -0
- ontolith-1.0.0/docs/adr/ADR-0019-public-api-stability-policy.md +267 -0
- ontolith-1.0.0/docs/adr/ADR-0020-hybrid-retrieval-storage-layer.md +263 -0
- ontolith-1.0.0/docs/adr/ADR-0021-rest-interface.md +201 -0
- ontolith-1.0.0/docs/adr/ADR-0022-rest-write-review-admin.md +513 -0
- ontolith-1.0.0/docs/adr/ADR-0023-multi-target-supersession-audit-trail.md +174 -0
- ontolith-1.0.0/docs/adr/ADR-0024-as-of-schema-resolution.md +113 -0
- ontolith-1.0.0/docs/adr/ADR-0025-policy-kb-parameter-and-source-quorum.md +186 -0
- ontolith-1.0.0/docs/adr/ADR-0026-security-ci-hardening.md +209 -0
- ontolith-1.0.0/docs/adr/ADR-0027-defer-relation-traversal-and-lookup-operators.md +138 -0
- ontolith-1.0.0/docs/adr/ADR-0028-value-type-enforcement-required-deferred.md +102 -0
- ontolith-1.0.0/docs/adr/ADR-0029-validator-invocation.md +89 -0
- ontolith-1.0.0/docs/adr/ADR-0030-retract-contradiction-capability-floor.md +85 -0
- ontolith-1.0.0/docs/adr/ADR-0031-retracted-terminal-for-winner-selection.md +81 -0
- ontolith-1.0.0/docs/adr/ADR-0032-duckdb-concurrency-lock.md +64 -0
- ontolith-1.0.0/docs/adr/ADR-0033-trust-at-least-delegation-attenuation.md +55 -0
- ontolith-1.0.0/docs/adr/ADR-0034-cli-schema-migrate.md +49 -0
- ontolith-1.0.0/docs/adr/ADR-0035-flag-contradiction-eligible-winner.md +65 -0
- ontolith-1.0.0/docs/adr/ADR-0036-rdf-owl-bridge.md +80 -0
- ontolith-1.0.0/docs/adr/ADR-0037-graphql-interface.md +482 -0
- ontolith-1.0.0/docs/adr/ADR-0038-admin-capability-gating.md +190 -0
- ontolith-1.0.0/docs/adr/ADR-0039-retract-interface-exposure.md +53 -0
- ontolith-1.0.0/docs/adr/ADR-0040-composite-policy-strategy.md +67 -0
- ontolith-1.0.0/docs/adr/ADR-0041-audit-table-immutability-triggers.md +106 -0
- ontolith-1.0.0/docs/adr/ADR-0042-admin-action-audit-trail.md +99 -0
- ontolith-1.0.0/docs/adr/ADR-0043-mcp-query-hybrid-retrieval-params.md +72 -0
- ontolith-1.0.0/docs/adr/ADR-0044-observability-scope.md +251 -0
- ontolith-1.0.0/docs/adr/ADR-0045-confidence-source-role-policy-strategies.md +233 -0
- ontolith-1.0.0/docs/adr/ADR-0046-proposal-reviewers-and-assign-action.md +241 -0
- ontolith-1.0.0/docs/adr/ADR-0047-provenance-on-ontology-not-entity.md +144 -0
- ontolith-1.0.0/docs/adr/ADR-0048-include-flagged-history-query-opt-ins.md +230 -0
- ontolith-1.0.0/docs/adr/ADR-0049-retraction-aware-as-of.md +208 -0
- ontolith-1.0.0/docs/adr/ADR-0050-time-varying-many-supersedes-hint.md +228 -0
- ontolith-1.0.0/docs/adr/ADR-0051-plugin-process-isolation.md +826 -0
- ontolith-1.0.0/docs/adr/ADR-0052-storage-format-migrations.md +481 -0
- ontolith-1.0.0/docs/adr/README.md +101 -0
- ontolith-1.0.0/docs/known-issues.md +2414 -0
- ontolith-1.0.0/examples/quickstart.py +213 -0
- ontolith-1.0.0/pyproject.toml +307 -0
- ontolith-1.0.0/src/ontolith/__init__.py +47 -0
- ontolith-1.0.0/src/ontolith/core/__init__.py +80 -0
- ontolith-1.0.0/src/ontolith/core/assertion.py +132 -0
- ontolith-1.0.0/src/ontolith/core/clock.py +116 -0
- ontolith-1.0.0/src/ontolith/core/embedder.py +141 -0
- ontolith-1.0.0/src/ontolith/core/entity.py +34 -0
- ontolith-1.0.0/src/ontolith/core/errors.py +159 -0
- ontolith-1.0.0/src/ontolith/core/ids.py +146 -0
- ontolith-1.0.0/src/ontolith/core/namespace.py +30 -0
- ontolith-1.0.0/src/ontolith/core/observability.py +216 -0
- ontolith-1.0.0/src/ontolith/govern/__init__.py +66 -0
- ontolith-1.0.0/src/ontolith/govern/conflict.py +234 -0
- ontolith-1.0.0/src/ontolith/govern/contradiction.py +112 -0
- ontolith-1.0.0/src/ontolith/govern/policy.py +886 -0
- ontolith-1.0.0/src/ontolith/govern/proposal.py +114 -0
- ontolith-1.0.0/src/ontolith/govern/provenance.py +44 -0
- ontolith-1.0.0/src/ontolith/identity/__init__.py +45 -0
- ontolith-1.0.0/src/ontolith/identity/admin_event.py +57 -0
- ontolith-1.0.0/src/ontolith/identity/credential.py +44 -0
- ontolith-1.0.0/src/ontolith/identity/ports.py +33 -0
- ontolith-1.0.0/src/ontolith/identity/principal.py +67 -0
- ontolith-1.0.0/src/ontolith/identity/token_auth.py +52 -0
- ontolith-1.0.0/src/ontolith/interfaces/__init__.py +0 -0
- ontolith-1.0.0/src/ontolith/interfaces/cli.py +1135 -0
- ontolith-1.0.0/src/ontolith/interfaces/graphql.py +1203 -0
- ontolith-1.0.0/src/ontolith/interfaces/mcp.py +1046 -0
- ontolith-1.0.0/src/ontolith/interfaces/rest.py +1407 -0
- ontolith-1.0.0/src/ontolith/observe/__init__.py +0 -0
- ontolith-1.0.0/src/ontolith/ontology.py +3614 -0
- ontolith-1.0.0/src/ontolith/plugins/__init__.py +40 -0
- ontolith-1.0.0/src/ontolith/plugins/manifest.py +79 -0
- ontolith-1.0.0/src/ontolith/plugins/ports.py +148 -0
- ontolith-1.0.0/src/ontolith/plugins/reference/__init__.py +33 -0
- ontolith-1.0.0/src/ontolith/plugins/reference/csv_importer.py +159 -0
- ontolith-1.0.0/src/ontolith/plugins/reference/json_exporter.py +56 -0
- ontolith-1.0.0/src/ontolith/plugins/reference/rdf_exporter.py +172 -0
- ontolith-1.0.0/src/ontolith/plugins/reference/required_fields_validator.py +103 -0
- ontolith-1.0.0/src/ontolith/plugins/registry.py +476 -0
- ontolith-1.0.0/src/ontolith/plugins/sandbox/__init__.py +18 -0
- ontolith-1.0.0/src/ontolith/plugins/sandbox/enforcement.py +417 -0
- ontolith-1.0.0/src/ontolith/plugins/sandbox/protocol.py +151 -0
- ontolith-1.0.0/src/ontolith/plugins/sandbox/remote_view.py +175 -0
- ontolith-1.0.0/src/ontolith/plugins/sandbox/runner.py +769 -0
- ontolith-1.0.0/src/ontolith/plugins/sandbox/wire.py +369 -0
- ontolith-1.0.0/src/ontolith/plugins/views.py +150 -0
- ontolith-1.0.0/src/ontolith/py.typed +0 -0
- ontolith-1.0.0/src/ontolith/query/__init__.py +9 -0
- ontolith-1.0.0/src/ontolith/query/builder.py +578 -0
- ontolith-1.0.0/src/ontolith/schema/__init__.py +58 -0
- ontolith-1.0.0/src/ontolith/schema/dsl.py +425 -0
- ontolith-1.0.0/src/ontolith/schema/ir.py +228 -0
- ontolith-1.0.0/src/ontolith/schema/linkml.py +367 -0
- ontolith-1.0.0/src/ontolith/schema/rdf.py +245 -0
- ontolith-1.0.0/src/ontolith/store/__init__.py +5 -0
- ontolith-1.0.0/src/ontolith/store/base.py +926 -0
- ontolith-1.0.0/src/ontolith/store/duckdb/__init__.py +11 -0
- ontolith-1.0.0/src/ontolith/store/duckdb/backend.py +2279 -0
- ontolith-1.0.0/src/ontolith/store/duckdb/migrations.py +430 -0
- ontolith-1.0.0/src/ontolith/store/migrations.py +72 -0
- ontolith-1.0.0/src/ontolith/store/sqlite/__init__.py +9 -0
- ontolith-1.0.0/src/ontolith/store/sqlite/backend.py +2549 -0
- ontolith-1.0.0/src/ontolith/store/sqlite/migrations.py +462 -0
- ontolith-1.0.0/tests/__init__.py +0 -0
- ontolith-1.0.0/tests/benchmarks/__init__.py +0 -0
- ontolith-1.0.0/tests/benchmarks/conftest.py +78 -0
- ontolith-1.0.0/tests/benchmarks/test_hybrid_query.py +449 -0
- ontolith-1.0.0/tests/benchmarks/test_traversal.py +378 -0
- ontolith-1.0.0/tests/contract/__init__.py +0 -0
- ontolith-1.0.0/tests/fixtures/plugins/__init__.py +6 -0
- ontolith-1.0.0/tests/fixtures/plugins/broken_bad_manifest.py +5 -0
- ontolith-1.0.0/tests/fixtures/plugins/broken_no_manifest.py +5 -0
- ontolith-1.0.0/tests/fixtures/plugins/broken_raises_on_init.py +10 -0
- ontolith-1.0.0/tests/fixtures/plugins/trivial_importer.py +15 -0
- ontolith-1.0.0/tests/fixtures/plugins/trivial_importer_filesystem_only.py +17 -0
- ontolith-1.0.0/tests/fixtures/plugins/trivial_importer_network_and_filesystem.py +16 -0
- ontolith-1.0.0/tests/fixtures/plugins/trivial_importer_network_only.py +17 -0
- ontolith-1.0.0/tests/fixtures/plugins/trivial_reasoner_default_caps.py +11 -0
- ontolith-1.0.0/tests/fixtures/plugins/trivial_validator.py +20 -0
- ontolith-1.0.0/tests/golden/__init__.py +0 -0
- ontolith-1.0.0/tests/golden/test_classes_ir_yaml_roundtrip.py +32 -0
- ontolith-1.0.0/tests/golden/test_schema_yaml_roundtrip.py +144 -0
- ontolith-1.0.0/tests/integration/__init__.py +0 -0
- ontolith-1.0.0/tests/property/__init__.py +0 -0
- ontolith-1.0.0/tests/property/test_embedder_properties.py +44 -0
- ontolith-1.0.0/tests/unit/__init__.py +0 -0
- ontolith-1.0.0/tests/unit/test_cli.py +2655 -0
- ontolith-1.0.0/tests/unit/test_contradiction.py +66 -0
- ontolith-1.0.0/tests/unit/test_core.py +175 -0
- ontolith-1.0.0/tests/unit/test_cross_interface_error_codes.py +311 -0
- ontolith-1.0.0/tests/unit/test_duckdb_backend.py +2542 -0
- ontolith-1.0.0/tests/unit/test_embedder.py +72 -0
- ontolith-1.0.0/tests/unit/test_govern.py +1071 -0
- ontolith-1.0.0/tests/unit/test_graphql.py +2024 -0
- ontolith-1.0.0/tests/unit/test_identity.py +224 -0
- ontolith-1.0.0/tests/unit/test_mcp_server.py +2480 -0
- ontolith-1.0.0/tests/unit/test_models.py +202 -0
- ontolith-1.0.0/tests/unit/test_observability.py +177 -0
- ontolith-1.0.0/tests/unit/test_ontology.py +1353 -0
- ontolith-1.0.0/tests/unit/test_ontology_validators.py +490 -0
- ontolith-1.0.0/tests/unit/test_plugin_isolation_conformance.py +103 -0
- ontolith-1.0.0/tests/unit/test_plugin_manifest.py +61 -0
- ontolith-1.0.0/tests/unit/test_plugin_registry.py +617 -0
- ontolith-1.0.0/tests/unit/test_plugin_sandbox.py +1288 -0
- ontolith-1.0.0/tests/unit/test_plugin_views.py +142 -0
- ontolith-1.0.0/tests/unit/test_principal.py +154 -0
- ontolith-1.0.0/tests/unit/test_principal_trust_immutability_invariant.py +40 -0
- ontolith-1.0.0/tests/unit/test_public_api_surface.py +298 -0
- ontolith-1.0.0/tests/unit/test_query.py +1153 -0
- ontolith-1.0.0/tests/unit/test_reference_csv_importer.py +206 -0
- ontolith-1.0.0/tests/unit/test_reference_json_exporter.py +84 -0
- ontolith-1.0.0/tests/unit/test_reference_plugins_registration.py +143 -0
- ontolith-1.0.0/tests/unit/test_reference_rdf_exporter.py +259 -0
- ontolith-1.0.0/tests/unit/test_reference_required_fields_validator.py +173 -0
- ontolith-1.0.0/tests/unit/test_rest.py +2537 -0
- ontolith-1.0.0/tests/unit/test_retract_contradiction_capability_floor.py +215 -0
- ontolith-1.0.0/tests/unit/test_schema_codegen.py +152 -0
- ontolith-1.0.0/tests/unit/test_schema_dsl.py +174 -0
- ontolith-1.0.0/tests/unit/test_schema_ir.py +358 -0
- ontolith-1.0.0/tests/unit/test_schema_linkml.py +549 -0
- ontolith-1.0.0/tests/unit/test_schema_rdf.py +388 -0
- ontolith-1.0.0/tests/unit/test_sqlite_backend.py +2604 -0
- ontolith-1.0.0/tests/unit/test_storage_migrations.py +1202 -0
- ontolith-1.0.0/uv.lock +2852 -0
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
|
|
9
|
+
# Least privilege (security review finding, M4 Workstream 7): none of this
|
|
10
|
+
# workflow's jobs write to the repo, comment on PRs, or otherwise need more
|
|
11
|
+
# than read access — checkout, running tests/lint/benchmarks, and uploading
|
|
12
|
+
# to codecov.io (no token; codecov-action doesn't need repo write access to
|
|
13
|
+
# do that) all only need contents: read. security.yml already scopes itself
|
|
14
|
+
# the same way, for the same reason.
|
|
15
|
+
permissions:
|
|
16
|
+
contents: read
|
|
17
|
+
|
|
18
|
+
jobs:
|
|
19
|
+
quality:
|
|
20
|
+
name: Code Quality
|
|
21
|
+
runs-on: ubuntu-latest
|
|
22
|
+
strategy:
|
|
23
|
+
matrix:
|
|
24
|
+
python-version: ["3.11", "3.12", "3.13"]
|
|
25
|
+
|
|
26
|
+
steps:
|
|
27
|
+
- uses: actions/checkout@v4
|
|
28
|
+
with:
|
|
29
|
+
# Full history so the griffe-diff step below can resolve the PR's
|
|
30
|
+
# base ref (KI-020) — same reason commitlint's checkout does this.
|
|
31
|
+
fetch-depth: 0
|
|
32
|
+
|
|
33
|
+
- name: Install uv
|
|
34
|
+
uses: astral-sh/setup-uv@v3
|
|
35
|
+
with:
|
|
36
|
+
enable-cache: true
|
|
37
|
+
|
|
38
|
+
- name: Set up Python ${{ matrix.python-version }}
|
|
39
|
+
run: uv python install ${{ matrix.python-version }}
|
|
40
|
+
|
|
41
|
+
- name: Install dependencies
|
|
42
|
+
run: uv sync --all-extras
|
|
43
|
+
|
|
44
|
+
- name: Format check
|
|
45
|
+
run: uv run ruff format --check
|
|
46
|
+
|
|
47
|
+
- name: Lint
|
|
48
|
+
run: uv run ruff check
|
|
49
|
+
|
|
50
|
+
- name: Type check
|
|
51
|
+
run: uv run mypy --strict src conformance/conftest.py
|
|
52
|
+
|
|
53
|
+
- name: Dependency rule check
|
|
54
|
+
run: uv run lint-imports
|
|
55
|
+
|
|
56
|
+
- name: Docstring coverage
|
|
57
|
+
run: uv run interrogate src/ontolith -c pyproject.toml
|
|
58
|
+
|
|
59
|
+
- name: Public API surface diff (KI-020)
|
|
60
|
+
if: matrix.python-version == '3.12'
|
|
61
|
+
# Blocking as of the 1.0 tag (Implementation Plan §5's "warn pre-1.0,
|
|
62
|
+
# block post-1.0"). This is NOT a required status check in the repo's
|
|
63
|
+
# branch ruleset (checked directly: only deletion, non_fast_forward,
|
|
64
|
+
# pull_request, code_quality, and code_scanning rules exist — no
|
|
65
|
+
# required_status_checks rule) — "blocking" here means a visible red
|
|
66
|
+
# CI failure a reviewer sees and must knowingly merge past, the same
|
|
67
|
+
# as any other job in this workflow, not a structural merge block.
|
|
68
|
+
#
|
|
69
|
+
# Griffe checks a module's `__all__` members if it has one, else its
|
|
70
|
+
# non-underscore/non-imported names — NOT "every non-underscore
|
|
71
|
+
# module-level function" (an earlier version of this comment claimed
|
|
72
|
+
# that; wrong, see below). A pure addition to `__all__` exits 0
|
|
73
|
+
# (confirmed). But it does NOT follow that only a genuine breaking
|
|
74
|
+
# change exits 1 — a still-earlier draft claimed that too, also
|
|
75
|
+
# wrong: griffe's breakage detector (`find_breaking_changes`) flags
|
|
76
|
+
# a public attribute's value TEXT changing even when semantically
|
|
77
|
+
# identical (confirmed: reordering `frozenset({"entity",
|
|
78
|
+
# "assertion"})` to `frozenset({"assertion", "entity"})` in
|
|
79
|
+
# store/base.py — same set, exit 1, "Attribute value was changed"),
|
|
80
|
+
# and a signature change on any name actually listed in its own
|
|
81
|
+
# module's `__all__` (or re-exported via another module's `__all__`
|
|
82
|
+
# — griffe follows the alias), even one this project's own ADR-0019
|
|
83
|
+
# doesn't consider part of the 13-package public surface (confirmed:
|
|
84
|
+
# adding a required parameter to plugins/sandbox/wire.py's
|
|
85
|
+
# restricted_loads, listed in that module's own `__all__` but not
|
|
86
|
+
# ADR-0019's — exit 1). A signature change on a name NOT listed in
|
|
87
|
+
# its own (or any re-exporting) module's `__all__` does NOT trip it
|
|
88
|
+
# (confirmed: same edit on cli.py's db_status, absent from cli.py's
|
|
89
|
+
# own `__all__ = ["app"]` and never re-exported — exit 0) — nothing
|
|
90
|
+
# catches this case, which is intended: `ontolith.interfaces.cli` is
|
|
91
|
+
# deliberately outside ADR-0019's SDK surface, and
|
|
92
|
+
# `test_public_api_surface.py`'s own docstring says plainly it does
|
|
93
|
+
# NOT catch signature-level changes at all, only export
|
|
94
|
+
# additions/removals/renames within the 13 packages it pins.
|
|
95
|
+
# Removing something from `__all__` alone, with the import kept,
|
|
96
|
+
# also doesn't trip this step (confirmed: exit 0) — for one of the
|
|
97
|
+
# 13 ADR-0019-pinned packages, `test_public_api_surface.py`'s own
|
|
98
|
+
# pinned `_EXPECTED` dict catches that instead; for `wire.py` or any
|
|
99
|
+
# other unpinned module, nothing catches it, same as the
|
|
100
|
+
# signature-change case above. Expect this gate to occasionally flag
|
|
101
|
+
# a cosmetic or internal-but-`__all__`-listed change as a false
|
|
102
|
+
# positive; that's a known, accepted cost of blocking it, not a bug
|
|
103
|
+
# in this workflow.
|
|
104
|
+
# Compares against the PR's base commit; on a push-to-main run (no
|
|
105
|
+
# PR context) compares against HEAD itself, i.e. a no-op — the
|
|
106
|
+
# meaningful comparison already happened during the PR's own run.
|
|
107
|
+
env:
|
|
108
|
+
BASE_REF: ${{ github.event.pull_request.base.sha || 'HEAD' }}
|
|
109
|
+
run: uv run python -m griffe check ontolith -s src -a "$BASE_REF" -f github
|
|
110
|
+
|
|
111
|
+
commitlint:
|
|
112
|
+
name: Commit message format
|
|
113
|
+
runs-on: ubuntu-latest
|
|
114
|
+
if: github.event_name == 'pull_request'
|
|
115
|
+
|
|
116
|
+
steps:
|
|
117
|
+
- uses: actions/checkout@v4
|
|
118
|
+
with:
|
|
119
|
+
fetch-depth: 0
|
|
120
|
+
|
|
121
|
+
- name: Validate Conventional Commits format
|
|
122
|
+
env:
|
|
123
|
+
BASE_SHA: ${{ github.event.pull_request.base.sha }}
|
|
124
|
+
HEAD_SHA: ${{ github.event.pull_request.head.sha }}
|
|
125
|
+
run: |
|
|
126
|
+
pattern='^(feat|fix|docs|test|refactor|chore|perf|ci)(\([a-zA-Z0-9_-]+\))?: .+'
|
|
127
|
+
failed=0
|
|
128
|
+
while IFS= read -r line; do
|
|
129
|
+
sha="${line%% *}"
|
|
130
|
+
subject="${line#* }"
|
|
131
|
+
if [[ ! "$subject" =~ $pattern ]]; then
|
|
132
|
+
echo "::error::Commit $sha does not follow Conventional Commits: $subject"
|
|
133
|
+
failed=1
|
|
134
|
+
fi
|
|
135
|
+
done < <(git log --no-merges --format='%H %s' "$BASE_SHA..$HEAD_SHA")
|
|
136
|
+
exit $failed
|
|
137
|
+
|
|
138
|
+
test:
|
|
139
|
+
name: Tests
|
|
140
|
+
runs-on: ${{ matrix.os }}
|
|
141
|
+
strategy:
|
|
142
|
+
matrix:
|
|
143
|
+
os: [ubuntu-latest, macos-latest, windows-latest]
|
|
144
|
+
python-version: ["3.11", "3.12", "3.13"]
|
|
145
|
+
|
|
146
|
+
steps:
|
|
147
|
+
- uses: actions/checkout@v4
|
|
148
|
+
|
|
149
|
+
- name: Install libseccomp (Linux only — ADR-0051 plugin sandbox enforcement)
|
|
150
|
+
if: matrix.os == 'ubuntu-latest'
|
|
151
|
+
run: sudo apt-get update && sudo apt-get install -y libseccomp2
|
|
152
|
+
|
|
153
|
+
- name: Install uv
|
|
154
|
+
uses: astral-sh/setup-uv@v3
|
|
155
|
+
with:
|
|
156
|
+
enable-cache: true
|
|
157
|
+
|
|
158
|
+
- name: Set up Python ${{ matrix.python-version }}
|
|
159
|
+
run: uv python install ${{ matrix.python-version }}
|
|
160
|
+
|
|
161
|
+
- name: Install dependencies
|
|
162
|
+
run: uv sync --all-extras
|
|
163
|
+
|
|
164
|
+
- name: Run tests + conformance (combined coverage)
|
|
165
|
+
env:
|
|
166
|
+
HYPOTHESIS_PROFILE: ci
|
|
167
|
+
# Folded scalar (`>-`), not a `\`-continued literal block: this step
|
|
168
|
+
# runs on windows-latest too, whose default shell is PowerShell, which
|
|
169
|
+
# doesn't treat a trailing backslash as a line continuation and fails
|
|
170
|
+
# to parse the command (`Missing expression after unary operator
|
|
171
|
+
# '--'`). A folded scalar collapses to one line, valid in every shell.
|
|
172
|
+
run: >-
|
|
173
|
+
uv run pytest tests/ conformance/
|
|
174
|
+
--cov=src/ontolith --cov-report=xml --cov-report=term
|
|
175
|
+
--cov-fail-under=90
|
|
176
|
+
|
|
177
|
+
- name: Upload coverage
|
|
178
|
+
if: matrix.os == 'ubuntu-latest' && matrix.python-version == '3.12'
|
|
179
|
+
uses: codecov/codecov-action@v4
|
|
180
|
+
with:
|
|
181
|
+
files: ./coverage.xml
|
|
182
|
+
fail_ci_if_error: false
|
|
183
|
+
|
|
184
|
+
- name: Run quickstart example
|
|
185
|
+
if: matrix.os == 'ubuntu-latest' && matrix.python-version == '3.12'
|
|
186
|
+
run: uv run python examples/quickstart.py
|
|
187
|
+
|
|
188
|
+
benchmarks:
|
|
189
|
+
# M4 Workstream 1 exit gate: the 5 SPEC §9 budget rows are enforced as
|
|
190
|
+
# hard per-test ceilings inside tests/benchmarks/ itself (see
|
|
191
|
+
# tests/benchmarks/conftest.py's assert_within_budget) — this job is
|
|
192
|
+
# blocking (no continue-on-error, runs on every PR, not just pushes to
|
|
193
|
+
# main) precisely because those assertions, not this job definition,
|
|
194
|
+
# are what fails a genuine regression.
|
|
195
|
+
name: Benchmarks (§9 budgets)
|
|
196
|
+
runs-on: ubuntu-latest
|
|
197
|
+
|
|
198
|
+
steps:
|
|
199
|
+
- uses: actions/checkout@v4
|
|
200
|
+
|
|
201
|
+
- name: Install uv
|
|
202
|
+
uses: astral-sh/setup-uv@v3
|
|
203
|
+
with:
|
|
204
|
+
enable-cache: true
|
|
205
|
+
|
|
206
|
+
- name: Set up Python
|
|
207
|
+
run: uv python install 3.12
|
|
208
|
+
|
|
209
|
+
- name: Install dependencies
|
|
210
|
+
run: uv sync --all-extras
|
|
211
|
+
|
|
212
|
+
- name: Run benchmarks
|
|
213
|
+
run: uv run pytest tests/benchmarks/ --benchmark-only --benchmark-json=benchmark-results.json -q
|
|
214
|
+
|
|
215
|
+
- name: Upload benchmark results
|
|
216
|
+
if: always()
|
|
217
|
+
uses: actions/upload-artifact@v4
|
|
218
|
+
with:
|
|
219
|
+
name: benchmark-results
|
|
220
|
+
path: benchmark-results.json
|
|
221
|
+
overwrite: true
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
name: Security
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
pull_request:
|
|
5
|
+
branches: [main]
|
|
6
|
+
schedule:
|
|
7
|
+
# Weekly, independent of PR activity — catches newly-disclosed CVEs in
|
|
8
|
+
# already-merged dependencies (Implementation Plan §7.1).
|
|
9
|
+
- cron: "0 6 * * 1"
|
|
10
|
+
|
|
11
|
+
permissions:
|
|
12
|
+
contents: read
|
|
13
|
+
|
|
14
|
+
jobs:
|
|
15
|
+
# pip-audit, bandit, and SBOM generation share one checkout + `uv sync`
|
|
16
|
+
# instead of three, to cut per-PR Actions-minute usage on this repo's
|
|
17
|
+
# private-repo minute allotment (this workflow otherwise roughly doubles
|
|
18
|
+
# security.yml's total runner time for no benefit — none of the three
|
|
19
|
+
# steps depend on each other's output, they're just sharing setup cost).
|
|
20
|
+
scan:
|
|
21
|
+
name: Dependency + static security scan
|
|
22
|
+
runs-on: ubuntu-latest
|
|
23
|
+
|
|
24
|
+
steps:
|
|
25
|
+
- uses: actions/checkout@v4
|
|
26
|
+
|
|
27
|
+
- name: Install uv
|
|
28
|
+
uses: astral-sh/setup-uv@v3
|
|
29
|
+
with:
|
|
30
|
+
enable-cache: true
|
|
31
|
+
|
|
32
|
+
- name: Set up Python
|
|
33
|
+
run: uv python install 3.12
|
|
34
|
+
|
|
35
|
+
- name: Install dependencies
|
|
36
|
+
run: uv sync --all-extras
|
|
37
|
+
|
|
38
|
+
- name: Run pip-audit
|
|
39
|
+
run: uv run pip-audit
|
|
40
|
+
|
|
41
|
+
# `if: always()` below: these three steps are otherwise independent of
|
|
42
|
+
# pip-audit's outcome, but without it a pip-audit failure silently
|
|
43
|
+
# skips bandit/SBOM for the rest of the job (a real incident — a
|
|
44
|
+
# newly-disclosed transitive-dependency CVE masked two genuine bandit
|
|
45
|
+
# findings for a full PR before anyone noticed bandit hadn't actually
|
|
46
|
+
# run). The job still fails overall if any step fails; this only
|
|
47
|
+
# ensures every step gets a chance to report its own result.
|
|
48
|
+
- name: Run bandit
|
|
49
|
+
if: always()
|
|
50
|
+
run: uv run bandit -r src/ontolith -c pyproject.toml
|
|
51
|
+
|
|
52
|
+
- name: Generate SBOM
|
|
53
|
+
if: always()
|
|
54
|
+
run: uv run cyclonedx-py environment --pyproject pyproject.toml -o sbom.json
|
|
55
|
+
|
|
56
|
+
- name: Upload SBOM
|
|
57
|
+
if: always()
|
|
58
|
+
uses: actions/upload-artifact@v4
|
|
59
|
+
with:
|
|
60
|
+
name: sbom
|
|
61
|
+
path: sbom.json
|
|
62
|
+
|
|
63
|
+
gitleaks:
|
|
64
|
+
name: Secret scanning (gitleaks)
|
|
65
|
+
runs-on: ubuntu-latest
|
|
66
|
+
|
|
67
|
+
steps:
|
|
68
|
+
- uses: actions/checkout@v4
|
|
69
|
+
with:
|
|
70
|
+
fetch-depth: 0
|
|
71
|
+
|
|
72
|
+
- name: Run gitleaks
|
|
73
|
+
uses: gitleaks/gitleaks-action@v3
|
|
74
|
+
env:
|
|
75
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
76
|
+
# This repo is private under a personal account (not an
|
|
77
|
+
# organization) — gitleaks-action's license requirement is gated
|
|
78
|
+
# on org vs. personal account, not public vs. private repo
|
|
79
|
+
# visibility, so no GITLEAKS_LICENSE is needed here. That would
|
|
80
|
+
# change if this repo ever moved under an organization.
|
|
81
|
+
#
|
|
82
|
+
# PR comments disabled so this job only needs the default
|
|
83
|
+
# read-only GITHUB_TOKEN (workflow permissions: contents: read,
|
|
84
|
+
# above) rather than pull-requests: write — findings still surface
|
|
85
|
+
# via the job's own log/summary output.
|
|
86
|
+
GITLEAKS_ENABLE_COMMENTS: false
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# Claude Code configuration (maintainer-only)
|
|
2
|
+
.claude/
|
|
3
|
+
|
|
4
|
+
# Python
|
|
5
|
+
__pycache__/
|
|
6
|
+
*.py[cod]
|
|
7
|
+
*$py.class
|
|
8
|
+
*.so
|
|
9
|
+
.Python
|
|
10
|
+
build/
|
|
11
|
+
develop-eggs/
|
|
12
|
+
dist/
|
|
13
|
+
downloads/
|
|
14
|
+
eggs/
|
|
15
|
+
.eggs/
|
|
16
|
+
lib/
|
|
17
|
+
lib64/
|
|
18
|
+
parts/
|
|
19
|
+
sdist/
|
|
20
|
+
var/
|
|
21
|
+
wheels/
|
|
22
|
+
*.egg-info/
|
|
23
|
+
.installed.cfg
|
|
24
|
+
*.egg
|
|
25
|
+
|
|
26
|
+
# Virtual environments
|
|
27
|
+
venv/
|
|
28
|
+
ENV/
|
|
29
|
+
env/
|
|
30
|
+
|
|
31
|
+
# Testing
|
|
32
|
+
.pytest_cache/
|
|
33
|
+
.coverage
|
|
34
|
+
htmlcov/
|
|
35
|
+
.hypothesis/
|
|
36
|
+
|
|
37
|
+
# IDEs
|
|
38
|
+
.vscode/
|
|
39
|
+
.idea/
|
|
40
|
+
*.swp
|
|
41
|
+
*.swo
|
|
42
|
+
*~
|
|
43
|
+
|
|
44
|
+
# OS
|
|
45
|
+
.DS_Store
|
|
46
|
+
Thumbs.db
|
|
47
|
+
|
|
48
|
+
# Project specific
|
|
49
|
+
*.db
|
|
50
|
+
*.sqlite
|
|
51
|
+
*.sqlite3
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
repos:
|
|
2
|
+
- repo: https://github.com/pre-commit/pre-commit-hooks
|
|
3
|
+
rev: v4.5.0
|
|
4
|
+
hooks:
|
|
5
|
+
- id: trailing-whitespace
|
|
6
|
+
- id: end-of-file-fixer
|
|
7
|
+
- id: check-yaml
|
|
8
|
+
- id: check-added-large-files
|
|
9
|
+
- id: check-merge-conflict
|
|
10
|
+
|
|
11
|
+
- repo: https://github.com/astral-sh/ruff-pre-commit
|
|
12
|
+
rev: v0.2.2
|
|
13
|
+
hooks:
|
|
14
|
+
- id: ruff
|
|
15
|
+
args: [--fix]
|
|
16
|
+
- id: ruff-format
|
|
17
|
+
|
|
18
|
+
- repo: https://github.com/pre-commit/mirrors-mypy
|
|
19
|
+
rev: v1.8.0
|
|
20
|
+
hooks:
|
|
21
|
+
- id: mypy
|
|
22
|
+
args: [--strict, --ignore-missing-imports]
|
|
23
|
+
additional_dependencies: [pydantic>=2.0, python-ulid>=2.0]
|
|
24
|
+
files: ^(src/|conformance/conftest\.py$)
|