Skip to content

feat(chassis,tenancy): SDK-chassis-in-prod + strict tenant DB binding flags [l9-ecosystem-fix] - #195

Merged
cryptoxdog merged 1 commit into
mainfrom
claude/campaign-execution-pipeline-dbc5cl
Aug 6, 2026
Merged

feat(chassis,tenancy): SDK-chassis-in-prod + strict tenant DB binding flags [l9-ecosystem-fix]#195
cryptoxdog merged 1 commit into
mainfrom
claude/campaign-execution-pipeline-dbc5cl

Conversation

@claude

@claude claude Bot commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

Summary

Reachable half of the l9-ecosystem-fix campaign for CEG: two production-safety feature flags (SDK-chassis-in-prod, strict tenant DB binding), the DEC-001 candidate-identity decision record, and canonical match contract fixtures — all bounded, reversible, and default-off.

What changed

  • W7-01 strict_tenant_database (default off) — removes the silent database="neo4j" fallback in GraphDriver.execute_query/execute_write; under the flag a missing database= raises. Back-compatible when off. The one internal caller (health ping) already passes database="neo4j" explicitly.
  • W7-02 require_sdk_chassis_in_prod (default off) — resolve_chassis() fails startup on a non-SDK chassis when l9_env==prod. Staged behind the flag so the SDK chassis can be validated before enforcement.
  • DEC-001 → OPTION-B (docs/adr/ADR-DEC-001-candidate-identity.md) — candidate identity is the namespaced entity_ref (<model>:<id>, e.g. res.partner:102), not a bare res.partner int nor a Neo4j-native node id; an explicit resolver is required. Records the live-handler entity_id vs contract entity_ref reconciliation as a residual task.
  • Canonical match fixtures (contracts/match_request.json, contracts/match_response.json) + conformance test rejecting removed/renamed required fields (no transport-forbidden fields on payloads).
  • Both flags registered in .claude/rules/feature-flags.md.

Verification

  • ruff check + ruff format --check clean; mypy — 140 files, no issues.
  • 21 targeted tests green (driver binding, chassis parity, canonical fixtures, sync projection); full tests/unit + tests/contracts exit 0.
  • tools/contract_scanner.py — no violations.

Residual risks

  • Two divergent Settings classes: engine/config/settings.py (live, now Wave 1–7) vs the stale chassis/auth/settings.py (no Wave 7). Reconcile or remove the duplicate.
  • Live match handler still keys candidate identity on the ungoverned entity_id node property; aligning it to the contract entity_ref is the open DEC-001 reconciliation (documented in the ADR).

Part of the governed l9-ecosystem-fix Program Execution v2 campaign. Draft — merge is a separate program-owner (AUTH-001) approval.


Generated by Claude Code

… flags

Campaign l9-ecosystem-fix Wave 1 (reachable half) for the CEG target:

- W7-01 strict_tenant_database (default off): removes the silent
  database="neo4j" fallback in GraphDriver.execute_query/execute_write; under
  the flag a missing database= raises. Back-compatible when off.
- W7-02 require_sdk_chassis_in_prod (default off): resolve_chassis() fails
  startup on a non-SDK chassis when l9_env==prod.
- DEC-001 identity contract resolved to OPTION-B (docs/adr): candidate identity
  is the namespaced entity_ref (<model>:<id>, e.g. res.partner:102), not a bare
  res.partner int nor a Neo4j-native id; explicit resolver required. Records the
  live entity_id vs contract entity_ref reconciliation as a residual task.
- Canonical match contract fixtures (contracts/match_request.json,
  match_response.json) + conformance test rejecting removed required fields.
- Register both flags in .claude/rules/feature-flags.md.

Feature-gated, reversible. Tests: 21 targeted green; full unit+contracts suite
exit 0; ruff + mypy (140 files) clean; contract scanner no violations.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QcrcFFfNb8SohQvpEajf4F
@github-actions

github-actions Bot commented Aug 5, 2026

Copy link
Copy Markdown

⚠️ Large PR Warning
Reviewable lines changed: 359
Warning threshold: 300 lines
Consider splitting for easier review

📋 Best Practices for Large Changes

  1. Refactoring + Features: Separate into 2 PRs
  2. Multiple Features: One PR per feature
  3. Database + Code: Separate migration from logic
  4. Generated Code: Exclude it from reviewable-size accounting

This PR passes the blocking limit but is larger than recommended.

@github-actions

github-actions Bot commented Aug 5, 2026

Copy link
Copy Markdown

L9 Audit Harness Report

  • Generated: 2026-08-05T15:52:37.303941+00:00
  • Repo root: /home/runner/work/Cognitive.Engine.Graphs/Cognitive.Engine.Graphs
  • Overall result: ✅ PASSED
  • Exit code: 0

Step Results

Step Status Exit Code Notes
Architecture Audit ✅ Passed 0
Spec Coverage ✅ Passed 0
Contract Wiring ✅ Passed 0

Architecture Audit Findings

Severity Count
🔴 CRITICAL 0
🟠 HIGH 0
🟡 MEDIUM 25
🔵 LOW 0

See artifacts/audit_report.md for full details.

Spec Coverage

  • ✅ Implemented: 37
  • ⚠️ Partial: 9
  • ❌ Missing: 0
  • Total features: 46
Category Implemented Partial Missing Total
gates 10 0 0 10
scoring 7 0 0 7
v1.1_node 2 0 0 2
v1.1_edge 2 0 0 2
v1.1_action 0 2 0 2
v1.1_scoring 1 1 0 2
action_handler 0 6 0 6
gds_algorithm 5 0 0 5
research_pattern 10 0 0 10

See artifacts/coverage_report.md for full details.

Next Steps

All checks passed. Safe to merge.

@sonarqubecloud

sonarqubecloud Bot commented Aug 5, 2026

Copy link
Copy Markdown

@cryptoxdog
cryptoxdog marked this pull request as ready for review August 6, 2026 07:32
@cryptoxdog
cryptoxdog self-requested a review as a code owner August 6, 2026 07:32
Copilot AI lite review requested due to automatic review settings August 6, 2026 07:32
@cryptoxdog
cryptoxdog merged commit 5314427 into main Aug 6, 2026
54 checks passed
@cryptoxdog
cryptoxdog deleted the claude/campaign-execution-pipeline-dbc5cl branch August 6, 2026 07:32

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

This PR advances the l9-ecosystem-fix campaign by adding two production-safety feature flags (default-off) and introducing canonical match contract fixtures plus a decision record that formalizes candidate identity as the contract-defined entity_ref.

Changes:

  • Add Wave 7 flags: strict_tenant_database (enforces explicit Neo4j database binding when enabled) and require_sdk_chassis_in_prod (enforces SDK chassis in prod when enabled).
  • Introduce canonical contracts/match_request.json / contracts/match_response.json fixtures with unit conformance tests.
  • Add ADR DEC-001 documenting candidate identity as a namespaced entity_ref and calling out current live-vs-contract divergence.

Reviewed changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
tests/unit/test_graph_driver_database_binding.py Adds unit tests for strict tenant DB binding behavior in GraphDriver.
tests/unit/test_canonical_contract_fixtures.py Validates canonical request/response fixtures against Pydantic payload models.
tests/contracts/test_chassis_parity.py Adds contract coverage for enforcing SDK chassis in prod when flagged.
engine/graph/driver.py Removes implicit database="neo4j" parameter default and gates fallback behind strict_tenant_database.
engine/config/settings.py Registers the two new Wave 7 feature flags and exposes is_production.
docs/adr/ADR-DEC-001-candidate-identity.md Records DEC-001 (Option B) for candidate identity via entity_ref.
contracts/match_response.json Adds canonical match response fixture.
contracts/match_request.json Adds canonical match request fixture.
chassis/entrypoint.py Enforces SDK chassis in prod when require_sdk_chassis_in_prod is enabled.
.claude/rules/feature-flags.md Documents the new Wave 7 feature flags in the feature flag registry.

Comment on lines +72 to +80
@pytest.mark.finding("EVID-003")
@pytest.mark.asyncio
async def test_explicit_database_is_preserved_when_strict() -> None:
"""An explicit database= (as the internal health probe passes) stays valid."""
driver = GraphDriver()
driver._raw_execute_query = AsyncMock(return_value=[]) # type: ignore[method-assign]
with patch("engine.config.settings.settings", _settings(strict=True)):
await driver.execute_query("RETURN 1", database="neo4j")
assert driver._raw_execute_query.await_args.args[2] == "neo4j"
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.

3 participants