Skip to content

feat(#139): domain pattern fingerprint & drift engine#140

Merged
zaebee merged 12 commits into
mainfrom
feat/issue-139-fingerprint-drift
Jun 9, 2026
Merged

feat(#139): domain pattern fingerprint & drift engine#140
zaebee merged 12 commits into
mainfrom
feat/issue-139-fingerprint-drift

Conversation

@zaebee

@zaebee zaebee commented Jun 9, 2026

Copy link
Copy Markdown
Owner

Closes #139

Summary

  • Add docs/ontology/patterns.yaml — 5 named pattern templates (pure_utility, pipeline_stage, orchestrator, layered_dag, dispatcher) with drift weights and 5 project domain expectations
  • Add src/cgis/query/fingerprint.pyPatternFingerprint frozen dataclass (7-component structural vector) + FingerprintExtractor (uses HealthScorer for cycle/fan metrics, BFS for chain length and DAG depth)
  • Add src/cgis/query/drift.pyDriftScorer (per-component normalized weighted MAE, directional penalties) + DriftReport + DomainConfig
  • Add cgis drift CLI command — scores all project domains, renders Rich table, exits 1 if any domain reaches critical threshold
  • Add gen_ideal_graph.py --from-ontology mode — generates ideal graph JSON using real FQN prefixes from patterns.yaml

Drift formula

drift = Σ w_i * clip(|actual_i - ideal_i| / norm_i, 0, 1) over constrained components only (re-normalized weights). Directional: {min: X} penalizes undershoot only, {max: X} penalizes overshoot only.

Test plan

  • uv run pytest tests/unit/test_patterns_yaml.py — 8 structural YAML validation tests
  • uv run pytest tests/unit/test_fingerprint.py — 14 FingerprintExtractor unit tests
  • uv run pytest tests/unit/test_drift.py — 11 DriftScorer unit tests
  • uv run pytest tests/unit/test_cli.py -k drift — 4 CLI integration tests
  • uv run pytest tests/unit/test_gen_ideal_graph.py -k ontology — 4 gen_ideal_graph tests
  • make format && make lint && make type-check && make pytest && make doc-coverage — all green (440 tests, 100% docstring coverage)
  • uv run cgis ingest . --source-root src --output /tmp/g.db && uv run cgis drift --db /tmp/g.db --patterns docs/ontology/patterns.yaml

🤖 Generated with Claude Code

zaebee and others added 6 commits June 9, 2026 16:50
6-task plan covering patterns.yaml, FingerprintExtractor, DriftScorer,
cgis drift CLI, and gen_ideal_graph --from-ontology mode.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Implements the seven-component structural fingerprint (hub_count, star_count,
chain_len, dag_depth, router_count, cycle_ratio, unresolved_ratio) for a
domain FQN prefix, backed by HealthScorer for cycle detection.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds `cgis drift` subcommand that loads project domains from patterns.yaml,
computes per-domain PatternFingerprints via FingerprintExtractor, scores them
with DriftScorer, and exits 1 if any domain meets or exceeds the critical
drift threshold.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds generate_from_ontology() to scripts/gen_ideal_graph.py, which reads
a patterns.yaml file and generates an ideal graph per project_domain using
the real fqn_prefix as the node namespace. Wires it up via --from-ontology
CLI flag. Adds 4 TDD tests covering schema validity, unique IDs, prefix
correctness, and no dangling edges.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request implements the Domain Pattern Fingerprint & Drift Engine, introducing a YAML-based pattern configuration, fingerprint extraction from the SQLite store, drift scoring against ideal templates, a new cgis drift CLI command, and an ontology-based ideal graph generator. The review feedback highlights critical algorithmic issues in the fingerprint extractor, specifically incorrect BFS traversals for path length and DAG depth calculations that should be replaced with memoized DFS. Additionally, the feedback identifies potential runtime errors, including a ZeroDivisionError and a KeyError in the drift scorer, a potential TypeError in the graph generator script when parsing empty configurations, and a lack of robust error handling in the new CLI command.

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.

Comment thread src/cgis/query/fingerprint.py Outdated
Comment thread src/cgis/query/fingerprint.py Outdated
Comment thread src/cgis/query/drift.py Outdated
Comment thread src/cgis/query/drift.py Outdated
Comment thread src/cgis/cli.py Outdated
Comment thread scripts/gen_ideal_graph.py Outdated
…except

- fingerprint.py: replace BFS with memoized DFS in _avg_chain_length and
  _max_dag_depth — BFS with global visited underestimates depth in DAGs
  where a node is reachable via multiple paths of different lengths
- drift.py: guard ZeroDivisionError when total_weight==0; replace raw
  KeyError on unknown expected_pattern with descriptive ValueError
- cli.py: wrap drift command core logic in try-except for consistent UX
- gen_ideal_graph.py: guard against yaml.safe_load returning None on
  empty file; use `or []` for project_domains to handle explicit None

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@zaebee

zaebee commented Jun 9, 2026

Copy link
Copy Markdown
Owner Author

/gemini review

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request implements the Domain Pattern Fingerprint & Drift Engine, introducing the cgis drift CLI command to measure architectural drift against ideal patterns defined in docs/ontology/patterns.yaml. It adds fingerprint extraction, drift scoring, and an ontology-based ideal graph generator, along with comprehensive unit tests. The review feedback identifies a bug where the drift command's --format option uses an enum that does not support the expected json output, and a performance bottleneck in _count_routers that can be optimized from O(N * M) to O(N + M) by pre-building a calls mapping.

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.

Comment thread src/cgis/cli.py
Comment thread src/cgis/query/fingerprint.py
zaebee and others added 2 commits June 9, 2026 17:22
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Split score() into _zero_drift_report() and _score_constraint() to bring
cognitive complexity from 18 down to ≤15. Also fix remaining float equality
check in test_fingerprint.py.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@zaebee

zaebee commented Jun 9, 2026

Copy link
Copy Markdown
Owner Author

/gemini review

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request implements the Domain Pattern Fingerprint & Drift Engine, introducing the cgis drift CLI command to measure architectural drift against ideal patterns defined in patterns.yaml. It adds fingerprint extraction, drift scoring, and support for generating ideal graphs from the ontology, along with comprehensive unit tests. The review feedback focuses on performance and robustness improvements, including caching database queries and health scoring in FingerprintExtractor, optimizing the complexity of _count_routers from quadratic to linear, safely retrieving weights in DriftScorer to avoid potential KeyErrors, and adding file existence checks in generate_from_ontology to prevent unhandled FileNotFoundErrors.

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.

Comment thread src/cgis/query/fingerprint.py Outdated
Comment thread src/cgis/query/fingerprint.py
Comment thread src/cgis/query/drift.py Outdated
Comment thread scripts/gen_ideal_graph.py
… FingerprintExtractor, safe weights

- cli: add DriftOutputFormat enum (TEXT/JSON) so --format json is a valid typer choice
- fingerprint: pre-build calls_by_source in _count_routers to reduce O(N*M) -> O(N+M)
- fingerprint: cache enriched nodes + edges in FingerprintExtractor._loaded() to avoid
  re-fetching per domain when scoring multiple domains in one drift run
- drift: use self._weights.get(name, 0.0) to prevent KeyError on custom patterns.yaml
- gen_ideal_graph: raise FileNotFoundError early in generate_from_ontology

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@zaebee

zaebee commented Jun 9, 2026

Copy link
Copy Markdown
Owner Author

/gemini review

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request implements the Domain Pattern Fingerprint & Drift Engine, introducing pattern templates in patterns.yaml, fingerprint extraction in fingerprint.py, drift scoring in drift.py, a new cgis drift CLI command, and an ontology-based synthetic graph generator. Feedback focuses on ensuring deterministic behavior in graph traversal metrics by sorting set-derived lists, and improving YAML loading robustness in DriftScorer to prevent potential TypeError or KeyError exceptions.

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.

Comment thread src/cgis/query/fingerprint.py Outdated
Comment thread src/cgis/query/fingerprint.py Outdated
Comment thread src/cgis/query/drift.py Outdated
- fingerprint: sort sources/roots before DFS to guarantee identical chain_len
  and dag_depth across runs (set iteration order is non-deterministic)
- drift: use `or {}` / `.get()` in DriftScorer.__init__ so empty or malformed
  patterns.yaml doesn't crash with TypeError/KeyError

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@zaebee

zaebee commented Jun 9, 2026

Copy link
Copy Markdown
Owner Author

/gemini review

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request implements the Domain Pattern Fingerprint & Drift Engine, adding the cgis drift CLI command to measure how much a domain's graph topology deviates from its ideal architectural pattern. It introduces pattern configurations in patterns.yaml, a FingerprintExtractor to compute structural metrics, a DriftScorer to evaluate drift, and updates gen_ideal_graph.py with a --from-ontology mode. The review feedback focuses on improving robustness when parsing YAML configurations by ensuring the loaded content is a dictionary before calling .get(), and safely falling back to an empty dictionary when retrieving expected patterns.

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.

Comment thread src/cgis/query/drift.py Outdated
Comment thread src/cgis/query/drift.py
Comment thread scripts/gen_ideal_graph.py Outdated
- fingerprint: extract shared _root_depths() helper — the memoized DFS was
  duplicated verbatim in _avg_chain_length and _max_dag_depth (sonar 13.6%
  duplication on new code)
- drift: isinstance guard on yaml.safe_load result (lists/strings no longer
  crash __init__); non-dict pattern template raises TypeError with a clear
  message instead of AttributeError in _parse_constraints
- gen_ideal_graph: same isinstance guard for malformed YAML

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@sonarqubecloud

sonarqubecloud Bot commented Jun 9, 2026

Copy link
Copy Markdown

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(query): domain pattern fingerprint & drift engine

1 participant