changelog_fragment_problem — entries are bounded at 300 characters #169

Merged
claude-bot-andresmgsl merged 1 commit from build/167-fragment-entry-bound into main 2026-07-24 18:54:09 +00:00
claude-bot-andresmgsl commented 2026-07-24 18:26:06 +00:00 (Migrated from github.com)

Closes #167.

One definition of the bound, in changelog_fragment_problem (D2): changelog-armed reds the PR that writes the fragment and bin/changelog-assemble refuses at release, both by inheritance — neither grows a copy. The entry is measured normalized per D1 (continuation lines joined, whitespace collapsed, marker stripped, citation included), so wrapping alone can never red an entry. Doctrine names the number in BUILDER.md's fragment bullet and CHANGELOG.md's header (D5); published sections gain no rule (D4).

Acceptance criteria

  • A fragment with a 301-character entry goes red in changelog-armed, naming the fragment, the length, the bound, and the split fix; an entry of exactly 300 passes.
  • A fragment with several entries each within the bound passes even though the file totals more than 300 characters.
  • A ~250-character entry wrapped over four continuation lines passes — wrapping alone can never red an entry.
  • In a grouped fragment, ### headings count toward no entry and bullets under them are bounded the same.
  • Published sections stay unvalidated: the existing over-bound entries in the 0.2.0/0.3.0 history red nothing on a clean tree.
  • The rule exists in exactly one function; neither the action nor the assembler grows a second copy.
  • BUILDER.md and CHANGELOG.md state the same number the guard enforces.
  • bash test/run.sh green (18 files, 0 failed, under mawk 1.3.4 — the CI awk).

Worklog

  • Add the length rule to changelog_fragment_problem in lib/changelog.sh, mawk-compatible, with the D3 refusal message.
  • State the bound and the split rule in BUILDER.md's fragment bullet and CHANGELOG.md's header prose.
  • Tests in test/changelog.test.sh (10 new cases) and test/changelog-armed.test.sh (action path, 2 cases).
  • changelog.d/167.md, flat — passing its own rule.
  • bash test/run.sh + CI's shellcheck-all.sh green locally.
  • CI green on the PR.
  • Mark ready-for-review, request the panel (codex, grok, kimi).

🤖 Generated with Claude Code

Closes #167. One definition of the bound, in `changelog_fragment_problem` (D2): `changelog-armed` reds the PR that writes the fragment and `bin/changelog-assemble` refuses at release, both by inheritance — neither grows a copy. The entry is measured normalized per D1 (continuation lines joined, whitespace collapsed, marker stripped, citation included), so wrapping alone can never red an entry. Doctrine names the number in BUILDER.md's fragment bullet and CHANGELOG.md's header (D5); published sections gain no rule (D4). ## Acceptance criteria - [x] A fragment with a 301-character entry goes red in `changelog-armed`, naming the fragment, the length, the bound, and the split fix; an entry of exactly 300 passes. - [x] A fragment with several entries each within the bound passes even though the file totals more than 300 characters. - [x] A ~250-character entry wrapped over four continuation lines passes — wrapping alone can never red an entry. - [x] In a grouped fragment, `### ` headings count toward no entry and bullets under them are bounded the same. - [x] Published sections stay unvalidated: the existing over-bound entries in the 0.2.0/0.3.0 history red nothing on a clean tree. - [x] The rule exists in exactly one function; neither the action nor the assembler grows a second copy. - [x] BUILDER.md and CHANGELOG.md state the same number the guard enforces. - [x] `bash test/run.sh` green (18 files, 0 failed, under mawk 1.3.4 — the CI awk). ## Worklog - [x] Add the length rule to `changelog_fragment_problem` in `lib/changelog.sh`, mawk-compatible, with the D3 refusal message. - [x] State the bound and the split rule in BUILDER.md's fragment bullet and CHANGELOG.md's header prose. - [x] Tests in `test/changelog.test.sh` (10 new cases) and `test/changelog-armed.test.sh` (action path, 2 cases). - [x] `changelog.d/167.md`, flat — passing its own rule. - [x] `bash test/run.sh` + CI's `shellcheck-all.sh` green locally. - [x] CI green on the PR. - [x] Mark ready-for-review, request the panel (codex, grok, kimi). 🤖 Generated with [Claude Code](https://claude.com/claude-code)
danmt (Migrated from github.com) reviewed 2026-07-24 18:26:06 +00:00
codex-bot-andresmgsl commented 2026-07-24 18:30:45 +00:00 (Migrated from github.com)

🔎 reviewing head 6c746364af

🔎 reviewing head 6c746364af173ec517e96924ea3752391c3dfe0e
grok-bot-andresmgsl commented 2026-07-24 18:30:46 +00:00 (Migrated from github.com)

🔎 reviewing head 6c746364af

🔎 reviewing head 6c746364af173ec517e96924ea3752391c3dfe0e
codex-bot-andresmgsl (Migrated from github.com) approved these changes 2026-07-24 18:32:21 +00:00
codex-bot-andresmgsl (Migrated from github.com) left a comment

All acceptance criteria are satisfied at 6c746364af173ec517e96924ea3752391c3dfe0e. The 300-character limit is defined only in changelog_fragment_problem, measures normalized entry text without the bullet marker, preserves wrapping semantics, applies equally to flat and grouped fragments, and is inherited by both the PR-time armed guard and release-time assembler without extending validation to published sections. The refusal includes the fragment, measured length, bound, entry prefix, and split remedy, and both doctrine locations state the enforced bound and remedy.

Verified locally: bash test/run.sh (18 files, 0 failed), bash .github/scripts/shellcheck-all.sh (39 tracked scripts), and bash .github/scripts/actionlint-all.sh (6 files) all pass. GitHub's test, action-exercise, release-exercise, docs-sync-exercise, and self-guards checks are green for this head.

All acceptance criteria are satisfied at `6c746364af173ec517e96924ea3752391c3dfe0e`. The 300-character limit is defined only in `changelog_fragment_problem`, measures normalized entry text without the bullet marker, preserves wrapping semantics, applies equally to flat and grouped fragments, and is inherited by both the PR-time armed guard and release-time assembler without extending validation to published sections. The refusal includes the fragment, measured length, bound, entry prefix, and split remedy, and both doctrine locations state the enforced bound and remedy. Verified locally: `bash test/run.sh` (18 files, 0 failed), `bash .github/scripts/shellcheck-all.sh` (39 tracked scripts), and `bash .github/scripts/actionlint-all.sh` (6 files) all pass. GitHub's test, action-exercise, release-exercise, docs-sync-exercise, and self-guards checks are green for this head.
grok-bot-andresmgsl (Migrated from github.com) approved these changes 2026-07-24 18:32:32 +00:00
grok-bot-andresmgsl (Migrated from github.com) left a comment

Verdict: approve

Head 6c746364af173ec517e96924ea3752391c3dfe0e against issue #167.

Acceptance criteria

Criterion Result
301 reds in changelog-armed with fragment, length, bound, split fix; 300 passes Met — unit + armed tests; message matches D3
Several within-bound entries pass though file totals >300 Met
~250-char entry over four continuation lines passes Met — join + whitespace collapse
Grouped ### headings count toward no entry; bullets bounded the same Met
Published sections unvalidated (0.2.0 / 0.3.0 over-bound history quiet) Met — only changelog_fragment_problem; changelog_section_problem unchanged
Rule in exactly one function; action and assembler inherit Met — sole definition in lib/changelog.sh; changelog-armed.sh:93 and bin/changelog-assemble:71 call it; no second copy
BUILDER.md and CHANGELOG.md state 300 and the split rule Met
bash test/run.sh green Met

Doctrine and the guard enforce the same number; fragment changelog.d/167.md itself is within the bound (normalized entries ~186 / ~133).

What I ran

  • Detached worktree at the head (main clone untouched).
  • bash test/run.sh — 18 files, 0 failed (mawk 1.3.4, same family as CI).
  • bash .github/scripts/shellcheck-all.sh — clean.
  • Manual probes: citation included in the measure, star bullets, whitespace-run collapse at 300/301, multi-heading grouped fragment.
  • CI on the PR: test, self-guards, release-exercise jobs green.

Spec / code notes (non-blocking)

Normalization matches D1 (join continuations, collapse whitespace, strip marker, keep citation). Bound is exclusive (len > max), so exactly 300 passes. Refusal names fragment, length, ~60-char preview, bound, and split fix. No request-changes.

No gaps I could not verify; environment had mawk + shellcheck.

## Verdict: approve Head `6c746364af173ec517e96924ea3752391c3dfe0e` against issue #167. ### Acceptance criteria | Criterion | Result | |---|---| | 301 reds in `changelog-armed` with fragment, length, bound, split fix; 300 passes | Met — unit + armed tests; message matches D3 | | Several within-bound entries pass though file totals >300 | Met | | ~250-char entry over four continuation lines passes | Met — join + whitespace collapse | | Grouped `### ` headings count toward no entry; bullets bounded the same | Met | | Published sections unvalidated (0.2.0 / 0.3.0 over-bound history quiet) | Met — only `changelog_fragment_problem`; `changelog_section_problem` unchanged | | Rule in exactly one function; action and assembler inherit | Met — sole definition in `lib/changelog.sh`; `changelog-armed.sh:93` and `bin/changelog-assemble:71` call it; no second copy | | BUILDER.md and CHANGELOG.md state 300 and the split rule | Met | | `bash test/run.sh` green | Met | Doctrine and the guard enforce the same number; fragment `changelog.d/167.md` itself is within the bound (normalized entries ~186 / ~133). ### What I ran - Detached worktree at the head (main clone untouched). - `bash test/run.sh` — 18 files, 0 failed (mawk 1.3.4, same family as CI). - `bash .github/scripts/shellcheck-all.sh` — clean. - Manual probes: citation included in the measure, star bullets, whitespace-run collapse at 300/301, multi-heading grouped fragment. - CI on the PR: `test`, `self-guards`, release-exercise jobs green. ### Spec / code notes (non-blocking) Normalization matches D1 (join continuations, collapse whitespace, strip marker, keep citation). Bound is exclusive (`len > max`), so exactly 300 passes. Refusal names fragment, length, ~60-char preview, bound, and split fix. No request-changes. No gaps I could not verify; environment had mawk + shellcheck.
kimi-bot-andresmgsl commented 2026-07-24 18:36:06 +00:00 (Migrated from github.com)

🔎 reviewing head 6c746364af

🔎 reviewing head 6c746364af173ec517e96924ea3752391c3dfe0e
kimi-bot-andresmgsl (Migrated from github.com) approved these changes 2026-07-24 18:39:30 +00:00
kimi-bot-andresmgsl (Migrated from github.com) left a comment

Approve head 6c746364af against #167.

Verified in a detached worktree at the head, under mawk 1.3.4 (the CI awk):

  • Bound behavior (AC1–AC4): ran the 10 new cases in test/changelog.test.sh — 301 red / 300 pass at the boundary, several within-bound entries pass with a >300-char file, a ~250-char entry wrapped over continuation lines passes, ### headings count toward no entry, and grouped bullets are bounded the same. test/changelog.test.sh: 65 passed, 0 failed. The two new action-path cases in test/changelog-armed.test.sh also pass — the refusal names the fragment, the measured length, the 300 bound, and the split fix (D3 message shape confirmed in the output).
  • One definition (AC6): max=300 exists only in changelog_fragment_problem (lib/changelog.sh:161); actions/changelog-armed/changelog-armed.sh and bin/changelog-assemble are untouched and inherit by call — no second copy.
  • Forward-only (AC5): changelog_section_problem gains no length rule; the tests pin that 0.2.0/0.3.0's over-bound history reds nothing.
  • Doctrine (AC7): BUILDER.md's fragment bullet and CHANGELOG.md's header both state 300 and the split rule, matching the guard. The PR's own fragment changelog.d/167.md passes the new rule (ran changelog_fragment_problem on it directly).
  • Normalization matches D1: the awk joins continuation lines, collapses whitespace runs, strips the - /* marker, and keeps the (#N) citation before measuring — read and traced by hand.

Test-suite caveat: bash test/run.sh shows 63 FAILs on this box, but the run on base origin/main (9008e03) in a second worktree fails identically — all pre-existing environment gaps (no node/npm for the package-json backend cases, which also fail on base), none introduced by this PR. Every file this PR touches is green except the node-dependent package-json cases that red on base too.

Could not verify locally: shellcheck/actionlint — neither is installed on this box; relying on CI for that gate. The new awk uses only mawk-safe constructs (no \x escapes, no gawkisms) by inspection.

Non-blocking nit: the awk accepts the * marker per D1, but no test constructs a *-bulleted over-bound entry — worth one case at the builder's discretion.

**Approve** head 6c746364af173ec517e96924ea3752391c3dfe0e against #167. Verified in a detached worktree at the head, under mawk 1.3.4 (the CI awk): - **Bound behavior (AC1–AC4):** ran the 10 new cases in `test/changelog.test.sh` — 301 red / 300 pass at the boundary, several within-bound entries pass with a >300-char file, a ~250-char entry wrapped over continuation lines passes, `### ` headings count toward no entry, and grouped bullets are bounded the same. `test/changelog.test.sh`: 65 passed, 0 failed. The two new action-path cases in `test/changelog-armed.test.sh` also pass — the refusal names the fragment, the measured length, the 300 bound, and the split fix (D3 message shape confirmed in the output). - **One definition (AC6):** `max=300` exists only in `changelog_fragment_problem` (lib/changelog.sh:161); `actions/changelog-armed/changelog-armed.sh` and `bin/changelog-assemble` are untouched and inherit by call — no second copy. - **Forward-only (AC5):** `changelog_section_problem` gains no length rule; the tests pin that 0.2.0/0.3.0's over-bound history reds nothing. - **Doctrine (AC7):** BUILDER.md's fragment bullet and CHANGELOG.md's header both state 300 and the split rule, matching the guard. The PR's own fragment `changelog.d/167.md` passes the new rule (ran `changelog_fragment_problem` on it directly). - **Normalization matches D1:** the awk joins continuation lines, collapses whitespace runs, strips the `- `/`* ` marker, and keeps the `(#N)` citation before measuring — read and traced by hand. **Test-suite caveat:** `bash test/run.sh` shows 63 FAILs on this box, but the run on base `origin/main` (9008e03) in a second worktree fails identically — all pre-existing environment gaps (no node/npm for the package-json backend cases, which also fail on base), none introduced by this PR. Every file this PR touches is green except the node-dependent package-json cases that red on base too. **Could not verify locally:** shellcheck/actionlint — neither is installed on this box; relying on CI for that gate. The new awk uses only mawk-safe constructs (no `\x` escapes, no gawkisms) by inspection. Non-blocking nit: the awk accepts the `* ` marker per D1, but no test constructs a `*`-bulleted over-bound entry — worth one case at the builder's discretion.
claude-bot-andresmgsl commented 2026-07-24 18:45:02 +00:00 (Migrated from github.com)

Round summary — converged, handing off

What shipped. changelog_fragment_problem (lib/changelog.sh) now bounds each fragment entry at 300 characters, in exactly one function. The entry is measured normalized per D1 — continuation lines joined, whitespace collapsed, bullet marker stripped, citation included — so wrapping alone can never red an entry. changelog-armed reds the offending PR and bin/changelog-assemble refuses at release, both by inheritance; neither grew a copy. In grouped fragments, ### headings count toward no entry and bullets under them are bounded the same. Doctrine names the number in BUILDER.md's fragment bullet and CHANGELOG.md's header (D5); published sections gain no rule (D4). Tests: 10 new cases in test/changelog.test.sh (including the 300/301 boundary pair and the wrapped ~250-char entry), 2 action-path cases in test/changelog-armed.test.sh. changelog.d/167.md rides along, flat, passing its own rule.

Rounds. One. Head 6c74636 is the first and only head; the panel (codex, grok, kimi) approved it unanimously with no changes requested — no addressing rounds.

Verified. bash test/run.sh green locally (18 files, 0 failed, under mawk 1.3.4 — the CI awk) and shellcheck-all.sh clean. CI green on the PR: all required checks pass. Three head-current approvals, no blocker:*, merges clean.

Post-merge residue. None owed. The over-bound entries in the published 0.2.0/0.3.0 history stay as they are by design (D4) — they red nothing on a clean tree. changelog.d/167.md is consumed at the next release by the assembler, which now enforces the same bound on the way in. No cross-repo follow-up.

Requesting @danmt's review and setting state:needs-human — the PR is yours.

## Round summary — converged, handing off **What shipped.** `changelog_fragment_problem` (`lib/changelog.sh`) now bounds each fragment entry at 300 characters, in exactly one function. The entry is measured normalized per D1 — continuation lines joined, whitespace collapsed, bullet marker stripped, citation included — so wrapping alone can never red an entry. `changelog-armed` reds the offending PR and `bin/changelog-assemble` refuses at release, both by inheritance; neither grew a copy. In grouped fragments, `### ` headings count toward no entry and bullets under them are bounded the same. Doctrine names the number in BUILDER.md's fragment bullet and CHANGELOG.md's header (D5); published sections gain no rule (D4). Tests: 10 new cases in `test/changelog.test.sh` (including the 300/301 boundary pair and the wrapped ~250-char entry), 2 action-path cases in `test/changelog-armed.test.sh`. `changelog.d/167.md` rides along, flat, passing its own rule. **Rounds.** One. Head `6c74636` is the first and only head; the panel (codex, grok, kimi) approved it unanimously with no changes requested — no addressing rounds. **Verified.** `bash test/run.sh` green locally (18 files, 0 failed, under mawk 1.3.4 — the CI awk) and `shellcheck-all.sh` clean. CI green on the PR: all required checks pass. Three head-current approvals, no `blocker:*`, merges clean. **Post-merge residue.** None owed. The over-bound entries in the published 0.2.0/0.3.0 history stay as they are by design (D4) — they red nothing on a clean tree. `changelog.d/167.md` is consumed at the next release by the assembler, which now enforces the same bound on the way in. No cross-repo follow-up. Requesting @danmt's review and setting `state:needs-human` — the PR is yours.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: heavy-duty/ceremony#169
No description provided.