# 2026-01-03: Implementation Decision Records (idrs)

Owner: Will Lachance <wlach@protonmail.com>

_This IDR describes the IDR format itself—a bit meta, but it demonstrates the format in action._

## Overview

### Problem Statement

Make it easier to implement modifications and improvements to software while documenting the result.

### Context (as needed)

LLM coding agents (early 2026) can make large, coherent changes but don't naturally capture _why_ choices were made—only _what_ was done.

Existing formats don't fit well:

- Design docs: good for brainstorming and discussion, expensive to maintain during implementation
- ADRs: capture decisions, but deliberately exclude implementation details

Desired: something that lives in-repo, captures both intent and execution details, can guide both humans and machines (LLMs as of early 2026), and is explicitly ephemeral.

This is an experiment to see if such a format is useful.

### Goals

- Provide scaffolding for humans to understand an approach before and during
  implementation
- Provide scaffolding for automated systems (e.g. LLMs) to use as an implementation
  guide, as well as critique during brainstorming.

### Non-Goals

- Provide the _best_ possible ergonomics for discussing a design or approach (Google docs or similar are always going to be better)
- Be a scaffolding for literary works of art (idrs are intended to be functional)
- Be long lived documentation (idrs are a snapshot in time)

### Proposed Solution

Create a command-line program called `idr`, for use by humans as well
as developer productivity tooling (LLM Agents in circa late 2025) that
generates "implementation decision records": short markdown documents
which describe the problem as well as the shape of the solution.

This implementation summary can and will be updated during implementation, and should be committed to VCS and included in a proposed
change at the end of that process.

## Detailed Design (as needed)

Create an executable with the following features:

- A command-line tool (`idr`) with a single sub-command: `new`. You can create an idr with it by running `idr new "<title of idr>"`. For example: `idr new "Add last modified metadata"` and (on Dec 30 at 16:00 UTC) it would create a file called `idrs/202512301600-add-last-modified-metadata.md`.

### idr template structure

The IDR template has the following structure:

```md
# {{ Date in YYYY-MM-DD }}: {{ title }}

Owner: {{ owner }}

## Overview

### Problem Statement

### Context (as needed)

### Goals

### Non-Goals

### Proposed Solution

## Detailed Design (as needed)

## Rollout plan (as needed)

## Cross cutting concerns (as needed)

## Alternatives considered (as needed)

## Future plans (as needed)

## Other reading (as needed)

## Implementation (ephemeral)
```

For the benefit of the person filling it out, instructions on what
to be put in the fields are specified as markdown comments.
To create IDRs without these comments:

- Use the --no-comments flag: rp idr new "Title" --no-comments
- Or set the environment variable: export IDR_NO_COMMENTS=1

### Implementation language

For maximum flexibility, the implementation is in Rust. This should (at least) allow incorporation of idr-tools into Rust and Python packages.

## Cross cutting concerns (as needed)

### Trust

As used in 2025/2026, these artifacts will often be partially generated by LLMs.
Without safeguards, they risk becoming inaccurate [work slop](https://www.404media.co/ai-workslop-is-killing-productivity-and-making-workers-miserable/).

**Mitigation strategies:**

1. **Review checkpoints**: IDRs must be human-reviewed at:

   - Initial creation (ensure problem statement is accurate)
   - Implementation completion (verify "Implementation" section matches reality)
   - PR review (confirm all technical details are correct)

2. **Validation prompts**: When using LLM assistance, always ask:

   - "Is every word here true and accurate to the current implementation?"
   - "Are there any speculative or aspirational statements presented as facts?"
   - "Do all code/file references actually exist?"

3. **Accountability**: IDRs should have a named author who takes responsibility for accuracy

4. **Ephemeral by design**: The "Implementation (ephemeral)" section acknowledges these are snapshots, not evergreen docs.

**Future tooling**: Consider automated validation (checking file references, detecting hallucination patterns, comparing against actual git diffs).

## Alternatives considered (as needed)

- Markdown ADRs aka [MADRs](https://adr.github.io/madr/): Has some commonalities (e.g. use of markdown). As generally used, much more concise than an implementation decision record and intended purely for human consumption. Generally feel like a document format that allows (but doesn't require!) more colour/thinking about the shape of an implementation is potentially useful.
- Traditional Design Docs circulated as Google Docs or similar: These are great! But often much heavier and almost invariably diverge from implementation (unless written deliberately). They also tend to be difficult to search for and find in most organizations. Generally most useful when trying to get buy-in or feedback from others. IDRs are generally for the benefit of implementors, their tools (LLMs in late 2025) and PR reviewers.

## Future plans (as needed)

- Publish distributions on Cargo and PyPI, for incorporation into Rust and Python projects

## Other reading (as needed)

- [Design Docs at Google](https://www.industrialempathy.com/posts/design-docs-at-google/)
- [Architectural Decision Records (ADRs)](https://adr.github.io/)

## Implementation (ephemeral)

### Project Structure

Created a Rust project `idr-tools` with:

- Binary named `idr` (configured via `Cargo.toml` `[[bin]]` section)
- Main source: `src/main.rs`
- Git identity helper: `src/git.rs`
- Template: `src/default_template.md.jinja`

### Dependencies

- `clap` (with derive features) - CLI argument parsing
- `jiff` - Timestamp handling for date/time formatting
- `minijinja` - Template rendering
- `slug` - Title slugification for filenames
- `gix` + `gix-config` - Git config reading for identity
- `regex` - HTML comment stripping

### Key Implementation Details

**CLI Structure** (`src/main.rs`):

- Used `clap` derive macros for clean CLI definition
- Single `new` subcommand with `title` argument
- `--no-comments` flag to strip HTML comments from output
- Environment variable support: `IDR_NO_COMMENTS=1`

**Filename Generation**:

- Format: `YYYYMMDDHHMM-slugified-title.md`
- Used `jiff::Timestamp::now()` for current time
- Formatted with `.strftime("%Y%m%d%H%M")`
- Title slugified using `slug` crate

**Directory Logic** (`get_idr_path()`):

- Checks if `idrs/` directory exists in current directory
- If yes: writes to `idrs/filename.md`
- If no: writes to `./filename.md`

**Template Rendering**:

- Used `minijinja` with embedded template via `include_str!`
- Template variables: `date` (YYYY-MM-DD), `title`, `owner`
- Date formatted with `.strftime("%Y-%m-%d")`

**Git Identity** (`src/git.rs`):

- Simplified from initial struct-based approach to just return `Option<String>`
- Priority order:
  1. Environment variables (`GIT_AUTHOR_NAME`/`GIT_AUTHOR_EMAIL` or `GIT_COMMITTER_*`)
  2. Repository config (if in a git repo)
  3. Global git config
- Format: `"Name <email>"`
- Fallback: `"Unknown <unknown>"` if not configured

**Comment Stripping** (`strip_html_comments()`):

- Regex-based implementation
- Removes HTML comments: `<!--.*?-->` (with DOTALL flag)
- Normalizes whitespace-only lines to blank lines
- Collapses 3+ consecutive newlines to exactly 2
- Strips leading/trailing whitespace from document

### Testing

Automated testing:

- 18 unit tests covering all utility functions
- Tests organized in `#[cfg(test)]` modules in `src/git.rs` and `src/utils.rs`
- Tests cover: filename generation, path resolution, comment stripping, git identity resolution
- All tests passing with `cargo test`

Manual testing confirmed:

- `idr new "Title"` creates IDR with comments
- `idr new "Title" --no-comments` creates IDR without comments
- `IDR_NO_COMMENTS=1 idr new "Title"` also strips comments
- Git identity correctly populated from local config
- Files created in `idrs/` when directory exists
- Proper filename format and slugification

### Code Organization

Final structure after refactoring:

- `src/main.rs` (~70 lines) - CLI definition and orchestration only
- `src/utils.rs` - IDR-specific utilities (filename, path, comment stripping) with tests
- `src/git.rs` - Git identity resolution with tests
- Clean separation of concerns, no "bag of tricks" in main

### Lessons Learned

- Started with complex char-by-char HTML comment parser, replaced with simple regex (YAGNI)
- Initially over-abstracted git identity with struct, simplified to `Option<String>` when realized template just needs formatted string
- For CLI tools, `.unwrap()` on invariants (embedded templates, etc.) is acceptable - these are "can't happen" errors
- Regex compilation optimization not worth it for single-invocation CLI tool
- Rust 2024 edition makes `env::set_var`/`remove_var` unsafe - needed `unsafe` blocks in tests
