{"id":50454114,"url":"https://github.com/mizcausevic-dev/policy-as-code-engine","last_synced_at":"2026-06-01T01:05:39.825Z","repository":{"id":358552091,"uuid":"1239242692","full_name":"mizcausevic-dev/policy-as-code-engine","owner":"mizcausevic-dev","description":"Declarative policy-as-code evaluator. JSON/YAML rules over Python contexts. Turns AI Procurement Decision Cards into runtime-enforceable PolicyBundles.","archived":false,"fork":false,"pushed_at":"2026-05-15T17:13:45.000Z","size":30,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-18T00:18:43.713Z","etag":null,"topics":["ai-governance","decision-intelligence","fastapi","kinetic-gain-protocol-suite","policy-as-code","pydantic","python","rules-engine"],"latest_commit_sha":null,"homepage":"https://kineticgain.com/","language":"Python","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/mizcausevic-dev.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"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-05-14T22:48:17.000Z","updated_at":"2026-05-15T16:08:11.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/mizcausevic-dev/policy-as-code-engine","commit_stats":null,"previous_names":["mizcausevic-dev/policy-as-code-engine"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/mizcausevic-dev/policy-as-code-engine","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mizcausevic-dev%2Fpolicy-as-code-engine","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mizcausevic-dev%2Fpolicy-as-code-engine/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mizcausevic-dev%2Fpolicy-as-code-engine/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mizcausevic-dev%2Fpolicy-as-code-engine/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mizcausevic-dev","download_url":"https://codeload.github.com/mizcausevic-dev/policy-as-code-engine/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mizcausevic-dev%2Fpolicy-as-code-engine/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33755379,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-05-31T02:00:06.040Z","response_time":95,"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-governance","decision-intelligence","fastapi","kinetic-gain-protocol-suite","policy-as-code","pydantic","python","rules-engine"],"created_at":"2026-06-01T01:05:39.762Z","updated_at":"2026-06-01T01:05:39.820Z","avatar_url":"https://github.com/mizcausevic-dev.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# policy-as-code-engine\n\n[![CI](https://github.com/mizcausevic-dev/policy-as-code-engine/actions/workflows/ci.yml/badge.svg)](https://github.com/mizcausevic-dev/policy-as-code-engine/actions/workflows/ci.yml)\n[![Python](https://img.shields.io/badge/python-3.11%20%7C%203.12%20%7C%203.13-blue)](https://www.python.org/)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)\n\n**Declarative policy-as-code evaluator for Python services.** JSON/YAML rules → first-match-wins evaluation → structured allow/deny decision with the matching rule and the reason. Cheap to embed; ships with a FastAPI surface; **pairs directly with [`procurement-decision-api`](https://github.com/mizcausevic-dev/procurement-decision-api)** so the same Decision Card that records a buyer's posture also becomes the runtime gate that enforces it.\n\n---\n\n## Why\n\nMost policy engines either ask you to learn a DSL (Rego, Cedar) or hand you a dictionary-of-lambdas and call it a library. Neither is the right shape when the *source of truth* is a JSON document a human signed off on. This engine:\n\n1. **Reads JSON/YAML bundles.** No DSL. The matcher tree is the policy.\n2. **Returns *why*, not just *what*.** Every decision carries the matched policy + rule + reason. Operators get a real audit log on each evaluation.\n3. **Bridges to the Kinetic Gain Protocol Suite.** A single endpoint turns an AI Procurement Decision Card into a runtime-enforceable `PolicyBundle` — approve, reject, or approve-with-conditions all map to concrete allow/deny logic.\n\n---\n\n## Install\n\n```bash\npip install policy-as-code-engine\n# with the FastAPI surface:\npip install \"policy-as-code-engine[api]\"\n```\n\nPython 3.11+. Runtime deps: `pydantic` + `PyYAML`.\n\n---\n\n## Library quickstart\n\n```python\nfrom policy_as_code_engine import (\n    EvaluationContext,\n    PolicyBundle,\n    PolicyEvaluator,\n)\n\nbundle = PolicyBundle.model_validate({\n    \"bundle_id\": \"edu-gate\",\n    \"policies\": [{\n        \"id\": \"writes-require-admin\",\n        \"default_effect\": \"deny\",\n        \"rules\": [\n            {\n                \"id\": \"admin-writes\",\n                \"effect\": \"allow\",\n                \"when\": {\n                    \"kind\": \"all_of\",\n                    \"matchers\": [\n                        {\"kind\": \"in\", \"field\": \"action\", \"value\": [\"create\", \"update\", \"delete\"]},\n                        {\"kind\": \"eq\", \"field\": \"subject.role\", \"value\": \"admin\"},\n                    ],\n                },\n            },\n        ],\n    }],\n})\n\nctx = EvaluationContext(\n    subject={\"id\": \"u-42\", \"role\": \"admin\"},\n    action=\"update\",\n    resource={\"id\": \"doc-7\"},\n)\n\nresult = PolicyEvaluator().evaluate(bundle, ctx)\nprint(result.decision.kind)             # \"allow\"\nprint(result.decision.matched_rule_id)  # \"admin-writes\"\nprint(result.decision.reason)           # \"matched rule 'admin-writes'\"\n```\n\n`result.policy_decisions` carries every per-policy outcome — drop it straight into your audit log.\n\n---\n\n## Bundle DSL\n\nA bundle is a small recursive structure. Matchers compose; rules ordered.\n\n### Field matchers\n\n| Kind            | Notes |\n| --------------- | --- |\n| `eq` / `ne`     | Strict equality. |\n| `gt` / `gte` / `lt` / `lte` | Comparison; returns `false` on incompatible types (won't raise). |\n| `in` / `not_in` | `value` must be a list. |\n| `contains`      | Works against strings, lists, sets, dicts. |\n| `exists` / `missing` | No `value`. Operates against the dotted-path resolver. |\n| `regex`         | Compiled patterns are cached per-evaluator. |\n| `starts_with` / `ends_with` | String-only. |\n\n### Composite matchers\n\n| Kind     | Children | Truth |\n| -------- | -------- | --- |\n| `all_of` | `matchers: [...]` | All children true. |\n| `any_of` | `matchers: [...]` | At least one child true. |\n| `not`    | `matcher: {...}`  | Inverts the child. |\n| `always` | —                 | Always true. Useful as a final catch-all. |\n\n### Dotted paths\n\nThe resolver looks at the merged context (`data` + `subject` + `action` + `resource`):\n\n```\nsubject.role\nresource.tags.0          # list index\ndata.conditions_satisfied.dpa-signed\n```\n\nMissing segments produce a `_MISSING` sentinel — `exists` / `missing` matchers see it; every other matcher returns `false`.\n\n---\n\n## FastAPI surface\n\n```bash\npip install \"policy-as-code-engine[api]\"\npython -m policy_as_code_engine     # binds 0.0.0.0:8089 by default\n```\n\n| Method | Path | What it does |\n| --- | --- | --- |\n| GET | `/healthz` | Liveness probe. |\n| GET | `/` | Service info. |\n| POST | `/bundles` | Register a `PolicyBundle` in memory. |\n| GET | `/bundles` | List registered bundle IDs. |\n| GET | `/bundles/{bundle_id}` | Inspect a registered bundle. |\n| POST | `/bundles/{bundle_id}/evaluate` | Evaluate a stored bundle against an `EvaluationContext`. |\n| POST | `/evaluate` | One-shot. Bundle + context in, decision out. |\n| POST | `/bundles/from-decision-card` | **The cross-ecosystem hook.** Turn a Kinetic Gain Procurement Decision Card into a `PolicyBundle` and register it. |\n\n---\n\n## The cross-ecosystem hook\n\nThe headline feature. An AI Procurement Decision Card is the buyer-side record that says \"we evaluated this vendor and our position is X.\" This engine turns that human-authored artifact into a runtime gate, mechanically.\n\n```bash\ncurl -X POST http://localhost:8089/bundles/from-decision-card \\\n  -H 'Content-Type: application/json' \\\n  -d @decision-card.json\n```\n\nMapping:\n\n| Decision Card status | Resulting bundle |\n| --- | --- |\n| `approved` | Single `allow-all` policy. |\n| `rejected` · `rejected-with-remediation` · `withdrawn` · `expired` · `pending` | Single `deny-all` policy (fail safe). |\n| `approved-with-conditions` | One policy *per* condition. Each policy `allow`s only when `conditions_satisfied.{condition_id}` is `true` in the evaluation context; `deny` otherwise. The bundle combiner does deny-trumps-allow, so **every** condition must be satisfied to allow. |\n\nWire your own satisfaction signal — DPA verifier, bias-audit freshness check, attestation timestamp — into the context, and the bundle does the rest.\n\n```python\nfrom policy_as_code_engine import (\n    EvaluationContext,\n    PolicyEvaluator,\n    policy_bundle_from_decision_card,\n)\n\ncard = {...}  # POST /decisions/draft output from procurement-decision-api\nbundle = policy_bundle_from_decision_card(card)\n\nctx = EvaluationContext(\n    subject={\"id\": \"u-1\"},\n    action=\"enroll\",\n    data={\n        \"conditions_satisfied\": {\n            \"dpa-signed\":         True,\n            \"bias-audit-fresh\":   True,\n        }\n    },\n)\n\ndecision = PolicyEvaluator().evaluate(bundle, ctx).decision\n```\n\n---\n\n## CLI\n\n```bash\npython -m policy_as_code_engine eval examples/example-bundle.yaml examples/example-context.json\n```\n\nPrints the full `EvaluationResult` as JSON. Exits non-zero on `deny`.\n\n---\n\n## How decisions combine\n\nInside a single policy: **first matching rule wins**, otherwise `default_effect`.\n\nAcross the bundle:\n\n```\ndeny     -\u003e deny      (any policy denies =\u003e bundle denies)\nallow    -\u003e allow     (otherwise, any allow =\u003e bundle allows)\nneither  -\u003e not_applicable\n```\n\nPer-policy decisions are always returned — useful for \"we denied because of policy B, but A would have allowed\" audit narratives.\n\n---\n\n## Tests\n\n```bash\npip install -e \".[dev]\"\nruff check src tests \u0026\u0026 ruff format --check src tests\nmypy src\npytest -v\n```\n\nCI matrix runs Python 3.11 / 3.12 / 3.13.\n\n---\n\n## Related in this ecosystem\n\n- **[procurement-decision-api](https://github.com/mizcausevic-dev/procurement-decision-api)** — drafts the Decision Cards that this engine enforces.\n- **[ai-procurement-decision-spec](https://github.com/mizcausevic-dev/ai-procurement-decision-spec)** — the v0.1 schema.\n- **[slo-budget-tracker](https://github.com/mizcausevic-dev/slo-budget-tracker)** — error-budget tracker that you can wire into the same FastAPI app.\n- **[reliability-toolkit-rs](https://github.com/mizcausevic-dev/reliability-toolkit-rs)** — Rust async reliability primitives.\n- More at [kineticgain.com](https://kineticgain.com/).\n\n---\n\n## License\n\nMIT. See [LICENSE](LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmizcausevic-dev%2Fpolicy-as-code-engine","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmizcausevic-dev%2Fpolicy-as-code-engine","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmizcausevic-dev%2Fpolicy-as-code-engine/lists"}