-
Notifications
You must be signed in to change notification settings - Fork 0
feat: package ontology + validators, docs, examples, and CI #1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 1 commit
1be4029
654976f
3a22e68
669cbd2
176d189
e178132
61ed271
61d1e12
edc364e
397b856
ca32387
69088f8
14f21f9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
| name: JS Build and Checks | ||
|
|
||
| on: | ||
| push: | ||
| pull_request: | ||
|
|
||
| jobs: | ||
| js: | ||
| name: Build JS package | ||
| runs-on: ubuntu-latest | ||
| defaults: | ||
| run: | ||
| working-directory: js/goblin-ontology | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
| - uses: actions/setup-node@v4 | ||
| with: | ||
| node-version: '20' | ||
| cache: 'npm' | ||
| cache-dependency-path: js/goblin-ontology/package.json | ||
| - name: Install | ||
| run: npm ci || npm i | ||
| - name: Typecheck | ||
| run: npm run typecheck | ||
| - name: Build | ||
| run: npm run build | ||
| - name: Test | ||
| run: npm test | ||
|
|
||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,71 @@ | ||
| name: Validate Ontology and Docs | ||
|
|
||
| on: | ||
| push: | ||
| pull_request: | ||
|
|
||
| jobs: | ||
| python-validate: | ||
| name: Python SHACL validation | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
| - uses: actions/setup-python@v5 | ||
| with: | ||
| python-version: '3.11' | ||
| - name: Install deps | ||
| run: | | ||
| python -m pip install --upgrade pip | ||
| pip install rdflib pyshacl | ||
| - name: Validate sample JSON-LD against SHACL | ||
| run: | | ||
| python - << 'PY' | ||
| from rdflib import Graph | ||
| from pyshacl import validate | ||
| data = Graph() | ||
| data.parse("examples/sample_score.json", format="json-ld") | ||
| shapes = Graph() | ||
| shapes.parse("goblin-shapes.ttl", format="turtle") | ||
| conforms, report_graph, report_text = validate(data_graph=data, shacl_graph=shapes, inference='rdfs', advanced=True) | ||
| print(report_text) | ||
| assert conforms, "SHACL validation failed" | ||
| PY | ||
| dot-check: | ||
| name: Render DOT and check committed artifacts | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
| - name: Install Graphviz | ||
| run: sudo apt-get update && sudo apt-get install -y graphviz | ||
| - name: Render goblin-map | ||
| run: | | ||
| dot -Tsvg goblin-map.dot -o docs/goblin-map.svg.new | ||
| dot -Tpng goblin-map.dot -o docs/goblin-map.png.new | ||
| - name: Fail if diffs vs committed images | ||
| run: | | ||
| set -e | ||
| if ! cmp --silent docs/goblin-map.svg docs/goblin-map.svg.new; then | ||
| echo "docs/goblin-map.svg differs from generated. Please regenerate and commit." | ||
| exit 1 | ||
| fi | ||
| if ! cmp --silent docs/goblin-map.png docs/goblin-map.png.new; then | ||
| echo "docs/goblin-map.png differs from generated. Please regenerate and commit." | ||
| exit 1 | ||
| fi | ||
| docs-link: | ||
| name: Verify docs links | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
| - name: Check docs/kg.html references | ||
| run: | | ||
| set -e | ||
| test -f docs/goblin-map.svg | ||
| test -f docs/goblin-map.png | ||
| test -f goblin-ontology.ttl | ||
| test -f goblin-shapes.ttl | ||
| grep -q "goblin-map.svg" docs/kg.html | ||
| grep -q "goblin-ontology.ttl" docs/kg.html | ||
| grep -q "goblin-shapes.ttl" docs/kg.html | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| # Sample system description | ||
|
|
||
| Context: multi-service web app with async jobs, third-party APIs, and manual backoffice workflows. | ||
|
|
||
| Key points: | ||
| - Frontend models assume immediate consistency; actual system is eventually consistent. | ||
| - External payment API introduces retries and delayed webhooks. | ||
| - Backoffice users can override orders out-of-band. | ||
|
|
||
| Requested: compute the Goblin score and per-dimension notes using the lim42 agent profile. | ||
|
|
||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| { | ||
| "@context": { | ||
| "ui": "https://nkllon.com/ui#", | ||
| "prob": "https://nkllon.com/problem#", | ||
| "rdfs": "http://www.w3.org/2000/01/rdf-schema#", | ||
| "xsd": "http://www.w3.org/2001/XMLSchema#", | ||
| "type": "@type", | ||
| "goblinScore": { "@id": "ui:goblinScore", "@type": "xsd:decimal" } | ||
| }, | ||
| "@id": "prob:ExampleSystem", | ||
| "type": "ui:UIClosureIllusionProblem", | ||
| "rdfs:label": "Example System", | ||
| "goblinScore": "0.73" | ||
| } | ||
|
|
||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -90,3 +90,39 @@ In practice: | |
| are high-leverage moves when their \( w_i \) are large. | ||
|
|
||
| Goblin score gives you a way to **prioritize** where to push on the system to reduce long-term misalignment energy. | ||
|
|
||
| ## Numerical Scenarios | ||
|
|
||
| Assume weights (subset): \( w_{\text{closure}}=0.18 \), \( w_{\text{dist}}=0.20 \), \( w_{\text{async}}=0.15 \), \( w_{\text{security}}=0.10 \), \( w_{\text{domain}}=0.12 \), \( w_{\text{energy}}=0.25 \). | ||
|
|
||
| ### Scenario A: Before → After (small targeted fix) | ||
| - Before: \( x_{\text{closure}}=0.9, x_{\text{dist}}=0.8, x_{\text{async}}=0.8, x_{\text{domain}}=0.6, x_{\text{security}}=0.7, x_{\text{energy}}=0.9 \) | ||
| - After (invest in domain invariants and observability): \( x_{\text{closure}}=0.8, x_{\text{dist}}=0.78, x_{\text{async}}=0.78, x_{\text{domain}}=0.4, x_{\text{security}}=0.7, x_{\text{energy}}=0.88 \) | ||
|
|
||
| Compute: | ||
| \[ | ||
| G_{\text{before}} \approx 0.18(0.9)+0.20(0.8)+0.15(0.8)+0.12(0.6)+0.10(0.7)+0.25(0.9)=0.808 | ||
| \] | ||
| \[ | ||
| G_{\text{after}} \approx 0.18(0.8)+0.20(0.78)+0.15(0.78)+0.12(0.4)+0.10(0.7)+0.25(0.88)=0.724 | ||
| \] | ||
| \[ | ||
| \Delta G = -0.084 \;\;(\text{~10.4% reduction}) | ||
| \] | ||
| With \( k=1 \), \( \Delta E=\Delta G \). | ||
|
|
||
| ### Scenario B: Local optimization that backfires globally | ||
| - Before: same as Scenario A before. | ||
| - Local move: reduce latency by caching and suppressing validation → \( x_{\text{async}}=0.7 \) improves, but \( x_{\text{closure}}=0.95 \), \( x_{\text{domain}}=0.75 \) worsen; others unchanged. | ||
|
|
||
| Compute: | ||
| \[ | ||
| G_{\text{local}} \approx 0.18(0.95)+0.20(0.8)+0.15(0.7)+0.12(0.75)+0.10(0.7)+0.25(0.9)=0.833 | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Bug: Incorrect arithmetic in energy gradient scenario calculationsThe numerical scenarios contain arithmetic errors in the Goblin score calculations. Line 104 claims |
||
| \] | ||
| \[ | ||
| \Delta G = +0.025 \;\;(\text{worse}) | ||
| \] | ||
|
|
||
| Tie-in to SHACL: | ||
| - The shapes constrain values like `ui:goblinScore` and ensure components (e.g., `ui:componentValue`) stay in \([0,1]\). | ||
| - Scenarios can be serialized as RDF/JSON-LD and validated against `goblin-shapes.ttl` to keep data consistent while experimenting. | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| __all__ = ["__version__"] | ||
| __version__ = "0.1.0" | ||
|
|
||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,67 @@ | ||
| from __future__ import annotations | ||
|
|
||
| import argparse | ||
| import sys | ||
| from pathlib import Path | ||
|
|
||
| from .validator import ValidationResult, validate | ||
|
|
||
|
|
||
| def _build_parser() -> argparse.ArgumentParser: | ||
| parser = argparse.ArgumentParser( | ||
| prog="goblin-validate", | ||
| description="Validate a Goblin score RDF/JSON-LD document against SHACL shapes.", | ||
| ) | ||
| parser.add_argument( | ||
| "data", | ||
| help="Path to data graph (JSON-LD, TTL, RDF/XML, etc.).", | ||
| ) | ||
| parser.add_argument( | ||
| "--shapes", | ||
| required=True, | ||
| help="Path to SHACL shapes TTL.", | ||
| ) | ||
| parser.add_argument( | ||
| "--data-format", | ||
| default=None, | ||
| help="Optional explicit RDF format for data (e.g., json-ld, turtle).", | ||
| ) | ||
| parser.add_argument( | ||
| "--shapes-format", | ||
| default="turtle", | ||
| help="Optional explicit RDF format for shapes (default: turtle).", | ||
| ) | ||
| parser.add_argument( | ||
| "--inference", | ||
| default="rdfs", | ||
| choices=["none", "rdfs", "owlrl"], | ||
| help="Inference mode during validation (default: rdfs).", | ||
| ) | ||
| parser.add_argument( | ||
| "--no-advanced", | ||
| action="store_true", | ||
| help="Disable advanced SHACL features.", | ||
| ) | ||
| return parser | ||
|
|
||
|
|
||
| def main(argv: list[str] | None = None) -> int: | ||
| args = _build_parser().parse_args(argv) | ||
|
|
||
| result: ValidationResult = validate( | ||
| data_graph_path=Path(args.data), | ||
| shapes_graph_path=Path(args.shapes), | ||
| data_format=args.data_format, | ||
| shapes_format=args.shapes_format, | ||
| inference=args.inference, | ||
| advanced=not args.no_advanced, | ||
| ) | ||
|
|
||
| print(result.report_text.strip()) | ||
| return 0 if result.conforms else 1 | ||
|
|
||
|
|
||
| if __name__ == "__main__": | ||
| raise SystemExit(main()) | ||
|
|
||
|
|
Uh oh!
There was an error while loading. Please reload this page.