Merge pull request #6524 from deepseek-harness/docs/ai-usage-pr-section

docs(skills): present AI usage as a badged stage table
This commit is contained in:
imccyu authored and GitHub committed 2026-10-19 13:27:40 +08:00
commit 473b3d360c
3 files changed
+149 -42

No files matched your search

+59 -26
View File
@@ -1,6 +1,6 @@
---
name: dsh-pr-description
description: Use when creating a deepseek-harness pull request, or when updating its description after later changes or a handled review round. Defines each description section, Issue references, test design, change-specific disclosures, and the Human and Agent Roles section with its levels, stages, grading rules, and update timing.
description: Use when creating a deepseek-harness pull request, or when updating its description after later changes or a handled review round. Defines each description section, Issue references, test design, change-specific disclosures, and the AI Usage section with its levels, stages, grading rules, AI-DECLARATION badge, and update timing.
user-invocable: false
---
@@ -16,7 +16,7 @@ This skill defines what a deepseek-harness PR description contains, how to write
## Description structure
The description uses four second-level headings, in this order: `## Motivation`, `## Changes`, `## Testing`, and `## Human and Agent Roles`.
The description uses four second-level headings, in this order: `## Motivation`, `## Changes`, `## Testing`, and `## AI Usage`.
Write all headings and labels, such as **Interface changes**, **Behavior changes**, **Test design**, and **Test entries**, in English. Write the rest of the description in Chinese unless a human asked for another language for this PR.
@@ -63,22 +63,22 @@ Write each disclosure in the section it concerns, usually Changes, after a bold
| Changing product-user-visible GUI behavior | An embedded demonstration GIF, with the disclosures that record-browser-gif requires beside the embed; for each GUI change without a GIF, a statement that none is embedded and why | [record-browser-gif](../record-browser-gif/SKILL.md#every-gui-pull-request-includes-a-gif) |
| Using a translation term the terminology list lacks | The source of the rendering, or a proposed rendering under pending terms | [Translation rules](../../../docs/i18n/translation-rules.md) |
## Human and Agent Roles
## AI Usage
This section records who made the decisions in each stage of the PR, and how autonomously the Agent worked.
This section records how much the AI took part in each stage of the PR, and who made the decisions.
### Levels
Levels are ordered from least to most AI involvement; each level pairs an English name with a Chinese name. Autonomy is the Agent's autonomy in that stage, a multiple of 5% within the chosen level's range.
Levels are ordered from least to most AI involvement; each level pairs an English name with a Chinese name. AI involvement is how much the AI participated in the decisions and work of that stage, recorded as a multiple of 5% within the chosen level's range. It is not a measure of code volume, time, or tokens.
| Level | Meaning | Agent autonomy |
| Level | Meaning | AI involvement |
|---|---|---|
| hint 人工独立 | A human does the work; AI takes no part or only offers passive suggestions that the human accepts or rejects | 0–10% |
| assist 人工主导 | A human supplies the main content or every key decision; AI completes part of the work | 15–25% |
| pair 人工引导 | A human gives the key direction or constraints and revises the AI's output several times; the human understands the internals | 30–50% |
| copilot 人工把关 | AI completes the whole task; a human reviews, selects, or rejects, and decides or clarifies key points without supplying substantive content | 55–85% |
| auto 模型自主 | AI completes the task autonomously; a human only sets the goal or accepts the output | 90–100% |
| n/a 暂不适用 | The stage does not exist or has not happened yet | Omitted |
| n/a 暂不适用 | The stage does not exist or has not happened yet | — |
### Stages and criteria
@@ -112,7 +112,7 @@ Stages appear in a fixed order; each stage pairs an English name with a Chinese
- pair 人工引导: a human requires reverting or redoing any part of the work, or specifies a refactoring or an implementation approach.
- assist 人工主导: a human writes the key parts in the diff; the Agent completes the rest. Dictating content for the Agent to write is not writing it.
**review 评审处理**: who decides whether each handled review comment is fixed or declined. Comments from bots and from people both count; grade by who decided, not by who posted the reply. When no review comment has been handled, the line stays n/a, even if comments exist or arrived after merge.
**review 评审处理**: who decides whether each handled review comment is fixed or declined. Comments from bots and from people both count; grade by who decided, not by who posted the reply. When no review comment has been handled, the row stays n/a, even if comments exist or arrived after merge.
- auto 模型自主: the Agent decides on and replies to every comment.
- copilot 人工把关: a human gives only a blanket authorization or category-level instructions, or responds to only a few items on a handling list the Agent prepared and leaves the rest to the Agent.
@@ -125,32 +125,55 @@ Stages appear in a fixed order; each stage pairs an English name with a Chinese
- Count only work that ends up in this PR, including work from earlier sessions that ends up in this PR. A human's request to revert or redo work counts even when the reverted work does not remain in the PR.
- In breakdown, design, testing, and implementation, the human is the author working with the Agent; reviewers' approvals and comments count only in review.
- Process and ordering instructions, such as branching, working order, staging, and when to commit, push, or open the PR, do not count as human involvement in any stage.
- When the records suffice, grade at the level with the most human involvement whose criterion the records meet, and express the human and Agent shares through the autonomy value. Only when the records do not suffice, take the level with less human involvement that the records support.
- When the records suffice, grade at the level with the most human involvement whose criterion the records meet, and express the human and Agent shares through the AI involvement value. Only when the records do not suffice, take the level with less human involvement that the records support.
- When a stage covers several changes, grade by the main change and state how the other changes differ in the description. The main change is the one with the largest share of the diff and review effort; when no single change dominates, grade by the change with the most human involvement. When later work changes which change is main, regrade the stage.
- Within the chosen level's range, choose a lower autonomy value the closer the human involvement comes to the criterion of the level with more human involvement, and a higher value the closer it comes to the level with less.
- Within the chosen level's range, choose a lower AI involvement value the closer the human involvement comes to the criterion of the level with more human involvement, and a higher value the closer it comes to the level with less.
### Line format
### Badge URLs
The section starts with one level line, followed by one line per stage in the fixed order:
The AI-DECLARATION block pins specification version 0.1.2. Use the badge for the highest level among the stage rows; a stage with n/a 暂不适用 does not affect the highest level.
| Level | Badge URL |
|---|---|
| hint 人工独立 | `https://img.shields.io/badge/䷼%20AI--DECLARATION-hint-ecfccb?labelColor=ecfccb` |
| assist 人工主导 | `https://img.shields.io/badge/䷼%20AI--DECLARATION-assist-fef9c3?labelColor=fef9c3` |
| pair 人工引导 | `https://img.shields.io/badge/䷼%20AI--DECLARATION-pair-ffedd5?labelColor=ffedd5` |
| copilot 人工把关 | `https://img.shields.io/badge/䷼%20AI--DECLARATION-copilot-fee2e2?labelColor=fee2e2` |
| auto 模型自主 | `https://img.shields.io/badge/䷼%20AI--DECLARATION-auto-ede9fe?labelColor=ede9fe` |
When the upstream specification changes, update this version and the version link in the declaration block together.
### Section format
The section starts with the AI-DECLARATION block, followed by one table row per stage in the fixed order:
```markdown
## Human and Agent Roles
## AI Usage
Levels and Agent autonomy: <ins>**hint 人工独立**</ins> 0–10%, <ins>**assist 人工主导**</ins> 15–25%, <ins>**pair 人工引导**</ins> 30–50%, <ins>**copilot 人工把关**</ins> 55–85%, <ins>**auto 模型自主**</ins> 90–100%; <ins>**n/a 暂不适用**</ins> marks a stage that does not exist or has not happened yet.
<!-- ai-declaration:start -->
[![AI-DECLARATION: <highest level>](<badge URL>)](https://ai-declaration.md)
- <ins>**<level English name> <level Chinese name>**</ins> <autonomy> · <stage English name> <stage Chinese name> — <description>
**AI declaration** ([v0.1.2](https://ai-declaration.md/en/0.1.2)): `<highest level>`
<!-- ai-declaration:end -->
| 阶段 | 级别 | AI 参与度 | 决策记录 |
|:--|:--|--:|:--|
| <stage English name> <stage Chinese name> | <level English name> <level Chinese name> | <AI involvement> | <description> |
```
- Write the level in bold and underlined; omit the autonomy value for n/a 暂不适用.
- The badge level is the highest level among the stage rows; ignore rows with n/a 暂不适用.
- Keep the `ai-declaration` markers so an existing declaration can be replaced in place without duplicating it.
- Write the description in the PR description's language, in one or two sentences of at most 80 Chinese characters or 40 English words. State who made which decisions: name one or two representative decisions, and give only a count for the rest.
- Write `—` for the AI involvement of a stage with n/a 暂不适用.
- State the description as settled fact, without hedges such as "not seen in the session" or "pending author confirmation".
- Refer to people as the author or a reviewer, never by username. Leave out judgments, session times, session ids, direct quotes, and the running or handling of checks and CI (local skips, hooks, reruns, unrelated failures).
### Update timing
- When you create the PR, the review line reads `- <ins>**n/a 暂不适用**</ins> · review 评审处理 — ` followed by a statement, in the description's language, that no review comments have been handled yet.
- When the description is updated after the PR exists, rewrite the affected lines so that they cover all work so far, including earlier stages whose decisions or human share the later work changed; do not append a history of changes.
- The review line records only handled review comments; it omits approvals, merge timing, and unhandled comments.
- When you create the PR, the review row reads `| review 评审处理 | n/a 暂不适用 | — | ` followed by a statement, in the description's language, that no review comments have been handled yet.
- When the description is updated after the PR exists, rewrite the affected rows so that they cover all work so far, including earlier stages whose decisions or human share the later work changed; do not append a history of changes.
- When a stage's level changes, update its row; when the highest level changes, update the badge URL and the declaration line with it.
- The review row records only handled review comments; it omits approvals, merge timing, and unhandled comments.
- A review round ends when its fixes are pushed and its comments answered. Comments that arrive after merge do not trigger an update.
### Example
@@ -158,15 +181,25 @@ Levels and Agent autonomy: <ins>**hint 人工独立**</ins> 0–10%, <ins>**assi
Filled in from the session and review records of #6013:
```markdown
- <ins>**pair 人工引导**</ins> 40% · breakdown 问题拆解 — The author identified two process-specific values that do not belong in the system prompt and pointed to the custom model route; the Agent traced the root cause.
- <ins>**assist 人工主导**</ins> 20% · design 方案设计 — The author supplied the design structure: runtime context, frozen legacy sections for old sessions, and a separate package; the Agent filled in the projection matching.
- <ins>**pair 人工引导**</ins> 40% · testing 验收测试 — The author required two scenarios: restoring an old session after upgrade, and changing ports after upgrade; the Agent wrote the cases and snapshots.
- <ins>**pair 人工引导**</ins> 35% · implementation 技术实现 — The Agent wrote the code and the Agent Note; the author required one revert and specified 3 approaches, such as getOrigin() instead of an origin property.
- <ins>**pair 人工引导**</ins> 40% · review 评审处理 — The author decided each bot comment, such as no upgrade guide and keeping a devDependency; the Agent fixed and replied.
## AI Usage
<!-- ai-declaration:start -->
[![AI-DECLARATION: pair](https://img.shields.io/badge/䷼%20AI--DECLARATION-pair-ffedd5?labelColor=ffedd5)](https://ai-declaration.md)
**AI declaration** ([v0.1.2](https://ai-declaration.md/en/0.1.2)): `pair`
<!-- ai-declaration:end -->
| 阶段 | 级别 | AI 参与度 | 决策记录 |
|:--|:--|--:|:--|
| breakdown 问题拆解 | pair 人工引导 | 40% | The author identified two process-specific values that do not belong in the system prompt and pointed to the custom model route; the Agent traced the root cause. |
| design 方案设计 | assist 人工主导 | 20% | The author supplied the design structure: runtime context, frozen legacy sections for old sessions, and a separate package; the Agent filled in the projection matching. |
| testing 验收测试 | pair 人工引导 | 40% | The author required two scenarios: restoring an old session after upgrade, and changing ports after upgrade; the Agent wrote the cases and snapshots. |
| implementation 技术实现 | pair 人工引导 | 35% | The Agent wrote the code and the Agent Note; the author required one revert and specified 3 approaches, such as getOrigin() instead of an origin property. |
| review 评审处理 | pair 人工引导 | 40% | The author decided each bot comment, such as no upgrade guide and keeping a devDependency; the Agent fixed and replied. |
```
## Creating and updating the description
1. Write the description to a file that git ignores, such as `.artifacts/pr/body.md`. Create the PR with `gh pr create --body-file <file>`, or update it with `gh pr edit <number> --body-file <file>`; when the description embeds a GIF, follow [record-browser-gif](../record-browser-gif/SKILL.md) and use `--attach`.
2. Before an update, save the current description with `gh pr view <number> --json body --jq .body`, and change only the sections that need it: keep content and media the author wrote, and remove statements that no longer match the code.
3. After writing, read the description back and confirm that all four sections are present and that Human and Agent Roles matches the current code and review state.
2. Before an update, save the current description with `gh pr view <number> --json body --jq .body`, and change only the sections that need it: keep content and media the author wrote, replace only the contents of an existing `ai-declaration` block, and remove statements that no longer match the code.
3. After writing, read the description back and confirm that all four sections are present and that AI Usage matches the current code and review state.
+77 -9
View File
@@ -215,17 +215,18 @@ test('keeps the pull request template aligned with the dsh-pr-description skill'
'## Motivation',
'## Changes',
'## Testing',
'## Human and Agent Roles',
'## AI Usage',
])
assert.doesNotMatch(source, /^### /m)
assert.doesNotMatch(source, /<ins>/)
const usageSection = source.slice(source.indexOf('## AI Usage'))
assert.ok(usageSection.includes('<!-- ai-declaration:start -->'), 'the AI declaration block is in AI Usage')
assert.ok(usageSection.includes('| 阶段 | 级别 | AI 参与度 | 决策记录 |'), 'the role table is in AI Usage')
assert.match(source, /^## Motivation\n\n<!-- [^\n]*Fixes #N[^\n]* -->$/m, 'the template prompts for an Issue reference')
assert.match(source, /- <!-- [^\n]+ -->\n\n <details>\n <summary>Proof<\/summary>/)
assert.equal(source.match(/<details>/g)?.length, 1)
assert.equal(source.match(/<\/details>/g)?.length, 1)
const levelLine = /^Levels and Agent autonomy: .+$/m
assert.ok(skill.match(levelLine), 'the skill shows the role level line')
assert.equal(source.match(levelLine)?.[0], skill.match(levelLine)?.[0], 'the template level line matches the skill')
const stagesSection = skill.match(/^### Stages and criteria\n([\s\S]*?)(?=^### )/m)?.[1]
assert.ok(stagesSection, 'the skill has a Stages and criteria section')
const skillStages = [...stagesSection.matchAll(/^\*\*(.+?)\*\*:/gm)].map(([, stage]) => stage)
@@ -235,18 +236,85 @@ test('keeps the pull request template aligned with the dsh-pr-description skill'
}
const reviewStage = 'review 评审处理'
assert.equal(skillStages.at(-1), reviewStage, 'review is the last stage')
const skillProse = skill.replace(/```[\s\S]*?```/g, '')
assert.match(skillProse, /^## AI Usage$/m, 'the skill names the section AI Usage')
assert.match(skillProse, /^### Section format$/m, 'the skill has a Section format section')
assert.ok(skill.includes('| Level | Meaning | AI involvement |'), 'the skill defines AI involvement')
const badgeSection = skill.match(/^### Badge URLs\n([\s\S]*?)(?=^### )/m)?.[1]
assert.ok(badgeSection, 'the skill has a Badge URLs section')
for (const [level, color] of [
['hint', 'ecfccb'],
['assist', 'fef9c3'],
['pair', 'ffedd5'],
['copilot', 'fee2e2'],
['auto', 'ede9fe'],
]) {
assert.ok(
badgeSection.includes(`https://img.shields.io/badge/䷼%20AI--DECLARATION-${level}-${color}?labelColor=${color}`),
`the skill has the ${level} badge URL`,
)
}
assert.ok(skill.includes('[v0.1.2](https://ai-declaration.md/en/0.1.2)'), 'the skill pins the specification version')
const sectionFormat = skill.match(/^### Section format\n[\s\S]*?```markdown\n([\s\S]*?)```/m)?.[1]
assert.ok(sectionFormat, 'the skill shows the section format')
const example = skill.match(/^### Example\n[\s\S]*?```markdown\n([\s\S]*?)```/m)?.[1]
assert.ok(example, 'the skill has an example')
for (const [label, markdown] of [
['section format', sectionFormat],
['example', example],
]) {
assert.match(markdown, /^## AI Usage$/m, `the ${label} uses the AI Usage heading`)
assert.match(markdown, /^<!-- ai-declaration:start -->$/m, `the ${label} starts the declaration block`)
assert.match(markdown, /^<!-- ai-declaration:end -->$/m, `the ${label} ends the declaration block`)
assert.ok(markdown.includes('| 阶段 | 级别 | AI 参与度 | 决策记录 |'), `the ${label} shows the role table header`)
}
const exampleRows = [...example.matchAll(/^\| .+? \| ([a-z]+) [^|]+ \| (\d+)% \| .+$/gm)]
assert.ok(exampleRows.length > 0, 'the example has stage rows')
const levelOrder = ['hint', 'assist', 'pair', 'copilot', 'auto']
const highestExampleLevel = exampleRows
.map(([, level]) => level)
.reduce((highest, level) => (levelOrder.indexOf(level) > levelOrder.indexOf(highest) ? level : highest))
assert.ok(example.includes(`AI-DECLARATION: ${highestExampleLevel}`), 'the example badge shows the highest level')
const declarationBlock = source.match(/^<!-- ai-declaration:start -->\n([\s\S]*?)\n<!-- ai-declaration:end -->$/m)?.[1]
assert.ok(declarationBlock, 'the template has one ordered AI declaration block')
assert.equal(source.match(/<!-- ai-declaration:start -->/g)?.length, 1)
assert.equal(source.match(/<!-- ai-declaration:end -->/g)?.length, 1)
assert.match(
declarationBlock,
/^\[!\[AI-DECLARATION: 待填级别\]\(https:\/\/img\.shields\.io\/badge\/[^)]+\)\]\(https:\/\/ai-declaration\.md\)$/m,
'the block has the badge link',
)
assert.match(
declarationBlock,
/^\*\*AI declaration\*\* \(\[v0\.1\.2\]\(https:\/\/ai-declaration\.md\/en\/0\.1\.2\)\): `待填级别`$/m,
'the block pins the declaration',
)
assert.ok(source.includes('| 阶段 | 级别 | AI 参与度 | 决策记录 |'), 'the template has the role table header')
assert.ok(source.includes('|:--|:--|--:|:--|'), 'the template right-aligns AI involvement')
assert.deepEqual(
[...source.matchAll(/^- <ins>\*\*(?:待填级别\*\*<\/ins> \?%|n\/a 暂不适用\*\*<\/ins>) · (.+?) — .+$/gm)].map(([, stage]) => stage),
[...source.matchAll(/^\| (.+?) \| (?:待填级别|n\/a 暂不适用) \| (?:\?%|—) \| .+$/gm)].map(([, stage]) => stage),
skillStages,
'the template has one line per skill stage, in skill order',
'the template has one row per skill stage, in skill order',
)
for (const stage of skillStages.slice(0, -1)) {
assert.ok(source.includes(`- <ins>**待填级别**</ins> ?% · ${stage} — 待填说明\n`), `${stage} has a placeholder line`)
assert.ok(source.includes(`| ${stage} | 待填级别 | ?% | 待填说明 |`), `${stage} has a placeholder row`)
}
assert.ok(
source.includes(`- <ins>**n/a 暂不适用**</ins> · ${reviewStage} — 尚无已处理的评审意见。\n`),
'the review line starts as n/a, as the skill requires at PR creation',
source.includes(`| ${reviewStage} | n/a 暂不适用 | — | 尚无已处理的评审意见。 |`),
'the review row starts as n/a, as the skill requires at PR creation',
)
for (const [label, text] of [
['template', source],
['skill', skill],
]) {
assert.doesNotMatch(text, /Human and Agent Roles/, `${label} has no old heading`)
assert.doesNotMatch(text, /autonomy/i, `${label} has no old autonomy term`)
assert.doesNotMatch(text, /<ins>/, `${label} has no old underline markup`)
}
})
test('ignores Issue title, body presentation, and assignee ownership', () => {
+13 -7
View File
@@ -17,12 +17,18 @@
</details>
## Human and Agent Roles
## AI Usage
Levels and Agent autonomy: <ins>**hint 人工独立**</ins> 0–10%, <ins>**assist 人工主导**</ins> 15–25%, <ins>**pair 人工引导**</ins> 30–50%, <ins>**copilot 人工把关**</ins> 55–85%, <ins>**auto 模型自主**</ins> 90–100%; <ins>**n/a 暂不适用**</ins> marks a stage that does not exist or has not happened yet.
<!-- ai-declaration:start -->
[![AI-DECLARATION: 待填级别](https://img.shields.io/badge/䷼%20AI--DECLARATION-待填级别-lightgrey)](https://ai-declaration.md)
- <ins>**待填级别**</ins> ?% · breakdown 问题拆解 — 待填说明
- <ins>**待填级别**</ins> ?% · design 方案设计 — 待填说明
- <ins>**待填级别**</ins> ?% · testing 验收测试 — 待填说明
- <ins>**待填级别**</ins> ?% · implementation 技术实现 — 待填说明
- <ins>**n/a 暂不适用**</ins> · review 评审处理 — 尚无已处理的评审意见。
**AI declaration** ([v0.1.2](https://ai-declaration.md/en/0.1.2)): `待填级别`
<!-- ai-declaration:end -->
| 阶段 | 级别 | AI 参与度 | 决策记录 |
|:--|:--|--:|:--|
| breakdown 问题拆解 | 待填级别 | ?% | 待填说明 |
| design 方案设计 | 待填级别 | ?% | 待填说明 |
| testing 验收测试 | 待填级别 | ?% | 待填说明 |
| implementation 技术实现 | 待填级别 | ?% | 待填说明 |
| review 评审处理 | n/a 暂不适用 | — | 尚无已处理的评审意见。 |