Skip to content

feat(project-graph): activate semantic extraction on email import (flag-gated)#927

Closed
seonghobae wants to merge 1 commit into
developfrom
feat/project-graph-import-activation
Closed

feat(project-graph): activate semantic extraction on email import (flag-gated)#927
seonghobae wants to merge 1 commit into
developfrom
feat/project-graph-import-activation

Conversation

@seonghobae

Copy link
Copy Markdown
Contributor

What

Turns the dead project-semantic-graph pipeline into a live one. The content-graph substrate is already built on every import (email_import_service.py persists ContentSegmentRecord), and the projects API + correction endpoint already read/annotate project_graph_objects — but nothing populated them (extract_project_semantics/persist_project_graph_projection had zero non-test callers). This wires extract→persist into the import path so /candidates returns real data.

This is Phase 1 of docs/plans/2026-07-06-ai-moat-project-graph-activation.md (#925) — the #1 AI-moat gap.

Safety (why this is low-risk despite touching the import path)

  • Flag-gated: PROJECT_GRAPH_EXTRACTION_ENABLED (default False) → zero behavior change until explicitly enabled per environment.
  • Best-effort: projection runs after the email is committed, wrapped in try/except + rollback, so a projection failure never fails the email import.
  • Async-safe: segments are snapshotted from the in-memory list before commit (no lazy-load → no MissingGreenlet); persistence runs after commit when segments have ids (the FK the repository needs).
  • Scope: workspace id follows the repository's enforced convention (workspace-<org_id>, or workspace-<user_id> without an org) — verified by _validate_segment_scope.

Tests

tests/test_project_graph_import_wiring.py (6, using the real deterministic extractor + mocked persistence): segment mapping, workspace scoping (org + user fallback), no-op on empty/no-objects, and best-effort rollback on failure. Existing import + project-graph suites unaffected — 56 passed locally (pytest tests/test_import_fixtures.py tests/test_project_graph_api.py tests/test_emails_api.py).

Follow-ups (separate PRs, per the plan)

  • Phase 2: upgrade the keyword extractor to grounded LLM/embedding extraction with source_segment_uids citations.
  • Move projection off the synchronous import path (queue/worker) before enabling at scale.
  • Phase 3: turn apply_project_graph_correction corrections into a per-tenant eval set + calibrated confidence.

🤖 Generated with Claude Code

…agged)

Wires the existing-but-dead project semantic graph pipeline into the import
path: after an imported email commits, its content segments are projected into
project_graph_objects via extract_project_semantics + persist_project_graph_
projection. This makes the projects /candidates surface return real data instead
of an empty store.

Safety:
- Gated behind PROJECT_GRAPH_EXTRACTION_ENABLED (default False) -> zero change
  to existing import behavior until explicitly enabled.
- Best-effort: runs AFTER the email is committed, wrapped in try/except with
  rollback, so a projection failure never fails the email import.
- Segments are snapshotted before commit (in-memory, no async lazy-load) to
  avoid MissingGreenlet; persistence runs after commit when segments have ids.
- Workspace scope uses the repository's convention (workspace-<org_id>, or
  workspace-<user_id> without an org).

Tests (tests/test_project_graph_import_wiring.py, 6): real deterministic
extractor + mocked persistence — mapping, workspace scoping (org + user
fallback), no-op on empty/no-objects, and best-effort rollback on failure.
Existing import + project-graph suites unaffected (56 passed).

This is Phase 1 of docs/plans/2026-07-06-ai-moat-project-graph-activation.md.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017RkKdtHRLG4wSLh6PVsp8J
import pytest
from unittest.mock import AsyncMock

import services.email_import_service as import_service
@github-actions

github-actions Bot commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

PR governance metadata gate is not ready for e832868d6f54c8fa5a0367ecfd4b8dfac3248a6f:

  • 1 unresolved current review thread(s) remain.

@seonghobae

Copy link
Copy Markdown
Contributor Author

Folded into #931, which is now retargeted to develop as one independent PR (this was a stacked PR that could not auto-merge). Closing to avoid duplicate/tangled merge order.

@seonghobae seonghobae closed this Jul 6, 2026
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.

1 participant