Skip to content

feat: Add idea fmt — Explicit Canonicalizer with Automatic Checkbox Adoption#18

Merged
sahil-noon merged 5 commits into
mainfrom
260612-4m3a-add-fmt-canonicalizer-adoption
Jun 12, 2026
Merged

feat: Add idea fmt — Explicit Canonicalizer with Automatic Checkbox Adoption#18
sahil-noon merged 5 commits into
mainfrom
260612-4m3a-add-fmt-canonicalizer-adoption

Conversation

@sahil-noon

Copy link
Copy Markdown
Collaborator

Meta

ID Type Confidence Plan Review
4m3a feat 5.0/5.0 10/10 tasks, 19/19 acceptance ✓ ✓ 1 cycle

Pipeline: intake ✓ → apply ✓ → review ✓ → hydrate ✓ → ship → review-pr

Impact: +896/−10 code (excluding fab/, docs/) · +1386/−22 total

Summary

Canonicalization previously happened only as a side-effect of the first mutating command, so a single idea done on a legacy backlog mixed formatting churn into the semantic diff — and bare - [ ] checkbox lines without an [id] anchor were invisible to idea, with no path to adopt an existing markdown task list. This adds idea fmt, a gofmt-style explicit canonicalizer built as a thin verb over the existing parse/format/save machinery: it rewrites the backlog to canonical form, automatically adopts bare checkboxes with fresh 4-char IDs, and ships a --check mode that serves as both dry-run preview and CI gate.

Changes

  • New subcommand: idea fmt (src/cmd/idea/fmt.go)
  • Canonicalization — explicit trigger over the existing writer
  • Automatic adoption of bare checkboxes
  • --check mode — unified preview + CI gate
  • Output contract: silent stdout, advisory stderr
  • File resolution & command surface (--file/--main/IDEAS_FILE inherited)
  • Spec updates (contract change in backlog-format.md and overview.md)

🤖 Generated with Claude Code

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces an explicit, gofmt-style canonicalization command (idea fmt) to rewrite the backlog into canonical form on demand, including automatic adoption of “bare” markdown checkbox tasks into managed idea entries, with a --check mode suitable for CI gating.

Changes:

  • Adds idea fmt CLI subcommand with --check (no-write, exit-1-if-non-canonical) behavior and stderr-only reporting.
  • Refactors internal parsing/serialization to expose a shared parseContent and render seam, and implements adoption + canonicalization in internal/idea.Fmt.
  • Adds comprehensive unit + e2e tests and updates specs/memory docs to document the new contract.

Reviewed changes

Copilot reviewed 15 out of 15 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
src/internal/idea/idea.go Refactors file parsing (parseContent) and serialization (render) to support fmt/check without duplicating the write path.
src/internal/idea/fmt.go Implements canonicalization + bare-checkbox adoption + --check/skip-write behavior via Fmt.
src/internal/idea/fmt_test.go Adds unit coverage for canonicalization, adoption guards, idempotency, and check mode.
src/cmd/idea/main.go Registers the new fmt subcommand in the root command.
src/cmd/idea/help_dump_test.go Ensures help-dump includes the new fmt node.
src/cmd/idea/fmt.go Adds the idea fmt cobra command wiring and stderr reporting contract.
src/cmd/idea/fmt_test.go Adds end-to-end tests for routing, output channels, idempotency, and --check behavior.
docs/specs/overview.md Documents idea fmt in the command table and behavior overview.
docs/specs/backlog-format.md Specifies the explicit canonicalizer, adoption rules, and the preservation carve-out.
docs/memory/cli/structure.md Updates CLI structure “memory” documentation to include fmt and the new seams.
docs/memory/cli/index.md Updates the CLI memory index row(s) for the structure page.
fab/changes/260612-4m3a-add-fmt-canonicalizer-adoption/plan.md Adds the generated plan/acceptance record for the change.
fab/changes/260612-4m3a-add-fmt-canonicalizer-adoption/intake.md Adds the generated intake/background for the change.
fab/changes/260612-4m3a-add-fmt-canonicalizer-adoption/.status.yaml Adds the generated status/progress metadata for the change.
fab/changes/260612-4m3a-add-fmt-canonicalizer-adoption/.history.jsonl Adds the generated history/event log for the change.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/internal/idea/fmt.go
Comment on lines +60 to +63
// Count what canonicalization will touch among the pre-existing managed
// lines, comparing each regenerated line against its raw on-disk text.
today := time.Now().Format("2006-01-02")
for i, lineIdx := range f.ideaIndices {

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed — render now takes today as a parameter; SaveFile and Fmt each pass a single value, so one fmt run stamps one consistent date across counting, adoption, and the written bytes. (68dd1ed)

Comment thread src/cmd/idea/fmt.go Outdated
Comment on lines +23 to +24
preserved. Lines whose text starts with a bracket (e.g. "- [ ] [DEV-1011] ...")
and all other non-idea content are preserved byte-for-byte. A second run is

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed — help text now says non-idea content keeps its text verbatim while line endings canonicalize file-wide (CRLF becomes LF, single trailing LF). (68dd1ed)

Comment thread docs/memory/cli/index.md Outdated
Comment thread docs/specs/backlog-format.md Outdated
- [ ] [DEV-1011] external item ← untouched (bracket guard)
```

The bracket guard keeps inert, byte-for-byte: Shape B lines (the `[issue_ids]` slot — see the next section) and bracket-metadata lines such as `- [ ] [TODO] buy milk` or `- [ ] [ab1] text` — external-looking metadata errs toward preservation. Text-less and whitespace-only checkboxes (`- [ ]` with no text) are not adopted. Headers, prose, and blank lines pass through verbatim as always.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed — reworded to text-verbatim preservation with the LF-canonicalization caveat (byte-identical round-trip holds for LF files); also precision-fixed the same claim in the Shape B section for consistency. (68dd1ed)

Comment thread docs/specs/backlog-format.md Outdated

> **Format-contract change note.** Earlier versions of this spec declared the date a mandatory part of the line and described an idea-managed "Shape A" that *required* the date. As of the resilient-parser change (`260610-wtmn-resilient-backlog-parser`), the date is **optional on input** and **canonical (always present) on output**, and `idea` additionally accepts `*`/`+` bullets, leading whitespace, and CRLF endings on input. This widens the input contract and was a deliberate, documented change to fix silent-failure on dateless backlogs (e.g. the shll.ai backlog). The **output** contract is unchanged: `idea` still emits exactly one canonical, machine-parseable form. Shape B second-bracket lines remain inert pass-through, exactly as before.

> **Format-contract change note.** As of the fmt change (`260612-4m3a-add-fmt-canonicalizer-adoption`), adoption **widens which lines `idea` may rewrite**: bare checkbox lines without the 4-char `[id]` anchor were previously guaranteed non-idea pass-through; `idea fmt` (and only `fmt`) now adopts them as managed canonical idea lines (fresh ID, today's date, checked state preserved). No other command's rewrite scope changed, the canonical output form is unchanged, and Shape B second-bracket lines remain inert byte-for-byte pass-through, exactly as before.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed — the change note now states text-untouched pass-through with canonical LF endings on rewrite (only LF files round-trip byte-identically). (68dd1ed)

@sahil87 sahil87 force-pushed the 260612-4m3a-add-fmt-canonicalizer-adoption branch from a46affe to d0be374 Compare June 12, 2026 08:24
@sahil-noon sahil-noon marked this pull request as ready for review June 12, 2026 09:46
@sahil-noon sahil-noon merged commit 9afc01d into main Jun 12, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants