gabriel / musehub public
Open #69 Bug
filed by gabriel human · 8 days ago

Show full SHA256 IDs in comment-list output instead of truncated form

0 Anchors
Blast radius
Churn 30d
0 Proposals

Overview

The muse hub issue comment-list command currently renders comment IDs in a truncated form (e.g. sha256:9 — just the first hex character after the prefix). This is useless for any downstream operation that requires a real identifier: copying a comment ID to reference it in another command, scripting against the output, or auditing provenance. Every other Muse command that emits an object ID outputs the full sha256:<64-hex> canonical form. Comment-list must match.

Affected output:

[2026-06-07] gabriel (sha256:9): ## Phase 1 complete

Expected output:

[2026-06-07] gabriel (sha256:3815aff3e764a58df4d776c129cd2667ae41b03cd9662a2c133a0fa015bd349c): ## Phase 1 complete

Phase 1 — Identify the truncation site

Trace exactly where the short ID originates. The truncation almost certainly happens in one of three places:

  1. Storage — the comment_id is stored truncated in the database
  2. API serializer — the full ID is stored but the serializer trims it before sending it over the wire
  3. CLI renderer — the hub client receives the full ID but truncates it before printing

Determine which layer is at fault:

# Check what the raw API returns — does the JSON contain the full ID or the short one?
muse -C ~/ecosystem/musehub hub issue comment-list <issue_number> --json   | python3 -c "import sys,json; [print(c.get('comment_id','<missing>')) for c in json.load(sys.stdin).get('comments',[])]"

If the JSON already contains the full ID, the truncation is in the CLI renderer only (cheapest fix). If the JSON contains the short ID, the bug is in the API serializer or the DB. Document which layer is at fault before writing any code.


Phase 2 — Fix the root cause

If CLI renderer only: find the format string or display helper that shortens the ID and remove the truncation. The display path for comment-list is in the hub CLI command handler — search for the string format responsible for sha256: followed by a single character.

muse -C ~/ecosystem/musehub code grep "comment_id" --json
muse -C ~/ecosystem/musehub content-grep "sha256:" --json   # find all truncation sites

If API serializer: find the Pydantic model or response schema for the comment resource and ensure comment_id is emitted as the full sha256:<64-hex> string. Use split_id / encode_id from muse.core.types — never do string slicing inline.

If DB storage: check the column type and any INSERT path that writes the comment_id. Confirm whether data at rest is already truncated (requires a migration to repair existing rows) or whether only new writes are affected.

Fix only the identified layer. Do not speculatively clean up adjacent code.


Phase 3 — Audit all comment ID emission paths

Once the root cause is fixed, do a sweep to ensure no other output surface truncates comment IDs:

muse -C ~/ecosystem/musehub content-grep "comment_id" --json

Check each hit:

  • hub issue comment-list — primary surface (fixed in Phase 2)
  • hub proposal comment list — same command on proposals, may share the same code path
  • hub issue read — does issue detail embed any comment IDs?
  • hub issue create / hub issue comment — do creation responses echo the new comment_id?

Any surface that emits a truncated ID must be fixed in this phase — not filed as a follow-up. Truncated IDs anywhere in the output are a correctness bug, not a cosmetic one.


Phase 4 — Verify JSON and text output are consistent

The --json flag must always return the full ID. The human-readable text output (without --json) may format it differently for readability, but must never truncate to the point of ambiguity (first character only is always ambiguous).

Acceptable text-mode formats:

  • Full: sha256:3815aff3e764a58df4d776c129cd2667ae41b03cd9662a2c133a0fa015bd349c
  • Short prefix (12 chars): sha256:3815aff3e764 — unambiguous in practice, clearly truncated

Unacceptable:

  • sha256:9 — single character, always ambiguous, useless for any downstream use

If the text renderer applies intentional shortening for readability, it must use a configurable prefix length (default 12 hex chars minimum) and must never be applied to --json output.


Phase 5 — Regression test

Add a test that asserts the full sha256:<64-hex> ID appears in comment-list JSON output:

def test_comment_list_emits_full_id(client, issue_with_comment):
    resp = client.get(f"/issues/{issue_with_comment.number}/comments")
    comments = resp.json()["comments"]
    assert len(comments) > 0
    for c in comments:
        cid = c["comment_id"]
        assert cid.startswith("sha256:"), f"expected sha256: prefix, got {cid!r}"
        hex_part = cid[len("sha256:"):]
        assert len(hex_part) == 64, f"expected 64-char hex, got {len(hex_part)}-char: {cid!r}"

Run with:

python3 -m pytest tests/test_issue_comments.py -q --tb=short

Acceptance criteria

[ ] muse hub issue comment-list --json returns full sha256:<64-hex> for every comment_id
[ ] muse hub proposal comment list --json returns full sha256:<64-hex> for every comment_id
[ ] Text-mode output shows at minimum a 12-char hex prefix (never single character)
[ ] No other hub command emits a truncated comment_id
[ ] Regression test added and passing
[ ] Existing comments in the DB are unaffected (if truncation was only in the serializer/renderer)
Activity
gabriel opened this issue 8 days ago
No activity yet. Use the CLI to comment.