Skip to content

feat: bound STATUS.md history with status_history_keep keep-last-N prune - #26

Merged
moui72 merged 7 commits into
mainfrom
feat/status-md-trim-prune
Jul 25, 2026
Merged

feat: bound STATUS.md history with status_history_keep keep-last-N prune#26
moui72 merged 7 commits into
mainfrom
feat/status-md-trim-prune

Conversation

@moui72

@moui72 moui72 commented Jul 24, 2026

Copy link
Copy Markdown
Owner

Gives /ardd-status a deterministic, opt-in keep-last-N prune of STATUS.md's _Updated: chronology, so the live file stays slim in long-running projects. Recent blocks stay verbatim; older history stays recoverable from git.

Vetted first in .project/plans/research-status-md-trim-prune-history-2026-07-24-e8a4.md (the key insight: STATUS.md is git-committed, so "durable re-entry chronology" never required unbounded file length — git backs it).

What changed

  • scripts/status-prune.sh <file> --keep <N> — POSIX tail-cut: preserves head matter + newest N _Updated: blocks byte-for-byte, drops the older tail, refuses (never corrupts) on a missing file or non-positive N. Never summarizes — the only edit it makes is removing whole older blocks. + scripts/test-status-prune.sh + a CI job.
  • New constitution workflow field status_history_keep: <N> (absent = unbounded, so existing installs are unchanged): validated by lint-project.sh (+ good/bad fixtures), accepted by ardd-state.sh stamp, asked by /ardd-init, backfilled/re-asked by /ardd-update.
  • Wired into /ardd-status step 6: runs the prune after each prepend when the field is set. The prepend-and-preserve invariant is narrowed — never-summarize stays absolute; unbounded-retention relaxes to keep-last-N.
  • install.sh ships the script; CLAUDE.md + docs/reference/{configuration,scripts}.md synced.

Design notes

  • The never-summarize half of the invariant is untouched — only unbounded retention is relaxed, and git backstops recoverability.
  • Rejected (per the research): in-place summarization (non-deterministic), a STATUS-archive.md file (redundant with git), age-based caps (fragile for bursty/dormant projects), a separate /ardd-prune skill (breaks single-writer ownership).

All gates green: lint-docs, lint-project, test-status-prune, test-lint-project, test-install-manifest-complete.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features
    • Added status_history_keep to bound .project/STATUS.md by retaining only the newest N _Updated: blocks.
    • Added scripts/status-prune.sh to deterministically prune older history while preserving kept blocks.
    • /ardd-init, /ardd-update, and /ardd-status now support the retention option.
  • Bug Fixes
    • Project validation/lint rejects non-positive or malformed status_history_keep values.
  • Documentation
    • Updated configuration, script, and skill guides to describe retention behavior and validation.
  • Tests
    • Added regression tests for pruning, linting, and stamp/unstamp, plus CI coverage (status-prune job).

@coderabbitai

coderabbitai Bot commented Jul 24, 2026

Copy link
Copy Markdown

Review Change Stack

Walkthrough

Adds an opt-in status_history_keep setting for retaining the newest _Updated: blocks in STATUS.md, a POSIX pruning utility with regression tests and CI coverage, validation and stamping support, workflow guidance, installation changes, and documentation updates.

Changes

STATUS.md history pruning

Layer / File(s) Summary
Feature design and implementation plan
.project/features/*, .project/plans/*, .project/tasks/*
Adds feature, research, plan, and task artifacts defining deterministic keep-last-N pruning while preserving recent blocks verbatim.
Pruning utility and regression coverage
scripts/status-prune.sh, scripts/test-status-prune.sh, .github/workflows/lint.yml
Adds argument and file validation, whole-block tail pruning, result reporting, fixture-based regression cases, and a CI job.
Constitution field validation and stamping
scripts/ardd-state.sh, scripts/lint-project.sh, scripts/test-ardd-state.sh, scripts/test-lint-project.sh, tests/fixtures/*
Adds positive-integer handling, frontmatter removal, and validation for status_history_keep, with accepted and rejected values covered by tests.
Workflow prompts and status behavior
skills/ardd-init/SKILL.md, skills/ardd-update/SKILL.md, skills/ardd-status/SKILL.md, CLAUDE.md
Adds configuration prompts and backfill behavior, and documents conditional pruning after /ardd-status prepends a new chronology block.
Installation and reference documentation
install.sh, docs/reference/*
Installs status-prune.sh and documents its command, configuration field, output, refusal conditions, and retention semantics.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant ardd-init-update
  participant constitution
  participant ardd-status
  participant status-prune.sh
  participant STATUS.md
  User->>ardd-init-update: choose status_history_keep
  ardd-init-update->>constitution: stamp status_history_keep N
  ardd-status->>STATUS.md: prepend _Updated block
  ardd-status->>status-prune.sh: prune STATUS.md with --keep N
  status-prune.sh->>STATUS.md: retain newest N blocks verbatim
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 25.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly describes the main change: bounding STATUS.md history with status_history_keep and keep-last-N pruning.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/status-md-trim-prune

Comment @coderabbitai help to get the list of available commands.

@moui72
moui72 marked this pull request as ready for review July 24, 2026 21:33
@moui72
moui72 force-pushed the feat/status-md-trim-prune branch from e49983e to 217a4a7 Compare July 25, 2026 02:16
@moui72

moui72 commented Jul 25, 2026

Copy link
Copy Markdown
Owner Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 25, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 9

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/lint.yml:
- Around line 69-73: Update the status-prune job in the workflow to grant only
contents read permission, and configure its actions/checkout step with
persist-credentials disabled before running test-status-prune.sh.

In `@CLAUDE.md`:
- Around line 48-49: Add status_history_keep to the exact frontmatter-field
inventory in CLAUDE.md and to the corresponding ardd-state.sh stamp inventory in
docs/reference/scripts.md, keeping both public lists synchronized.

In `@docs/reference/scripts.md`:
- Around line 107-110: Update the pruning script’s rewrite flow to create a
secure temporary file in the target file’s directory, register cleanup on exit,
and avoid the predictable $file.prune.$$ path. Ensure failures from generating
or writing the pruned content stop processing and report pruned=false; emit
pruned=true only after the temporary file is successfully renamed into place.

In `@scripts/ardd-state.sh`:
- Around line 391-396: Use the same range-safe positive-integer validation
contract as status-prune.sh for status_history_keep, rejecting digit strings
outside the consumer’s supported arithmetic range. Apply this change in
scripts/ardd-state.sh lines 391-396 within the status_history_keep case and
scripts/lint-project.sh lines 206-216, keeping both validators identical so lint
and stamp accept only processable values.

In `@scripts/status-prune.sh`:
- Around line 77-78: Update the STATUS.md rewrite flow around the temporary
variable and the head/mv pipeline to use a collision-resistant temporary file,
register a cleanup trap for it, and explicitly handle failures from file
creation, head, and mv by returning nonzero. Ensure cleanup runs on both success
and failure, and never report success unless the rename completes.

In `@scripts/test-lint-project.sh`:
- Around line 118-127: Update scripts/test-lint-project.sh to create one per-run
temporary directory with mktemp -d, register a cleanup trap, and store all
captured lint outputs there instead of using the predictable /tmp/lint-bad.out
path. Update the assertions around the bad-project output to reference the
run-specific file while preserving existing cleanup behavior.

In `@skills/ardd-update/SKILL.md`:
- Around line 262-265: Update the reconfigure prompt text near the
status_history_keep description to remove the extra closing parenthesis, so it
ends with “leave it unbounded)” while preserving the surrounding wording and
prompt semantics.
- Around line 262-271: Update the reconfigure workflow and its handling of
status_history_keep so choosing “keep the full chronology” removes an existing
status_history_keep field instead of leaving the previous value. Add or use an
unset/removal path alongside ardd-state.sh stamp, while preserving stamping for
positive integer selections and leaving unrelated fields unchanged.
- Around line 232-244: Make invalid status_history_keep values behave
consistently across all configuration paths: in skills/ardd-update/SKILL.md
lines 232-244, validate the value before treating field presence as suppressing
backfill; in skills/ardd-status/SKILL.md lines 319-323, treat invalid values as
absent or use the documented refusal path; and in
docs/reference/configuration.md lines 137-154, document the workflow and pruner
behavior actually implemented.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: b55b4721-89cd-47d5-ac08-c7c08c5beaf7

📥 Commits

Reviewing files that changed from the base of the PR and between cd96e35 and 217a4a7.

📒 Files selected for processing (19)
  • .github/workflows/lint.yml
  • .project/features/status-md-trim-prune-history.md
  • .project/plans/plan-status-md-trim-prune-history-2026-07-24-1038.md
  • .project/plans/research-status-md-trim-prune-history-2026-07-24-e8a4.md
  • .project/tasks/tasks-status-md-trim-prune-history-485d.md
  • CLAUDE.md
  • docs/reference/configuration.md
  • docs/reference/scripts.md
  • install.sh
  • scripts/ardd-state.sh
  • scripts/lint-project.sh
  • scripts/status-prune.sh
  • scripts/test-lint-project.sh
  • scripts/test-status-prune.sh
  • skills/ardd-init/SKILL.md
  • skills/ardd-status/SKILL.md
  • skills/ardd-update/SKILL.md
  • tests/fixtures/bad-project/.project/artifacts/constitution.md
  • tests/fixtures/good-project/.project/artifacts/constitution.md

Comment thread .github/workflows/lint.yml
Comment thread CLAUDE.md
Comment thread docs/reference/scripts.md
Comment thread scripts/ardd-state.sh
Comment thread scripts/status-prune.sh Outdated
Comment thread scripts/test-lint-project.sh
Comment thread skills/ardd-update/SKILL.md
Comment thread skills/ardd-update/SKILL.md Outdated
Comment thread skills/ardd-update/SKILL.md
- status-prune.sh fails closed: mktemp temp file in the target's own
  directory, cleanup trap, explicit nonzero handling on head/mv —
  pruned=true only after the rename lands (reason=write-failed otherwise)
- one range-safe contract across all three validators: status_history_keep
  is a positive integer of at most 4 digits in ardd-state.sh stamp,
  lint-project.sh, and status-prune.sh --keep (shell arithmetic stays safe)
- ardd-state.sh gains 'unstamp <file> <field>' (allowlisted optional
  fields, frontmatter-scoped removal) — the scripted way back to unbounded
  history; ardd-update --reconfigure wires it for status_history_keep
- invalid status_history_keep contract made explicit and consistent:
  ardd-status treats it as absent (skip prune, note in report),
  ardd-update backfill re-asks instead of letting garbage suppress it
- test-lint-project.sh captures output in a per-run mktemp -d dir
- stamp inventory in docs/reference/scripts.md gains status_history_keep
  + unstamp; malformed '))' prompt fixed
- new regression cases: >4-digit keep refusals (status-prune + stamp),
  unstamp removal/no-op/body-line-preserved/non-removable

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

@coderabbitai coderabbitai Bot 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.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
scripts/test-lint-project.sh (1)

123-132: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Add a fixture case for the four-digit maximum.

This only verifies -3. Add a bad-project fixture/assertion for status_history_keep: 10000 so lint’s new upper-bound contract cannot regress.

As per coding guidelines, every deterministic check must have a fixture-based regression test, and new checks must add their CI job and regression test in the same commit.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@scripts/test-lint-project.sh` around lines 123 - 132, Add a bad-project
fixture setting status_history_keep to 10000 and extend the assertions in the
test-lint-project.sh regression checks to require the field name, value, and
allowed-range message for this four-digit upper-bound violation, while
preserving the existing -3 and good-project coverage.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@scripts/test-lint-project.sh`:
- Around line 123-132: Add a bad-project fixture setting status_history_keep to
10000 and extend the assertions in the test-lint-project.sh regression checks to
require the field name, value, and allowed-range message for this four-digit
upper-bound violation, while preserving the existing -3 and good-project
coverage.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: ad48b2b8-c72a-417c-8145-74a8925b733c

📥 Commits

Reviewing files that changed from the base of the PR and between 217a4a7 and 302daf2.

📒 Files selected for processing (10)
  • docs/reference/configuration.md
  • docs/reference/scripts.md
  • scripts/ardd-state.sh
  • scripts/lint-project.sh
  • scripts/status-prune.sh
  • scripts/test-ardd-state.sh
  • scripts/test-lint-project.sh
  • scripts/test-status-prune.sh
  • skills/ardd-status/SKILL.md
  • skills/ardd-update/SKILL.md
🚧 Files skipped from review as they are similar to previous changes (7)
  • scripts/lint-project.sh
  • docs/reference/configuration.md
  • docs/reference/scripts.md
  • skills/ardd-status/SKILL.md
  • skills/ardd-update/SKILL.md
  • scripts/status-prune.sh
  • scripts/test-status-prune.sh

@moui72
moui72 merged commit 541b283 into main Jul 25, 2026
53 checks passed
@moui72
moui72 deleted the feat/status-md-trim-prune branch July 25, 2026 03:46
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.

1 participant