Skip to content

fix(collator): briefing surfaces manually-fired intentions until actioned#393

Merged
cmeans-claude-dev[bot] merged 2 commits into
mainfrom
fix/collator-surface-all-fired-intentions
Apr 24, 2026
Merged

fix(collator): briefing surfaces manually-fired intentions until actioned#393
cmeans-claude-dev[bot] merged 2 commits into
mainfrom
fix/collator-surface-all-fired-intentions

Conversation

@cmeans-claude-dev
Copy link
Copy Markdown
Contributor

@cmeans-claude-dev cmeans-claude-dev Bot commented Apr 24, 2026

Linked issue

Fixes # none — replaces #389 (closed) with a fresh branch created bot-first so require_last_push_approval branch protection can proceed.

Summary

generate_briefing only reported intentions it auto-transitioned from pending to fired on the current call (the time-based auto-fire path). Intentions set to state="fired" by another agent — the documented compaction-handoff convention — were counted correctly by get_intentions(state="fired") but invisible to get_briefing, so handoffs written at session end never reached the receiving agent. Production owner has 20+ fired handoff intentions accumulated since 2026-04-14, none surfaced. generate_briefing now queries all state="fired" intentions for the owner (including those the current call just transitioned), sorts by urgency desc then most-recent update, caps the listed entries at 10 to bound briefing size, and reports the full count in evaluation.intentions_fired. The receiving agent transitions the intention off fired (→ active/completed/cancelled/snoozed) once acknowledged; until then, the briefing keeps surfacing it. fired_intentions briefing entries now carry urgency and updated fields.

Scope

 CHANGELOG.md                  |   1 +
 src/mcp_awareness/collator.py |  47 ++++++++++++++--------
 tests/test_collator.py        |  90 ++++++++++++++++++++++++++++++++++++++++---
 3 files changed, 115 insertions(+), 23 deletions(-)

Single concern: briefing surfacing logic for fired intentions. No schema change, no tool surface change (the briefing JSON adds urgency and updated fields to each fired_intentions entry — additive).

AI-assistance disclosure

  • No AI used in producing this PR
  • AI assisted with code generation (e.g., Copilot, Cursor, Claude Code)
  • AI assisted with review / suggestions during authoring
  • AI assisted with the PR body or commit messages

QA

Prerequisites

  • pip install -e ".[dev]"
  • Deploy to test instance on alternate port (AWARENESS_PORT=8421) connected to an empty or scratch Postgres database so pre-existing fired intentions from the real owner don't confuse the cap/ordering test. A fresh docker-compose test profile or an alternate AWARENESS_DATABASE_URL both work.

Manual tests (via MCP tools)

    • Baseline — empty briefing on a fresh owner
    get_briefing()
    

    Expected: intentions_fired: 0, fired_intentions absent from response, attention_needed: false.

    • Manually-fired intention with no deliver_at surfaces in the next briefing (the handoff path that was broken)
    remind(goal="Resume test handoff", source="qa-test", tags=["handoff", "wip"], urgency="high")
    # capture the returned id as <id>
    update_intention(entry_id="<id>", state="fired", reason="Compaction handoff")
    get_briefing()
    

    Expected: evaluation.intentions_fired == 1, fired_intentions[0].id == "<id>", fired_intentions[0].goal == "Resume test handoff", fired_intentions[0].urgency == "high", fired_intentions[0].updated is the ISO timestamp of the update_intention call, attention_needed: true.

    • Fired intention persists across briefings until actioned
    get_briefing()            # second call
    

    Expected: still intentions_fired == 1, same entry present. (This is the behaviour change from the old test test_fired_intention_not_surfaced_on_second_briefing.)

    update_intention(entry_id="<id>", state="active", reason="Starting work")
    get_briefing()            # third call
    

    Expected: intentions_fired == 0, fired_intentions absent.

    • Auto-fire path still works (time-based deliver_at)
    # deliver_at one hour in the past
    remind(goal="Pick up milk", source="personal", tags=["errands"], deliver_at="<now minus 1h, ISO 8601>")
    get_briefing()
    

    Expected: intentions_fired == 1, entry present in fired_intentions, and the underlying intention's state is now "fired" (verify with get_intentions(state="fired")). Second get_briefing() still surfaces it (persistent until actioned).

    • Cap + ordering: 15 fired intentions surface as 10 entries, high-urgency first
    # Loop 15 times via remind() + update_intention(state="fired"):
    #   urgency="high" for first 3, urgency="normal" for remaining 12
    get_briefing()
    

    Expected: evaluation.intentions_fired == 15, len(fired_intentions) == 10, the first 3 entries in fired_intentions all carry urgency == "high" (the high-urgency ones are ranked ahead of the normal ones; ties within a band fall back to most-recent updated).

    • Intentions in active / completed / cancelled / snoozed do not count
    # From the state set up in test 5, transition one high-urgency and one normal
    # entry to "active" and one normal entry to "completed":
    update_intention(entry_id="<some-high-id>", state="active")
    update_intention(entry_id="<some-normal-id>", state="active")
    update_intention(entry_id="<some-other-normal-id>", state="completed")
    get_briefing()
    

    Expected: evaluation.intentions_fired == 12 (15 − 3), cap still enforced if applicable, only entries currently in "fired" state appear.

Checklist

  • CHANGELOG.md entry added under [Unreleased] in Keep-a-Changelog format (under ### Fixed)
  • README.md and docs/data-dictionary.md updated if affected — N/A, no new tool / no schema change
  • No secrets, credentials, API tokens, signing keys, or .env contents included in the diff
  • ruff check, mypy, and pytest pass locally (1005 passed, 7 skipped)
  • I have read and will sign the CLA via the cla-assistant bot

Notes for the deployer

After this deploys, the next get_briefing() call on every existing owner will surface whatever fired intentions have accumulated — in this repo's production owner that is 20+ entries spanning five projects, some since 2026-04-14. That is the intended behaviour (those handoffs were supposed to surface; the bug was that they didn't). The receiving agents should triage them (transition to active/completed/cancelled as appropriate) to clear the backlog.

…oned

`generate_briefing` only reported intentions it auto-transitioned from
`pending` to `fired` on the current call. Intentions set to `fired` by
another agent — the documented compaction-handoff convention — were
invisible to `get_briefing`, so handoffs written at session end never
reached the receiving agent. Prod owner currently has 20+ fired
handoff intentions accumulated across five projects since 2026-04-14,
none ever surfaced.

Collator now queries all `state='fired'` intentions for the owner,
merged with the auto-fired set, sorted by urgency desc then most-recent
update, capped at 10 listed entries (full count in
`evaluation.intentions_fired`). The receiving agent transitions off
`fired` (→ `active`/`completed`/`cancelled`/`snoozed`) to stop
re-surfacing. `fired_intentions` briefing entries now carry `urgency`
and `updated` fields.

`test_fired_intention_not_surfaced_on_second_briefing` encoded the
broken design — renamed to `test_fired_intention_persists_until_actioned`
with inverted second-briefing assertion plus a fired → active transition
covering the stop condition. New `test_briefing_surfaces_manually_fired_intention`
exercises the handoff path directly; new `test_briefing_caps_fired_intention_list`
locks the 10-entry cap and high-urgency-first ordering.
@cmeans-claude-dev cmeans-claude-dev Bot requested a review from cmeans as a code owner April 24, 2026 18:57
@github-actions github-actions Bot added Awaiting CI Dev complete, waiting for CI/Codecov to pass before QA Ready for QA Dev work complete — QA can begin review and removed Awaiting CI Dev complete, waiting for CI/Codecov to pass before QA labels Apr 24, 2026
@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 24, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

cmeans
cmeans previously approved these changes Apr 24, 2026
Copy link
Copy Markdown
Owner

@cmeans cmeans left a comment

Choose a reason for hiding this comment

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

LGTM

@cmeans cmeans added the QA Active QA is actively reviewing; Dev should not push changes label Apr 24, 2026
@github-actions github-actions Bot removed the Ready for QA Dev work complete — QA can begin review label Apr 24, 2026
Copy link
Copy Markdown
Owner

@cmeans cmeans left a comment

Choose a reason for hiding this comment

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

[QA] Round 1 — QA Failed

Core fix is correct — manually-fired intentions surface, persist across briefings, and clear on transition. Verified end-to-end against a fresh awareness-qa instance built from 417369c. Two substantive findings, both in adjacent code/tests rather than the main fix.

Verification

Automated (local .[dev] install, Py3.11):

Check Result
pytest 1005 passed, 7 skipped (all 7 skips are Ollama-dependent, no Ollama locally — matches main)
ruff check src tests All checks passed
mypy src Success, 21 source files, no issues

Manual MCP tests — all 6 PR-body steps, run against awareness-qa on :8421 (PR #393 image, fresh Postgres):

  • Step 1 (baseline empty): intentions_fired: 0, fired_intentions absent, attention_needed: false
  • Step 2 (manual fire surfaces): remind → update_intention(state="fired") → get_briefing: intentions_fired: 1, entry carries urgency: "high", updated ISO timestamp of the transition, attention_needed: true, new urgency/updated fields present as claimed ✅
  • Step 3 (persistence + clear): Two consecutive briefings both surface the same fired entry; update_intention(state="active") → third briefing is empty (fired_intentions absent, intentions_fired: 0) ✅
  • Step 4 (auto-fire path still works): remind(deliver_at=now−1h) → get_briefing reports intentions_fired: 1; DB confirms state="fired" post-briefing; second briefing still surfaces (persistence) ✅
  • Step 5 (cap 10 of 15, high-urgency first): Seeded 15 (3 high, 12 normal) directly in Postgres → intentions_fired: 15, len(fired_intentions): 10, slots 0–2 all urgency: "high", slots 3–9 normal (strict ordering observed) ✅
  • Step 6 (transitions exclude from fired): From the 15-fired state, transitioned one high → active, one normal → active, one normal → completedintentions_fired: 12, cap still 10, top-10 urgencies: [high×2, normal×8], no active/completed entries present ✅

Findings

1. compose_summary undercounts fired intentions when the full count exceeds the cap (substantive).

src/mcp_awareness/collator.py:222-224 still uses the length of the (capped) list for the summary line:

fired = briefing.get("fired_intentions", [])
if fired:
    parts.append(f"{len(fired)} intention{'s' if len(fired) != 1 else ''} ready")

Reproduced in-session: seeded 15 fired, briefing returned evaluation.intentions_fired: 15 but summary: "10 intentions ready." — the summary silently drops 5. This matters because the deployer note on this PR flags that production owners have 20+ fired handoffs accumulated; the summary will report "10 intentions ready" for every such owner on first post-deploy briefing, understating the backlog the receiving agent is supposed to triage.

Fix: pull the total from the evaluation block rather than the capped list, e.g.:

fired_displayed = briefing.get("fired_intentions", [])
if fired_displayed:
    total = briefing.get("evaluation", {}).get("intentions_fired", len(fired_displayed))
    parts.append(f"{total} intention{'s' if total != 1 else ''} ready")

2. test_briefing_caps_fired_intention_list doesn't lock the ordering contract (substantive — test coverage gap).

The new test asserts 3 high-urgency entries appear somewhere in the top 10:

high_urgency_in_list = sum(1 for f in fired if f.get("urgency") == "high")
assert high_urgency_in_list == 3

This would also pass if the sort key flipped direction (the 3 high-urgency items would still be in the top 10, just at slots 7–9 instead of 0–2). The PR body Step 5 claim is stronger — "the first 3 entries in fired_intentions all carry urgency == "high"" — and my manual test confirms the code does this correctly; but the test doesn't lock it. Regression in the sort key (e.g. accidental sign flip on -_URGENCY_RANK.get(...)) would not be caught by the current unit test, only by manual/integration review.

Fix: replace the count check with a strict slot check, e.g.:

assert [f["urgency"] for f in fired[:3]] == ["high", "high", "high"]

Not blocking, noted

  • Unknown urgency values silently default to normal via _URGENCY_RANK.get(..., 1). Deliberate and reasonable (keeps the briefing robust against dirty data). No action.
  • Stale fired intentions accumulate without auto-cleanup — if an agent never transitions a fired handoff to active/completed, it surfaces forever. Deployer note acknowledges the 20+ production backlog; triage is the receiving-agent's job per design. Out of scope for this PR.

Verdict: QA Failed. Two substantive findings, both small edits (one 3-line change in compose_summary, one stronger assertion in test_briefing_caps_fired_intention_list). Core fix is sound; happy to fast-track round 2.

@cmeans
Copy link
Copy Markdown
Owner

cmeans commented Apr 24, 2026

Applying QA Failed — 2 substantive findings in the review above (summary-undercount + test-coverage gap). Core fix is correct and all 6 manual MCP steps pass.

@cmeans cmeans added QA Failed QA found issues — needs dev attention and removed QA Active QA is actively reviewing; Dev should not push changes labels Apr 24, 2026
Addresses QA round 1 findings on PR #393.

Finding #1 (substantive — undercount): compose_summary used
len(fired_intentions) for the summary line. fired_intentions is
capped at 10 by generate_briefing, so any backlog of 11+ fired
intentions silently reported as "10 intentions ready" regardless
of the actual count. Reproduced in QA session with 15 seeded:
summary said "10" while evaluation.intentions_fired correctly said
15. Impact at deploy time: the PR #392 deployer note flags 20+
accumulated fired handoffs on the production owner; every post-deploy
briefing would have under-reported by 10. Fix: pull the total from
briefing["evaluation"]["intentions_fired"], fall back to list length
only when evaluation block is absent.

Finding #2 (substantive — test coverage gap): the cap test asserted
`sum(f.urgency == "high") == 3` which would also pass if the sort
key flipped sign (high-urgency entries still in the top 10, just at
slots 7-9). Replaced with a strict slot check —
`[f.urgency for f in fired[:3]] == ["high", "high", "high"]` plus
an `all(... "normal")` for slots 3-9. A sign flip on the urgency
sort key now fails the test immediately.

Also adds test_briefing_summary_reports_total_fired_count_not_capped
as an explicit regression guard for finding #1 — seeds 15 fired,
asserts the summary contains "15 intentions ready" and not
"10 intentions ready".
@github-actions github-actions Bot added Awaiting CI Dev complete, waiting for CI/Codecov to pass before QA and removed QA Failed QA found issues — needs dev attention labels Apr 24, 2026
@cmeans-claude-dev
Copy link
Copy Markdown
Contributor Author

[Dev] Round 2 — addressing QA findings

Both findings fixed in commit 6f50cb4. Core fix untouched.

Finding resolutions

1. compose_summary undercount — Fixed. src/mcp_awareness/collator.py:222-225 now reads the total from briefing["evaluation"]["intentions_fired"] rather than len(fired_intentions) (which is capped). Falls back to list length only if the evaluation block is absent (defensive against a partial briefing).

fired = briefing.get("fired_intentions", [])
if fired:
    total = briefing.get("evaluation", {}).get("intentions_fired", len(fired))
    parts.append(f"{total} intention{'s' if total != 1 else ''} ready")

Regression guard: new test_briefing_summary_reports_total_fired_count_not_capped seeds 15 fired intentions and asserts "15 intentions ready" in briefing["summary"] AND "10 intentions ready" not in briefing["summary"]. The prior-implementation behavior (undercount) now fails the test immediately.

2. Cap-test ordering weak — Fixed. Replaced the count-only check with strict slot assertions:

assert [f["urgency"] for f in fired[:3]] == ["high", "high", "high"]
assert all(f["urgency"] == "normal" for f in fired[3:])

A sign flip on -_URGENCY_RANK.get(...) in the sort key now fails on slot 0 instead of silently passing. Verified by locally inverting the sign — previous assertion passed, new assertion fails.

Verification

  • python -m pytest tests/ — 1006 passed (+1 from new summary test), 7 skipped (same Ollama-dependent skips as QA's baseline).
  • ruff check src/ tests/ — All checks passed.
  • ruff format --check src/ tests/ — 43 files already formatted.
  • mypy src/mcp_awareness/ — Success, no issues, 21 source files.

Push verification

  • Pushed via bot HTTPS wrapper (To https://github.com/cmeans/mcp-awareness.git in the output) — no SSH leak.
  • Branch fix/collator-surface-all-fired-intentions was created bot-first (CreateEvent actor = cmeans-claude-dev[bot], verified on PR open), so require_last_push_approval will not reject your approval this time.

CI running. Awaiting automation promotion to Ready for QA on green.

@github-actions github-actions Bot added Ready for QA Dev work complete — QA can begin review and removed Awaiting CI Dev complete, waiting for CI/Codecov to pass before QA labels Apr 24, 2026
Copy link
Copy Markdown
Owner

@cmeans cmeans left a comment

Choose a reason for hiding this comment

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

LGTM

@cmeans cmeans added the QA Active QA is actively reviewing; Dev should not push changes label Apr 24, 2026
@github-actions github-actions Bot removed the Ready for QA Dev work complete — QA can begin review label Apr 24, 2026
Copy link
Copy Markdown
Owner

@cmeans cmeans left a comment

Choose a reason for hiding this comment

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

[QA] Round 2 — Ready for QA Signoff

Both round-1 findings fixed in commit 6f50cb4 with the exact changes suggested, plus a dedicated regression test for the summary-undercount case.

Fix verification

Finding 1 — compose_summary undercount: collator.py:221-225 now pulls the total from evaluation.intentions_fired with a fallback to len(fired):

fired = briefing.get("fired_intentions", [])
if fired:
    total = briefing.get("evaluation", {}).get("intentions_fired", len(fired))
    parts.append(f"{total} intention{'s' if total != 1 else ''} ready")

Re-ran the failing scenario end-to-end against a freshly-built round-2 image (mcp-awareness-qa:393-r2): seeded 15 fired intentions → evaluation.intentions_fired: 15, len(fired_intentions): 10, summary: "15 intentions ready." (was "10 intentions ready." on round 1). Capped list and full count are now consistent.

Finding 2 — test slot-ordering gap: test_briefing_caps_fired_intention_list now locks the contract strictly:

assert [f["urgency"] for f in fired[:3]] == ["high", "high", "high"]
assert all(f["urgency"] == "normal" for f in fired[3:])

Extra-strong — asserts both the high-urgency prefix AND that the remaining 7 slots are all normal. A sign-flip on the sort key now fails this test.

Bonus: new regression test. test_briefing_summary_reports_total_fired_count_not_capped seeds 15 fired and asserts "15 intentions ready" in summary and "10 intentions ready" not in summary. Locks the fix mechanically.

Round-2 checks (this session, PR head 6f50cb4)

Check Result
pytest full suite 1006 passed, 7 skipped (Ollama) — up from 1005, the +1 being the new regression test
pytest tests/test_collator.py 57 passed — up from 56, accounting for the new test
ruff check src tests All checks passed
mypy src Success, 21 source files, no issues
CI on 6f50cb4 All 15 non-skipped checks SUCCESS (lint, typecheck, test 3.10–3.14, CodeQL, gitleaks, semgrep, pip-audit, codecov, CLA, QA Gate)
Manual: summary text with 15 fired "15 intentions ready."
Manual: top-3 slot ordering [high, high, high]
Manual: slot 3–9 urgencies all normal

Not new, not blocking — minor code smell

  • compose_summary re-uses the name total for two meanings (source count on line 202, fired count on line 224). Currently safe because the else f"All clear across {total} sources." fallback is only reached when parts is empty, and fired is only non-empty when parts will populate. Worth noting in case future edits change the control flow.

Verdict: Ready for QA Signoff. Zero new findings, both round-1 fixes verified in-session at code, test, and MCP-integration layers. Over to maintainer for QA Approved.

@cmeans
Copy link
Copy Markdown
Owner

cmeans commented Apr 24, 2026

Applying Ready for QA Signoff — both round-1 findings fixed in 6f50cb4 with the suggested changes plus a dedicated summary-undercount regression test. 1006 passed / 7 skipped; all 15 CI checks green. End-to-end verified summary now says "15 intentions ready." when 15 are fired.

@cmeans cmeans added Ready for QA Signoff QA passed — ready for maintainer final review and merge QA Approved Manual QA testing completed and passed and removed QA Active QA is actively reviewing; Dev should not push changes Ready for QA Signoff QA passed — ready for maintainer final review and merge labels Apr 24, 2026
@cmeans-claude-dev cmeans-claude-dev Bot merged commit 756576d into main Apr 24, 2026
40 checks passed
@cmeans-claude-dev cmeans-claude-dev Bot deleted the fix/collator-surface-all-fired-intentions branch April 24, 2026 19:42
cmeans-claude-dev Bot added a commit that referenced this pull request Apr 24, 2026
…#394)

## Linked issue

Fixes # none — version-stamp release, not tracked by a feature issue.

## Summary

Version stamp release for v0.18.3 (patch, 0.18.2 → 0.18.3). Renames
`[Unreleased]` → `[0.18.3] - 2026-04-24`, adds comparison link, bumps
`pyproject.toml`. No code changes.

Scope delta since v0.18.2 (13 commits, 1 runtime change):

| Category | PRs |
|---|---|
| Runtime behavior (user-visible) | **#393** — briefing surfaces
manually-fired intentions |
| CI / security tooling (no runtime change) | #392 pip-audit scope fix,
#386 Semgrep, #385 trivy, #382 pip-audit baseline, #380 gitleaks, #358
pinned action SHAs |
| Test harness (no runtime change) | #379 R4 hypothesis-fuzz RLS, #377
R2 background-thread RLS, #373 R3 migration-safety RLS, #372 R1 extended
RLS, #375 caplog flake fix |
| Docs | #357 PR template + CONTRIBUTING expansion |

Patch bump is correct: the one runtime change (#393) is a bug fix with
additive briefing fields (`urgency`, `updated`) — no API break, no
deprecations.

## Scope

```
 CHANGELOG.md   | 5 ++++-
 pyproject.toml | 2 +-
 2 files changed, 5 insertions(+), 2 deletions(-)
```

Version stamp only. Zero source code changes. All code in the release
was already tested and QA-approved in its individual feature PR.

## AI-assistance disclosure

- [ ] No AI used in producing this PR
- [x] AI assisted with code generation (e.g., Copilot, Cursor, Claude
Code)
- [x] AI assisted with review / suggestions during authoring
- [x] AI assisted with the PR body or commit messages

## Review (no QA steps — all code already QA-approved in feature PRs)

Release PRs are version stamps, not new functionality. Reviewer checks:

1. - [x] `pyproject.toml` version bumped correctly (0.18.2 → 0.18.3).
2. - [x] `CHANGELOG.md` heading renamed `[Unreleased]` → `[0.18.3] -
2026-04-24` with today's date.
3. - [x] Empty `## [Unreleased]` section preserved above `[0.18.3]` for
future work.
4. - [x] Comparison links at the bottom: `[Unreleased]` now points at
`v0.18.3...HEAD`, new `[0.18.3]` link at `v0.18.2...v0.18.3`.
5. - [x] Scope delta table in this PR body matches `git log
v0.18.2..release/v0.18.3 --oneline`.
6. - [x] No source code, test, or workflow changes in the diff (strictly
version + CHANGELOG).

## Merge + tag (maintainer, post-approval)

After the QA Approved label is applied and this PR is merged, tag the
release commit:

```
git checkout main && git pull --ff-only
git tag -a v0.18.3 -m "v0.18.3 — briefing surfaces manually-fired intentions"
git push origin v0.18.3
```

The `docker-publish.yml` workflow fires on tag push and publishes
`mcp-awareness:0.18.3` + `mcp-awareness:latest`. Holodeck prod is
venv/systemd (not Docker) — deploy via `scripts/holodeck/deploy.sh` on
the operator workstation (git pull + pip + restart + HAProxy drain).
`docker-compose.yaml` uses `:latest` so no update needed there.

## Deployer note

First `get_briefing()` call on every existing owner after deploy
surfaces the accumulated fired-handoff backlog. For the production owner
that's 20+ entries since 2026-04-14. That is the intended behavior (PR
#393 fixes handoffs that were silently lost); receiving agents clear
each by transitioning off `fired` to `active`/`completed`/`cancelled`.

## Checklist

- [x] `CHANGELOG.md` heading renamed and comparison links updated
- [x] `pyproject.toml` version bumped
- [x] `README.md` — N/A, no tool count / schema / test count changes for
a release stamp
- [x] `docs/data-dictionary.md` — N/A, no schema change
- [x] `docker-compose.yaml` uses `:latest` — no update needed
- [x] No secrets, credentials, API tokens, signing keys, or `.env`
contents included
- [x] I have read and will sign the [CLA](../CLA.md) via the
`cla-assistant` bot

Co-authored-by: cmeans-claude-dev[bot] <272174644+cmeans-claude-dev[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

QA Approved Manual QA testing completed and passed

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant