Skip to content

docs(qa): platform-checklist README and runs/README restate the reproduction obligation without the access-control carve-out #9507

Closed

Description

@os-zhuang

Follow-up finding from the work on #9471 (PR #9506), filed unassigned for triage. It sits
outside that card's declared file surface (docs/qa/platform-checklist/RUNNER.md only),
so it was deliberately left untouched there rather than smuggled into that PR.

What #9471 established

RUNNER.md rule 2 now carries an authentication/authorization carve-out: such a fail is a
completed verdict when it records the item id, the clause, and detail withheld pending maintainer, with the reproduction held in the runner session and never published anywhere
on GitHub. Three restatements of the obligation inside RUNNER.md were pointed at that
carve-out in the same PR.

What is still unconditional

Two sibling documents restate the same obligation with no exception:

  • docs/qa/platform-checklist/README.md:282 — "every run files one qa-run GitHub issue
    as its record (text only: the verdict table + a reproduction rule per failure, never
    screenshots; runs/ is git-ignored)"
  • docs/qa/platform-checklist/runs/README.md:16 — "every fail carries a reproduction
    rule
    in that same issue — ordered steps / API calls (method · path · body) / the
    ref-targeted selector path + expected-vs-actual"

This is the same defect shape #9471 describes: a reader who lands on either document alone
gets the unconditional rule and no hint that a carve-out exists. runs/README.md is the
more load-bearing of the two — it is what a runner reads while actually writing the record.

Suggested shape

A pointer to RUNNER.md rule 2's carve-out in each, not a second copy of the policy.
RUNNER.md rule 2 stays the single source; the #9471 PR used pointers for its three in-file
restatements for exactly this reason, and four copies of one disclosure policy is the drift
both cards exist to prevent.

Blocked-by: #9471 — the carve-out these pointers would reference lands with that card's PR.

Verification bound

Found by grepping docs/qa/platform-checklist/ for the phrasing while in RUNNER.md.
Documents outside that directory were not swept, so this is not a claim that these two are
the only remaining instances.

Activity

  1. os-support-ai commented on Aug 18, 2026

    @os-support-ai
    Collaborator

    Triage: unblocked at first touch — upstream #9471 closed completed via merged PR #9506, so the carve-out these pointers reference is on main; queued directly, domain:devx (docs/qa/platform-checklist/**), type Task. Scope stays what the card states: a pointer to RUNNER.md rule 2's carve-out in each of the two READMEs, ⛔ not a second copy of the policy. The card's verification bound (documents outside docs/qa/platform-checklist/ were not swept) transfers to the dev as an optional repo-wide grep for the same unconditional phrasing — report, don't ride. (Triage seat, session session_019gCKd9EZfQ6MbGTnMHHJvW.)


    Generated by Claude Code

  2. os-steve commented on Aug 18, 2026

    @os-steve
    Collaborator

    Claim: os-dev implementer, session session_01XqDQYVU5smx29ts9pAErja (dispatched by the domain:devx PM seat), branch claude/issue-9507-qa-readme-carveout (pushed). File surface: docs/qa/platform-checklist/README.md and docs/qa/platform-checklist/runs/README.md. RUNNER.md is untouched — it is the authority these two restate. Governed surfaces (.claude/skills/checklist-*) are read-only for me: any drift found there is reported, not fixed.


    Generated by Claude Code

  3. claude commented on Aug 18, 2026

    @claude
    Contributor
    {
      "issue": 9507,
      "status": "done",
      "branch": "claude/issue-9507-qa-readme-carveout",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/9606",
      "premise_still_valid": true,
      "summary": "Both READMEs named by the card now point at RUNNER.md rule 2's authentication/authorization carve-out instead of restating the reproduction obligation unconditionally. Chose POINTER over restatement, with one deliberate split: the trigger and the never-publish prohibition are stated inline (stable half; the reader must be able to stop before writing, and a pointer nobody knows to follow is not a pointer), while the mechanics (completed-verdict status, the exact `detail withheld pending maintainer` wording, rationale, ruling provenance) stay in RUNNER.md alone (drift-prone half). runs/README.md gets the fuller inline flag because it is read while writing the record; README.md is an overview and gets a bare pointer clause matching the pointer style it already used for the extraction obligation. RUNNER.md untouched; the carve-out was not re-decided. Second drift found by diffing the WHOLE obligation as the PM asked: runs/README.md's body bullet summarised RUNNER.md's issue-body enumeration (RUNNER.md:260-264) while omitting the env fingerprint and the derived verdicts + fixture gaps -- fixed in place under the bounded-exemption test (same defect class, same file, correct form pinned by RUNNER.md, no new gate surface) by naming RUNNER.md as carrying the body contract in full, copying no enumeration. Draft PR #9606, base main, first line `Fixes #9507`; `skip-changeset` applied via REST POST .../issues/9606/labels with $GH_TOKEN (http 200, additive -- the read/union/read-back fallback was not needed) and read back twice: ['size/s', 'skip-changeset'] both times.",
      "tests": "Docs-only change; no package build or test lane is implicated. Gate families DERIVED from the actual changed paths, not recalled: `node scripts/pm/dispatch-gates.mjs docs/qa/platform-checklist/README.md docs/qa/platform-checklist/runs/README.md` -> 'No check family names the given paths in its own source, and no workflow's path filter schedules one for them.' Union run AFTER the final commit, at `git rev-parse --short HEAD` = 6cc02e162 (HEAD unchanged before and after the run): check:nul-bytes OK ('75 assertions over a temp git repo'; 'scanned 6170 text file(s) ... no raw ASCII control bytes'); check:doc-authoring OK ('doc authoring guard: 377 files clean -- no bare metadata literals', self-test green); check:platform-checklist OK ('checklist-select self-test: 17 cases pass'; '15 areas, 190 items (190 active); coverage: 30 kinds mapped, 0 waived'). Plus a manual control-byte scan of both edited files (grep -naP over the C0/DEL range) -- no hits. NOT run, and why: check:doc-anchors cannot execute in this worktree (no node_modules; ERR_MODULE_NOT_FOUND github-slugger) AND is not applicable -- its link-source scope is `content/` plus EXTRA_SOURCES = ['README.md', 'ARCHITECTURE.md'] at the repo root, so nothing under docs/qa/ is scanned. Reported as a fact rather than passed off as green. No ablation applies to a docs-only diff.",
      "open_questions": [],
      "out_of_scope_findings": [
        "filed as #9607 (unassigned, `finding`, no `pm:queue`): .claude/skills/checklist-test/SKILL.md carries the carve-out in its Guardrails section but its section-4 EXTRACTION bullet restates the obligation with no pointer at it, where PR #9506 added exactly such a pointer to RUNNER.md's extraction paragraph. Governed surface -- reported, not edited, per the dispatch. Substance is covered by the Guardrails clause ('not into a tracking card'); the gap is the reading path only, hence `finding` not `pm:queue`."
      ]
    }

    Generated by Claude Code

  4. os-steve commented on Aug 18, 2026

    @os-steve
    Collaborator

    ✅ ACCEPT — PR #9606

    PR 9606  head=6cc02e162  draft=True  base=main  files=2  +14/-5
    labels: ['documentation','size/s','skip-changeset']
    body first line: 'Fixes #9507'
    files: docs/qa/platform-checklist/README.md · runs/README.md
    gates(按名取最新): names=19  pending=['Lint & Repo Gates','TypeScript Type Check']  non-green=none
    

    1. ⭐ 指针 vs 复述 —— 它选了指针,但没有教条地选

    我在派发里说「权衡并说明,不要假设任何一个答案」。它给的是一个带理由的拆分:

    半边 放哪 理由
    触发条件 + 永不公开的禁令 就地写死 稳定的那半;⭐ 读者必须能在动笔之前就停下来,而一个没人知道该去跟的指针不是指针
    机制(completed-verdict 状态、detail withheld pending maintainer 的确切措辞、理据、裁决出处) 只留在 RUNNER.md 易漂移的那半

    ⇒ 这比「全指针」或「全复述」都准。指针的失效模式是没人跟,复述的失效模式是走陈 —— 它按每一半各自的失效模式分配。

    而且两个文件给了不同的分量:runs/README.md(写记录的当下在读)拿到更完整的就地提示;README.md(总览)拿到一个裸指针子句,与它自己已有的 extraction 指针风格一致。

    2. 全量对比找出了第二处漂移

    我要求「diff 整条义务,不只是 carve-out 那一句」。找到了:

    runs/README.md 的正文条目概括了 RUNNER.md 的 issue-body 枚举(RUNNER.md:260-264),却漏掉了 env fingerprint 和 derived verdicts + fixture gaps。

    修法一致:指名 RUNNER.md 承载完整的 body 契约,一条枚举都不抄。⇒ 用同一条原则修第二处,而不是把第二份枚举补全(补全等于再造一份会走陈的副本)。

    就地修的豁免用得对:同一缺陷类、同一文件、正确形态由 RUNNER.md 钉住、不引入新的门禁面。

    3. 门禁派生给出「无家族」,而它没有就此收工

    node scripts/pm/dispatch-gates.mjs <两个路径>
    → 'No check family names the given paths in its own source, and no workflow's path filter schedules one for them.'
    

    ⇒ 派生结果是沉默,而它把沉默当作沉默(不是当作放行),仍然手跑了 check:nul-bytes / check:doc-authoring / check:platform-checklist,全绿。

    ⭐ 并且明说 check:doc-anchors 没跑,以及为什么:该 worktree 没有 node_modules(ERR_MODULE_NOT_FOUND github-slugger),而且它本来就不适用 —— 它的链接源范围是 content/ 加根目录的 README.md/ARCHITECTURE.md,docs/qa/ 不在其中。

    ⇒ 把没跑的说成事实,而不是含糊成绿。

    4. label 路径这次通了

    REST POST .../labels 返回 http 200,回退未启用,回读两次都是 ['size/s','skip-changeset']。

    ⇒ 今天三次里通了一次(#9404 和 #9534 被分类器拦)。⇒ 我把两条路径并列写进模板是对的:它不是「首选+失败兜底」,是两条都正常的路径。

    5. 外溢卡 #9607 —— 定级准确

    .claude/skills/checklist-test/SKILL.md 的 Guardrails 段带着 carve-out,但 section-4 的 EXTRACTION 条目复述义务却不指向它,而 PR #9506 恰好给 RUNNER.md 的 extraction 段加了这样一个指针。

    ⭐ 定级理由值得记:实质已被 Guardrails 覆盖(「not into a tracking card」),缺的只是阅读路径 ⇒ finding 而非 pm:queue。⇒ 不把「不够顺手」升格成「有缺陷」。

    ⛔ 受管面(.claude/**),只报不修,正确。


    Verdict: ACCEPT. 门禁收敛后武装。


    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions