diff --git a/.codex/skills/do-task/SKILL.codex.md b/.codex/skills/implement-task/SKILL.codex.md similarity index 100% rename from .codex/skills/do-task/SKILL.codex.md rename to .codex/skills/implement-task/SKILL.codex.md diff --git a/.codex/skills/do-task/SKILL.md b/.codex/skills/implement-task/SKILL.md similarity index 92% rename from .codex/skills/do-task/SKILL.md rename to .codex/skills/implement-task/SKILL.md index 9efccdd..17c8338 100644 --- a/.codex/skills/do-task/SKILL.md +++ b/.codex/skills/implement-task/SKILL.md @@ -1,16 +1,16 @@ --- -name: do-task +name: implement-task description: Phase 2 skill. Use when issue scope is locked by Product Owner (Phase 1 done). Plan, implement, create PR, and own it until merged as Developer. --- -# Do Task +# Implement Task **Phase:** 2 — Requirement Implementation **Role:** Developer ## When to invoke -- User says: "implement issue #X", "/do-task #X" +- User says: "implement issue #X", "/implement-task #X" - Phase 1 is complete (issue has a "Final Requirements" comment from PO). ## Prerequisite @@ -75,6 +75,7 @@ description: Phase 2 skill. Use when issue scope is locked by Product Owner (Pha - Never edit remote files directly — always work on local branch. - Never claim completion without fresh verification output. - Keep changes strictly scoped to the approved plan. +- If the change needs durable documentation, create/update `docs/adr/**`. Do not commit `docs/superpowers/**` planning artifacts. ## Next skill After PR is created, the user invokes `/review-pr ` on the Reviewer agent. diff --git a/.codex/skills/review-pr/SKILL.md b/.codex/skills/review-pr/SKILL.md index b7bd40b..4584b47 100644 --- a/.codex/skills/review-pr/SKILL.md +++ b/.codex/skills/review-pr/SKILL.md @@ -104,6 +104,8 @@ Validation: - Post review proactively if verdict is clear. - Mention validation commands you actually ran. - No bracketed author/tool tags. +- Accept `docs/adr/**` when it records a direct, durable decision tied to the issue scope. +- Treat `docs/superpowers/**` and other agent execution artifacts as scope creep. When rejecting docs, explain whether the content should be deleted entirely or rewritten as an ADR. ## What happens next - **PASS (APPROVED):** Developer merges the PR. diff --git a/.codex/skills/validate-issue/SKILL.md b/.codex/skills/validate-issue/SKILL.md index 5f51be0..4d62b22 100644 --- a/.codex/skills/validate-issue/SKILL.md +++ b/.codex/skills/validate-issue/SKILL.md @@ -35,6 +35,7 @@ description: Phase 1 skill. Use when a Gitea issue is created or updated and nee - Stop. Wait for user to respond, then re-run this skill. - **Clear and feasible:** - Post Final Requirements (see format below). + - If the change likely needs a durable ADR, add a note: "ADR recommended: this change locks in a behavior/contract that future work must preserve." - This locks the scope and signals Phase 2 can begin. ## Final Requirements format diff --git a/AGENT.md b/AGENT.md index 03737e1..9c9dc98 100644 --- a/AGENT.md +++ b/AGENT.md @@ -118,7 +118,16 @@ Validation: --- -## 7. Comment Style +## 7. Documentation Rules + +- Durable architecture or behavior decisions belong in `docs/adr/**`. +- `docs/superpowers/**` is for agent execution artifacts and must not be merged as part of product implementation PRs. +- If a PR needs a lasting technical rationale, author an ADR in `docs/adr/` instead. +- Reviewers should treat temporary plan/spec docs as scope creep, but accept ADRs that directly document the accepted behavior of the change. + +--- + +## 8. Comment Style - Use readable multiline markdown. - Use short sections (Summary, Changes, Test Plan). diff --git a/docs/adr/0001-imap-thread-resolution.md b/docs/adr/0001-imap-thread-resolution.md new file mode 100644 index 0000000..7f8372a --- /dev/null +++ b/docs/adr/0001-imap-thread-resolution.md @@ -0,0 +1,35 @@ +--- +type: ADR +id: "0001" +title: "IMAP thread resolution prefers In-Reply-To and falls back to References" +status: active +date: 2026-04-28 +--- + +## Context + +The IMAP ingress flow stores a `thread_id` before dispatching work to OpenClaw. Previously the bridge only used `In-Reply-To` to find a parent task. Some valid email clients preserve thread ancestry through `References` even when `In-Reply-To` is absent. In those cases, the bridge created a new `thread_id`, which broke conversation continuity and downstream session reuse. + +This decision needs to be durable because future refactors of mail parsing, dispatch, or storage must preserve the same thread-resolution behavior. + +## Decision + +The bridge resolves parent thread linkage by trying `In-Reply-To` first. If no parent task is found, it falls back to `References`, scanning message IDs from last to first and using the first match found in the database. If neither header yields a known parent, the message's own `message_id` becomes the new `thread_id`. + +## Options considered + +- **Use `In-Reply-To` first, then `References` last-to-first** (chosen): preserves existing behavior, matches common email ancestry ordering, and favors the most recent known parent. +- **Use only `In-Reply-To`**: simpler, but breaks valid threads when clients omit `In-Reply-To`. +- **Search `References` from first to last**: may attach to an older ancestor even when a more recent known parent exists. +- **Normalize all thread linkage into a more complex conversation graph**: more flexible, but out of scope for the current bridge behavior. + +## Consequences + +Thread continuity is improved for replies that rely on `References`. +Future contributors have an explicit behavioral contract for threading semantics. +Mail parsing changes must preserve the header precedence and reverse scan behavior unless a new ADR supersedes this one. +The current approach still depends on existing message IDs being present in the database; if upstream behavior changes significantly, this decision may need reevaluation. + +## Advice + +If a future change wants different precedence rules or deeper conversation reconstruction, create a new ADR rather than silently changing this behavior. diff --git a/docs/adr/README.md b/docs/adr/README.md new file mode 100644 index 0000000..74d212a --- /dev/null +++ b/docs/adr/README.md @@ -0,0 +1,75 @@ +# Architecture Decision Records + +This directory contains Architecture Decision Records (ADRs) for durable technical decisions in this repository. + +## Purpose + +ADRs capture cross-cutting or behavior-defining decisions that future contributors need to preserve. + +Use an ADR when a change introduces or locks in a decision such as: + +- runtime behavior that future work must preserve +- repository-wide technical policy +- architecture or integration contracts +- storage or threading semantics +- quality gate or workflow policy + +Do not use ADRs for: + +- temporary implementation plans +- agent execution checklists +- one-off debugging notes +- PR-local task breakdowns + +## Format + +Each ADR is a markdown file with YAML frontmatter. + +```md +--- +type: ADR +id: "NNNN" +title: "Short decision title" +status: active +date: YYYY-MM-DD +--- + +## Context + +Why does this decision need to exist now? + +## Decision + +**State the decision clearly in one or two sentences.** + +## Options considered + +- **Option A** (chosen): description with pros and cons +- **Option B**: description with pros and cons +- **Option C**: description with pros and cons + +## Consequences + +What becomes easier? +What becomes harder? +What risks were accepted? +What would trigger re-evaluation? + +## Advice + +Optional. Capture important external input or review notes. +``` + +## Rules + +- One decision per file. +- Name files `NNNN-short-kebab-title.md`. +- Once active, do not rewrite an ADR's meaning later. Supersede it with a new ADR instead. +- Keep the index below aligned with the current files in this directory. +- Do not keep placeholder or mock entries in the index. + +## Index + +| ID | Title | Status | +|----|-------|--------| +| 0001 | IMAP thread resolution prefers In-Reply-To and falls back to References | active |