ideation: hard-reject a slug that collides with a shipped post #370
No reviewers
Labels
No labels
Agent
Compat/Breaking
Kind/Bug
Kind/Documentation
Kind/Enhancement
Kind/Feature
Kind/Security
Kind/Testing
Priority
Critical
Priority
High
Priority
Low
Priority
Medium
Reviewed
Confirmed
Reviewed
Duplicate
Reviewed
Invalid
Reviewed
Won't Fix
Status
Abandoned
Status
Blocked
Status
Need More Info
No milestone
No assignees
2 participants
Notifications
Total time spent: 40 seconds
Due date
igor
40 seconds
No due date set.
Dependencies
No dependencies set
Reference
joshtronic/igor!370
Loading…
Reference in a new issue
No description provided.
Delete branch "fix/367-slug-collision"
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?
Closes #367. Adds a hard slug-collision gate to the ideation pipeline.
The shipped-digest dedup is a nudge to the model, not a gate — it didn't catch a same-slug regeneration (
ergo-decedo, 7/7 then 7/8). The duplicate wrote the same Eleventy permalink, so the PR's CI could never go green (Output conflict), wasting a draft + rework round + escalation.Now, right after the slug is chosen and before the expensive draft, any slug that already exists as a shipped post is rejected and the run exits clean — the daily slot retries next tick and re-rolls a fresh idea. So the un-mergeable duplicate-permalink PR is never opened.
11 lines, shellcheck clean,
make testgreen. Reuses the existing*-<slug>.mdfind pattern the link-resolver already uses. (Left the optional 'auto-close an existing duplicate-permalink PR' bonus out — the source-side gate prevents it upstream.)🤖 Review —
COMMENT(automated)CI for
5806aa7d: successAdds an 11-line hard slug-collision gate to
bin/ideation-pipeline.shthat exits clean (re-roll next tick) when the chosen slug already exists as a shipped post, before the expensive draft. Focused, in scope, honestly described, CI green. One correctness nuance worth a human glance before merge.Findings
Potential false-positive from the suffix glob (
bin/ideation-pipeline.sh, thefind ... -name "*-${SLUG}.md"clause). Posts are namedYYYY-MM-DD-slug.md, so*-${SLUG}.mdalso matches any file whose slug ends in-${SLUG}. E.g. a new slugdecedowould match the existing2026-07-07-ergo-decedo.mdand be rejected even though its permalink (posts/decedo/) does not actually collide withposts/ergo-decedo/. The failure mode is benign (an unnecessary re-roll next tick, no bad PR opened), and the description notes this reuses the link-resolver's existing pattern — but it means the gate is broader than "same permalink." If the intent is strictly permalink-collision, an exact-slug check (e.g. matching????-??-??-${SLUG}.mdor deriving the actual permalink) would be tighter. Flagging so the human can decide whether the over-rejection is acceptable.No dedicated test for the new gate. The contract asks for tests alongside behavior changes. This is a shell early-exit path;
make testis green per CI, but I can't see a test that exercises the collision branch (skip vs. proceed). If the repo has any shell/bats harness, a case covering "slug matches shipped post → exit 0, no draft" would lock in the behavior. If there's no such harness, that's understandable — just noting the gap.Non-issues (checked)
2>/dev/null+grep -q .correctly treats a missingsrc/postsas "no collision" → proceeds. Fine.exit 0(clean) is intentional per the description so the scheduler retries next tick — consistent with the stated design.SLUGis quoted in the-namepattern; worst case a glob metachar in a slug causes a mismatch, not injection.No blocking defect found; the suffix-match breadth is the one thing I'd want the human to confirm is intended.
Independent review by the harness on
claude-opus-4-8(effort: high). The human reviewer is requested once Igor has reviewed; a human still merges.Closes #NNkeyword when a PR resolves an issue #372