Skip to content

feat(ci): adopt fleet issue-template + priority-enforcement pattern#38

Merged
justin-layerv merged 3 commits into
mainfrom
feat/ci-issue-templates-fleet-rollout
Apr 24, 2026
Merged

feat(ci): adopt fleet issue-template + priority-enforcement pattern#38
justin-layerv merged 3 commits into
mainfrom
feat/ci-issue-templates-fleet-rollout

Conversation

@justin-layerv
Copy link
Copy Markdown
Contributor

Summary

Ports the structured issue-forms + reusable-workflow shim pattern from layervai/qurl-service#358, layervai/qurl-integrations#114, and layervai/qurl-typescript#45 to qurl-python.

Business value

  • Faster triage. Required Priority dropdown + Python-version / package-version fields replace free-text markdown.
  • Fleet consistency. Same rubric, same reusable workflows, same pin shape across the whole org.
  • Fewer silent breakages. validate-issue-templates.yml catches schema-broken forms at PR time.

Per-repo derivation

  • No Component dropdown. qurl-python's commit format is <type>: <description> (no scopes), identical to qurl-typescript. A dropdown would be noise.
  • Python version required (paste from python --version).
  • Package version required — published to PyPI as layerv-qurl (run pip show layerv-qurl).
  • Logs field expects a Python traceback, no render: to avoid miscoloring.
  • Redaction hint calls out lv_live_* API keys — reporters likely use production keys against the SDK.
  • No Discussions link. Discussions is not enabled on this repo.

What changed

  • .github/ISSUE_TEMPLATE/bug_report.yml + feature_request.yml (replacing .md).
  • .github/ISSUE_TEMPLATE/config.yml: blank_issues_enabled: false + GHSA link.
  • .github/workflows/issue-priority.ymlops-routines-workflows@v0.3.0.
  • .github/workflows/validate-issue-templates.ymlops-routines-workflows@v0.4.0. No caller-side concurrency blocklayervai/ops-routines#39.

Priority labels + bug + enhancement already exist on this repo.

Test plan

  • validate-issue-templates.yml runs green on this PR
  • check-jsonschema + actionlint pass locally
  • Post-merge: file a test issue, confirm Priority dropdown is required and priority: * auto-applies

Fleet rollout

Fourth of ~8 active repos. Completes wave 1 (qurl-service / qurl-integrations / qurl-typescript / qurl-python — Go / Node / Python shakedown).

justin-layerv and others added 2 commits April 23, 2026 19:26
Ports the structured issue-forms + reusable-workflow shim pattern from
layervai/qurl-service#358, qurl-integrations#114, and qurl-typescript#45
to qurl-python. Reporters land on a required Priority dropdown,
Python-shaped fields (package version, Python version, traceback-
aware logs field), and `lv_live_…` redaction hints.

Changes:
- Replace `.md` issue templates with `.yml` forms. No Component
  dropdown — qurl-python's commit format has no scopes (same shape
  as qurl-typescript). Package version + Python version + OS carry
  the real triage signal.
- `config.yml` disables blank issues and adds a GHSA contact link.
  Discussions is not enabled on this repo, so no link there.
- Add `issue-priority.yml` → ops-routines-workflows@v0.3.0 and
  `validate-issue-templates.yml` → ops-routines-workflows@v0.4.0.
  The validate shim has NO caller-side concurrency block (reusable
  self-collision bug, tracked as layervai/ops-routines#39).

Priority labels + `bug` + `enhancement` already exist on this repo;
no label creation needed.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Drop double space before v0.4.0 comment on the validate shim's
`uses:` line. Cosmetic fleet-consistency fix flagged by cr on
qurl-typescript#45.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@claude
Copy link
Copy Markdown

claude Bot commented Apr 24, 2026

Review — looks good to merge

Thoughtful infrastructure change. Defense-in-depth reasoning in the YAML comments is genuinely useful — these are the kind of comments I'd expect a future maintainer to thank the author for. A few observations; none block.

What's done well

  • SHA-pinned reusables with version annotations (@5f1eb1a… # v0.3.0, @39fcb54f… # v0.4.0). Correct pin shape.
  • Least-privilege permissions: workflow-level contents: read, job-scoped issues: write only where needed.
  • Recursion guard is layered: outer if: github.actor != 'github-actions[bot]' + reusable's inner sender.type != 'Bot' + GitHub's own GITHUB_TOKEN suppression. Comment correctly acknowledges the trade-off that a future PAT/App-token swap could bypass GITHUB_TOKEN suppression but this caller guard still holds.
  • Concurrency asymmetry is explained, not just left as drift. issue-priority.yml has a caller-side block mirroring the reusable's literal-prefix group; validate-issue-templates.yml deliberately omits it because the reusable uses github.workflow (would self-collide — cross-refs layervai/nhp#1307 and tracked at layervai/ops-routines#39). This is exactly the right way to leave a workaround: annotated and linked to the upstream fix.
  • blank_issues_enabled: false + validate-templates shim closes the silent-breakage hole (malformed form → issue creation disappears from UI). Good pairing.
  • Rubric phrasing is form-aware: critical-for-bug describes harm from a defect; critical-for-feature describes unblocking delivery / compliance gap. The inline comment calling this out is the right place for it.
  • lv_live_* redaction hint is SDK-appropriate — production-key pattern, not generic boilerplate.
  • No render: on the logs field with justification. Agree — render: shell miscolors Python tracebacks.

Minor observations (non-blocking)

  1. Required-field count in bug_report.yml: priority + description + reproduction + expected + actual + package version + python version = 7 required fields. That's on the higher end; some reporters will abandon. Fleet consistency is the overriding concern so I wouldn't change it, but worth knowing if triage ever sees a drop in issue volume after merge.
  2. os is optional while python_version and package version are required. Reasonable for a pure-Python SDK where OS rarely matters, but worth a one-line rationale comment if the asymmetry was deliberate (matches the style of the other comments in this file).
  3. Bot-opener exemption side effect is correctly documented in the inline comment. Release Please (if it ever files issues, which it doesn't today) would author as github-actions[bot] and hit this exemption — the comment's "not sticky, re-engages on human edit" line is accurate and covers the concern.
  4. Test plan item 1 already satisfied: validate-templates / validate-templates is green on this PR per check status — can be ticked.

Security / correctness

  • No secrets, no external action usage beyond the org's own reusables. Permissions are minimal. SHA pins prevent tag-mutation supply-chain risk.
  • blank_issues_enabled: false is a UI-level guard only; API-filed issues still materialize and hit the enforcement path. The config.yml comment correctly acknowledges this.

Test coverage

N/A for workflow/template changes. check-jsonschema + actionlint + the reusable validator cover the schema dimension; post-merge smoke test (filing a real issue) is the right manual verification for the runtime-priority path.

LGTM.

@claude
Copy link
Copy Markdown

claude Bot commented Apr 24, 2026

Review — looks good to merge

This is a well-scoped, well-documented CI/infra PR. The reasoning comments in each workflow file are unusually thorough and make the config readable to whoever touches it next. No blocking issues.

Strengths

  • SHA-pinned reusables with version comments (@<sha> # v0.3.0 / v0.4.0) — correct shape for supply-chain safety, and consistent with what the fleet uses.
  • Minimal permissions: workflow-level contents: read, job-level issues: write only where needed.
  • Anti-recursion guard at both the caller (if: github.actor != 'github-actions[bot]') and (per your comment) in the reusable — good defense-in-depth against a future ref bump silently dropping the reusable-side check.
  • cancel-in-progress: false with a written rationale tied to the failure mode (cancelled run leaving an issue unlabeled → tripping the enforcement fail path). Exactly the right call given the 2-min runtime bound.
  • No caller-side concurrency on validate-issue-templates.yml with the linked root cause (layervai/ops-routines#39) — saves the next person from re-hitting that footgun.
  • Security redirect at the top of bug_report.yml is prominent and matches the existing SECURITY.md. The GHSA URL in config.yml is the correct path for this repo.
  • Logs field without render: — good call; render: shell really does miscolor Python tracebacks.

Minor observations (non-blocking)

  1. github-actions[bot]-filed issues are exempt from priority enforcement at open time. Your comment in issue-priority.yml:44-49 already calls this out and notes it's not sticky (human edited/labeled re-engages enforcement). Just confirming this is a deliberate trade-off you've accepted — fine as-is.

  2. bug_report.yml:84-85 — inline YAML comment inside the attributes: block is valid but unusual placement. Some YAML linters have been picky about this historically. check-jsonschema doesn't care, but if you ever add a stricter formatter this is the kind of thing it might flag. Not worth moving.

  3. Package-version placeholder (e.g. 0.1.0) is fine, but note that layerv-qurl is pre-1.0 and the placeholder will feel stale once you cut a 0.2 or 1.0 release. A generic e.g. 0.3.2 or dropping the placeholder entirely avoids future churn. Trivial.

  4. feature_request.yml intentionally has no logs / version fields — appropriate for a feature form, matches the rubric where critical-for-feature describes absence not harm. Your inline comment at lines 8-13 makes this explicit. Nice.

  5. Test plan still shows validate-issue-templates.yml runs green on this PR unchecked — worth confirming in the Checks tab before merge, since that's the whole point of adding the validator in the same PR as the forms it validates.

Security

  • No pull_request_target usage, no untrusted-input interpolation into shell, no secrets exposure. Workflows touch only issue metadata. ✅
  • SHA pins on both reusables. ✅

Test coverage

N/A — CI/infra change with no runtime code. The validate-issue-templates.yml check is itself the test surface for the forms.

Style / conventions

Matches the repo's CLAUDE.md (no scoped commits — PR title feat(ci): ... is a Conventional Commit scope, which Release Please will happily consume as a feat). No changes to Python source, so ruff/mypy/pytest are not impacted.

LGTM.

cr round 1 nit on #38: `e.g. 0.1.0` placeholder will rot once Release
Please cuts 0.2.x / 1.0.x. Generic `0.3.x` matches the drift-proofing
pattern landed in qurl-service#358 for the Go version placeholder.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@justin-layerv
Copy link
Copy Markdown
Contributor Author

Round 1 feedback addressed:

  1. Acknowledged — bot exemption is a deliberate trade-off; documented in the shim's if: comment.
  2. Acknowledged — YAML comment in attributes: is accepted by check-jsonschema; leaving unless a stricter formatter flags it.
  3. Package version placeholder (540217e): 0.1.00.3.x. Drift-proofed for future Release Please bumps (matches qurl-service#358's Go version fix).
  4. Acknowledged — feature form intentionally lacks logs/version; the critical rubric is absence-shaped.
  5. validate-templates / validate-templates shows SUCCESS on this PR — ticking the checkbox in the test plan.

@claude
Copy link
Copy Markdown

claude Bot commented Apr 24, 2026

Code Review

Thorough PR — the defensive comments in the workflow shims are genuinely useful and explain why, not what. A few observations, all minor:

Strengths

  • SHA-pinned reusables with version comments (@5f1eb1a… # v0.3.0, @39fcb54… # v0.4.0) — correct supply-chain hygiene.
  • Per-repo derivation section in the PR body documents why this shim differs from sibling repos. That's the kind of context that otherwise gets lost.
  • Comments explain the failure modes they're guarding against (label-event recursion, mid-flight cancellation leaving issues unlabeled, caller-side concurrency colliding with itself on the validate-issue-templates reusable). Mirroring the dependency-age-check-pip.yml shim convention is the right call.
  • SECURITY.md exists — the config.yml contact link and bug_report.yml banner both resolve correctly.
  • render: omission on logs is correctly justified — Python tracebacks + render: shell would miscolor, and the inline comment says exactly that.

Observations / Minor Questions

  1. issue-priority.yml triggers on labeled / unlabeled. The bot-actor guard (github.actor != 'github-actions[bot]') prevents recursion from the reusable's own labeling, but a human manually removing a priority: * label will re-trigger enforcement — which I assume is intended (forces re-priority). Worth confirming that's the designed behavior vs. accidental side effect. The comment suggests this is deliberate.

  2. bug_report.yml title prefix [BUG] combined with the bug label is slightly redundant, but consistent with the fleet pattern per the PR description. Non-blocking.

  3. feature_request.yml has no Python-version / package-version fields. Correct — feature requests aren't environment-dependent. Noting it only because the asymmetry with bug_report.yml is easy to miss on scan.

  4. validate-issue-templates.yml on.push includes main in addition to pull_request. This gives you a safety net if a form is merged that somehow passed PR-gate (e.g. merge-queue race with another PR touching the schema). Reasonable belt-and-braces; no change needed.

  5. Priority dropdown has no default option. Intentional per the "required" validation — users must actively choose rather than accepting a silent default. Good.

Potential Issues

  • None blocking. The blank_issues_enabled: false + required Priority + fleet enforcement workflow combination is well-constructed. The comment in config.yml correctly identifies that the UI block + enforcement-workflow fail-path are complementary defenses for different failure modes (UI-created vs API-created).

Test Coverage

  • validate-issue-templates.yml will self-test on this PR — the checkbox in the test plan covers it.
  • Post-merge test-issue filing is the right manual verification for the enforcement path; can't be exercised pre-merge because workflow changes don't run against PR refs for issues events.

CLAUDE.md Compliance

  • No Python source changes, so ruff / mypy / pytest don't apply.
  • No direct push to main; PR from feat/ci-issue-templates-fleet-rollout. ✓
  • Title follows conventional-commit format (feat(ci): …). ✓

LGTM pending the green validate-issue-templates run and the post-merge test-issue verification listed in the test plan.


🤖 Review by Claude (Opus 4.7)

@justin-layerv justin-layerv self-assigned this Apr 24, 2026
@justin-layerv justin-layerv merged commit 133aad8 into main Apr 24, 2026
12 checks passed
@justin-layerv justin-layerv deleted the feat/ci-issue-templates-fleet-rollout branch April 24, 2026 03:35
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