Issue 创建
核心规则
在提议或发布之前,先发现目标仓库的贡献工作流程。YAML Issue 表单是默认自动化路径的格式权威:将审核后的答案物化到私有的 BODY_FILE 中,并使用 --body-file 发布。
安全发现
首先运行只读检查:
gh auth status
REPO="$(gh repo view --json nameWithOwner -q .nameWithOwner)"
REPO_URL="$(gh repo view --json url -q .url)"
HOST="${REPO_URL#*://}"
HOST="${HOST%%/*}"
TARGET="$HOST/$REPO"
gh repo view --json nameWithOwner,url,hasDiscussionsEnabled,hasIssuesEnabled,isBlankIssuesEnabled
git ls-files README.md CONTRIBUTING.md CONTRIBUTING.* .github/CONTRIBUTING.md .github/ISSUE_TEMPLATE .github/ISSUE_TEMPLATE/config.yml
gh api --hostname "$HOST" --paginate "repos/$REPO/labels?per_page=100" --jq '.[].name'
检查 README.md、贡献说明、.github/ISSUE_TEMPLATE/config.yml 的联系链接、表单、标签以及已开启和已关闭的 Issue。对于问题/支持,优先遵循仓库规定的 Discussions/联系路由;否则询问或停止。完成 REPO、HOST 和 TARGET 的目标验证。在身份验证、目标验证、Issue 可用性、策略、表单选择或所需元数据缺失或不明确时,在变更前失败并停止。仅当 isBlankIssuesEnabled 明确为 true 时,才允许空白回退。
仅从审核过且存在、策略允许执行者应用的标签构建 LABEL_ARGS:
LABEL_ARGS=()
LABEL_ARGS+=(--label "$LABEL") # 仅为每个允许发现的标签重复该命令。
重复与表单决策
-
用一句话描述报告,推导出
QUERY,然后完成一次跨开启和关闭 Issue 的重复搜索:gh issue list --repo "$TARGET" --state all --search "$QUERY" --limit 1000代理必须主动完成重复搜索并保留其结果证据。如果结果已饱和或完整性不确定,则缩小只读搜索范围或停止。对于确认的重复项,应发表评论而不是创建新 Issue。在评论确认的重复项之前,对确切的评论正文执行与发布相同的隐私扫描/脱敏。
-
仅当其声明的目的匹配时,才选择一个仓库提供的表单。如果多个表单匹配且策略无法区分它们,则停止并要求用户决定。
-
对于 YAML 表单,读取其模式并按声明顺序建立控件。仅支持
input、textarea、dropdown和checkboxes。Markdown 控件是非答案指南:在收集和物化相邻答案时遵守其可见指令,但不要将它们渲染为响应部分。在格式错误、不支持、缺失或必需的答案结构不明确时,在变更前失败并停止。模式格式错误、必需的答案缺失或不明确,都会导致变更前失败:不要打开浏览器或进行变更。仅当用户明确要求浏览器完成,或者自动路径无法安全/忠实地表示语法上有效的选定表单时,才提供浏览器交接;否则报告自动化为何不安全并停止。
| 控件 | 必需的处理方式 |
|---|---|
input / textarea | 保留可见标签。当 validations.required 为 true 时需要回答;否则渲染 _No response_。 |
dropdown | 保留可见标签和选项。需要精确的选定选项文本;单次选择有一个选择,多次选择按声明选项顺序保留选择。必需的 dropdown 需要至少一个有效选择;可选的 dropdown 若无选择则渲染 _No response_。 |
checkboxes | 保留可见标签和每个选项,格式为 - [x] 或 - [ ],按声明顺序排列。强制执行单个必需的复选框。对于代理可验证的操作选项,主动完成该操作并仅用保留的证据标记它;代理只能明确证明其自身基于证据的工作,并且不得将其操作归因于用户。个人事实、同意、法律声明和其他第一人称用户断言需要用户明确确认;此类用户声明需要明确的第二人称肯定。不要全选复选框:请求发布并不表示对任何复选框的肯定。 |
对于每个答案,渲染 ### <visible label>,后跟其物化值。对于 textarea.attributes.render,使用声明的语言和足够长的 fence 来包围答案。切勿编造答案、选择、确认或标签。
Markdown 模板只能从已知证据完成到相同的私有 BODY_FILE 中。如果没有匹配的模板,仅当空白 Issue 明确启用时才使用经过审核的结构化空白回退;否则停止而不发布。
复查与发布
在单次创建尝试之前,复查目标、标题、选定的表单或允许的回退、确切的正文以及允许的标签。代理必须在发布前立即完成对确切正文的隐私扫描/脱敏并保留其证据:用有用的占位符替换私有项目名称、用户名、主机名、主目录路径、凭据和私有网络地址,同时不破坏复现结构。
在仓库外部创建一个仅限所有者的临时目录,用于存放两个私有文件;将其限制为当前用户,并在每次退出/结果时清理这两个文件:
umask 077
REPO_ROOT="$(git rev-parse --show-toplevel)" || exit 1
REPO_ROOT="$(cd "$REPO_ROOT" && pwd -P)" || exit 1
if [ "$REPO_ROOT" = "/" ]; then
printf '%s\n' "临时目录在仓库内部" >&2; exit 1
fi
TMP_DIR="$(TMPDIR=/tmp mktemp -d /tmp/gentle-ai-issue.XXXXXXXX)" || exit 1
trap 'rm -rf -- "$TMP_DIR"' EXIT
TMP_DIR_REAL="$(cd "$TMP_DIR" && pwd -P)" || exit 1
case "$TMP_DIR_REAL/" in
"$REPO_ROOT/") printf '%s\n' "临时目录在仓库内部" >&2; exit 1 ;;
esac
chmod 700 "$TMP_DIR_REAL"
BODY_FILE="$TMP_DIR_REAL/body.md"
READBACK_FILE="$TMP_DIR_REAL/readback.json"
通过自动化路径进行一次变更尝试,并且仅发布一次:
gh issue create --repo "$TARGET" --title "$TITLE" --body-file "$BODY_FILE" "${LABEL_ARGS[@]}"
当上述表单决策允许浏览器完成时,一个可选的、单独的浏览器交接可以打开仓库表单。它绝不能证明发布,也绝不能作为对格式错误模式或缺失/不明确必需答案的响应:
gh issue create --repo "$TARGET" --web
不要重试超时、网络故障、身份缺失或其他不确定的结果。捕获返回的 Issue 编号,然后在报告成功之前从已验证的目标主机读取它:
gh issue view "$NUMBER" --repo "$TARGET" --json number,url,title,body,state,labels >"$READBACK_FILE"
确认读回能识别目标主机的 Issue,并且标题和正文仅经过 CRLF 到 LF 和尾部换行符规范化后匹配。仅在此目标主机读回之后才报告 confirmed。否则,当权威拒绝证明未创建 Issue 时报告 no_write,或者报告 unknown 并停止所有后续变更。
分类
在批准或关闭 Issue 之前,验证其是具体的、非重复的、有充分证据的、在范围内的,并且与仓库标签/状态策略一致。如果任何点不确定,则保留仓库审查状态并请求最小的缺失证据。