Skip to content

Commit cda4e68

Browse files
dcramerclaude
andauthored
fix(github): Skip duplicate-check narration when creating issues (#117)
Add a guardrail to the GitHub skill that suppresses negative duplicate-search reporting (e.g. "no duplicates found") when the user explicitly asks to create an issue. The agent still searches for duplicates as part of its research, but only surfaces results when matches are actually found and are relevant. Additionally restructures the GitHub skill for clarity: - Merge `github-issue-api.md` into `api-surface.md` to eliminate duplicate command references - Add conditional reference loading table so the agent only loads files relevant to the current operation - Separate clone and issue paths into distinct workflow branches - Group guardrails by concern (execution, quality, scope) - Remove delegated footer instruction from SKILL.md (already in every template) Adds an eval to verify the dupe-narration behavior. Fixes #113 --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent ef109e8 commit cda4e68

4 files changed

Lines changed: 112 additions & 119 deletions

File tree

packages/junior-github/skills/github/SKILL.md

Lines changed: 60 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,24 @@ allowed-tools: bash
88

99
# GitHub Operations
1010

11-
Use this skill for GitHub issue workflows in the harness. Issues are the primary surface. Repository checkout is limited to `gh repo clone` guidance and execution when local code context is needed.
11+
Issue workflows and repository checkout via `gh` CLI.
12+
13+
## Reference loading
14+
15+
Load references conditionally based on the operation:
16+
17+
| Operation | Load |
18+
| ------------------ | -------------------------------------------------------------------------------------------------------------------------------------------- |
19+
| Any operation | [references/api-surface.md](references/api-surface.md) |
20+
| `clone` | [references/sandbox-runtime.md](references/sandbox-runtime.md) |
21+
| `create` | Type-specific template + research rules (see step 3) |
22+
| `create`, `update` | [references/issue-quality-checklist.md](references/issue-quality-checklist.md), [references/issue-examples.md](references/issue-examples.md) |
23+
| On failure | [references/troubleshooting-workarounds.md](references/troubleshooting-workarounds.md) |
24+
| Credential issues | [references/sandbox-runtime.md](references/sandbox-runtime.md) |
1225

1326
## Workflow
1427

15-
1. Confirm operation and target:
28+
### 1. Resolve operation and target
1629

1730
- Determine `clone`, `create`, `update`, `comment`, `labels`, `state`, or read-only inspection.
1831
- Resolve repository (`owner/repo`) and issue number for non-create issue operations.
@@ -21,19 +34,30 @@ Use this skill for GitHub issue workflows in the harness. Issues are the primary
2134
- If config exists and is valid `owner/repo`, use it as default.
2235
- If repository is still missing, ask the user for `owner/repo`.
2336

24-
2. Handle repository checkout first when operation is `clone`:
37+
### 2. Execute by operation type
38+
39+
**Clone** → Follow the clone path below.
40+
**Issue operation** → Follow the issue path below.
41+
42+
---
43+
44+
### Clone path
2545

26-
- Default to a shallow clone for local inspection or one-off edits:
46+
- Default to a shallow clone:
2747
- `gh repo clone owner/repo [directory] -- --depth=1`
2848
- Pass extra `git clone` flags only after `--`.
29-
- Use a full-history clone only when the task explicitly needs history-heavy operations such as `git blame`, `git bisect`, tag/release archaeology, or broad commit-log analysis.
30-
- If the initial shallow clone is insufficient, deepen incrementally instead of recloning:
49+
- Use full-history clone only when the task needs `git blame`, `git bisect`, tag/release archaeology, or broad commit-log analysis.
50+
- Deepen incrementally instead of recloning:
3151
- `git -C <directory> fetch --depth=<n> origin`
3252
- `git -C <directory> fetch --unshallow`
33-
- When cloning a fork, keep the default upstream remote behavior unless the user asks for a different remote name.
34-
- After checkout, report the local directory and whether the clone is shallow or full. Stop here for clone-only requests.
53+
- When cloning a fork, keep the default upstream remote behavior unless the user asks otherwise.
54+
- Report the local directory and whether the clone is shallow or full.
55+
56+
---
57+
58+
### Issue path
3559

36-
3. Classify issue type before drafting:
60+
#### 3. Classify issue type
3761

3862
- Use explicit user type when provided (`bug`, `feature`, `task`).
3963
- Otherwise infer from intent:
@@ -42,51 +66,53 @@ Use this skill for GitHub issue workflows in the harness. Issues are the primary
4266
- `task`: maintenance, cleanup, docs, refactor, operational chore.
4367
- Default to `task` when uncertain.
4468

45-
4. Draft issue content:
69+
#### 4. Draft issue content
70+
71+
Load the type-specific template and research rules:
72+
73+
| Type | Template | Research rules |
74+
| --------- | ---------------------------------------------------------------------------- | -------------------------------------------------------------------- |
75+
| `bug` | [references/issue-template-bug.md](references/issue-template-bug.md) | [references/issue-type-bug.md](references/issue-type-bug.md) |
76+
| `feature` | [references/issue-template-feature.md](references/issue-template-feature.md) | [references/issue-type-feature.md](references/issue-type-feature.md) |
77+
| `task` | [references/issue-template-task.md](references/issue-template-task.md) | [references/issue-type-task.md](references/issue-type-task.md) |
78+
79+
Follow [references/research-rules.md](references/research-rules.md) for cross-type research standards.
4680

47-
- Load the type-specific template:
48-
- `bug`: [references/issue-template-bug.md](references/issue-template-bug.md)
49-
- `feature`: [references/issue-template-feature.md](references/issue-template-feature.md)
50-
- `task`: [references/issue-template-task.md](references/issue-template-task.md)
51-
- Follow [references/research-rules.md](references/research-rules.md) and the type-specific research rules:
52-
- `bug`: [references/issue-type-bug.md](references/issue-type-bug.md)
53-
- `feature`: [references/issue-type-feature.md](references/issue-type-feature.md)
54-
- `task`: [references/issue-type-task.md](references/issue-type-task.md)
5581
- Generalize conversation context: replace user names, slash-command invocations, channel references, and session-specific fragments with the underlying technical problem.
5682
- Include code snippets when they clarify the problem pattern or proposed change.
5783
- Cross-reference related issues and PRs when they provide context.
58-
- For quality gates, use [references/issue-quality-checklist.md](references/issue-quality-checklist.md).
59-
- For structure examples, use [references/issue-examples.md](references/issue-examples.md).
60-
- When creating a new issue on behalf of a user, append a final attribution line at the end of the body in the form `Action taken on behalf of <name>.`
61-
- Use the clearest available user identifier from conversation context. Prefer a human name, then stable handle, and do not omit attribution for delegated mutations.
6284

63-
5. Execute operation:
85+
#### 5. Execute operation
6486

65-
- Select the matching declared capability for the operation:
87+
- Issue the matching capability credential before executing:
6688
- Read-only (`gh issue view`, comment reads via `gh api`): `github.issues.read`
6789
- Create/update/state changes: `github.issues.write`
6890
- Comments: `github.issues.comment`
6991
- Labels: `github.labels.write`
70-
- Repository checkout does not need a GitHub issue capability. Use `gh repo clone` directly.
7192
- Resolve command and flags from [references/api-surface.md](references/api-surface.md).
72-
- Execute using `gh` CLI directly. Use [references/github-issue-api.md](references/github-issue-api.md) for exact command shapes.
7393
- Use [references/common-use-cases.md](references/common-use-cases.md) for ready-to-run operation patterns.
74-
- If an operation fails, follow [references/troubleshooting-workarounds.md](references/troubleshooting-workarounds.md) before retrying.
75-
- Read [references/sandbox-runtime.md](references/sandbox-runtime.md) when you need the GitHub CLI credential delivery details.
7694

77-
6. Report result:
95+
#### 6. Report result
7896

79-
- Return canonical issue URL, issue number, issue type, applied changes, and confidence for issue workflows.
80-
- For clone operations, return the repository, local directory, clone mode (`shallow` or `full`), and any follow-up deepen/unshallow action taken.
97+
- Return canonical issue URL, issue number, issue type, applied changes, and confidence.
8198
- Include references used for verified claims.
8299

83100
## Guardrails
84101

102+
### Execution
103+
85104
- Execute operations as soon as required fields are available. Do not pause for confirmation unless the user explicitly asks for preview/dry-run.
86105
- Require explicit confirmation only for close/reopen or destructive broad rewrites.
87-
- Default to shallow clones for efficiency. Do not use a full clone unless the task requires repository history or the user asks for it.
106+
- Do not overwrite issue fields unless explicitly requested. Prefer partial updates over full body replacement.
107+
108+
### Quality
109+
88110
- Never claim verification without citing sources.
89111
- For `bug` issues, do not present a fix as definitive unless root-cause evidence is explicit.
90-
- Do not overwrite issue fields unless explicitly requested. Prefer partial updates over full body replacement.
112+
- Do not report negative duplicate-search results to the user (e.g. "no duplicates found"). Searching for duplicates is expected, but only mention duplicates when matches are actually found and are relevant to surface.
113+
114+
### Scope
115+
116+
- Issue workflows plus repository checkout only. Do not execute pull-request or repository admin mutations.
117+
- Default to shallow clones. Do not use a full clone unless the task requires repository history or the user asks for it.
91118
- If repository or installation access is missing, stop and return a concrete remediation message.
92-
- Scope is issue workflows plus repository checkout. Do not execute pull-request or repository admin mutations in this skill.
Lines changed: 36 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,41 @@
11
# GitHub CLI API Surface
22

3-
This skill supports issue workflows plus repository checkout via `gh repo clone`.
3+
All operations use `gh` CLI. Commands must be deterministic and non-interactive.
44

5-
All operations use `gh` CLI.
5+
## Authentication
6+
7+
- Preferred: sandbox network policy injects Authorization headers for `api.github.com`.
8+
- Optional local fallback: `GITHUB_TOKEN` (short-lived GitHub App installation token).
9+
- If `GITHUB_TOKEN` is a host placeholder value, rely on header transforms and do not override it.
610

711
## Capability to command mapping
812

9-
| Capability | Commands |
10-
| --- | --- |
11-
| none required | `gh repo clone` |
12-
| `github.issues.read` | `gh issue view`, `gh api /repos/.../comments` |
13-
| `github.issues.write` | `gh issue create`, `gh issue edit`, `gh issue close`, `gh issue reopen` |
14-
| `github.issues.comment` | `gh issue comment` |
15-
| `github.labels.write` | `gh issue edit --add-label/--remove-label` |
13+
| Capability | Commands |
14+
| ----------------------- | ----------------------------------------------------------------------- |
15+
| none required | `gh repo clone` |
16+
| `github.issues.read` | `gh issue view`, `gh api /repos/.../comments` |
17+
| `github.issues.write` | `gh issue create`, `gh issue edit`, `gh issue close`, `gh issue reopen` |
18+
| `github.issues.comment` | `gh issue comment` |
19+
| `github.labels.write` | `gh issue edit --add-label/--remove-label` |
1620

1721
## Command matrix
1822

19-
| Operation | Command |
20-
| --- | --- |
21-
| Clone repository (default shallow) | `gh repo clone owner/repo [DIRECTORY] -- --depth=1` |
22-
| Deepen shallow clone | `git -C DIRECTORY fetch --depth=N origin` |
23-
| Convert shallow clone to full | `git -C DIRECTORY fetch --unshallow` |
24-
| Create issue | `gh issue create --repo owner/repo --title "..." [--body-file PATH]` |
25-
| Update issue fields | `gh issue edit NUMBER --repo owner/repo [--title "..."] [--body-file PATH]` |
26-
| Close issue | `gh issue close NUMBER --repo owner/repo [--comment "..."]` |
27-
| Reopen issue | `gh issue reopen NUMBER --repo owner/repo` |
28-
| Add labels | `gh issue edit NUMBER --repo owner/repo --add-label LABEL [--add-label LABEL2]` |
29-
| Remove labels | `gh issue edit NUMBER --repo owner/repo --remove-label LABEL [--remove-label LABEL2]` |
30-
| Add comment | `gh issue comment NUMBER --repo owner/repo --body-file PATH` |
31-
| Read issue | `gh issue view NUMBER --repo owner/repo --json number,title,state,labels,assignees,author,url,body` |
32-
| Read comments | `gh api /repos/owner/repo/issues/NUMBER/comments --method GET --header "Accept: application/vnd.github+json"` |
33-
34-
## Credential + config helper commands
23+
| Operation | Command |
24+
| ---------------------------------- | ------------------------------------------------------------------------------------------------------------- |
25+
| Clone repository (default shallow) | `gh repo clone owner/repo [DIRECTORY] -- --depth=1` |
26+
| Deepen shallow clone | `git -C DIRECTORY fetch --depth=N origin` |
27+
| Convert shallow clone to full | `git -C DIRECTORY fetch --unshallow` |
28+
| Create issue | `gh issue create --repo owner/repo --title "..." [--body-file PATH]` |
29+
| Update issue fields | `gh issue edit NUMBER --repo owner/repo [--title "..."] [--body-file PATH]` |
30+
| Close issue | `gh issue close NUMBER --repo owner/repo [--comment "..."]` |
31+
| Reopen issue | `gh issue reopen NUMBER --repo owner/repo` |
32+
| Add labels | `gh issue edit NUMBER --repo owner/repo --add-label LABEL [--add-label LABEL2]` |
33+
| Remove labels | `gh issue edit NUMBER --repo owner/repo --remove-label LABEL [--remove-label LABEL2]` |
34+
| Add comment | `gh issue comment NUMBER --repo owner/repo --body-file PATH` |
35+
| Read issue | `gh issue view NUMBER --repo owner/repo --json number,title,state,labels,assignees,author,url,body` |
36+
| Read comments | `gh api /repos/owner/repo/issues/NUMBER/comments --method GET --header "Accept: application/vnd.github+json"` |
37+
38+
## Credential and config helpers
3539

3640
Resolve repo default:
3741

@@ -45,12 +49,6 @@ Set repo default:
4549
jr-rpc config set github.repo owner/repo
4650
```
4751

48-
Pass extra `git clone` flags after `--`:
49-
50-
```bash
51-
gh repo clone owner/repo -- --depth=1 --filter=blob:none
52-
```
53-
5452
Issue scoped credentials:
5553

5654
```bash
@@ -59,3 +57,10 @@ jr-rpc issue-credential github.issues.write
5957
jr-rpc issue-credential github.issues.comment
6058
jr-rpc issue-credential github.labels.write
6159
```
60+
61+
## Behavior notes
62+
63+
- Prefer `--json` output for machine-readable parsing where available.
64+
- Use `gh api` for endpoints not fully covered by `gh issue` subcommands.
65+
- Pass extra `git clone` flags after `--` (e.g. `gh repo clone owner/repo -- --depth=1`).
66+
- Return actionable errors for auth, permission, not-found, and validation failures.

packages/junior-github/skills/github/references/github-issue-api.md

Lines changed: 0 additions & 54 deletions
This file was deleted.

packages/junior/evals/conversational/skill-workflows.eval.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,22 @@ describe("Conversational Evals: Skill Workflows", () => {
6767
thread_ts: "17000000.default-repo",
6868
};
6969

70+
slackEval("skills: github issue create skips dupe narration", {
71+
overrides: {
72+
enable_test_credentials: true,
73+
plugin_packages: ["@sentry/junior-github"],
74+
test_credential_token: "eval-github-token",
75+
skill_dirs: ["skills"],
76+
},
77+
events: [
78+
mention(
79+
"Create an issue for adding rate limiting to the API endpoint in getsentry/junior",
80+
),
81+
],
82+
criteria:
83+
"The assistant creates a GitHub issue without narrating duplicate-search results. The reply must not mention checking for duplicates, searching for similar issues, or reporting that no duplicates were found. The reply should proceed directly to issue creation and report the result.",
84+
});
85+
7086
slackEval("skills: default repo setup via natural language", {
7187
overrides: {
7288
enable_test_credentials: true,

0 commit comments

Comments
 (0)