video-accessibility/docs/principles.md
Vadym Samoilenko a3b300b76a docs: add canonical documentation + audit cleanup
- AGENTS.md: canonical project entry point (Quick Nav, pipeline, constraints)
- docs/: complete docs tree — architecture, API spec, DB schema, infra,
  runbook, requirements, tech stack, principles, reference ADRs, guides,
  tasks backlog, testing strategy
- tests/README.md: test commands, structure, known gaps
- README.md / CLAUDE.md / DEPLOYMENT.md: updated with canonical doc links
- .archive/: backup of pre-documentation-pipeline originals
- backend/uv.lock: uv dependency lockfile
- Delete committed __pycache__ .pyc files (should have been gitignored)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-29 14:22:51 +01:00

3.9 KiB
Raw Permalink Blame History

Development Principles — Accessible Video Processing Platform

These 11 principles govern all engineering decisions on this project. They are ordered by priority — earlier principles override later ones when they conflict.


P-01: Standards First

Implement to agreed specifications. The video_accessibility_development_plan.txt is the authoritative source for API contracts, schemas, state machine transitions, and worker pipeline behaviour. Read it before implementing a new feature. When the spec and the code diverge, fix the code.

P-02: Security by Design

Security controls are non-negotiable:

  • Access tokens in JS memory only — never localStorage
  • Refresh tokens in HttpOnly cookies only
  • RBAC enforced on every endpoint server-side
  • Signed GCS URLs with 24h expiry — never store URLs
  • All reviewer actions must emit audit log entries
  • Generic error messages — never return internal exception details to clients

P-03: Async Correctness

The backend is async (FastAPI + asyncio). Celery workers run in a separate sync process. Rules:

  • Never call synchronous blocking I/O (requests.get, time.sleep) in async FastAPI routes
  • Never share asyncio connections across Celery task boundaries — create connections per task
  • Use httpx.AsyncClient for HTTP in async routes
  • Use asyncio.get_running_loop().run_in_executor() only as a last resort for unavoidable sync calls

P-04: Fail Loudly on Configuration

Missing required secrets must crash startup, not fall back to insecure defaults. Use os.environ["KEY"] (raises KeyError) instead of os.environ.get("KEY", "weak_default"). The DEFAULT_ADMIN_PASSWORD fallback is a known violation that must be fixed.

P-05: YAGNI

Build only what is specified and currently needed. No speculative abstractions, no helper utilities for hypothetical future use cases. Three similar lines is better than a premature abstraction. If a feature is out of scope, defer it — don't build a "foundation" for it.

P-06: KISS

Simple code is correct code. Prefer flat, readable functions over clever abstractions. A 20-line function that does one thing clearly is better than a 5-line function using three layers of metaprogramming.

P-07: DRY — but only after the second time

Do not abstract on first encounter. Abstract when the same logic appears in a second place. The broadcast_status_update() function is copy-pasted in two task files — this is the known violation to fix.

P-08: No Comments for What, Only for Why

Code identifiers describe what the code does. Comments explain non-obvious constraints, hidden invariants, or bug workarounds. # logger undefined here is a good comment. # increment counter is not.

P-09: Validate at System Boundaries Only

Validate untrusted input (HTTP request bodies, AI model output, file uploads) at the boundary. Trust internal code, framework guarantees, and typed function signatures. Do not add defensive null-checks on values that the framework guarantees are non-null.

P-10: No Silent Failures

Every error has two acceptable outcomes: it is handled with a logged warning, or it propagates up as an exception. Swallowed exceptions that log nothing (except Exception: pass) are forbidden. The authz.py cache_key NameError swallowed silently is a known violation.

P-11: Test What Matters

Follow risk-based testing (Priority = Business Impact × Probability). Tests with Priority ≥15 must exist before a feature is considered production-ready. Current critical gaps: RBAC (authz.py), job state machine (ingest_and_ai.py), audit logger, glossary retrieval — all Priority ≥20.


Maintenance

Update triggers: New architectural decision that changes how engineers should approach a class of problems. Verification: Each principle has a measurable compliance check — run a brief audit against recent commits before each production deploy.