ontogen 1.2.0__py3-none-any.whl

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.
Files changed (93) hide show
  1. onto/__init__.py +2 -0
  2. onto/attest.py +224 -0
  3. onto/cli.py +530 -0
  4. onto/core/__init__.py +0 -0
  5. onto/core/conformance.py +72 -0
  6. onto/core/court.py +407 -0
  7. onto/core/expr.py +303 -0
  8. onto/core/genome.py +399 -0
  9. onto/core/interview.py +246 -0
  10. onto/core/ir.py +95 -0
  11. onto/core/membrane.py +130 -0
  12. onto/core/migrate.py +113 -0
  13. onto/core/modules.py +231 -0
  14. onto/core/mutants.py +97 -0
  15. onto/core/mutgate.py +92 -0
  16. onto/core/organism.py +378 -0
  17. onto/core/placer.py +139 -0
  18. onto/core/propose.py +61 -0
  19. onto/core/serve.py +408 -0
  20. onto/core/skills.py +265 -0
  21. onto/core/spectral.py +179 -0
  22. onto/core/store.py +124 -0
  23. onto/core/warden.py +385 -0
  24. onto/dialects/__init__.py +0 -0
  25. onto/dialects/go_stdlib/__init__.py +0 -0
  26. onto/dialects/go_stdlib/emit.py +129 -0
  27. onto/dialects/go_stdlib/gates.py +119 -0
  28. onto/dialects/go_stdlib/rulebench.py +42 -0
  29. onto/dialects/go_stdlib/skeleton.py +470 -0
  30. onto/dialects/python_stdlib/__init__.py +0 -0
  31. onto/dialects/python_stdlib/gates.py +80 -0
  32. onto/dialects/python_stdlib/skeleton.py +454 -0
  33. onto/dialects/registry.py +24 -0
  34. onto/growdialect.py +197 -0
  35. onto/growgen.py +215 -0
  36. onto/growisland.py +174 -0
  37. onto/judge.py +74 -0
  38. onto/lint.py +82 -0
  39. onto/mcp_server.py +90 -0
  40. onto/nlfront.py +391 -0
  41. onto/ribosome.py +342 -0
  42. onto/scaffold.py +256 -0
  43. onto/templates_gallery/hotel/flows.yaml +23 -0
  44. onto/templates_gallery/hotel/genome.yaml +16 -0
  45. onto/templates_gallery/hotel/modules/commerce_events.yaml +8 -0
  46. onto/templates_gallery/hotel/modules/lago_metering.yaml +175 -0
  47. onto/templates_gallery/hotel/modules/loyalty.yaml +27 -0
  48. onto/templates_gallery/hotel/modules/orders.yaml +55 -0
  49. onto/templates_gallery/hotel/modules/payments.yaml +39 -0
  50. onto/templates_gallery/hotel/modules/reservations.yaml +25 -0
  51. onto/templates_gallery/hotel/modules/rooms.yaml +26 -0
  52. onto/templates_gallery/hotel/modules/shipping.yaml +25 -0
  53. onto/templates_gallery/hotel/modules/stock.yaml +33 -0
  54. onto/templates_gallery/hotel/modules/support.yaml +33 -0
  55. onto/templates_gallery/lago/flows.yaml +59 -0
  56. onto/templates_gallery/lago/genome.yaml +8 -0
  57. onto/templates_gallery/lago/modules/commerce_events.yaml +8 -0
  58. onto/templates_gallery/lago/modules/lago_metering.yaml +175 -0
  59. onto/templates_gallery/lago/modules/loyalty.yaml +27 -0
  60. onto/templates_gallery/lago/modules/orders.yaml +55 -0
  61. onto/templates_gallery/lago/modules/payments.yaml +39 -0
  62. onto/templates_gallery/lago/modules/reservations.yaml +25 -0
  63. onto/templates_gallery/lago/modules/rooms.yaml +26 -0
  64. onto/templates_gallery/lago/modules/shipping.yaml +25 -0
  65. onto/templates_gallery/lago/modules/stock.yaml +33 -0
  66. onto/templates_gallery/lago/modules/support.yaml +33 -0
  67. onto/templates_gallery/market/flows.yaml +36 -0
  68. onto/templates_gallery/market/genome.yaml +69 -0
  69. onto/templates_gallery/market/islands/fraudscore.py +13 -0
  70. onto/templates_gallery/market/islands/fx_adapter.py +34 -0
  71. onto/templates_gallery/market/islands/gateway.py +18 -0
  72. onto/templates_gallery/market/islands/idp.py +15 -0
  73. onto/templates_gallery/market/islands/tracker.py +14 -0
  74. onto/templates_gallery/market/modules/commerce_events.yaml +8 -0
  75. onto/templates_gallery/market/modules/lago_metering.yaml +175 -0
  76. onto/templates_gallery/market/modules/loyalty.yaml +27 -0
  77. onto/templates_gallery/market/modules/orders.yaml +55 -0
  78. onto/templates_gallery/market/modules/payments.yaml +39 -0
  79. onto/templates_gallery/market/modules/reservations.yaml +25 -0
  80. onto/templates_gallery/market/modules/rooms.yaml +26 -0
  81. onto/templates_gallery/market/modules/shipping.yaml +25 -0
  82. onto/templates_gallery/market/modules/stock.yaml +33 -0
  83. onto/templates_gallery/market/modules/support.yaml +33 -0
  84. onto/templates_gallery/starter/flows.yaml +12 -0
  85. onto/templates_gallery/starter/genome.yaml +25 -0
  86. onto/theory/__init__.py +0 -0
  87. onto/theory/formulas.py +95 -0
  88. onto/theory/provenance.py +53 -0
  89. ontogen-1.2.0.dist-info/METADATA +100 -0
  90. ontogen-1.2.0.dist-info/RECORD +93 -0
  91. ontogen-1.2.0.dist-info/WHEEL +4 -0
  92. ontogen-1.2.0.dist-info/entry_points.txt +2 -0
  93. ontogen-1.2.0.dist-info/licenses/LICENSE +190 -0
onto/__init__.py ADDED
@@ -0,0 +1,2 @@
1
+ """onto v1 — a living compiler of ontologies. Map: docs/design/SPEC.md, protocol: CLAUDE.md."""
2
+ __version__ = "1.2.0"
onto/attest.py ADDED
@@ -0,0 +1,224 @@
1
+ # -*- coding: utf-8 -*-
2
+ """ATTESTATION OF GUARANTEES (U10, D74; PARADIGM_LIMITS §1+5+9).
3
+
4
+ A compiler that prints the phenotype but not an attestation of its guarantees
5
+ lies by omission. `onto attest` is a signable release artifact: WHAT is proved
6
+ (the court, rule by rule), WHAT is assumed (membranes, auth, ignorance), WHAT is
7
+ monitored, and WHERE THE WEAKEST SEAM lies (the system's guarantee = the min
8
+ across membranes — so let that min be visible and named). Plus provenance: the
9
+ genome hash, the engine version, and the fingerprint of the frozen IR."""
10
+ from __future__ import annotations
11
+
12
+ import hashlib
13
+ import json
14
+ import math
15
+ import pathlib
16
+ import random
17
+
18
+ from onto import __version__
19
+ from onto.core import court, genome as G, ir, membrane as MB
20
+
21
+
22
+ def build_attest(genome_path, skills_cache=None) -> dict:
23
+ genome_path = pathlib.Path(genome_path)
24
+ g = G.load(genome_path)
25
+ raw = genome_path.read_bytes()
26
+
27
+ # --- court: rule by rule + entity induction (D80)
28
+ proofs, proved, failed = {}, 0, 0
29
+ entity_induction = {}
30
+ for en, ent in g.entities.items():
31
+ rules_spec = [(rn, r.guard, r.body, r.contract.post,
32
+ dict(g.events[r.when]))
33
+ for rn, r in ent.rules.items() if r.when in g.events]
34
+ ev_v = court.prove_entity(dict(ent.state), dict(ent.init),
35
+ rules_spec, g.events)
36
+ entity_induction[en] = (ev_v.status if ev_v.status != "proved"
37
+ else "entity-inductive")
38
+ for rn, r in ent.rules.items():
39
+ verdicts = court.prove_rule(dict(ent.state), dict(g.events[r.when]),
40
+ r.guard, r.body, r.contract.post,
41
+ r.contract.conserves)
42
+ for kind, v in verdicts.items():
43
+ proofs[f"{en}.{rn}.{kind}"] = v.status
44
+ proved += v.status == "proved"
45
+ failed += v.status == "counterexample"
46
+
47
+ # --- seams: every membrane + the weakest one
48
+ seams = {}
49
+ for name, raw_ext in g.externals.items():
50
+ ext = MB.External.model_validate(raw_ext)
51
+ seams[name] = {"assumptions": len(ext.assumptions), "quota": ext.quota,
52
+ "growable": bool(ext.intent and ext.cases)}
53
+ weakest = (min(seams, key=lambda n: (seams[n]["assumptions"],
54
+ -seams[n]["quota"]))
55
+ if seams else None)
56
+
57
+ # --- skills: quantile DKW certificate (Part VII §3 / thm.8), not a checkbox
58
+ skills = {}
59
+ if g.skills:
60
+ from onto.core import skills as SK
61
+ cache = pathlib.Path(skills_cache) if skills_cache else None
62
+ for name, raw_sk in g.skills.items():
63
+ phase = next((ph for ph in ("fast", "naive") if cache
64
+ and (cache / f"{name}.{ph}.py").exists()), None)
65
+ if not phase:
66
+ skills[name] = {"phase": "NOT CERTIFIED"}
67
+ continue
68
+ sk = SK.Skill.model_validate(raw_sk)
69
+ fn = SK.load_body((cache / f"{name}.{phase}.py").read_text(),
70
+ f"{phase}_{name}", sk.types)
71
+ rnd, M, defects = random.Random(20260831), 200, 0
72
+ for _ in range(M):
73
+ case = SK.gen_case(sk, rnd)
74
+ try:
75
+ defects += bool(SK.check_properties(
76
+ sk, case, SK.run_case(fn, sk, case)))
77
+ except Exception: # noqa: BLE001
78
+ defects += 1
79
+ delta = 0.01
80
+ q = max(0.0, round(1 - defects / M
81
+ - math.sqrt(math.log(2 / delta) / (2 * M)), 3))
82
+ skills[name] = {"phase": phase, "quantile_cert":
83
+ {"eta": 0, "q": q, "delta": delta, "M": M}}
84
+
85
+ inv_verdicts = court.prove_invariants(g)
86
+ invariants = {n: ("proved" if v.status == "proved" else f"monitored:{v.note}")
87
+ for n, v in inv_verdicts.items()}
88
+ n_rules = sum(len(e.rules) for e in g.entities.values())
89
+ return {
90
+ "genome": {"name": g.name, "sha256": hashlib.sha256(raw).hexdigest(),
91
+ "path": str(genome_path)},
92
+ "engine": {"version": __version__, "hub": ir.HUB_VERSION,
93
+ "ir_fingerprint": ir.FROZEN_V1_FINGERPRINT},
94
+ "proved": {"rules_total": n_rules, "obligations_proved": proved,
95
+ "obligations_failed": failed, "per_rule": proofs,
96
+ "entity_induction": entity_induction,
97
+ "NOTE": "per-rule proved = SELF-induction (post preserves "
98
+ "itself); the strong guarantee is entity_induction"},
99
+ "assumed": {
100
+ "seams": seams, "weakest_seam": weakest,
101
+ "auth": ("deny-by-default" if g.auth else
102
+ "NONE — every event is open"),
103
+ "skills": skills},
104
+ "invariants": invariants,
105
+ "monitored": {"drift_monitors": sum(s["assumptions"]
106
+ for s in seams.values()),
107
+ "webhooks": len(g.webhooks), "timers": len(g.timers),
108
+ "invariants_monitored": sum(1 for v in invariants.values()
109
+ if v.startswith("monitored"))},
110
+ "chains": _chains(g, proofs),
111
+ "survival": _hazard_moves(g),
112
+ "honest": {
113
+ "island_content": "NOT PROVED — only contained "
114
+ "(assumptions+drift+revoke)",
115
+ "coverage": f"{proved} proved obligations over {n_rules} rules; "
116
+ f"{len(seams)} islands OUTSIDE the court"},
117
+ }
118
+
119
+
120
+ def _chains(g, proofs: dict) -> dict:
121
+ """End-to-end paths (VII.1'/D79): event -> rules -> emissions (cascade,
122
+ cap 8) -> webhook. A rule with a PROVED post = a deterministic step
123
+ (q=1); a fully PROVED chain == the court proved every step. A webhook is
124
+ fire-and-forget: delivery is NOT certified (stated honestly in the attestation)."""
125
+ ev_rules = {}
126
+ for en, ent in g.entities.items():
127
+ for rn, r in ent.rules.items():
128
+ ev_rules.setdefault(r.when, []).append((en, rn, r))
129
+ out = {}
130
+ for ev0 in g.events:
131
+ steps, frontier, seen = [], [ev0], set()
132
+ for _ in range(8):
133
+ nxt = []
134
+ for ev in frontier:
135
+ for en, rn, r in ev_rules.get(ev, []):
136
+ if (en, rn) in seen:
137
+ continue
138
+ seen.add((en, rn))
139
+ proved = all(v == "proved" for k, v in proofs.items()
140
+ if k.startswith(f"{en}.{rn}."))
141
+ has_obl = any(k.startswith(f"{en}.{rn}.")
142
+ for k in proofs)
143
+ steps.append({"rule": f"{en}.{rn}",
144
+ "proved": proved and has_obl})
145
+ nxt += [em.event for em in r.emit]
146
+ if not nxt:
147
+ break
148
+ frontier = nxt
149
+ if not steps:
150
+ continue
151
+ hooked = [e for e in ([ev0] + [em.event
152
+ for _, _, r in ev_rules.get(ev0, []) for em in r.emit])
153
+ if e in g.webhooks]
154
+ out[ev0] = {"steps": steps,
155
+ "proved_end_to_end": all(st["proved"] for st in steps),
156
+ "webhook": ("fire-and-forget (delivery NOT certified)"
157
+ if hooked else None)}
158
+ return out
159
+
160
+
161
+ def _hazard_moves(g) -> dict:
162
+ """Part VI slide 6'.2: hazard moves — for each bad set S, a declared
163
+ move with a lower bound h; worst-case recovery time 1/h.
164
+ h=1 is a deterministic move; moves with h<1 require measurement (§2.2 VII)."""
165
+ moves = {}
166
+ if g.externals:
167
+ moves["island_storm"] = {
168
+ "move": "REVOKE trust (membrane quota)", "h": 1.0,
169
+ "worst_recovery_steps": 1.0,
170
+ "assumes": "drift monitors see the storm (declared assumptions)"}
171
+ moves["bad_molt"] = {
172
+ "move": "rollback from pre-molt backup (warden)", "h": 1.0,
173
+ "worst_recovery_steps": 1.0, "assumes": "backup alive (membrane)"}
174
+ moves["crash_loop"] = {
175
+ "move": "warden restart + replay", "h": None,
176
+ "worst_recovery_steps": None,
177
+ "assumes": "MEASURE h per deployment (Part VII §2.2) — not claimed"}
178
+ return moves
179
+
180
+
181
+ def render_md(a: dict) -> str:
182
+ L = [f"# ATTESTATION OF GUARANTEES · {a['genome']['name']}",
183
+ f"genome sha256:{a['genome']['sha256'][:16]}… · engine "
184
+ f"{a['engine']['version']} · IR v{a['engine']['hub']} "
185
+ f"(frozen {a['engine']['ir_fingerprint'][:12]}…)", "",
186
+ "## PROVED (court, inductively)",
187
+ f"- obligations: {a['proved']['obligations_proved']} PROVED, "
188
+ f"{a['proved']['obligations_failed']} FAILED "
189
+ f"(rules: {a['proved']['rules_total']}; per-rule = self-induction)"]
190
+ L += [f" - {k}: {v}" for k, v in a["proved"]["per_rule"].items()]
191
+ L += [f"- induction of entity {en}: {v}"
192
+ for en, v in a["proved"]["entity_induction"].items()]
193
+ L += ["", "## ASSUMED (membranes and open surfaces)",
194
+ f"- auth: {a['assumed']['auth']}"]
195
+ for n, s in a["assumed"]["seams"].items():
196
+ mark = " ← WEAKEST SEAM" if n == a["assumed"]["weakest_seam"] else ""
197
+ L.append(f"- island '{n}': {s['assumptions']} assumptions, "
198
+ f"quota {s['quota']}{mark}")
199
+ for n, sc in a["assumed"]["skills"].items():
200
+ if isinstance(sc, dict) and "quantile_cert" in sc:
201
+ c = sc["quantile_cert"]
202
+ L.append(f"- skill '{n}': {sc['phase']} · DKW (η={c['eta']}, "
203
+ f"q≥{c['q']}, δ={c['delta']}, M={c['M']})")
204
+ else:
205
+ L.append(f"- skill '{n}': {sc.get('phase', sc) if isinstance(sc, dict) else sc}")
206
+ L += ["", "## MONITORED",
207
+ f"- {a['monitored']['drift_monitors']} drift monitors, "
208
+ f"{a['monitored']['timers']} timers, "
209
+ f"{a['monitored']['webhooks']} webhooks", "",
210
+ "", "## END-TO-END PATHS (VII.1': composition of steps)"]
211
+ for ev, ch in a.get("chains", {}).items():
212
+ mark = "PROVED end-to-end" if ch["proved_end_to_end"] else \
213
+ "has UNproven steps"
214
+ wh = f" · webhook: {ch['webhook']}" if ch["webhook"] else ""
215
+ L.append(f"- {ev} -> {' -> '.join(st['rule'] for st in ch['steps'])}"
216
+ f" · {mark}{wh}")
217
+ L += ["", "## SURVIVAL (hazard moves, Part VI slide 6'.2)"]
218
+ for sname, m in a["survival"].items():
219
+ hh = "h=1 (deterministic)" if m["h"] == 1.0 else "h NOT MEASURED"
220
+ L.append(f"- {sname}: {m['move']} · {hh} · assumption: {m['assumes']}")
221
+ L += ["",
222
+ "## HONEST", f"- {a['honest']['island_content']}",
223
+ f"- {a['honest']['coverage']}"]
224
+ return "\n".join(L) + "\n"