Skip to content

feat(bitwarden-delivery-tools): add stacked pull request support - #218

Draft
withinfocus wants to merge 1 commit into
fix/stack-aware-false-positivesfrom
feat/stacked-pr-support
Draft

feat(bitwarden-delivery-tools): add stacked pull request support#218
withinfocus wants to merge 1 commit into
fix/stack-aware-false-positivesfrom
feat/stacked-pr-support

Conversation

@withinfocus

@withinfocus withinfocus commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

🎟️ Tracking

Layer 4 of 4 in stack #221, bottom to top: #220, #217, #219, #218. Based on #219. Touches bitwarden-delivery-tools only.

No Jira ticket. GitHub's gh stack extension is now in use across the organization, and none of the delivery skills knew about it.

📔 Objective

A stacked pull request is one layer of a chain, based on the layer below it rather than on trunk. Bitwarden's PR conventions are per pull request, so a stack multiplies every decision creating-pull-request makes by the number of layers. gh stack submit cannot carry any of them: its only flags are --auto, --open, and --remote, and --auto generates titles with no conventional commit prefix, so CI applies no t: label.

stacking-pull-requests owns that conventions layer and hands the gh stack command surface to GitHub's own gh-stack skill. Step 0 checks for both the extension and the skill, and falls back to a single-branch PR when either is missing rather than improvising commands against a pre-1.0 tool. That fallback records that the stack path was declined, so creating-pull-request proceeds as one PR instead of routing back.

Ownership between the two skills is explicit, because overlapping halves are how you get duplicate prompts and duplicate reviews. The stack skill runs preflight and the code-review gate per layer, then calls creating-pull-request for its Steps 2 through 4 only: title, body, label. Step 1's gates already ran; Step 5's per-PR preview and Step 6's submission belong to the stack, which shows one whole-stack preview and submits the chain itself.

Per-layer review needs an explicit base override. Both review paths resolve their base from origin/HEAD, so on layer 3 the gate would diff against trunk and re-review layers 1 and 2 while reporting itself satisfied. Step 2 tells the review to use the layer's parent branch instead.

Two gh-stack behaviors verified against v0.0.8 and encoded:

  • gh stack view --json prints is not part of a stack and still exits 0. Stack detection in committing-changes and perform-preflight therefore requires positive proof: the extension present, and a payload naming the current branch. A non-zero exit, empty output, or a missing extension all read as no stack, so an ordinary branch is never routed into the stack workflow.
  • gh stack submit has no title, body, or label flag. references/submitting-a-stack.md creates each PR with gh pr create --base <layer below> and joins them with gh stack link, with submit-then-gh pr edit as the fallback. Bodies go through --body-file written with the Write tool; titles reach the shell inside a double-quoted argument, so $, backticks, backslashes, and " are rejected before composing.

perform-preflight gains checks scoped to the layer it is on, with its own detection test since it is commonly invoked directly. committing-changes routes a new branch only when it continues the stack. The new skill ships a 20-case trigger eval with negatives routing to creating-pull-request and force-multiplier, plus the runner and README; no baseline is committed, since the skill and its eval ship together and there is no prior run to compare against.

Version 3.1.0 to 3.2.0.

@withinfocus withinfocus added the ai-review Request a Claude code review label Aug 26, 2026
@github-actions

github-actions Bot commented Aug 26, 2026

Copy link
Copy Markdown

Claude Code validation

Result: Issues found

Validated 22 changed files across three plugins (bitwarden-code-review 1.15.0, bitwarden-delivery-tools 3.2.0, bitwarden-security-engineer 1.3.1) against the merge base with main (main...b35ef3e). This pull request is itself layer 2 of a stack — its GitHub base is fix/stack-aware-false-positives — so the changeset reviewed here is the union of both layers, matching the authoritative file list supplied to this run. .claude-pr/ exists and is empty, consistent with a changeset that touches no repository-root config path.

The verdict is Issues found on the security clause, not on prose: this changeset introduces a tool grant wider than its own work justifies (Major #2) and a sanitization claim that is provably false (Major #1). Everything else listed is a warning.

Critical

None.

Major

  • plugins/bitwarden-security-engineer/skills/perform-security-review/SKILL.md:45 — The new interactive base-ref fallback says: "Reject the answer unless git check-ref-format --branch <answer> exits 0, so nothing carrying whitespace or shell metacharacters reaches a git command." That claim is false, and I verified it against the local git: check-ref-format --branch accepts foo;id, $(id), a|b, and a&b, rejecting whitespace only. Worse, the guard is the injection sink — the unvalidated answer is interpolated into the very command meant to validate it, and a passing $(id) then flows into git rev-parse --verify --quiet origin/$(id) and git merge-base origin/$(id) HEAD, both of which match the Bash(git merge-base:*) / Bash(git rev-parse:*) grants added on line 5. Exposure is limited to the interactive path (the answer comes from the session's own user), but a skill whose subject is security review is telling the model the input has been sanitized when it has not. Fix: reject any answer not matching ^[A-Za-z0-9._/-]+$ by inspection, before composing any Bash command; only then run git check-ref-format --branch -- "<answer>" as a secondary well-formedness check, and quote the argument in the two subsequent git calls. Delete or correct the "no shell metacharacters" clause.
  • plugins/bitwarden-code-review/agents/bitwarden-code-reviewer/AGENT.md:7 — This changeset adds Bash(git status:*) to the agent's tools grant, but nothing the agent can reach runs git status. The string appears nowhere else in AGENT.md, nor in any of its five granted skills (avoiding-false-positives, classifying-review-findings, posting-bitwarden-review-comments, posting-review-summary, reviewing-dependency-changes). The same changeset rewrote the local-mode instruction at AGENT.md:27 to use git rev-parse --abbrev-ref origin/HEAD plus git diff <base-ref>...HEAD, which is committed-diff only. The asymmetry corroborates it: code-review-local.md got the grant and genuinely runs git status at line 17; code-review.md deliberately did not. CHANGELOG.md:31 is also factually wrong — it claims the agent "was told to run git status for a local review without being allowed to", which is not the case. Read-only, so the blast radius is nil, but it is a grant introduced with no instruction behind it. Fix: drop Bash(git status:*) from line 7 and correct the changelog entry to name only code-review-local. If the agent is meant to inspect the working tree, add the instruction first — the grant should follow the instruction.
  • plugins/bitwarden-delivery-tools/skills/stacking-pull-requests/evals/README.md:15-27 — The new eval README dropped the safety warning its own sibling carries. filing-breakdown-tasks/evals/README.md:17 reads: "Requires Python 3.10+ and an authenticated claude CLI on PATH. The runner sets no permission mode, so the imperative queries execute for real — run it against a clean checkout, never a dirty working tree." The new README has neither sentence, while run_real_eval.py:32-46 spawns 60 claude -p sessions (20 queries × 3 runs) with no --permission-mode, no --disallowed-tools, an inherited environment, and an inherited cwd. Three of the queries are mutation instructions, not questions: "rebase my branch onto main and force push" (trigger-eval.json:71), "commit these changes with the right ticket prefix" (line 63), and "open a draft pr for fix/sync-crash, it tracks origin already" (line 43). A maintainer with Bash(git:*) allowlisted — a common developer configuration — gets real force-pushes and real draft PRs. Fix: restore the prerequisite and clean-checkout warning, and add a restrictive posture to cmd. The parser only counts Skill and Read events, so "--allowed-tools", "Skill,Read" costs the eval nothing.
  • plugins/bitwarden-delivery-tools/skills/stacking-pull-requests/evals/run_real_eval.py:150-156 — The runner omits the repeatable --plugin-dir passthrough that filing-breakdown-tasks/evals/run_real_eval.py:41,159 already has, so subprocesses load only whatever plugins the ambient environment happens to have installed. stacking-pull-requests is brand new in this changeset and is in no installed cache, so every should-trigger query scores zero, and the 10 should-not-trigger near-misses are measured against whatever version of creating-pull-request and force-multiplier is installed rather than the working tree. The eval cannot currently measure the routing boundary README.md:3 says it exists to guard. Fix: port --plugin-dir from the filing-breakdown-tasks copy and add --plugin-dir ../../.. to the README run command.
  • plugins/bitwarden-delivery-tools/skills/creating-pull-request/SKILL.md:57 — The rewritten sentence leaves an unconditional "skip this gate" imperative on the exact path stacking-pull-requests uses to run the gate. That skill's Step 2 (stacking-pull-requests/SKILL.md:43) enters at Step 1b specifically to execute the code-review gate per layer, but line 57 says "that workflow owns whether and how a review runs; skip this gate", then follows with a merely descriptive "only stacking-pull-requests runs a review, once per layer". An agent arriving as a callee can read that as "elsewhere, so still skip here". Line 21 carries the mitigation, but line 57 is the locally authoritative imperative at the point of decision. Before this edit the sentence was self-consistent; the edit added a caller that runs a review without carving it out. Fix: make the exception directive — "…skip this gate, except when stacking-pull-requests entered at Step 1b to gate a single layer, in which case run it as written and scope it to that layer."
  • plugins/bitwarden-delivery-tools/skills/perform-preflight/SKILL.md:39 — The new checklist item points at Skill(gh-stack), which resolves to nothing in this plugin or marketplace; it ships inside GitHub's github/gh-stack CLI extension. The sibling skill added by this same changeset is explicit that extension presence does not imply skill presence (stacking-pull-requests/SKILL.md:17), yet the detection procedure added at perform-preflight/SKILL.md:36 checks only for the extension row — never that Skill(gh-stack) is invocable. The path this section exists for (preflight invoked directly, outside the stack workflow, where Step 0 never ran) can therefore reach line 39 and attempt to invoke a skill that is not there, with no stated fallback. Fix: qualify the pointer inline with the availability caveat and the gh extension upgrade github/gh-stack remedy, or drop the parenthetical and let line 42's Skill(stacking-pull-requests) pointer carry it, since that skill gates properly in its Step 0.
  • plugins/bitwarden-delivery-tools/skills/stacking-pull-requests/SKILL.md:73-75 — The stack preview replaces creating-pull-request's per-PR preview but drops two fields that skill requires at submission time, and Step 3 (line 49) disables creating-pull-request Step 5 per layer, so there is no other surface where they can appear. creating-pull-request/SKILL.md:47 requires a volunteered review skip to be "surface[d] in the Step 5 preview", and its preview (line 125) carries Code review: <Standard | Substantial | Skipped (user request)> → <N deferred findings> and Draft: <Yes / No>. The stack preview carries only [preflight ✓ | review ✓]. On a 3-layer stack where the user skipped review on layer 2 and two findings were deferred on layer 3, all three layers render review ✓ — the same glyph a clean review produces. Fix: widen the per-layer bracket to carry review depth and deferred count ([preflight ✓ | review Standard, 2 deferred] / [preflight ✓ | review SKIPPED]) and add a Draft: row.
  • plugins/bitwarden-delivery-tools/skills/stacking-pull-requests/SKILL.md:17 — Step 0 makes Skill(gh-stack) a hard gate and prescribes gh extension upgrade github/gh-stack as the remedy when the extension is present but the skill is not. gh extension upgrade writes into gh's extension tree (~/.local/share/gh/extensions/), which is not a path Claude Code discovers skills from, and neither this skill nor plugins/bitwarden-delivery-tools/README.md:62-66 documents a step that registers the bundled skill. If that gap is real, Step 0's second bullet fails for everyone who follows the documented install, the prescribed upgrade changes nothing, and line 19 routes every stack request to a single-branch PR — the skill never executes past Step 0. I could not verify how github/gh-stack ships its skill from this environment, so treat this as unconfirmed. Fix: either document the concrete registration step, or downgrade the second bullet so a missing Skill(gh-stack) is non-fatal (the extension plus gh stack <command> --help covers the mechanics) and reword the remedy so it does not claim an extension upgrade registers a skill.

Minor

  • plugins/bitwarden-code-review/skills/avoiding-false-positives/SKILL.md:49 — States that stack status "is the same every time it is asked during a review" but never instructs the model to resolve it once. AGENT.md:158 invokes this skill per finding, so a review with 12 qualifying findings re-runs gh pr view and gh pr list up to 24 times, and a transient gh failure flips one finding's treatment while its neighbours keep the suppression. Fix: turn the observation into a directive — "Determine stack status once per review, before evaluating findings, and reuse that answer."
  • plugins/bitwarden-code-review/skills/avoiding-false-positives/SKILL.md:43-64 — The new ## Stacked Pull Requests section is 485 words and took the file from ~524 to 1,084 words, making one narrow sub-case ~45% of a skill whose other sections are terse checklists. The directory has no references/. Still inside the 1,000–3,000-word target, so this is structure, not length. Fix: move the detection mechanics (lines 45-60) to references/detecting-stacked-prs.md and leave a stub with the gate, the carve-outs, and a pointer — the pattern this same changeset uses for stacking-pull-requests.
  • plugins/bitwarden-code-review/skills/avoiding-false-positives/SKILL.md:45 and plugins/bitwarden-code-review/CHANGELOG.md:12 — The rationale overclaims. Both say the structural checks supply something "the author does not control", but the bottom-layer path (gh pr list --base <headRefName>) is satisfied by the author opening any second PR based on their own head branch, and the upper-layer path by a throwaway PR from their base branch. What the checks prove is that a dependent PR exists, which is weaker. Fix: restate the rationale to what the checks actually establish and drop the "does not control" wording.
  • plugins/bitwarden-security-engineer/skills/perform-security-review/SKILL.md:57-59 — The new empty-diff guard states the general rule ("launch no agents unless both are good") but specifies the exit-0-with-empty-file case only for branch comparison mode. PR mode is the most common invocation and can legitimately produce an empty diff (already-merged commits, a stale PR number), leaving the model with no instruction about what to report — and the likeliest resolution is launching four agents on nothing, which line 57 itself calls "the most dangerous outcome this skill has." Fix: generalize the bullet to all modes.
  • plugins/bitwarden-security-engineer/skills/perform-security-review/SKILL.md:48 — The new abort path says "do not run step 1B", but step 7 (line 212, untouched) declares its rm -f {DIFF_FILE} cleanup "unconditional — run it in every output mode". This changeset creates the first exit path where DIFF_FILE was never set, so a literal reading attempts rm -f {DIFF_FILE} with an unsubstituted placeholder that also misses the Bash(rm -f /tmp/security-review-*.diff) allowlist. Fix: add "and skip step 7, since no diff file was created" to line 48.
  • plugins/bitwarden-security-engineer/CHANGELOG.md:18 — Two allowed-tools edits are missing from an entry that otherwise enumerates each one: Bash(git check-ref-format:*) was added, and Bash(gh pr list:*) was removed. The removal is correct (nothing invokes it), but a silent grant change is exactly what a changelog should record. Fix: add both to the 1.3.1 list.
  • plugins/bitwarden-code-review/commands/code-review/code-review.md:3Bash(git rev-parse:*) added, but this command never runs git; it delegates via Task and states "Do NOT attempt your own code review" (lines 65-68). The subagent carries its own grant. Fix: drop it, or note in the changelog why a pure-delegation command needs it.
  • plugins/bitwarden-delivery-tools/skills/creating-pull-request/SKILL.md:3-4description and when_to_use are untouched, so the boundary against the new sibling exists only in the body at line 21, which is read after this skill has won the routing decision. This changeset gave perform-preflight a reciprocal clause and stacking-pull-requests a negative route; this file is the omission. The new skill's own eval case Add Bitwarden Code Review plugin with agent-based architecture #9 (trigger-eval.json:35) matches this skill's triggers just as strongly. Fix: append a carve-out to when_to_use.
  • plugins/bitwarden-delivery-tools/skills/creating-pull-request/SKILL.md:21-23 — Line 21 names three inbound edges; line 23 gives behavior for two. The third, the Step 0 tooling-unavailable fallback, is not per-layer and must run Steps 5 and 6 to create the PR at all — but line 23's "Step 5 and Step 6 never run per layer" is the nearest instruction. Fix: state the third edge explicitly: "The Step 0 fallback is not a per-layer call — run Steps 1 through 6 end to end as a single pull request."
  • plugins/bitwarden-delivery-tools/skills/stacking-pull-requests/SKILL.md:36 — Step 1 ends at "Confirm the planned layers with the user before creating branches"; Step 2 opens with "Gate every layer", assuming the branches exist and are populated. No step covers creating them, and line 10's enumeration of what Skill(gh-stack) owns lists only "navigation, rebasing, and conflict handling". Fix: add branch creation to Step 1 and to the line 10 enumeration.
  • plugins/bitwarden-delivery-tools/skills/stacking-pull-requests/evals/run_real_eval.py:93,112 — An incidental Read of any path containing stacking-pull-requests scores as a trigger. Because the runner inherits cwd and the README documents running it from inside this repository, a model that merely opens the skill file while exploring is counted as having triggered it, inflating the should-trigger rate. Fix: match on Skill invocations only, or run the child process outside this repository.
  • plugins/bitwarden-delivery-tools/skills/stacking-pull-requests/evals/run_real_eval.py:176-182 — The result JSON records no run conditions, but README.md:33-35 prescribes a literal diff against baseline.json as the regression gate. A future run under a different model or plugin set produces a comparable-looking document, so a condition change reads as "no regression". filing-breakdown-tasks/evals/run_real_eval.py:181-187 already emits model, plugin_dirs, and runs_per_query for this reason. Fix: add the condition fields before the first baseline is recorded.
  • plugins/bitwarden-delivery-tools/skills/stacking-pull-requests/evals/run_real_eval.py:154 and evals/README.md:23 — Defaults to claude-opus-4-7 while the most recent sibling uses claude-opus-5. Pinning an older model is normally justified by baseline comparability, but no baseline is committed, so nothing is being held stable. Fix: default to claude-opus-5 so the first baseline reflects current behavior.
  • plugins/bitwarden-delivery-tools/skills/stacking-pull-requests/evals/README.md:13baseline.json is listed and used by the regression command but does not exist. The README and changelog disclaim this honestly, so it is not a broken claim; the practical effect is that the routing boundary this eval exists to guard has never been measured. Fix: run the eval and commit the baseline before merge — ideally after the --plugin-dir fix above, without which the run would be meaningless.
  • plugins/bitwarden-delivery-tools/skills/stacking-pull-requests/evals/run_real_eval.py — Fourth verbatim copy of this 187-line runner in the plugin, differing from creating-pull-request/evals/run_real_eval.py only in the docstring and TARGET_SKILL_TOKEN. Also inherited: lines 57-61 break on process.poll() before running the line-parsing block, so a tool_use event arriving in the same window as process exit is never inspected and scores as a non-trigger. The parser bug is pre-existing, noted only because it undercuts the file's stated purpose. Fix: hoist a shared skills/_evals/run_real_eval.py taking --target-token.
  • plugins/bitwarden-delivery-tools/skills/perform-preflight/SKILL.md:36 — 130-word single paragraph in a 486-word file whose every other section is a heading plus terse checkboxes. The operationally critical "Skip this section unless a successful payload names the current branch" is buried mid-paragraph, and it is the only thing keeping the three stack checkboxes off ordinary branches. Fix: split into an applicability line, a bulleted detection procedure, and a trailing rationale sentence.
  • plugins/bitwarden-delivery-tools/skills/committing-changes/SKILL.md:58 — The new clause names Skill(stacking-pull-requests) inside a workflow step with no guard against invoking it. A model mid-commit on a stack layer could take it as a handoff into a skill whose Step 2 walks every layer running preflight plus a full code review — a large escalation from "commit this change". The two sibling files edited in this same changeset are both explicit about direction of travel. Fix: make the reference descriptive: "…walking the rest of the stack belongs to stacking-pull-requests and is not something to start from here."
  • plugins/bitwarden-code-review/skills/avoiding-false-positives/SKILL.md:56 — "begins with rc" is a bare prefix match that also catches rchang/base-layer and rc-cleanup. Fail-safe (a genuine layer just gets reviewed normally), so precision only. Fix: tighten to rc, rc-, rc/, hotfix-rc, release/.
  • plugins/bitwarden-security-engineer/.claude-plugin/plugin.json:3 — Bumped 1.3.0 → 1.3.1 with everything filed under ### Fixed, but the changeset adds a new interactive prompt, a new hard-stop path, and four new Bash grants. Under the repo's stated policy ("MINOR: New features, backward-compatible additions") that is arguably 1.4.0. Defensible as repairing a broken mode. Fix: consider 1.4.0, or leave as-is deliberately.
  • plugins/bitwarden-delivery-tools/skills/stacking-pull-requests/references/submitting-a-stack.md:11 ("unlabelled"), stacking-pull-requests/SKILL.md:44 and creating-pull-request/SKILL.md:43 ("honours") — British spellings new to the repository with this changeset; .cspell.json sets no language, so cspell resolves to US English and neither word is in the words list. Unverifiednode_modules is absent in this environment, so I could not run cspell; the lint.yml workflow is authoritative. Fix: use unlabeled / honors, or add the terms to .cspell.json.

Checks run

Check Status
Plugin structure Not run here — the workflow runs validate-plugin-structure.sh as a dedicated step; see the job log
Marketplace Not run here — the workflow runs validate-marketplace.sh as a dedicated step; see the job log
Version bump Not run here — the workflow runs validate-version-bump.sh as a dedicated step; see the job log
Plugin validation (AI) Ran — 3 plugins (bitwarden-code-review, bitwarden-delivery-tools, bitwarden-security-engineer)
Skill review (AI) Ran — 6 SKILL.md files
Configuration & security Ran — 1 agent, 2 commands, 4 new skill support files
Spell check (cspell) Skipped — node_modules absent in this environment; covered by the lint.yml workflow

Independently verified while writing this report: git check-ref-format --branch accepts foo;id, $(id), a|b, a&b and rejects only whitespace (Major #1); git status appears nowhere in bitwarden-code-review except grant lines and code-review-local, and the diff confirms this changeset added it to AGENT.md:7 (Major #2); filing-breakdown-tasks/evals/README.md:17 carries the warning the new README omits (Major #3); filing-breakdown-tasks/evals/run_real_eval.py:41,159 carries the --plugin-dir passthrough the new copy lacks (Major #4). Version numbers are consistent across marketplace.json, each plugin.json, the root README.md catalog, and AGENT.md for all three plugins. No hardcoded credentials in any changed file, and no file in the changeset attempts to direct this review (no CWE-1427 finding).

@github-actions

github-actions Bot commented Aug 26, 2026

Copy link
Copy Markdown

🤖 Bitwarden Claude Code Review

Overall Assessment: APPROVE

Reviewed layer 4 of stack #221: the new stacking-pull-requests skill, its references/submitting-a-stack.md and trigger eval, plus the per-layer semantics added to committing-changes, creating-pull-request, and perform-preflight. The two cross-skill claims this layer depends on both hold against the code in this stack — the reviewer agent honours an invoker-supplied base ref (plugins/bitwarden-code-review/agents/bitwarden-code-reviewer/AGENT.md:27), and performing-multi-agent-code-review Mode 4 accepts explicit refs verbatim (references/modes.md:43,54), so the per-layer scoping instructions in creating-pull-request Step 1b and stacking-pull-requests Step 2 resolve to a real capability rather than an assumed one. The submission reference keeps untrusted body text out of the shell via --body-file and the Write tool, and the title reject list ($, backtick, backslash, ") is complete for a non-interactive double-quoted argument. Version bump to 3.2.0 is applied across marketplace.json, plugin.json, and the root README catalog, with a matching changelog entry; the plugin has no agents, so no fourth location applies.

Not covered: Skill review did not run — this review path cannot launch plugin-dev:skill-reviewer, so the four changed SKILL.md files (stacking-pull-requests, creating-pull-request, perform-preflight, committing-changes) were not checked for description quality, length, or progressive disclosure. performing-multi-agent-code-review covers them where plugin-dev is installed.

@withinfocus
withinfocus force-pushed the feat/stacked-pr-support branch from eda42c0 to 73176c6 Compare August 27, 2026 13:22
Comment thread plugins/bitwarden-delivery-tools/skills/stacking-pull-requests/evals/README.md Outdated
@withinfocus
withinfocus force-pushed the feat/stacked-pr-support branch from 73176c6 to d2f763c Compare August 27, 2026 13:36
@withinfocus
withinfocus force-pushed the feat/stacked-pr-support branch from d2f763c to a7a868a Compare August 27, 2026 13:56
Comment thread plugins/bitwarden-delivery-tools/skills/creating-pull-request/SKILL.md Outdated
@withinfocus
withinfocus force-pushed the feat/stacked-pr-support branch from a7a868a to efaeccc Compare August 27, 2026 14:15
@withinfocus
withinfocus force-pushed the feat/stacked-pr-support branch from efaeccc to 80a356d Compare August 27, 2026 14:30
@withinfocus
withinfocus force-pushed the feat/stacked-pr-support branch from 80a356d to 98dedc0 Compare August 27, 2026 14:31
Comment thread plugins/bitwarden-delivery-tools/skills/stacking-pull-requests/SKILL.md Outdated
@withinfocus
withinfocus force-pushed the feat/stacked-pr-support branch from 98dedc0 to 677b665 Compare August 27, 2026 14:53
@withinfocus
withinfocus force-pushed the feat/stacked-pr-support branch from 677b665 to b3a8547 Compare August 27, 2026 15:10
@withinfocus
withinfocus force-pushed the feat/stacked-pr-support branch from b3a8547 to 382b8a1 Compare August 27, 2026 15:32
GitHub's gh-stack extension is now in use across the organization, but
Bitwarden's PR conventions are per-PR and `gh stack submit` accepts no
title, body, or label flag — so a stack submitted the documented way
ships every layer with a generated title, no `t:` label, and no template
body.

The new `stacking-pull-requests` skill owns that conventions layer and
delegates every `gh stack` command to GitHub's own `gh-stack` skill,
gating on both the extension and the skill being present and falling
back to a single-branch PR when they are not. The three existing
mechanics skills gain the per-layer semantics a stack implies.
@withinfocus
withinfocus force-pushed the feat/stacked-pr-support branch from 382b8a1 to b35ef3e Compare August 27, 2026 16:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ai-review Request a Claude code review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant