feat: Fix source_issue write path (persist off-label)#103
Conversation
There was a problem hiding this comment.
QA panel review — WARN
code-review-structural · head fee74c78a1ef · formal
[review-synthesizer completed: workflow code-review-structural:report]
Overall risk is low; the change narrows the read path for source_issue but existing data using the old label format is unlikely to exist. The single confirmed minor finding regarding the removed fallback should be addressed first to prevent silent data loss for any legacy beads. The panel was unanimous, with no disagreements. Verification confirmed the finding and explicitly noted the diff removes the label-read logic without a migration path. A structural analysis pass was skipped, leaving broader architectural impacts unreviewed.
[
{
"file": "store.py",
"line": 1227,
"severity": "minor",
"category": "removed-behavior",
"claim": "Existing beads with source_issue stored as `source:owner/repo#N` labels will silently lose their source_issue because _project no longer reads from labels.",
"evidence": "Old _project extracted source_issue via `next((l[len(LABEL_SOURCE_PREFIX):] for l in labels if l.startswith(LABEL_SOURCE_PREFIX)), '')`; new code uses only `_split_notes(bead.get('notes'))`. No fallback to the old label format. (PR notes old label writes were already broken for real beads CLI, so existing data is unlikely, but the read path is narrowed without migration.)",
"verdict": "confirmed",
"note": "Diff shows old label-read code (`next((l[len(LABEL_SOURCE_PREFIX):] ...)` ) removed from `_project` and replaced with `files_to_modify, source_issue = _split_notes(bead.get('notes'))`; no fallback to `LABEL_SOURCE_PREFIX` labels exists in the new code."
}
]1 finding(s) downgraded to uncertain: the code they quote as evidence does not appear in the file at the reviewed head, nor in this PR's patch for it. A finding that cannot be grounded does not gate a merge (issue #25) — it still stands for a human to judge.
store.py(minor) — quoted evidence not found at this head:next((l[len(LABEL_SOURCE_PREFIX):] for l in labels if l.startswith(LABEL_SOURCE_PREFIX)), '')
|
Operator adjudication of the WARN (brain-ruled): dismiss. The finding describes migrating beads with |
There was a problem hiding this comment.
Promoting the WARN verdict for head fee74c78a1ef: all checks terminal-green, zero unresolved review threads. (approve-on-green)
Open findings carried by this approval — non-blocking, but they did not go away:
- minor
store.py:1227— Existing beads with source_issue stored assource:owner/repo#Nlabels will silently lose their source_issue because _project no longer reads from labels.
Approving a WARN does not resolve its findings (issue #22).
Summary
source_issuewas persisted as asource:owner/repo#Nlabel, but beads' label validator only allows alphanumeric/hyphen/underscore/colon — every real write failed withVALIDATION_FAILED(only the fake-brunit tests kept passing). No migration is needed since no real value ever persisted.source_issuenow rides off-label as a structuredsource-issue: owner/repo#Nmetadata line in the beadnotesfield, beside thefiles_to_modifypath lines (_render_notes/_split_notesinstore.py). Sincebr update --notesreplaces the whole field,update_featurerewrites it carrying the untouched half forward — a files-only update never drops the source line, and vice versa.files_to_modify+source_issue, soloop._source_issue(the PR opener'sFixes #Nstamp) andboard_get_featurekeep reading the same projected field from the new location.tests/test_source_issue_roundtrip.pyruns against the realbrCLI in a throwaway workspace — create →get_feature→ value survives, which fails with the old label path (skipped only whenbrisn't on PATH).Fixes #101