Core Components Distinction Guide
This document aims to clarify the distinction between the different “Core” components within the SecInterp project to avoid confusion for both human developers and AI agents.
⚠️ The Fundamental Distinction
Two “Core” entities coexist in this development environment:
SecInterp Core (The Project’s Kernel):
Location:
/coredirectory within the project root.Purpose: Contains pure business logic, geological algorithms, processing services, and domain models (DTOs) specific to SecInterp.
Current State: Decoupled. As of version 2.8.0, this module has been sanitized to have no direct dependencies on QGIS live classes during heavy processing (Thread-Safe).
QGIS Core (The QGIS API):
Reference:
qgis.corePython package.Purpose: Provides the underlying geospatial infrastructure (geometries, layers, projects, CRS).
Interaction: SecInterp uses
qgis.coreto extract data in the main thread, but the SecInterp Core processes this data using agnostic types (WKT, dictionaries, primitives).
🧭 Guidelines for Developers and AI
To maintain architectural integrity, follow these directives:
1. Do not assume “Core” always means QGIS
If asked to “review the core”, it almost exclusively refers to the /core directory of this plugin. Do not attempt to search for or modify internal files of the QGIS engine.
2. Data Boundaries (Decoupling)
Inside
/core: Agnostic domain types must be used. Avoid instantiatingQgsVectorLayeror accessingQgsProject.instance()within kernel services. UseDomainGeometry(WKT) and attribute dictionaries.Inside
/gui: This is where the translation between the real QGIS API (qgis.core) and the SecInterp Core takes place. Geometries are extracted and DTOs are prepared here.
3. File Naming and Imports
Local Files: Files in
core/(e.g.,core/services/geology_service.py) are the SecInterp Brain.External API: Imports starting with
qgis.core,qgis.gui, orqgis.utilsare External Dependencies.Naming Rule: In discussions or code comments, use “Internal Core” to refer to
/coreand “PyQGIS API” for the software’s API.
4. The “Extract-then-Compute” Pattern
To avoid future complications, the data flow MUST follow this pattern:
GUI/Task Interface Layer: Receives QGIS objects (
QgsVectorLayer,QgsFeature). Extracts what is necessary (WKT geometry, attribute dictionaries).Core Layer: Receives only the extracted data (strings, dicts, floats). Performs heavy geometric calculations.
Result: The Core returns DTOs (Data Transfer Objects) defined in
core/types.py. The GUI layer is responsible for converting these back to QGIS layers if necessary.
5. Golden Rules for Thread-Safety
Prohibited: Importing
qgis.guiinsidecore/. Background threads will crash if they attempt to touch any widget or window.Restriction: Minimize the use of
qgis.coreinsidecore/. While some classes likeQgsGeometryare thread-safe, it is preferable to operate on WKT to guarantee total independence.Application Context: Never use
ifaceorQgsProject.instance()insidecore/. If project data is needed, pass it as pre-extracted arguments.
🧪 Differentiated Testing Strategy
Core Tests (
tests/core/): Must be able to run without a full QGIS installation. They use lightweight mocks. They are the thermometer of geological logic.Integration Tests (
tests/integration/): Require real QGIS. They test that our “Core” correctly communicates with the “QGIS API”.
🛠️ Decoupling Summary (January 2026)
A major effort has been completed to ensure:
GeologyServicedoes not use live QGIS layers in its processing method.DrillholeServiceuses dictionaries instead ofQgsFeatureobjects during trace calculation.3D projection logic accepts tuples and primitive types.
In summary: Keep our Core “pure”. Treat QGIS as an external service provider. Do not let the roots of one enter the logic of the other.