Add 'fiscal/' from commit '102ba84500dbd9655a0471288c3e278652593ca9'

git-subtree-dir: fiscal
git-subtree-mainline: d95165fc8f
git-subtree-split: 102ba84500
This commit is contained in:
gti
2026-09-29 14:43:23 -03:00
868 changed files with 566394 additions and 0 deletions
+661
View File
@@ -0,0 +1,661 @@
"""Run the narrowly scoped, read-only Mission 00 Firebird probe."""
from __future__ import annotations
import argparse
import ctypes
import importlib.metadata
import json
import os
import platform
import re
import struct
import sys
from pathlib import Path
from typing import Any
PROJECT_ROOT = Path(__file__).resolve().parents[1]
sys.path.insert(0, str(PROJECT_ROOT / "src"))
from gti_discovery.firebird_connection import (
AUTHORIZED_DATABASE_PATH,
_FirebirdAdapter,
_ADAPTER_CREATION_TOKEN,
_create_firebird_adapter,
connect_authorized_read_only,
get_database_identity,
validate_authorized_database_path,
validate_authorized_database_identity,
)
from gti_discovery.collector import _safe_sample_rows, collect_metadata
from gti_discovery.fingerprint import (
SCHEMA_CHANGED,
SCHEMA_SUPPORTED,
SCHEMA_UNKNOWN,
build_fingerprint,
classify_schema,
)
from gti_discovery.mapping import build_schema_mapping, identify_product_candidates
from gti_discovery.provenance import (
ProvenanceError,
validate_fdb_provenance,
validate_imported_fdb_provenance,
)
DEFAULT_TARGET = AUTHORIZED_DATABASE_PATH
CLIENT_LIBRARY = Path(r"C:\Program Files\Firebird\Firebird_2_5\bin\fbclient.dll")
_BLOCKER_CATEGORIES = {
ValueError: "target_rejected",
ImportError: "driver_unavailable",
FileNotFoundError: "client_library_unavailable",
PermissionError: "connection_failed",
RuntimeError: "connection_failed",
}
class _FdbDriver:
version = "unknown"
def __init__(self, fdb_module: Any):
self._fdb = fdb_module
self.version = str(getattr(fdb_module, "__version__", "unknown"))
self._last_connection = None
def connect(self, **options):
if set(options) - {"database", "read_only", "client_library"}:
raise RuntimeError("unexpected connection settings")
if options.pop("read_only", None) is not True:
raise RuntimeError("read-only mode is required")
client_library = options.pop("client_library", None)
user = os.environ.get("FB_USER")
password = os.environ.get("FB_PASSWORD")
if not user or not password:
raise RuntimeError("Firebird credentials are unavailable in FB_USER/FB_PASSWORD")
isolation_level = _read_only_isolation_level(self._fdb)
raw = self._fdb.connect(
database=options["database"],
user=user,
password=password,
fb_library_name=client_library,
isolation_level=isolation_level,
)
self._last_connection = raw
observed = getattr(raw, "default_tpb", None)
if observed != isolation_level:
close = getattr(raw, "close", None)
if callable(close):
close()
raise RuntimeError("driver did not establish the fdb read-only TPB")
evidence = {
"accepted": True,
"driver_api": "fdb.Connection.default_tpb",
"configured_tpb": bytes(isolation_level),
"observed_default_tpb": bytes(observed),
}
return _create_firebird_adapter(raw, evidence, _ADAPTER_CREATION_TOKEN)
def facts(self) -> dict[str, Any]:
return {name: _fact(self._last_connection, name) for name in (
"engine_version", "database_sql_dialect", "ods_version",
"ods_minor_version", "charset", "page_size",
)}
def compatibility_evidence(self, client_version: str) -> dict[str, Any]:
isolation_level = _read_only_isolation_level(self._fdb)
return {
"fdb_version": self.version,
"client_version": client_version,
"firebird_version": ".".join(str(client_version).split(".")[:3]),
"read_only_isolation": _read_only_isolation_level(self._fdb) is not None,
"read_only_tpb": bytes(isolation_level),
"read_only_api": "fdb.Connection.default_tpb",
}
def _read_only_isolation_level(fdb: Any) -> Any:
"""Use fdb 2.0.4's actual read-only TPB constant (including its spelling)."""
value = getattr(fdb, "ISOLATION_LEVEL_READ_COMMITED_RO", None)
if isinstance(value, bytes) and value == b"\x03\x08\x06\x0f\x11":
return value
raise RuntimeError("fdb read-only isolation API is unavailable")
def _fact(connection: Any, name: str) -> Any:
try:
value = getattr(connection, name)
except Exception:
return None
if isinstance(value, (str, int, float, bool)) or value is None:
return value
return str(value)
def _read_file_version(path: Path) -> str | None:
"""Read Windows file-version metadata without loading the client DLL."""
if sys.platform != "win32":
return None
try:
version = ctypes.windll.version
size = version.GetFileVersionInfoSizeW(str(path), None)
if not size:
return None
buffer = ctypes.create_string_buffer(size)
if not version.GetFileVersionInfoW(str(path), 0, size, buffer):
return None
pointer = ctypes.c_void_p()
length = ctypes.c_uint()
if not version.VerQueryValueW(buffer, "\\", ctypes.byref(pointer), ctypes.byref(length)):
return None
class FixedFileInfo(ctypes.Structure):
_fields_ = [("signature", ctypes.c_uint32), ("struct_version", ctypes.c_uint32),
("file_version_ms", ctypes.c_uint32), ("file_version_ls", ctypes.c_uint32)]
info = ctypes.cast(pointer, ctypes.POINTER(FixedFileInfo)).contents
return ".".join((str(info.file_version_ms >> 16), str(info.file_version_ms & 0xffff),
str(info.file_version_ls >> 16), str(info.file_version_ls & 0xffff)))
except Exception:
return None
def _client_metadata(path: Path) -> dict[str, Any]:
exists = path.is_file()
return {"path": str(path), "exists": exists, "version": _read_file_version(path) if exists else None}
def _read_client_architecture(path: Path) -> str:
"""Read PE architecture metadata without loading or executing the DLL."""
try:
with path.open("rb") as handle:
if handle.read(2) != b"MZ":
return "UNKNOWN"
handle.seek(0x3C)
offset = struct.unpack("<I", handle.read(4))[0]
handle.seek(offset)
if handle.read(4) != b"PE\x00\x00":
return "UNKNOWN"
machine = struct.unpack("<H", handle.read(2))[0]
except (OSError, struct.error):
return "UNKNOWN"
return {0x014C: "x86", 0x8664: "x64", 0xAA64: "arm64"}.get(machine, "UNKNOWN")
def _python_architecture() -> str:
return "x64" if struct.calcsize("P") == 8 else "x86" if struct.calcsize("P") == 4 else "UNKNOWN"
def validate_firebird_runtime(*, fdb_module: Any = None) -> dict[str, Any]:
"""Return deterministic dependency evidence; never infer unknown facts."""
try:
provenance = validate_fdb_provenance()
except ProvenanceError as error:
return {"status": "UNKNOWN", "blocker": "compatibility_unproven", "provenance": error.evidence}
client = _client_metadata(CLIENT_LIBRARY)
client = dict(client)
client["architecture"] = client.get("architecture", _read_client_architecture(CLIENT_LIBRARY))
distribution_version = None
try:
distribution_version = importlib.metadata.version("fdb")
except (importlib.metadata.PackageNotFoundError, ImportError):
pass
fdb_version = getattr(fdb_module, "__version__", distribution_version)
python_architecture = _python_architecture()
read_only_api = (
fdb_module is not None
and isinstance(getattr(fdb_module, "ISOLATION_LEVEL_READ_COMMITED_RO", None), bytes)
and getattr(fdb_module, "ISOLATION_LEVEL_READ_COMMITED_RO") == b"\x03\x08\x06\x0f\x11"
)
version_match = fdb_version == "2.0.4" and distribution_version == "2.0.4"
architecture_match = client["architecture"] in {"x86", "x64", "arm64"} and (
(python_architecture == "x64" and client["architecture"] == "x64")
or (python_architecture == "x86" and client["architecture"] == "x86")
)
valid = (
provenance.get("status") == "VALID"
and client["exists"] is True
and client["version"] == "2.5.9.27139"
and client["architecture"] != "UNKNOWN"
and architecture_match
and version_match
and fdb_module is not None
and read_only_api
)
compatibility = {
"status": "VALID" if valid else "UNKNOWN",
"python_client_architecture_match": architecture_match,
"fdb_client_version_match": version_match,
"read_only_api": read_only_api,
}
return {
"status": "VALID" if valid else "UNKNOWN",
"python_runtime": {"version": platform.python_version(), "architecture": python_architecture},
"fdb": {"version": fdb_version, "distribution_version": distribution_version},
"client": client,
"provenance": provenance,
"compatibility": compatibility,
**({} if valid else {"blocker": "compatibility_unproven"}),
}
def _blocker_category(error: Exception) -> str:
if type(error).__name__ == "DatabaseError" and (
"-902" in str(error) or "user name and password are not defined" in str(error).lower()
):
return "credentials_rejected"
if isinstance(error, ValueError) and "read-only" in str(error).lower():
return "read_only_unproven"
if isinstance(error, RuntimeError) and "credentials" in str(error).lower():
return "credentials_unavailable"
if isinstance(error, RuntimeError) and "compatib" in str(error).lower():
return "compatibility_unproven"
if isinstance(error, RuntimeError) and "provenance" in str(error).lower():
return "compatibility_unproven"
return next((category for error_type, category in _BLOCKER_CATEGORIES.items()
if isinstance(error, error_type)), "unexpected_failure")
def _firebird_259(version: Any) -> bool:
match = re.match(r"^(\d+)\.(\d+)\.(\d+)", str(version or ""))
return bool(match and tuple(int(item) for item in match.groups()) == (2, 5, 9))
def _validate_runtime_compatibility(driver: Any) -> dict[str, Any]:
"""Prove the installed 2.5.9 client and usable driver before connect."""
client = _client_metadata(CLIENT_LIBRARY)
if not client["exists"] or not _firebird_259(client["version"]):
raise RuntimeError("Firebird 2.5.9 client compatibility is unproven")
if type(driver) is not _FdbDriver:
raise RuntimeError("Firebird driver/client compatibility is unproven")
try:
import fdb as installed_fdb
installed_version = importlib.metadata.version("fdb")
except (ImportError, importlib.metadata.PackageNotFoundError) as error:
raise RuntimeError("Firebird driver/client compatibility is unproven") from error
if (
driver._fdb is not installed_fdb
or installed_version != "2.0.4"
or getattr(installed_fdb, "__version__", None) != "2.0.4"
or _read_only_isolation_level(installed_fdb) != b"\x03\x08\x06\x0f\x11"
):
raise RuntimeError("Firebird driver/client compatibility is unproven")
return client
def _validate_preimport_compatibility() -> dict[str, Any]:
provenance = validate_fdb_provenance()
client = _client_metadata(CLIENT_LIBRARY)
client = dict(client)
client["architecture"] = client.get("architecture", _read_client_architecture(CLIENT_LIBRARY))
try:
fdb_version = importlib.metadata.version("fdb")
except importlib.metadata.PackageNotFoundError as error:
raise RuntimeError("fdb 2.0.4 compatibility is unproven") from error
if (
not client["exists"]
or not _firebird_259(client["version"])
or client["architecture"] == "UNKNOWN"
or client["architecture"] != _python_architecture()
or fdb_version != "2.0.4"
):
raise RuntimeError("Firebird 2.5.9/fdb 2.0.4 compatibility is unproven")
if not _preimport_read_only_api_proven():
raise RuntimeError("Firebird read-only isolation API compatibility is unproven")
return {"client": client, "provenance": provenance}
def _preimport_read_only_api_proven() -> bool:
"""Prove the pinned driver's read-only API from installed source, without import."""
try:
spec = __import__("importlib.util", fromlist=["find_spec"]).find_spec("fdb")
locations = list(getattr(spec, "submodule_search_locations", ()) or ())
if not locations:
return False
package = Path(locations[0])
init_source = (package / "__init__.py").read_text(encoding="utf-8")
core_source = (package / "fbcore.py").read_text(encoding="utf-8")
except (OSError, UnicodeError, ImportError, AttributeError, TypeError):
return False
return (
"ISOLATION_LEVEL_READ_COMMITED_RO" in init_source
and "ISOLATION_LEVEL_READ_COMMITED_RO = bs([" in core_source
and all(token in core_source for token in (
"isc_tpb_version3", "isc_tpb_read", "isc_tpb_wait",
"isc_tpb_read_committed", "isc_tpb_rec_version",
))
)
def _security_gate(path: os.PathLike[str] | str, driver: Any) -> dict[str, Any]:
validate_authorized_database_path(path)
if not os.environ.get("FB_USER") or not os.environ.get("FB_PASSWORD"):
raise RuntimeError("Firebird credentials are unavailable in FB_USER/FB_PASSWORD")
evidence = validate_firebird_runtime(fdb_module=getattr(driver, "_fdb", None))
if evidence["status"] != "VALID":
raise RuntimeError("Firebird driver/client compatibility is unproven")
return {"client": evidence["client"], "compatibility_evidence": evidence}
_SAMPLE_DENYLIST = (
"CUSTOMER", "CLIENT", "EMAIL", "PHONE", "MOBILE", "CONTACT", "ADDRESS",
"PRICE", "COST", "AMOUNT", "TOTAL", "TAX", "CRED", "PASSWORD",
"SECRET", "TOKEN", "BLOB", "SOURCE", "DEFAULT", "SALARY", "MARGIN",
"DISCOUNT", "PROFIT", "IMAGE", "PHOTO", "FILE", "PATH", "URL",
)
_SAMPLE_ALLOWLIST = (
"ID", "KEY", "CODE", "CODIGO", "SKU", "ITEM", "PRODUCT", "DESCRIPTION",
"DESCRICAO", "NAME", "NOME", "BARCODE", "EAN", "GTIN", "REFERENCE",
"REFERENCIA", "REF", "UNIT", "UNIDADE", "CATEGORY", "GROUP", "GRUPO",
"BRAND", "MARCA", "PRODUTO", "ESTOQUE", "STATUS", "ACTIVE", "ATIVO",
)
def _permitted_sample_plan(metadata: dict[str, Any]) -> list[tuple[str, list[str]]]:
fields_by_relation: dict[str, list[dict[str, Any]]] = {}
for field in metadata.get("fields", []):
if not isinstance(field, dict):
continue
relation = str(field.get("RELATION_NAME", "")).strip()
if relation:
fields_by_relation.setdefault(relation.upper(), []).append(field)
candidates = identify_product_candidates(metadata, {})
plan = []
for candidate in candidates:
relation = str(candidate.get("relation", "")).strip()
if not relation or candidate.get("classification") == "UNKNOWN":
continue
columns = []
for field in fields_by_relation.get(relation.upper(), []):
name = str(field.get("FIELD_NAME", "")).strip()
type_name = str(field.get("TYPE_NAME", field.get("FIELD_TYPE", ""))).upper()
upper_name = name.upper()
if not name or any(word in upper_name for word in _SAMPLE_DENYLIST):
continue
if "BLOB" in type_name or not any(word in upper_name for word in _SAMPLE_ALLOWLIST):
continue
columns.append(name)
if columns:
plan.append((relation, columns[:8]))
return plan
def _collect_samples(reader: Any, metadata: dict[str, Any]) -> dict[str, list[dict[str, Any]]]:
samples = {}
plan = _permitted_sample_plan(metadata)
if not isinstance(plan, list) or any(
not isinstance(item, tuple)
or len(item) != 2
or not isinstance(item[0], str)
or not isinstance(item[1], list)
or not item[1]
or any(
not isinstance(column, str)
or any(word in column.upper() for word in _SAMPLE_DENYLIST)
or not any(word in column.upper() for word in _SAMPLE_ALLOWLIST)
for column in item[1]
)
for item in plan
):
raise RuntimeError("sample plan is not permitted")
for relation, columns in plan:
rows = reader.sample_relation_rows(relation, columns, 5)
if not isinstance(rows, list) or any(not isinstance(row, dict) for row in rows):
raise RuntimeError("sample evidence is malformed")
samples[relation] = _safe_sample_rows(rows)
return samples
def _blocked(
blocker: str,
*,
connection_attempts: int = 0,
other_databases_accessed: int | str = 0,
) -> dict[str, Any]:
return {
"status": "MISSION_00_BLOCKED",
"blocker": blocker,
"application_writes": 0,
"other_databases_accessed": other_databases_accessed,
"connection_attempts": connection_attempts,
}
def _valid_metadata(metadata: Any) -> bool:
if not isinstance(metadata, dict):
return False
if not all(isinstance(metadata.get(name), list) for name in ("relations", "fields", "errors", "unavailable")):
return False
return (
all(isinstance(row, dict) for name in ("relations", "fields", "errors") for row in metadata[name])
and all(isinstance(name, str) and bool(name) for name in metadata["unavailable"])
)
def _valid_mapping(mapping: Any) -> bool:
required = {"product", "fields", "fiscal", "stock", "media", "incremental", "triggers"}
if type(mapping) is not dict or set(mapping) != required:
return False
allowed = {"CONFIRMED", "INFERRED", "UNKNOWN"}
def strings(value: Any) -> bool:
return type(value) is list and all(type(item) is str and bool(item) for item in value)
def classified(value: Any, keys: set[str]) -> bool:
return type(value) is dict and set(value) == keys and value["classification"] in allowed
def field_record(value: Any) -> bool:
if type(value) is not dict or not {"classification", "sample_present", "type"} <= set(value):
return False
if set(value) - {"classification", "sample_present", "type", "subtype", "value"}:
return False
return value["classification"] in allowed and type(value["sample_present"]) is bool and type(value["type"]) is str and bool(value["type"]) and all(
type(value[key]) in (str, int, float, bool) for key in ("subtype", "value") if key in value
)
def field_map(value: Any) -> bool:
return type(value) is dict and all(type(key) is str and bool(key) and field_record(item) for key, item in value.items())
def relation_record(value: Any) -> bool:
if type(value) is not dict or not {"classification", "fields", "relationships"} <= set(value):
return False
if set(value) - {"classification", "fields", "relationships", "evidence"}:
return False
relationships = value["relationships"]
return value["classification"] in allowed and field_map(value["fields"]) and type(relationships) is list and all(
type(item) is dict and set(item) == {"child_relation", "child_field", "referenced_relation", "referenced_field"}
and all(type(item[key]) is str and bool(item[key]) for key in item)
for item in relationships
) and ("evidence" not in value or type(value["evidence"]) is str)
def relation_map(value: Any) -> bool:
return type(value) is dict and all(type(key) is str and bool(key) and relation_record(item) for key, item in value.items())
product = mapping["product"]
product_keys = {"classification", "relation", "evidence", "candidates"}
candidate_keys = {"classification", "relation", "evidence"}
evidence_keys = {"primary_key", "field_count", "semantic_fields", "sample_fields", "semantic_sample_fields", "approximate_count"}
if not classified(product, product_keys) or (product["relation"] is not None and (type(product["relation"]) is not str or not product["relation"])) or type(product["evidence"]) is not dict or set(product["evidence"]) - evidence_keys:
return False
candidates = product.get("candidates")
if not isinstance(candidates, list) or not all(
classified(item, candidate_keys) and type(item["relation"]) is str and bool(item["relation"])
and type(item["evidence"]) is dict and set(item["evidence"]) - evidence_keys == set()
and strings(item["evidence"].get("primary_key"))
and type(item["evidence"].get("field_count")) is int
and strings(item["evidence"].get("semantic_fields")) for item in candidates
):
return False
for evidence in (product["evidence"], *(item["evidence"] for item in candidates)):
if not evidence:
continue
if not strings(evidence.get("primary_key")) or type(evidence.get("field_count")) is not int or evidence["field_count"] < 0 or not strings(evidence.get("semantic_fields")):
return False
if "sample_fields" in evidence and not strings(evidence["sample_fields"]):
return False
if "semantic_sample_fields" in evidence and not strings(evidence["semantic_sample_fields"]):
return False
if "approximate_count" in evidence and type(evidence["approximate_count"]) not in (str, int, float, bool, type(None)):
return False
if not field_map(mapping["fields"]):
return False
for section in ("fiscal", "media"):
value = mapping[section]
if not classified(value, {"classification", "fields", "relations"}) or not field_map(value["fields"]) or not relation_map(value["relations"]):
return False
if not classified(mapping["stock"], {"classification", "relations"}) or not relation_map(mapping["stock"]["relations"]):
return False
incremental = mapping["incremental"]
evidence = incremental.get("evidence")
if not classified(incremental, {"classification", "evidence"}) or type(evidence) is not dict or set(evidence) != {"timestamps", "triggers", "generators"}:
return False
if not strings(evidence["timestamps"]) or type(evidence["triggers"]) is not int or evidence["triggers"] < 0 or type(evidence["generators"]) is not int or evidence["generators"] < 0:
return False
triggers = mapping["triggers"]
return type(triggers) is list and all(
classified(trigger, {"classification", "relation", "trigger", "timing", "event", "trigger_type", "dependencies", "source"})
and all(type(trigger[key]) is str and bool(trigger[key]) for key in ("relation", "trigger", "timing", "event", "source"))
and type(trigger["trigger_type"]) in (str, int) and bool(str(trigger["trigger_type"]))
and strings(trigger.get("dependencies"))
for trigger in triggers
)
def _valid_fingerprint(value: Any) -> bool:
return isinstance(value, str) and bool(re.fullmatch(r"[0-9a-f]{64}", value))
def _public_compatibility(evidence: Any) -> dict[str, str]:
"""Expose compatibility categories only; never serialize internal evidence."""
if not isinstance(evidence, dict):
return {"status": "UNKNOWN"}
return {
"status": evidence.get("status", "UNKNOWN") if evidence.get("status") in {"VALID", "UNKNOWN"} else "UNKNOWN",
"architecture": "MATCH" if evidence.get("compatibility", {}).get("python_client_architecture_match") is True else "UNKNOWN",
"fdb_client": "MATCH" if evidence.get("compatibility", {}).get("fdb_client_version_match") is True else "UNKNOWN",
"read_only_api": "PROVEN" if evidence.get("compatibility", {}).get("read_only_api") is True else "UNKNOWN",
}
def _public_metadata(metadata: dict[str, Any]) -> dict[str, Any]:
"""Remove database identity rows, which may contain an absolute FDB path."""
return {key: value for key, value in metadata.items() if key != "database"}
def run_discovery(path: os.PathLike[str] | str, *, driver: Any) -> dict[str, Any]:
"""Run the gated, structured, sanitized discovery workflow."""
try:
security = _security_gate(path, driver)
client = security.get("client", security)
except RuntimeError as error:
return _blocked(_blocker_category(error))
try:
connection = connect_authorized_read_only(
path, driver, client_library=str(CLIENT_LIBRARY)
)
except Exception as error:
return _blocked(_blocker_category(error), connection_attempts=1)
try:
try:
database_name = get_database_identity(connection)
validate_authorized_database_identity(database_name, path)
except Exception:
return _blocked(
"identity_mismatch",
connection_attempts=1,
other_databases_accessed="UNKNOWN",
)
try:
facts = driver.facts() if callable(getattr(driver, "facts", None)) else {}
metadata = collect_metadata(connection)
if not _valid_metadata(metadata):
return _blocked("discovery_invalid", connection_attempts=1)
samples = _collect_samples(connection, metadata)
mapping = build_schema_mapping(metadata, samples)
if not _valid_mapping(mapping):
return _blocked("discovery_invalid", connection_attempts=1)
unavailable = set(metadata.get("unavailable", []))
optional_catalog_gaps = {"events", "packages", "procedure_parameters"}
blocking_errors = [
error for error in metadata.get("errors", [])
if not (
error.get("kind") == "optional_unsupported"
or error.get("query") == "monitoring"
)
]
complete = (
not blocking_errors
and unavailable <= optional_catalog_gaps
and (not metadata.get("incomplete") or bool(unavailable) and unavailable <= optional_catalog_gaps)
and bool(metadata.get("relations"))
and bool(samples)
)
fingerprint = None
classification = SCHEMA_UNKNOWN
if complete:
evidence = {"metadata": metadata, "samples": samples, "mapping": mapping}
fingerprint = build_fingerprint(evidence)
if not _valid_fingerprint(fingerprint):
return _blocked("discovery_invalid", connection_attempts=1)
expected = getattr(driver, "expected_fingerprints", ())
classification = classify_schema(
metadata,
expected,
mapping_ambiguous=mapping.get("product", {}).get("classification") == "UNKNOWN",
)
if classification not in {SCHEMA_SUPPORTED, SCHEMA_CHANGED, SCHEMA_UNKNOWN}:
return _blocked("discovery_invalid", connection_attempts=1)
return {
"status": "CONNECTED" if complete else SCHEMA_UNKNOWN,
"driver_version": str(getattr(driver, "version", "unknown")),
"architecture": platform.architecture()[0],
"engine_version": facts.get("engine_version"),
"dialect": facts.get("database_sql_dialect"),
"ods": {
"major": facts.get("ods_version"),
"minor": facts.get("ods_minor_version"),
},
"charset": facts.get("charset"),
"page_size": facts.get("page_size"),
"metadata": _public_metadata(metadata),
"samples": samples,
"schema_mapping": mapping,
"fingerprint": fingerprint,
"schema_classification": classification,
"compatibility": _public_compatibility(security.get("compatibility_evidence")),
"application_writes": 0,
"other_databases_accessed": 0,
"connection_attempts": 1,
}
except Exception:
return _blocked("discovery_failed", connection_attempts=1)
finally:
connection.close()
def main(argv: list[str] | None = None) -> int:
parser = argparse.ArgumentParser(description=__doc__)
parser.parse_args(argv)
try:
if not os.environ.get("FB_USER") or not os.environ.get("FB_PASSWORD"):
raise RuntimeError("credentials unavailable")
compatibility = _validate_preimport_compatibility()
import fdb
provenance = validate_imported_fdb_provenance(fdb)
runtime_compatibility = validate_firebird_runtime(fdb_module=fdb)
if runtime_compatibility["status"] != "VALID":
raise RuntimeError("Firebird driver/client compatibility is unproven")
result = run_discovery(DEFAULT_TARGET, driver=_FdbDriver(fdb))
result["compatibility"] = _public_compatibility(runtime_compatibility)
except Exception as error:
result = {
"status": "MISSION_00_BLOCKED",
"blocker": _blocker_category(error),
"application_writes": 0,
"other_databases_accessed": 0,
"connection_attempts": 0,
}
print(json.dumps(result, ensure_ascii=True, sort_keys=True))
return 0 if result["status"] == "CONNECTED" else 2
if __name__ == "__main__":
sys.exit(main())