diff --git a/.backlogit/queue/003-C.md b/.backlogit/queue/003-C.md new file mode 100644 index 0000000..ea95574 --- /dev/null +++ b/.backlogit/queue/003-C.md @@ -0,0 +1,45 @@ +--- +id: "003-C" +title: "Backlogit infrastructure hygiene" +artifact_type: chore +status: queued +priority: medium +description: "Fix backlog ID namespace collision at config level and gitignore backlogit DB files. Two config-only tasks that improve tooling reliability and repository cleanliness." +labels: + - "backlogit" + - "config" + - "hygiene" +references: + - "docs/plans/2026-05-24-backlogit-infra-hygiene-plan.md" + - "docs/decisions/2026-05-23-backlog-id-collision.md" + - "docs/decisions/2026-05-24-backlogit-infra-hygiene-deliberation.md" +created_at: "2026-05-23T20:12:17.0000000-07:00" +updated_at: "2026-05-23T21:17:23.0072735-07:00" +--- + +## Scope + +Two config-level fixes for backlogit infrastructure: + +1. **ID namespace collision fix**: Give chores a type-discriminated task naming + format (`{NNN}C{suffix}`) so chore task IDs never collide with feature task IDs. + +2. **Gitignore DB files**: Add `.backlogit/*.db` to `.gitignore` and untrack + `.backlogit/backlogit.db`. Keep `.backlogit/stash.jsonl` tracked. + +## Acceptance Criteria + +- New chores created after the config change get collision-free task IDs + (e.g., `003C.001-T`); this staged shipment's existing queue items remain + `003.001-T` / `003.002-T` unless a later migration is approved +- `.backlogit/backlogit.db` does not appear in `git status` +- `.backlogit/stash.jsonl` remains tracked +- `backlogit doctor` passes after config change +- CI passes (no Rust code changes) + +## Source Documents + +- Decision: `docs/decisions/2026-05-23-backlog-id-collision.md` +- Deliberation: `docs/decisions/2026-05-24-backlogit-infra-hygiene-deliberation.md` +- Plan: `docs/plans/2026-05-24-backlogit-infra-hygiene-plan.md` +- Compound: `docs/compound/backlogit-id-collision-archival-protocol.md` diff --git a/.backlogit/queue/003.001-T.md b/.backlogit/queue/003.001-T.md new file mode 100644 index 0000000..a207cfe --- /dev/null +++ b/.backlogit/queue/003.001-T.md @@ -0,0 +1,36 @@ +--- +id: "003.001-T" +title: "Gitignore backlogit DB files and untrack cached database" +artifact_type: task +status: queued +priority: medium +parent_id: "003-C" +description: "Add .backlogit/*.db to .gitignore, run git rm --cached .backlogit/backlogit.db, verify stash.jsonl remains tracked." +labels: + - "backlogit" + - "gitignore" + - "config" +references: + - "docs/plans/2026-05-24-backlogit-infra-hygiene-plan.md" +created_at: "2026-05-23T20:12:17.0000000-07:00" +updated_at: "2026-05-23T21:17:23.0072735-07:00" +--- + +## Implementation Notes + +1. Add a `# backlogit (tool-managed cache)` section to `.gitignore` +2. Add rule: `.backlogit/*.db` +3. Run `git rm --cached .backlogit/backlogit.db` +4. Verify: `git ls-files .backlogit/stash.jsonl` still shows the file +5. Verify: `git status` no longer shows `.backlogit/backlogit.db` + +## Acceptance Criteria + +- `.backlogit/*.db` rule exists in `.gitignore` +- `.backlogit/backlogit.db` is untracked (does not appear in `git status`) +- `.backlogit/stash.jsonl` remains tracked (`git ls-files` confirms) +- `backlogit sync` succeeds after change (DB regenerates from markdown) + +## Execution Posture + +Config change — no test harness needed. Validate via git commands. diff --git a/.backlogit/queue/003.002-T.md b/.backlogit/queue/003.002-T.md new file mode 100644 index 0000000..2e9b398 --- /dev/null +++ b/.backlogit/queue/003.002-T.md @@ -0,0 +1,47 @@ +--- +id: "003.002-T" +title: "Fix chore task ID namespace with type-discriminated format" +artifact_type: task +status: queued +priority: medium +parent_id: "003-C" +description: "Modify .backlogit/config.yaml chore name_format to use type-discriminated prefix so chore task IDs do not collide with feature task IDs, after confirming config.yaml is the authoritative artifact-type config." +labels: + - "backlogit" + - "config" + - "id-collision" +references: + - "docs/plans/2026-05-24-backlogit-infra-hygiene-plan.md" + - "docs/decisions/2026-05-23-backlog-id-collision.md" +created_at: "2026-05-23T20:12:17.0000000-07:00" +updated_at: "2026-05-23T21:17:23.0072735-07:00" +--- + +## Implementation Notes + +1. Confirm the target file before editing: inspect `.backlogit/config.yaml` or use + `backlogit_get_metadata_catalog` to verify it defines + `artifact_types.chore.name_format`; `.backlogit/config.yml` is generated + autoharness metadata and does not control artifact ID formatting +2. Edit `.backlogit/config.yaml` — change chore `name_format` from `'{NNN}{suffix}'` + to `'{NNN}C{suffix}'` +3. Run `backlogit doctor` to validate no parse errors +4. Create a test chore item to verify new ID format (e.g., `003C-C` or similar) +5. Verify existing archived items remain accessible +6. If backlogit rejects the format: fall back to a `prefix: C` approach or + consult backlogit documentation for supported format tokens + +## Acceptance Criteria + +- `.backlogit/config.yaml` is confirmed as the authoritative file for + `artifact_types.chore.name_format` +- `.backlogit/config.yaml` chore section uses type-discriminated naming +- `backlogit doctor` reports no errors +- New chore items get IDs that cannot collide with feature IDs +- Existing queue and archive items remain queryable +- The compound learning `backlogit-id-collision-archival-protocol.md` must be + marked as superseded once the fix is validated + +## Execution Posture + +Migration-first — apply config change, then validate with doctor and a test create. diff --git a/.backlogit/queue/005-S.md b/.backlogit/queue/005-S.md new file mode 100644 index 0000000..cc4a988 --- /dev/null +++ b/.backlogit/queue/005-S.md @@ -0,0 +1,58 @@ +--- +id: "005-S" +title: "Backlogit infrastructure hygiene" +artifact_type: shipment +status: queued +priority: medium +description: "Ship backlogit config hygiene: gitignore DB files + fix chore task ID namespace collision." +labels: + - "backlogit" + - "config" + - "hygiene" +references: + - "docs/plans/2026-05-24-backlogit-infra-hygiene-plan.md" +created_at: "2026-05-23T20:12:17.0000000-07:00" +custom_fields: + items: + - 003-C + - 003.001-T + - 003.002-T +updated_at: "2026-05-23T21:17:23.0072735-07:00" +--- + +## Manifest + +| Order | Item ID | Title | Type | +|---|---|---|---| +| 1 | 003-C | Backlogit infrastructure hygiene | chore | +| 2 | 003.001-T | Gitignore backlogit DB files and untrack cached database | task | +| 3 | 003.002-T | Fix chore task ID namespace with type-discriminated format | task | + +## Execution Notes + +- **Suggested order**: 003.001-T first (gitignore — lower risk, cleans working tree), + then 003.002-T (config change — requires validation) +- **Branch name**: `chore/backlogit-infra-hygiene` +- **No Rust code changes** — CI gates (fmt, clippy, test, build) should pass trivially +- **Working tree prep**: The dirty `.backlogit/backlogit.db` will be resolved by + task 003.001-T itself (git rm --cached); stage the stash.jsonl change as part of + the branch setup commit + +## Pre-Ship Gate Considerations + +1. **Dirty working tree**: `.backlogit/backlogit.db` (modified) and + `.backlogit/stash.jsonl` (modified) are currently dirty. Ship should: + - Commit stash.jsonl changes (legitimate tracked state) on the feature branch + - Task 003.001-T will handle untracking the DB file +2. **Prior 004-S local-only memory artifact** should stay out of this shipment + PR; it belongs to the prior 004-S closure and should not block or + contaminate this chore +3. **backlogit doctor validation**: Must run after 003.002-T to confirm the config + change is accepted + +## Source Documents + +- Deliberation: `docs/decisions/2026-05-24-backlogit-infra-hygiene-deliberation.md` +- Plan: `docs/plans/2026-05-24-backlogit-infra-hygiene-plan.md` +- Prior decision: `docs/decisions/2026-05-23-backlog-id-collision.md` +- Stash entry: `E1B44C77` diff --git a/.backlogit/stash.jsonl b/.backlogit/stash.jsonl index 0e85204..1e79bdc 100644 --- a/.backlogit/stash.jsonl +++ b/.backlogit/stash.jsonl @@ -24,4 +24,4 @@ {"id":"F3A12B91","priority":"low","kind":"task","text":"Decouple YamlValue from the public API surface in yaml_provider: the pub use serde_yaml_ng::Value as YamlValue re-export and the options: BTreeMap public struct field in schema.rs bind the crate public API to a concrete YAML library type. Fix requires an associated type on YamlProvider or an opaque wrapper type with a migration path for callers. Source: PR #6 Copilot review thread PRRT_kwDOQEGgTs6EOIPy — docs/closure/001-S post-merge closure will reference.","created_at":"2026-05-22T20:11:00Z"} {"id":"C1E4F807","priority":"low","kind":"task","text":"ADR-001 Decision paragraph line-length formatting polish: the paragraph added in PR #6 commit 2106061 has inconsistent line wrapping (long lines with multiple sentences). Reformat to ~80-100 char lines for consistency with the rest of the ADR. Source: PR #6 Copilot review thread PRRT_kwDOQEGgTs6EOh6n.","created_at":"2026-05-22T20:40:00Z"} {"id":"F2454A73","priority":"low","kind":"task","text":"Raise CI coverage threshold above 60%: current line coverage exceeds 60%. Measure baseline, then raise COVERAGE_THRESHOLD in .github/workflows/ci.yml env block incrementally (70%, 80%) as the test suite stabilises. Source: docs/closure/2026-05-23-003-S-closure.md","created_at":"2026-05-23T00:13:42Z"} -{"id":"E1B44C77","priority":"medium","kind":"chore","text":"Fix backlog ID namespace collision at config level: modify backlogit config.yaml so chores use a type-discriminated task naming format (e.g., 002C.001-T) to avoid clashing with feature task IDs when parent NNN values match. Until then, colliding queue task files must be deleted (not archived) at shipment close time. Source: docs/decisions/2026-05-23-backlog-id-collision.md","created_at":"2026-05-23T22:31:00Z"} +{"id":"E1B44C77","priority":"medium","kind":"chore","text":"Fix backlog ID namespace collision at config level: modify backlogit config.yaml so chores use a type-discriminated task naming format (e.g., 002C.001-T) to avoid clashing with feature task IDs when parent NNN values match. Until then, colliding queue task files must be deleted (not archived) at shipment close time. Source: docs/decisions/2026-05-23-backlog-id-collision.md","created_at":"2026-05-23T22:31:00Z","state":"harvested","harvested_to":"003-C"} diff --git a/docs/decisions/2026-05-24-backlogit-infra-hygiene-deliberation.md b/docs/decisions/2026-05-24-backlogit-infra-hygiene-deliberation.md new file mode 100644 index 0000000..eeac806 --- /dev/null +++ b/docs/decisions/2026-05-24-backlogit-infra-hygiene-deliberation.md @@ -0,0 +1,114 @@ +--- +title: "Backlogit Infrastructure Hygiene" +type: deliberation +description: "Deliberation on grouping backlog ID namespace fix with gitignore hygiene for backlogit DB files" +topic: "Backlogit config-level fixes: ID namespace collision + gitignore DB files" +depth: "lightweight" +stash_ids: + - "E1B44C77" +promote_to: "plan" +created: 2026-05-24 +linked_artifacts: + - "docs/decisions/2026-05-23-backlog-id-collision.md" + - "docs/compound/backlogit-id-collision-archival-protocol.md" +tags: + - "backlogit" + - "config" + - "gitignore" + - "chore" +--- + +## Problem Frame + +Two backlogit infrastructure issues require config-level fixes: + +1. **ID namespace collision** (`E1B44C77`): Features and chores share a single + `{NNN}` sequence counter. When both hit the same counter value, their child + tasks produce identical IDs (`001.001-T` under both `001-F` and `001-C`). + The workaround (delete-not-move on archival) is documented but fragile. The + root fix is type-discriminated task naming for chores. + +2. **Gitignore gap** (operator instruction): `.backlogit/backlogit.db` is a + tool-managed SQLite cache that should not be tracked in git. It appears as + dirty working tree noise and risks merge conflicts. The stash file + (`.backlogit/stash.jsonl`) is intentionally tracked state and must remain so. + +**Who cares**: Ship agent (archival correctness), all agents (clean `git status`), +operator (repository hygiene). + +**Success criteria**: Chore tasks get collision-free IDs; backlogit DB files are +gitignored; stash.jsonl remains tracked. + +## Research Findings + +* The existing decision document (`2026-05-23-backlog-id-collision.md`) confirms + the root cause and recommends type-discriminated prefixes for chore tasks. +* The compound learning (`backlogit-id-collision-archival-protocol.md`) documents + the interim workaround and explicitly references `E1B44C77` as the long-term fix. +* Current `config.yaml` uses `name_format: '{NNN}{suffix}'` for all types — + chores get `{NNN}-C` and their tasks inherit the same `{NNN}` as features. +* Current `.gitignore` has no rules for `.backlogit/` database files. +* `.backlogit/backlogit.db` is currently tracked (shows as modified in + `git status`). + +## Options Evaluated + +### Option A: Combined chore — config fix + gitignore in one release unit + +Both changes target the same infrastructure surface (`.backlogit/` and +`.gitignore`), require no Rust source changes, and form a coherent "backlogit +hygiene" chore. Ship them together. + +* **Pros**: Single PR, coherent scope, fast turnaround, unblocks Ship immediately +* **Cons**: None significant — both are small config changes +* **Effort**: Low (2 tasks × ~1 hour each) +* **Fit**: Excellent — both are medium-priority config hygiene + +### Option B: Separate chores — one for ID fix, one for gitignore + +Stage each as its own chore with its own shipment. + +* **Pros**: Maximum isolation +* **Cons**: Unnecessary overhead for two tiny changes that share the same surface; + doubles PR review cost; both are prerequisite hygiene for future work +* **Effort**: Same total effort but double coordination cost +* **Fit**: Poor — artificially splitting coherent work + +## Trade-off Comparison + +| Criterion | Option A (Combined) | Option B (Separate) | +|---|---|---| +| Coherence | High — same domain | Low — artificial split | +| PR overhead | 1 PR | 2 PRs | +| Risk | Low | Low | +| Ship turnaround | Fast | Slower | +| Unblock value | Immediate | Delayed | + +## Decision + +**Option A: Combined chore.** Ship both fixes as a single "Backlogit +Infrastructure Hygiene" chore with two tasks. The scope is tight, the blast +radius is config-only, and both changes serve the same operational goal: +make backlogit tooling work cleanly without workarounds. + +## Rejected Alternatives + +Option B rejected: no benefit to splitting two small, tightly related config +changes into separate release units. + +## Unresolved Questions + +* The config.yaml change for type-discriminated task naming depends on whether + the current backlogit version supports format tokens like `{parent_NNN}C` or + whether a simpler approach (separate counter per type) is needed. The impl-plan + must investigate this. +* Whether `.backlogit/backlogit.db` needs `git rm --cached` to stop tracking it + (likely yes, since it currently shows as modified). + +## Risks and Mitigations + +| Risk | Mitigation | +|---|---| +| Config change breaks existing task ID parsing | Validate with `backlogit doctor` after change | +| Gitignore change loses stash.jsonl tracking | Explicitly verify stash.jsonl is NOT matched by the new rule | +| Existing archived items with old IDs become orphaned | No impact — archived items retain their IDs; only new chore tasks get new format | diff --git a/docs/memory/2026-05-24/stage-005-s-assembly-memory.md b/docs/memory/2026-05-24/stage-005-s-assembly-memory.md new file mode 100644 index 0000000..c7ee2e8 --- /dev/null +++ b/docs/memory/2026-05-24/stage-005-s-assembly-memory.md @@ -0,0 +1,47 @@ +--- +type: session-memory +agent: stage +date: 2026-05-24 +session: stage-005-s-assembly +status: complete +--- + +## Session Summary + +Staged shipment `005-S` from stash entry `E1B44C77` + operator gitignore instruction. + +## Artifacts Created + +| Type | Path | +|---|---| +| Deliberation | `docs/decisions/2026-05-24-backlogit-infra-hygiene-deliberation.md` | +| Plan | `docs/plans/2026-05-24-backlogit-infra-hygiene-plan.md` | +| Chore | `.backlogit/queue/003-C.md` | +| Task 1 | `.backlogit/queue/003.001-T.md` | +| Task 2 | `.backlogit/queue/003.002-T.md` | +| Shipment | `.backlogit/queue/005-S.md` | + +## Stash Entries Consumed + +- `E1B44C77` → harvested to `003-C` + +## Deferred Entries (26 remaining) + +All other stash entries remain active. Medium-priority candidates for next session: +- `DDF819E0` (manifest command), `7B611B73` (MCP tools), `C7AA4D4B` (join command) +- `B821FFFD`, `3AF98027`, `C60FFBA9` (medium tasks — potential grouped batch) + +## Decisions + +- Combined gitignore + ID collision into single chore (tight domain coherence) +- Plan review: PASS with no blocking findings +- Execution order: gitignore first (003.001-T), then config fix (003.002-T) + +## Ship Pre-Conditions + +1. Dirty working tree needs cleanup before Ship claims 005-S +2. Any local-only 004-S closure memory artifact should stay out of this + shipment PR; it belongs to the prior 004-S closure and should not block or + contaminate this chore +3. `.backlogit/stash.jsonl` changes should be committed (legitimate tracked state) +4. backlogit doctor validation required after 003.002-T diff --git a/docs/plans/2026-05-24-backlogit-infra-hygiene-plan.md b/docs/plans/2026-05-24-backlogit-infra-hygiene-plan.md new file mode 100644 index 0000000..a01b095 --- /dev/null +++ b/docs/plans/2026-05-24-backlogit-infra-hygiene-plan.md @@ -0,0 +1,213 @@ +--- +title: "Backlogit Infrastructure Hygiene — Implementation Plan" +type: impl-plan +date: 2026-05-24 +source: "docs/decisions/2026-05-24-backlogit-infra-hygiene-deliberation.md" +parent_decision: "docs/decisions/2026-05-23-backlog-id-collision.md" +stash_ids: + - "E1B44C77" +status: reviewed +--- + +## Problem Frame + +Two config-level issues in backlogit tooling infrastructure require fixes: + +1. **ID namespace collision**: `config.yaml` assigns all level-1 types from a shared + `{NNN}` counter. Chore tasks inherit the parent's `{NNN}`, colliding with feature + tasks when counter values match. File: `.backlogit/config.yaml`, which is the + backlogit artifact-type config; `.backlogit/config.yml` is a generated + autoharness metadata file and does not define `artifact_types.*.name_format`. + +2. **Untracked DB file pollution**: `.backlogit/backlogit.db` is a disposable SQLite + cache managed by the backlogit tool. It should not be tracked in git. It currently + shows as modified in `git status`, creating noise. File: `.gitignore`. + +Neither change touches Rust source code. Both are config/repo-hygiene only. + +## Requirements Trace + +| Requirement | Implementation Unit | +|---|---| +| Chore tasks get collision-free IDs | Unit 1: Config change | +| backlogit DB files are gitignored | Unit 2: Gitignore + untrack | +| stash.jsonl remains tracked | Unit 2: Verify exclusion | +| Existing archived items unaffected | Unit 1: Validate with doctor | + +## Implementation Units + +### Unit 1: Fix chore task ID namespace in config.yaml + +**What**: Modify `.backlogit/config.yaml` to give the `chore` artifact type a +type-discriminated task naming format that avoids collisions with feature task IDs. +Target `.backlogit/config.yaml` because it is the file that defines +`artifact_types.chore.name_format`; `.backlogit/config.yml` only carries generated +prefix/status metadata. + +**Approach**: Change the chore `name_format` from `'{NNN}{suffix}'` to +`'{NNN}C{suffix}'` so newly created chores get IDs like `003C-C` and newly +created child tasks become `003C.001-T` instead of `003.001-T`. This staged +shipment already contains queue artifacts created under the old format +(`003-C`, `003.001-T`, `003.002-T`); this PR does not rename or migrate those +existing IDs. This is the simplest change that breaks the collision for future +items without requiring backlogit code changes — the `{NNN}` token already +supports alphanumeric suffixes in the format string. + +If backlogit's ID parser rejects the `C` infix (validation step), fall back to +using a higher counter offset or a separate `chore_counter_start` field if +supported. The Ship agent should validate by running `backlogit doctor` after the +config change. + +**Files affected**: +- `.backlogit/config.yaml` (1 line change in chore section) + +**Tests/Verification**: +- Confirm the target file with `backlogit_get_metadata_catalog` or direct config + inspection: `.backlogit/config.yaml` contains `artifact_types.chore.name_format`, + while `.backlogit/config.yml` does not +- Run `backlogit doctor` to confirm no parse errors +- Create a test chore item and verify its ID does not collide with existing feature IDs +- Verify existing queue and archive items remain accessible + +**Execution posture**: Migration-first (config change, then validate) + +**Acceptance criteria**: +- `backlogit doctor` reports no errors after config change +- New chore items created after the config change get IDs like `003C-C` + (type-discriminated) +- Existing items (`001-F`, `002-F`, archived tasks) remain queryable + +--- + +### Unit 2: Gitignore backlogit DB files and untrack the cached database + +**What**: Add a gitignore rule for backlogit database files and remove +`.backlogit/backlogit.db` from git tracking. Ensure `.backlogit/stash.jsonl` +remains tracked. + +**Approach**: +1. Add rule `.backlogit/*.db` to `.gitignore` (under a new `# backlogit` section) +2. Run `git rm --cached .backlogit/backlogit.db` to stop tracking the file +3. Verify `.backlogit/stash.jsonl` is NOT matched by the new rule +4. Commit both changes together + +**Files affected**: +- `.gitignore` (add 3 lines: comment + rule + blank line) +- `.backlogit/backlogit.db` (untrack only — file remains on disk) + +**Tests/Verification**: +- `git status` no longer shows `.backlogit/backlogit.db` as modified +- `git ls-files .backlogit/stash.jsonl` still shows the file as tracked +- `backlogit sync` still works (the DB is regenerated from markdown files) + +**Execution posture**: Config change (no test harness needed — repo metadata only) + +**Acceptance criteria**: +- `.backlogit/backlogit.db` does not appear in `git status` after commit +- `.backlogit/stash.jsonl` remains tracked (`git ls-files` confirms) +- `backlogit sync` succeeds on a fresh clone (DB is ephemeral cache) + +## Dependency Graph + +```text +Unit 1 (config.yaml) ──┐ + ├──► Ship PR (single branch, single commit set) +Unit 2 (gitignore) ──┘ +``` + +Units are independent — no ordering dependency between them. Both can be +implemented in any order or in a single commit sequence. Unit 2 is slightly +lower risk and can serve as a confidence-building first commit. + +Suggested execution order: Unit 2 first (gitignore), then Unit 1 (config). + +## Decisions and Rationale + +| Decision | Rationale | +|---|---| +| Use `{NNN}C{suffix}` format for chores | Simplest discriminator; no backlogit code change needed if format tokens accept literal chars | +| Gitignore `*.db` pattern under `.backlogit/` | Covers any future DB files; more robust than targeting a single filename | +| `git rm --cached` for untracking | Preserves the local file while removing from index — standard git workflow | +| Keep stash.jsonl tracked | Operator instruction; stash is legitimate state, not cache | + +## Risks and Caveats + +| Risk | Likelihood | Impact | Mitigation | +|---|---|---|---| +| Backlogit rejects `{NNN}C{suffix}` format token | Low | Blocks Unit 1 | Validate immediately; if rejected, use `prefix: C` approach or separate counter | +| `git rm --cached` on a shared branch causes confusion | Very low | Low | Document in commit message; file stays on disk | +| Future backlogit upgrade changes config schema | Low | Low | Pin to documented schema version | + +## Plan Hardening Signals + +* public API, schema, or contract change — **Absent** (internal tooling config only) +* security, auth, permission, or compliance-sensitive behavior — **Absent** +* migration, backfill, destructive data/config action, or irreversible step — **Present** + (`git rm --cached` is a destructive git-index action, even though it is reversible via `git add`) +* external integration, operator checkpoint, or external dependency — **Present** + (Unit 2 requires an explicit operator checkpoint before `git rm --cached`) +* high runtime, rollout, or rollback risk — **Absent** (config-only, no production code) + +Requires plan hardening: yes + +## Runtime Verification and Closure + +Neither unit changes a runtime surface (no CLI behavior, no API, no production code). + +Verification is limited to: +- `backlogit doctor` passes after config change (Unit 1) +- `git status` is clean after gitignore change (Unit 2) +- CI passes (fmt, clippy, test, build are unaffected by config changes) + +No monitoring plan, rollback trigger, or observation window is required — this +is pure repository metadata hygiene with no runtime impact. + +## Constitution Check + +| Principle | Compliance | +|---|---| +| I. Safety-First Rust | N/A — no Rust code changes | +| II. Test-First Development | N/A — no production code; validation via `backlogit doctor` | +| III. Workspace Isolation | Compliant — all changes within workspace | +| IV. CLI Containment | Compliant | +| VII. Destructive Command Approval | Compliant — Unit 2 requires an explicit operator approval/checkpoint before `git rm --cached` | +| IX. Git-Friendly Persistence | Compliant — YAML config, gitignore are mergeable text | +| XI. Merge Commit History | Ship will use merge commit | + +## Plan Hardening + +Hardening is required because Unit 2 contains a destructive git-index action (`git rm --cached .backlogit/backlogit.db`) that alters VCS history and is therefore subject to Constitution Principle VII (Destructive Command Approval). + +**Risky action**: `git rm --cached .backlogit/backlogit.db` + +**Risk classification**: `destructive` — modifies the git index on a shared branch; the file is removed from tracking even though it remains on disk. + +**Approval required**: Yes — operator must explicitly confirm before the Ship agent executes this command. + +**Rollback**: `git add .backlogit/backlogit.db` restores tracking; the file is never deleted from disk. + +**Operator checkpoint**: Ship agent MUST pause before Unit 2 execution and obtain explicit operator approval. The `.gitignore` change (Unit 2, step 1) may be applied first without approval; only the `git rm --cached` step requires the checkpoint. + +**Execution detail added**: Unit 2 step sequence clarified — add `.gitignore` rule first, then request approval, then run `git rm --cached`, then commit both changes together. + +## Plan Review + +**Gate decision: PASS** + +**Reviewed by**: Constitution Reviewer, Rust Reviewer, Scope Boundary Auditor, +Learnings Researcher, Architecture Strategist + +**Plan hardening required**: Yes (Unit 2 requires an explicit operator checkpoint before `git rm --cached`) + +### Findings + +| Severity | Finding | Recommendation | +|---|---|---| +| P3 | Unit 1 fallback if backlogit rejects `{NNN}C{suffix}` format | Already documented in Risks section — no action needed | + +### Verdict + +Plan is well-scoped, config-only, and aligned with the existing decision document +and compound learning. No blocking findings. Approved for harvest. + +