Skip to content

Close 1 shipped-but-open trackers so the workspace stops reporting finished work as in flight - #21

Merged
unbraind merged 3 commits into
mainfrom
chore/close-shipped-trackers
Jul 28, 2026
Merged

unbraind merged 3 commits into
mainfrom
chore/close-shipped-trackers

Conversation

@unbraind

@unbraind unbraind commented Jul 28, 2026 •

Copy link
Copy Markdown
Owner

What

Closes 1 trackers in this repo that were still in_progress while the work they describe had already shipped.

Why

project management = context management. An agent opening this workspace reads the open trackers as the current state of the world. Stale in_progress items actively mislead it into believing shipped work is still in flight — the oldest in this fleet sweep had been open for 60 days.

Verification

Nothing here was closed on the basis of its title. Each category was checked against the repository first:

category check
changelog-script adoption all four package.json changelog scripts pass --respect-item-release; pm-changelog pinned >= 2026.7.24
host-owned flag registration package installs and loads on pm-cli 2026.7.28 with failed: [] in pm health; commands register and execute
audit / hardening waves superseded — package now ships 2026.7.28 against pm-cli 2026.7.28 with a green release gate

Closing is changelog-safe: every changelog script in this repo passes --respect-item-release, so an item whose fix already shipped attributes to its original release window instead of landing in Unreleased. CHANGELOG.md was regenerated after the closures and changelog:check is green.

Items closed

Part of a fleet-wide sweep across 13 repos that took the fleet from 42 stale in_progress trackers to 0.

Summary by Sourcery

Close a shipped-but-open tracker and record the completed work in the changelog so the workspace no longer reports it as in-progress.

Enhancements:

  • Mark the pm-github-w7m7 tracker as completed and archive its history to reflect the shipped state of the work.

Documentation:

  • Update CHANGELOG.md with an entry describing adoption of --respect-item-release in changelog scripts and the pm-changelog version bump associated with pm-github-w7m7.

Chores:

  • Clean up stale project management metadata by closing an outdated in-progress tracker.

Summary by cubic

Closes one shipped-but-open tracker (pm-github-w7m7) so the workspace stops showing completed work as in progress, adds release: 2026.7.25 so it lands in the right historical section, and regenerates CHANGELOG.md. Appends a correction note with the exact pm-changelog range (^2026.7.25), lockfile resolution (2026.7.25), and confirmation that 4 scripts pass --respect-item-release.

Written for commit fdcfe79. Summary will update on new commits.

Review in cubic

These trackers described work that had already shipped, in some cases
weeks earlier. Leaving them open makes every agent that reads this
workspace believe the work is still in flight, which is the opposite of
what the tracker is for.

Each was verified against the repository before closing:

- changelog-script adoption trackers: confirmed all four changelog
  scripts in package.json pass --respect-item-release and pm-changelog
  is pinned at 2026.7.24 or later.
- host-owned flag registration trackers: confirmed the package installs
  and loads on pm-cli 2026.7.28 with an empty failed[] in pm health, and
  that its commands register and execute.
- audit and hardening waves: superseded, the package has shipped many
  releases since and now tracks pm-cli 2026.7.28.

Closing is changelog-safe because every changelog script here passes
--respect-item-release, so an item whose fix already shipped attributes
to its original release window rather than to Unreleased.

CHANGELOG.md regenerated after the closures, per repo convention.
@gemini-code-assist

Copy link
Copy Markdown

Caution

The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased.

@sourcery-ai

sourcery-ai Bot commented Jul 28, 2026 •

Copy link
Copy Markdown
Reviewer's guide (collapsed on small PRs)

Reviewer's Guide

Closes a previously in-progress pm tracker whose work has already shipped, updates its history, and records the already-adopted changelog-script changes in CHANGELOG.md so the workspace state and changelog accurately reflect reality.

State diagram for closing shipped-but-open tracker

stateDiagram-v2
  [*] --> In_progress
  In_progress --> Shipped
  Shipped --> Closed

  state In_progress {
    [*] --> Tracker_open
  }

  state Closed {
    Closed_tracker : status closed
    Closed_tracker : history updated
    Closed_tracker : changelog_respects_item_release
  }
Loading

File-Level Changes

Change Details Files
Record the already-shipped changelog-script adoption work in the changelog so it attributes to the correct release window.
  • Add a new Unreleased section to the changelog with an "Other" entry describing adoption of --respect-item-release in changelog scripts and the pm-changelog bump.
  • Link the changelog entry to the pm-github-w7m7 tracker for traceability.
CHANGELOG.md
Close the pm-github-w7m7 tracker now that its described work has shipped, and sync its history log.
  • Update the pm-github-w7m7 tracker definition to mark it as no longer in_progress (e.g., set status to closed/done or equivalent).
  • Adjust any tracker metadata as needed to indicate completion and align with the verified state of the repo.
  • Append or update history entries in the pm-github-w7m7 history log to reflect the closure event and any relevant timestamps or notes.
.agents/pm/chores/pm-github-w7m7.toon
.agents/pm/history/pm-github-w7m7.jsonl

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@coderabbitai

coderabbitai Bot commented Jul 28, 2026 •

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@unbraind, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 45 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: f8a20a8d-58d2-4902-aa01-1289b0e95100

📥 Commits

Reviewing files that changed from the base of the PR and between d5cba66 and fdcfe79.

📒 Files selected for processing (3)
  • .agents/pm/chores/pm-github-w7m7.toon
  • .agents/pm/history/pm-github-w7m7.jsonl
  • CHANGELOG.md

Walkthrough

The changelog now documents --respect-item-release adoption and the pm-changelog version bump. The related tracker records are marked closed with timestamps, a close reason, and updated history.

Changes

Changelog chore closure

Layer / File(s) Summary
Changelog update and tracker closure
.agents/pm/chores/pm-github-w7m7.toon, .agents/pm/history/pm-github-w7m7.jsonl, CHANGELOG.md
The changelog records the script and pm-changelog updates, while tracker metadata and history record the completed work and verification details.

Estimated code review effort: 1 (Trivial) | ~3 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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.
Title check ✅ Passed The title clearly matches the main change: closing a shipped-but-open tracker so it no longer appears in flight.
Description check ✅ Passed The description is directly about closing the stale tracker and updating changelog metadata.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch chore/close-shipped-trackers

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@sourcery-ai sourcery-ai 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.

Hey - I've reviewed your changes and they look great!


Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment thread CHANGELOG.md Outdated
@greptile-apps

greptile-apps Bot commented Jul 28, 2026 •

Copy link
Copy Markdown

Greptile Summary

Closes one stale tracker (pm-github-w7m7) that had been in_progress since 2026-07-24 despite the underlying work already having shipped. A release: 2026.7.25 field was added after the close to ensure the changelog entry lands in the correct historical section, and the changelog was regenerated to reflect this.

  • The tracker is now closed with closed_at set, release: 2026.7.25 declared, and a correction note appended to address the caret-range vs pin wording raised by CodeRabbit on a sibling repo.
  • The CHANGELOG.md entry for pm-github-w7m7 appears under ## 2026.7.25 (not Unreleased), correctly attributing the work to its original release window.
  • The history file's before/after hash chain is internally consistent across all six entries.

Confidence Score: 5/5

Safe to merge — the change is a well-verified tracker closure with no functional code modified.

All three files contain only project-management metadata updates: the tracker moves to closed with a correct release field, the append-only history file maintains a valid hash chain, and the CHANGELOG entry is placed in the right version section. The previous release-attribution concern is directly addressed. No source code, workflows, or configuration files are touched.

Files Needing Attention: No files require special attention.

Important Files Changed

Filename Overview
.agents/pm/chores/pm-github-w7m7.toon Tracker closed: status → closed, closed_at added, release: 2026.7.25 set (addressing prior release-attribution finding), correction note appended for caret-vs-pin wording in close_reason.
.agents/pm/history/pm-github-w7m7.jsonl Three new append-only entries: close op, release field update, and correction note; before/after hash chain is internally consistent across all six entries.
CHANGELOG.md pm-github-w7m7 entry now appears in the 2026.7.25 section (not Unreleased), correctly reflecting the release: 2026.7.25 field set in the tracker.

Reviews (4): Last reviewed commit: "chore(pm): record the exact pm-changelog..." | Re-trigger Greptile

Greptile flagged on pm-ops#30 that closing an item without a `release:`
field gives `--respect-item-release` nothing to honour, so already-shipped
work lands under `## Unreleased` and gets re-announced in the next release
notes. That was a real defect in the sweep: the earlier verification
confirmed the flag was present in every changelog script but not that the
items themselves carried release attribution.

Each closed item is now attributed to the first release tag cut at or
after its last pre-close `updated_at`, read from `origin/main` because the
close overwrote the field. Tags are zero-padded (`v2026.07.25`); the
release field takes the unpadded form (`2026.7.25`).

CHANGELOG.md regenerated: the entries move out of Unreleased and into
their historical version sections.
@unbraind

Copy link
Copy Markdown
Owner Author

Greptile's finding was correct and is now fixed — thank you, upvoted

Greptile flagged on pm-ops#30 that closing an item without a release: field gives --respect-item-release nothing to honour, so already-shipped work lands under ## Unreleased and gets re-announced as new in the next release notes.

That was a real defect in this sweep, and worth being precise about why I missed it: I verified that all four changelog scripts in every repo pass --respect-item-release and treated that as sufficient. It is not. The flag only respects an attribution the item carries — it cannot infer one. Flag present + release: absent still means Unreleased. Greptile caught the half I did not check.

Fix applied

Every item closed by this sweep is now attributed to the first release tag cut at or after its last pre-close updated_at, read from origin/main because the close itself overwrote that field. Tags in these repos are zero-padded (v2026.07.25); the release: field takes the unpadded form (2026.7.25).

Result on pm-ops, which is representative of all 13:

-## Unreleased
-
-### Other
-
-- Adopt --respect-item-release in changelog scripts and bump pm-changelog to 2026.7.24 ([ops-g3br](...))
+## 2026.7.25 - 2026-07-25
+
+### Other
+
+- Adopt --respect-item-release in changelog scripts and bump pm-changelog to 2026.7.24 ([ops-g3br](...))

grep -c '^## Unreleased' CHANGELOG.md → 0. changelog:check green in all 13 repos.

One case worth recording, since it looks wrong and is not

pm-slack/pm-slack-v7nq was last updated 2026-05-29 but attributes to 2026.7.7. That repo's earliest release tag is v2026.07.07 — there was no release between the work finishing and that tag, so the first release that could have shipped it is the correct answer. The rule is "first tag at or after the item", not "nearest tag by date".

For future reviews

The generalisable rule here: --respect-item-release is a no-op on an item with no release: field. Any PR that closes a tracker for already-shipped work needs the attribution set explicitly, not just the flag present in the script. Worth flagging whenever a diff closes an item and touches CHANGELOG.md without adding a release: line.

Re-requesting review on the updated commit below.

@unbraind

Copy link
Copy Markdown
Owner Author

@greptileai review

/gemini review

@coderabbitai full review

@gemini-code-assist

Copy link
Copy Markdown

Caution

The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased.

@coderabbitai

coderabbitai Bot commented Jul 28, 2026 •

Copy link
Copy Markdown

@unbraind: Starting a full review of the updated changes, including verification that the closed tracker has explicit release attribution and does not reappear under Unreleased.


✏️ Learnings added
Learnt from: unbraind
URL: https://github.com/unbraind/pm-github/pull/21

Timestamp: 2026-07-28T11:25:31.092Z
Learning: For this repository’s tracker/changelog workflow, `--respect-item-release` is a no-op for a closed item lacking an explicit `release:` field. When closing already-shipped work and regenerating `CHANGELOG.md`, attribute the item to the first release tag at or after its final pre-close `updated_at`; otherwise the changelog generator places it under `Unreleased` and it may be re-announced in future release notes.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.

✅ Action performed

Full review finished.


Your included review limit is currently reached under our Fair Usage Limits Policy. This review may still proceed through usage-based billing if eligible. Your next included review will be available in 52 minutes.

…losed tracker

CodeRabbit flagged on pm-ts-starter#43 that the close reason's phrase
"pinned at 2026.7.24 or later" is imprecise: the manifest declares a
caret RANGE, not a pin.

The substance of the closure holds — every repo's floor is at or above
2026.7.24 — but the wording was loose, so this appends a correction note
carrying the exact `package.json` spec, the lockfile resolution, and the
count of changelog scripts passing --respect-item-release, verified per
repo today.

The original record is preserved rather than rewritten, per CodeRabbit's
suggested remedy and the append-only nature of these audit trails.
@unbraind

Copy link
Copy Markdown
Owner Author

Follow-up commit: CodeRabbit correctly flagged on pm-ts-starter#43 that the close reason's "pinned at 2026.7.24 or later" is imprecise — ^2026.7.24 is a caret range, not a pin. Upvoted and applied across all 12 repos carrying that close reason, as an appended correction note rather than a rewrite (these records are append-only). Each note carries this repo's own verified package.json spec and lockfile resolution rather than a copied number.

Earlier round: Greptile's release-attribution finding is fixed and verified — entries moved out of Unreleased into their historical version sections, changelog:check green.

@greptileai review

/gemini review

@coderabbitai full review

@gemini-code-assist

Copy link
Copy Markdown

Caution

The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased.

@coderabbitai

coderabbitai Bot commented Jul 28, 2026 •

Copy link
Copy Markdown
🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '== Changed files and PR diff =='
git diff --name-status HEAD^ HEAD
git diff --no-ext-diff --unified=80 HEAD^ HEAD -- \
  .agents/pm/chores/pm-github-w7m7.toon \
  .agents/pm/history/pm-github-w7m7.jsonl \
  CHANGELOG.md \
  package.json \
  package-lock.json \
  npm-shrinkwrap.json \
  pnpm-lock.yaml \
  yarn.lock \
  bun.lock \
  bun.lockb \
  2>/dev/null || true

echo '== Candidate dependency and PM files =='
fd -a -t f -E .git \
  '^(package\.json|package-lock\.json|npm-shrinkwrap\.json|pnpm-lock\.yaml|yarn\.lock|bun\.lock|bun\.lockb|pm-github-w7m7\.(toon|jsonl)|CHANGELOG\.md)$' \
  . | sort

echo '== Relevant tracker/changelog and dependency lines =='
rg -n -C 8 \
  '^(release|status|updated_at|closed_at|close_reason|notes|assignee):|respect-item-release|pm-changelog|^## (Unreleased|2026\.7\.|[0-9])|pm-github-w7m7' \
  .agents/pm/chores/pm-github-w7m7.toon \
  .agents/pm/history/pm-github-w7m7.jsonl \
  CHANGELOG.md \
  package.json \
  package-lock.json \
  npm-shrinkwrap.json \
  pnpm-lock.yaml \
  yarn.lock \
  bun.lock \
  2>/dev/null || true

echo '== Release-tag context =='
git tag --list 'v*' --sort=creatordate | tail -n 30

Length of output: 41430


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '== Available refs =='
git branch -a --no-color
git remote -v

base_ref=''
for candidate in origin/main main origin/master master; do
  if git rev-parse --verify --quiet "$candidate" >/dev/null; then
    base_ref="$candidate"
    break
  fi
done
if [ -z "$base_ref" ]; then
  echo 'ERROR: No base branch ref is available.'
  exit 0
fi

merge_base="$(git merge-base "$base_ref" HEAD)"
echo "BASE_REF=$base_ref"
echo "MERGE_BASE=$merge_base"
echo '== Full PR changed files =='
git diff --name-status "$merge_base"...HEAD
echo '== Full PR diff =='
git diff --no-ext-diff --unified=30 "$merge_base"...HEAD

echo '== Validate JSONL event structure and replay =='
python3 - <<'PY'
import hashlib
import json
from pathlib import Path

history_path = Path(".agents/pm/history/pm-github-w7m7.jsonl")
tracker_path = Path(".agents/pm/chores/pm-github-w7m7.toon")
state = {}

def pointer_parts(path):
    assert path.startswith("/")
    return [part.replace("~1", "/").replace("~0", "~") for part in path[1:].split("/")]

def apply_op(doc, operation):
    parts = pointer_parts(operation["path"])
    parent = doc
    for part in parts[:-1]:
        parent = parent[int(part)] if isinstance(parent, list) else parent[part]
    key = parts[-1]
    if operation["op"] == "add":
        if isinstance(parent, list):
            parent.insert(len(parent) if key == "-" else int(key), operation["value"])
        else:
            parent[key] = operation["value"]
    elif operation["op"] == "replace":
        if isinstance(parent, list):
            parent[int(key)] = operation["value"]
        else:
            parent[key] = operation["value"]
    elif operation["op"] == "remove":
        if isinstance(parent, list):
            del parent[int(key)]
        else:
            del parent[key]
    else:
        raise ValueError(f"unsupported operation: {operation['op']}")

for number, line in enumerate(history_path.read_text().splitlines(), 1):
    event = json.loads(line)
    for operation in event["patch"]:
        apply_op(state, operation)
    print(f"event {number}: {event['op']} parsed and applied")

metadata = state["metadata"]
print("replayed status:", metadata["status"])
print("replayed release:", metadata.get("release"))
print("replayed updated_at:", metadata["updated_at"])
print("replayed notes:", len(metadata.get("notes", [])))

tracker = tracker_path.read_text()
checks = {
    "tracker closed": "status: closed" in tracker,
    "tracker release attributed": "release: 2026.7.25" in tracker,
    "correction retained": "manifest declares a caret RANGE rather than a pin" in tracker,
    "four scripts stated": "and 4 changelog scripts pass --respect-item-release" in tracker,
}
for label, passed in checks.items():
    print(f"{label}: {'PASS' if passed else 'FAIL'}")
PY

echo '== Explicit changelog section check =='
awk '
  /^## Unreleased$/ {unreleased++}
  /^## 2026\.7\.25 - 2026-07-25$/ {in_target=1; next}
  /^## / {in_target=0}
  in_target && /pm-github-w7m7/ {item=1}
  END {
    printf("unreleased_sections=%d\nitem_in_2026.7.25=%s\n", unreleased+0, item ? "yes" : "no")
  }
' CHANGELOG.md

Length of output: 17998


🏁 Script executed:

#!/bin/bash
set -euo pipefail

python3 - <<'PY'
import json
from pathlib import Path

path = Path(".agents/pm/history/pm-github-w7m7.jsonl")
events = [json.loads(line) for line in path.read_text().splitlines() if line.strip()]

for index, (previous, current) in enumerate(zip(events, events[1:]), start=2):
    if previous["after_hash"] != current["before_hash"]:
        raise SystemExit(
            f"FAIL: hash continuity breaks before event {index}: "
            f"{previous['after_hash']} != {current['before_hash']}"
        )
print(f"hash_continuity=PASS ({len(events)} events)")

state = {}
def tokens(pointer):
    if not pointer.startswith("/"):
        raise ValueError(pointer)
    return [p.replace("~1", "/").replace("~0", "~") for p in pointer[1:].split("/")]

def apply(doc, patch):
    parts = tokens(patch["path"])
    if len(parts) == 1:
        key = parts[0]
        if patch["op"] in ("add", "replace"):
            doc[key] = patch["value"]
        elif patch["op"] == "remove":
            del doc[key]
        return

    parent = doc
    for part in parts[:-1]:
        parent = parent[int(part)] if isinstance(parent, list) else parent[part]
    key = parts[-1]
    if patch["op"] == "add":
        if isinstance(parent, list):
            parent.insert(len(parent) if key == "-" else int(key), patch["value"])
        else:
            parent[key] = patch["value"]
    elif patch["op"] == "replace":
        if isinstance(parent, list):
            parent[int(key)] = patch["value"]
        else:
            parent[key] = patch["value"]
    elif patch["op"] == "remove":
        if isinstance(parent, list):
            parent.pop(int(key))
        else:
            del parent[key]
    else:
        raise ValueError(patch["op"])

for event in events:
    for patch in event["patch"]:
        apply(state, patch)

metadata = state["metadata"]
assert metadata["status"] == "closed"
assert metadata["release"] == "2026.7.25"
assert len(metadata["notes"]) == 3
assert "caret RANGE rather than a pin" in metadata["notes"][2]["text"]
assert metadata["updated_at"] == events[-1]["ts"]
print("replay=PASS")
print("final_release=" + metadata["release"])
print("final_notes=" + str(len(metadata["notes"])))
PY

echo '== Changelog placement =='
if rg -n '^## Unreleased$' CHANGELOG.md; then
  echo 'FAIL: Unreleased section exists'
  exit 1
fi
rg -n -A14 -B3 '^## 2026\.7\.25 - 2026-07-25$' CHANGELOG.md
echo 'unreleased_sections=0'

echo '== Exact script count =='
python3 - <<'PY'
import json
package = json.load(open("package.json"))
scripts = package["scripts"]
matches = [name for name, command in scripts.items()
           if name in {"changelog", "changelog:full", "changelog:check", "release:notes"}
           and "--respect-item-release" in command]
assert len(matches) == 4, matches
print("respect_item_release_scripts=" + ",".join(matches))
PY

Length of output: 3349


🏁 Script executed:

#!/bin/bash
set -euo pipefail

python3 - <<'PY'
import json
from pathlib import Path

events = [json.loads(line) for line in Path(".agents/pm/history/pm-github-w7m7.jsonl").read_text().splitlines() if line]
state = {}

def parts(pointer):
    return [part.replace("~1", "/").replace("~0", "~") for part in pointer[1:].split("/")]

for event in events:
    for operation in event["patch"]:
        path = parts(operation["path"])
        parent = state
        for part in path[:-1]:
            if isinstance(parent, list):
                parent = parent[int(part)]
            else:
                if part not in parent:
                    if operation["op"] != "add":
                        raise KeyError(f"missing parent {part} for {operation}")
                    parent[part] = {}
                parent = parent[part]
        key = path[-1]
        if operation["op"] == "add":
            if isinstance(parent, list):
                parent.insert(len(parent) if key == "-" else int(key), operation["value"])
            else:
                parent[key] = operation["value"]
        elif operation["op"] == "replace":
            if isinstance(parent, list):
                parent[int(key)] = operation["value"]
            else:
                parent[key] = operation["value"]
        elif operation["op"] == "remove":
            if isinstance(parent, list):
                parent.pop(int(key))
            else:
                del parent[key]
        else:
            raise ValueError(operation["op"])

metadata = state["metadata"]
assert metadata["status"] == "closed"
assert metadata["release"] == "2026.7.25"
assert metadata["updated_at"] == "2026-07-28T11:30:02.569Z"
assert len(metadata["notes"]) == 3
assert "caret RANGE rather than a pin" in metadata["notes"][2]["text"]
print("history_replay=PASS")
print(f"status={metadata['status']}")
print(f"release={metadata['release']}")
print(f"notes={len(metadata['notes'])}")
PY

if rg -n '^## Unreleased$' CHANGELOG.md; then
  echo 'FAIL: Unreleased section exists'
  exit 1
fi
if ! sed -n '/^## 2026\.7\.25 - 2026-07-25$/,/^## /p' CHANGELOG.md | rg -q 'pm-github-w7m7'; then
  echo 'FAIL: tracker is not in its attributed release section'
  exit 1
fi
echo 'changelog_attribution=PASS (2026.7.25; no Unreleased section)'

python3 - <<'PY'
import json
scripts = json.load(open("package.json"))["scripts"]
required = ("changelog", "changelog:full", "changelog:check", "release:notes")
missing = [name for name in required if "--respect-item-release" not in scripts.get(name, "")]
assert not missing, missing
print("respect_item_release=PASS (" + ", ".join(required) + ")")
PY

Length of output: 2993


@unbraind: Full review complete — no findings.

Verified that the correction is append-only and accurate: package.json declares the caret range ^2026.7.25, while package-lock.json resolves pm-changelog to 2026.7.25. The JSONL history chain is continuous and replays to the current closed, release-attributed tracker state.

Also confirmed all four changelog scripts use --respect-item-release, and pm-github-w7m7 is listed under 2026.7.25 with no ## Unreleased section present. 🐇✅

✅ Action performed

Full review finished.


Your included review limit is currently reached under our Fair Usage Limits Policy. This review may still proceed through usage-based billing if eligible. Your next included review will be available in 45 minutes.

@unbraind
unbraind merged commit 8f12d7b into main Jul 28, 2026
6 checks passed
@unbraind
unbraind deleted the chore/close-shipped-trackers branch July 28, 2026 11:38
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