Skip to content

feat(skill): Anchor primitive, Task archetype, two-mode operation + validator hygiene - #5

Merged
phj6688 merged 4 commits into
mainfrom
feat/anchor-and-validator-hygiene
Jul 6, 2026
Merged

phj6688 merged 4 commits into
mainfrom
feat/anchor-and-validator-hygiene

Conversation

@phj6688

@phj6688 phj6688 commented Jul 5, 2026

Copy link
Copy Markdown
Owner

Increment 1 (+4) of the evidence-backed linear-issue-craft redesign. Retargets the skill around the autonomous pipeline that consumes its output (planner, held-out probe, implementer, reviewer, merge gate), where a false-green is the failure mode.

What changed

New authoring primitive: the Anchor. Every story and task names one machine-resolvable target (file.ext:line, file.ext:symbol, module.function, METHOD /path -> status, or playwright:selector) that the held-out probe binds to. A probe cannot test a thing the issue never named. WARN in the skill validator; a save-hook (next increment) promotes it to a create-only ERROR.

Task archetype for a one-cause bug / chore / spike / ops change (Type: Bug|Chore|Spike|Ops -> Anchor / Problem / Verification). Closes the coverage gap where a one-line bug had to be inflated into a Story or mis-filed as a one-issue Hardening ticket.

Runnable acceptance. Evaluation items must run headless against the checkout and may not assert against a stub of the thing under test (HLB-495 shipped Done-but-broken behind a stubbed-seam eval). Soaks/dashboards move to a Post-ship follow-up line. Hardening issues gain a per-issue Verify: line.

Two-mode operation. Interactive mode keeps the three gates + approval. Headless/pipeline mode drops the per-issue reviewer and approval but keeps Gate 1 mandatory before every save (10/11 real runs were headless; one filed 80 issues with the validator never run).

Validator correctness fixes

  • epic-backlink demoted to WARN with an Epic: none sentinel (was the feat(skill): add validate_issue.py hard gate and fix the rules it exposed #1 fail-loop)
  • labels-verify WARN deleted (undischargeable noise, fired 111x)
  • vague-verb now requires a metric adjacent to the verb (a bare issue-id no longer launders it)
  • code-fence / inline-code aware scans (quoted ## Description, robust-parser.ts no longer trip)
  • --- splitting is fence-aware and merges title-less tails (a mid-body rule can no longer drop the tail of an issue from validation)
  • epic-story-count counts any child bullet; role-titled children exempt from the em-dash check
  • estimate is a save-time Linear field, not a body mandate; priority enum reconciled (adds Urgent)

Verification

  • ruff check . clean
  • python3 skill/scripts/tests/test_validate.py -> 28 passed, 0 failed (11 original + 17 new: fence blindness, --- tail-drop, standalone story, metric false-negative, Anchor shape)
  • CLI exercised end-to-end on good/bad/epic+children/task drafts

Full plan and evidence: 4-agent audit + war-room verdict (sequenced increments, boundary rule = issue TEXT owns what only the author knows, gates own what must hold regardless of author).

Summary by CodeRabbit

  • New Features

    • Added a new Task issue archetype and expanded templates with required, machine-resolvable Anchor lines.
    • Introduced an on-save validation gate for create-only filings, with observe (log-only) and enforce (block) modes.
  • Bug Fixes

    • Improved draft validation accuracy: fence/code-aware parsing, more reliable issue splitting, and reduced noisy warnings.
    • Strengthened headless-run acceptance/verification checks for stories and hardening items.
  • Documentation

    • Refreshed README and skill/reference guides with updated examples, filing workflow, and template boundaries (including post-ship follow-ups).

…tion; fix validator correctness

Retarget the skill around the pipeline that consumes its output. Every story
and task now names one machine-resolvable Anchor (file:line, file:symbol,
module.function, METHOD /path -> status, or playwright:selector) that the
held-out probe binds to. Acceptance must be runnable headless against the
checkout and may not stub the thing under test; soaks and dashboards move to a
Post-ship follow-up line.

Add a lightweight Task archetype (Type: Bug/Chore/Spike/Ops -> Anchor / Problem
/ Verification) so a one-line bug is no longer inflated into a Story or filed as
a one-issue Hardening ticket. Add a story Out-of-scope non-goal and a per-issue
hardening Verify line.

Split the flow into interactive and headless modes: headless drops the per-issue
independent reviewer and the approval ceremony but keeps Gate 1 mandatory before
every save (a save-hook enforces this at the tool boundary).

Validator correctness:
- epic-backlink demoted to WARN (Epic: none sentinel); it was the top fail-loop
- labels-verify WARN deleted (undischargeable noise on every block)
- vague-verb requires a metric adjacent to the verb, not anywhere on the line
- code-fence and inline-code aware: quoted headings/identifiers no longer trip
- --- splitting is fence-aware and merges title-less tails, so a mid-body rule
  can no longer drop the tail of an issue from validation
- epic-story-count counts any child bullet; role-titled children exempt from em-dash
- estimate is a save-time Linear field, not a body mandate; priority enum reconciled

Ruff clean, 28 validator tests pass.
@coderabbitai

coderabbitai Bot commented Jul 5, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

You’ve reached a temporary PR review limit under our Fair Usage Limits Policy.

Your recent review volume is higher than typical usage, so adaptive limits are currently applied.

Next review available in: 33 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: CHILL

Plan: Pro

Run ID: 7fc089a0-3412-47c5-a704-2eaa69bccd5b

📥 Commits

Reviewing files that changed from the base of the PR and between ab06da8 and 87e37bd.

📒 Files selected for processing (8)
  • CHANGELOG.md
  • README.md
  • hooks/test_hook.sh
  • hooks/validate-issue-on-save.sh
  • skill/prompts/brief-to-epic.md
  • skill/prompts/refactor-story.md
  • skill/scripts/tests/test_validate.py
  • skill/scripts/validate_issue.py
📝 Walkthrough

Walkthrough

This PR updates issue-authoring guidance, validation logic, tests, and a new save-hook to support Anchor fields, the Task archetype, headless filing behavior, and stricter validator checks.

Changes

Anchor/Task archetype and validator update

Layer / File(s) Summary
Changelog and README overview updates
CHANGELOG.md, README.md
Documents the Anchor/Task archetype changes, two-mode workflow, and validator correctness updates.
SKILL.md archetype, gate, and mode contract
skill/SKILL.md
Adds Task archetype and Anchor requirements, moves estimate handling to save_issue time, and formalizes interactive vs headless Gate 1/Gate 3 behavior.
Prompt templates for epic, hardening, and refactor stories
skill/prompts/brief-to-epic.md, skill/prompts/hardening-issue.md, skill/prompts/refactor-story.md
Adds Anchor/Out-of-scope/Verify lines, headless acceptance wording, and blocked-by relation guidance.
Reference guides, tone rules, anti-patterns, and canonical examples
skill/references/01-title-patterns.md, skill/references/02-description-templates.md, skill/references/03-tone-guide.md, skill/references/05-anti-patterns.md, skill/references/06-canonical-examples.md
Adds Task title pattern, Anchor/Out of scope templates, tone calibration updates, anti-pattern fixes, and new canonical examples.
Gate 3 issue-reviewer prompt updates
skill/review/issue-reviewer.md
Adds Anchor-resolution and headless-verification checks, revises estimate severity, and expands archetype calibration.
Validator core: fence-aware parsing, Anchor/Task/Priority checks
skill/scripts/validate_issue.py
Adds fence-aware parsing, Anchor/Task/Priority checks, and stricter vague-verb/em-dash/AI-tell detection.
Validator test coverage
skill/scripts/tests/test_validate.py
Expands fixtures and assertions for the new anchor/task/priority/fence-aware validation behavior.
Save-hook validation gate and hook tests
hooks/README.md, hooks/test_hook.sh, hooks/validate-issue-on-save.sh
Documents and implements the create-only save hook, plus tests for observe/enforce behavior, anchor failures, exemptions, and logging.

Estimated code review effort: 3 (Moderate) | ~30 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Agent
  participant Gate1Validator as Gate1 (validate_issue.py)
  participant Gate3Reviewer
  participant Linear as save_issue

  Agent->>Gate1Validator: run validator before save
  Gate1Validator-->>Agent: pass/fail (ERROR/WARN)
  alt interactive mode
    Agent->>Gate3Reviewer: request independent review
    Gate3Reviewer-->>Agent: approval
  else headless mode
    Agent->>Agent: skip per-issue Gate 3
  end
  Agent->>Linear: save_issue(estimate, priority)
Loading

Possibly related PRs

Poem

A rabbit hops through anchor and gate,
Task drafts now file with a steadier fate. 🐇
Fences keep false alarms out of sight,
Verify lines make hardening bright.
Hop, validate, and save just right —
The warren hums in orderly light.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main additions: Anchor, Task, two-mode operation, and validator fixes.
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.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/anchor-and-validator-hygiene

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

@coderabbitai coderabbitai 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.

Actionable comments posted: 5

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
skill/prompts/refactor-story.md (1)

94-100: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Show the Epic field in the refactor skeleton.

Step 3 already makes **Epic:** part of the contract, including none for standalone refactors, but the filing skeleton drops it. That leaves authors with no place to record the backlink the validator reads.

♻️ Proposed fix
 **Title:** <title>
+**Epic:** <parent epic, or `none` for a deliberately standalone refactor>
 **Anchor:** <the new file/function being introduced>
 **Labels:** <domain>, tech-debt
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@skill/prompts/refactor-story.md` around lines 94 - 100, The refactor skeleton
is missing the Epic field even though the contract in the story template already
requires it. Update the refactor story template to include an `**Epic:**` line
in the filing skeleton, alongside the existing `Title`, `Anchor`, `Labels`, and
`Priority` fields, so authors can provide the backlink the validator expects;
keep the formatting consistent with the surrounding placeholders in the story
template.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@README.md`:
- Line 36: Update the Task archetype row in the README so it matches the Task
contract used elsewhere by including Ops alongside Bug, Chore, and Spike. Adjust
the Task table entry in the README template reference so the allowed type list
is consistent with the rest of the docs.
- Line 5: Update the README overview paragraph to describe both archetypes in
the autonomous pipeline, not just Story: keep the existing explanation of the
planner, held-out probe, implementer, reviewer, and merge gate, but revise the
probe description so it reflects Task drafts using Problem plus Verification
alongside Story’s Requirements plus Evaluation. Use the existing overview text
near the opening paragraph and keep the wording consistent with the rest of
README.md.

In `@skill/prompts/brief-to-epic.md`:
- Around line 100-105: The story skeleton is missing the validator-readable Epic
backlink, so update the template in brief-to-epic.md to include a `**Epic:**`
line in the story body alongside `**Parent:**`. Keep `Parent` as metadata, but
restore the explicit `Epic` backlink in the `Story 1 of N` block so the
generated story shape satisfies the validator. Use the existing story header
fields (`Title`, `Anchor`, `Parent`, `Labels`) as the place to add it without
changing the overall template structure.

In `@skill/references/06-canonical-examples.md`:
- Around line 88-95: Item 1 still uses a Helicone dashboard read as a validation
gate, which conflicts with the headless Evaluation contract. Update the
acceptance criteria in the canonical examples doc so the primary check for the
relevant LLM call site is a local assertion or test, using the existing
“Validates R1 + R2” wording as the anchor. If you want to keep the dashboard
visibility check, move it into the Post-ship follow-up section alongside the 24h
soak note rather than leaving it in the main validation list.

In `@skill/scripts/tests/test_validate.py`:
- Around line 164-193: The VAGUE_WITH_ID fixture is not isolating the laundering
case because check_vague_verbs scans the entire block and the current title
already trips vague-verb before the PROJ-19 text is reached. Update the
VAGUE_WITH_ID content in test_validate.py so the title is clean and the vague
verb appears only in the body with the issue ID, or split this into a separate
fixture dedicated to the laundering path. Use the VAGUE_WITH_ID fixture and
check_vague_verbs as the main anchors while adjusting the test data.

---

Outside diff comments:
In `@skill/prompts/refactor-story.md`:
- Around line 94-100: The refactor skeleton is missing the Epic field even
though the contract in the story template already requires it. Update the
refactor story template to include an `**Epic:**` line in the filing skeleton,
alongside the existing `Title`, `Anchor`, `Labels`, and `Priority` fields, so
authors can provide the backlink the validator expects; keep the formatting
consistent with the surrounding placeholders in the story template.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 5481eed7-9490-4f61-8a31-b419076a64a8

📥 Commits

Reviewing files that changed from the base of the PR and between 0be2632 and d866f85.

📒 Files selected for processing (14)
  • CHANGELOG.md
  • README.md
  • skill/SKILL.md
  • skill/prompts/brief-to-epic.md
  • skill/prompts/hardening-issue.md
  • skill/prompts/refactor-story.md
  • skill/references/01-title-patterns.md
  • skill/references/02-description-templates.md
  • skill/references/03-tone-guide.md
  • skill/references/05-anti-patterns.md
  • skill/references/06-canonical-examples.md
  • skill/review/issue-reviewer.md
  • skill/scripts/tests/test_validate.py
  • skill/scripts/validate_issue.py

Comment thread README.md Outdated
Comment thread README.md Outdated
Comment thread skill/prompts/brief-to-epic.md
Comment thread skill/references/06-canonical-examples.md
Comment thread skill/scripts/tests/test_validate.py
…boundary

A headless subagent filing a batch can skip the skill's interactive Gate 1; this
PreToolUse hook on mcp__linear__save_issue runs the same validator at the point
of creation, and PreToolUse fires for subagent tool calls, so the batch path is
covered. Create-only (updates with an id pass untouched, so the pre-Anchor corpus
is never orphaned), build-lane scoped (governance labels exempt), observe by
default and enforce on an operator flip via permissionDecision: deny. A missing
or prose Anchor is promoted to a block on create. Fails open on bad input.

Ships in the skill repo as a portable reference hook; the operator installs it
and owns the enforce flip (gated on a clean corpus replay). test_hook.sh covers
the 7-case decision matrix.

@coderabbitai coderabbitai 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.

Actionable comments posted: 1

🧹 Nitpick comments (1)
hooks/test_hook.sh (1)

34-42: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Replace A && ok || bad with explicit if/then/else.

Static analysis flags this pattern on lines 34-39 and 42 (SC2015): A && B || C is not if/then/else — C can also run if B fails. ok()'s body currently never fails, so this is latent rather than an active bug, but it's fragile against future changes to ok()/bad().

🔧 Suggested fix (apply to each assertion)
-[ "$(bad_create | decide observe)" = "allow" ]     && ok || bad "observe allows bad create"
+if [ "$(bad_create | decide observe)" = "allow" ]; then ok; else bad "observe allows bad create"; fi
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@hooks/test_hook.sh` around lines 34 - 42, The shell assertions in
test_hook.sh use the fragile A && ok || bad pattern, which static analysis flags
as not being true if/then/else. Replace each assertion around bad_create,
good_create, bad_update, missing_anchor, and governance with an explicit
if/then/else block so only the intended branch runs, while keeping the existing
ok and bad helpers and the observe log check unchanged.

Source: Linters/SAST tools

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@hooks/validate-issue-on-save.sh`:
- Line 67: The exemption handling in validate-issue-on-save.sh is inconsistent:
the inline comment mentions decision/adjudication, but the default EXEMPT value
only includes human,eval, and the matching is case-sensitive. Update the EXEMPT
default or the comment so they agree, and normalize LINEAR_ISSUE_GATE_EXEMPT to
lowercase before the comparison in the exemption check logic so mixed-case
overrides still match.

---

Nitpick comments:
In `@hooks/test_hook.sh`:
- Around line 34-42: The shell assertions in test_hook.sh use the fragile A &&
ok || bad pattern, which static analysis flags as not being true if/then/else.
Replace each assertion around bad_create, good_create, bad_update,
missing_anchor, and governance with an explicit if/then/else block so only the
intended branch runs, while keeping the existing ok and bad helpers and the
observe log check unchanged.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 34ce80b2-aa72-4282-811a-54ed19ee67f5

📥 Commits

Reviewing files that changed from the base of the PR and between d866f85 and ab06da8.

📒 Files selected for processing (5)
  • CHANGELOG.md
  • hooks/README.md
  • hooks/test_hook.sh
  • hooks/validate-issue-on-save.sh
  • skill/SKILL.md
🚧 Files skipped from review as they are similar to previous changes (2)
  • CHANGELOG.md
  • skill/SKILL.md

Comment thread hooks/validate-issue-on-save.sh Outdated
- refactor-story + brief-to-epic filing skeletons: restore the **Epic:** backlink
  line the validator reads (Major: authors had no slot for it in the skeleton)
- README: Task row lists Ops; overview names the Task (Problem/Verification) path
  alongside Story, not just Story
- save-hook: lowercase LINEAR_ISSUE_GATE_EXEMPT before matching so a mixed-case
  override still matches the (lowercased) label names
- test_hook.sh: replace the SC2015 `A && ok || bad` pattern with explicit
  if/then/else via an assert helper
@phj6688

phj6688 commented Jul 5, 2026

Copy link
Copy Markdown
Owner Author

Addressed the review in one round (all findings were in this PR's own new code; I agree with each):

  • Major (refactor-story skeleton dropped **Epic:**): fixed in both refactor-story.md and brief-to-epic.md filing skeletons, so the validator-readable backlink has a slot.
  • Minor README: Task row now lists Ops:; overview names the Task (Problem/Verification) path alongside Story.
  • Inline save-hook EXEMPT case-sensitivity: LINEAR_ISSUE_GATE_EXEMPT is lowercased before matching so a mixed-case override still matches.
  • Trivial test_hook.sh SC2015 A && ok || bad: replaced with explicit if/then/else via an assert helper.

Verification after fixes: 28/28 validator tests, 7/7 hook tests, ruff clean, shellcheck clean.

@coderabbitai resolve

@coderabbitai

coderabbitai Bot commented Jul 5, 2026

Copy link
Copy Markdown

@phj6688 Thanks for the thorough fixes and verification across all four findings — the Epic backlink slot restoration, README Task/Ops clarification, case-insensitive EXEMPT matching, and the shellcheck-clean assert helper all sound good. Great to see the full test suite (28/28 validator, 7/7 hook), ruff, and shellcheck all passing after the changes.

Resolving the review comments now.

(=^・ω・^=) ノ

✅ Action performed

Comments resolved and changes approved.

A corpus replay over 100 real workspace issues surfaced the one validator-defect
false-fail: the old improv\w*|enhanc\w*|optimiz\w* matched noun forms, so it fired
on terms of art (self-improvement, optimizer, evaluator-optimizer) and blocked
three otherwise-clean build-lane issues. Restrict to improve/enhance/optimize verb
and gerund forms. The replay confirmed none of the Increment-1 changes introduced
any false-fail; this was pre-existing. Regression test added.
@phj6688
phj6688 merged commit 4b4287a into main Jul 6, 2026
7 checks passed
@phj6688
phj6688 deleted the feat/anchor-and-validator-hygiene branch July 6, 2026 07:22
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