Core changes: - Add @defgroup/@ingroup to 1791 C2+ contracts (555 files) for HCA 128× pre-training DSA grouping - Add §0.1 Pre-Training Frequency matrix to semantics-core - Add §VIII Attention Architecture rules (ATTN_1-4) with MLA/CSA/HCA/DSA mechanics - Add @defgroup/@ingroup to canonical syntax (§II) and all contract examples Agent prompts (5 files): - Add ZERO-STATE RATIONALE with MLA/CSA/HCA/DSA compression mechanics - Add pre-training note: @RATIONALE/@REJECTED are in-context learned tags - svelte-coder: add missing #region contract, fix Svelte rule violations - python-coder/fullstack-coder: honor function contracts from speckit plan - qa-tester: add attention compliance audit (P3 ATTN_1-4 checks) Skills (6 files): - Translate all axiom_config descriptions to English - Fix doc_dirs to index .opencode/ and .specify/ - Deduplicate 5× complexity_rules → single global_tags catalog - Reduce semantics-svelte 591→485 lines (remove duplicate code blocks) - Fix semantics-testing: 'Short IDs' → 'Short hierarchical IDs' - Fix all examples: flat IDs → hierarchical Domain.Name format - Fix Svelte examples: replace raw Tailwind + <button> with semantic tokens + /ui Speckit workflow (commands + templates): - speckit.plan: add Function-Level Contracts for C3+ with @PRE/@POST/@TEST_EDGE - speckit.plan: add Attention Compliance Gate (ATTN_1-4 before contract generation) - speckit.tasks: add function contract inlining format (constraints in task description) - speckit.specify: load semantics-core for spec density rules - spec-template: add #region contract, @SEMANTICS grouping, hierarchical IDs - ux-reference-template: add #region wrapper - plan-template: add attention gate, @defgroup/@ingroup guidance - tasks-template: add attention audit + rebuild + orphan check tasks - constitution.md: translate to English, add Principle VIII (attention-optimized contracts) Reference modules rewritten (hierarchical IDs + full contracts): - Auth.Jwt: 6 child contracts with @RATIONALE/@REJECTED/@TEST_EDGE - Api.Auth: 5 endpoints with @TEST_EDGE + molecular CoT markers - Migration.Model: @defgroup Migration with 18 @ACTION + 6 @INVARIANT Scripts: - add_defgroup_ingroup.py: zero-risk additive @ingroup migration (1791 insertions) - migrate_hierarchical.py: flat→hierarchical ID dry-run analysis (792 contracts) - merge_prompts.py: merge all prompts/skills/commands into one review file Config: - axiom_config.yaml: 749→395 lines (-47%), English, doc_dirs include prompts - Fix test_datasets.py import collision (rename → test_datasets_routes.py) - Fix test_preview.py: SupersetClient→get_superset_client, AsyncMock, logger f-string
74 lines
2.7 KiB
Python
74 lines
2.7 KiB
Python
# #region AuthLoggerModule [C:5] [TYPE Module] [SEMANTICS auth, audit, logging]
|
|
# @defgroup Auth Module group.
|
|
#
|
|
# @BRIEF Structured auth logging module for audit trail generation.
|
|
# @LAYER Core
|
|
# @RELATION DEPENDS_ON -> [EXT:frontend:core_logger]
|
|
#
|
|
# @INVARIANT Must not log sensitive data like passwords or full tokens.
|
|
# Sensitive field names (password, secret, token, key, authorization)
|
|
# in the details dict are automatically masked.
|
|
# @PRE Auth module initialized
|
|
# @POST Audit logging functions exported
|
|
# @SIDE_EFFECT Writes auth audit log entries
|
|
# @DATA_CONTRACT AuthEvent -> LogEntry
|
|
|
|
from datetime import UTC, datetime
|
|
import re
|
|
from typing import Any
|
|
|
|
from ..logger import belief_scope, logger
|
|
|
|
# Sensitive field name patterns — values for these keys are masked in logs
|
|
_SENSITIVE_KEYS = re.compile(
|
|
r"^(password|secret|token|api_key|api\.key|authorization|auth|credential|credit_card|ssn)$",
|
|
re.IGNORECASE,
|
|
)
|
|
|
|
|
|
def _mask_details(details: dict[str, Any] | None) -> dict[str, Any] | None:
|
|
"""Return a copy of details with sensitive field values replaced by '***'."""
|
|
if not details:
|
|
return details
|
|
masked = {}
|
|
for key, value in details.items():
|
|
if isinstance(key, str) and _SENSITIVE_KEYS.match(key):
|
|
masked[key] = "***"
|
|
elif isinstance(value, dict):
|
|
masked[key] = _mask_details(value)
|
|
else:
|
|
masked[key] = value
|
|
return masked
|
|
|
|
|
|
# #region log_security_event [TYPE Function]
|
|
# @ingroup Auth
|
|
# @BRIEF Logs a security-related event for audit trails.
|
|
# @PRE event_type and username are strings.
|
|
# @POST Security event is written to the application log via %s-formatting to prevent log injection.
|
|
# Sensitive fields in details dict are masked.
|
|
# @RELATION DEPENDS_ON -> [logger]
|
|
# @RATIONALE Uses %s-formatting (not f-strings) to prevent log forging via CRLF injection in
|
|
# user-controlled fields — see [SEC:H-1]. Sensitive fields in details
|
|
# dict are masked to prevent credential leakage — see [SEC:L-1].
|
|
def log_security_event(event_type: str, username: str, details: dict = None):
|
|
with belief_scope("log_security_event", f"{event_type}:{username}"):
|
|
timestamp = datetime.now(UTC).isoformat()
|
|
logger.info(
|
|
"[AUDIT][%s][%s] User: %s",
|
|
timestamp,
|
|
event_type,
|
|
username,
|
|
)
|
|
safe_details = _mask_details(details)
|
|
if safe_details:
|
|
logger.info(
|
|
"[AUDIT][%s][%s] Details: %s",
|
|
timestamp,
|
|
event_type,
|
|
safe_details,
|
|
)
|
|
# #endregion log_security_event
|
|
|
|
# #endregion AuthLoggerModule
|