docs(specs): drift gate semantics v2 — intra-domain cycles, gate_failed, tolerance precedence (#176 + #170)#216
Conversation
|
/guardian review |
There was a problem hiding this comment.
LGTM — no defects found in this diff.
Diff is a design specification document (markdown), not executable code. No logic, type safety, or ontology violations to flag. Verified no code changes or test gaps in the provided diff.
🤖 mistral-medium-latest · 6,347 prompt + 50 completion = 6,397 tokens
There was a problem hiding this comment.
Code Review
This pull request introduces a design specification for Drift Gate Semantics v2, addressing intra-domain cycles, a new gate_failed status, and per-domain tolerance precedence. The feedback suggests key improvements to the spec: making the effective bound resolution operator-aware to support both min and max constraints, validating that the hygiene_baseline configuration is a mapping before parsing, and ensuring the loader safely handles the optional drift_tolerance field when it is missing or null.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
…tolerance loader (gemini review) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
zaebee
left a comment
There was a problem hiding this comment.
Spec review — strong, 2 design points to nail before implementation
Read it end to end. The corrected #176 diagnosis (§1.1: CALLS edges never enter the cycle computation — _compute_cycles is Tarjan over IMPORTS between FILE/MODULE nodes, and the wall is per-domain blast-radius of file-level import cycles) is right and well-argued, and explicitly not building call_cycle_ratio is the correct call. Intra-domain SCC (§2.1) with single-file→0-by-construction is clean. Operator-aware baseline resolution and the enforce-uniform any_critical (retiring the #178 score-term deferral) are good. Two things I'd resolve before/in the impl:
1. Hygiene/template key collision makes gate_failed provenance ambiguous (§2.2) — and it's LIVE
score() keeps {**hygiene, **template} and adds a "which keys came from hygiene" set. But unresolved_ratio is declared in BOTH — hygiene {max: 0.2} and the pure_utility template {max: 0.1}. After the merge the template wins (0.1), yet the key is still "hygiene-provenance" → a domain at unresolved_ratio 0.15 (violates the template's 0.1, satisfies the hygiene invariant 0.2) would be forced to gate_failed / undilutable — escalating a template breach as if it were a hygiene-invariant breach.
Suggest evaluating hygiene and template constraints separately (don't dict-merge), each judged against its own bound with its own provenance. That also removes the need for a side "provenance key set". The collision is real in today's patterns.yaml, so this isn't hypothetical.
2. The emitted hygiene_baseline must round UP, or init-ontology fails its own round-trip (§2.2)
The whole point of the baseline is the #174 round-trip: init-ontology → drift on the proposal must stay green. With effective bound max(global_max=0.0, baseline), the gate passes only if measured <= baseline. So the emitted baseline must be ≥ the measured value — exact, or _ceil2-style ceil, never floored to 2dp. If init-ontology emits 0.08 for a measured 0.0833, the proposal gate_faileds on its own graph. Pin the rounding direction the same way tolerances use _ceil2.
Smaller notes
- Sequencing: the
hygiene_baselineemission rides onontology_init.py, i.e. this impl should land after #211 merges. - §2.1 tarjan reuse: make sure the SCC helper is a shared module-level util, not reached into via
HealthScorerinternals (fingerprint→health private coupling). - §2.2 stray baselines: a
hygiene_baselinedeclared for a non-hygiene key should be validated/ignored — say so, or it silently no-ops.
None are blockers for the spec — #1 and #2 are the two I'd want pinned in the doc before the plan, since both touch correctness (undilutability semantics, and the round-trip guarantee this section exists to protect). Nice work on the diagnosis especially.
…shared tarjan, strict baseline keys (colleague review) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
Re: the spec review — all five folded in (be41007):
The unresolved_ratio collision catch especially — that one would have shipped as a subtle wrong-escalation. Thanks. 🤖 Generated with Claude Code |
|



Summary
Combined design spec for #176 + #170 (roadmap #179 P1 — "make the gate correct across topologies"). One spec because both change what the gate means, and the cycle fix interacts with both #170 halves AND #174's round-trip guarantee.
Key content:
call_cycle_ratiowould gate a thing the metric never measured; explicitly NOT builtcycle_ratiofrom the domain's OWN import subgraph; single-file domains → 0 by construction; cross-domain cycles routed to the quotient layer (030C motifs) as a pinned principlegate_failedstatus (user-decided) — hygiene-provenance violations force it regardless of TV score, undilutable; tripsany_criticalwhen enforcedinit-ontologyproduce instantly-failing baselines on any cyclic repo.hygiene_baseline:per-domain = acknowledged debt (ratchet-down convention); init-ontology emits it for measured breaches → round-trip guarantee survives, NEW debt beyond baseline fails absolutelydrift_tolerancebinds;max_driftdemoted to default-for-undeclared; relative warning band (0.75×); the gate becomes uniformly status-based and enforce-respecting (also retires the cgis_drift: zero-match / no-signal domains report 'clean' instead of 'empty' (silent mis-targeted ontology passes green) #178-era "score term is enforce-blind" deferral)Test Plan
🤖 Generated with Claude Code