|
| 1 | +# Follow-ups Backlog Pattern - DevTrail |
| 2 | + |
| 3 | +> Reproducible convention for managing accumulated `§Follow-ups` and `R<N> (new, not in Charter)` entries across many AILOGs and Charters. |
| 4 | +
|
| 5 | +**Languages**: English | [Español](i18n/es/FOLLOW-UPS-BACKLOG-PATTERN.md) | [简体中文](i18n/zh-CN/FOLLOW-UPS-BACKLOG-PATTERN.md) |
| 6 | + |
| 7 | +--- |
| 8 | + |
| 9 | +## Status |
| 10 | + |
| 11 | +**v0 — proven in N=1 domain** (`StrangeDaysTech/sentinel` CHARTER-12, 2026-05-06). |
| 12 | + |
| 13 | +This is a **convention**, not a CLI feature. Adopters reproduce it locally with markdown + a portable bash script. The pattern may evolve into a `devtrail followups` subcommand once a second adopter validates it (see [Open questions](#open-questions)). |
| 14 | + |
| 15 | +--- |
| 16 | + |
| 17 | +## When this pattern applies |
| 18 | + |
| 19 | +DevTrail's per-AILOG `§Follow-ups` convention works at write time — when an AILOG is created, the implementer documents what is deferred to subsequent Charters or operational triggers. That works fine until the cumulative list grows past what an operator can scan from memory. |
| 20 | + |
| 21 | +Adopt this pattern when **any** of these conditions hold: |
| 22 | + |
| 23 | +- The project has accumulated **~20 or more AILOGs** with non-trivial `§Follow-ups` sections. |
| 24 | +- Operators repeatedly ask agents to "list what's pending across the project" and the answer requires a multi-file scan. |
| 25 | +- A "do this when X arrives" follow-up was almost lost because the originating AILOG was never re-read after X arrived. |
| 26 | +- A Charter retrospective surfaces follow-ups that should have been classified as `closed` weeks earlier but were never indexed. |
| 27 | + |
| 28 | +Below that volume, the per-AILOG convention alone is sufficient — adopting this pattern early adds maintenance overhead without payoff. |
| 29 | + |
| 30 | +--- |
| 31 | + |
| 32 | +## Shape |
| 33 | + |
| 34 | +### Registry file |
| 35 | + |
| 36 | +Single markdown file at the canonical path: |
| 37 | + |
| 38 | +``` |
| 39 | +.devtrail/follow-ups-backlog.md |
| 40 | +``` |
| 41 | + |
| 42 | +### Frontmatter (YAML) |
| 43 | + |
| 44 | +```yaml |
| 45 | +--- |
| 46 | +last_scan: 2026-05-06 |
| 47 | +schema_version: v0 |
| 48 | +buckets: |
| 49 | + - ready |
| 50 | + - time-triggered |
| 51 | + - charter-triggered |
| 52 | + - phase-blocked |
| 53 | + - operational |
| 54 | +fully_extracted_ailogs: |
| 55 | + - AILOG-2026-04-11-001 |
| 56 | + - AILOG-2026-04-12-001 |
| 57 | + # ... one entry per AILOG whose follow-ups have been processed |
| 58 | +--- |
| 59 | +``` |
| 60 | + |
| 61 | +The `fully_extracted_ailogs` list is the **load-bearing metadata** for drift detection. Every AILOG whose `§Follow-ups` and `R<N>` entries have been transferred into the registry (or explicitly classified as superseded) belongs in this list. Drift detection compares this list against AILOGs that have follow-up content in the repo. |
| 62 | + |
| 63 | +### Buckets |
| 64 | + |
| 65 | +Five buckets organize entries by trigger type: |
| 66 | + |
| 67 | +- `ready` — actionable now, no dependency on external trigger. |
| 68 | +- `time-triggered` — calendar-based trigger (audit cycle, periodic review). |
| 69 | +- `charter-triggered` — gated on a future Charter that touches the relevant area. |
| 70 | +- `phase-blocked` — gated on a future component or phase that does not yet exist. |
| 71 | +- `operational` — manual operator decision or external system action. |
| 72 | + |
| 73 | +### Entry schema |
| 74 | + |
| 75 | +Each entry inside a bucket follows this shape: |
| 76 | + |
| 77 | +```markdown |
| 78 | +### FU-NNN — <short description> |
| 79 | +- **Origin**: AILOG-NNNN-NN-NN-NNN <pointer to source section> |
| 80 | +- **Status**: open | in-progress | closed | superseded |
| 81 | +- **Trigger**: ready | <calendar date> | when <X> | <other> |
| 82 | +- **Destination**: <Charter id, "operations", or future phase> |
| 83 | +- **Cost**: <effort estimate> |
| 84 | +- **Notes**: <free-form context> |
| 85 | +``` |
| 86 | + |
| 87 | +`FU-NNN` is monotonically increasing across the registry's lifetime; do not renumber when entries close. |
| 88 | + |
| 89 | +### Status vocabulary |
| 90 | + |
| 91 | +- `open` — pending, not yet acted on. |
| 92 | +- `in-progress` — a Charter has been declared or is executing that addresses this entry. |
| 93 | +- `closed` — entry resolved (Charter merged, operational task done, time elapsed and reviewed). |
| 94 | +- `superseded` — addressed by other work that did not reference this entry directly. |
| 95 | + |
| 96 | +Closed and superseded entries stay in the file (auditable history). Operators may move them to a `## Bucket: closed` section at the bottom for visual decluttering, but they are never deleted. |
| 97 | + |
| 98 | +--- |
| 99 | + |
| 100 | +## Drift detection |
| 101 | + |
| 102 | +A small bash script is the verification layer that keeps the registry in sync with new AILOGs. The script lives in the adopter's repo (suggested path: `scripts/check-followups-drift.sh`) and has three modes. |
| 103 | + |
| 104 | +### Modes |
| 105 | + |
| 106 | +- **Default** — scan AILOGs modified in `git diff origin/main..HEAD` (with `HEAD~1..HEAD` fallback). Warn on any AILOG with `§Follow-ups` / `R<N> (new)` content that is not in `fully_extracted_ailogs`. Exit 1 on drift. |
| 107 | +- **`--apply`** — same scan, but auto-append new entries under `## Bucket: ready` with auto-generated `FU-NNN` ids and append the AILOG id to `fully_extracted_ailogs`. The operator reclassifies into the correct bucket later. |
| 108 | +- **`--scan-all`** — scan every AILOG in the project (periodic full sweep). |
| 109 | + |
| 110 | +### Per-AILOG vs per-bullet granularity |
| 111 | + |
| 112 | +Tracking is **per-AILOG**, not per-bullet. An AILOG is either fully extracted (its id is in `fully_extracted_ailogs` — trust the registry) or it is not (extract everything). Per-bullet matching would require fingerprinting (text hashing or fuzzy comparison), which produces false positives whenever a registry entry paraphrases the AILOG bullet — and curated entries always paraphrase. |
| 113 | + |
| 114 | +The cost of per-AILOG granularity: when a follow-up is added to an already-extracted AILOG post-Charter close, drift detection misses it. The remediation is operator-driven — manually remove the AILOG from `fully_extracted_ailogs` and re-run with `--apply`. This trade-off is intentional for v0 because most AILOGs are write-once after Charter close. |
| 115 | + |
| 116 | +### Script template |
| 117 | + |
| 118 | +A reference implementation (~290 lines of POSIX bash) is in `StrangeDaysTech/sentinel` at `scripts/check-followups-drift.sh`. Copy it into your repo and adjust the constants at the top: |
| 119 | + |
| 120 | +```bash |
| 121 | +BACKLOG_FILE=".devtrail/follow-ups-backlog.md" |
| 122 | +AILOG_DIR=".devtrail/07-ai-audit/agent-logs" |
| 123 | +``` |
| 124 | + |
| 125 | +The script uses `awk` and `grep` only — no jq, no yq, no heavyweight dependencies. Portable across Linux and macOS. |
| 126 | + |
| 127 | +--- |
| 128 | + |
| 129 | +## Agent integration |
| 130 | + |
| 131 | +The agent (Claude / Gemini / etc.) becomes the primary maintainer of the registry. Add to your `CLAUDE.md` / `AGENT.md`: |
| 132 | + |
| 133 | +```markdown |
| 134 | +## Follow-ups backlog |
| 135 | + |
| 136 | +- **Session start**: glance at `.devtrail/follow-ups-backlog.md` to know what is pending across the project. |
| 137 | +- **Pre-commit checklist**: created or modified any AILOG with `## Follow-ups` or `R<N> (new, not in Charter)` entries? → run `scripts/check-followups-drift.sh --apply` to extend the backlog in the same commit. |
| 138 | +- **Post-Charter close**: review entries the Charter resolved; mark them `closed` (with the closing Charter id in `Notes`) or `superseded`. |
| 139 | +``` |
| 140 | + |
| 141 | +This makes the agent the maintainer, the script the verification layer, and the operator the periodic reviewer (re-bucketing, marking closed, pruning superseded). |
| 142 | + |
| 143 | +--- |
| 144 | + |
| 145 | +## Adoption walkthrough |
| 146 | + |
| 147 | +For an adopter starting fresh: |
| 148 | + |
| 149 | +1. Create `.devtrail/follow-ups-backlog.md` with the frontmatter above (empty `fully_extracted_ailogs:` list initially) and the five `## Bucket: <name>` headers. |
| 150 | +2. Copy the reference script from `StrangeDaysTech/sentinel` to `scripts/check-followups-drift.sh`. Adjust `AILOG_DIR` if your AILOGs live elsewhere. |
| 151 | +3. Run `scripts/check-followups-drift.sh --scan-all --apply` to seed the registry from existing AILOGs. |
| 152 | +4. Reclassify the auto-generated `## Bucket: ready` entries into the correct buckets manually. This is one-time triage, typically 30-60 min for a backlog of ~50 entries. |
| 153 | +5. Add the agent integration block to `CLAUDE.md` / `AGENT.md`. |
| 154 | +6. Optionally wire `scripts/check-followups-drift.sh` into a pre-commit hook for hard enforcement. |
| 155 | + |
| 156 | +For an adopter migrating from ad-hoc tracking: the same flow, but step 4 may require deciding which entries are already `closed` or `superseded` — that classification is what makes the registry useful. |
| 157 | + |
| 158 | +--- |
| 159 | + |
| 160 | +## Reference implementation |
| 161 | + |
| 162 | +`StrangeDaysTech/sentinel` CHARTER-12, merged 2026-05-06: |
| 163 | + |
| 164 | +- Implementation PR: [sentinel#53](https://github.com/StrangeDaysTech/sentinel/pull/53) (registry + script + CLAUDE.md additions). |
| 165 | +- Close-out PR: [sentinel#54](https://github.com/StrangeDaysTech/sentinel/pull/54) (post-merge verification + Charter close). |
| 166 | + |
| 167 | +Empirical context: 47 entries seeded from CHARTER-08 → CHARTER-11 retrospective (~30 min of multi-agent triage). The chain demonstrated the gap that motivated the pattern — without the registry, the operator could not see "what is pending across the project" without re-classifying each Charter's follow-ups in isolation. With the registry, session-start glance is one file read. |
| 168 | + |
| 169 | +--- |
| 170 | + |
| 171 | +## Open questions |
| 172 | + |
| 173 | +These are not resolved in v0. Future revisions of this pattern, or a CLI helper, may address them: |
| 174 | + |
| 175 | +- **Bucket classification heuristic**. Today `--apply` dumps every new entry into `## Bucket: ready`; the operator reclassifies manually. A heuristic using AILOG `tags` and Charter `effort_estimate` could suggest a bucket automatically. |
| 176 | +- **Schema validation**. The registry follows a tacit schema; no `.devtrail/schemas/follow-ups-backlog.schema.v0.json` exists yet. Validation today is human review. |
| 177 | +- **Integration with the audit cycle**. When `devtrail charter audit --merge-reports` produces real-debt findings that are not remediated atomically pre-close, those findings live only in `.devtrail/audits/<id>/review.md`. They do not auto-flow into the central registry. Surfacing them automatically would close a known gap. |
| 178 | +- **`closed` vs `superseded` semantics**. Today the difference is whether the resolving work explicitly referenced the entry. A stricter convention may emerge. |
| 179 | +- **Cristalization as `devtrail followups` CLI**. Once a second adopter validates the pattern, the framework may ship a subcommand mirroring the existing `devtrail charter` trio: `list` / `close` / `drift`. Adopters at v0 (this pattern) migrate by deleting their local script and switching the agent instruction. |
| 180 | + |
| 181 | +--- |
| 182 | + |
| 183 | +## Credits |
| 184 | + |
| 185 | +Contributed via [issue #111](https://github.com/StrangeDaysTech/devtrail/issues/111) by the Sentinel adopter. Empirical foundation: CHARTER-08 → CHARTER-11 chain in `StrangeDaysTech/sentinel`. Author: Claude Opus 4.7 on behalf of operator José Villaseñor Montfort. |
| 186 | + |
| 187 | +--- |
| 188 | + |
| 189 | +*DevTrail v4.10.0 | [Strange Days Tech](https://strangedays.tech)* |
0 commit comments