v3.5.9 - the defects that were filed and never read #236
No reviewers
Labels
No labels
already-shipped
bug
documentation
duplicate
enhancement
external-review
good first issue
help wanted
in progress
invalid
needs-decision
proposal
question
security
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference: crenshawdev/cadence-archived#236
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "cadence/v3.5.9"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Ten defects sat in the capture archive unread from 2026-08-05 until the 2026-08-22 triage reproduced every one against the current tree. Filed as #231 and #232, and the theme is one sentence: the release seam and the frontmatter reader both return a clean answer over a case they did not actually handle.
Two phases, five requirement ids, all five traced to a verified phase. /cad-audit PASS on both arms, fourteen of fourteen acceptance criteria covered.
Phase 1 (REL-01, REL-02, REL-03) is the release/changelog seam, the seam v3.5.8 rewrote. Fence-aware heading scans so a '## ' inside a code block stops ending a section, a heading-only release section reporting empty, the trailing link-reference block bounded by what its keys name, a version-less manifest halting the close instead of passing as a benign skip, changelog.state on every emitting envelope, and an unparseable --version refusing by naming the raw argument.
Phase 2 (FRM-01, FRM-02) is the frontmatter reader under plan-overlap. The four value-level grammar codes are scoped to the two list keys the seams read, so a backtick in goal: stops bailing the risk floor on a plan's whole declared file list, while the five structural codes still cross keys on purpose. And a markdown-decorated files: path now reports markdown-decorated-path instead of parsing clean, so two plans that collide on one file route sequential rather than into separate worktrees.
The goal-backward verify pass on phase 2 found the decoration rule covered only the three shapes AC3 named, so an italic path still cleared. Widened to a matched-wrap table and retested; all 597 frontmatter files: entries under .planning were measured first and none opens or closes on a wrap byte.
Closes #231
Closes #232
A PRIMARY .claude-plugin/plugin.json whose verdict is skip/no-version-field returned {"ok":true,"action":"skip"} at exit 0, so milestone.md read the close as successful and the release shipped with a manifest nobody bumped. The seam re-classifies that one verdict as a refusal - ok:false, action:"refuse", reason:"no-version-field", exit 1, nothing written - with its own detail sentence rather than the verdict's benign "leave it untouched". The pure core is unchanged and SIBLING manifests keep skipping: this project's own .claude-plugin/marketplace.json carries no version by design, and a verdict-level refusal would halt its close every cycle. A new test copies both real manifests into a fixture and pins that.`bump --version v` returned {"ok":false,"reason":"no-target-version", "target":""}: the seam stripped the leading v, was left with an empty string, discarded the raw argument and then reported that no version was given. That is false - a version WAS given - and it names nothing the operator can repair. The raw trimmed value is kept when normalization is left with nothing usable, so decideManifestBump reaches its own unparseable-version, whose sentence already quotes the offending value. No verdict code is minted at the seam. normalizeTargetVersion is unchanged: planning.mjs reads it for v-stripping inside the audit's version_drift signal. An ABSENT --version still refuses as no-target-version and a blank one still refuses at its declared arg-contract row as missing-flag-value; a test pins all five spellings.`milestone-prune.test.mjs`'s live-REQUIREMENTS corpus asserted that every moved bullet wraps, so the suite went red the moment a requirement was written on one line - a state of the repository, not a result, and the same mistake the empty-roadmap case above was already fixed for. The wrapped assert now tallies instead, and says out loud when nothing wraps. Relaxing it surfaced what it had been masking: the row lookup matched on `startsWith('| REL-02 ')` against the whole Shipped table, and ids are reused across milestones, so it compared this run's archive against a `REL-02` that shipped in v1.1.0-rc.2. Scoped to the rows the run added, which is the scoping the pipe-count check twelve lines below already uses. The `## Active` bullets are rewrapped to 80 columns so the corpus still exercises the multi-line span, and to match the prose around them. 2673 tests, 0 failures.