116 lines
6.5 KiB
Markdown
116 lines
6.5 KiB
Markdown
> Core 中立版(Increment 4 改写)。术语对照见 core/adapters/TERMINOLOGY.md;本组织实例表述见 dogfood 对应文件。
|
|||
|
|
|
||
|
|
## Session Scope Guard (mandatory)
|
||
|
|
|
||
|
|
> Enforcement layer: precheck-mechanized (injection-budget batch-2,
|
||
|
|
> [org-internal #3667]) — pre-flight sources 1-3 below live in the repo's
|
||
|
|
> session-conflicts script, source 4 in the claim script's compare-and-swap.
|
||
|
|
> This file is the normative definition, NOT part of any `agents_md`
|
||
|
|
> injection whitelist since 2026-08-29 — do not re-add; the checks run at
|
||
|
|
> claim time regardless.
|
||
|
|
|
||
|
|
Standalone and ticket-seeded sessions run without a pipeline around them —
|
||
|
|
no plan, no reviewer keeping them inside their work item. When such a
|
||
|
|
session hits a test failure NOT caused by its own change ([org-internal
|
||
|
|
[org-internal #1803]], via [org-internal #1753]/[[org-internal #1744]]), it tends to fix the foreign
|
||
|
|
failure in place (drifting off-task), and sessions seeded for the same issue
|
||
|
|
collide on the same shared flaky test.
|
||
|
|
|
||
|
|
**Iron Law: if a test fails and it was NOT caused by your change, you MUST
|
||
|
|
classify → file → continue. Do NOT fix it in place — unless that test IS your
|
||
|
|
task.**
|
||
|
|
|
||
|
|
### The classify → file → continue protocol
|
||
|
|
|
||
|
|
1. **Classify** — rerun the failing test on the base commit / last-green:
|
||
|
|
fails there too → **baseline failure (BF)**; intermittent across runs →
|
||
|
|
**flaky test (FT)**; fails only with your change → **your regression** —
|
||
|
|
fix it now.
|
||
|
|
2. **File** — register every BF/FT as an issue in the ticket backend labeled
|
||
|
|
`baseline-failure` or `flaky-test` with a `BF-NNN` / `FT-NNN` id, per the
|
||
|
|
testing rule. Deduplicate against an existing BF/FT issue (comment your
|
||
|
|
run evidence instead of filing a twin).
|
||
|
|
3. **Continue** — return to your assigned task; cite the BF/FT issue number
|
||
|
|
in your report / PR body so the next session sees it is owned.
|
||
|
|
|
||
|
|
A foreign failure does not block your task, but the task is NOT done until
|
||
|
|
the failure is filed — an un-filed BF/FT is a process gap. Filing is the
|
||
|
|
whole job: **the fix belongs to whoever owns that test**, not to you.
|
||
|
|
|
||
|
|
### One task, one owner — check before you start
|
||
|
|
|
||
|
|
Before starting work on an issue or code area, you MUST verify no other
|
||
|
|
session already owns it. The pre-flight check spans four sources — (1) live
|
||
|
|
sessions referencing `#N`, (2) a workflow branch already covering #N
|
||
|
|
(worktrees, local branches, remote `workflow/*` refs), (3) an open PR
|
||
|
|
referencing `#N`, (4) assignee + claim comment naming another owner. A hit
|
||
|
|
on ANY source → the ticket is already owned: ABORT (or, for a DEAD claim,
|
||
|
|
take over via the mechanized channel below; otherwise coordinate on the
|
||
|
|
issue), never silently start a second owner.
|
||
|
|
|
||
|
|
**Mechanized ([org-internal #3667])**: the repo's session-conflicts script
|
||
|
|
(`<session-conflicts-cmd> <ticket>`) scans sources 1-3 in one read-only pass
|
||
|
|
(exit 4 = conflict, matching the claim script; source 1 fail-opens visibly
|
||
|
|
when the app API is down — the backend hard guard [org-internal #1989]
|
||
|
|
backstops); source 4 IS the claim script's compare-and-swap. Dead-claim
|
||
|
|
takeover is mechanized in the claim script (see below); manual recipes:
|
||
|
|
the headless-session-ops skill's ticket-recipe reference §0.
|
||
|
|
|
||
|
|
**Dead-claim takeover ([org-internal #3668]).** A claim whose session is
|
||
|
|
gone (404 on the app API) and whose branch was never pushed is a DEAD claim
|
||
|
|
— the [org-internal #3419] shape. Do NOT hand-edit the dead claim comment
|
||
|
|
(the retired admin workaround — unauditable); run the claim script's
|
||
|
|
takeover subcommand (`<claim-takeover-cmd> <ticket> <branch> --session-id
|
||
|
|
<id>`) instead. Evidence rule (the claim script's header is normative): a
|
||
|
|
competing claim is dead iff its named branch is ABSENT on the remote AND
|
||
|
|
(its session 404s OR the comment is at least `CLAIM_TAKEOVER_STALE_DAYS`
|
||
|
|
old — age >= the threshold, default 3d). Evidence holds → one atomic
|
||
|
|
takeover: assignee re-set + a `**claim**` comment carrying
|
||
|
|
`supersedes-claim #<id>` markers and the inline evidence (auditable chain,
|
||
|
|
nothing edited) + branch push, with post-posting race re-verification.
|
||
|
|
Evidence fails (session alive, branch pushed = completed claim, or fresh
|
||
|
|
claim with unknown liveness) → exit 10, zero mutation — coordinate on the
|
||
|
|
issue or salvage the worktree instead. A valid claim is never superseded.
|
||
|
|
|
||
|
|
**Claim-first (atomic 3-step claim).** The FIRST action when starting
|
||
|
|
ticket-driven work is to claim the ticket — one atomic action of THREE
|
||
|
|
steps, valid ONLY when all complete: (1) set the issue assignee to the
|
||
|
|
working account, (2) post a claim comment naming the workflow branch and
|
||
|
|
session id, (3) push the workflow branch to remote (even an empty commit —
|
||
|
|
a purely local branch is invisible to other sessions, [org-internal
|
||
|
|
[org-internal #2280]/[org-internal #2282]]). Use the repo's claim wrappers (staged-transaction claim
|
||
|
|
script; exit codes and CAS semantics in its header; non-zero = NOT claimed)
|
||
|
|
and the provision wrapper (adds the worktree + Tier-1 runs scaffold). The
|
||
|
|
manual 3-step is the fallback where the scripts are unavailable, same
|
||
|
|
re-verification.
|
||
|
|
|
||
|
|
**Merge-time equivalence check.** Before merging, scan the remote main
|
||
|
|
branch's recent commits for `#<ticket>` — surfacing an equivalent
|
||
|
|
implementation already on main *before* the merge rejection.
|
||
|
|
|
||
|
|
**Merge-time review gate ([org-internal #2345]).** `pipeline/review-code` is
|
||
|
|
a required status: merge needs it green OR the route-based exemption
|
||
|
|
(Kind/* close routes skip review-code — posted by the repo's
|
||
|
|
review-gate-exemption script). Read the commit-status endpoint for the PR
|
||
|
|
SHA: `success` + `review not required (route:` description → route
|
||
|
|
exemption, proceed; `success` otherwise → proceed; missing / `error` /
|
||
|
|
`pending` / other → BLOCK — a missing status never approves.
|
||
|
|
|
||
|
|
**Epic ownership table.** Multi-chunk parallel Epics keep a chunk →
|
||
|
|
session/account ownership table on the parent issue — consult it and claim
|
||
|
|
your chunk before starting.
|
||
|
|
|
||
|
|
Two sessions owning the same issue or code area is never faster — it is the
|
||
|
|
exact collision this rule prevents. If a collision HAS happened, follow the
|
||
|
|
failure-path playbook at the ownership-collision runbook (Tier-2 reference
|
||
|
|
page, reachable via the ticket backend).
|
||
|
|
|
||
|
|
### Scope
|
||
|
|
|
||
|
|
Applies semantically to **every session** — pipeline subagents (Producer /
|
||
|
|
Verifier / Reviewer / Tool) and standalone/ticket-seeded sessions alike;
|
||
|
|
for subagents, "your task" is the delegated prompt's scope, and classify →
|
||
|
|
file → continue applies unchanged. Filing rides the testing rule;
|
||
|
|
launch-time owner checks live in the headless-session-ops skill (which
|
||
|
|
points here). This file stays the normative definition — read on demand.
|