Migration note: Migrated from ADR-0035 on 2026-05-02 per ADR-0047. Original file retained at
docs/adr/0035-session-traceability-convention.mdwith deprecation banner.
GOV-0004: Session Traceability Convention for LLM-Assisted Operations¶
Sources¶
- ADR-0035: Session Traceability Convention for LLM-Assisted Operations (2026-04-21)
| Field | Value |
|---|---|
| ID | GOV-0004 |
| Date | 2026-04-21 |
| Status | Accepted |
| Author | Ben Peries |
| Phases | All |
| ADO WI | #283 |
| Class | security/GOV |
Context¶
Archon is a homelab platform being built toward agentic AI operations. Work is conducted across three surfaces that currently have no shared identity model:
- Claude.ai threads — where problem analysis, architecture decisions, and multi-turn reasoning occur
- Claude Code sessions — where implementation, IaC authoring, and ADO operations execute
- ADO work items, PRs, commits, and branches — where all changes are permanently recorded
When something goes wrong — a regression, a missed constraint, an unexpected state — there is no mechanism to reconstruct which conversation produced which change. The audit trail exists in pieces across ADO history, git log, and Claude.ai chat history, but they are not linked.
This is not a theoretical concern. During session 26-04-20-A.2:
- A preservation commit captured the global agent state as a merge base
- That commit introduced stale
esp1naming that had already been corrected by a prior session's WI-265 merge - The root cause was traced to a state fork between the global
~/.claude/agents/directory and the project-local.claude/agents/directory - Reconstructing the causal chain required reading the full JSONL transcript, checking git log across two branches, and inspecting ADO PR history manually
A session ID that appears in all four surfaces would have made this investigation trivial: filter by session ID, reconstruct the timeline, identify the fork.
LLM Observability Hierarchy¶
This convention draws on established distributed tracing vocabulary, applied to LLM-assisted operations:
| Concept | Archon surface | Description |
|---|---|---|
| Thread | Claude.ai conversation | Master session — human-initiated reasoning thread |
| Trace | Claude Code session | Child session — implementation derived from Thread |
| Span | Individual tool call | Atomic operation within a Trace |
This maps directly to OpenTelemetry's Thread/Trace/Span model and is consistent with Langwatch trace ID patterns and the broader LLMOps observability literature (see References).
Decision¶
A session ID convention is adopted for all Archon LLM-assisted work. The format is:
Where:
- YY-MM-DD — the calendar date the session started (the session's "birthday")
- X — a letter starting at
Aeach new calendar day, incrementing for each master Claude.ai thread started that day (A= first master,B= second,C= third, etc.) - n — the child session number under that thread (
1= master Claude.ai thread itself;2,3, ... = Claude Code sessions or other tool-layer sessions spawned from that master)
Examples:
| ID | Meaning |
|---|---|
26-04-21-A.1 |
21 April 2026, first master thread of the day, the thread itself |
26-04-21-A.2 |
21 April 2026, first master thread, second child (first Claude Code session) |
26-04-21-B.1 |
21 April 2026, second master thread started that day |
26-04-21-B.3 |
21 April 2026, second master thread, third child session |
Session Boundary Rule¶
Standard rule¶
Every new calendar day starts a new session letter sequence. Sessions do not carry across midnight. If work continues the next day, a new session ID is assigned. Prior sessions are linked via WI references, PR descriptions, and commit footers — not via a shared session ID.
Midnight-crossing exception (hybrid policy)¶
This platform operates in a 24/7 hybrid environment. Administrators may work late shifts, cross midnight during a live incident, or sustain long-haul sessions during sprint completion. The midnight boundary is therefore a default, not a hard gate.
When a session crosses midnight:
- The session retains the original start-date session ID (no ID change mid-session)
- A brief rationale must be recorded in the next WI comment, PR description, or commit footer. Acceptable rationale examples:
- "Session continued past midnight — incident response, no natural close point"
- "Late sprint push — continuous work, single context window"
- "Cross-midnight — test deployment required same-session verification"
- The following day's session IDs begin fresh from
A.1regardless of whether the prior session continued past midnight
This policy is intentionally human-first. The platform does not prevent long-haul work. It records the rationale so the audit trail remains honest without penalising operators for real-world work patterns.
What this rule does NOT cover:
A session that was genuinely closed and resumed the next day must use a new session ID. The midnight exception applies only to continuous sessions with a documented rationale. Retroactively back-dating a session ID to avoid creating a new one is a policy violation and must be recorded as such.
Applicability and Compliance Model¶
This is a homelab convention for portfolio observability and LLMOps audit.
Compliance is aspirational and documented, not gated by tooling.
Claude Code agents and human operators are expected to apply session IDs when creating WIs, PRs, commits, and branches. When a session ID is not captured, this is recorded as a traceability gap (e.g., "session ID not captured") rather than blocked. WI #284 (automation script) will provide tooling assistance but will not enforce compliance — enforcement remains at the human and process layer.
This mirrors the GOV-0003 agentic gap model: AI agents are compliance-aware but not compliance-enforcing. The session ID convention is the advisory layer; WI #284 automation is the assistance layer; human review is the enforcement layer.
Session ID Placement¶
When feasible, the session ID appears in all of the following locations:
| Location | Format | Example |
|---|---|---|
| ADO WI tag | session:YY-MM-DD-X.n |
session:26-04-21-A.2 |
| ADO WI title prefix | [YY-MM-DD-X.n] |
[26-04-21-A.2] Add Grype scan to pipeline |
| ADO WI description | First line: Session: YY-MM-DD-X.n |
|
| PR title prefix | [YY-MM-DD-X.n] |
[26-04-21-A.2] feat(ci): add Grype scan |
| PR description | Session: YY-MM-DD-X.n line in metadata block |
|
| Commit footer | Session: YY-MM-DD-X.n |
see example below |
| Branch name prefix | YY-MM-DD-X.n/ when feasible |
26-04-21-A.2/wi-283-adr-session |
Branch name prefixing is optional — the wi-NNN-slug pattern remains the
primary branch naming convention. The session prefix may be omitted when it
would make the branch name unwieldy.
Commit footer example:
feat(agents): add board hygiene block to ccagnt-session-light
Adds Step 4 Board Visibility Check to ccagnt-session-light.md.
Detects WIs at root iteration path or root area path and documents
the fix procedure.
ADO WI: #266
Session: 26-04-20-A.2
Co-Authored-By: Claude Sonnet 4.5 <REDACTED>
Retroactive Application¶
Session IDs may be assigned retroactively to completed sessions when doing so aids reconstruction of a causal chain. Retroactive IDs must be:
- Noted as retroactive in the WI or PR description
- Not applied to already-merged PRs or already-closed WIs (add as a comment instead)
- Consistent with the date the session actually occurred
The retroactive tag 26-04-20-A.2 for the WI-266 agent reconciliation session
is the first application of this convention and was the motivating incident for
this ADR. It is recorded here as a documented retroactive assignment.
Automation¶
WI #284 tracks the implementation of a tooling assistant for session ID assignment. The script will:
- Prompt for or auto-generate the session ID at session start
- Inject the ID into WI creation commands, PR descriptions, and commit templates
- Log the session ID to a local registry for audit
WI #284 must not be started until this ADR is in Accepted status.
Alternatives Considered¶
Option A: Use ADO sprint ID as session anchor Rejected. Sprint IDs are too coarse — a sprint spans two weeks and contains dozens of sessions. Cannot reconstruct individual session causality from a sprint ID alone.
Option B: Use git commit SHA as session anchor Rejected. A session may produce multiple commits and a session in Claude.ai produces no commits at all. SHA links are point-in-time, not session-scoped.
Option C: Use OpenTelemetry trace IDs (UUID format) Rejected for primary use. UUIDs are not human-readable and cannot be eyeballed in a git log or PR title. The YY-MM-DD-X.n format is human-readable and sortable. An OpenTelemetry integration could consume this convention as input to a trace ID in a future LLM-as-a-judge pipeline.
Option D: Hard midnight boundary, no exceptions Rejected. The platform operates in a hybrid 24/7 environment. A hard boundary penalises legitimate long-haul sessions and creates pressure to falsify session IDs. The hybrid policy with documented rationale is more honest and more durable.
Option E: No convention, rely on ADO linking only Rejected. ADO WI links survive at the PR and commit level but do not capture the Claude.ai thread that produced the reasoning. The session ID is the missing link between the reasoning layer (Claude.ai) and the execution layer (Claude Code → ADO).
Consequences¶
- All new WIs, PRs, commits, and branches created in LLM-assisted sessions should carry a session ID tag where feasible
- ccagnt-session-light and ccagnt-session-full handoff templates updated to include session ID in the header (separate WI or PR as needed)
- WI #284 (automation script) may begin after this ADR is accepted
- Retroactive ID
26-04-20-A.2applied to WI #266 session as first instance
References¶
- Langwatch trace ID patterns — LLM observability trace structure reference
- Azure DevOps AB# auto-linking — ADO automatic WI linking via commit message syntax
- arxiv 2511.18187 — traceability link recovery in software engineering; applied here to LLM-assisted commit chains
- GOV-0003: ADO Board as Single Source of Truth and WI-First Branching Policy
- WI #283: ADR authoring task
- WI #284: Automation script for session ID assignment (depends on this ADR)