Skip to content
Merged
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
18 changes: 18 additions & 0 deletions .github/workflows/quality.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
name: Profile quality

on:
push:
branches: [main]
pull_request:

permissions:
contents: read

jobs:
static:
name: Static integrity
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6
- run: python3 scripts/check_text.py
- run: python3 scripts/check_profile.py
14 changes: 10 additions & 4 deletions profile/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,13 @@
</picture>
</p>

<h1 align="center">Meaning flows through graphs.<br>GraphABI finds where it breaks.</h1>
<p align="center"><strong>Semantic Compatibility Infrastructure for agent graphs.</strong></p>

<h1 align="center">Your schema passed.<br>Your agent still broke.</h1>

<p align="center">
Semantic Compatibility Infrastructure for agent graphs.<br>
Find the first incompatible edge, inspect the recorded witness, and trace everything downstream.
GraphABI finds the first edge where meaning changed, shows the recorded witness,<br>
and maps every downstream node that may be affected.
</p>

![GraphABI semantic pulse stopping at researcher to verifier and revealing the affected path and trace-backed witness](assets/demo.gif)
Expand All @@ -19,6 +21,10 @@
uvx --from git+https://github.com/graphabi/graphabi graphabi demo --allow-breaking
```

| Explicit contracts | Trace-backed evidence | Honest uncertainty |
|---|---|---|
| Consumers state the assumptions they rely on. | Every verdict points to an observed run and witness. | Missing evidence stays unknown. It never becomes a pass. |

<p align="center">
<a href="https://github.com/graphabi/graphabi"><strong>Repository</strong></a>
·
Expand All @@ -29,4 +35,4 @@ uvx --from git+https://github.com/graphabi/graphabi graphabi demo --allow-breaki
<a href="https://github.com/graphabi/graphabi/security/policy"><strong>Security</strong></a>
</p>

<p align="center"><sub>Public alpha · Apache-2.0 · Local and deterministic by default · No API key required</sub></p>
<p align="center"><sub>One project · Public alpha · Apache-2.0 · Local and deterministic by default</sub></p>
39 changes: 39 additions & 0 deletions scripts/check_profile.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
"""Verify the organization profile's small public contract."""

from __future__ import annotations

from pathlib import Path
from xml.etree import ElementTree

ROOT = Path(__file__).parents[1]


def main() -> int:
readme = (ROOT / "profile/README.md").read_text(encoding="utf-8")
required = (
"Explicit contracts",
"Trace-backed evidence",
"Honest uncertainty",
"https://github.com/graphabi/graphabi",
"https://graphabi.github.io",
"CONTRIBUTING.md",
"/security/policy",
"uvx --from git+https://github.com/graphabi/graphabi",
)
missing = [item for item in required if item not in readme]
for name in ("logo-dark.svg", "logo-light.svg"):
ElementTree.parse(ROOT / "profile/assets" / name)
gif = (ROOT / "profile/assets/demo.gif").read_bytes()
if not gif.startswith((b"GIF87a", b"GIF89a")):
missing.append("valid demo.gif")
if missing:
print("Organization profile verification failed:")
for item in missing:
print(f"- missing {item}")
return 1
print("Organization profile links, principles, command, and assets are present.")
return 0


if __name__ == "__main__":
raise SystemExit(main())
36 changes: 36 additions & 0 deletions scripts/check_text.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
"""Reject prohibited punctuation and private paths in tracked text."""

from __future__ import annotations

import subprocess
from pathlib import Path

ROOT = Path(__file__).parents[1]


def main() -> int:
names = subprocess.check_output(["git", "ls-files", "-z"], cwd=ROOT).split(b"\0")
offenders: list[str] = []
mac_user_prefix = "/" + "Users" + "/"
windows_user_prefix = "C:" + "\\" + "Users" + "\\"
for name in names:
if not name:
continue
path = ROOT / name.decode()
try:
text = path.read_text(encoding="utf-8")
except (UnicodeDecodeError, OSError):
continue
if chr(0x2014) in text or mac_user_prefix in text or windows_user_prefix in text:
offenders.append(str(path.relative_to(ROOT)))
if offenders:
print("Tracked public text contains prohibited content:")
for offender in offenders:
print(f"- {offender}")
return 1
print("Tracked public text contains no em dash or private absolute path.")
return 0


if __name__ == "__main__":
raise SystemExit(main())