You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							176 lines
						
					
					
						
							4.9 KiB
						
					
					
				
			
		
		
		
			
			
			
				
					
				
				
					
				
			
		
		
	
	
							176 lines
						
					
					
						
							4.9 KiB
						
					
					
				
								# Agent Contract — TimeSafari Logging (Unified, MANDATORY)
							 | 
						|
								
							 | 
						|
								**Author**: Matthew Raymer
							 | 
						|
								**Date**: 2025-08-19
							 | 
						|
								**Status**: 🎯 **ACTIVE** - Mandatory logging standards
							 | 
						|
								
							 | 
						|
								## Overview
							 | 
						|
								
							 | 
						|
								This document defines unified logging standards for the TimeSafari project,
							 | 
						|
								ensuring consistent, rest-parameter logging style using the project logger.
							 | 
						|
								No `console.*` methods are allowed in production code.
							 | 
						|
								
							 | 
						|
								## Scope and Goals
							 | 
						|
								
							 | 
						|
								**Scope**: Applies to all diffs and generated code in this workspace unless
							 | 
						|
								explicitly exempted below.
							 | 
						|
								
							 | 
						|
								**Goal**: One consistent, rest-parameter logging style using the project
							 | 
						|
								logger; no `console.*` in production code.
							 | 
						|
								
							 | 
						|
								## Non‑Negotiables (DO THIS)
							 | 
						|
								
							 | 
						|
								- You **MUST** use the project logger; **DO NOT** use any `console.*`
							 | 
						|
								
							 | 
						|
								  methods.
							 | 
						|
								
							 | 
						|
								- Import exactly as:
							 | 
						|
								
							 | 
						|
								  - `import { logger } from '@/utils/logger'`
							 | 
						|
								
							 | 
						|
								  - If `@` alias is unavailable, compute the correct relative path (do not
							 | 
						|
								
							 | 
						|
								    fail).
							 | 
						|
								
							 | 
						|
								- Call signatures use **rest parameters**: `logger.info(message, ...args)`
							 | 
						|
								
							 | 
						|
								- Prefer primitives/IDs and small objects in `...args`; **never build a
							 | 
						|
								
							 | 
						|
								  throwaway object** just to "wrap context".
							 | 
						|
								
							 | 
						|
								- Production defaults: Web = `warn+`, Electron = `error`, Dev/Capacitor =
							 | 
						|
								
							 | 
						|
								  `info+` (override via `VITE_LOG_LEVEL`).
							 | 
						|
								
							 | 
						|
								- **Database persistence**: `info|warn|error` are persisted; `debug` is not.
							 | 
						|
								
							 | 
						|
								  Use `logger.toDb(msg, level?)` for DB-only.
							 | 
						|
								
							 | 
						|
								## Available Logger API (Authoritative)
							 | 
						|
								
							 | 
						|
								- `logger.debug(message, ...args)` — verbose internals, timings, input/output
							 | 
						|
								
							 | 
						|
								  shapes
							 | 
						|
								
							 | 
						|
								- `logger.log(message, ...args)` — synonym of `info` for general info
							 | 
						|
								
							 | 
						|
								- `logger.info(message, ...args)` — lifecycle, state changes, success paths
							 | 
						|
								
							 | 
						|
								- `logger.warn(message, ...args)` — recoverable issues, retries, degraded mode
							 | 
						|
								
							 | 
						|
								- `logger.error(message, ...args)` — failures, thrown exceptions, aborts
							 | 
						|
								
							 | 
						|
								- `logger.toDb(message, level?)` — DB-only entry (default level = `info`)
							 | 
						|
								
							 | 
						|
								- `logger.toConsoleAndDb(message, isError)` — console + DB (use sparingly)
							 | 
						|
								
							 | 
						|
								- `logger.withContext(componentName)` — returns a scoped logger
							 | 
						|
								
							 | 
						|
								## Level Guidelines (Use These Heuristics)
							 | 
						|
								
							 | 
						|
								### DEBUG
							 | 
						|
								
							 | 
						|
								Use for method entry/exit, computed values, filters, loops, retries, and
							 | 
						|
								external call payload sizes.
							 | 
						|
								
							 | 
						|
								### INFO
							 | 
						|
								
							 | 
						|
								Use for user-visible lifecycle and completed operations.
							 | 
						|
								
							 | 
						|
								### WARN
							 | 
						|
								
							 | 
						|
								Use for recoverable issues, fallbacks, unexpected-but-handled conditions.
							 | 
						|
								
							 | 
						|
								### ERROR
							 | 
						|
								
							 | 
						|
								Use for unrecoverable failures, data integrity issues, and thrown
							 | 
						|
								exceptions.
							 | 
						|
								
							 | 
						|
								## Context Hygiene (Consistent, Minimal, Helpful)
							 | 
						|
								
							 | 
						|
								- **Component context**: Prefer scoped logger.
							 | 
						|
								
							 | 
						|
								- **Emojis**: Optional and minimal for visual scanning.
							 | 
						|
								
							 | 
						|
								- **Sensitive data**: Never log secrets (tokens, keys, passwords) or
							 | 
						|
								  payloads >10KB. Prefer IDs over objects; redact/hash when needed.
							 | 
						|
								
							 | 
						|
								## DB Logging Rules
							 | 
						|
								
							 | 
						|
								- `debug` **never** persists automatically.
							 | 
						|
								
							 | 
						|
								- `info|warn|error` persist automatically.
							 | 
						|
								
							 | 
						|
								- For DB-only events (no console), call `logger.toDb('Message',
							 | 
						|
								  'info'|'warn'|'error')`.
							 | 
						|
								
							 | 
						|
								## Exceptions (Tightly Scoped)
							 | 
						|
								
							 | 
						|
								Allowed paths (still prefer logger):
							 | 
						|
								
							 | 
						|
								- `**/*.test.*`, `**/*.spec.*`
							 | 
						|
								
							 | 
						|
								- `scripts/dev/**`, `scripts/migrate/**`
							 | 
						|
								
							 | 
						|
								To intentionally keep `console.*`, add a pragma on the previous line:
							 | 
						|
								
							 | 
						|
								```typescript
							 | 
						|
								
							 | 
						|
								// cursor:allow-console reason="short justification"
							 | 
						|
								console.log('temporary output');
							 | 
						|
								
							 | 
						|
								```
							 | 
						|
								
							 | 
						|
								## CI & Diff Enforcement
							 | 
						|
								
							 | 
						|
								- Do not introduce `console.*` anywhere outside allowed, pragma'd spots.
							 | 
						|
								
							 | 
						|
								- If an import is missing, insert it and resolve alias/relative path
							 | 
						|
								  correctly.
							 | 
						|
								
							 | 
						|
								- Enforce rest-parameter call shape in reviews; replace object-wrapped
							 | 
						|
								  context.
							 | 
						|
								
							 | 
						|
								- Ensure environment log level rules remain intact (`VITE_LOG_LEVEL`
							 | 
						|
								  respected).
							 | 
						|
								
							 | 
						|
								---
							 | 
						|
								
							 | 
						|
								**See also**:
							 | 
						|
								  `.cursor/rules/development/logging_migration.mdc` for migration patterns and examples.
							 | 
						|
								
							 | 
						|
								**Status**: Active and enforced
							 | 
						|
								**Priority**: Critical
							 | 
						|
								**Estimated Effort**: Ongoing reference
							 | 
						|
								**Dependencies**: TimeSafari logger utility
							 | 
						|
								**Stakeholders**: Development team, Code review team
							 | 
						|
								
							 | 
						|
								## Model Implementation Checklist
							 | 
						|
								
							 | 
						|
								### Before Adding Logging
							 | 
						|
								
							 | 
						|
								- [ ] **Logger Import**: Import logger as `import { logger } from
							 | 
						|
								  '@/utils/logger'`
							 | 
						|
								- [ ] **Log Level Selection**: Determine appropriate log level
							 | 
						|
								  (debug/info/warn/error)
							 | 
						|
								- [ ] **Context Planning**: Plan what context information to include
							 | 
						|
								- [ ] **Sensitive Data Review**: Identify any sensitive data that needs redaction
							 | 
						|
								
							 | 
						|
								### During Logging Implementation
							 | 
						|
								
							 | 
						|
								- [ ] **Rest Parameters**: Use `logger.info(message, ...args)` format, not object
							 | 
						|
								  wrapping
							 | 
						|
								- [ ] **Context Addition**: Include relevant IDs, primitives, or small objects in
							 | 
						|
								  args
							 | 
						|
								- [ ] **Level Appropriateness**: Use correct log level for the situation
							 | 
						|
								- [ ] **Scoped Logger**: Use `logger.withContext(componentName)` for
							 | 
						|
								  component-specific logging
							 | 
						|
								
							 | 
						|
								### After Logging Implementation
							 | 
						|
								
							 | 
						|
								- [ ] **Console Check**: Ensure no `console.*` methods are used (unless in
							 | 
						|
								  allowed paths)
							 | 
						|
								- [ ] **Performance Review**: Verify logging doesn't impact performance
							 | 
						|
								- [ ] **DB Persistence**: Use `logger.toDb()` for database-only logging if needed
							 | 
						|
								- [ ] **Environment Compliance**: Respect `VITE_LOG_LEVEL` environment
							 | 
						|
								  variable
							 | 
						|
								
							 |