- AGENTS.md: platform overview, build/run, project structure, key patterns, constraint rules A-H adapted for forensic password-cracking toolchain - ARCHITECTURE.md: components, data flow, deployment model, performance targets - GLOSSARY.md: 12 domain terms (.accdb, AES-256-CBC, ECMA-376, JtR, mutation, etc.) - MODIFICATIONS.md: file map, 4 known gotchas, conventions, session log - docs/CONTEXT.md and docs/index.md: project-specific routing - Scaffold docs/ai-development/solutions/gca-law-password-crack/ with full structure: sessions/2026/, summaries/, reports/, imports/ |
||
|---|---|---|
| .factory | ||
| archive | ||
| docs | ||
| server | ||
| tools | ||
| .env.example | ||
| .gitattributes | ||
| .gitignore | ||
| AGENTS.md | ||
| ARCHITECTURE.md | ||
| DOCUMENTATION_STANDARD.md | ||
| GLOSSARY.md | ||
| MODIFICATIONS.md | ||
| README.md | ||
| REFACTOR_DESIGN.md.example | ||
| TEMPLATE_USAGE.md | ||
ADR-AI Development Documentation System
Every AI coding session on this repository becomes a permanent, version-controlled, vendor-neutral document. Prompts, responses, tool calls, file changes, decisions, token usage, and git state are captured automatically, redacted of secrets, normalized to a common schema, and written into
docs/ai-development/where they can be committed next to the code they produced.
Status: Complete and verified (10/10 build sessions finished 2026-07-16; 439 tests passing; acceptance-verified end to end against synthetic fixtures and 18 real Factory.ai session logs).
Table of contents
- What this solution is
- Why prompts are the source code of agentic AI programming
- Download and install on a Factory.ai computer
- Verify it is working
- Layout of the prompt-documentation store
- Importing legacy Factory.ai sessions
- Supporting other AI tools
- Troubleshooting and FAQ
- Repository map and further reading
1. What this solution is
The AI Development Record (ADR-AI) system is a self-contained toolkit that documents AI-assisted software development the same way git documents code. It has two halves:
| Half | Where | What it does |
|---|---|---|
| Tooling | tools/adr_ai/ |
Python package: vendor adapters, schema validator, secret redactor, historical importer, index/report generators, and automatic SessionStart/SessionEnd hooks |
| Store | docs/ai-development/ |
The generated documentation: one directory per project ("Solution"), one directory per session, plus cross-session summaries, reports, and the canonical schema |
Two capture paths feed the store:
- Automatic (hooks). A
SessionStart/SessionEndhook pair, wired at.factory/hooks.json, documents every live Factory.ai droid session the moment it ends: no manual step. The hooks are fail-open (they can never block or corrupt a session), idempotent (re-firing produces a zero-byte diff), and dry-runnable. - Batch (importer).
run_import()walks your existing Factory.ai session logs (months or years of history), groups them by project, and backfills the store in one pass. Re-running it is a no-op.
Every captured session is normalized to an 11-event-type JSONL schema
(session_start, prompt, response, tool_call, tool_result,
file_change, command, validation, decision, human_review,
session_end), redacted of secrets before anything touches disk,
validated against JSON Schema, and rendered three ways per session:
session.md, a human-readable narrative of the sessiontranscript.jsonl, the machine-readable event log (one event per line)metadata.yaml, the structured envelope (model, tokens, duration, commit-before/after, branch, files touched)
The pipeline is vendor-neutral by construction: Factory.ai and Claude Code adapters are implemented, and six more tools (Codex CLI, Cursor, Continue, Cline, Aider, Gemini CLI) ship as documented adapter stubs (see Section 7).
2. Why prompts are the source code of agentic AI programming
In conventional development the source code is the durable creative artifact: everything else (binaries, docs) can be regenerated from it. In agentic development that relationship inverts. The generated code is the output. The durable creative act is what the human contributed: the intent, the constraints, the corrections, the acceptance judgments, and the decision points, and those live in the prompts and the session transcript, nowhere else.
Concretely:
- Code cannot answer "why". A diff shows what changed. The session transcript shows what was asked for, which alternatives were rejected, what constraint forced the design, and what the human approved. That is the information a future maintainer (human or AI) actually needs, and it is destroyed the moment a session window closes undocumented.
- The code is increasingly regenerable; the intent is not. Given the recorded prompts, constraints, and decisions, a future (better) model can re-derive, port, or upgrade the implementation. Given only the code, no tool can recover the intent. Losing prompts is losing the master copy and keeping the printout.
- Vendor session logs are not an archive. Native logs live outside the
repository (for Factory:
~/.factory/sessions/), in a proprietary shape that changes between versions, on one machine, unredacted, and invisible to version control. This system converts them into redacted, schema- stable, git-friendly Markdown/JSONL that is committed next to the code each session produced, withcommit_before/commit_afterrecorded so every code change is traceable to the conversation that caused it. - Provenance and audit become first-class. Which model wrote this
module, at what token cost, running which commands, validated how, and
approved by whom: those questions become greppable
(
summaries/prompts-by-topic.md,reports/contributor-report.md,reports/token-usage.md) instead of unanswerable. - Onboarding compounds. A new contributor (or a fresh AI session with an
empty context window) reads
summaries/timeline.mdandsummaries/decisions.mdand inherits the project's entire reasoning history, not just its current state.
That is the thesis of this repository: treat the conversation as source, and version it accordingly.
3. Download and install on a Factory.ai computer
Prerequisites
- Python 3.11+ available as
pythononPATH(the hooks invoke it) - Factory.ai droid CLI installed and working
- git on
PATH(optional but recommended; used for commit/branch correlation and, of course, for committing the store)
Step 1: Get the repository
Clone (or copy) this repository onto the machine:
git clone <your-remote-for-this-repo> C:\ADR # or copy the folder
cd C:\ADR
This repository is shipped without git history initialized. If you received it as a plain folder, initialize it so commit correlation and store versioning work:
git init -b main; git add .; git commit -m "adopt ADR-AI system".
Step 2: Create the venv and install the pinned dependencies
cd C:\ADR
python -m venv venv
venv\Scripts\python -m pip install -r tools\adr_ai\requirements.txt
POSIX equivalent: python -m venv venv && venv/bin/python -m pip install -r tools/adr_ai/requirements.txt.
The dependency set is deliberately tiny (stdlib-first policy): jsonschema
(+ its three transitive pins) for validation, and pytest + PyYAML for
the test suite only.
Step 3: Make the hook interpreter able to import jsonschema
The shipped hook wiring (.factory/hooks.json) runs the hooks with the
python on Factory's PATH, not the venv. Pick one:
-
Option A (default): install the runtime deps into that interpreter:
python -m pip install -r tools\adr_ai\requirements.txt -
Option B (keep everything in the venv): edit
.factory/hooks.jsonand replace both"python"command prefixes with the venv interpreter, e.g."$FACTORY_PROJECT_DIR/venv/Scripts/python.exe"on Windows or"$FACTORY_PROJECT_DIR/venv/bin/python"on Linux/macOS.
If neither is done, nothing breaks: the hooks are fail-open and will simply log the import error and exit 0, but no sessions get documented, so do one of them.
Step 4: Hooks are already wired (project scope)
The repo ships with the hooks enabled for itself:
// .factory/hooks.json (shipped)
"SessionStart" -> python tools/adr_ai/hooks/run_session_start_hook.py (timeout 30s)
"SessionEnd" -> python tools/adr_ai/hooks/run_session_end_hook.py (timeout 60s)
Any droid session run inside this project is documented automatically from now on. Nothing else to configure.
To document other repositories on the same machine, merge the same two
blocks into your user-scope ~/.factory/hooks.json. A safety gate applies:
without an explicit ADR_AI_DOCS_ROOT, the SessionEnd hook only documents a
repo whose docs/ai-development/ directory already exists, so a
user-scoped hook can never spawn a documentation store in an arbitrary
repo. To opt a repo in, either create that directory (copy
docs/ai-development/schema/ along with it) or set ADR_AI_DOCS_ROOT to
the target store path.
Environment-variable control surface (all optional)
| Variable | Effect | Default |
|---|---|---|
ADR_AI_HOOK_DISABLED |
truthy = both hooks become no-ops | off |
ADR_AI_HOOK_DRY_RUN |
truthy = full pipeline, zero writes | off |
ADR_AI_DOCS_ROOT |
explicit store path; also bypasses the opt-in gate | <session cwd>/docs/ai-development |
ADR_AI_HOOK_STATE_DIR |
where SessionStart stashes git state | <tempdir>/adr_ai_hooks |
ADR_AI_HOOK_LOG |
the hooks' own operational log | ~/.factory/logs/adr_ai_hook.log |
ADR_AI_FACTORY_SESSIONS_HOME |
where the importer looks for Factory logs | ~/.factory/sessions |
Truthy means one of 1, true, yes, on (case-insensitive). Full
contract: tools/adr_ai/hooks/CONTEXT.md.
4. Verify it is working
4.1 Run the test suite (should be 439 passing)
cd C:\ADR
venv\Scripts\python -m pytest tools\adr_ai\tests -q
Expected: 439 passed. This exercises every stage (adapters, validator,
redactor, importer, generators, hooks) against synthetic fixtures,
including end-to-end import and hook cycles.
4.2 Dry-run a live capture
$env:ADR_AI_HOOK_DRY_RUN = "1"
# ...run any short droid session in this repo, then:
Get-Content "$HOME\.factory\logs\adr_ai_hook.log" -Tail 20
Remove-Item Env:ADR_AI_HOOK_DRY_RUN
You should see session_start and session_end log lines for your session
and no new files under docs/ai-development/solutions/.
4.3 Capture one real session
Run a short droid session in this repo (ask it anything), end it, then:
Get-ChildItem -Recurse docs\ai-development\solutions -Filter session.md | Select-Object -Last 3
A new solutions/<slug>/sessions/<year>/<date>-session-<NNN>/ directory
should exist containing session.md, transcript.jsonl, metadata.yaml,
and hashes.txt, and that Solution's summaries/ and reports/ files
should have refreshed. The hook log gets one line per stage.
4.4 Confirm the safety properties
- Idempotency: run the importer twice (Section 6);
the second run must report every session
unchangedandgit statusmust show no diff. - Secret safety: generated files never contain raw secrets (the
redactor replaces them with
<REDACTED:kind[:xxxxxxxx]>tokens and writes a redaction report). The only unredacted copy is the archived vendor JSON underimports/raw/, which is gitignored (see.gitignore) and stays local. - Fail-open: break something on purpose (e.g. temporarily rename
tools/adr_ai/) and end a session; the droid session itself must be unaffected, with the failure visible only in the hook log.
5. Layout of the prompt-documentation store
Everything generated lives under docs/ai-development/:
docs/ai-development/
README.md what this subtree is, how it is produced
index.md local router ("to answer X, read Y")
CONTEXT.md directory contract (every directory has one)
schema/ THE CANONICAL CONTRACT (hand-ratified, not generated)
ai-session-schema.md the 11 normalized transcript event types, field by field
metadata-schema.md the metadata.yaml field set
templates/ fill-in blanks: session.md, transcript.jsonl, metadata.yaml
json/ machine-checkable JSON Schema (draft 2020-12), one file
per event type + common.schema.json + metadata.schema.json
solutions/ one directory per Solution (project/workspace)
example-solution/ permanent placeholder illustrating the layout (never
written to by the tooling; see FAQ)
<your-solution-slug>/ created by the importer/hook on first real capture
README.md orientation for this Solution
CONTEXT.md
sessions/
<YYYY>/ year partition (multi-year history stays navigable)
<YYYY-MM-DD>-session-<NNN>/ ordinal NNN never renumbers
session.md human-readable narrative (goal, prompts, decisions,
files changed, validations, outcome)
transcript.jsonl one schema-valid event per line, in order
metadata.yaml model, tokens, duration, branch,
commit_before/commit_after, files, tools
hashes.txt SHA-256 of the other three (tamper/consistency check)
artifacts/ oversized/binary payloads, content-addressed by
sha256; transcript events hold blob_refs instead
summaries/ REGENERATED cross-session indexes
timeline.md chronological session index
prompts-by-topic.md every prompt, grouped by topic
files-by-session.md which session touched which file
decisions.md every recorded decision, with context
reports/ REGENERATED analytics
statistics.md session/event/tool counts and distributions
token-usage.md token spend per session/model
contributor-report.md human vs AI contribution breakdown
redaction-report.md what the redactor found and replaced (hook runs)
imports/
import-log.md append-only journal, one entry per import run
redaction-report.md redaction summary for batch import runs
raw/ archived original vendor JSON [GITIGNORED, local only]
Reading order for a newcomer: a Solution's summaries/timeline.md, then any
interesting session's session.md, then its transcript.jsonl when you
need the exact event-level record. The schema that governs every generated
file is documented (prose and JSON Schema) under docs/ai-development/schema/.
Commit policy: everything above is designed to be committed except
imports/raw/, which is excluded by .gitignore because it is the one
unredacted copy of the vendor logs.
6. Importing legacy Factory.ai sessions
If this machine has been running Factory.ai droid sessions, their logs are already on disk at:
~/.factory/sessions/<workspace>/<session-uuid>.jsonl (one per session)
~/.factory/sessions/<workspace>/<session-uuid>.settings.json (sidecar, if present)
where <workspace> encodes the project directory (e.g. -C-ADR for
C:\ADR). The historical importer backfills the store from these in one
deliberate, repeatable pass.
6.1 Run the import
From the repo root:
@'
import sys
sys.path.insert(0, "tools")
from adr_ai.importer import run_import
report = run_import()
print(f"sessions discovered: {report.discovered}")
for slug in sorted({o.solution_id for o in report.outcomes}):
print(f" {slug}: imported={report.imported_count(slug)}"
f" refreshed={report.refreshed_count(slug)}"
f" unchanged={report.unchanged_count(slug)}"
f" invalid={len(report.invalid_for(slug))}")
print(f"duplicate sources: {len(report.duplicate_sources)}"
f" content duplicates: {len(report.content_duplicates)}")
'@ | venv\Scripts\python -
What one run does, per discovered session (the ratified 9-step process):
discover and de-duplicate by session UUID, group by Solution (derived from
each session's recorded working directory, not its folder name), normalize
to the 11-event schema, redact secrets, validate against the JSON
Schema (invalid streams are reported and never written), overflow oversized
fields to artifacts/, render and write the four session files (only if
bytes changed), archive the raw vendor JSON to imports/raw/ (gitignored),
then per Solution: write the redaction report, append an entry to
imports/import-log.md, and regenerate summaries/ + reports/.
6.2 Scope the import (recommended for multi-project machines)
By default the importer walks all of ~/.factory/sessions, which
creates one Solution per project it finds. To import only one project's
history, point discovery at that workspace directory:
$env:ADR_AI_FACTORY_SESSIONS_HOME = "$HOME\.factory\sessions\-C-ADR" # this repo only
# ...run the import block above, then:
Remove-Item Env:ADR_AI_FACTORY_SESSIONS_HOME
(Equivalently, pass run_import(discover_root=Path(...)) in the snippet.)
6.3 Verify and commit
# 1. Re-run the same import: every session must now report "unchanged"
# and `git status` must be clean (byte-identical idempotency).
# 2. Inspect a few generated session.md files and the summaries.
# 3. Confirm nothing secret leaked: the only unredacted copy is under
# imports/raw/, and `git status` must NOT list anything under it.
git add docs/ai-development
git commit -m "adr-ai: import historical Factory.ai sessions"
6.4 Known limitation for real Factory logs (DOC-9)
Current real Factory.ai logs omit a session_start timestamp and use
is_error / modelId fields where the adapter expects status/
exit_code / model. Everything still imports, validates, and re-runs
idempotently, but until the documented one-file adapter fix lands
(docs/changes/gotchas.md DOC-9): real sessions are partitioned under
sessions/unknown/ with unknown-date-session-NNN names, errored tool
results normalize as status: "ok", and per-response model names are not
captured (the session-level model still is). Track or fix via gotcha DOC-9.
7. Supporting other AI tools
The store is vendor-neutral; adapters translate each tool's native log into
the common schema. Shipped today (tools/adr_ai/adapters/):
| Adapter | Status |
|---|---|
factory.py (Factory.ai droid) |
Implemented, hook-integrated |
claude_code.py (Claude Code CLI) |
Implemented (batch import) |
stubs.py: Codex CLI, Cursor, Continue, Cline, Aider, Gemini CLI |
Documented stubs with per-tool mapping research in their docstrings |
To add a tool: subclass BaseAdapter, implement discover() /
session_id() / to_events(), decorate with @register, and add
fixtures. The conformance suite (tests/test_adapter_conformance.py)
auto-covers every registered adapter, and the importer picks it up with no
importer changes. Contract: tools/adr_ai/adapters/CONTEXT.md.
8. Troubleshooting and FAQ
A session ended but nothing appeared in the store.
Check, in order: (1) the hook log (~/.factory/logs/adr_ai_hook.log), where
every failure is recorded (hooks are fail-open by design and never surface
errors into your session); (2) that python -c "import jsonschema" works
for the interpreter named in .factory/hooks.json (Step 3 above); (3) that
neither ADR_AI_HOOK_DISABLED nor ADR_AI_HOOK_DRY_RUN is set; (4) the
opt-in gate: for repos other than this one, docs/ai-development/ must
already exist or ADR_AI_DOCS_ROOT must be set.
My imported sessions are under sessions/unknown/.
Expected for current real Factory logs until the DOC-9 adapter fix lands
(see Section 6.4).
Why is there a Solution named example-solution?
It is a permanent, hand-authored placeholder that illustrates the layout
(Windows cannot create a directory literally named <solution-name>). The
tooling refuses to write into it (SolutionCollisionError), so it never
mixes with real data. See gotcha FS-1.
Does anything get committed automatically? No. The hooks and importer only stage files in the working tree; a human (or your own workflow) commits. Auto-commit was deliberately not adopted.
How do I pause or remove the system?
Pause: ADR_AI_HOOK_DISABLED=1. Preview: ADR_AI_HOOK_DRY_RUN=1. Remove:
delete the two hook blocks from .factory/hooks.json (and any user-scope
copy); the store remains as plain committed documentation.
Where do secrets go?
Detected secrets never reach generated files: the redactor replaces them
with stable <REDACTED:kind[:xxxxxxxx]> tokens pre-write and logs the
counts to a redaction report. The archived originals under imports/raw/ are
gitignored. Redaction patterns and the allowlist live in
tools/adr_ai/redactor/ (constraint AGENTS.md B5 applies).
Is my history safe if I change AI vendors? That is the point: the committed store is schema-stable Markdown/JSONL, and new vendors only need an adapter (Section 7).
9. Repository map and further reading
| Path | What it is |
|---|---|
tools/adr_ai/ |
The toolkit (each subpackage has a CONTEXT.md contract) |
docs/ai-development/ |
The generated store + canonical schema |
.factory/hooks.json |
Project-scope hook wiring (the automatic capture) |
docs/refactors/ADR_AI_SYSTEM_DECISION_RECORD.md |
Every ratified design decision (§4.a-k) behind the system |
docs/refactors/Completed/REFACTOR_DESIGN_ADR_AI_DOCUMENTATION_SYSTEM.md |
The original design specification |
docs/refactors/Completed/REFACTORING_DIRECTIONS_ADR_AI_DOCUMENTATION_SYSTEM.md |
The 10-session build plan, with per-session results |
docs/changes/latest.md, docs/changes/gotchas.md |
Session log and known gotchas (DOC-1..DOC-9, FS-1) |
AGENTS.md, docs/index.md |
The AI operating contract and the global routing index |
MODIFICATIONS.md |
File map and source-of-truth index |
About the surrounding framework. This repository is built on a reusable
AI-refactor-workflow template (bootstrap contract in AGENTS.md, routing
index in docs/index.md, refactor methodology in
docs/workflows/refactor-methodology.md, and a placeholder Flask/SQLite
server/ scaffold that the ADR-AI system does not touch). If you want to
reuse that template for new projects, read TEMPLATE_USAGE.md; it is
independent of the ADR-AI system documented here.