Merge pull request 'docs: amend constitution to v1.1.0 — Observability after the tracing migration' (#149) from docs/tracing-constitution into master

Reviewed-on: #149
This commit was merged in pull request #149.
This commit is contained in:
cameron committed 2026-09-29 23:49:09 +00:00
commit aeeb05b289
4 files changed
+55 -21

No files matched your search

+3 -1
View File
@@ -28,7 +28,9 @@ HLS_CONCURRENCY=2
HLS_TIMEOUT_SECONDS=900 HLS_TIMEOUT_SECONDS=900
PLAYLIST_CLEANUP_INTERVAL_SECONDS=86400 PLAYLIST_CLEANUP_INTERVAL_SECONDS=86400
# ── Telemetry (release builds only) ───────────────────────────────────── # ── Telemetry ────────────────────────────────────────────────────────────
# Span export over OTLP in any build when set (unset = spans stay local).
# RUST_LOG also gates span export: keep it at info or debug.
# OTLP_OTLS_ENDPOINT=http://localhost:4317 # OTLP_OTLS_ENDPOINT=http://localhost:4317
# ── AI Insights — Ollama (local LLM) ──────────────────────────────────── # ── AI Insights — Ollama (local LLM) ────────────────────────────────────
+48 -17
View File
@@ -1,20 +1,31 @@
<!-- <!--
Sync Impact Report Sync Impact Report
================== ==================
Version change: (new) -> 1.0.0 Version change: 1.0.0 -> 1.1.0
Modified principles: N/A (initial ratification) Bump rationale: MINOR. Principle V is materially expanded: the tracing
Added sections: mechanism changed (tracing + tracing-opentelemetry in every build), and
- Core Principles (5 principles) it adds two new MUST rules: no manual Context threading, and carrying
- Technology Stack & Constraints the parent span across spawns. No principle is removed or redefined in
- Development Workflow intent.
- Governance Modified principles:
- V. Observability: mechanism + rules updated for the tracing migration
(map #135, PR #148)
Also updated:
- I. Layered Architecture: Database Layer "traced" wording
- Technology Stack & Constraints: Tracing line
Added sections: N/A
Removed sections: N/A Removed sections: N/A
Templates requiring updates: Templates requiring updates:
- .specify/templates/plan-template.md — ✅ no changes needed (Constitution Check section is generic) - .specify/templates/plan-template.md — ✅ no changes needed (generic Constitution Check)
- .specify/templates/spec-template.md — ✅ no changes needed - .specify/templates/spec-template.md — ✅ no changes needed
- .specify/templates/tasks-template.md — ✅ no changes needed - .specify/templates/tasks-template.md — ✅ no changes needed
- .specify/templates/checklist-template.md — ✅ no changes needed - .specify/templates/checklist-template.md — ✅ no changes needed
- .specify/templates/agent-file-template.md — ✅ no changes needed - .specify/templates/agent-file-template.md — ✅ no changes needed
Runtime guidance:
- CLAUDE.md "Tracing" — ✅ already consistent (conventions landed with #148);
OTLP env line + dependency list updated alongside this amendment
- README.md — ✅ RUST_LOG default/gating corrected; OTLP_OTLS_ENDPOINT added
- .env.example — ✅ telemetry header corrected
Follow-up TODOs: None Follow-up TODOs: None
--> -->
@@ -34,7 +45,8 @@ All features MUST follow the established layered architecture:
contracts. Every DAO MUST be defined as a trait to enable mock contracts. Every DAO MUST be defined as a trait to enable mock
implementations for testing. implementations for testing.
- **Database Layer** (Diesel ORM, `schema.rs`): Concrete `Sqlite*Dao` - **Database Layer** (Diesel ORM, `schema.rs`): Concrete `Sqlite*Dao`
implementations. All queries traced with OpenTelemetry. implementations. Every query runs inside a `tracing` span via
`otel::trace_db_call`.
New features MUST NOT bypass layers (e.g., HTTP handlers MUST NOT New features MUST NOT bypass layers (e.g., HTTP handlers MUST NOT
execute raw SQL). Actix actors are permitted for long-running async execute raw SQL). Actix actors are permitted for long-running async
@@ -84,17 +96,35 @@ prohibited.
### V. Observability ### V. Observability
All database operations and HTTP handlers MUST be instrumented All database operations and HTTP handlers MUST be instrumented with
with OpenTelemetry spans via the `trace_db_call` helper or `tracing` spans, exported through `tracing-opentelemetry`: DAO bodies via
equivalent tracing macros. `otel::trace_db_call`, and handlers / feature functions via
`#[tracing::instrument]`. The per-request root span comes from the
`tracing-actix-web` middleware, which also honors an incoming W3C
`traceparent`.
- Release builds export traces to the configured OTLP endpoint. - Spans are produced in debug and release builds alike. OTLP export is
- Debug builds use the basic logger. enabled by `OTLP_OTLS_ENDPOINT`, not by build profile.
- Code MUST NOT thread an OpenTelemetry `Context` through call chains.
Spans parent on the ambient span.
- Every `tokio::spawn` or cross-thread fan-out (rayon, per-pass runtimes)
MUST carry its parent span: `.instrument(span)` or
`info_span!(parent: &span, ...)`. Tracing context is thread-local, and
an uncarried spawn orphans its spans onto a fresh trace.
- `RUST_LOG` gates span export as well as console output (one `EnvFilter`).
Deployments MUST run at `info` or `debug`.
- Logs are a separate pipeline: `env_logger` in debug, OTel log export in
release.
- Prometheus metrics (`imageserver_image_total`, - Prometheus metrics (`imageserver_image_total`,
`imageserver_video_total`) MUST be maintained for key counters. `imageserver_video_total`) MUST be maintained for key counters.
- Errors MUST be logged at `error!` level with sufficient context - Errors MUST be logged at `error!` level with sufficient context
for debugging without reproducing the issue. for debugging without reproducing the issue.
**Rationale:** span parenting that relies on hand-threaded contexts drifted
into orphaned traces (the pre-migration baseline, #137). Ambient
parenting, plus an explicit carry at each spawn boundary, keeps a request or
job in one trace by construction.
## Technology Stack & Constraints ## Technology Stack & Constraints
- **Language**: Rust (stable toolchain, Cargo build system) - **Language**: Rust (stable toolchain, Cargo build system)
@@ -105,8 +135,9 @@ equivalent tracing macros.
- **Video Processing**: ffmpeg/ffprobe (CLI, must be on PATH) - **Video Processing**: ffmpeg/ffprobe (CLI, must be on PATH)
- **Image Processing**: `image` crate for thumbnails, `kamadak-exif` - **Image Processing**: `image` crate for thumbnails, `kamadak-exif`
for EXIF extraction for EXIF extraction
- **Tracing**: OpenTelemetry with OTLP export (release), - **Tracing**: `tracing` + `tracing-opentelemetry` (every build), OTLP
basic logger (debug) export when `OTLP_OTLS_ENDPOINT` is set; logs via `env_logger` (debug) /
OTel log export (release)
- **Testing**: `cargo test`, `actix_web::test`, in-memory SQLite - **Testing**: `cargo test`, `actix_web::test`, in-memory SQLite
External dependencies (ffmpeg, Ollama) are optional runtime External dependencies (ffmpeg, Ollama) are optional runtime
@@ -146,4 +177,4 @@ MUST comply with these principles.
these principles. The CLAUDE.md file provides runtime development these principles. The CLAUDE.md file provides runtime development
guidance and MUST remain consistent with this constitution. guidance and MUST remain consistent with this constitution.
**Version**: 1.0.0 | **Ratified**: 2026-02-26 | **Last Amended**: 2026-02-26 **Version**: 1.1.0 | **Ratified**: 2026-02-26 | **Last Amended**: 2026-09-29
+2 -2
View File
@@ -696,7 +696,7 @@ Optional:
WATCH_QUICK_INTERVAL_SECONDS=60 # Quick scan interval WATCH_QUICK_INTERVAL_SECONDS=60 # Quick scan interval
WATCH_FULL_INTERVAL_SECONDS=3600 # Full scan interval WATCH_FULL_INTERVAL_SECONDS=3600 # Full scan interval
DATE_BACKFILL_MAX_PER_TICK=500 # Cap on canonical-date drain per watcher tick DATE_BACKFILL_MAX_PER_TICK=500 # Cap on canonical-date drain per watcher tick
OTLP_OTLS_ENDPOINT=http://... # OpenTelemetry collector (release builds) OTLP_OTLS_ENDPOINT=http://... # OTLP collector for span export (any build; unset = no export)
# AI Insights Configuration # AI Insights Configuration
OLLAMA_PRIMARY_URL=http://desktop:11434 # Primary Ollama server (e.g., desktop) OLLAMA_PRIMARY_URL=http://desktop:11434 # Primary Ollama server (e.g., desktop)
@@ -956,7 +956,7 @@ side if exposing beyond a trusted network.
- **image**: Thumbnail generation - **image**: Thumbnail generation
- **walkdir**: Directory traversal - **walkdir**: Directory traversal
- **rayon**: Parallel processing - **rayon**: Parallel processing
- **opentelemetry**: Distributed tracing - **tracing** + **tracing-opentelemetry** + **tracing-actix-web**: spans (exported via `opentelemetry-otlp`)
- **bcrypt**: Password hashing - **bcrypt**: Password hashing
- **infer**: Magic number file type detection - **infer**: Magic number file type detection
+2 -1
View File
@@ -72,7 +72,8 @@ They should be defined where the binary is located or above it in an `.env` file
- `GIFS_DIRECTORY` is a path where generated video GIF thumbnails should be stored - `GIFS_DIRECTORY` is a path where generated video GIF thumbnails should be stored
- `BIND_URL` is the url and port to bind to (typically your own IP address) - `BIND_URL` is the url and port to bind to (typically your own IP address)
- `SECRET_KEY` is the *hopefully* random string to sign Tokens with - `SECRET_KEY` is the *hopefully* random string to sign Tokens with
- `RUST_LOG` is one of `off, error, warn, info, debug, trace`, from least to most noisy [error is default] - `RUST_LOG` is one of `off, error, warn, info, debug, trace`, from least to most noisy [default: `info` for spans, `error` for dev console logs]. It also gates tracing-span export, so keep it at `info` or `debug`
- `OTLP_OTLS_ENDPOINT` (optional) is an OTLP/gRPC collector URL (e.g. SigNoz, Jaeger) for span export, in any build [default: unset, no export]
- `EXCLUDED_DIRS` is a comma separated list of directories to exclude from the Memories API - `EXCLUDED_DIRS` is a comma separated list of directories to exclude from the Memories API
- `PREVIEW_CLIPS_DIRECTORY` (optional) is a path where generated video preview clips should be stored [default: `preview_clips`] - `PREVIEW_CLIPS_DIRECTORY` (optional) is a path where generated video preview clips should be stored [default: `preview_clips`]
- `WATCH_QUICK_INTERVAL_SECONDS` (optional) is the interval in seconds for quick file scans [default: 60] - `WATCH_QUICK_INTERVAL_SECONDS` (optional) is the interval in seconds for quick file scans [default: 60]