Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 64 additions & 0 deletions .github/workflows/qualify-track-c2-cognee-governance-exec.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
name: Qualify Track C2 Cognee Governance Executable
on:
workflow_dispatch:
pull_request:
branches: [main]
paths:
- '.github/workflows/qualify-track-c2-cognee-governance-exec.yml'
- 'tests/qualification/track-c2/specialists/cognee-governance-exec.py'
- 'tests/qualification/track-c2/specialists/verify-cognee-governance-exec.py'
permissions:
contents: read
jobs:
cognee-governance-executable:
runs-on: ubuntu-latest
timeout-minutes: 40
env:
REQUIRE_AUTHENTICATION: 'true'
ENABLE_BACKEND_ACCESS_CONTROL: 'true'
HASH_API_KEY: 'false'
FASTAPI_USERS_JWT_SECRET: 'yukh-qualification-only-secret'
DATA_ROOT_DIRECTORY: ${{ github.workspace }}/runtime/cognee/data
SYSTEM_ROOT_DIRECTORY: ${{ github.workspace }}/runtime/cognee/system
DB_PROVIDER: sqlite
DB_NAME: cognee_ov89
GRAPH_DATABASE_PROVIDER: kuzu
GRAPH_DATASET_DATABASE_HANDLER: kuzu
VECTOR_DB_PROVIDER: lancedb
VECTOR_DATASET_DATABASE_HANDLER: lancedb
LLM_API_KEY: qualification-not-used
steps:
- uses: actions/checkout@v7
with: {persist-credentials: false}
- uses: actions/checkout@v7
with:
repository: topoteretes/cognee
ref: 690c0ec023719a2a277dc893cdecfec1ca8012cc
path: external/cognee
persist-credentials: false
- uses: actions/setup-python@v6
with: {python-version: '3.12'}
- name: Install pinned Cognee
run: |
python -m pip install --upgrade pip
python -m pip install -e external/cognee
mkdir -p runtime/cognee/data runtime/cognee/system artifacts/track-c2-specialists
- name: A owns M and B is denied
run: python tests/qualification/track-c2/specialists/cognee-governance-exec.py setup artifacts/track-c2-specialists/cognee-state.json
- name: Explicit public grant to active B
run: python tests/qualification/track-c2/specialists/cognee-governance-exec.py grant artifacts/track-c2-specialists/cognee-state.json artifacts/track-c2-specialists/cognee-grant.json
- name: Explicit public revoke while A B M remain alive
run: python tests/qualification/track-c2/specialists/cognee-governance-exec.py revoke artifacts/track-c2-specialists/cognee-state.json artifacts/track-c2-specialists/cognee-revoke.json
- name: Fresh app process verifies persisted revoke
run: python tests/qualification/track-c2/specialists/cognee-governance-exec.py restart artifacts/track-c2-specialists/cognee-state.json artifacts/track-c2-specialists/cognee-restart.json
- name: Finalize normalized evidence
run: python tests/qualification/track-c2/specialists/cognee-governance-exec.py finalize artifacts/track-c2-specialists/cognee-state.json artifacts/track-c2-specialists/cognee-grant.json artifacts/track-c2-specialists/cognee-revoke.json artifacts/track-c2-specialists/cognee-restart.json artifacts/track-c2-specialists/cognee-governance-exec.json
- name: Verify COMPLEMENT_PASS
run: python tests/qualification/track-c2/specialists/verify-cognee-governance-exec.py artifacts/track-c2-specialists/cognee-governance-exec.json
- uses: actions/upload-artifact@v6
if: always()
with:
name: track-c2-cognee-governance-exec-690c0ec0
path: artifacts/track-c2-specialists
if-no-files-found: error
retention-days: 30
88 changes: 88 additions & 0 deletions tests/qualification/track-c2/specialists/cognee-governance-exec.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
#!/usr/bin/env python3
import json, sys
from pathlib import Path
from fastapi.testclient import TestClient
from cognee.api.client import app

PIN="690c0ec023719a2a277dc893cdecfec1ca8012cc"
DATASET_NAME="yukh-governance-m"
PASS="synthetic-password-OV89!"

def write(path,payload):
p=Path(path); p.parent.mkdir(parents=True,exist_ok=True); p.write_text(json.dumps(payload,indent=2,sort_keys=True)+"\n")

def register_and_key(c,email):
r=c.post("/api/v1/auth/register",json={"email":email,"password":PASS}); assert r.status_code in (201,400),r.text
r=c.post("/api/v1/auth/login",data={"username":email,"password":PASS}); assert r.status_code==200,r.text
token=r.json()["access_token"]
me=c.get("/api/v1/auth/me",headers={"Authorization":f"Bearer {token}"}); assert me.status_code==200,me.text
key=c.post("/api/v1/auth/api-keys",json={"name":"yukh-ov89"},headers={"Authorization":f"Bearer {token}"}); assert key.status_code==200,key.text
return me.json(),key.json()["key"]

def hdr(key): return {"X-Api-Key":key}

def visible_ids(c,key):
r=c.get("/api/v1/datasets",headers=hdr(key)); assert r.status_code==200,r.text
return {str(x["id"]):x for x in r.json()}

def setup(out):
with TestClient(app) as c:
# Use the same syntactically ordinary email domain as Cognee's pinned
# backend-auth integration test. The qualification remains fully synthetic.
a,ak=register_and_key(c,"ov89-alice@example.com")
b,bk=register_and_key(c,"ov89-bob@example.com")
aid=str(a["id"]); bid=str(b["id"])
tenants=c.get("/api/v1/permissions/tenants/me",headers=hdr(ak)); assert tenants.status_code==200,tenants.text
tlist=tenants.json(); assert tlist,tlist
tenant_id=str(tlist[0]["id"])
add=c.post(f"/api/v1/permissions/users/{bid}/tenants",params={"tenant_id":tenant_id},headers=hdr(ak)); assert add.status_code==200,add.text
sel=c.post("/api/v1/permissions/tenants/select",json={"tenant_id":tenant_id},headers=hdr(bk)); assert sel.status_code==200,sel.text
ds=c.post("/api/v1/datasets",json={"name":DATASET_NAME},headers=hdr(ak)); assert ds.status_code==200,ds.text
dataset=ds.json(); did=str(dataset["id"])
assert did in visible_ids(c,ak)
before=visible_ids(c,bk)
assert did not in before, f"B saw A dataset before grant: {before}"
write(out,{"pin":PIN,"alice_id":aid,"bob_id":bid,"alice_key":ak,"bob_key":bk,"tenant_id":tenant_id,"dataset_id":did,"dataset_name":DATASET_NAME,"a_visible_before":True,"b_denied_before":True})

def grant(state_path,out):
x=json.loads(Path(state_path).read_text())
with TestClient(app) as c:
g=c.post(f"/api/v1/permissions/datasets/{x['bob_id']}",params={"permission_name":"read"},json=[x["dataset_id"]],headers=hdr(x["alice_key"])); assert g.status_code==200,g.text
ids=visible_ids(c,x["bob_key"]); assert x["dataset_id"] in ids,ids
a=visible_ids(c,x["alice_key"]); assert x["dataset_id"] in a
write(out,{"pin":PIN,"grant_status":"public-api-success","b_reads_after_grant":True,"a_still_reads":True})

def revoke(state_path,out):
x=json.loads(Path(state_path).read_text())
with TestClient(app) as c:
r=c.request("DELETE",f"/api/v1/permissions/datasets/{x['bob_id']}",params={"permission_name":"read"},json=[x["dataset_id"]],headers=hdr(x["alice_key"])); assert r.status_code==200,r.text
ids=visible_ids(c,x["bob_key"]); assert x["dataset_id"] not in ids,ids
a=visible_ids(c,x["alice_key"]); assert x["dataset_id"] in a
write(out,{"pin":PIN,"revoke_status":"public-api-success","b_denied_after_revoke":True,"a_still_reads":True,"users_remain_alive":True,"dataset_remains_alive":True})

def restart(state_path,out):
x=json.loads(Path(state_path).read_text())
with TestClient(app) as c:
b=visible_ids(c,x["bob_key"]); a=visible_ids(c,x["alice_key"])
assert x["dataset_id"] not in b,b
assert x["dataset_id"] in a,a
me_b=c.get("/api/v1/auth/me",headers=hdr(x["bob_key"])); assert me_b.status_code==200,me_b.text
write(out,{"pin":PIN,"revocation_persists_after_fresh_app_process":True,"b_still_active":True,"b_still_denied":True,"a_still_allowed":True,"dataset_still_alive":True})

def finalize(state_path,grant_path,revoke_path,restart_path,out):
s=json.loads(Path(state_path).read_text()); g=json.loads(Path(grant_path).read_text()); r=json.loads(Path(revoke_path).read_text()); z=json.loads(Path(restart_path).read_text())
obs={"initial_denial":s["b_denied_before"],"explicit_grant":g["b_reads_after_grant"],"explicit_revoke":r["b_denied_after_revoke"],"subjects_survive_revoke":r["users_remain_alive"],"object_survives_revoke":r["dataset_remains_alive"],"restart_persistence":z["revocation_persists_after_fresh_app_process"],"owner_access_preserved":z["a_still_allowed"],"revoked_subject_active":z["b_still_active"]}
ok=all(obs.values())
report={"schema_version":1,"track":"C2","gate":"cognee-governance-complement-executable","candidate":"topoteretes/cognee","revision":PIN,"protected_object":"dataset","acl_semantics":"principal × permission × dataset; explicit public grant/revoke","observations":obs,"result":"COMPLEMENT_PASS" if ok else "FAIL","limitations":["dataset/collection granularity, not per-memory atom","qualified with dataset metadata visibility rather than LLM retrieval to keep the ACL test model-free and bounded"],"authority_boundary":"Cognee ACL governs contextual dataset visibility only; Yukh accepted-state/evidence authority remains external."}
write(out,report)
assert ok

def main():
mode=sys.argv[1]
if mode=="setup": setup(sys.argv[2])
elif mode=="grant": grant(sys.argv[2],sys.argv[3])
elif mode=="revoke": revoke(sys.argv[2],sys.argv[3])
elif mode=="restart": restart(sys.argv[2],sys.argv[3])
elif mode=="finalize": finalize(*sys.argv[2:])
else: raise SystemExit(mode)
if __name__=="__main__": main()
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#!/usr/bin/env python3
import json,sys
from pathlib import Path
r=json.loads(Path(sys.argv[1]).read_text())
assert r["track"]=="C2"
assert r["gate"]=="cognee-governance-complement-executable"
assert r["candidate"]=="topoteretes/cognee"
assert r["revision"]=="690c0ec023719a2a277dc893cdecfec1ca8012cc"
assert r["protected_object"]=="dataset"
assert r["result"]=="COMPLEMENT_PASS"
for k,v in r["observations"].items(): assert v is True,k
assert "explicit public grant/revoke" in r["acl_semantics"]
assert "dataset/collection granularity" in r["limitations"][0]
assert "Yukh accepted-state/evidence authority remains external" in r["authority_boundary"]
print("verified Cognee governance complement executable: COMPLEMENT_PASS")
Loading