From 88f5571bf9a09d897cd59a0b0668ebce0217e3db Mon Sep 17 00:00:00 2001 From: "Aaron D. Lee" Date: Thu, 2 Apr 2026 15:07:31 -0400 Subject: [PATCH] Complete rebrand cleanup: remaining env vars and references MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix STEGASOO_* env vars → FIELDWITNESS_* and VERISOO_* → FIELDWITNESS_* across stego module, attest module, and frontends. Wire format identifiers (VERISOO\x00 magic bytes, STEGASOO-Z: QR prefixes) intentionally preserved for backwards compatibility. Co-Authored-By: Claude Opus 4.6 (1M context) --- CLAUDE.md | 10 +++++----- README.md | 18 +++++++++--------- docs/deployment.md | 2 +- frontends/web/static/js/fieldwitness.js | 4 ++-- frontends/web/templates/stego/about.html | 2 +- src/fieldwitness/attest/api.py | 2 +- src/fieldwitness/attest/cli.py | 4 ++-- src/fieldwitness/attest/embed.py | 24 ++++++++++++------------ src/fieldwitness/keystore/manager.py | 6 +++--- src/fieldwitness/paths.py | 4 ++-- src/fieldwitness/stego/__init__.py | 4 ++-- src/fieldwitness/stego/api.py | 4 ++-- src/fieldwitness/stego/api_auth.py | 2 +- src/fieldwitness/stego/channel.py | 6 +++--- src/fieldwitness/stego/cli.py | 16 ++++++++-------- src/fieldwitness/stego/constants.py | 6 +++--- src/fieldwitness/stego/debug.py | 10 +++++----- src/fieldwitness/stego/decode.py | 4 ++-- src/fieldwitness/stego/encode.py | 4 ++-- 19 files changed, 66 insertions(+), 66 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index 508f89e..cfa0d99 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -34,9 +34,9 @@ src/fieldwitness/ Core library __init__.py Package init, __version__ (0.2.0) _availability.py Runtime checks for optional subpackages (has_stego, has_attest) api.py Optional unified FastAPI app (uvicorn fieldwitness.api:app) - audit.py Append-only JSON-lines audit log (~/.fieldwitness/audit.jsonl) + audit.py Append-only JSON-lines audit log (~/.fwmetadata/audit.jsonl) cli.py Click CLI entry point (fieldwitness command) - paths.py All ~/.fieldwitness/* path constants (single source of truth, lazy resolution) + paths.py All ~/.fwmetadata/* path constants (single source of truth, lazy resolution) config.py Unified config loader (FieldWitnessConfig dataclass + JSON) exceptions.py FieldWitnessError, ChainError, ChainIntegrityError, ChainAppendError, KeystoreError metadata.py Extract-then-strip EXIF pipeline with field classification @@ -179,7 +179,7 @@ Stego and Attest are inlined subpackages, not separate pip packages: - **Extract-then-strip model**: Stego strips all EXIF (carrier is vessel); attestation extracts evidentiary EXIF (GPS, timestamp) then strips dangerous fields (device serial) - **subprocess_stego.py copies verbatim** from fieldwitness.stego -- it's a crash-safety boundary -- **All state under ~/.fieldwitness/** -- one directory to back up, one to destroy. +- **All state under ~/.fwmetadata/** -- one directory to back up, one to destroy. `FIELDWITNESS_DATA_DIR` env var relocates everything (cover mode, USB mode) - **Offline-first**: All static assets vendored, no CDN. pip wheels bundled for airgap install - **Flask blueprints**: stego, attest, fieldkit, keys, admin, dropbox, federation @@ -208,10 +208,10 @@ Stego and Attest are inlined subpackages, not separate pip packages: - **Transport-aware stego**: --transport whatsapp|signal|telegram auto-selects DCT/JPEG and pre-resizes carrier for platform survival -## Data directory layout (`~/.fieldwitness/`) +## Data directory layout (`~/.fwmetadata/`) ``` -~/.fieldwitness/ +~/.fwmetadata/ config.json Unified configuration (FieldWitnessConfig dataclass) audit.jsonl Append-only audit trail (JSON-lines) carrier_history.json Carrier reuse tracking database diff --git a/README.md b/README.md index 7740061..b4c41d7 100644 --- a/README.md +++ b/README.md @@ -48,7 +48,7 @@ fieldwitness init fieldwitness serve ``` -This creates the `~/.fieldwitness/` directory structure, generates an Ed25519 identity and +This creates the `~/.fwmetadata/` directory structure, generates an Ed25519 identity and channel key, writes a default config, and starts an HTTPS web UI on `https://127.0.0.1:5000`. @@ -146,7 +146,7 @@ responses. ### Field Security (Fieldkit) -- **Killswitch** -- emergency destruction of all data under `~/.fieldwitness/`, ordered by +- **Killswitch** -- emergency destruction of all data under `~/.fwmetadata/`, ordered by sensitivity (keys first, then data, then logs). Includes: - **Deep forensic scrub** -- removes `__pycache__`, `.pyc`, pip `dist-info`, pip download cache, and scrubs shell history entries containing "fieldwitness" @@ -307,7 +307,7 @@ FieldWitness ships four configuration presets at `deploy/config-presets/`: | `critical-threat.json` | 3 min | On | 6h / 1h grace | "System Statistics" | ```bash -cp deploy/config-presets/high-threat.json ~/.fieldwitness/config.json +cp deploy/config-presets/high-threat.json ~/.fwmetadata/config.json ``` See [docs/deployment.md](docs/deployment.md) for the full deployment guide including @@ -317,7 +317,7 @@ security hardening, Kubernetes manifests, systemd services, and operational secu ## CLI Reference -All commands accept `--data-dir PATH` to override the default `~/.fieldwitness` directory, +All commands accept `--data-dir PATH` to override the default `~/.fwmetadata` directory, and `--json` for machine-readable output. ``` @@ -488,7 +488,7 @@ through Flask blueprints. Served by **Waitress** (production WSGI server) by def ## Configuration -FieldWitness loads configuration from `~/.fieldwitness/config.json`. All fields have sensible defaults. +FieldWitness loads configuration from `~/.fwmetadata/config.json`. All fields have sensible defaults. `fieldwitness init` writes the default config file. ### Config fields @@ -522,7 +522,7 @@ FieldWitness loads configuration from `~/.fieldwitness/config.json`. All fields | Variable | Description | |---|---| -| `FIELDWITNESS_DATA_DIR` | Override the data directory (default: `~/.fieldwitness`). Enables portable USB mode and cover/duress directory naming | +| `FIELDWITNESS_DATA_DIR` | Override the data directory (default: `~/.fwmetadata`). Enables portable USB mode and cover/duress directory naming | --- @@ -582,10 +582,10 @@ deploy/ Deployment artifacts config-presets/ Threat level presets (low/medium/high/critical) ``` -### Data directory (`~/.fieldwitness/`) +### Data directory (`~/.fwmetadata/`) ``` -~/.fieldwitness/ +~/.fwmetadata/ config.json Unified configuration audit.jsonl Append-only audit trail carrier_history.json Carrier reuse tracking database @@ -612,7 +612,7 @@ Sensitive directories (`identity/`, `auth/`, `certs/`, and the root) are created Argon2id from user-supplied factors. Attest uses Ed25519 for signing. These serve different security purposes and are kept strictly separate. -**Killswitch priority.** The killswitch destroys all data under `~/.fieldwitness/`, including +**Killswitch priority.** The killswitch destroys all data under `~/.fwmetadata/`, including the audit log. This is intentional -- in a field compromise scenario, data destruction takes precedence over audit trail preservation. The deep forensic scrub extends beyond the data directory to remove Python bytecache, pip metadata, pip download cache, shell diff --git a/docs/deployment.md b/docs/deployment.md index 1c45e71..b82a35a 100644 --- a/docs/deployment.md +++ b/docs/deployment.md @@ -593,7 +593,7 @@ RestartSec=5 NoNewPrivileges=yes ProtectSystem=strict ProtectHome=read-only -ReadWritePaths=/home/fieldwitness/.fieldwitness +ReadWritePaths=/home/fieldwitness/.fwmetadata PrivateTmp=yes [Install] diff --git a/frontends/web/static/js/fieldwitness.js b/frontends/web/static/js/fieldwitness.js index 8e5f0ed..b488812 100644 --- a/frontends/web/static/js/fieldwitness.js +++ b/frontends/web/static/js/fieldwitness.js @@ -1602,7 +1602,7 @@ const Stego = { // Webcam QR scanning for RSA key (v4.1.5) document.getElementById('rsaQrWebcam')?.addEventListener('click', () => { this.showQrScanner((text) => { - // Check for raw PEM or compressed format (STEGASOO-Z: prefix) + // Check for raw PEM or compressed format (legacy STEGASOO-Z: prefix) const isRawPem = text.includes('-----BEGIN') && text.includes('KEY-----'); const isCompressed = text.startsWith('STEGASOO-Z:'); if (isRawPem || isCompressed) { @@ -1672,7 +1672,7 @@ const Stego = { // Webcam QR scanning for RSA key (v4.1.5) document.getElementById('rsaQrWebcam')?.addEventListener('click', () => { this.showQrScanner((text) => { - // Check for raw PEM or compressed format (STEGASOO-Z: prefix) + // Check for raw PEM or compressed format (legacy STEGASOO-Z: prefix) const isRawPem = text.includes('-----BEGIN') && text.includes('KEY-----'); const isCompressed = text.startsWith('STEGASOO-Z:'); if (isRawPem || isCompressed) { diff --git a/frontends/web/templates/stego/about.html b/frontends/web/templates/stego/about.html index 792a9f4..4395a4d 100644 --- a/frontends/web/templates/stego/about.html +++ b/frontends/web/templates/stego/about.html @@ -325,7 +325,7 @@
This server is running in public mode. - Set STEGASOO_CHANNEL_KEY to enable server-wide channel isolation. + Set FIELDWITNESS_CHANNEL_KEY to enable server-wide channel isolation.
{% endif %} diff --git a/src/fieldwitness/attest/api.py b/src/fieldwitness/attest/api.py index 3f12dc2..a33d10a 100644 --- a/src/fieldwitness/attest/api.py +++ b/src/fieldwitness/attest/api.py @@ -33,7 +33,7 @@ from .crypto import verify_signature, load_public_key_from_bytes # Configuration via environment DATA_DIR = Path(os.environ.get("FIELDWITNESS_DATA_DIR", Path.home() / ".fieldwitness")) -BASE_URL = os.environ.get("VERISOO_BASE_URL", "https://attest.io") +BASE_URL = os.environ.get("FIELDWITNESS_BASE_URL", "https://attest.io") app = FastAPI( title="Attest", diff --git a/src/fieldwitness/attest/cli.py b/src/fieldwitness/attest/cli.py index b60d18c..20d2eb3 100644 --- a/src/fieldwitness/attest/cli.py +++ b/src/fieldwitness/attest/cli.py @@ -686,8 +686,8 @@ def serve(host: str, port: int) -> None: \b ENVIRONMENT VARIABLES: - VERISOO_DATA_DIR Override data directory - VERISOO_BASE_URL Base URL for proof links (default: https://attest.io) + FIELDWITNESS_DATA_DIR Override data directory + FIELDWITNESS_BASE_URL Base URL for proof links (default: https://attest.io) \b SECURITY NOTES: diff --git a/src/fieldwitness/attest/embed.py b/src/fieldwitness/attest/embed.py index 49171ab..7735f1b 100644 --- a/src/fieldwitness/attest/embed.py +++ b/src/fieldwitness/attest/embed.py @@ -37,9 +37,9 @@ try: has_jpegio_support, calculate_dct_capacity, ) - HAS_STEGASOO = True + HAS_STEGO = True except ImportError: - HAS_STEGASOO = False + HAS_STEGO = False has_dct_support = lambda: False has_jpegio_support = lambda: False @@ -50,7 +50,7 @@ except ImportError: # Fixed public seed for Attest proof links # This is intentionally public - anyone should be able to extract the proof link -VERISOO_SEED = b"attest" +ATTEST_SEED = b"attest" # Base URL for proof links DEFAULT_BASE_URL = "https://attest.io" @@ -250,7 +250,7 @@ def embed_proof_in_jpeg( ImportError: If stego is not available ValueError: If image is too small or embedding fails """ - if not HAS_STEGASOO: + if not HAS_STEGO: raise ImportError( "DCT embedding requires stego. " "Ensure stego is installed or available at ../stego" @@ -268,7 +268,7 @@ def embed_proof_in_jpeg( stego_bytes, stats = embed_in_dct( data=payload, carrier_image=image_data, - seed=VERISOO_SEED, + seed=ATTEST_SEED, output_format="jpeg", color_mode="color", ) @@ -291,13 +291,13 @@ def extract_proof_from_jpeg(image_data: bytes) -> str | None: Returns: Proof URL string or None if not found/invalid """ - if not HAS_STEGASOO: + if not HAS_STEGO: return None try: payload = extract_from_dct( stego_image=image_data, - seed=VERISOO_SEED, + seed=ATTEST_SEED, ) # Validate it looks like a proof link @@ -327,7 +327,7 @@ def get_embed_method(image_path: Path) -> str: suffix = image_path.suffix.lower() if suffix in DCT_FORMATS: - if HAS_STEGASOO and has_jpegio_support(): + if HAS_STEGO and has_jpegio_support(): return "dct" else: return "xmp" # Fallback to XMP if stego unavailable @@ -485,7 +485,7 @@ def extract_proof_link(image_path: Path) -> ExtractResult: suffix = image_path.suffix.lower() # Try DCT for JPEG - if suffix in DCT_FORMATS and HAS_STEGASOO: + if suffix in DCT_FORMATS and HAS_STEGO: try: image_data = image_path.read_bytes() proof_link = extract_proof_from_jpeg(image_data) @@ -523,14 +523,14 @@ def extract_proof_link(image_path: Path) -> ExtractResult: def can_embed_dct() -> bool: """Check if DCT embedding is available.""" - return HAS_STEGASOO and has_jpegio_support() + return HAS_STEGO and has_jpegio_support() def get_embed_capabilities() -> dict[str, Any]: """Get information about available embedding capabilities.""" return { - "dct_available": HAS_STEGASOO and has_dct_support(), - "jpeg_native": HAS_STEGASOO and has_jpegio_support(), + "dct_available": HAS_STEGO and has_dct_support(), + "jpeg_native": HAS_STEGO and has_jpegio_support(), "xmp_available": True, # Always available "supported_dct_formats": list(DCT_FORMATS) if can_embed_dct() else [], "supported_xmp_formats": list(XMP_FORMATS | RAW_FORMATS), diff --git a/src/fieldwitness/keystore/manager.py b/src/fieldwitness/keystore/manager.py index 7a5edb0..04079da 100644 --- a/src/fieldwitness/keystore/manager.py +++ b/src/fieldwitness/keystore/manager.py @@ -199,11 +199,11 @@ class KeystoreManager: def has_channel_key(self) -> bool: """Check if a channel key is configured.""" - return bool(os.environ.get("STEGASOO_CHANNEL_KEY")) or self._channel_key_file.exists() + return bool(os.environ.get("FIELDWITNESS_CHANNEL_KEY")) or self._channel_key_file.exists() def get_channel_key(self) -> str | None: """Get the channel key, or None if not configured.""" - env_key = os.environ.get("STEGASOO_CHANNEL_KEY") + env_key = os.environ.get("FIELDWITNESS_CHANNEL_KEY") if env_key: return env_key if self._channel_key_file.exists(): @@ -246,7 +246,7 @@ class KeystoreManager: # representation to back up, so we refuse rather than silently skip. if not self._channel_key_file.exists(): raise KeystoreError( - "Channel key is set via STEGASOO_CHANNEL_KEY environment variable " + "Channel key is set via FIELDWITNESS_CHANNEL_KEY environment variable " "and cannot be rotated through fieldwitness. Unset the variable and store " "the key in the keystore first." ) diff --git a/src/fieldwitness/paths.py b/src/fieldwitness/paths.py index 540edeb..23752b4 100644 --- a/src/fieldwitness/paths.py +++ b/src/fieldwitness/paths.py @@ -30,7 +30,7 @@ _PATH_DEFS: dict[str, tuple[str, ...]] = { # on fragile filesystem mtime. "IDENTITY_META": ("identity", "identity.meta.json"), # Stego state - "STEGASOO_DIR": ("stego",), + "FIELDWITNESS_DIR": ("stego",), "CHANNEL_KEY_FILE": ("stego", "channel.key"), # Attest attestation storage "ATTESTATIONS_DIR": ("attestations",), @@ -84,7 +84,7 @@ def ensure_dirs() -> None: dirs = [ BASE_DIR, __getattr__("IDENTITY_DIR"), - __getattr__("STEGASOO_DIR"), + __getattr__("FIELDWITNESS_DIR"), __getattr__("ATTESTATIONS_DIR"), __getattr__("CHAIN_DIR"), __getattr__("AUTH_DIR"), diff --git a/src/fieldwitness/stego/__init__.py b/src/fieldwitness/stego/__init__.py index b6e8bcb..95ebae5 100644 --- a/src/fieldwitness/stego/__init__.py +++ b/src/fieldwitness/stego/__init__.py @@ -22,7 +22,7 @@ from .channel import ( validate_channel_key, ) -# Audio support — gated by STEGASOO_AUDIO env var and dependency availability +# Audio support — gated by FIELDWITNESS_AUDIO env var and dependency availability from .constants import AUDIO_ENABLED, VIDEO_ENABLED # Crypto functions @@ -87,7 +87,7 @@ else: encode_audio = None decode_audio = None -# Video support — gated by STEGASOO_VIDEO env var and ffmpeg + audio deps +# Video support — gated by FIELDWITNESS_VIDEO env var and ffmpeg + audio deps if VIDEO_ENABLED: from .decode import decode_video from .encode import encode_video diff --git a/src/fieldwitness/stego/api.py b/src/fieldwitness/stego/api.py index ab1e109..08bcb4f 100644 --- a/src/fieldwitness/stego/api.py +++ b/src/fieldwitness/stego/api.py @@ -45,7 +45,7 @@ from pathlib import Path from typing import Literal # Configure logging for API frontend -_log_level = os.environ.get("STEGASOO_LOG_LEVEL", "").strip().upper() +_log_level = os.environ.get("FIELDWITNESS_LOG_LEVEL", "").strip().upper() if _log_level and hasattr(logging, _log_level): logging.basicConfig( level=getattr(logging, _log_level), @@ -53,7 +53,7 @@ if _log_level and hasattr(logging, _log_level): datefmt="%H:%M:%S", stream=sys.stderr, ) -elif os.environ.get("STEGASOO_DEBUG", "").strip() in ("1", "true", "yes"): +elif os.environ.get("FIELDWITNESS_DEBUG", "").strip() in ("1", "true", "yes"): logging.basicConfig( level=logging.DEBUG, format="[%(asctime)s.%(msecs)03d] [%(levelname)s] [%(name)s] %(message)s", diff --git a/src/fieldwitness/stego/api_auth.py b/src/fieldwitness/stego/api_auth.py index e11ab8a..6e5e5a9 100644 --- a/src/fieldwitness/stego/api_auth.py +++ b/src/fieldwitness/stego/api_auth.py @@ -32,7 +32,7 @@ PROJECT_CONFIG_DIR = Path("./config") API_KEYS_FILE = "api_keys.json" # Environment variable for API key (alternative to file) -API_KEY_ENV_VAR = "STEGASOO_API_KEY" +API_KEY_ENV_VAR = "FIELDWITNESS_API_KEY" def _hash_key(key: str) -> str: diff --git a/src/fieldwitness/stego/channel.py b/src/fieldwitness/stego/channel.py index b8718ab..c4eab5e 100644 --- a/src/fieldwitness/stego/channel.py +++ b/src/fieldwitness/stego/channel.py @@ -12,7 +12,7 @@ Use cases: - Public instances: No channel key = compatible with any instance without a channel key Storage priority: -1. Environment variable: STEGASOO_CHANNEL_KEY +1. Environment variable: FIELDWITNESS_CHANNEL_KEY 2. Config file: ~/.stego/channel.key or ./config/channel.key 3. None (public mode - compatible with any instance without a channel key) @@ -39,7 +39,7 @@ CHANNEL_KEY_LENGTH = 32 # Characters (excluding dashes) CHANNEL_KEY_FORMATTED_LENGTH = 39 # With dashes # Environment variable name -CHANNEL_KEY_ENV_VAR = "STEGASOO_CHANNEL_KEY" +CHANNEL_KEY_ENV_VAR = "FIELDWITNESS_CHANNEL_KEY" # Config locations (in priority order) CONFIG_LOCATIONS = [ @@ -200,7 +200,7 @@ def get_channel_key() -> str | None: Get the current channel key from environment or config. Checks in order: - 1. STEGASOO_CHANNEL_KEY environment variable + 1. FIELDWITNESS_CHANNEL_KEY environment variable 2. ./config/channel.key file 3. ~/.stego/channel.key file diff --git a/src/fieldwitness/stego/cli.py b/src/fieldwitness/stego/cli.py index 879f277..7af11de 100644 --- a/src/fieldwitness/stego/cli.py +++ b/src/fieldwitness/stego/cli.py @@ -533,7 +533,7 @@ def audio_encode( if not AUDIO_ENABLED: raise click.UsageError( "Audio support is disabled. Install audio extras (pip install stego[audio]) " - "or set STEGASOO_AUDIO=1 to force enable." + "or set FIELDWITNESS_AUDIO=1 to force enable." ) from .audio_steganography import calculate_audio_lsb_capacity @@ -723,7 +723,7 @@ def audio_decode( if not AUDIO_ENABLED: raise click.UsageError( "Audio support is disabled. Install audio extras (pip install stego[audio]) " - "or set STEGASOO_AUDIO=1 to force enable." + "or set FIELDWITNESS_AUDIO=1 to force enable." ) from .decode import decode_audio @@ -819,7 +819,7 @@ def audio_info(ctx, audio): if not AUDIO_ENABLED: raise click.UsageError( "Audio support is disabled. Install audio extras (pip install stego[audio]) " - "or set STEGASOO_AUDIO=1 to force enable." + "or set FIELDWITNESS_AUDIO=1 to force enable." ) from .audio_steganography import calculate_audio_lsb_capacity @@ -964,7 +964,7 @@ def video_encode( if not VIDEO_ENABLED: raise click.UsageError( "Video support is disabled. Install ffmpeg and audio extras, " - "or set STEGASOO_VIDEO=1 to force enable." + "or set FIELDWITNESS_VIDEO=1 to force enable." ) from .encode import encode_video @@ -1137,7 +1137,7 @@ def video_decode( if not VIDEO_ENABLED: raise click.UsageError( "Video support is disabled. Install ffmpeg and audio extras, " - "or set STEGASOO_VIDEO=1 to force enable." + "or set FIELDWITNESS_VIDEO=1 to force enable." ) from .decode import decode_video @@ -1232,7 +1232,7 @@ def video_info(ctx, video): if not VIDEO_ENABLED: raise click.UsageError( "Video support is disabled. Install ffmpeg and audio extras, " - "or set STEGASOO_VIDEO=1 to force enable." + "or set FIELDWITNESS_VIDEO=1 to force enable." ) from .video_utils import calculate_video_capacity, get_video_info @@ -1713,7 +1713,7 @@ def info(ctx, full): click.echo(json.dumps(info_data, indent=2)) else: # Fastfetch-style output - click.echo(f"\033[1mSTEGASOO\033[0m v{__version__}") + click.echo(f"\033[1mFIELDWITNESS\033[0m v{__version__}") click.echo("─" * 36) # Service status @@ -1819,7 +1819,7 @@ def channel_generate(ctx, save, save_user): click.echo(f"Saved to: {path}") else: click.echo("To use this key:") - click.echo(f' export STEGASOO_CHANNEL_KEY="{key}"') + click.echo(f' export FIELDWITNESS_CHANNEL_KEY="{key}"') click.echo() click.echo("Or save to config:") click.echo(" stego channel generate --save") diff --git a/src/fieldwitness/stego/constants.py b/src/fieldwitness/stego/constants.py index bcb4cf1..5329ed9 100644 --- a/src/fieldwitness/stego/constants.py +++ b/src/fieldwitness/stego/constants.py @@ -320,7 +320,7 @@ def detect_stego_mode(encrypted_data: bytes) -> str: # Environment variables to enable/disable optional feature families. # Values: "auto" (default — detect dependencies), "1"/"true" (force on), # "0"/"false" (force off even if deps are installed). -# Pi builds or minimal installs can set STEGASOO_AUDIO=0 to stay image-only. +# Pi builds or minimal installs can set FIELDWITNESS_AUDIO=0 to stay image-only. import os as _os @@ -370,8 +370,8 @@ def _resolve_feature(toggle: str | bool, dep_check: callable) -> bool: return dep_check() -_audio_toggle = _parse_feature_toggle("STEGASOO_AUDIO") -_video_toggle = _parse_feature_toggle("STEGASOO_VIDEO") +_audio_toggle = _parse_feature_toggle("FIELDWITNESS_AUDIO") +_video_toggle = _parse_feature_toggle("FIELDWITNESS_VIDEO") AUDIO_ENABLED: bool = _resolve_feature(_audio_toggle, _check_audio_deps) VIDEO_ENABLED: bool = _resolve_feature(_video_toggle, _check_video_deps) diff --git a/src/fieldwitness/stego/debug.py b/src/fieldwitness/stego/debug.py index f6cc5fc..dfdfaad 100644 --- a/src/fieldwitness/stego/debug.py +++ b/src/fieldwitness/stego/debug.py @@ -4,14 +4,14 @@ Stego Debugging Utilities Debugging, logging, and performance monitoring tools. Configuration: - STEGASOO_LOG_LEVEL env var controls log level: + FIELDWITNESS_LOG_LEVEL env var controls log level: - Not set or empty: logging disabled (production default) - DEBUG: verbose debug output (encode/decode flow, crypto params, etc.) - INFO: operational messages (format detection, mode selection) - WARNING: potential issues (fallback KDF, format transcoding) - ERROR: operation failures - STEGASOO_DEBUG=1 is a shorthand for STEGASOO_LOG_LEVEL=DEBUG + FIELDWITNESS_DEBUG=1 is a shorthand for FIELDWITNESS_LOG_LEVEL=DEBUG CLI: stego --debug encode ... (sets DEBUG level for that invocation) @@ -47,12 +47,12 @@ VALIDATION_ASSERTIONS = True # Enable runtime validation assertions def _configure_from_env() -> bool: """Configure logging from environment variables. Returns True if debug enabled.""" - # STEGASOO_DEBUG=1 is shorthand for DEBUG level - if os.environ.get("STEGASOO_DEBUG", "").strip() in ("1", "true", "yes"): + # FIELDWITNESS_DEBUG=1 is shorthand for DEBUG level + if os.environ.get("FIELDWITNESS_DEBUG", "").strip() in ("1", "true", "yes"): _setup_logging(logging.DEBUG) return True - level_str = os.environ.get("STEGASOO_LOG_LEVEL", "").strip().upper() + level_str = os.environ.get("FIELDWITNESS_LOG_LEVEL", "").strip().upper() if level_str and level_str in _LEVEL_MAP: _setup_logging(_LEVEL_MAP[level_str]) return level_str == "DEBUG" diff --git a/src/fieldwitness/stego/decode.py b/src/fieldwitness/stego/decode.py index 1b882d4..51d4cc4 100644 --- a/src/fieldwitness/stego/decode.py +++ b/src/fieldwitness/stego/decode.py @@ -314,7 +314,7 @@ def decode_audio( if not AUDIO_ENABLED: raise ExtractionError( "Audio support is disabled. Install audio extras (pip install stego[audio]) " - "or set STEGASOO_AUDIO=1 to force enable." + "or set FIELDWITNESS_AUDIO=1 to force enable." ) from .audio_utils import detect_audio_format, transcode_to_wav @@ -434,7 +434,7 @@ def decode_video( if not VIDEO_ENABLED: raise ExtractionError( "Video support is disabled. Install video extras and ffmpeg, " - "or set STEGASOO_VIDEO=1 to force enable." + "or set FIELDWITNESS_VIDEO=1 to force enable." ) from .video_utils import detect_video_format diff --git a/src/fieldwitness/stego/encode.py b/src/fieldwitness/stego/encode.py index 4a970a6..6211e74 100644 --- a/src/fieldwitness/stego/encode.py +++ b/src/fieldwitness/stego/encode.py @@ -382,7 +382,7 @@ def encode_audio( if not AUDIO_ENABLED: raise AudioError( "Audio support is disabled. Install audio extras (pip install stego[audio]) " - "or set STEGASOO_AUDIO=1 to force enable." + "or set FIELDWITNESS_AUDIO=1 to force enable." ) from .audio_utils import detect_audio_format, transcode_to_wav @@ -485,7 +485,7 @@ def encode_video( if not VIDEO_ENABLED: raise VideoError( "Video support is disabled. Install video extras and ffmpeg, " - "or set STEGASOO_VIDEO=1 to force enable." + "or set FIELDWITNESS_VIDEO=1 to force enable." ) from .video_utils import detect_video_format