v0.1.5: standalone-readability pass — delink --strip provenance mode ([TT-NNNN]), Tier-2 dangling refs neutralized, verify/review-code giant skills split into reference/ on-demand files; guards now runtime-neutral (bun|node)
This commit is contained in:
@@ -9,7 +9,7 @@
|
||||
> - `frontend/SKILL.md`
|
||||
>
|
||||
> (The `roadmap`, `requirements-elicitation`, `design`, and `plan-iterations`
|
||||
> referencing skills were archived 2026-08-21, [org-internal #3072] phase 3 — see
|
||||
> referencing skills were archived 2026-08-21, [TT-3072] phase 3 — see
|
||||
> `.octopus/archive/skills/`; their copies of this directive moved with them.)
|
||||
>
|
||||
> **When editing:** update this file only. Each skill references this file via a
|
||||
|
||||
@@ -70,6 +70,6 @@
|
||||
`review-dag` (review-artifact targets — same id feeds the
|
||||
`pipeline/{REVIEW_TYPE}` commit-status context; see review-artifact Phase
|
||||
Bindings). (The design-space/plan targets were archived 2026-08-21,
|
||||
[org-internal #3072] phase 3.)
|
||||
[TT-3072] phase 3.)
|
||||
- `{DIMENSION_COUNT}` — 10 (code review; 9 in standalone-bugfix mode), 3 (review-dag single gate), or 10 (process audit); used in
|
||||
the skill's SKILL.md reference text, not inside this template body
|
||||
|
||||
@@ -113,7 +113,7 @@ Each skill references this base template via `core/skills/_shared/review-orchest
|
||||
rather than inlining the JSON array. This centralization ensures the base
|
||||
permission surface stays consistent across all review/audit skills.
|
||||
|
||||
**Tier-1 local exception** ([org-internal #1988]): migrated skills that write raw per-dimension
|
||||
**Tier-1 local exception** ([TT-1988]): migrated skills that write raw per-dimension
|
||||
findings to `<runs-root>/**` (e.g. `review-code`) add ONE scoped `edit` allow
|
||||
to the base set — `{ permission: "edit", pattern: "<runs-root>/**", action:
|
||||
"allow" }` — so the reviewer can write its OWN finding file. This is a
|
||||
@@ -122,7 +122,7 @@ edit on the code under review, so rule #7 (auditor independence) holds. See
|
||||
`_shared/review-pipeline-phases.md` Phase A step 4 and `review-code/SKILL.md`
|
||||
Phase A step 3 for the inline extended array.
|
||||
|
||||
Residual risk — accepted trade-off (TD/STD-F004, [org-internal #2688]): the grant is scoped
|
||||
Residual risk — accepted trade-off (TD/STD-F004, [TT-2688]): the grant is scoped
|
||||
to `<runs-root>/**`, wider than the reviewer's own findings file. Per-file
|
||||
narrowing was considered and rejected: findings paths are round- and
|
||||
dimension-dependent (`{slug}/reviews/{stage}/round{N}/findings-{DIMENSION_CODE}.json`),
|
||||
@@ -132,7 +132,7 @@ residual exposure — a misbehaving reviewer could overwrite a sibling stage's
|
||||
Tier 1 files — is recorded here as accepted; auditor independence is
|
||||
unaffected (code under review lives outside `runs/`).
|
||||
|
||||
### No bash for Explorer sub-agents (deliberate boundary, [org-internal #2115] RC4 / [org-internal #2126])
|
||||
### No bash for Explorer sub-agents (deliberate boundary, [TT-2115] RC4 / [TT-2126])
|
||||
|
||||
Explorer sub-agents (Reviewer / auditor / Tool roles) have **no bash**. The
|
||||
`explorer` agent is built deny-by-default at
|
||||
@@ -151,7 +151,7 @@ Synthesizer / Verifier's job (Worker sub-agents, which DO have bash via the
|
||||
`worker` agent defaults) — not the Reviewer's. Report the need in findings
|
||||
instead of attempting bash.
|
||||
|
||||
> **[org-internal #2126] Task 2 conclusion — keep + document.** The `deny **` pushed per-tool
|
||||
> **[TT-2126] Task 2 conclusion — keep + document.** The `deny **` pushed per-tool
|
||||
> at `<harness-package>/src/session/prompt.ts` is the **session tool-enable /
|
||||
> disable map** (it disables `todowrite` / `task` / `experimental.primary_tools`
|
||||
> for subagents and allows forwarded MCP tools). It is NOT the source of the
|
||||
@@ -165,4 +165,4 @@ instead of attempting bash.
|
||||
- `{REVISION_ROLE}` — "Developer" (code review), "Analyst" (review-dag single
|
||||
gate), or "Remediator" (process audit). The Worker role that revises
|
||||
artifacts between rounds. (The Architect/Planner revision roles belonged to
|
||||
the archived design-space / iteration-plan targets, [org-internal #3072] phase 3.)
|
||||
the archived design-space / iteration-plan targets, [TT-3072] phase 3.)
|
||||
|
||||
@@ -9,14 +9,14 @@ parameters and reference this doc rather than duplicating the shared mechanics.
|
||||
legitimately uses "auditor"/"Re-audit" terminology. All generic descriptions
|
||||
use `{REVIEWER_OR_AUDITOR}`.
|
||||
|
||||
**Output model — two findings sinks** ([org-internal #1988] Tier 1 migration): raw per-dimension
|
||||
**Output model — two findings sinks** ([TT-1988] Tier 1 migration): raw per-dimension
|
||||
reviewer findings have ONE of two sinks, chosen per skill. The **synthesis**
|
||||
(human gate) and **commit status** are ALWAYS Tier 2 (Gitea) regardless of the
|
||||
findings sink.
|
||||
|
||||
| Sink | Skills | Reviewer writes findings to | Synthesizer reads findings from |
|
||||
|---|---|---|---|
|
||||
| `tier1-local` (migrated) | `review-code`, `review-artifact` (live targets: review-dag, audit-process; the roadmap/design-space/plan targets were archived 2026-08-21, [org-internal #3072] phase 3) | `<runs-root>/{slug}/reviews/{stage}/round{N}/findings-{DIMENSION_CODE}.json` (validated by `core/schemas/reviewer-output.schema.json`) | the local finding files (no Gitea call) |
|
||||
| `tier1-local` (migrated) | `review-code`, `review-artifact` (live targets: review-dag, audit-process; the roadmap/design-space/plan targets were archived 2026-08-21, [TT-3072] phase 3) | `<runs-root>/{slug}/reviews/{stage}/round{N}/findings-{DIMENSION_CODE}.json` (validated by `core/schemas/reviewer-output.schema.json`) | the local finding files (no Gitea call) |
|
||||
| `tier2-comment` (fallback) | _(none — all targets migrated)_ | Gitea PR/issue comment via `工单评论 API(见 TERMINOLOGY)` (Pattern 5) | `工单评论 API(见 TERMINOLOGY)` (Pattern 3) |
|
||||
|
||||
Migration complete — every review/audit skill now outputs `tier1-local`; the
|
||||
@@ -61,7 +61,7 @@ in `_shared/gitea-write-patterns.md`.
|
||||
`stage` = `{REVIEW_TYPE}`, `produced_by` = `Orchestrator`, `schema` = the
|
||||
review-status `$id`).
|
||||
|
||||
1. **Tool-availability probe** (defense-in-depth, [org-internal #2115] RC1 / [org-internal #2126]). Before
|
||||
1. **Tool-availability probe** (defense-in-depth, [TT-2115] RC1 / [TT-2126]). Before
|
||||
dispatching any {REVIEWER_OR_AUDITOR}, verify reviewers will be able to read
|
||||
wiki artifacts (requirements / design / plan / prior-review reports). A
|
||||
reviewer that cannot read its inputs aborts or hallucinates — catch this ONCE
|
||||
@@ -74,7 +74,7 @@ in `_shared/gitea-write-patterns.md`.
|
||||
reachable; anything else — timeout, connection refused, 5xx — is
|
||||
unreachable). If reachable → continue to step 2.
|
||||
- **Fallback path** (when REST is unreachable, e.g. a
|
||||
cross-repo scenario [org-internal #2115]): verify the **local wiki clone** at
|
||||
cross-repo scenario [TT-2115]): verify the **local wiki clone** at
|
||||
`<wiki-clone-root>/{repo}-wiki/` is readable —
|
||||
`glob(pattern="*.md", path="<wiki-clone-root>/{repo}-wiki/")`. If the clone
|
||||
is readable → continue to step 2; reviewers use the local clone (see
|
||||
@@ -266,7 +266,7 @@ Otherwise:
|
||||
- The {REVISION_ROLE} MUST NOT receive the full text of all findings inline —
|
||||
use finding-file path / comment references only to avoid context explosion.
|
||||
- Convergence status: blockers/majors remaining vs. previous round.
|
||||
- **Revision survival ([org-internal #2601]) — primary path**: the task tool's completion
|
||||
- **Revision survival ([TT-2601]) — primary path**: the task tool's completion
|
||||
output includes a `task_id`; passing it back resumes the SAME
|
||||
{REVISION_ROLE} subagent session instead of creating a fresh one. Round 1:
|
||||
persist the returned `task_id` with the round's working-notes entry (it
|
||||
@@ -322,24 +322,24 @@ After the {REVISION_ROLE} completes revision:
|
||||
`core/schemas/review-status.schema.json`).
|
||||
- `review-code` skill: **2** default / **3** high-risk (a BLOCKER survived a
|
||||
round, or the diff touches a frozen cross-session contract) —
|
||||
`<instance-root>/workflow-routing.yaml` `review.max_rounds` ([org-internal #3567], process-diet
|
||||
`<instance-root>/workflow-routing.yaml` `review.max_rounds` ([TT-3567], process-diet
|
||||
P0b). At budget without convergence: STOP, register the remaining
|
||||
BLOCKER/MAJOR findings as TD registry rows, then compute the verdict
|
||||
with the shared three-tier ladder (`core/schemas/synthesis.schema.json`
|
||||
`overall_verdict` + `core/skills/_shared/review-orchestrator-rules.md`
|
||||
rule 3): FAIL if any BLOCKER or FAIL dimension remains, else WARN,
|
||||
PASS only if every remaining dimension is PASS ([org-internal #4786]:
|
||||
PASS only if every remaining dimension is PASS ([TT-4786]:
|
||||
the prior binary "else PASS" wording silently upgraded WARN-eligible
|
||||
outcomes to PASS; a PASS round has already stopped at the convergence
|
||||
table above, so the residual tail lands WARN or FAIL). The debt is
|
||||
carried by those TD registry rows
|
||||
(see `review-code/SKILL.md` Phase D). This
|
||||
supersedes the 2026-08-25 [org-internal #3380] calibration (p50=2, p95=5, n=66): the runs
|
||||
supersedes the 2026-08-25 [TT-3380] calibration (p50=2, p95=5, n=66): the runs
|
||||
past round 3 are the marathon tail this budget exists to cut; their residue
|
||||
flows to the TD registry instead of reviewer rounds. Ledger:
|
||||
`docs/workflow-refactor/thresholds-ledger.md`.
|
||||
|
||||
Rationale for `review-artifact` = 3 (evaluated in [org-internal #1969], replacing the prior blanket
|
||||
Rationale for `review-artifact` = 3 (evaluated in [TT-1969], replacing the prior blanket
|
||||
default of 5): (1) the Round-3 Escalation Guardrail below already detects
|
||||
non-convergence at the start of round 3; (2) the INFO-disposition rule below
|
||||
removes spurious WARN rounds previously caused by non-blocking INFO findings;
|
||||
@@ -350,8 +350,8 @@ reaches round 4 — its round budget is 2/3, see the binding above.)
|
||||
|
||||
**Provisional, not empirically validated**: the four safeguards make `review-artifact`=3
|
||||
defensible, but it has no fresh run-data yet. Treat it as a hypothesis to
|
||||
confirm via the retrospective signal ([org-internal #1834]; gate-trim's landing machinery was
|
||||
retired, [org-internal #3072] phase 3 — the check is observational, not a trim proposal): if
|
||||
confirm via the retrospective signal ([TT-1834]; gate-trim's landing machinery was
|
||||
retired, [TT-3072] phase 3 — the check is observational, not a trim proposal): if
|
||||
live `review-artifact` runs frequently hit round 3 still improving yet are
|
||||
forced to stop at WARN/FAIL, bump it back to 4.
|
||||
|
||||
@@ -379,8 +379,8 @@ block convergence and NEVER drive a reviser round.
|
||||
**Round-3 Escalation Guardrail** (applies to the `review-artifact` skill's
|
||||
live targets — the process audit target AND the review-dag single-gate
|
||||
target; the roadmap / design / plan targets were archived 2026-08-21,
|
||||
[org-internal #3072] phase 3). `review-code` does NOT use this guardrail; it uses its round
|
||||
budget ([org-internal #3567], see the `{MAX_ROUNDS}` binding above).
|
||||
[TT-3072] phase 3). `review-code` does NOT use this guardrail; it uses its round
|
||||
budget ([TT-3567], see the `{MAX_ROUNDS}` binding above).
|
||||
|
||||
At the start of round 3, if the combined blocker+major count is still >50% of
|
||||
round 1's count, STOP the loop and surface to the user:
|
||||
@@ -391,7 +391,7 @@ round 1's count, STOP the loop and surface to the user:
|
||||
> (a) Return to upstream — for the `process` audit target, escalate to the
|
||||
> octopus maintainer for a process-level redesign (the legacy producer skills
|
||||
> `roadmap` / `requirements-elicitation` / `design` / `plan-iterations` were
|
||||
> archived 2026-08-21, [org-internal #3072] phase 3 — `<instance-root>/archive/`), then restart this
|
||||
> archived 2026-08-21, [TT-3072] phase 3 — `<instance-root>/archive/`), then restart this
|
||||
> review at round 1.
|
||||
> (b) Continue iterating — accept that more rounds may be needed (capped by
|
||||
> `{MAX_ROUNDS}`).
|
||||
@@ -406,7 +406,7 @@ review and escalate to a human, or (b) continue into round 4 — via the
|
||||
`question` tool. The guard means "escalate with a choice", NOT "force-stop".
|
||||
The choice is UNCONDITIONAL at the round-3→4 transition — instance skills may
|
||||
narrow when an escalation *variant* (e.g. a design-level decision) fires, but
|
||||
never narrow the choice gate itself. The call MUST be optionized ([org-internal #3378]):
|
||||
never narrow the choice gate itself. The call MUST be optionized ([TT-3378]):
|
||||
two options — `Stop & escalate to a human` (first, when recommended) /
|
||||
`Continue into round 4` — with `stage` set to the running skill's stage so
|
||||
auto-approval applies in autonomous mode; free-text asking is a spec
|
||||
@@ -414,12 +414,12 @@ violation.
|
||||
Instance: review-dag D4 option-b (`review-artifact/SKILL.md` §"Round-3
|
||||
Escalation Guardrail interaction") — the sole live instance, its D4 round cap
|
||||
(≤4) being the only budget that reaches round 4 (`review-code` is capped 2/3,
|
||||
[org-internal #3567]).
|
||||
Rationale (retro 2026-08-21 / [org-internal #3050]): unattended late-round loops drift into
|
||||
[TT-3567]).
|
||||
Rationale (retro 2026-08-21 / [TT-3050]): unattended late-round loops drift into
|
||||
review marathons — the choice forces the design-level stall to surface to a
|
||||
human at round 4 instead of round 6.
|
||||
|
||||
**Efficiency optimization**: From round 2 onward ([org-internal #2598]), only spawn
|
||||
**Efficiency optimization**: From round 2 onward ([TT-2598]), only spawn
|
||||
{REVIEWER_OR_AUDITOR}s for dimensions that had FAIL, WARN, or UNRESOLVED in
|
||||
the previous round. Every 2 rounds, run a full {DIMENSION_COUNT}-reviewer
|
||||
sweep to catch regressions. From round 2 onward reviewer input is also
|
||||
@@ -486,7 +486,7 @@ not the round-1 full set.
|
||||
`REQUEST_REVIEW` registration to be recorded, and only THEN ask the human
|
||||
to approve. Approving before the reviewer is registered produces
|
||||
`official: false` on the approval — the gate treats the PR as unapproved
|
||||
and the approval must be re-done. ([org-internal #1931]: audit R2→R3 re-loop + re-approve,
|
||||
and the approval must be re-done. ([TT-1931]: audit R2→R3 re-loop + re-approve,
|
||||
~30min wasted on exactly this ordering.)
|
||||
|
||||
4. Present the final report to the user and obtain approval via the `question`
|
||||
|
||||
@@ -31,7 +31,7 @@ After revising, report a summary of changes made:
|
||||
- Findings waived as cosmetic MINOR (round 2+): {WAIVED-{id} → reason}
|
||||
|
||||
Persist that summary to `{RETURN_FILE}` as your LAST action, BEFORE
|
||||
returning it — worker-report persistence ([org-internal #2847], see
|
||||
returning it — worker-report persistence ([TT-2847], see
|
||||
`.octopus/skills/_shared/worker-report-persistence.md`). The persisted copy
|
||||
is the report of record; if your completion notification is lost, the
|
||||
Orchestrator recovers the revision outcome from this file.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
> Core 中立版(Increment 6a 改写,原 deferHard verbatim)。编号与条目结构严格不变(C-2 不变量);实例术语按 `core/adapters/TERMINOLOGY.md` 绑定。
|
||||
name: Coordinator
|
||||
purpose: >
|
||||
Pool dispatch coordinator (billing-v2 [org-internal #4041] §7, REQ-F-012): a wake-driven,
|
||||
Pool dispatch coordinator (billing-v2 [TT-4041] §7, REQ-F-012): a wake-driven,
|
||||
STATELESS decision-maker session living in the pool pod alongside workers.
|
||||
List eligible issues (Gitea API, scoped token) → produce DAG-aware dispatch
|
||||
proposals → commit each dispatch through the N-16 assignment API
|
||||
@@ -62,14 +62,14 @@ agents_md:
|
||||
#
|
||||
# Security posture (AC-5, see docs/security/threat-model.md §自治批处理):
|
||||
# the coordinator authenticates with a workspace-level API token
|
||||
# (TD-687/[org-internal #3898] owner-minted, jti-revocable, role claim org_role). TODAY'S
|
||||
# (TD-687/[TT-3898] owner-minted, jti-revocable, role claim org_role). TODAY'S
|
||||
# mint shape hardcodes org_role=viewer — read-capable only (assignment table
|
||||
# + pool surfaces); the editor-capable mint needed for dispatch submission is
|
||||
# an explicit deployment-time decision on the [org-internal #3898] channel (not landed with
|
||||
# an explicit deployment-time decision on the [TT-3898] channel (not landed with
|
||||
# N-19). Either way the token can NOT mint tokens, touch wallet internals, or
|
||||
# merge PRs — the merge gate stays human (E-4).
|
||||
#
|
||||
# Worker-report persistence ([org-internal #2847] — see
|
||||
# Worker-report persistence ([TT-2847] — see
|
||||
# core/skills/_shared/worker-report-persistence.md): a Coordinator
|
||||
# sub-agent persists its FINAL RETURN REPORT to disk as its LAST action,
|
||||
# before returning — <runs-root>/{slug}/workers/{chunk-id}-worker-{seq}.md
|
||||
|
||||
@@ -15,7 +15,7 @@ agents_md:
|
||||
- claim-discipline
|
||||
- compact
|
||||
|
||||
# Worker-report persistence ([org-internal #2847], retro-2696 AI#2 — see
|
||||
# Worker-report persistence ([TT-2847], retro-2696 AI#2 — see
|
||||
# core/skills/_shared/worker-report-persistence.md): every Producer
|
||||
# sub-agent persists its FINAL RETURN REPORT to disk as its LAST action,
|
||||
# before returning — <runs-root>/{slug}/workers/{chunk-id}-worker-{seq}.md
|
||||
@@ -23,7 +23,7 @@ agents_md:
|
||||
# else /tmp/octopus/{chunk-id}-worker-{seq}.md. The persisted copy is the
|
||||
# report of record; the task notification is a convenience copy.
|
||||
#
|
||||
# Working-notes contract ([org-internal #2600] — see core/templates/runs-layout.md §
|
||||
# Working-notes contract ([TT-2600] — see core/templates/runs-layout.md §
|
||||
# working-notes.md): at stage exit the Producer appends ONE entry (≤30 lines:
|
||||
# decisions and why, dead ends, reviewer feedback that changed the work, hints
|
||||
# for the next stage) to <runs-root>/{slug}/working-notes.md, and registers
|
||||
|
||||
@@ -14,7 +14,7 @@ agents_md:
|
||||
- ticket-lifecycle
|
||||
- compact
|
||||
|
||||
# Working-notes contract ([org-internal #2600] — see core/templates/runs-layout.md §
|
||||
# Working-notes contract ([TT-2600] — see core/templates/runs-layout.md §
|
||||
# working-notes.md): the Reviewer side appends ONE distilled entry via the
|
||||
# Synthesizer at review convergence — never per dimension dispatch (9
|
||||
# dimension dispatches = 1 entry) — to <runs-root>/{slug}/working-notes.md.
|
||||
|
||||
@@ -12,7 +12,7 @@ agents_md:
|
||||
- claim-discipline
|
||||
- compact
|
||||
|
||||
# Working-notes contract ([org-internal #2600] — see core/templates/runs-layout.md §
|
||||
# Working-notes contract ([TT-2600] — see core/templates/runs-layout.md §
|
||||
# working-notes.md): Tool agents append to <runs-root>/{slug}/working-notes.md
|
||||
# ONLY when the task produced a load-bearing finding (e.g. image evidence that
|
||||
# changed a decision) — not for routine single-shot output.
|
||||
|
||||
@@ -15,7 +15,7 @@ agents_md:
|
||||
- claim-discipline
|
||||
- compact
|
||||
|
||||
# Worker-report persistence ([org-internal #2847], retro-2696 AI#2 — see
|
||||
# Worker-report persistence ([TT-2847], retro-2696 AI#2 — see
|
||||
# core/skills/_shared/worker-report-persistence.md): the Verifier
|
||||
# persists its FINAL RETURN REPORT (DoD verdict + evidence pointers) to disk
|
||||
# as its LAST action, before returning —
|
||||
@@ -23,7 +23,7 @@ agents_md:
|
||||
# else /tmp/octopus/{chunk-id}-worker-{seq}.md. The persisted copy is the
|
||||
# report of record; the task notification is a convenience copy.
|
||||
#
|
||||
# Working-notes contract ([org-internal #2600] — see core/templates/runs-layout.md §
|
||||
# Working-notes contract ([TT-2600] — see core/templates/runs-layout.md §
|
||||
# working-notes.md): the Verifier appends ONE entry at verify exit (what the
|
||||
# DoD sweep caught, flaky/deferral context the next run should know). The
|
||||
# Phase 5.5 archive step additionally inlines the final working-notes.md
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
- **Commit SHA**: `{SHA}` (the HEAD commit being reviewed).
|
||||
- **Review type**: `{REVIEW_TYPE}` — one of `review-code`, `review-dag`,
|
||||
`audit-process` (the `review-design-space` / `review-iteration-plan` /
|
||||
`review-roadmap` targets were archived 2026-08-21, [org-internal #3072] phase 3 — their
|
||||
`review-roadmap` targets were archived 2026-08-21, [TT-3072] phase 3 — their
|
||||
historical synthesis data remains readable).
|
||||
|
||||
## Your Job
|
||||
@@ -189,7 +189,7 @@
|
||||
9. Persist your return summary (the exact text from the Return Format
|
||||
below) to `<runs-root>/{slug}/reviews/{stage}/round{N}/synthesis-return.md`
|
||||
(Tier 1) as your LAST action, BEFORE returning it — worker-report
|
||||
persistence ([org-internal #2847], `_shared/worker-report-persistence.md`). The persisted
|
||||
persistence ([TT-2847], `_shared/worker-report-persistence.md`). The persisted
|
||||
copy is the report of record; if your completion notification is lost, the
|
||||
Orchestrator recovers the round verdict from this file.
|
||||
|
||||
@@ -211,7 +211,7 @@ synthesis JSON — it is already posted to the pipeline PR / source issue
|
||||
comment (for audit-process runs, the wiki page `audit/{date}/round{N}/synthesis`).
|
||||
Persist this summary verbatim to
|
||||
`<runs-root>/{slug}/reviews/{stage}/round{N}/synthesis-return.md` before
|
||||
returning (step 9 above — worker-report persistence [org-internal #2847]).
|
||||
returning (step 9 above — worker-report persistence [TT-2847]).
|
||||
|
||||
```
|
||||
## Synthesis Complete
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
> Canonical convention for every worker sub-agent dispatch (roles whose
|
||||
> `agent:` is `worker` — Producer sub-roles, Verifier, Synthesizer, …),
|
||||
> foreground or background (`task background=true`). Origin: retro WWW#5 /
|
||||
> [org-internal #2696] action item #2 ([org-internal #2847]) — at least one confirmed case where a
|
||||
> [TT-2696] action item #2 ([TT-2847]) — at least one confirmed case where a
|
||||
> background worker's completion report reached the orchestrating session
|
||||
> only via the task-tool notification; the notification was lost and the
|
||||
> report evaporated, leaving nothing but reverse-engineering from artifacts.
|
||||
|
||||
@@ -3,7 +3,7 @@ name: analyze-dag
|
||||
description: >
|
||||
Use ONLY when an Epic is routed to the DAG ticket pipeline (Kind/Epic or
|
||||
Kind/Feature — both resolve to analyze-dag via the routes table directly,
|
||||
[org-internal #3072] phase 3 / [org-internal #3061] Phase 2). The
|
||||
[TT-3072] phase 3 / [TT-3061] Phase 2). The
|
||||
Analyst decomposes the Epic into a single task-DAG artifact — merging
|
||||
roadmap+requirements+design+plan into one graph (nodes = acceptance
|
||||
criteria, edges = contracts, topology = plan).
|
||||
@@ -31,7 +31,7 @@ role: Producer
|
||||
analyze-dag is the **entry skill** of the DAG ticket pipeline
|
||||
(`dag.route.entry.skill`, spec-07 §2). For a DAG-routed Epic
|
||||
(`Kind/Epic`, or `Kind/Feature` — both resolve here via the routes table
|
||||
directly, [org-internal #3072] phase 3 / [org-internal #3061] Phase 2 / TD-388 —
|
||||
directly, [TT-3072] phase 3 / [TT-3061] Phase 2 / TD-388 —
|
||||
including BACKFILL mode for MVP graduates and big-bug relabels), it
|
||||
**replaces** `roadmap` + `requirements-elicitation` + `design` +
|
||||
`plan-iterations` and produces **ONE artifact**: the task DAG, published as
|
||||
@@ -66,12 +66,12 @@ a topological order (the plan), then publishes the single graph.
|
||||
| 设计主导 | 主要风险是一个有 ≥2 个可行选项的架构/平台决策,而非任务分解;需要先做一次探索 | 将开放问题转 `prototype`(THROWAWAY spike)或设计探索;决策记录后重入 |
|
||||
| 外部契约未决 | scope 依赖未决的外部契约(第三方 schema、上游 API 未定) | 按 External-System Rule(见下文)解析或围栏;不可拆的残余隔离后再重入 |
|
||||
|
||||
**反向拦截(Kind/MVP 降级建议,[org-internal #3061])**:一个 `Kind/Feature` 工单在分解预检中
|
||||
**反向拦截(Kind/MVP 降级建议,[TT-3061])**:一个 `Kind/Feature` 工单在分解预检中
|
||||
暴露"概念未稳"(scope 仍在探索、成功标准未定、决策日志会推翻节点划分)时,
|
||||
正确出口不是硬分解,而是建议改标签 `Kind/MVP` 先行交互式验证——概念稳定后
|
||||
经 backfill 模式(见下文)带着决策日志重入。
|
||||
|
||||
### Phase 0 需求澄清(disqualifier 的结构化扩展,[org-internal #3061])
|
||||
### Phase 0 需求澄清(disqualifier 的结构化扩展,[TT-3061])
|
||||
|
||||
预检不止于"能否分解",还须证明"需求已澄清到可分解"。两项强制检查:
|
||||
|
||||
@@ -217,7 +217,7 @@ Rules:
|
||||
- `refs_by` is derived from the REQMAP "every requirement ≥1 node" criterion
|
||||
(missing coverage = a requirement with no node).
|
||||
|
||||
## Breadth Coverage — 类目覆盖矩阵 + 排除账本 ([org-internal #2905] 方案 1)
|
||||
## Breadth Coverage — 类目覆盖矩阵 + 排除账本 ([TT-2905] 方案 1)
|
||||
|
||||
The four-stage fold that produced the single DAG artifact kept requirement
|
||||
**depth** (REQMAP three-path coverage + falsifiable AC) but dropped legacy
|
||||
@@ -271,7 +271,7 @@ sub-page `{epic-slug}/dag-coverage` using the same mechanics as AC sinking
|
||||
frozen copy) — purely organizational, NOT an oversize signal, no
|
||||
re-derivation.
|
||||
|
||||
### Breadth probe nodes (P2, [org-internal #2905] 方案 2)
|
||||
### Breadth probe nodes (P2, [TT-2905] 方案 2)
|
||||
|
||||
When a 待确认 category is cheapest to resolve empirically, a **probe node**
|
||||
is a legal task node at the granularity floor:
|
||||
@@ -306,12 +306,12 @@ is a legal task node at the granularity floor:
|
||||
冻结副本(新增需求必然改变节点集合或 `req_refs`;需要新节点时全额按
|
||||
node_split 建单传播)。
|
||||
|
||||
### Data layer — read `dag.route.preflight` BEFORE decomposition ([org-internal #2905] 方案 3)
|
||||
### Data layer — read `dag.route.preflight` BEFORE decomposition ([TT-2905] 方案 3)
|
||||
|
||||
Before starting decomposition, analyze-dag MUST read
|
||||
`<instance-root>/workflow-routing.yaml` `dag.route.preflight` and, when the list is
|
||||
non-empty, verify each item as a producer self-check (the same injection
|
||||
contract `implement` applies for `routes.{Kind}.preflight`, [org-internal #2599] — landed
|
||||
contract `implement` applies for `routes.{Kind}.preflight`, [TT-2599] — landed
|
||||
items carry their retro evidence in `evidence`):
|
||||
|
||||
1. Read the `dag:` block's `route.preflight` array (live yaml, repo root).
|
||||
@@ -407,7 +407,7 @@ external contract). This is what lets the REQMAP "需求覆盖" (requirement
|
||||
coverage) check mechanically verify that external-integration requirements map
|
||||
to nodes. (The `ARCH 1.1` system-context diagram is discarded only for
|
||||
process-infrastructure-type Epics; product Epics get this alternative rule
|
||||
instead.) [org-internal #2905]: this rule is the 外部系统集成 category of the breadth
|
||||
instead.) [TT-2905]: this rule is the 外部系统集成 category of the breadth
|
||||
coverage matrix held at its original strength — see Breadth Coverage above.
|
||||
|
||||
## Exec-Resource Configuration (spec-07 §4 — mechanical destination of folded checklist rows)
|
||||
@@ -433,7 +433,7 @@ observe:
|
||||
`> DAG 工件状态: draft`.
|
||||
2. After the single-gate (`review-dag`) PASS, the **aggregator agent** (main
|
||||
session / Orchestrator — not analyze-dag) asks the freeze confirmation
|
||||
question ([org-internal #3379]), then on confirmation flips the page to
|
||||
question ([TT-3379]), then on confirmation flips the page to
|
||||
`> DAG 工件状态: frozen` and stamps version `v1`. The confirmation is an
|
||||
OPTIONIZED `question` call (stage `review-dag`, never `destructive` —
|
||||
freeze is a process gate, not a business decision): options
|
||||
@@ -454,7 +454,7 @@ observe:
|
||||
the version stamp `vN → vN+1` (no re-confirmation — only the initial
|
||||
freeze gates on a decision).
|
||||
|
||||
## Backfill Input Mode (Kind/MVP graduation & big-bug relabels, [org-internal #3061])
|
||||
## Backfill Input Mode (Kind/MVP graduation & big-bug relabels, [TT-3061])
|
||||
|
||||
When a `Kind/MVP` ticket graduates (relabel → `Kind/Feature` → Step 0 → this
|
||||
skill), the DAG is derived from **what was actually built**, not from greenfield
|
||||
@@ -500,4 +500,4 @@ decomposition:
|
||||
- `dag-pipeline/spec-06` — dag_metrics derivation + thresholds
|
||||
- `dag-pipeline/spec-07` — dag.route landing row (entry skill, skip set, single-gate) + §4 landing list
|
||||
- `dag-pipeline/spec-08` — DAG artifact lifecycle / version stamp
|
||||
- `<instance-root>/archive/skills/roadmap/SKILL.md` — legacy route (archived 2026-08-21, [org-internal #3072] phase 3; this skill replaces it for all Epics)
|
||||
- `<instance-root>/archive/skills/roadmap/SKILL.md` — legacy route (archived 2026-08-21, [TT-3072] phase 3; this skill replaces it for all Epics)
|
||||
|
||||
@@ -185,7 +185,7 @@ When a `verify` work item has an E2E or UI DoD entry:
|
||||
## Session cleanup (mandatory)
|
||||
|
||||
A Playwright MCP browser is a real Chrome with a `/tmp` user-data-dir — its
|
||||
mode follows `mcp.playwright.headless` (`headless-field-v1`, [org-internal #4393]): the repo
|
||||
mode follows `mcp.playwright.headless` (`headless-field-v1`, [TT-4393]): the repo
|
||||
default `auto` spawns headed on desktop (win32/darwin; linux only with
|
||||
DISPLAY/WAYLAND_DISPLAY set) and headless otherwise; an explicit `true`/`false`
|
||||
or `OCTOPUS_MCP_HEADLESS=1|0` pins it. The mode is fixed per new session —
|
||||
@@ -194,7 +194,7 @@ stays alive as long as its MCP server runs, and the MCP server stays alive as
|
||||
long as its parent octopus backend runs. When a browser-debug session ends
|
||||
without an explicit `browser_close`, OR the octopus session times out mid-task,
|
||||
the Chrome + its MCP server are orphaned and accumulate across sessions —
|
||||
burning CPU and leaving dead profile dirs (issue [org-internal #1315]); in headed mode the
|
||||
burning CPU and leaving dead profile dirs (issue [TT-1315]); in headed mode the
|
||||
orphan is a visible stray window.
|
||||
|
||||
**Iron rule: every browser-debug session MUST close its browser before ending.**
|
||||
|
||||
@@ -171,7 +171,7 @@ Disable the watcher on slow filesystems (WSL2 `/mnt` drives, network mounts):
|
||||
codegraph serve --mcp --no-watch
|
||||
```
|
||||
|
||||
### Workflow worktrees get their own index ([org-internal #2561] / TD-006)
|
||||
### Workflow worktrees get their own index ([TT-2561] / TD-006)
|
||||
|
||||
The main checkout's `.codegraph/` does NOT cover git worktrees — they live
|
||||
outside the repo path, so nearest-`.codegraph/` resolution finds nothing under
|
||||
|
||||
@@ -315,7 +315,7 @@ Present the report to the user. Route to code review if > 20 lines or ≥ 3 file
|
||||
- `core/checklists/frontend.md` — Frontend self-check checklist
|
||||
- `core/skills/implement/SKILL.md` — General + pipeline implementation workflow
|
||||
- `core/skills/review-code/SKILL.md` — Code review (next step)
|
||||
- `<instance-root>/archive/skills/design/SKILL.md` — Design document production (legacy upstream, archived [org-internal #3072] phase 3)
|
||||
- `<instance-root>/archive/skills/design/SKILL.md` — Design document production (legacy upstream, archived [TT-3072] phase 3)
|
||||
- `core/skills/browser-debug/SKILL.md` — Interactive browser verification (invoke during Phase 3 / 4 for visual + interaction evidence)
|
||||
- `core/rules/testing.md`, `core/rules/type-checking.md` — Repository conventions (test commands, typecheck)
|
||||
- `core/rules/code-graph.md` — Code graph first
|
||||
|
||||
@@ -158,9 +158,9 @@ history. If a token leaks into a remote URL, rewrite the remote
|
||||
|
||||
**Create a release** — `POST .../releases {"tag_name":"v1.2.0","target":"main",...}`
|
||||
|
||||
**Create a wiki page** — `POST .../wiki/new {"title":"My Page","content_base64":"<b64>","message":"add page"}`. **`content_base64` is the ONLY field that writes body text** — this fork **silently ignores** the upstream-style `content` field on wiki create/update (no error, `201` returned, page saved 0 bytes; evidence [org-internal #3944]: commits f5eaf18/4f0217d/bad5880). `content` is valid only on the file API, never on wiki.
|
||||
**Create a wiki page** — `POST .../wiki/new {"title":"My Page","content_base64":"<b64>","message":"add page"}`. **`content_base64` is the ONLY field that writes body text** — this fork **silently ignores** the upstream-style `content` field on wiki create/update (no error, `201` returned, page saved 0 bytes; evidence [TT-3944]: commits f5eaf18/4f0217d/bad5880). `content` is valid only on the file API, never on wiki.
|
||||
|
||||
**Read / edit / delete a wiki page** — `GET|PATCH|DELETE .../wiki/page/{pageName}`. **Read by the mangled name, not the logical title**: this fork rewrites stored filenames for titles containing `/`, spaces, or `:` (slash percent-encoded into the filename + a `.-` suffix — see [org-internal #3218]), so `GET /wiki/page/bugfix-3204/bugfix-report` 404s. Always `GET .../wiki/pages` first and use the returned `sub_url` **verbatim** (it already carries the `%2F` encoding and `.-` suffix). PATCH/DELETE take the same mangled `pageName`. For PATCH, **omit `title` to keep the page name** and send only `content_base64`+`message` (fixed in gitea `dev-421-g7ff56aec08`, [org-internal #3510] — before that a title-less PATCH silently renamed the page to `unnamed.md` and later edits deleted target pages). Same trap as create: a PATCH carrying `content` instead of `content_base64` returns `200` with a **0-byte page** ([org-internal #3944]) — always base64-encode the body and verify non-empty via a follow-up `GET`.
|
||||
**Read / edit / delete a wiki page** — `GET|PATCH|DELETE .../wiki/page/{pageName}`. **Read by the mangled name, not the logical title**: this fork rewrites stored filenames for titles containing `/`, spaces, or `:` (slash percent-encoded into the filename + a `.-` suffix — see [TT-3218]), so `GET /wiki/page/bugfix-3204/bugfix-report` 404s. Always `GET .../wiki/pages` first and use the returned `sub_url` **verbatim** (it already carries the `%2F` encoding and `.-` suffix). PATCH/DELETE take the same mangled `pageName`. For PATCH, **omit `title` to keep the page name** and send only `content_base64`+`message` (fixed in gitea `dev-421-g7ff56aec08`, [TT-3510] — before that a title-less PATCH silently renamed the page to `unnamed.md` and later edits deleted target pages). Same trap as create: a PATCH carrying `content` instead of `content_base64` returns `200` with a **0-byte page** ([TT-3944]) — always base64-encode the body and verify non-empty via a follow-up `GET`.
|
||||
|
||||
## This fork's specifics
|
||||
|
||||
@@ -171,7 +171,7 @@ history. If a token leaks into a remote URL, rewrite the remote
|
||||
GET/PATCH/DELETE, `pages`, `revisions/{pageName}`). This fork has **no**
|
||||
upstream `raw/{pageName}` or `pages/{pageName}` single-page endpoints, and
|
||||
`page/{pageName}` only matches the mangled filename (see the wiki recipe
|
||||
above and [org-internal #3218]) — clone the wiki git repo (default branch `main`) only if
|
||||
above and [TT-3218]) — clone the wiki git repo (default branch `main`) only if
|
||||
you need history beyond `/wiki/revisions` or bulk filename surgery.
|
||||
- The authoritative route table is `routers/api/v1/api.go` in the Gitea
|
||||
source; the human-readable docs UI is `<BASE>/api/swagger`.
|
||||
|
||||
@@ -33,7 +33,7 @@ triggers:
|
||||
- launch session for issue
|
||||
- launch session for ticket
|
||||
- spawn session for ticket
|
||||
# English — patrol mode (delayed self-wake polling loops, [org-internal #3937]).
|
||||
# English — patrol mode (delayed self-wake polling loops, [TT-3937]).
|
||||
- patrol loop
|
||||
- patrol mode
|
||||
- delayed wake
|
||||
@@ -42,28 +42,28 @@ triggers:
|
||||
- 拉起会话
|
||||
- 自治会话
|
||||
- 无头会话
|
||||
# Chinese — patrol mode ([org-internal #3937]).
|
||||
# Chinese — patrol mode ([TT-3937]).
|
||||
- 巡检模式
|
||||
- 延迟唤醒
|
||||
- 会话不生成
|
||||
- 会话卡死
|
||||
- 为工单拉起会话
|
||||
- 工单拉起会话
|
||||
# English — lifecycle (hung rescue, stale-worldview correction, [org-internal #2459]).
|
||||
# English — lifecycle (hung rescue, stale-worldview correction, [TT-2459]).
|
||||
- abort session
|
||||
- revive session
|
||||
- session rescue
|
||||
- fact baseline
|
||||
# English — quota-wall recovery ([org-internal #3669]): worker killed by provider usage limit.
|
||||
# English — quota-wall recovery ([TT-3669]): worker killed by provider usage limit.
|
||||
- quota wall
|
||||
- usage limit reached
|
||||
- quota exhausted
|
||||
- switch provider
|
||||
# Chinese — lifecycle ops ([org-internal #2459]).
|
||||
# Chinese — lifecycle ops ([TT-2459]).
|
||||
- 唤醒会话
|
||||
- 会话挂死
|
||||
- 事实基线
|
||||
# Chinese — quota-wall recovery ([org-internal #3669]).
|
||||
# Chinese — quota-wall recovery ([TT-3669]).
|
||||
- 配额墙
|
||||
- 配额耗尽
|
||||
- 用量上限
|
||||
@@ -89,7 +89,7 @@ and worktree discipline are **orthogonal**: this skill only opens a session
|
||||
record pointed at a directory; whether the launched session later creates its
|
||||
own worktree is a _workflow_ decision (per the worktree-discipline rule) it
|
||||
makes when it starts actual work — not something the launcher does. One
|
||||
exception: the **ticket-driven recipe** below, where claim-first ([org-internal #2297])
|
||||
exception: the **ticket-driven recipe** below, where claim-first ([TT-2297])
|
||||
requires the launcher to push the workflow branch before launch, making a
|
||||
pre-built worktree the claim carrier + ready workspace (see Pitfall #10
|
||||
carve-out). So, unless a different repo / path is specifically targeted,
|
||||
@@ -122,7 +122,7 @@ carve-out). So, unless a different repo / path is specifically targeted,
|
||||
seed prompt, not the directory field (sidebar visibility, see bullet 1). The
|
||||
owner-check (`GET /session?directory=$DIR`) is scoped per directory, so
|
||||
rooting the session at the correct code checkout is also what makes the
|
||||
duplicate-session guard meaningful. Server-side backstop ([org-internal #3190]): creating a
|
||||
duplicate-session guard meaningful. Server-side backstop ([TT-3190]): creating a
|
||||
session whose directory IS a linked git worktree answers with an
|
||||
`X-Session-Directory-Warning` response header and a server warn log naming
|
||||
the owning main repo — if you see that header, the session will be invisible
|
||||
@@ -131,8 +131,8 @@ carve-out). So, unless a different repo / path is specifically targeted,
|
||||
|
||||
> **Authoritative reference:** `rules/headless-session-ops` wiki page
|
||||
> (<<instance-base-url>/Octopus/octopus/wiki/rules%2Fheadless-session-ops>).
|
||||
> This skill is its runtime carrier. Provenance: issue **[org-internal #1695]** (which
|
||||
> corrected the misdiagnosed [org-internal #1691], see comment 9205). Code citations below were
|
||||
> This skill is its runtime carrier. Provenance: issue **[TT-1695]** (which
|
||||
> corrected the misdiagnosed [TT-1691], see comment 9205). Code citations below were
|
||||
> verified against `<harness-package>` at HEAD.
|
||||
|
||||
## The `model` field — always provide a known-good model (read this first)
|
||||
@@ -166,7 +166,7 @@ section). Two reasons:
|
||||
`handlers/session.ts`) and never reaches the HTTP
|
||||
caller — so the session looks healthy (HTTP 204, user message persisted) yet
|
||||
**never generates**. This is exactly the "silent stall" observed empirically
|
||||
in [org-internal #1695]: a session with a 1-message transcript (user only) and frozen
|
||||
in [TT-1695]: a session with a 1-message transcript (user only) and frozen
|
||||
`time.updated`.
|
||||
|
||||
| payload | result |
|
||||
@@ -280,10 +280,10 @@ curl -s -X POST "$BASE/session/$SID/prompt_async?directory=$DIR" \
|
||||
queued behind a session that is generating with no live runner in this
|
||||
process (wedge/zombie shape — stored and re-driven on restart drain or the
|
||||
next runner), **202** when `delay_sec` defers delivery to an in-memory
|
||||
delayed wake ([org-internal #3937] A — see "巡检模式 / Patrol mode" below), and **409**
|
||||
delayed wake ([TT-3937] A — see "巡检模式 / Patrol mode" below), and **409**
|
||||
when the session is paused (message NOT stored) or the maintenance-mode
|
||||
hold queue is full.
|
||||
- **Global route alternative ([org-internal #4307]):** when the client only knows the
|
||||
- **Global route alternative ([TT-4307]):** when the client only knows the
|
||||
sessionID (no `?directory=` routing), `POST /prompt_async` (no path prefix)
|
||||
resolves the instance from the app database by the body's `sessionID` and
|
||||
delegates to the same delivery core — same 204/202/409 semantics, same
|
||||
@@ -294,17 +294,17 @@ curl -s -X POST "$BASE/session/$SID/prompt_async?directory=$DIR" \
|
||||
- `delay_sec` (optional, integer 0..86400, else 400) schedules the prompt for
|
||||
a one-shot delayed self-wake: the server holds the prompt in memory and
|
||||
fires it exactly once after `delay_sec` seconds, only for an idle session
|
||||
at intake. **Precedence ([org-internal #3937] review):** `delay_sec` applies only when the
|
||||
at intake. **Precedence ([TT-3937] review):** `delay_sec` applies only when the
|
||||
intake would otherwise start processing now (immediate class). For the
|
||||
queued-behind-wedge 202 member and under maintenance queue mode it is
|
||||
stripped — retention semantics win (the server logs the drop; the delay is
|
||||
NOT honored). Pending wakes are **in-memory only — a server restart abandons
|
||||
them**; a patrol loop must therefore tolerate a missed wake and re-arm.
|
||||
Never use `sleep <big>; curl ...` in a bash tool call to wait — that blocks
|
||||
the turn with zero output (the [org-internal #3937] incident shape); the bash tool now
|
||||
warns on bare sleeps > 120s (long-sleep guard, [org-internal #3937] C).
|
||||
the turn with zero output (the [TT-3937] incident shape); the bash tool now
|
||||
warns on bare sleeps > 120s (long-sleep guard, [TT-3937] C).
|
||||
- `model` is `{ providerID, modelID }` or the shorthand string
|
||||
`"providerID/modelID"` (split on the FIRST `/`; accepted since [org-internal #4307] —
|
||||
`"providerID/modelID"` (split on the FIRST `/`; accepted since [TT-4307] —
|
||||
e.g. `"zai-coding-plan/glm-5.2"`). **Do not omit it.** Fill the values from
|
||||
your own session's model (see "Reuse the current session's model" above) —
|
||||
never hardcode a specific model. A string without a `/` is rejected with
|
||||
@@ -335,7 +335,7 @@ curl -s "$BASE/session/$SID/message?directory=$DIR&limit=1" \
|
||||
Verdict: `latest_role == "assistant"` → the first generation completed (the
|
||||
seed is `user`; the newest message flips to `assistant` only once the model
|
||||
answered — an errored turn also persists an assistant message carrying the ⚠️
|
||||
usage-limit part, [org-internal #2912], so check the tail text before declaring success).
|
||||
usage-limit part, [TT-2912], so check the tail text before declaring success).
|
||||
Stays `user` across 2–3 polls spaced 10–30 s → **apparent silent stall**;
|
||||
almost certainly the model did not resolve to a usable one (fallback landed
|
||||
badly, or you omitted `model`). Redeliver Step 2 with an explicit known-good
|
||||
@@ -351,33 +351,33 @@ just never omit `limit`.
|
||||
|
||||
The common case: an agent (or cron/CI) spins up a fresh main session to work a
|
||||
tracked issue — seed prompt composed **from the issue body**, launched on the
|
||||
current session's model. **Step-0 owner check is MANDATORY ([org-internal #1803])**: four data
|
||||
current session's model. **Step-0 owner check is MANDATORY ([TT-1803])**: four data
|
||||
sources (session-title scan, assignee/claim, open PRs, remote branches); any
|
||||
live claim → ABORT the launch (`session-scope-guard.md` points here for that
|
||||
pre-step). Full recipe — owner-check scan script with `X-Total-Count` /
|
||||
`X-Has-More` pagination handling ([org-internal #3190]), claim-first atomic 3-step ([org-internal #2297],
|
||||
+ one-command provisioning via `script/claim-provision.sh`, [org-internal #3642]),
|
||||
seed-prompt MUSTs, backend duplicate-ticket hard guard ([org-internal #1989], on by default
|
||||
[org-internal #2350]), launch + poll commands: `reference/ticket-recipe.md` (read BEFORE
|
||||
`X-Has-More` pagination handling ([TT-3190]), claim-first atomic 3-step ([TT-2297],
|
||||
+ one-command provisioning via `script/claim-provision.sh`, [TT-3642]),
|
||||
seed-prompt MUSTs, backend duplicate-ticket hard guard ([TT-1989], on by default
|
||||
[TT-2350]), launch + poll commands: `reference/ticket-recipe.md` (read BEFORE
|
||||
creating any ticket-driven session).
|
||||
|
||||
## Completion-report protocol (完成回报协议, [org-internal #2374])
|
||||
## Completion-report protocol (完成回报协议, [TT-2374])
|
||||
|
||||
`prompt_async` is fire-and-forget **for the launcher too**: without this
|
||||
protocol the orchestrator has NO push channel and must poll forever ([org-internal #2366]).
|
||||
protocol the orchestrator has NO push channel and must poll forever ([TT-2366]).
|
||||
The worker actively reports `status=done|blocked|handoff` back into the
|
||||
orchestrator's session via `prompt_async`, with an issue-comment fallback.
|
||||
Default report format is `branch=<ref>`-based — workers never open PRs
|
||||
(TD-678/[org-internal #4425]); `pr=#N` appears only on `uncoordinated` self-opens.
|
||||
(TD-678/[TT-4425]); `pr=#N` appears only on `uncoordinated` self-opens.
|
||||
Hard constraints: a headless worker MUST NOT call the `question` tool
|
||||
([org-internal #2378] — directional/irreversible decisions are `status=blocked` reports,
|
||||
([TT-2378] — directional/irreversible decisions are `status=blocked` reports,
|
||||
then STOP), and MUST NOT self-merge its PR / self-close the issue / touch
|
||||
`main` ([org-internal #2386] — keep the PR open; the orchestrator merges and closes). Full
|
||||
`main` ([TT-2386] — keep the PR open; the orchestrator merges and closes). Full
|
||||
protocol — orchestrator-side seed block (verbatim template), worker-side
|
||||
steps, decision-authority layering: `reference/completion-report.md` (read
|
||||
BEFORE composing a seed prompt for any worker you need to hear back from).
|
||||
|
||||
## Post-launch lifecycle: health check, hung rescue, stale-worldview correction ([org-internal #2459])
|
||||
## Post-launch lifecycle: health check, hung rescue, stale-worldview correction ([TT-2459])
|
||||
|
||||
Launching is half the job — a headless worker can hang silently or wake with
|
||||
a stale worldview. Health check = two polls 30–60 s apart (`.state` + `progress`
|
||||
@@ -386,19 +386,19 @@ samples = hung → abort FIRST (`POST /session/:id/abort`), then re-wake with a
|
||||
known-good model + the anti-re-hang clause. Stale worldview → fact-baseline
|
||||
injection (only the CURRENT authority injects; if YOU might be the stale one,
|
||||
verify identity against the durable record first). Full runbooks — verdict
|
||||
table + [org-internal #3215] dual-sample rule, abort + re-wake sequence, fact-baseline
|
||||
table + [TT-3215] dual-sample rule, abort + re-wake sequence, fact-baseline
|
||||
structure, authorization asymmetry: `reference/lifecycle-ops.md` (read when
|
||||
managing a launched session). Quota wall — the worker's turn killed by a
|
||||
terminal usage-limit error (looks like silent completion: no report, ticket
|
||||
stalled) — has its own runbook: detection signals (finish=error ⚠️ tail,
|
||||
provider quota markers), provider-switch re-wake, fact-baseline template,
|
||||
pre-dispatch provider check: `reference/quota-wall-recovery.md` ([org-internal #3669], evidence
|
||||
[org-internal #3627]; read when a worker goes silent mid-task).
|
||||
pre-dispatch provider check: `reference/quota-wall-recovery.md` ([TT-3669], evidence
|
||||
[TT-3627]; read when a worker goes silent mid-task).
|
||||
|
||||
## 巡检模式 / Patrol mode (delayed self-wake, [org-internal #3937])
|
||||
## 巡检模式 / Patrol mode (delayed self-wake, [TT-3937])
|
||||
|
||||
A patrol loop periodically nudges a headless session without holding a
|
||||
connection or burning a turn on a blocking sleep. Since [org-internal #3937] A the server
|
||||
connection or burning a turn on a blocking sleep. Since [TT-3937] A the server
|
||||
supports this natively via `delay_sec` on `prompt_async`.
|
||||
|
||||
```sh
|
||||
@@ -427,16 +427,16 @@ Rules of the road:
|
||||
- **Restart abandons pending wakes.** They are in-memory server fibers — no
|
||||
persistence, no drain. After any server restart the patrol driver owns
|
||||
re-arming the next wake; treat a missed wake as expected, not as an error.
|
||||
- **Latest wake wins, per session ([org-internal #4069]).** Arming `delay_sec` on a session
|
||||
- **Latest wake wins, per session ([TT-4069]).** Arming `delay_sec` on a session
|
||||
that already has a pending wake SUPERSEDES it: the previous countdown is
|
||||
cancelled, only the latest wake fires. Re-arming each turn is the intended
|
||||
patrol pattern — a superseded wake never delivers its prompt and publishes
|
||||
no error. (Pre-[org-internal #4069] stacks both FIFO — on old binaries, re-arm only after
|
||||
no error. (Pre-[TT-4069] stacks both FIFO — on old binaries, re-arm only after
|
||||
the previous wake fired.)
|
||||
- **Never emulate a delay with the bash tool.** `sleep 900; curl ...` blocks
|
||||
the turn with zero output and gets manually aborted as a hang (the [org-internal #3937]
|
||||
the turn with zero output and gets manually aborted as a hang (the [TT-3937]
|
||||
incident). The bash tool now prepends a `<shell_warning>` on bare sleeps
|
||||
beyond 120s ([org-internal #3937] C) — treat that warning as a redirect to this section.
|
||||
beyond 120s ([TT-3937] C) — treat that warning as a redirect to this section.
|
||||
|
||||
## Do NOT use this skill when
|
||||
|
||||
@@ -461,15 +461,15 @@ Rules of the road:
|
||||
| 6 | Using synchronous `prompt` for headless launch | `prompt` blocks until done — wrong for fire-and-forget; use `prompt_async` |
|
||||
| 7 | Shell-escaping errors in a multi-line seed prompt | Build the payload with `jq -n --rawfile` from a file |
|
||||
| 8 | Verifying models via `GET /model` — no such endpoint (404) | Use `GET /provider` → `.connected` (provider live check); `list-models` tool also works. `GET /config/providers` lists _configured_ models only |
|
||||
| 9 | Launching a session for a ticket another live session already owns → conflicting diffs, duplicate work ([org-internal #1744]/[org-internal #1753]) | Run the Step-0 owner check (`GET /session` title scan + worktree/branch/PR scan); ABORT and report on conflict |
|
||||
| 10 | Creating a worktree / fresh checkout for the new session (unnecessary `bun install` + `.codegraph/` rebuild cost) | Don't — for _general_ launches: a session is a conversation pointed at a directory, so reuse the current workspace; worktree creation is a separate _workflow_ decision the launched session makes if/when it starts a workflow. **Ticket-recipe carve-out ([org-internal #2297]):** the ticket's work happens in a dedicated worktree anyway (worktree discipline), and claim-first pushes the workflow branch before launch — so the launcher pre-builds the worktree as the claim carrier + ready workspace, and the session reuses it (cost is front-loaded, not wasted). The worktree path goes in the claim comment + seed prompt; `?directory=` stays on the creator's workspace |
|
||||
| 11 | Launching a worker and never hearing back — orchestrator polls a few times, stops, loses visibility ([org-internal #2374]) | Append the completion-report block to the seed prompt (Completion-report protocol section): worker `prompt_async`s a one-line status back into the orchestrator session on done/blocked/handoff, with issue-comment fallback |
|
||||
| 12 | Headless worker calls the `question` tool → no attached client: the question deadlocks in a queue, or `auto_approve` silently auto-approves a direction-setting decision ([org-internal #2378]) | NEVER call `question` from a headless worker. Decision boundary (Completion-report protocol section): directional/irreversible decision → `status=blocked` report + one-line decision point, then STOP; the orchestrator is the sole human-decision entry point |
|
||||
| 13 | Headless worker self-merges its PR / self-closes the issue once the PR looks ready, despite a seed instruction to keep it open ([org-internal #2386]; N-02 [org-internal #2367] / N-03 [org-internal #2368], commits `d1565c99` / `040f21b7`) | Self-merge / self-close / touching `main` are irreversible directional actions → blocked by the Decision boundary. PR ready → keep it OPEN, report `status=done branch=<ref>`; the orchestrator opens/admits the PR, merges and closes uniformly |
|
||||
| 9 | Launching a session for a ticket another live session already owns → conflicting diffs, duplicate work ([TT-1744]/[TT-1753]) | Run the Step-0 owner check (`GET /session` title scan + worktree/branch/PR scan); ABORT and report on conflict |
|
||||
| 10 | Creating a worktree / fresh checkout for the new session (unnecessary `bun install` + `.codegraph/` rebuild cost) | Don't — for _general_ launches: a session is a conversation pointed at a directory, so reuse the current workspace; worktree creation is a separate _workflow_ decision the launched session makes if/when it starts a workflow. **Ticket-recipe carve-out ([TT-2297]):** the ticket's work happens in a dedicated worktree anyway (worktree discipline), and claim-first pushes the workflow branch before launch — so the launcher pre-builds the worktree as the claim carrier + ready workspace, and the session reuses it (cost is front-loaded, not wasted). The worktree path goes in the claim comment + seed prompt; `?directory=` stays on the creator's workspace |
|
||||
| 11 | Launching a worker and never hearing back — orchestrator polls a few times, stops, loses visibility ([TT-2374]) | Append the completion-report block to the seed prompt (Completion-report protocol section): worker `prompt_async`s a one-line status back into the orchestrator session on done/blocked/handoff, with issue-comment fallback |
|
||||
| 12 | Headless worker calls the `question` tool → no attached client: the question deadlocks in a queue, or `auto_approve` silently auto-approves a direction-setting decision ([TT-2378]) | NEVER call `question` from a headless worker. Decision boundary (Completion-report protocol section): directional/irreversible decision → `status=blocked` report + one-line decision point, then STOP; the orchestrator is the sole human-decision entry point |
|
||||
| 13 | Headless worker self-merges its PR / self-closes the issue once the PR looks ready, despite a seed instruction to keep it open ([TT-2386]; N-02 [TT-2367] / N-03 [TT-2368], commits `d1565c99` / `040f21b7`) | Self-merge / self-close / touching `main` are irreversible directional actions → blocked by the Decision boundary. PR ready → keep it OPEN, report `status=done branch=<ref>`; the orchestrator opens/admits the PR, merges and closes uniformly |
|
||||
| 14 | Trusting `state=generating` as "alive" — a hung stream goes unrescued (session A, 2026-08-16: `generating` 6+ min, count frozen at 478) | Poll state AND message count twice 30–60 s apart; frozen count = hung → abort + re-wake (Post-launch lifecycle section) |
|
||||
| 15 | Re-sending a wake prompt to a hung session and waiting — queued prompts are never consumed while the stream is dead | Abort FIRST (`POST /session/:id/abort` → 200, verify `idle`), THEN re-send; a prompt queued before the abort may still never fire — always re-deliver |
|
||||
| 16 | A worker woken from restart / long idle acts on its stale worldview — re-dispatches superseded work or claims authority it no longer holds (2026-08-16: revived worker re-ran an already-published FAIL verify; ops session announced an inherited "orchestrator" takeover) | Fact-baseline injection (Post-launch lifecycle section): authoritative facts + invalidated assumptions + one concrete re-assignment. Only the CURRENT authority injects; a session that suspects IT is stale verifies identity against the durable record first (`rules/compact.md` identity clause) |
|
||||
| 17 | Worker goes silent mid-task: provider quota wall killed the turn (usage limit / 429) — no completion-report, no blocked report; from the issue side indistinguishable from silent completion (2026-08-29 [org-internal #3627]: opencode-go `weekly usage limit reached` after the 13:18 Round-1 FAIL; ticket stalled until manually re-woken) | Detect via tail probe (`finish=error` + ⚠️ usage-limit part, `metadata.reason` in the quota family) + `GET /provider` quota markers; re-wake on a known-good provider with the fact-baseline template — `reference/quota-wall-recovery.md` ([org-internal #3669]). Prevent: pre-dispatch provider check + the seed's 配额自报 clause (`reference/completion-report.md`, [org-internal #3669]) — quota exhaustion is a `status=blocked reason=quota-exhausted` report, not a silent death |
|
||||
| 17 | Worker goes silent mid-task: provider quota wall killed the turn (usage limit / 429) — no completion-report, no blocked report; from the issue side indistinguishable from silent completion (2026-08-29 [TT-3627]: opencode-go `weekly usage limit reached` after the 13:18 Round-1 FAIL; ticket stalled until manually re-woken) | Detect via tail probe (`finish=error` + ⚠️ usage-limit part, `metadata.reason` in the quota family) + `GET /provider` quota markers; re-wake on a known-good provider with the fact-baseline template — `reference/quota-wall-recovery.md` ([TT-3669]). Prevent: pre-dispatch provider check + the seed's 配额自报 clause (`reference/completion-report.md`, [TT-3669]) — quota exhaustion is a `status=blocked reason=quota-exhausted` report, not a silent death |
|
||||
|
||||
## Known limitation (separate from this workaround)
|
||||
|
||||
@@ -482,9 +482,9 @@ catches that cause (`forkPromptDelivery` in `handlers/session.ts`) so the HTTP
|
||||
caller never sees it. The proper fix is to surface the error (or reject unusable
|
||||
models at the boundary) so a stalled session is diagnosable. Until then, **always
|
||||
provide an explicit known-good `model`** — this skill is the documented
|
||||
workaround (see [org-internal #1695] "遗留 minor").
|
||||
workaround (see [TT-1695] "遗留 minor").
|
||||
|
||||
**Update ([org-internal #2912], 2026-08-20)**: usage-limit turn failures (HTTP 429 /
|
||||
**Update ([TT-2912], 2026-08-20)**: usage-limit turn failures (HTTP 429 /
|
||||
FreeUsageLimitError / GoUsageLimitError) are no longer silent shells. When such
|
||||
a turn terminates (retry schedule ends or the spin is aborted), the errored
|
||||
assistant message persists `finish=error` plus a human-readable ⚠️ text part
|
||||
@@ -494,23 +494,23 @@ the web UI like any assistant text. Pitfall #14's double-poll is still the
|
||||
liveness check while a 429 retry spin is IN progress (the spin itself retries
|
||||
with backoff until interrupted); the explicit error part only appears once the
|
||||
turn ends. The general async-path observability gap above remains tracked by
|
||||
[org-internal #1695].
|
||||
[TT-1695].
|
||||
|
||||
## See also
|
||||
|
||||
- Source issue / full manual: **[org-internal #1695]** (this skill adds the ticket-driven recipe
|
||||
- Source issue / full manual: **[TT-1695]** (this skill adds the ticket-driven recipe
|
||||
- current-model reuse, and corrects the endpoint/claim against current code).
|
||||
- Completion-report protocol: **[org-internal #2374]** (worker-side active report back to the
|
||||
- Completion-report protocol: **[TT-2374]** (worker-side active report back to the
|
||||
launching orchestrator session; fallback to issue comment).
|
||||
- Quota-wall recovery recipe: **[org-internal #3669]** (evidence instance [org-internal #3627]) — detect a
|
||||
- Quota-wall recovery recipe: **[TT-3669]** (evidence instance [TT-3627]) — detect a
|
||||
worker killed by a provider usage limit, re-wake on a known-good provider,
|
||||
pre-dispatch prevention.
|
||||
- Decision boundary: **[org-internal #2378]** (headless worker MUST NOT call `question`;
|
||||
- Decision boundary: **[TT-2378]** (headless worker MUST NOT call `question`;
|
||||
directional decisions go through `status=blocked` reports to the
|
||||
orchestrator) and **[org-internal #2386]** (the worker MUST NOT self-merge its PR,
|
||||
orchestrator) and **[TT-2386]** (the worker MUST NOT self-merge its PR,
|
||||
self-close the issue, or touch `main` — the orchestrator merges and closes
|
||||
uniformly).
|
||||
- Correction of the prior misdiagnosis: **[org-internal #1691]** (closed Invalid), comment 9205.
|
||||
- Correction of the prior misdiagnosis: **[TT-1691]** (closed Invalid), comment 9205.
|
||||
- Synchronous client always sends `model`:
|
||||
`packages/app/src/components/prompt-input/submit.ts:158-165`.
|
||||
- Code citations: `<harness-package>/src/session/prompt.ts:858,804-822,1399`,
|
||||
@@ -525,15 +525,15 @@ turn ends. The general async-path observability gap above remains tracked by
|
||||
specific ticket (#N)`): read BEFORE creating any session for issue #N —
|
||||
Step-0 owner check, seed-prompt composition, launch + poll commands.
|
||||
- `reference/completion-report.md` — completion-report protocol (完成回报协议,
|
||||
[org-internal #2374]): read BEFORE composing a seed prompt for a worker you need to hear
|
||||
[TT-2374]): read BEFORE composing a seed prompt for a worker you need to hear
|
||||
back from — orchestrator block template, worker-side report steps, decision
|
||||
boundary ([org-internal #2378] / [org-internal #2386]), quota self-report clause ([org-internal #3669]).
|
||||
- `reference/lifecycle-ops.md` — post-launch lifecycle ([org-internal #2459]): read when
|
||||
boundary ([TT-2378] / [TT-2386]), quota self-report clause ([TT-3669]).
|
||||
- `reference/lifecycle-ops.md` — post-launch lifecycle ([TT-2459]): read when
|
||||
managing a launched session — health-check polling, hung-stream diagnosis
|
||||
(state=generating + frozen counters), abort + re-wake rescue,
|
||||
fact-baseline injection, authorization asymmetry.
|
||||
- `reference/quota-wall-recovery.md` — quota-wall recovery ([org-internal #3669], evidence
|
||||
[org-internal #3627]): read when a worker goes silent mid-task (suspected provider usage
|
||||
- `reference/quota-wall-recovery.md` — quota-wall recovery ([TT-3669], evidence
|
||||
[TT-3627]): read when a worker goes silent mid-task (suspected provider usage
|
||||
limit) or BEFORE dispatching a long-running worker — detection signals
|
||||
(finish=error ⚠️ tail, provider quota markers, log grep patterns),
|
||||
provider-switch re-wake + fact-baseline template, pre-dispatch provider
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
> Extracted from headless-session-ops/SKILL.md (Completion-report protocol (完成回报协议, [org-internal #2374])) — moved verbatim 2026-08-26, ticket [org-internal #3480].
|
||||
> Extracted from headless-session-ops/SKILL.md (Completion-report protocol (完成回报协议, [TT-2374])) — moved verbatim 2026-08-26, ticket [TT-3480].
|
||||
|
||||
## Completion-report protocol (完成回报协议, [org-internal #2374])
|
||||
## Completion-report protocol (完成回报协议, [TT-2374])
|
||||
|
||||
`prompt_async` is fire-and-forget **for the launcher too**: once the worker
|
||||
session starts generating, the orchestrator receives NO event when it finishes
|
||||
@@ -8,8 +8,8 @@ or blocks. The `task` tool auto-returns `task_result` for subagents; a
|
||||
`prompt_async`-launched independent main session has no equivalent — the
|
||||
orchestrator's only built-in channel is bare polling of
|
||||
`GET /session/:id/message?limit=1` (tail probe — the no-`limit` form loads the
|
||||
whole transcript server-side), which it eventually stops doing ([org-internal #2366]: worker ran
|
||||
~1h past the orchestrator's last poll, merged PR [org-internal #2371] and closed [org-internal #2366] while
|
||||
whole transcript server-side), which it eventually stops doing ([TT-2366]: worker ran
|
||||
~1h past the orchestrator's last poll, merged PR [TT-2371] and closed [TT-2366] while
|
||||
the orchestrator had zero visibility).
|
||||
|
||||
The protocol below closes that gap WITHOUT changing server semantics: the
|
||||
@@ -24,21 +24,21 @@ parallel chunk work, any long-running delegated ticket), append a
|
||||
completion-report block to the seed prompt. It MUST state:
|
||||
|
||||
- the orchestrator's **session id** (`$LAUNCHER_SID`) and **directory**;
|
||||
- the report endpoint: `POST $BASE/session/$LAUNCHER_SID/prompt_async?directory=$DIR` (or, when the directory is unknown to the worker, the global route `POST $BASE/prompt_async` with the sessionID in the body — [org-internal #4307]);
|
||||
- the report endpoint: `POST $BASE/session/$LAUNCHER_SID/prompt_async?directory=$DIR` (or, when the directory is unknown to the worker, the global route `POST $BASE/prompt_async` with the sessionID in the body — [TT-4307]);
|
||||
- the exact report format (one-line, machine-greppable);
|
||||
- the fallback (issue comment) if the report call fails.
|
||||
|
||||
Template (include verbatim in `seed.txt` when you are the launcher):
|
||||
|
||||
```text
|
||||
## 完成回报协议 (mandatory, [org-internal #2374])
|
||||
## 完成回报协议 (mandatory, [TT-2374])
|
||||
|
||||
你由编排会话 (orchestrator) 启动。完成、阻塞、或将工单移交他人时,必须向编排会话回报:
|
||||
POST <BASE>/session/<LAUNCHER_SID>/prompt_async?directory=<DIR>
|
||||
body: {"agent":"builder","model":{...},"parts":[{"type":"text","text":"<report>"}]}
|
||||
<report> 格式(单行,machine-greppable):
|
||||
[#<ticket>] [<node-or-slug>] status=done|blocked|handoff branch=<ref> [pr=#<N>] verify=<changed+typecheck> risk=<high|low> summary=<one line>
|
||||
默认(TD-678 / [org-internal #4425]):worker 只推分支不开 PR——交付推送前置本地验证
|
||||
默认(TD-678 / [TT-4425]):worker 只推分支不开 PR——交付推送前置本地验证
|
||||
(<harness-package> 下 test:changed 全绿 + typecheck 0 error,verify 字段回执);
|
||||
risk 按 risk-classifier 冻结表(HIGH_RISK_GLOBS)自报。PR 由编排按容量串行开
|
||||
1:1(正文携 worker 报告),或 batch 模式 epic 经 land-batch 技能按迭代统一合成
|
||||
@@ -46,15 +46,15 @@ risk 按 risk-classifier 冻结表(HIGH_RISK_GLOBS)自报。PR 由编排按
|
||||
若回报调用失败(HTTP 非 2xx / 连接拒绝 — orchestrator 会话可能已结束或实例重启),
|
||||
退而在源 issue(或父 Epic)发同内容评论作为兜底(fallback, 非主通道)。
|
||||
回报是你的 mandatory step,与 issue-checklist-sync 并列;不得静默结束。
|
||||
决策边界([org-internal #2378]):headless worker 禁止调用 `question` 工具 —— 遇方向性/不可逆
|
||||
决策边界([TT-2378]):headless worker 禁止调用 `question` 工具 —— 遇方向性/不可逆
|
||||
决策点 → `status=blocked` + 一行决策点描述后 STOP,勿调 question(无人应答死锁 /
|
||||
被 auto_approve 静默自动批准)。
|
||||
配额自报([org-internal #3669]):若收到配额/用量上限错误(usage limit / 429 / 402
|
||||
配额自报([TT-3669]):若收到配额/用量上限错误(usage limit / 429 / 402
|
||||
insufficient_quota),立即回报 status=blocked reason=quota-exhausted
|
||||
summary=<provider 与 ⚠️ 部分中的重置提示>(branch=<ref> 必带)后停止
|
||||
——勿自行换模型重试;换供应商重唤醒由编排者执行
|
||||
(reference/quota-wall-recovery.md)。
|
||||
PR 就绪后保持 open:不自行合并 PR、不关闭 issue、不动 main([org-internal #2386]);
|
||||
PR 就绪后保持 open:不自行合并 PR、不关闭 issue、不动 main([TT-2386]);
|
||||
合并与 issue 关闭由编排者统一执行。
|
||||
```
|
||||
|
||||
@@ -73,7 +73,7 @@ final step (before idling):
|
||||
done); `pr=#N` only for an `uncoordinated` self-open; use
|
||||
`status=blocked` + the blocker description when stuck; use
|
||||
`status=handoff` when deliberately transferring the ticket.
|
||||
1. **Quota exhaustion is a blocked report, not a silent death ([org-internal #3669]).** A
|
||||
1. **Quota exhaustion is a blocked report, not a silent death ([TT-3669]).** A
|
||||
worker whose turn is killed by a usage-limit error (429 / 402 quota
|
||||
family) cannot finish the turn — but per the seed's 配额自报 clause it
|
||||
reports `status=blocked reason=quota-exhausted summary=<provider +
|
||||
@@ -93,7 +93,7 @@ final step (before idling):
|
||||
remains the stakeholder-facing record; the report is the
|
||||
orchestrator-facing wake-up signal.
|
||||
|
||||
### Orchestrator side — serial PR admission on done reports ([org-internal #4425])
|
||||
### Orchestrator side — serial PR admission on done reports ([TT-4425])
|
||||
|
||||
On a `status=done branch=<ref> verify=… risk=…` report:
|
||||
|
||||
@@ -103,16 +103,16 @@ On a `status=done branch=<ref> verify=… risk=…` report:
|
||||
code; keep the queue shallow.
|
||||
2. Open the 1:1 PR (title from the ticket node, body carrying the worker
|
||||
report: branch / files / self-test / verify), apply the `Risk/*` label
|
||||
from the report's `risk=` hint, merge via `script/pr-merge.sh` ([org-internal #3864]).
|
||||
Batch-mode epics: one `land-batch` PR per iteration instead ([org-internal #3731]).
|
||||
from the report's `risk=` hint, merge via `script/pr-merge.sh` ([TT-3864]).
|
||||
Batch-mode epics: one `land-batch` PR per iteration instead ([TT-3731]).
|
||||
3. A first red on the opened PR goes back through the report fallback
|
||||
channel (issue comment) — the worker may already be idle; the issue
|
||||
comment is the durable re-entry point.
|
||||
|
||||
Prose discipline on the orchestrator session only — no new daemon, no
|
||||
mergeable-state automation (merge-coordinator retired, [org-internal #4385]).
|
||||
mergeable-state automation (merge-coordinator retired, [TT-4385]).
|
||||
|
||||
### Decision boundary (决策边界, [org-internal #2378])
|
||||
### Decision boundary (决策边界, [TT-2378])
|
||||
|
||||
The report channel defines how the worker *answers*; this subsection defines
|
||||
the boundary of what it may *ask*. A headless worker session has NO attached
|
||||
@@ -134,15 +134,15 @@ authority is layered instead:
|
||||
point, then STOPs. The orchestrator is the sole human-decision entry point:
|
||||
it interacts with the user, then replies to the worker (or acts on its
|
||||
behalf).
|
||||
- **No self-merge / no self-close / never touch main ([org-internal #2386])**: a headless
|
||||
- **No self-merge / no self-close / never touch main ([TT-2386])**: a headless
|
||||
worker MUST NOT merge its own PR, close the source issue, or rebase /
|
||||
force-push `main`. These are irreversible directional actions of exactly
|
||||
the class this boundary blocks — even when the seed prompt's instruction
|
||||
to "keep the PR open" is absent or the worker judges the PR ready. When
|
||||
the PR is ready the worker keeps it OPEN and reports
|
||||
`status=done pr=#N` to the orchestrator; the orchestrator performs the
|
||||
merge and the issue close uniformly. (Counter-example: N-02 [org-internal #2367] /
|
||||
N-03 [org-internal #2368] self-merged their PRs — commits `d1565c99` / `040f21b7` —
|
||||
merge and the issue close uniformly. (Counter-example: N-02 [TT-2367] /
|
||||
N-03 [TT-2368] self-merged their PRs — commits `d1565c99` / `040f21b7` —
|
||||
despite a seed instruction to keep them open.)
|
||||
- **Local implementation decisions within the AC scope** (pattern choice,
|
||||
helper extraction, test shape) → the worker decides autonomously and notes
|
||||
@@ -150,7 +150,7 @@ authority is layered instead:
|
||||
|
||||
Rule of thumb: the worker's only way to "ask" is a `status=blocked` report.
|
||||
A genuine ambiguity left by the seed prompt that would change scope is a
|
||||
blocked report, NOT a `question` call. (Field sample: N-04 [org-internal #2369] — the
|
||||
blocked report, NOT a `question` call. (Field sample: N-04 [TT-2369] — the
|
||||
worker spontaneously did NOT merge its own PR and left merging to the
|
||||
orchestrator; this subsection codifies that behavior.)
|
||||
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
> Extracted from headless-session-ops/SKILL.md (Post-launch lifecycle: health check, hung rescue, stale-worldview correction ([org-internal #2459])) — moved verbatim 2026-08-26, ticket [org-internal #3480].
|
||||
> Extracted from headless-session-ops/SKILL.md (Post-launch lifecycle: health check, hung rescue, stale-worldview correction ([TT-2459])) — moved verbatim 2026-08-26, ticket [TT-3480].
|
||||
|
||||
## Post-launch lifecycle: health check, hung rescue, stale-worldview correction ([org-internal #2459])
|
||||
## Post-launch lifecycle: health check, hung rescue, stale-worldview correction ([TT-2459])
|
||||
|
||||
Launching is half the job — a headless worker can hang silently or wake up
|
||||
with an outdated worldview. All three failure modes below were observed in
|
||||
production on 2026-08-16 during Epic [org-internal #2459] (ops-restart window); the runbooks
|
||||
production on 2026-08-16 during Epic [TT-2459] (ops-restart window); the runbooks
|
||||
are extracted from that incident record.
|
||||
|
||||
### Health check — three states, one poll pattern
|
||||
@@ -24,7 +24,7 @@ server-side:
|
||||
| idle | `state=idle` AND `progress` absent-or-stale across both polls | turn ended — read the LAST message (same `limit=1` fetch): task unfinished → wake prompt; `status=done` report → harvest |
|
||||
| **hung** | `state=generating` AND `progress.stepCount`/`lastStepAt` AND newest message id ALL frozen across both polls | the generation stream is dead; queued prompts will NEVER be consumed — rescue required |
|
||||
|
||||
`state` alone lies in BOTH directions ([org-internal #3215]): a hung session still reports
|
||||
`state` alone lies in BOTH directions ([TT-3215]): a hung session still reports
|
||||
`generating` (field sample: session A, 2026-08-16 — `state=generating` for 6+
|
||||
minutes with the message count frozen at 478), and a healthy mid-step worker
|
||||
can read `idle`/empty message tails in a single snapshot (2026-08-23 W3 wave:
|
||||
@@ -32,7 +32,7 @@ can read `idle`/empty message tails in a single snapshot (2026-08-23 W3 wave:
|
||||
discriminator; a single snapshot is NEVER an abort basis.**
|
||||
|
||||
`progress` (`stepCount` cumulative LLM-round counter, `lastStepAt` epoch-ms
|
||||
heartbeat — [org-internal #3215]) moves on every round even when message tails are
|
||||
heartbeat — [TT-3215]) moves on every round even when message tails are
|
||||
transiently empty or `state` flickers; it is absent for sessions that never
|
||||
ran since instance start (treat absent = no signal, fall back to count
|
||||
deltas). `lastStepAt` freshness alone does NOT prove liveness (a long tool
|
||||
@@ -77,7 +77,7 @@ claim authority it does not hold (field samples, 2026-08-16: a revived worker
|
||||
re-ran an M-01 verify another session had already published as FAIL —
|
||||
deduplicated via flag #comment-21590; an ops-notification session inherited an
|
||||
"orchestrator" identity from a compaction summary and announced a takeover —
|
||||
corrected via 勘误 #comment-21654/[org-internal #21668]).
|
||||
corrected via 勘误 #comment-21654/[TT-21668]).
|
||||
|
||||
When you detect a stale-worldview session, do not wait for it to finish being
|
||||
wrong — inject a fact-baseline prompt immediately (regular `prompt_async`),
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
> Added from headless-session-ops/SKILL.md (triggers `quota wall` / `配额墙`,
|
||||
> Post-launch lifecycle section, pitfall #17, References) — new runbook
|
||||
> 2026-08-29, ticket [org-internal #3669] (evidence instance [org-internal #3627]). Companion runbooks:
|
||||
> 2026-08-29, ticket [TT-3669] (evidence instance [TT-3627]). Companion runbooks:
|
||||
> `lifecycle-ops.md` (hung rescue, fact-baseline structure) and
|
||||
> `completion-report.md` §"Orchestrator side" (the quota self-report clause);
|
||||
> §Prevention is this file's own closing section.
|
||||
@@ -14,15 +14,15 @@ it looks EXACTLY like silent completion: no completion-report, no
|
||||
equals the orchestrator's polling interval, and without this runbook the
|
||||
recovery was improvised.
|
||||
|
||||
**Evidence instance ([org-internal #3627], 2026-08-29)** — the shapes below are field-verified:
|
||||
**Evidence instance ([TT-3627], 2026-08-29)** — the shapes below are field-verified:
|
||||
|
||||
|时刻 (+08)| 事件 |
|
||||
|---|---|
|
||||
| 08-29 13:18 | review-code Round-1 synthesis (FAIL) posted on [org-internal #3627]; worker session `ses_fb46e705bffe9kYbSoHayoJ1OQ` (builder, opencode-go model, branch `workflow/session/3627-wedge-promptasync`) entered its revision loop |
|
||||
| 08-29 13:18 | review-code Round-1 synthesis (FAIL) posted on [TT-3627]; worker session `ses_fb46e705bffe9kYbSoHayoJ1OQ` (builder, opencode-go model, branch `workflow/session/3627-wedge-promptasync`) entered its revision loop |
|
||||
| ~13:18–16:00 | worker hit the provider's `weekly usage limit reached` mid-revision — turn killed, **no** completion-report, **no** blocked report; issue side silent |
|
||||
| detection | orchestrator noticed the `/session` state stall, then confirmed via the quota error in the session log (message tail carries the ⚠️ usage-limit part, [org-internal #2912]) |
|
||||
| detection | orchestrator noticed the `/session` state stall, then confirmed via the quota error in the session log (message tail carries the ⚠️ usage-limit part, [TT-2912]) |
|
||||
| recovery | re-wake via `prompt_async` on a known-good provider (`zhipuai-coding-plan`/glm-5.3 — since renamed `zai-coding-plan`) **plus a fact-baseline injection** (what happened / what is done / where to resume) |
|
||||
| 16:26 / 16:51 | Round-2 synthesis PASS; `status=done pr=[org-internal #3675]` report received |
|
||||
| 16:26 / 16:51 | Round-2 synthesis PASS; `status=done pr=[TT-3675]` report received |
|
||||
|
||||
## Detection — three signals, in this order
|
||||
|
||||
@@ -35,7 +35,7 @@ SID=<worker session id>
|
||||
```
|
||||
|
||||
**Signal 1 — tail probe (primary; survives restarts, lives in the DB).** Since
|
||||
[org-internal #2912]/[org-internal #3190] a quota-killed turn persists an assistant message with
|
||||
[TT-2912]/[TT-3190] a quota-killed turn persists an assistant message with
|
||||
`finish=error` plus a human-readable ⚠️ text part whose metadata names the
|
||||
quota family. Probe the TAIL (`limit=1`, never the no-`limit` full transcript):
|
||||
|
||||
@@ -52,10 +52,10 @@ rate_limit}` (metadata also carries `provider`). The ⚠️ text is one of — a
|
||||
strings observed in this repo's runtime (`session/retry.ts`):
|
||||
|
||||
- `` `weekly usage limit` reached. It will reset in … `` / `Go limit reached`
|
||||
(GoUsageLimitError — the [org-internal #3627] shape; `weekly` is the body's `limitName`)
|
||||
(GoUsageLimitError — the [TT-3627] shape; `weekly` is the body's `limitName`)
|
||||
- `Free limit reached` (FreeUsageLimitError)
|
||||
- `Account-level usage limit — switching API keys does not reset it. You can
|
||||
continue after HH:mm.` ([org-internal #3407], zhipu/zai code 1308 — account-level)
|
||||
continue after HH:mm.` ([TT-3407], zhipu/zai code 1308 — account-level)
|
||||
- `Provider <id> rate limited (HTTP 429)` (generic 429)
|
||||
- `Generation failed — …` with a 402 `insufficient_quota` body (balance, not
|
||||
window — recovery is top-up, not provider switch)
|
||||
@@ -73,9 +73,9 @@ curl -s "$BASE/session?directory=$DIR" | jq -r --arg s "$SID" \
|
||||
30–60 s apart → the 429 retry spin is still running (it retries with backoff
|
||||
until the schedule ends) OR the stream is hung — treat exactly like the hung
|
||||
shape in `lifecycle-ops.md`: abort FIRST, then re-wake. A single snapshot is
|
||||
never an abort basis ([org-internal #3215]).
|
||||
never an abort basis ([TT-3215]).
|
||||
|
||||
**Signal 3 — provider-level confirmation ([org-internal #2911] quota markers).** `GET
|
||||
**Signal 3 — provider-level confirmation ([TT-2911] quota markers).** `GET
|
||||
/provider` overlays active usage-limit cooldowns, so the dead provider is
|
||||
visible without reading logs:
|
||||
|
||||
@@ -86,7 +86,7 @@ date -d @$(($(curl -s "$BASE/provider?directory=$DIR" | jq '[.all[].quota.resetA
|
||||
```
|
||||
|
||||
**Log grep (fallback; the dev log is restart-truncated).** Patterns actually
|
||||
seen in the wild — [org-internal #3627] produced the first:
|
||||
seen in the wild — [TT-3627] produced the first:
|
||||
|
||||
```sh
|
||||
grep -E "usage limit reached|Go limit reached|Free limit reached|Account-level usage limit|GoUsageLimitError|FreeUsageLimitError|rate limited \(HTTP 429\)|insufficient_quota" \
|
||||
@@ -96,7 +96,7 @@ grep -E "usage limit reached|Go limit reached|Free limit reached|Account-level u
|
||||
```
|
||||
|
||||
The wall is only terminal after failover has exhausted the same-name pools
|
||||
([org-internal #2911] failover); the `retrying … on …` WARNs above tell you the pool was
|
||||
([TT-2911] failover); the `retrying … on …` WARNs above tell you the pool was
|
||||
already draining before it died.
|
||||
|
||||
## Recovery — abort (only if needed), re-wake on a known-good provider, inject facts
|
||||
@@ -130,7 +130,7 @@ curl -s "$BASE/provider?directory=$DIR" | jq -r \
|
||||
# own current model — it is generating by definition).
|
||||
```
|
||||
|
||||
([org-internal #3627]: opencode-go dead → re-woken on zhipuai-coding-plan/glm-5.3, since
|
||||
([TT-3627]: opencode-go dead → re-woken on zhipuai-coding-plan/glm-5.3, since
|
||||
renamed `zai-coding-plan`. Do NOT "wait for reset" as the default — weekly
|
||||
windows mean days.)
|
||||
|
||||
@@ -159,9 +159,9 @@ curl -s "$BASE/provider?directory=$DIR" | jq -r \
|
||||
**Step 3 — re-wake with a fact-baseline prompt.** Build the payload from a file
|
||||
(`jq --rawfile`, SKILL.md pitfall #7), same wake shape as
|
||||
`lifecycle-ops.md` but with the quota facts. The template also restates the
|
||||
completion-report protocol ([org-internal #2374]) so the recovery is self-contained: it
|
||||
completion-report protocol ([TT-2374]) so the recovery is self-contained: it
|
||||
assumes the original seed still contains the protocol block — if you are
|
||||
unsure it does (e.g. the worker was dispatched before [org-internal #3669] added the quota
|
||||
unsure it does (e.g. the worker was dispatched before [TT-3669] added the quota
|
||||
clause), the template's own block below carries it; fill
|
||||
`<BASE>`/`<LAUNCHER_SID>`/`<DIR>` with the orchestrator session's values:
|
||||
|
||||
@@ -176,7 +176,7 @@ cat > wake.txt <<'EOF'
|
||||
3. 从哪继续:<一件具体的下一步任务>。
|
||||
4. 证据规则:逐条到引用来源(issue 评论 / PR / 工件)核实后再行动,
|
||||
勿仅凭本基线行动。
|
||||
## 完成回报协议(重申 [org-internal #2374]/[org-internal #3669];不确定原始 seed 是否含协议块时以本节为准)
|
||||
## 完成回报协议(重申 [TT-2374]/[TT-3669];不确定原始 seed 是否含协议块时以本节为准)
|
||||
完成、阻塞或移交时,必须回报编排会话(你的唤醒者):
|
||||
POST <BASE>/session/<LAUNCHER_SID>/prompt_async?directory=<DIR>
|
||||
body: {"agent":"builder","model":{...},"parts":[{"type":"text","text":"<report>"}]}
|
||||
@@ -195,7 +195,7 @@ jq -n --rawfile p wake.txt '{agent:"builder",
|
||||
Then poll the tail (`limit=1`) until an assistant message appears, and keep
|
||||
expecting the completion-report per protocol — the re-woken worker owes you
|
||||
`status=done|blocked` like any other (the restated block in the template
|
||||
makes this hold even when the original seed predates [org-internal #3669]).
|
||||
makes this hold even when the original seed predates [TT-3669]).
|
||||
|
||||
## Prevention — before dispatch, and in the seed
|
||||
|
||||
@@ -213,7 +213,7 @@ If the intended provider is already quota-marked, dispatch on a different one
|
||||
|
||||
**Quota self-report clause (turns a silent death into a harvestable
|
||||
blocked).** The canonical clause text lives in `completion-report.md`
|
||||
§"Orchestrator side" (配额自报, [org-internal #3669]) — append it VERBATIM to the seed
|
||||
§"Orchestrator side" (配额自报, [TT-3669]) — append it VERBATIM to the seed
|
||||
prompt's completion-report block. Single source of truth: do not fork or
|
||||
restate the clause here; its blocked payload already follows the one-line
|
||||
key=value spec (`status=blocked reason=quota-exhausted summary=<provider +
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
> Extracted from headless-session-ops/SKILL.md (Launch a session for a specific ticket (#N)) — moved verbatim 2026-08-26, ticket [org-internal #3480].
|
||||
> Extracted from headless-session-ops/SKILL.md (Launch a session for a specific ticket (#N)) — moved verbatim 2026-08-26, ticket [TT-3480].
|
||||
|
||||
## Launch a session for a specific ticket (#N)
|
||||
|
||||
@@ -7,13 +7,13 @@ work a tracked issue. Compose the seed prompt **from the issue itself** so the
|
||||
new session starts with real context, and launch it on **the current session's
|
||||
model**.
|
||||
|
||||
0. **Owner check (MANDATORY pre-step, [org-internal #1803]).** Before creating anything,
|
||||
0. **Owner check (MANDATORY pre-step, [TT-1803]).** Before creating anything,
|
||||
verify no other live session already owns this ticket or code area —
|
||||
duplicate ownership is how [org-internal #1744]/[org-internal #1753] collided. The check spans four
|
||||
duplicate ownership is how [TT-1744]/[TT-1753] collided. The check spans four
|
||||
data sources; any live claim → **ABORT the launch and report the
|
||||
conflict**.
|
||||
|
||||
**Mechanized ([org-internal #3667])**: `bash script/session-conflicts.sh <N>` runs the
|
||||
**Mechanized ([TT-3667])**: `bash script/session-conflicts.sh <N>` runs the
|
||||
session-title scan (a), the branch scan (d), and the open-PR check (c)
|
||||
in one read-only pass (exit 4 = conflict, `--json` for a machine
|
||||
summary); the assignee/claim check (b) is `claim.sh`'s compare-and-swap
|
||||
@@ -23,7 +23,7 @@ model**.
|
||||
**a. Session-title scan (live session check).** The listing endpoint
|
||||
returns at most `limit` (default 100) sessions — on busy repos (300+ live
|
||||
sessions in one directory) that silently truncates and the scan misses
|
||||
owners ([org-internal #3190]). Non-range listing responses carry `X-Total-Count` (full
|
||||
owners ([TT-3190]). Non-range listing responses carry `X-Total-Count` (full
|
||||
filter population, untruncated) and `X-Has-More: true` (only when the
|
||||
page is truncated). Scan procedure: fetch page 1, and when
|
||||
`X-Has-More: true` is present re-fetch once with `limit=$TOTAL` — treat
|
||||
@@ -57,7 +57,7 @@ model**.
|
||||
the launch and report the conflict** (issue comment naming the owning
|
||||
session id). Do not launch a second session for the same ticket.
|
||||
|
||||
**b. Assignee / claim check ([org-internal #2297]).** Read the issue via
|
||||
**b. Assignee / claim check ([TT-2297]).** Read the issue via
|
||||
`工单 API(见 TERMINOLOGY)get(owner, repo, index: N)` (or `GET /api/v1/repos/$OWNER/$REPO/issues/$N`):
|
||||
- If `assignee` is set and is **not** the launching agent → **ABORT** and
|
||||
report (the ticket is already claimed).
|
||||
@@ -68,7 +68,7 @@ model**.
|
||||
`GET <gitea-base-url>/api/v1/repos/issues/search?q="#N"&type=pulls&state=open`
|
||||
(API source) — and **ABORT** if an open PR already covers the ticket.
|
||||
|
||||
**d. Remote branch check ([org-internal #2297]).** A local branch is invisible to other
|
||||
**d. Remote branch check ([TT-2297]).** A local branch is invisible to other
|
||||
sessions — check the remote too:
|
||||
`git ls-remote origin 'workflow/*'` and scan for a branch tail covering `#N`.
|
||||
Also check the repo side locally: `git worktree list` +
|
||||
@@ -76,7 +76,7 @@ model**.
|
||||
|
||||
- A stale hit (session idle for hours / clearly abandoned) → do NOT
|
||||
hand-post a takeover comment (retired admin workaround — unauditable);
|
||||
dead-claim takeover is mechanized ([org-internal #3668]): `bash script/claim.sh
|
||||
dead-claim takeover is mechanized ([TT-3668]): `bash script/claim.sh
|
||||
takeover <ticket> <branch> --session-id <id>`. It enforces the
|
||||
evidence gate (branch ABSENT on origin AND (session 404 OR comment at
|
||||
least CLAIM_TAKEOVER_STALE_DAYS old)) and exits 10 when the evidence
|
||||
@@ -87,13 +87,13 @@ model**.
|
||||
§"Dead-claim takeover" (claim.sh header is normative).
|
||||
The runtime counterpart of this check is `core/rules/session-scope-guard.md`
|
||||
("One task, one owner"), injected into every session's prompt.
|
||||
- **Backend hard guard ([org-internal #1989]):** `POST /session` hard-rejects duplicate-ticket
|
||||
session creation with HTTP 400. The backend guard is **on by default ([org-internal #2350])**;
|
||||
- **Backend hard guard ([TT-1989]):** `POST /session` hard-rejects duplicate-ticket
|
||||
session creation with HTTP 400. The backend guard is **on by default ([TT-2350])**;
|
||||
set `enabled: false` in config to opt out. It fails open ONLY on defect
|
||||
paths (DB / config errors), never as a configured disable. The front-end
|
||||
soft check above is now backed by this backend hard check for defense in
|
||||
depth.
|
||||
- **Claim-first ([org-internal #2297]).** Claiming a ticket is one atomic 3-step action:
|
||||
- **Claim-first ([TT-2297]).** Claiming a ticket is one atomic 3-step action:
|
||||
(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 (`git push -u origin workflow/...`). The claim is valid ONLY when all
|
||||
@@ -101,7 +101,7 @@ model**.
|
||||
session until all three steps are done (see
|
||||
`core/rules/session-scope-guard.md` §"Claim-first"). If a collision HAS
|
||||
already happened, follow `rules/ownership-collision-runbook` (wiki, L2 on-demand).
|
||||
- **Provisioning after claim ([org-internal #3642]) is ONE command** — claim + worktree +
|
||||
- **Provisioning after claim ([TT-3642]) is ONE command** — claim + worktree +
|
||||
Tier-1 runs scaffold:
|
||||
`bash script/claim-provision.sh <N> workflow/<branch>` (runs claim.sh with
|
||||
exit codes passed through, attaches the session worktree to the claimed
|
||||
@@ -123,7 +123,7 @@ model**.
|
||||
- restate the **goal** in one sentence;
|
||||
- list the **constraints** and **acceptance criteria**;
|
||||
- cite every **wiki artifact path** / related issue referenced in the body
|
||||
(e.g. `{epic-slug}/dag`, `{epic-slug}/dag-nodes/{node-id}`, `[org-internal #1691]`);
|
||||
(e.g. `{epic-slug}/dag`, `{epic-slug}/dag-nodes/{node-id}`, `[TT-1691]`);
|
||||
- tell the new agent to follow the right pipeline skill for the work type
|
||||
(implement / bugfix / design / …).
|
||||
Write it to a file (handles newlines):
|
||||
@@ -141,16 +141,16 @@ your change — classify (pre-existing/flaky), file a BF/FT issue per
|
||||
core/rules/session-scope-guard.md, and continue this task. Do NOT fix
|
||||
unrelated failing tests in place.
|
||||
|
||||
## 完成回报协议 (mandatory, [org-internal #2374])
|
||||
## 完成回报协议 (mandatory, [TT-2374])
|
||||
|
||||
完成、阻塞、或移交时,向编排会话回报:
|
||||
POST <BASE>/session/<LAUNCHER_SID>/prompt_async?directory=<DIR>
|
||||
(编排目录未知时可用全局路由 POST <BASE>/prompt_async,body 携 sessionID,[org-internal #4307])
|
||||
(编排目录未知时可用全局路由 POST <BASE>/prompt_async,body 携 sessionID,[TT-4307])
|
||||
body: {"agent":"builder","model":{...},"parts":[{"type":"text","text":"<report>"}]}
|
||||
<report>: [#N] [<node-or-slug>] status=done|blocked|handoff branch=<ref> [pr=#<PR>] verify=<changed+typecheck> risk=<high|low> summary=<one line>
|
||||
约束:worker 只推分支不开 PR(PR 由编排串行开);交付推送前 test:changed+typecheck 须绿。若再遇配额/用量上限错误,立即回报 status=blocked reason=quota-exhausted summary=<provider 与重置提示>(branch=<ref> 必带)后停止,勿自行换模型重试。
|
||||
回报失败(非 2xx / 连接拒绝)→ 在本 issue(或父 Epic)发同内容评论兜底。
|
||||
决策边界([org-internal #2378]):遇方向性决策点 → status=blocked 回报,勿调 question。
|
||||
决策边界([TT-2378]):遇方向性决策点 → status=blocked 回报,勿调 question。
|
||||
EOF
|
||||
```
|
||||
|
||||
@@ -179,4 +179,4 @@ EOF
|
||||
|
||||
6. **Add the completion-report block to the seed prompt** (see next section) so
|
||||
the worker reports back when it finishes or blocks — without it, this
|
||||
orchestrator has no push channel and must poll forever ([org-internal #2374]).
|
||||
orchestrator has no push channel and must poll forever ([TT-2374]).
|
||||
|
||||
@@ -8,7 +8,7 @@ description: >
|
||||
self-checks against the relevant checklist before handing off to code
|
||||
review.
|
||||
# `stage` is intentionally omitted: `implement` is a production-phase name the
|
||||
# stage registry rules invalid post-[org-internal #3072] phase 3 (see
|
||||
# stage registry rules invalid post-[TT-3072] phase 3 (see
|
||||
# core/schemas/workflow-routing.schema.json stage enum — production-phase
|
||||
# names are "no longer valid anywhere"). The implement skill has no registry
|
||||
# gate id; the gates it feeds into are `review-code` and `verify`.
|
||||
@@ -77,7 +77,7 @@ In **pipeline mode** (work item from iteration plan), follow the standard precon
|
||||
|
||||
**On-demand references**: each mode's phase-by-phase detail (templates, prompts, orchestration flows, historical notes) lives in `reference/{mode}-mode.md`, NOT injected — read it at mode entry. Full read-timing table: References section.
|
||||
|
||||
> **Progressive disclosure ([org-internal #3734])**: when dispatching a Developer scoped to
|
||||
> **Progressive disclosure ([TT-3734])**: when dispatching a Developer scoped to
|
||||
> one mode, pass `skills: ["implement:mode-bugfix"]` (preamble + that
|
||||
> mode's workflow only) instead of the full body; pipeline-mode dispatches
|
||||
> should also carry `pipeline-detection`
|
||||
@@ -97,12 +97,12 @@ The Developer is responsible for:
|
||||
- Writing code that faithfully implements the design.
|
||||
- Running typecheck, lint, and tests to self-verify.
|
||||
- Self-checking against the relevant checklist before handoff.
|
||||
- Persisting the final report to disk before returning — worker-report persistence ([org-internal #2847], see `../_shared/worker-report-persistence.md`).
|
||||
- Persisting the final report to disk before returning — worker-report persistence ([TT-2847], see `../_shared/worker-report-persistence.md`).
|
||||
- Writing no more and no less than the work item scope — no opportunistic refactoring of unrelated code.
|
||||
|
||||
The Builder's role is to validate the implementation output and pass it to code review. The Builder MUST NOT write or revise implementation code.
|
||||
|
||||
### Pre-flight checklist injection ([org-internal #2599])
|
||||
### Pre-flight checklist injection ([TT-2599])
|
||||
|
||||
Before dispatching ANY Developer (or Tester) sub-agent — in every mode (implement / bugfix / refactor / port; pipeline or standalone) — the orchestrator resolves the ticket's route (the Process Assessment Gate Step 0 already resolves the Kind/* route) and reads `<instance-root>/workflow-routing.yaml` `routes.{Kind}.preflight`. When the list is non-empty, prepend it to the sub-agent's task prompt as:
|
||||
|
||||
@@ -162,7 +162,7 @@ Standard workflow for work items from an approved iteration plan. Full phase det
|
||||
>
|
||||
> At Phase 6 handoff, pass `mode: "dag-task"` to review-code (its DAG Task Mode keys off the same frozen-DAG-copy detection).
|
||||
|
||||
> **Legacy pipeline preconditions retired ([org-internal #3072] phase 3, 2026-08-21)**: tiered artifact-existence and review-convergence checks belonged to the archived legacy pipeline. Live input modes: DAG task mode (above) and standalone modes (the request itself is the spec). Historical tiered publish targets: `reference/implement-mode.md` § Legacy notes.
|
||||
> **Legacy pipeline preconditions retired ([TT-3072] phase 3, 2026-08-21)**: tiered artifact-existence and review-convergence checks belonged to the archived legacy pipeline. Live input modes: DAG task mode (above) and standalone modes (the request itself is the spec). Historical tiered publish targets: `reference/implement-mode.md` § Legacy notes.
|
||||
|
||||
Before starting implementation, confirm:
|
||||
|
||||
@@ -186,13 +186,13 @@ Every gate below is hard — agents rationalize skipping exactly these. Full det
|
||||
4. **Phase 4 — Self-Check** (all mandatory):
|
||||
1. `bun typecheck` (or project-equivalent) — zero errors.
|
||||
2. `bun oxlint --deny-warnings` (repo root — the review-code mechanical gate's canonical lint invocation; `bun lint` is the package-script alias) — zero errors.
|
||||
3. `bun run test:changed` (or project-equivalent; full suite `bun run test:parallel` is verify's job, not a per-revision gate, [org-internal #2598]) — all tests pass.
|
||||
3. `bun run test:changed` (or project-equivalent; full suite `bun run test:parallel` is verify's job, not a per-revision gate, [TT-2598]) — all tests pass.
|
||||
4. Post-deletion cleanup (when any code was removed): re-run lint + typecheck to catch orphaned imports/variables/type references.
|
||||
Then self-check `core/checklists/implementation.md`; every new function/method/exported API has ≥ 1 test; interface promises cross-checked against the node's edge contracts. **Review-readiness GATE**: self-attest `core/checklists/code-review.md` (COR, DGN, SEC, PERF, TST, STY, DBT, A11Y, DOC, TRC), record pass/fail per dimension in the Phase 5 report; handoff requires **0 BLOCKERs and 0 MAJORs** — if you can find a MAJOR, the formal review will too; fix it now.
|
||||
5. **Phase 4.5 — Iteration Completion Commit**: after ALL work items in the iteration pass Phase 4, commit with format `[{chunk-id}][{iteration}] {summary}`; commit body REQUIRED for non-trivial commits (> 1 file or > 20 LOC): What (files + purpose + the `WI-{NNN}` ID — code-review TRC 10.1), Why (design/REQ motivation), Evidence (test names / verification commands). Full rules: `reference/implement-mode.md` § Phase 4.5.
|
||||
6. **Phase 4.6 — Issue Checklist Sync (progressive)**: after committing, mark items this iteration delivered `- [x]` + `_(commit {sha}: file/component)_` per the `issue-checklist-sync` L1 rule; do NOT touch items outside this iteration's scope.
|
||||
7. **Phase 4.7 — PR-Creation Sync**: the session pushes its branch and reports `status=done branch=<ref> verify=… risk=…` — the orchestrator opens the PR (serially per TD-678/[org-internal #4425]) and applies the `Risk/*` label from the report's `risk=` hint, computed per the risk-classifier frozen table (`HIGH_RISK_GLOBS` in `.gitea/scripts/risk-classifier.ts`: core/migrations/deploy/`core/rules/**`/`.gitea/workflows/**` → `Risk/High`, else `Risk/Low`); `Risk/High` PRs merge manually by design. Once the PR exists, ensure `## 当前状态` exists (PR / 代码评审 / CI rows are written by the `status-sync` poller, NOT by hand); append the PR reference to the matching Epic task-list row. **Never hand-sync main into the PR branch** — that is the keep-mergeable workflow's job. Detail: `reference/implement-mode.md` § Phase 4.6 / § Phase 4.7.
|
||||
8. **Phase 5 — Report**: implementation report with AC → test traceability (template: `reference/implement-mode.md` § Phase 5). **Persist before returning ([org-internal #2847])** — the Developer's LAST action before returning the report: write it to `<runs-root>/{slug}/workers/{chunk-id}-worker-{seq}.md` (Tier 1 run workspace) else `/tmp/octopus/{chunk-id}-worker-{seq}.md` (`../_shared/worker-report-persistence.md`). The persisted copy is the report of record — applies to EVERY mode's report phase.
|
||||
7. **Phase 4.7 — PR-Creation Sync**: the session pushes its branch and reports `status=done branch=<ref> verify=… risk=…` — the orchestrator opens the PR (serially per TD-678/[TT-4425]) and applies the `Risk/*` label from the report's `risk=` hint, computed per the risk-classifier frozen table (`HIGH_RISK_GLOBS` in `.gitea/scripts/risk-classifier.ts`: core/migrations/deploy/`core/rules/**`/`.gitea/workflows/**` → `Risk/High`, else `Risk/Low`); `Risk/High` PRs merge manually by design. Once the PR exists, ensure `## 当前状态` exists (PR / 代码评审 / CI rows are written by the `status-sync` poller, NOT by hand); append the PR reference to the matching Epic task-list row. **Never hand-sync main into the PR branch** — that is the keep-mergeable workflow's job. Detail: `reference/implement-mode.md` § Phase 4.6 / § Phase 4.7.
|
||||
8. **Phase 5 — Report**: implementation report with AC → test traceability (template: `reference/implement-mode.md` § Phase 5). **Persist before returning ([TT-2847])** — the Developer's LAST action before returning the report: write it to `<runs-root>/{slug}/workers/{chunk-id}-worker-{seq}.md` (Tier 1 run workspace) else `/tmp/octopus/{chunk-id}-worker-{seq}.md` (`../_shared/worker-report-persistence.md`). The persisted copy is the report of record — applies to EVERY mode's report phase.
|
||||
9. **Phase 6 — Handoff to Code Review**: present the report; signal readiness via `signal_stage_done`. Do NOT mark the work item complete until code review passes.
|
||||
|
||||
#### Tester focus & Common Rationalizations
|
||||
@@ -216,7 +216,7 @@ The regression test MUST fail before the fix — the Tester dispatches between P
|
||||
2. **Phase 2 — Isolate Root Cause**: trace symptom → proximate cause → root cause (RCA template: `reference/bugfix-mode.md` § Phase 2); fixing a symptom → stop, go deeper; not found after 3 levels of indirection → pause and report, no surface-level patch. Then evaluate routing (below).
|
||||
3. **Phase 3 — Write a Regression Test**: exercise the exact bug path with the failing inputs; it MUST fail with the bug's symptom NOW, before the fix (already passing → the test does not cover the bug, rewrite it; no failing test possible → most targeted test, marked `[flaky]`).
|
||||
4. **Phase 4 — Fix**: minimum change resolving the root cause; one conceptual change per fix — no bundled refactoring, style changes, or "while I'm here" improvements (root cause in a different file → fix it there). Run the regression test (MUST pass) + relevant unit tests.
|
||||
5. **Phase 5 — Self-Check & Report**: `bun typecheck`; `bun oxlint --deny-warnings`; `bun run test:changed` (all pass; full suite belongs to verify); verify `core/checklists/bugfix.md`; publish the bugfix report as wiki page `{slug}/bugfix-report` (template: `reference/bugfix-mode.md` § Bugfix Report); persist per the Phase 5 persistence rule (Mode: implement, [org-internal #2847]).
|
||||
5. **Phase 5 — Self-Check & Report**: `bun typecheck`; `bun oxlint --deny-warnings`; `bun run test:changed` (all pass; full suite belongs to verify); verify `core/checklists/bugfix.md`; publish the bugfix report as wiki page `{slug}/bugfix-report` (template: `reference/bugfix-mode.md` § Bugfix Report); persist per the Phase 5 persistence rule (Mode: implement, [TT-2847]).
|
||||
6. **Phase 5.5 — Issue Checklist Sync (standalone bugfix)**: sync the source issue at each transition (commit / PR / review / CI / close) per the `issue-checklist-sync` L1 rule and its standalone-flow table.
|
||||
7. **Phase 6 — Approval**: present the report (prompt: `reference/bugfix-mode.md` § Phase 6 — Approval).
|
||||
|
||||
@@ -224,14 +224,14 @@ The regression test MUST fail before the fix — the Tester dispatches between P
|
||||
|
||||
Full escalate/stay criteria: `reference/bugfix-mode.md` § Routing Decision. In short — **escalate to pipeline** on ANY of: ≥ 5 files · ≥ 2 modules/components · design-level root cause · data migration / schema change · public-API / contract change · dependency change · > 50 lines · user requests full-process; **stay standalone** only when ALL the opposites hold. If uncertain, escalate — a false escalation costs review rounds; a false standalone decision skips quality gates.
|
||||
|
||||
**Big-bug relabel rule ([org-internal #3061])** — before the generic escalation above, split the triggers by kind:
|
||||
**Big-bug relabel rule ([TT-3061])** — before the generic escalation above, split the triggers by kind:
|
||||
|
||||
- **Design-level triggers** (root cause is a design decision — protocol / schema / architecture; shared-contract or public-API change; data migration): do NOT push through bugfix — **relabel the ticket `Kind/Feature`** and reroute via Step 0 (DAG route; 1–3 node small DAG expected); repro + root-cause notes become node input.
|
||||
- **Mechanical size triggers only** (many files / lines, same design): stay in bugfix — batch into iterations, keep review-code + verify. Scale alone never justifies a relabel.
|
||||
|
||||
#### Pipeline Mode (bugfix)
|
||||
|
||||
> **Legacy path retired ([org-internal #3072] phase 3)**: the requirements → design → review → plan front-end was archived; a big bug needing a design-level decision relabels `Kind/Feature` into the DAG route (big-bug relabel rule above).
|
||||
> **Legacy path retired ([TT-3072] phase 3)**: the requirements → design → review → plan front-end was archived; a big bug needing a design-level decision relabels `Kind/Feature` into the DAG route (big-bug relabel rule above).
|
||||
|
||||
When a bugfix escalates beyond standalone scope, the bug report becomes a pipeline input; the bugfix phases (reproduce, root cause, regression test, fix) are embedded within the implement stage, and review-code + verify remain mandatory. On the DAG route the node spec lives in `{epic-slug}/dag`; the Developer follows bugfix Phases 1–6 as the implementation method, then produces the standard implementation report (Mode: implement, Phase 5).
|
||||
|
||||
@@ -259,7 +259,7 @@ Restructure existing code without changing observable behavior — the existing
|
||||
1. **Phase 1 — Scope & Baseline**: map exact files + dependents; run `bun run test:parallel` (the refactor baseline legitimately needs the full suite) — ANY pre-existing failure → stop ("Cannot begin refactoring with failing tests. Fix them first."). Capture baseline: test count, coverage, optional complexity (template: `reference/refactor-mode.md` § Baseline).
|
||||
2. **Phase 2 — Define Target Pattern**: Extract / Inline / Rename / Move / Replace / Simplify / Upgrade, with one-sentence goal + success criteria (all tests pass unchanged; structural goal met; coverage does not decrease). Pipeline mode: align with the node spec + contracts, or justify in the report.
|
||||
3. **Phase 3 — Decompose into Steps**: smallest individually-verifiable steps (each reversible, suite-passing, ONE conceptual transformation); present the plan before executing (user may approve / reorder / reject). **If > 10 steps, the scope is too large — split into multiple sessions.**
|
||||
4. **Phase 4 — Incremental Execution**: per step — transform, run `bun run test:changed` (ALL pass; per-step scoped reruns — full suite is verify's job, [org-internal #2598]), commit `refactor: {what} from {where}`. **If FAIL: revert immediately** — do NOT fix the test or code within the same step; find a smaller decomposition (exception: fix a flaky test first as a prerequisite step, then retry).
|
||||
4. **Phase 4 — Incremental Execution**: per step — transform, run `bun run test:changed` (ALL pass; per-step scoped reruns — full suite is verify's job, [TT-2598]), commit `refactor: {what} from {where}`. **If FAIL: revert immediately** — do NOT fix the test or code within the same step; find a smaller decomposition (exception: fix a flaky test first as a prerequisite step, then retry).
|
||||
5. **Phase 5 — Final Validation**: `bun run test:parallel` all pass; `bun typecheck` zero errors; `bun oxlint --deny-warnings` zero errors; coverage MUST NOT decrease vs baseline (±1% noise).
|
||||
6. **Phase 6 — Report**: before/after metrics, steps executed, verification results, design deviations (template: `reference/refactor-mode.md` § Refactor Report).
|
||||
7. **Phase 7 — Approval**: present the report (prompt: `reference/refactor-mode.md` § Phase 7 — Approval). Route to code review if > 50 lines or ≥ 5 files.
|
||||
@@ -336,7 +336,7 @@ Not all work items involve writing new code — some are refactoring, bugfix, or
|
||||
- `core/skills/browser-debug/SKILL.md` — Interactive browser verification (for frontend work items) and UI bug reproduction (bugfix Phase 1)
|
||||
- `core/skills/review-code/SKILL.md` — Code review (next step after implementation)
|
||||
- `core/skills/verify/SKILL.md` — Integration + fidelity verification (pipeline-mode bugfix, large port)
|
||||
- `<instance-root>/archive/skills/` — Legacy requirements/design/plan/roadmap skills (archived [org-internal #3072] phase 3; their templates moved to `<instance-root>/archive/templates/`)
|
||||
- `<instance-root>/archive/skills/` — Legacy requirements/design/plan/roadmap skills (archived [TT-3072] phase 3; their templates moved to `<instance-root>/archive/templates/`)
|
||||
- `reference/source-analysis.md` — Port Phase A1, A1.5, A1.7, A1.8 detailed processes & templates
|
||||
- `reference/mapping-and-design.md` — Port Phase A2, A3, A4 detailed processes & templates
|
||||
- `reference/large-port-pipeline.md` — Port Phase B1–B4 detailed processes
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
> Extracted from implement/SKILL.md (Mode: bugfix) — moved verbatim 2026-08-25, ticket [org-internal #3381].
|
||||
> Extracted from implement/SKILL.md (Mode: bugfix) — moved verbatim 2026-08-25, ticket [TT-3381].
|
||||
|
||||
### Mode: bugfix
|
||||
|
||||
@@ -182,7 +182,7 @@ If the Developer is uncertain, escalate. A false pipeline escalation costs a few
|
||||
extra review rounds. A false standalone decision risks missing a quality gate on
|
||||
a complex change.
|
||||
|
||||
**Big-bug relabel rule ([org-internal #3061])** — before the generic escalation below, split
|
||||
**Big-bug relabel rule ([TT-3061])** — before the generic escalation below, split
|
||||
the triggers by kind:
|
||||
|
||||
- **Design-level triggers** (root cause is a design decision — protocol /
|
||||
@@ -449,7 +449,7 @@ resolves it by permitting triage but forbidding deferral.
|
||||
|
||||
#### Pipeline Mode (bugfix)
|
||||
|
||||
> **Legacy path retired ([org-internal #3072] phase 3, 2026-08-21)**: the full
|
||||
> **Legacy path retired ([TT-3072] phase 3, 2026-08-21)**: the full
|
||||
> requirements-elicitation → design → review-artifact(design-space) →
|
||||
> plan-iterations → review-artifact(plan) front-end was archived
|
||||
> (`<instance-root>/archive/skills/`). A big bug that needs a design-level decision
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
> Extracted from implement/SKILL.md (Mode: implement) — moved verbatim 2026-08-25, ticket [org-internal #3381].
|
||||
> Extracted from implement/SKILL.md (Mode: implement) — moved verbatim 2026-08-25, ticket [TT-3381].
|
||||
|
||||
### Mode: implement (default)
|
||||
|
||||
@@ -8,7 +8,7 @@ and self-verify before passing to code review.
|
||||
|
||||
#### Pre-flight
|
||||
|
||||
The pre-flight self-check prompt format ([org-internal #2599]), prepended to the Developer
|
||||
The pre-flight self-check prompt format ([TT-2599]), prepended to the Developer
|
||||
sub-agent's task prompt when `routes.{Kind}.preflight` is non-empty:
|
||||
|
||||
```
|
||||
@@ -75,7 +75,7 @@ Developer is structurally biased to miss.
|
||||
|
||||
#### Preconditions
|
||||
|
||||
> **Publish target (tiered targeting retired, [org-internal #3072] phase 3)**: the
|
||||
> **Publish target (tiered targeting retired, [TT-3072] phase 3)**: the
|
||||
> `Size/*`-tiered publish rule (`rules/workflow-routing.md` §"Publish target
|
||||
> by Size/* tier — RETIRED") was retired with the legacy producer skills.
|
||||
> Artifacts publish where the live mode puts them: DAG task mode → node spec
|
||||
@@ -125,7 +125,7 @@ Developer is structurally biased to miss.
|
||||
|
||||
Before starting implementation, confirm:
|
||||
|
||||
> **Legacy pipeline preconditions retired ([org-internal #3072] phase 3, 2026-08-21)**: the
|
||||
> **Legacy pipeline preconditions retired ([TT-3072] phase 3, 2026-08-21)**: the
|
||||
> tier-dependent requirements/design/plan artifact-existence checks and the
|
||||
> design-space / iteration-plan review-convergence checks that used to head
|
||||
> this list belonged to the archived legacy pipeline (`<instance-root>/archive/`).
|
||||
@@ -162,7 +162,7 @@ the work-item list from the frozen DAG copy: the ready/pending task nodes in
|
||||
`{epic-slug}/dag` (via `wiki 读写 API(见 TERMINOLOGY)`), cross-checked against the
|
||||
node tickets on the Epic's `## DAG 状态` table. (Legacy tier-based resolution
|
||||
via `{slug}/04-plan-04-iteration-assignment` was archived 2026-08-21,
|
||||
[org-internal #3072] phase 3.) Present the current ready nodes for selection:
|
||||
[TT-3072] phase 3.) Present the current ready nodes for selection:
|
||||
|
||||
```
|
||||
Current iteration: Iteration {N}: {Goal}
|
||||
@@ -346,7 +346,7 @@ a one-pass implementation into a multi-round review.
|
||||
| "Design is ambiguous here, I'll pick the obvious option" | Inventing a design decision is a Phase 2 abort condition. Flag the gap; do not guess. |
|
||||
| "Already manually verified it works" | Manual ≠ systematic — no record, can't re-run, can't bisect. `bun run test:changed` is the evidence the report demands. |
|
||||
| "Report is busywork, the diff speaks for itself" | No report → review-code cannot trace AC→test. Phase 5 is the handoff contract; skip it and the review stalls. |
|
||||
| "X× improvement — assumed, no measurement" | Quick-measure before it becomes an AC. Unverified assumptions in ACs waste framing cost ([org-internal #1932]: YAML token density assumed 2-3×, measured 0.95 — hypothesis rejected by data). |
|
||||
| "X× improvement — assumed, no measurement" | Quick-measure before it becomes an AC. Unverified assumptions in ACs waste framing cost ([TT-1932]: YAML token density assumed 2-3×, measured 0.95 — hypothesis rejected by data). |
|
||||
|
||||
---
|
||||
|
||||
@@ -463,14 +463,14 @@ waiting for the final verify gate.
|
||||
|
||||
The session pushes its branch and reports `status=done branch=<ref> verify=…
|
||||
risk=…`; the orchestrator admits the PR (serially, one open at a time) —
|
||||
workers never open PRs (TD-678/[org-internal #4425]; `uncoordinated` self-open only when
|
||||
workers never open PRs (TD-678/[TT-4425]; `uncoordinated` self-open only when
|
||||
the orchestrator is unreachable). Once that PR exists, update the source
|
||||
issue so stakeholders see the mergeable state without waiting for code
|
||||
review. Mandated by the `issue-checklist-sync` L1 rule; skip if no source
|
||||
issue exists.
|
||||
|
||||
> PR shape per mode: default = one 1:1 PR per task (body carries the worker
|
||||
> report); batch-mode epics ([org-internal #3731], per-epic opt-in) = the orchestrator
|
||||
> report); batch-mode epics ([TT-3731], per-epic opt-in) = the orchestrator
|
||||
> composes ONE batch PR per iteration via the `land-batch` skill. This phase
|
||||
> then runs per member issue as usual (N times), each pointing at its PR
|
||||
> (batch: the single batch PR); the poller writes the PR/CI/review rows
|
||||
@@ -549,7 +549,7 @@ Produce an implementation report:
|
||||
**Handoff**: Ready for `core/skills/review-code/SKILL.md`
|
||||
```
|
||||
|
||||
**Persist before returning ([org-internal #2847])**: the Developer MUST write the final
|
||||
**Persist before returning ([TT-2847])**: the Developer MUST write the final
|
||||
report above to disk as its LAST action, BEFORE returning it —
|
||||
`<runs-root>/{slug}/workers/{chunk-id}-worker-{seq}.md` when the Tier 1
|
||||
run workspace exists, else `/tmp/octopus/{chunk-id}-worker-{seq}.md`
|
||||
@@ -582,7 +582,7 @@ To notify workflow completion, call the `signal_stage_done` tool.
|
||||
|
||||
#### Legacy notes
|
||||
|
||||
> **Publish target (tiered targeting retired, [org-internal #3072] phase 3)**: the
|
||||
> **Publish target (tiered targeting retired, [TT-3072] phase 3)**: the
|
||||
> `Size/*`-tiered publish rule (`rules/workflow-routing.md` §"Publish target
|
||||
> by Size/* tier — RETIRED") was retired with the legacy producer skills.
|
||||
> Artifacts publish where the live mode puts them: DAG task mode → node spec
|
||||
|
||||
@@ -155,7 +155,7 @@ analysis:
|
||||
|
||||
## Phase B3 — Handoff to DAG Decomposition
|
||||
|
||||
> Legacy note ([org-internal #3072] phase 3, 2026-08-21): this handoff used to target the
|
||||
> Legacy note ([TT-3072] phase 3, 2026-08-21): this handoff used to target the
|
||||
> archived `roadmap` skill; it now targets `analyze-dag`.
|
||||
|
||||
Present the source analysis and request task-DAG decomposition:
|
||||
@@ -194,7 +194,7 @@ core/skills/implement/SKILL.md
|
||||
|
||||
(The legacy per-chunk `requirements-elicitation` → `design` →
|
||||
`review-artifact(design-space)` → `plan-iterations` → `review-artifact(plan)`
|
||||
front-end was archived 2026-08-21, [org-internal #3072] phase 3 — `<instance-root>/archive/`.)
|
||||
front-end was archived 2026-08-21, [TT-3072] phase 3 — `<instance-root>/archive/`.)
|
||||
|
||||
### implement
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
> Extracted from implement/SKILL.md (Mode: port) — moved verbatim 2026-08-25, ticket [org-internal #3381].
|
||||
> Extracted from implement/SKILL.md (Mode: port) — moved verbatim 2026-08-25, ticket [TT-3381].
|
||||
|
||||
### Mode: port
|
||||
|
||||
@@ -274,7 +274,7 @@ port (source analysis)
|
||||
→ verify (integration + fidelity)
|
||||
```
|
||||
|
||||
> Legacy diagram (archived [org-internal #3072] phase 3): the former per-chunk pipeline ran
|
||||
> Legacy diagram (archived [TT-3072] phase 3): the former per-chunk pipeline ran
|
||||
> requirements-elicitation → design → review (target: design-space) →
|
||||
> plan-iterations → review (target: plan) → implement → review-code. Those
|
||||
> skills/targets are archived (`<instance-root>/archive/`); the live path is the
|
||||
@@ -286,7 +286,7 @@ port (source analysis)
|
||||
| B1.5 | **GATE** — 10-dimensional peer review of source analysis | `reference/large-port-pipeline.md` |
|
||||
| B1.7+B1.8 | Target surface & capability boundary as formal artifacts for peer review | `reference/large-port-pipeline.md` |
|
||||
| B2 | Self-check source analysis against port checklist | `reference/large-port-pipeline.md` |
|
||||
| B3 | Handoff to analyze-dag — decompose by source module into DAG nodes (legacy: roadmap skill, archived [org-internal #3072] phase 3) | `reference/large-port-pipeline.md` |
|
||||
| B3 | Handoff to analyze-dag — decompose by source module into DAG nodes (legacy: roadmap skill, archived [TT-3072] phase 3) | `reference/large-port-pipeline.md` |
|
||||
| B4 | Per-node DAG task route: implement → review-code (the review-dag single gate replaces the legacy design-space + plan reviews at the Epic level) | `reference/large-port-pipeline.md` |
|
||||
| B5 | Verify — integration + fidelity, every `FID-*` traced to a passing test | `reference/fidelity-verification.md` |
|
||||
| B6 | **Final Approval** — consolidated port report | *(inline below)* |
|
||||
@@ -324,7 +324,7 @@ Present source analysis summary and request task-DAG decomposition. The
|
||||
Builder routes to `core/skills/analyze-dag/SKILL.md` with slug
|
||||
`port-{name}` (nodes per source module; the source analysis supplies node
|
||||
ACs and edge contracts). (Legacy: this handed off to the archived `roadmap`
|
||||
skill — `<instance-root>/archive/skills/roadmap/`, [org-internal #3072] phase 3.) See
|
||||
skill — `<instance-root>/archive/skills/roadmap/`, [TT-3072] phase 3.) See
|
||||
`reference/large-port-pipeline.md` for the handoff format.
|
||||
|
||||
##### Phase B4 — Per-Node Pipeline
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
> Extracted from implement/SKILL.md (Mode: refactor) — moved verbatim 2026-08-25, ticket [org-internal #3381].
|
||||
> Extracted from implement/SKILL.md (Mode: refactor) — moved verbatim 2026-08-25, ticket [TT-3381].
|
||||
|
||||
### Mode: refactor
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
> Extracted from implement/SKILL.md (Pipeline Work Item Detection) — moved verbatim 2026-08-25, ticket [org-internal #3381].
|
||||
> Extracted from implement/SKILL.md (Pipeline Work Item Detection) — moved verbatim 2026-08-25, ticket [TT-3381].
|
||||
|
||||
## Pipeline Work Item Detection
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
name: land-batch
|
||||
description: >
|
||||
Use ONLY when the orchestrator lands the finished task branches of one DAG
|
||||
iteration as a single batch PR ([org-internal #3731] batch-landing pilot). Composes
|
||||
iteration as a single batch PR ([TT-3731] batch-landing pilot). Composes
|
||||
path-disjoint member branches via the deterministic batch-compose script,
|
||||
pre-validates locally, opens ONE PR for N tasks (one CI fan-out instead of
|
||||
N on the single-runner pool), pastes each member's review synthesis into
|
||||
@@ -27,18 +27,18 @@ role: Producer
|
||||
(single writer at iteration close — the same role that already owns uniform
|
||||
merge/close). `workflow/batch/*` branches are NOT claim branches: no
|
||||
`claim.sh` interaction, no assignee; the orchestrator is the only composer.
|
||||
Pilot charter: the decision comment on [org-internal #3731] (scope, opt-in protocol, cap,
|
||||
Pilot charter: the decision comment on [TT-3731] (scope, opt-in protocol, cap,
|
||||
success criteria) — this skill implements that charter, not the epic's
|
||||
frozen DAG v1 (which covers only the merge-coordinator nodes N-01..04).
|
||||
|
||||
## Applicability: post-hoc composition only (topology B)
|
||||
|
||||
Two batch shapes exist ([org-internal #3731] charter addendum, comment 39347):
|
||||
Two batch shapes exist ([TT-3731] charter addendum, comment 39347):
|
||||
|
||||
- **Topology A — single-session mono-branch batch**: one session owns every
|
||||
ticket from inception and writes them on ONE branch (instance: PR [org-internal #3861],
|
||||
ticket from inception and writes them on ONE branch (instance: PR [TT-3861],
|
||||
audit-h1). Hand composition is natural there — do NOT force this skill on
|
||||
it; record the outcome on [org-internal #3731] as a manual-batch datum instead.
|
||||
it; record the outcome on [TT-3731] as a manual-batch datum instead.
|
||||
- **Topology B — parallel workers, post-hoc composition**: workers finish on
|
||||
SEPARATE branches at different times; the orchestrator composes at
|
||||
iteration close. This is the skill's ONLY applicability — cross-branch
|
||||
@@ -173,7 +173,7 @@ Do NOT hand-merge, do NOT hand-sync main into the batch branch.
|
||||
|
||||
Member issues auto-close via the English keywords; their `## 当前状态`
|
||||
PR/代码评审/CI rows fan out to EVERY close ref (status-sync poller Wide
|
||||
behavior — requires [org-internal #3867], merged 2026-08-31). `task done ≡ PR merged`
|
||||
behavior — requires [TT-3867], merged 2026-08-31). `task done ≡ PR merged`
|
||||
still holds, transitively
|
||||
through the batch PR; verify milestones fire unchanged.
|
||||
|
||||
@@ -189,15 +189,15 @@ through the batch PR; verify milestones fire unchanged.
|
||||
Any fallback preserves today's behavior — batch landing is an optimization,
|
||||
never a dependency.
|
||||
|
||||
## Measurement (pilot duty — revised per [org-internal #3731] charter addendum 39347)
|
||||
## Measurement (pilot duty — revised per [TT-3731] charter addendum 39347)
|
||||
|
||||
Per-iteration attribution only; the global 7-day ratio is trend context,
|
||||
never a pass/fail judge (same-window confounders: test-slim [org-internal #3855] /
|
||||
test-dedupe [org-internal #3854] / the pilot's own PRs). On the server,
|
||||
never a pass/fail judge (same-window confounders: test-slim [TT-3855] /
|
||||
test-dedupe [TT-3854] / the pilot's own PRs). On the server,
|
||||
`bun .gitea/scripts/ci-run-stats.ts --days 7 --json /tmp/<slug>-ci-stats.json`
|
||||
(the `--json` flag takes a filename — bare, it is a silent no-op; the human
|
||||
summary still prints). Same methodology as the checklist-merge-gate.yml
|
||||
2026-08-27 note. Record on [org-internal #3731]: (a) this batch iteration's per-workflow
|
||||
2026-08-27 note. Record on [TT-3731]: (a) this batch iteration's per-workflow
|
||||
trigger counts vs a historically similar 1:1 iteration, and (b) one
|
||||
fallback drill (construct a path-overlap group → exit-3 split executed).
|
||||
Baseline, trend only: 2026-08-31, 5,081 runs / TOTAL 2.75x single runner.
|
||||
|
||||
@@ -8,7 +8,7 @@ description: >
|
||||
project scaffolding. Do not use for application-level configuration —
|
||||
this skill covers the octopus project lifecycle, not user application code.
|
||||
triggers:
|
||||
# High-discrimination phrases only ([org-internal #4525]): bare "setup"/"init"/"配置" fire
|
||||
# High-discrimination phrases only ([TT-4525]): bare "setup"/"init"/"配置" fire
|
||||
# on any configuration mention, and the skill gate folds the previous
|
||||
# assistant turn on approval turns — one stray "配置" in a reply re-fires
|
||||
# the gate every turn. Keep triggers to phrases that name THIS workflow;
|
||||
@@ -36,7 +36,7 @@ This skill activates when the user's text matches any of the trigger keywords:
|
||||
- `project setup` — asking how to set up a project in octopus
|
||||
- `项目初始化` / `项目配置` — asking how to initialize or configure an octopus project (Chinese)
|
||||
|
||||
Generic "setup"/"init"/"配置" mentions are deliberately NOT triggers ([org-internal #4525]): they collide with everyday configuration talk, and the hard skill gate folds the previous assistant turn into its match text on approval turns — a passing "或配置x: false" in a reply would re-fire the gate every turn. `/init` note: `/init` generates AGENTS.md via LLM; kickoff uses the managed template from `octopus setup` — the Builder distinguishes based on context.
|
||||
Generic "setup"/"init"/"配置" mentions are deliberately NOT triggers ([TT-4525]): they collide with everyday configuration talk, and the hard skill gate folds the previous assistant turn into its match text on approval turns — a passing "或配置x: false" in a reply would re-fire the gate every turn. `/init` note: `/init` generates AGENTS.md via LLM; kickoff uses the managed template from `octopus setup` — the Builder distinguishes based on context.
|
||||
|
||||
Typical user intents include: encountering a readiness prompt at session start, wondering how to initialize a project, or wanting to understand the kickoff workflow steps.
|
||||
|
||||
@@ -74,14 +74,14 @@ The kickoff workflow runs in four automated steps:
|
||||
- [2/5] **Scaffold** — Creates the `<instance-root>/` skeleton (`core/skills/` directory + default `octopus.jsonc` template if absent); domain skills content arrives via the [5/5] overlay pull
|
||||
- [3/5] **Config stub + MCP wiring** — Writes the `mcp.codegraph` block into `octopus.jsonc`
|
||||
- [4/5] **Codegraph init** — Initializes and builds the per-project `.codegraph/` index
|
||||
- [5/5] **Skills remote + overlay pull** — Opt-in semantics ([org-internal #4370]); branches by flags when no `overlay.remotes` entry is configured:
|
||||
- [5/5] **Skills remote + overlay pull** — Opt-in semantics ([TT-4370]); branches by flags when no `overlay.remotes` entry is configured:
|
||||
- no flags (interactive run) — **safe default**: nothing is written; a remediation hint is printed (pass `--skills-remote`, or edit `overlay.remotes`), and the readiness skills item stays not-ready
|
||||
- `--yes` — legacy behavior kept: writes the default skills remote, then pulls domain skills content (`octopus skills pull` equivalent)
|
||||
- `--skills-remote <owner/repo>` (+ optional `--skills-remote-base-url <url>`) — writes the specified remote instead (ref `main`; base URL defaults to `<instance-base-url>`), then pulls from it
|
||||
- `overlay.remotes` already configured — the write is skipped (idempotent; an explicit `--skills-remote` is ignored with a warning)
|
||||
4. **Post-kickoff verification** — Run `octopus kickoff --check-only` again. After a `--yes` or `--skills-remote` run it reports all 5 items as ready; after a no-flag interactive run it reports 4 of 5 — the skills item stays not-ready until a remote is configured (`--skills-remote`, `--yes`, or a manual `overlay.remotes` edit + `octopus skills pull`).
|
||||
|
||||
### First-ticket hint ([org-internal #3061])
|
||||
### First-ticket hint ([TT-3061])
|
||||
|
||||
For a brand-new project still validating its concept, open the FIRST ticket as
|
||||
`Kind/MVP` — the interactive no-pipeline mode (decision log + debt register in
|
||||
|
||||
@@ -63,14 +63,14 @@ Run each check against the live project. Stop and report failures.
|
||||
- No new HIGH or CRITICAL CVEs block the release.
|
||||
- Pre-existing HIGH/CRITICAL CVEs do NOT block but **MUST be filed as
|
||||
tech-debt** before the release lands. File them in TWO TIERS (batching
|
||||
rule, [org-internal #3846] — a single release audit once fanned out to 14 TDs → 14 PRs →
|
||||
rule, [TT-3846] — a single release audit once fanned out to 14 TDs → 14 PRs →
|
||||
56-84 CI runs on a saturated runner pool): Tier A below is the general
|
||||
mechanical-change batching rule; Tier B and the escape hatch follow it.
|
||||
|
||||
<a id="phase-1-tier-a"></a>
|
||||
### Tier A — 通用机械变更并单规则 / Universal mechanical-change batching rule
|
||||
|
||||
Origin [org-internal #3846] (audit-batch pilot, generalized in place): the rule covers ANY
|
||||
Origin [TT-3846] (audit-batch pilot, generalized in place): the rule covers ANY
|
||||
single-source fan-out of mechanical changes, not just dependency audits.
|
||||
Two source types today: (a) dependency bump audits; (b) docs 批量修订
|
||||
(batch docs revisions).
|
||||
@@ -81,7 +81,7 @@ Two source types today: (a) dependency bump audits; (b) docs 批量修订
|
||||
source are filed as ONE batch issue + ONE batch PR — never N×issue +
|
||||
N×PR. The batch body keeps one row per item (per-CVE / per-doc mapping),
|
||||
so per-item traceability is unchanged; work the batch as a single PR.
|
||||
- **(a) Dependency bump audits** (the [org-internal #3846] origin case): advisories whose
|
||||
- **(a) Dependency bump audits** (the [TT-3846] origin case): advisories whose
|
||||
remediation is a plain version bump (lockfile-only diff, no semver-major
|
||||
jump, no overrides/catalog surgery, no API or adapter fallout) are filed
|
||||
together via REST `POST .../issues` with
|
||||
@@ -132,7 +132,7 @@ Two source types today: (a) dependency bump audits; (b) docs 批量修订
|
||||
along the reported pairs (or land the overlapping member 1:1) and re-run
|
||||
per group; `4` merge conflict / `5` transport/git error → fall back to
|
||||
1:1 PRs for the whole batch.
|
||||
- **Preflight hedge ([org-internal #3846])**: run `bun install --dry-run` before opening
|
||||
- **Preflight hedge ([TT-3846])**: run `bun install --dry-run` before opening
|
||||
a dependency-batch PR — the resolver accepting the composed version set
|
||||
is a cheap pre-CI rejection of impossible bump combinations.
|
||||
|
||||
@@ -292,7 +292,7 @@ Write to root `CHANGELOG.md` (prepend section).
|
||||
> the goal is identical (turn the tag into downloadable assets).
|
||||
|
||||
The CI publish pipeline (`.gitea/workflows/publish.yml`) was **retired by
|
||||
[org-internal #2003]** (138/138 historical runs cancelled; the pipeline sat unused for 35+
|
||||
[TT-2003]** (138/138 historical runs cancelled; the pipeline sat unused for 35+
|
||||
days). Releasing octopus is now a **manual local process**. All former CI
|
||||
steps live in repo scripts, runnable from a maintainer machine with the right
|
||||
credentials in the environment.
|
||||
@@ -358,11 +358,11 @@ credentials in the environment.
|
||||
### Notes
|
||||
|
||||
- **Windows code-signing** is not provisioned (no Windows runner / Azure
|
||||
Trusted Signing); the CLI ships unsigned, as before ([org-internal #252]).
|
||||
Trusted Signing); the CLI ships unsigned, as before ([TT-252]).
|
||||
- **Rollback**: if a step fails mid-release, the draft release + tag can be
|
||||
deleted and re-run; every script above is idempotent or safely re-runnable.
|
||||
- If a future CI pipeline replaces this manual flow, update this section and
|
||||
reference [org-internal #2003] for the retirement rationale.
|
||||
reference [TT-2003] for the retirement rationale.
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -232,7 +232,7 @@ review findings not actionable upstream]`.
|
||||
archive-at-close; (b) the committed archive bundles
|
||||
`<runs-root>/archive/{slug}.json`, where per-review round counts are
|
||||
reconstructed from the documented `reviews/{stage}/round{N}/` layout in
|
||||
`index.artifacts[].path` ([org-internal #2591] — the archive source is what makes M3
|
||||
`index.artifacts[].path` ([TT-2591] — the archive source is what makes M3
|
||||
durable instead of structurally emptying as runs close). Available once
|
||||
any run has closed.
|
||||
- Rework fraction: 🟢 <15% / 🟡 15–30% / 🔴 >30%.
|
||||
@@ -245,7 +245,7 @@ or upstream design unclear]`.
|
||||
- 🟢 cache_read/input > 10:1 / 🟡 3–10:1 / 🔴 < 3:1.
|
||||
- < 3:1 → `[SIGNAL: cache hit <3:1 — context re-read, code-graph-first
|
||||
not followed]`.
|
||||
- **Compact frequency ([org-internal #2601] pilot data)**: report the token-telemetry
|
||||
- **Compact frequency ([TT-2601] pilot data)**: report the token-telemetry
|
||||
"Compactor Activity" line (compactor messages/tokens in window) and the
|
||||
zero-compact share of short runs (bugfix / DAG task) — the capacity-driven compaction
|
||||
pilot metrics. A rising zero-compact share with NO late-stage
|
||||
@@ -259,7 +259,7 @@ not followed]`.
|
||||
- < 1:1 → `[SIGNAL: explore/execute <1:1 — workers doing explorers' job,
|
||||
exploration skipped or under-delegated]`.
|
||||
|
||||
### 2.8 Gate defect-escape analysis (single metric, [org-internal #3061])
|
||||
### 2.8 Gate defect-escape analysis (single metric, [TT-3061])
|
||||
|
||||
Gates earn their cost by what they CATCH, and the honest test is what slips
|
||||
past them: a gate that runs clean while the same defect resurfaces downstream
|
||||
@@ -297,7 +297,7 @@ status` CLI or commit-status inspection. Final reports at
|
||||
downstream sources for an escape.
|
||||
3. Tally per `gate_id`: `clean_runs`, `escapes`, `escape_rate`.
|
||||
4. Reading (thresholds are this skill's own policy — the `gate_trim:` block
|
||||
they once deferred to was retired 2026-08-21, [org-internal #3072] phase 3; nothing
|
||||
they once deferred to was retired 2026-08-21, [TT-3072] phase 3; nothing
|
||||
trims gates anymore, so the trim-candidate branch below is gone):
|
||||
- `escape_rate ≥ 0.3` → the gate is
|
||||
**UNDER-POWERED**: route the escape causes into §2.9 pre-flight
|
||||
@@ -305,12 +305,12 @@ status` CLI or commit-status inspection. Final reports at
|
||||
propose trimming it.
|
||||
- `escape_rate < 0.3` → healthy; report the numbers, no further verdict.
|
||||
|
||||
**DAG single-gate exclusion ([org-internal #2267])**: `review-dag` is structurally
|
||||
**DAG single-gate exclusion ([TT-2267])**: `review-dag` is structurally
|
||||
non-trimmable (`dag.route.single_gate.never_trim: true` — self-contained in
|
||||
the `dag:` block); `verify` and `merge-pr` were `never_trim` in the retired
|
||||
`gate_trim` block and stay untouchable by convention.
|
||||
|
||||
**keep_gates exclusion (TD-390, [org-internal #3061]) — RETIRED with gate_trim**: the
|
||||
**keep_gates exclusion (TD-390, [TT-3061]) — RETIRED with gate_trim**: the
|
||||
rule that a trim candidate's gate must not be a member of the target route's
|
||||
`keep_gates` guarded a landing field (`sizing.tiers.*.additional_skip`)
|
||||
that no longer exists. Historical record: wiki `rules/gate-trim`.
|
||||
@@ -331,10 +331,10 @@ runs for a gate → report the raw numbers with
|
||||
- [NOTE: insufficient sample for gate X] where clean runs < 5.
|
||||
- UNDER-POWERED gates (escape_rate ≥ 0.3) feed §2.9 pre-flight — never a
|
||||
unilateral trim: the only exit is a furlough entry in
|
||||
`<instance-root>/gate-ledger.yaml` (evidence + reopen condition, [org-internal #3607]).
|
||||
`<instance-root>/gate-ledger.yaml` (evidence + reopen condition, [TT-3607]).
|
||||
```
|
||||
|
||||
### 2.9 Pre-flight defect-prevention analysis ([org-internal #2599])
|
||||
### 2.9 Pre-flight defect-prevention analysis ([TT-2599])
|
||||
|
||||
First-round FAIL/WARN findings are the pipeline's cost multiplier: every
|
||||
multi-round review pays for them twice (review round + revision round).
|
||||
@@ -348,13 +348,13 @@ code.
|
||||
reports for the cycle's tickets (`{slug}/reviews/{stage}/final/report` —
|
||||
round-1 findings with severity FAIL/WARN, their dimension codes, and the
|
||||
finding text for root-cause categorization) + the source issues'
|
||||
`Kind/*` labels. For DAG-routed Epics ([org-internal #2905] 方案 3), two further
|
||||
`Kind/*` labels. For DAG-routed Epics ([TT-2905] 方案 3), two further
|
||||
read-only sources feed the `REQ × late-discovery` root cause (step 1):
|
||||
(a) **DAG oversize-signal events** — `node_split` / registry-row additions
|
||||
recorded on the Epic's issue timeline / `## DAG 状态` whose trigger is a NEW
|
||||
requirement rather than a refactor; (b) **demo-period feedback** —
|
||||
stakeholder comments naming functionality the frozen DAG never covered. For browser-evidence
|
||||
cycles ([org-internal #4499], contract `browser-evidence-4486/shared/evidence-ref-v1` §3), a
|
||||
cycles ([TT-4499], contract `browser-evidence-4486/shared/evidence-ref-v1` §3), a
|
||||
third read-only
|
||||
source: (c) **browser session rows** — per browser-debug session
|
||||
`{session_id, outcome: evidence-captured | env-unavailable | replay-failed,
|
||||
@@ -373,7 +373,7 @@ Rows are currently Task-DAG cycle products by default (the helper's
|
||||
Bug- or Feature-cycle session to its own landing slot). The replay
|
||||
success-rate baseline (N-03 BENCH) is exposed as a consumable metric — a SEEDED CONVENTION (fixture-authored outcomes, channel health),
|
||||
NOT a live-browser trend baseline. Mechanical helper:
|
||||
`<harness-package>/scripts/browser-retro-tally.ts`. Boundary rules ([org-internal #4499]
|
||||
`<harness-package>/scripts/browser-retro-tally.ts`. Boundary rules ([TT-4499]
|
||||
AC-3): out-of-enum or empty categories fall into an explicit `other` bucket
|
||||
with provenance (recorded, never silently swallowed, never a crash); rows
|
||||
missing replay/attribution fields yield structured errors in the tally
|
||||
@@ -395,10 +395,10 @@ late-discovery` — 冻结后才被发现的需求 (a requirement that surfaced
|
||||
oversize signal or demo comment — count it from sources (a)/(b) above,
|
||||
not only from review findings.
|
||||
2. Tally per **route-class** — `Bug`, `Feature-DAG`, `Epic-DAG-route`,
|
||||
`Task-DAG` (Kind/Feature routes to the DAG pipeline since [org-internal #3061] Phase 2 /
|
||||
`Task-DAG` (Kind/Feature routes to the DAG pipeline since [TT-3061] Phase 2 /
|
||||
TD-388 — `Feature-legacy` survives only as a historical bucket for tickets
|
||||
closed before 2026-08-20; the Size dimension is retired from retro keying,
|
||||
[org-internal #3061]: DAG-routed tickets derive depth instead of carrying `Size/*`
|
||||
[TT-3061]: DAG-routed tickets derive depth instead of carrying `Size/*`
|
||||
(spec-06), and `Kind/Bug` carries no ladder). First-round hit count
|
||||
and distinct-ticket count per cause per class.
|
||||
3. A cause is a **pre-flight candidate** when ALL hold (thresholds from
|
||||
@@ -408,7 +408,7 @@ late-discovery` — 冻结后才被发现的需求 (a requirement that surfaced
|
||||
A qualifying `Epic × DAG-route` cause (e.g. `REQ × late-discovery`) lands
|
||||
on `<instance-root>/workflow-routing.yaml` `dag.route.preflight` — NOT
|
||||
`routes.Kind/Epic.preflight` (legacy-roadmap-era landing; the legacy route
|
||||
was archived [org-internal #3072] phase 3) ([org-internal #2905] 方案 3). The analyze-dag skill reads
|
||||
was archived [TT-3072] phase 3) ([TT-2905] 方案 3). The analyze-dag skill reads
|
||||
`dag.route.preflight` before decomposition.
|
||||
4. Aging: for causes ALREADY landed in `routes.{Kind}.preflight` or
|
||||
`dag.route.preflight`, count
|
||||
@@ -423,7 +423,7 @@ Sample-sufficiency guard mirrors 2.8: zero qualifying tickets → emit
|
||||
|
||||
| route-class | Cause (checklist-qualified dim × root-cause) | 1st-round hits | tickets | qualify? |
|
||||
| -------------- | ------------------------------------------- | -------------- | --------------------------- | -------------------------------- |
|
||||
| Bug | code-review.md COR × unhandled-null | 5 | 4 ([org-internal #2400] [org-internal #2429] [org-internal #2471] [org-internal #2488]) | ✅ PROPOSE |
|
||||
| Bug | code-review.md COR × unhandled-null | 5 | 4 ([TT-2400] [TT-2429] [TT-2471] [TT-2488]) | ✅ PROPOSE |
|
||||
| Bug | code-review.md STY × wrong-import-order | 6 | 2 | ⛔ tickets <3 |
|
||||
| Feature-DAG | code-review.md TST × missing-boundary-test | 3 | 3 | ⛔ hits <5 |
|
||||
| Epic-DAG-route | REQ × late-discovery | 5 | 3 (#27xx #28xx #29xx) | ✅ PROPOSE → dag.route.preflight |
|
||||
@@ -433,7 +433,7 @@ Sample-sufficiency guard mirrors 2.8: zero qualifying tickets → emit
|
||||
- Landed-item aging: `cor-unhandled-null clean streak 5 ≥ aging 5` → REMOVAL row.
|
||||
```
|
||||
|
||||
### 2.10 Derived-ticket health ([org-internal #3061])
|
||||
### 2.10 Derived-ticket health ([TT-3061])
|
||||
|
||||
Derived tickets (TD promotions, BF umbrellas, FT tickets) are the pipeline's
|
||||
exhaust. Unmanaged they accumulate into flush cycles (2026-08 evidence: 122
|
||||
@@ -477,7 +477,7 @@ this probe checks whether the system DIGESTS what it records:
|
||||
- rows marked [COLD] this cycle: {list or "none"}
|
||||
```
|
||||
|
||||
### 2.11 Threshold calibration tally ([org-internal #3380])
|
||||
### 2.11 Threshold calibration tally ([TT-3380])
|
||||
|
||||
Process prose constants (round caps, D1–D4 thresholds, preflight knobs,
|
||||
escape-rate cutoffs, quotas — full index:
|
||||
@@ -665,7 +665,7 @@ Each item MUST specify:
|
||||
- Action items that modify SKILLs or templates are applied immediately (the
|
||||
Retrospective Lead can edit `<instance-root>/` files).
|
||||
- Action items MUST NOT be vague ("try harder", "be more careful").
|
||||
- **Layering question** (injection-budget ruling item 3, [org-internal #3547]): every action
|
||||
- **Layering question** (injection-budget ruling item 3, [TT-3547]): every action
|
||||
item that encodes a lesson as a process constraint MUST answer **"which
|
||||
layer carries this lesson?"** — options in ascending per-turn cost, pick
|
||||
the cheapest that actually enforces it:
|
||||
@@ -682,7 +682,7 @@ Each item MUST specify:
|
||||
corpus — do not casually re-grow it; the rule-GC report in that same check
|
||||
flags aging L1 rules for L2 retirement).
|
||||
|
||||
**TRIM PROPOSAL rows — RETIRED ([org-internal #3072] phase 3, 2026-08-21)**: the
|
||||
**TRIM PROPOSAL rows — RETIRED ([TT-3072] phase 3, 2026-08-21)**: the
|
||||
gate-trim landing machinery (`gate_trim.action` →
|
||||
`sizing.tiers.{Size}.additional_skip` / `routes.{Kind}.skip` /
|
||||
`auto_approve.stages`) was removed with the `gate_trim:` and `sizing:`
|
||||
@@ -691,12 +691,12 @@ Gate health findings flow exclusively through §2.8's escape-rate verdict
|
||||
(UNDER-POWERED → §2.9 pre-flight) and ordinary action items. Historical
|
||||
spec: wiki `rules/gate-trim` (L2).
|
||||
|
||||
**PRE-FLIGHT PROPOSAL rows** (from Phase 2.9 defect-prevention, [org-internal #2599]): format
|
||||
**PRE-FLIGHT PROPOSAL rows** (from Phase 2.9 defect-prevention, [TT-2599]): format
|
||||
the What cell as
|
||||
`Add pre-flight '{id}' to {Kind} ({hits} first-round FAIL/WARN hits, {tickets} tickets — {evidence})`
|
||||
and the Where cell as
|
||||
`<instance-root>/workflow-routing.yaml` `routes.{Kind}.preflight` — or, for causes
|
||||
keyed `Epic × DAG-route` (e.g. `REQ × late-discovery`, [org-internal #2905] 方案 3),
|
||||
keyed `Epic × DAG-route` (e.g. `REQ × late-discovery`, [TT-2905] 方案 3),
|
||||
`<instance-root>/workflow-routing.yaml` `dag.route.preflight` (consumed by
|
||||
analyze-dag before decomposition).
|
||||
Aging removal rows: `Remove pre-flight '{id}' from {Kind} (clean streak {N} ≥ aging threshold)`.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
---
|
||||
name: review-artifact
|
||||
description: >-
|
||||
Use ONLY after analyze-dag has produced the DAG artifact — review the task DAG (review-dag single gate) — OR when auditing the <instance-root>/ process infrastructure itself (audit-process). Spawns N parallel Explorer reviewers (1 dimension each) against the matching checklist, synthesizes findings with a Worker Synthesizer, and iterates with a Worker reviser until convergence. The legacy roadmap / design-space / iteration-plan targets were archived 2026-08-21 ([org-internal #3072] phase 3, <instance-root>/archive/). Do NOT use for code review — use the review-code skill for that.
|
||||
Use ONLY after analyze-dag has produced the DAG artifact — review the task DAG (review-dag single gate) — OR when auditing the <instance-root>/ process infrastructure itself (audit-process). Spawns N parallel Explorer reviewers (1 dimension each) against the matching checklist, synthesizes findings with a Worker Synthesizer, and iterates with a Worker reviser until convergence. The legacy roadmap / design-space / iteration-plan targets were archived 2026-08-21 ([TT-3072] phase 3, <instance-root>/archive/). Do NOT use for code review — use the review-code skill for that.
|
||||
triggers:
|
||||
- audit-process
|
||||
- review-dag
|
||||
@@ -25,7 +25,7 @@ role: Reviewer
|
||||
## Tool Availability & Path Resolution
|
||||
|
||||
This skill's reviewers (parallel Explorer subagents) read two kinds of files.
|
||||
Some runs cannot reach the Gitea REST API (cross-repo scenario, [org-internal #2115]); the
|
||||
Some runs cannot reach the Gitea REST API (cross-repo scenario, [TT-2115]); the
|
||||
fallbacks below keep reviews working without it.
|
||||
|
||||
The Orchestrator probes REST reachability **before dispatching reviewers** (Phase A
|
||||
@@ -74,7 +74,7 @@ This skill reviews different artifact types. Identify the target from the pipeli
|
||||
| **review-dag** | `review-dag` | `core/checklists/dag-single-gate.md` | 3 | Analyst | `{epic-slug}/reviews/review-dag/` |
|
||||
|
||||
> **Retired targets (historical)**: the `roadmap`, `design-space`, and `plan`
|
||||
> targets were archived on 2026-08-21 per [org-internal #3072] phase 3 (ruling:
|
||||
> targets were archived on 2026-08-21 per [TT-3072] phase 3 (ruling:
|
||||
> `docs/workflow-refactor/phase3-retirement-ruling.md`) — the legacy
|
||||
> production skills they gated no longer exist (see `<instance-root>/archive/`).
|
||||
> Their stage ids (`review-roadmap`, `review-design-space`,
|
||||
@@ -84,7 +84,7 @@ This skill reviews different artifact types. Identify the target from the pipeli
|
||||
|
||||
The stage IDs remain as-is — they are used by the stage registry and auto-approve system. The skill name is `review-artifact`, but the stage IDs do not change.
|
||||
|
||||
> **Progressive disclosure ([org-internal #3734])**: this skill has two disjoint live
|
||||
> **Progressive disclosure ([TT-3734])**: this skill has two disjoint live
|
||||
> targets — dispatch an auditor/reviewer with
|
||||
> `skills: ["review-artifact:target-process"]` or
|
||||
> `["review-artifact:target-review-dag"]` (preamble + that target only)
|
||||
@@ -148,7 +148,7 @@ Before launching any review, confirm:
|
||||
|
||||
Each target adds specific preconditions listed in its section below. If any precondition is unmet, abort and inform the user.
|
||||
|
||||
> ## Retired targets (historical, [org-internal #3072] phase 3)
|
||||
> ## Retired targets (historical, [TT-3072] phase 3)
|
||||
|
||||
The three legacy production-review targets — **roadmap** (stage
|
||||
`review-roadmap`, checklist `roadmap.md`, revision role Analyst),
|
||||
@@ -187,7 +187,7 @@ The audit target is the **SDLC factory itself** — the set of skills, checklist
|
||||
- [ ] `core/skills/` exists and contains at least one `SKILL.md`.
|
||||
- [ ] `core/checklists/audit-process.md` is accessible.
|
||||
- [ ] `core/schemas/` contains the shared review schemas (`reviewer-output`, `synthesis`, `review-status`).
|
||||
- [ ] **Process-tests-green gate ([org-internal #4787] STD 8.8)**: before dispatching
|
||||
- [ ] **Process-tests-green gate ([TT-4787] STD 8.8)**: before dispatching
|
||||
auditors, the Orchestrator (bash-capable; Explorer auditors have none by
|
||||
construction) runs the process's own suite and guards — from
|
||||
`<harness-package>`: `bun run test:parallel`, plus the repo-root `check:*`
|
||||
@@ -366,9 +366,9 @@ from `Size/*` labels.
|
||||
| D1 | 1 | `all` |
|
||||
| D2 | 3 | `TOPO:1 REQMAP:1 RELEASE:1` |
|
||||
| D3 | 5 | `TOPO:2 REQMAP:2 RELEASE:1` |
|
||||
| D4 | 5 ([org-internal #3061] cap) | `TOPO:2 REQMAP:2 RELEASE:1` |
|
||||
| D4 | 5 ([TT-3061] cap) | `TOPO:2 REQMAP:2 RELEASE:1` |
|
||||
|
||||
> **D4 cap ([org-internal #3061])**: D4 keeps its own rounds budget (4) but its fanout is
|
||||
> **D4 cap ([TT-3061])**: D4 keeps its own rounds budget (4) but its fanout is
|
||||
> capped at D3 level (5 reviewers) — under the 3-dimension + checklist-bound
|
||||
> review the marginal coverage of 9 reviewers was redundancy, and round
|
||||
> iteration is the backstop.
|
||||
@@ -390,7 +390,7 @@ file (concurrent write race):
|
||||
`core/schemas/reviewer-output.schema.json`. Finding ids inside slot
|
||||
files MUST be slot-prefixed (`{DIM}R{k}-F{NNN}`, e.g. `TOPOR1-F001`) so ids
|
||||
stay unique across a dimension's slot files. This preserves per-reviewer
|
||||
attribution (retrospective overlap analysis, [org-internal #2996] step ①a) and makes the
|
||||
attribution (retrospective overlap analysis, [TT-2996] step ①a) and makes the
|
||||
write race impossible by construction.
|
||||
- Synthesis input for a dimension = ALL `findings-{DIM}*.json` in the round
|
||||
directory — the synthesizer already globs every `findings-*.json`; the slot
|
||||
|
||||
@@ -5,7 +5,7 @@ description: >
|
||||
ticket under a DAG-routed parent) against the node spec + frozen
|
||||
cross-session contracts of the frozen DAG copy (`{epic-slug}/dag`), or in
|
||||
standalone-bugfix mode without a design baseline. (The legacy
|
||||
approved-design pipeline mode was archived 2026-08-21, [org-internal #3072] phase 3.) Spawns up to 10 parallel Explorer reviewers (risk-tier scaled;
|
||||
approved-design pipeline mode was archived 2026-08-21, [TT-3072] phase 3.) Spawns up to 10 parallel Explorer reviewers (risk-tier scaled;
|
||||
fewer in standalone-bugfix mode where DGN may be skipped) against core/checklists/code-review.md, synthesizes
|
||||
findings with a Worker Synthesizer (the main-session Orchestrator aggregates), and iterates with a Worker developer until
|
||||
convergence.
|
||||
@@ -57,7 +57,7 @@ abstract best practices.
|
||||
|
||||
Before launching this review, confirm:
|
||||
|
||||
> **Legacy pipeline preconditions retired ([org-internal #3072] phase 3, 2026-08-21)**: the
|
||||
> **Legacy pipeline preconditions retired ([TT-3072] phase 3, 2026-08-21)**: the
|
||||
> design-document / design-space-convergence / iteration-plan-convergence
|
||||
> checks that used to head this list belonged to the archived legacy pipeline
|
||||
> (`design` / `plan-iterations` skills — `<instance-root>/archive/`). Live entry
|
||||
@@ -66,7 +66,7 @@ Before launching this review, confirm:
|
||||
> runs' design pages stay readable via `_shared/gitea-read-patterns.md`.
|
||||
|
||||
- [ ] Code files to review are specified (list of file paths or use `git diff`).
|
||||
- [ ] Mechanical-green gate PASSED (L0-enforced, [org-internal #2598]): run
|
||||
- [ ] Mechanical-green gate PASSED (L0-enforced, [TT-2598]): run
|
||||
`bun core/skills/review-code/scripts/precondition-gate.ts {slug}` —
|
||||
CI-aligned checks (`bun oxlint --deny-warnings` + `bun turbo typecheck`
|
||||
+ `test:changed` with `CI=true TEST_SHARDS=3`, mirroring ci.yml).
|
||||
@@ -83,7 +83,7 @@ Before launching this review, confirm:
|
||||
- [ ] 跨阶段门控清单: `core/checklists/pipeline-gate.md` is accessible and
|
||||
its Upstream Review Convergence section has been confirmed item by item.
|
||||
|
||||
**Kind/MVP graduation chokepoint ([org-internal #3061])**: when this skill is invoked ad hoc
|
||||
**Kind/MVP graduation chokepoint ([TT-3061])**: when this skill is invoked ad hoc
|
||||
on a `Kind/MVP` ticket's changes (no mode, no pipeline), the mechanical-green
|
||||
gate applies, and the Orchestrator additionally checks the diff for
|
||||
**graduation triggers** — changes crossing ≥2 modules, touching a shared
|
||||
@@ -110,9 +110,9 @@ no design doc exists at `.artifacts/{slug}/design/index.md`(存量只读,不
|
||||
|
||||
**Weakened preconditions** for standalone mode:
|
||||
|
||||
- Design doc existence → NOT required (the legacy design pipeline is archived, [org-internal #3072] phase 3).
|
||||
- Design doc existence → NOT required (the legacy design pipeline is archived, [TT-3072] phase 3).
|
||||
- **Instead require**: `.artifacts/{slug}/repro-notes.md`(存量只读,不迁移;Gitea 等效:wiki page `{slug}/repro-notes`,`_shared/gitea-read-patterns.md` Pattern 1)exists (bugfix Phase 1-2 output: reproduction steps + root cause) OR `.artifacts/{slug}/impl-notes.md`(存量只读,不迁移;Gitea 等效:wiki page `{slug}/impl-notes`,`_shared/gitea-read-patterns.md` Pattern 1)exists (post-fix behavior contract).
|
||||
- All other Preconditions (code files specified, mechanical-green gate green ([org-internal #2598]), checklist accessible) STILL APPLY.
|
||||
- All other Preconditions (code files specified, mechanical-green gate green ([TT-2598]), checklist accessible) STILL APPLY.
|
||||
- The `core/checklists/pipeline-gate.md` cross-stage gate (Upstream Review Convergence section) → NOT required; the bugfix-specific Pre-Design Falsification Gate section still applies if relevant.
|
||||
|
||||
**DGN dimension handling**: In standalone-bugfix mode, the DGN (Design Compliance & Dependencies) reviewer is SKIPPED because there is no design to comply with. The Orchestrator dispatches 9 reviewers (all 10 dimensions except DGN).
|
||||
@@ -120,7 +120,7 @@ no design doc exists at `.artifacts/{slug}/design/index.md`(存量只读,不
|
||||
**What standalone bugfix review focuses on**: code correctness, error handling & compatibility (COR), regression coverage (TST), security (SEC), performance (PERF), style & conventions (STY), database & data (DBT), accessibility & browser compatibility (A11Y), documentation (DOC), traceability (TRC) — everything that does not depend on a design baseline.
|
||||
|
||||
**Historical**: the legacy pipeline mode (design doc + design-space/plan
|
||||
review convergence as preconditions) was archived 2026-08-21 ([org-internal #3072] phase 3).
|
||||
review convergence as preconditions) was archived 2026-08-21 ([TT-3072] phase 3).
|
||||
Historical design pages remain readable via `_shared/gitea-read-patterns.md`.
|
||||
|
||||
### DAG Task Mode
|
||||
@@ -147,7 +147,7 @@ table and implement's §"DAG-mode input path"):
|
||||
| Iteration-plan review converged (`--stage iteration-plan`) | REMOVED (DAG has no plan review; the single review-dag gate replaces both) |
|
||||
| `slug` matches the design slug | N/A (review is scoped to the node ticket; run slug = `{epic-slug}-task-{node-id}` — the same node-task run namespace verify's task mode archives to — so review outputs are node-scoped and never clobber sibling nodes' reports. Note: this namespace covers review + verify runs only; the node's implement report below lives in the Epic run workspace `{epic-slug}/workers/` — implement worker runs keep the Epic run slug (implement §Preconditions: "DAG: `{epic-slug}`"), a different run from this review run) |
|
||||
| `core/checklists/pipeline-gate.md` Upstream Review Convergence | NOT required — the review-dag convergence check above stands in its place |
|
||||
| All other preconditions (code files specified, mechanical-green gate green ([org-internal #2598]), checklist accessible) | KEEP — unconditional; plus the implement report (AC → test traceability) present — Tier 1 at `<runs-root>/{epic-slug}/workers/{node-id}-worker-{seq}.md` (implement Phase 5 persistence; `{chunk-id}` = the node id) |
|
||||
| All other preconditions (code files specified, mechanical-green gate green ([TT-2598]), checklist accessible) | KEEP — unconditional; plus the implement report (AC → test traceability) present — Tier 1 at `<runs-root>/{epic-slug}/workers/{node-id}-worker-{seq}.md` (implement Phase 5 persistence; `{chunk-id}` = the node id) |
|
||||
|
||||
The `{BASELINE_SECTION}` for DAG-task mode uses the node spec + cross-session
|
||||
edge contracts from `{epic-slug}/dag` instead of the design index; the 5-Check
|
||||
@@ -228,7 +228,7 @@ file is a test file.
|
||||
- Design-space review convergence → NOT required.
|
||||
- Iteration-plan review convergence → NOT required.
|
||||
- All Preconditions from the pipeline checklist are bypassed.
|
||||
- Only requires: the mechanical-green gate ([org-internal #2598]) — same script as the full
|
||||
- Only requires: the mechanical-green gate ([TT-2598]) — same script as the full
|
||||
mode; on a test-only changeset `test:changed` selects exactly the changed
|
||||
tests, so the gate cost stays proportional to the diff.
|
||||
|
||||
@@ -263,7 +263,7 @@ fall back to the appropriate full mode (pipeline or standalone-bugfix).
|
||||
|
||||
## Agent Roles
|
||||
|
||||
> **Progressive disclosure ([org-internal #3722])**: when dispatching a Reviewer /
|
||||
> **Progressive disclosure ([TT-3722])**: when dispatching a Reviewer /
|
||||
> Synthesizer / Developer scoped to one phase, pass
|
||||
> `skills: ["review-code:phase-a"]` (preamble — incl. dimensions, JSON
|
||||
> schema, prompt template — plus that phase only) instead of the full body;
|
||||
@@ -338,7 +338,7 @@ audit (`review-artifact` targets):
|
||||
| `core/schemas/synthesis.schema.json` | Orchestrator round synthesis (Tier 2 — synthesis comment) |
|
||||
| `core/schemas/review-status.schema.json` | Review lifecycle tracking |
|
||||
|
||||
> **Findings sink: `tier1-local`** ([org-internal #1988]). `review-code` writes raw
|
||||
> **Findings sink: `tier1-local`** ([TT-1988]). `review-code` writes raw
|
||||
> per-dimension findings to Tier 1 local files (`<runs-root>/{slug}/reviews/code/`),
|
||||
> not Gitea issue comments. The synthesis comment + commit status stay Tier 2.
|
||||
> See `_shared/review-pipeline-phases.md` "Output model — two findings sinks"
|
||||
@@ -362,7 +362,7 @@ table).
|
||||
- `{REVIEWER_ROLE}`: code reviewer
|
||||
- `{BASELINE_SECTION}`:
|
||||
|
||||
**Legacy pipeline mode** (archived 2026-08-21, [org-internal #3072] phase 3 — the design
|
||||
**Legacy pipeline mode** (archived 2026-08-21, [TT-3072] phase 3 — the design
|
||||
doc at `{slug}/03-design-*` / `{slug}/02-03-req-design` it read is
|
||||
historical; live modes use the two baselines below):
|
||||
|
||||
@@ -464,7 +464,7 @@ table).
|
||||
|
||||
When invoked from the `implement` skill in bugfix mode (caller passes
|
||||
`mode: "standalone-bugfix"` — the legacy "detect absence of a design doc"
|
||||
fallback is retired with the design pipeline, [org-internal #3072] phase 3):
|
||||
fallback is retired with the design pipeline, [TT-3072] phase 3):
|
||||
|
||||
1. The Orchestrator dispatches **9 reviewers** (all 10 dimensions **except DGN** — Design Compliance & Dependencies), because there is no design baseline to audit compliance against.
|
||||
2. For any dimension that would normally receive design reference files (COR, DGN, SEC, PERF, TST, DBT, A11Y, DOC, TRC), substitute the bugfix baseline docs:
|
||||
@@ -480,7 +480,7 @@ fallback is retired with the design pipeline, [org-internal #3072] phase 3):
|
||||
```
|
||||
5. The `{CONTRADICTION_RULE}` is weakened: code that contradicts repro-notes/impl-notes is a MAJOR — there is no design to elevate to BLOCKER.
|
||||
6. All other Phase A dispatch rules (reviewer comment posting, commit status, reviewer prompt template, temperature, permissions, worktree-path rule) apply unchanged.
|
||||
7. Efficiency optimization (round 2+, [org-internal #2598]): follows the shared Phase D rule (`_shared/review-pipeline-phases.md` Phase D "Efficiency optimization") with no standalone-mode deviation — partial re-dispatch, full sweep every 2 rounds, delta-scoped reviewer input.
|
||||
7. Efficiency optimization (round 2+, [TT-2598]): follows the shared Phase D rule (`_shared/review-pipeline-phases.md` Phase D "Efficiency optimization") with no standalone-mode deviation — partial re-dispatch, full sweep every 2 rounds, delta-scoped reviewer input.
|
||||
|
||||
**Orchestrator actions**:
|
||||
|
||||
@@ -498,7 +498,7 @@ fallback is retired with the design pipeline, [org-internal #3072] phase 3):
|
||||
|
||||
2. Initialize or update review status by posting a commit status via `POST /api/v1/repos/Octopus/octopus/statuses/{sha}` (`_shared/gitea-write-patterns.md` Pattern 8) with context `pipeline/review-code`. The commit-status payload carries `state` and `description`; the full review lifecycle state is documented in `core/schemas/review-status.schema.json` and tracked by the `octopus review status` CLI.
|
||||
|
||||
2.5. **Mechanical-green gate (mandatory, [org-internal #2598])** — before spawning ANY reviewer,
|
||||
2.5. **Mechanical-green gate (mandatory, [TT-2598])** — before spawning ANY reviewer,
|
||||
run `bun core/skills/review-code/scripts/precondition-gate.ts {slug} --round {N}`
|
||||
from the worktree root. Exit 0 → continue to step 3. Exit 1 → the script has
|
||||
appended a PRECONDITION-BLOCK record (Tier 1,
|
||||
@@ -516,7 +516,7 @@ fallback is retired with the design pipeline, [org-internal #3072] phase 3):
|
||||
|
||||
3. Spawn **all reviewers in parallel** (10 in pipeline mode at Large tier; fewer at Small/Medium tiers; DGN skipped in standalone-bugfix mode). Each reviewer receives:
|
||||
- The standardized prompt (above) with dimension-specific values filled in.
|
||||
- For round ≥ 2 ([org-internal #2598] delta scoping): `{FILE_SECTIONS}` lists ONLY the
|
||||
- For round ≥ 2 ([TT-2598] delta scoping): `{FILE_SECTIONS}` lists ONLY the
|
||||
files revised since the previous round plus their 3–5 convention-comparison
|
||||
neighbors — not the round-1 full file set. Round 1 keeps the full set.
|
||||
- Agent type: Explorer.
|
||||
@@ -607,7 +607,7 @@ fallback is retired with the design pipeline, [org-internal #3072] phase 3):
|
||||
- Updates review status by posting a commit status via `POST /api/v1/repos/Octopus/octopus/statuses/{sha}` (`_shared/gitea-write-patterns.md` Pattern 8)with context `pipeline/review-code`.
|
||||
- Persists its return summary to
|
||||
`<runs-root>/{slug}/reviews/code/round{N}/synthesis-return.md` (Tier 1,
|
||||
worker-report persistence [org-internal #2847] — see
|
||||
worker-report persistence [TT-2847] — see
|
||||
`_shared/worker-report-persistence.md`) BEFORE returning, and registers
|
||||
the `index.json` row (type `other`, schema null, stage `review-code`,
|
||||
produced_by `Synthesizer`). The persisted copy is the report of record —
|
||||
@@ -633,240 +633,14 @@ fallback is retired with the design pipeline, [org-internal #3072] phase 3):
|
||||
---
|
||||
|
||||
<!-- section:phase-c -->
|
||||
## Phase C — Developer Revision
|
||||
### Phase C+D — Developer Revision & Re-review Loop — see `reference/revision-loop.md`
|
||||
|
||||
If `overall_verdict` is PASS, skip to Phase E.
|
||||
> Phase C (Developer revision: task-file preparation, revision survival via
|
||||
> `task_id` resume, convergence tracking) and Phase D (re-review loop until
|
||||
> convergence or round budget exhaustion) live in
|
||||
> `reference/revision-loop.md`. Read it when `overall_verdict` is not PASS.
|
||||
> On PASS, skip both phases and proceed to Phase E.
|
||||
|
||||
Otherwise:
|
||||
|
||||
**Orchestrator actions**:
|
||||
|
||||
1. Prepare the Developer's input as a structured task file,
|
||||
created as a wiki page via `wiki 读写 API(见 TERMINOLOGY)` (`_shared/gitea-write-patterns.md` Pattern 1)with page_name `{slug}/reviews/code/round{N}/task-developer`.
|
||||
|
||||
This file must contain:
|
||||
- Paths to all code files that need revision.
|
||||
- Reference to the synthesis comment on the ticket (posted via `工单评论 API(见 TERMINOLOGY)` in Phase B — Tier 2).
|
||||
- References to the Tier 1 finding files for dimensions that have FAIL or WARN
|
||||
verdicts (`<runs-root>/{slug}/reviews/code/round{N}/findings-{DIMENSION_CODE}.json`).
|
||||
- The Developer MUST NOT receive the full text of all reviewer findings
|
||||
inline — use finding-file path references only to avoid context explosion.
|
||||
- Convergence status: blockers/majors remaining vs. previous round.
|
||||
- **Revision survival ([org-internal #2601]) — primary path**: the task tool's completion
|
||||
output includes a `task_id`; passing it back resumes the SAME Developer
|
||||
subagent session instead of creating a fresh one. Round 1: persist the
|
||||
returned `task_id` with the round's working-notes entry (it must survive
|
||||
round-boundary compaction). Round ≥ 2: dispatch with `task_id` set to the
|
||||
previous revision round's — the Developer continues in-session with its
|
||||
prior diff/context; the round's task page then carries only the findings
|
||||
delta, not a full re-derivation. Reviewers are NEVER resumed — per-round
|
||||
freshness is their independence.
|
||||
- **Revision survival — fallback** (task_id lost to compaction before it
|
||||
was persisted): prepend the current `<runs-root>/{slug}/working-notes.md`
|
||||
content (run narrative memory — prior decisions, dead ends, reviewer
|
||||
feedback from earlier rounds) and reference the previous round's revision
|
||||
summary (`{slug}/reviews/code/round{N-1}/revision-summary`), stating
|
||||
explicitly that this revises code a prior round already wrote — do NOT
|
||||
re-read the full design/acceptance artifacts unless a finding requires
|
||||
them.
|
||||
|
||||
2. Spawn the Developer (Worker) with the prompt
|
||||
template at `core/skills/_shared/review-revision-prompt.md`, substituting:
|
||||
|
||||
- `{ROLE}`: Developer
|
||||
- `{TASK_FILE}`: task-developer
|
||||
- `{REVISION_SCOPE}`: Apply the Developer Revision Protocol (see Protocol
|
||||
subsection below) — evaluate each finding against codebase reality:
|
||||
Explorer reviewers are automated LLM sub-agents that can hallucinate
|
||||
citations, misapply rules, or miss design context. Verify cited code
|
||||
exists, the rule applies, and the fix does not break existing
|
||||
functionality. WAIVE technically-incorrect findings with justification
|
||||
(`WAIVED-{finding-id}` → one-line reason; canonical definition of the
|
||||
`WAIVED-{id}` convention, incl. the round-2+ cosmetic-MINOR waiver
|
||||
rule: `_shared/review-revision-prompt.md`). Revise code minimally and
|
||||
surgically — do NOT refactor unrelated code or introduce new behavior.
|
||||
- `{RESOLUTION_RULE}`: Do NOT silently deviate from the approved baseline
|
||||
(DAG task mode: the node spec + frozen cross-session contracts in
|
||||
`{epic-slug}/dag`; the legacy `{slug}/03-design-*` baseline is archived
|
||||
historical, [org-internal #3072] phase 3). If a finding exposes a design flaw, mark it
|
||||
as deferred with justification and suggest a design amendment — do not
|
||||
change the code against the baseline.
|
||||
- `{COSMETIC_MINOR_EXAMPLES}`: naming, comments, dead code, import
|
||||
ordering, style
|
||||
- `{WAIVED_EXAMPLE}`: `WAIVED-COR-R2-001`
|
||||
- `{CHECKLIST_REF}`: `core/checklists/code-review.md`
|
||||
- `{FILES_MODIFIED_LINE}`: {list}
|
||||
- `{RETURN_FILE}`:
|
||||
`<runs-root>/{slug}/reviews/code/round{N}/revision-return.md`
|
||||
(Tier 1 return persistence — [org-internal #2847],
|
||||
`_shared/worker-report-persistence.md`)
|
||||
|
||||
3. The Developer revises the code files in place. The Developer creates a
|
||||
revision summary as a wiki page via `wiki 读写 API(见 TERMINOLOGY)` (`_shared/gitea-write-patterns.md` Pattern 1)with page_name `{slug}/reviews/code/round{N}/revision-summary`,
|
||||
and persists its final return summary to
|
||||
`<runs-root>/{slug}/reviews/code/round{N}/revision-return.md` (Tier 1,
|
||||
worker-report persistence [org-internal #2847] — see
|
||||
`_shared/worker-report-persistence.md`) BEFORE returning. If the
|
||||
completion notification is lost, the Orchestrator recovers the revision
|
||||
outcome from the persisted return (wiki page for the full summary,
|
||||
Tier 1 file for the conclusion of record).
|
||||
|
||||
4. **Pre-handoff gate** — before reporting completion, the Developer MUST run
|
||||
the same mechanical gate the Orchestrator will re-run at Phase D re-entry
|
||||
(the tree-fingerprint cache turns the re-run into a cache hit — one real
|
||||
execution per tree state, no double-paying):
|
||||
- Run `bun core/skills/review-code/scripts/precondition-gate.ts {slug} --round {N}`
|
||||
from the worktree root (oxlint + typecheck + `test:changed`, CI-aligned —
|
||||
`bun run test:parallel` is verify's job, not a per-revision
|
||||
requirement ([org-internal #2598])).
|
||||
- Exit 0 required; a new test failure, lint error, or type error introduced
|
||||
by the revision must be fixed before the Orchestrator proceeds to Phase D.
|
||||
- Report the gate's per-check results in the revision summary.
|
||||
|
||||
---
|
||||
|
||||
### Phase C — Developer Revision: Protocol
|
||||
|
||||
The Developer applies this cognitive protocol before implementing any finding.
|
||||
**Core principle:** reviewer findings are claims to evaluate, not orders to
|
||||
execute. Verify before implementing. Technical correctness over performative
|
||||
agreement.
|
||||
|
||||
#### Response Pattern
|
||||
|
||||
1. **READ** — Load every FAIL/WARN dimension finding file
|
||||
(`<runs-root>/{slug}/reviews/code/round{N}/findings-{DIMENSION_CODE}.json`,
|
||||
Tier 1 local). Do not react item-by-item.
|
||||
2. **UNDERSTAND** — Restate each finding's requirement in your own words.
|
||||
If you cannot, the finding is unclear — see STOP rule below.
|
||||
3. **VERIFY** — Check the finding against codebase reality: does the cited
|
||||
code exist at the given file:line? Does the cited rule apply?
|
||||
4. **EVALUATE** — Is the finding technically correct for THIS codebase?
|
||||
Does the proposed fix break existing functionality? Does it conflict
|
||||
with the approved baseline (DAG task mode: the node spec + contracts in
|
||||
`{epic-slug}/dag`)?
|
||||
5. **RESPOND** — Fix it (correct), WAIVE it (`WAIVED-{finding-id}` →
|
||||
one-line reason), or flag it (unclear / design-level question).
|
||||
6. **IMPLEMENT** — One verified finding at a time, test each individually.
|
||||
|
||||
#### Evaluating Findings — 5-Check Gate
|
||||
|
||||
Before implementing any finding, run these checks:
|
||||
|
||||
1. **Cited code is real** — Open the file:line. Does the code exist and say
|
||||
what the finding claims?
|
||||
2. **Rule applies** — Does the cited checklist rule actually match this issue?
|
||||
3. **Reason for current implementation** — Is the flagged behavior
|
||||
intentional? Check the baseline (node spec + contracts in
|
||||
`{epic-slug}/dag` for DAG task mode) for rationale.
|
||||
4. **Fix does not break existing functionality** — Will the proposed change
|
||||
cause a regression?
|
||||
5. **Reviewer has full context** — Did the reviewer see the baseline (node
|
||||
spec + acceptance criteria) and the diff context? An isolated diff review
|
||||
can miss architectural intent.
|
||||
|
||||
```
|
||||
IF a finding seems wrong:
|
||||
WAIVE it: WAIVED-{finding-id} → <one-line technical reason>
|
||||
|
||||
IF you cannot easily verify a finding:
|
||||
State the limitation in revision_summary.md and request direction.
|
||||
|
||||
IF a finding conflicts with the approved design:
|
||||
Flag as a design-level question — do NOT silently change code against the design.
|
||||
```
|
||||
|
||||
#### Unclear Findings — STOP Rule
|
||||
|
||||
```
|
||||
IF any finding is unclear:
|
||||
STOP — do not implement ANY finding yet.
|
||||
Flag the unclear items in revision_summary.md and request clarification.
|
||||
|
||||
WHY: findings may be related. Partial understanding produces wrong
|
||||
implementation across multiple items.
|
||||
```
|
||||
|
||||
**Example:** The synthesis lists findings F1–F6. You understand F1, F2, F3, F6.
|
||||
F4 and F5 are ambiguous about what change is expected.
|
||||
- **WRONG:** implement F1, F2, F3, F6 now; ask about F4, F5 later.
|
||||
- **RIGHT:** "Understand F1, F2, F3, F6. Need clarification on F4, F5 before
|
||||
proceeding — they may interact with the same module."
|
||||
|
||||
#### YAGNI Check
|
||||
|
||||
```
|
||||
IF a reviewer suggests "implementing this properly" (full abstraction,
|
||||
generic API, configurable layer):
|
||||
Check actual usage (codegraph callers / grep) BEFORE expanding scope.
|
||||
|
||||
IF unused: WAIVE — "No call sites found. Leaving as-is (YAGNI)."
|
||||
IF used: Then implement properly.
|
||||
```
|
||||
|
||||
#### Forbidden Responses in revision_summary.md
|
||||
|
||||
**NEVER** write:
|
||||
- "You're absolutely right!" / "Great point!" / "Excellent catch!" — performative.
|
||||
- "Thanks for catching that!" / any gratitude expression.
|
||||
- "Let me implement that now" — before verification.
|
||||
|
||||
**INSTEAD:**
|
||||
- Restate the technical requirement concisely.
|
||||
- State the fix factually: `Fixed {finding-id}: <what changed> at <file:line>`.
|
||||
- Just fix it and show the result in the diff.
|
||||
|
||||
#### Gracefully Correcting a WAIVE
|
||||
|
||||
If you WAIVEd a finding and were wrong:
|
||||
```
|
||||
"Verified {finding-id} — the reviewer is correct. My initial read missed
|
||||
<reason>. Implementing now."
|
||||
```
|
||||
State the correction factually. No lengthy apology.
|
||||
|
||||
#### Implementation Order
|
||||
|
||||
For multi-finding revisions, after clarifying all unclear items:
|
||||
1. **Blocking issues** — security, data loss, breaks existing functionality.
|
||||
2. **Simple fixes** — typos, imports, naming, dead code.
|
||||
3. **Complex fixes** — logic changes, refactoring within minimal-surgical scope.
|
||||
Test each fix individually.
|
||||
|
||||
#### Rationalization-Anticipation Quick Reference
|
||||
|
||||
| Trap | Hold to |
|
||||
|------|---------|
|
||||
| "The reviewer flagged it as BLOCKER, so it must be real." | VERIFY cited code exists and rule applies before any edit. |
|
||||
| "Just fix everything to avoid a re-review round." | EVALUATE each finding; WAIVE the wrong ones with reasoning. |
|
||||
| "This finding looks plausible — I'll fix it without checking." | Open the file:line, confirm the behavior. |
|
||||
| "I'll implement the clear findings and ask about unclear ones later." | STOP. Clarify ALL unclear items before implementing any. |
|
||||
| "The reviewer wants it done 'properly' — full abstraction." | Check call sites first. If unused, WAIVE (YAGNI). |
|
||||
| "I shouldn't push back — the reviewer is probably right." | Push back with technical reasoning. The diff is the acknowledgment. |
|
||||
|
||||
---
|
||||
|
||||
<!-- section:phase-d -->
|
||||
## Phase D — Re-review Loop
|
||||
|
||||
After the Developer completes revision:
|
||||
|
||||
1. Increment the round counter (the Synthesizer updates the commit status in Phase B
|
||||
with the new round's results).
|
||||
2. Re-enter Phase A at step 2.5 — the mechanical-green gate re-runs on the
|
||||
revised tree before any reviewer spawn (a red gate blocks dispatch exactly
|
||||
as on round-1 entry) — then spawn the new round of reviewers against the
|
||||
revised files.
|
||||
|
||||
**Convergence criteria**: see `core/skills/_shared/review-pipeline-phases.md` Phase D for the canonical table (stop conditions). `{MAX_ROUNDS}` is per-skill — code review binds the routing budget: **2** rounds default, **3** for high risk (a BLOCKER survived a round, or the diff touches a frozen cross-session contract) — `<instance-root>/workflow-routing.yaml` `review.max_rounds` ([org-internal #3567]). The code-review-specific addition is inheritance of the shared INFO-disposition rule. The shared Round-3 Escalation Guardrail is scoped to the `review-artifact` skill targets only and does not apply here.
|
||||
|
||||
**Round budget (mandatory, [org-internal #3567])**: when `current_round` reaches the budget (2; 3 for high risk) without convergence, do NOT enter another round. STOP: register every remaining BLOCKER/MAJOR finding as TD registry rows (`rules/ticket-lifecycle.md`), record the verdict with the shared three-tier ladder (`core/schemas/synthesis.schema.json` `overall_verdict` + `core/skills/_shared/review-orchestrator-rules.md` rule 3): FAIL if any BLOCKER or FAIL dimension remains, else WARN, PASS only if every remaining dimension is PASS ([org-internal #4786]: the prior binary "else PASS" wording silently upgraded WARN-eligible outcomes to PASS), and close the loop. The debt is carried by the TD registry rows just registered, not by the recorded verdict. A review that cannot converge within budget is a design-level stall wearing review clothes (retro 2026-08-21 / [org-internal #3050]): in DAG task mode, map it to the DAG oversize signals (`<instance-root>/workflow-routing.yaml` `dag.size_derivation.oversize_signals`) and let the aggregator agent drive re-derivation + a `review-dag` re-run; otherwise record the design-level finding on the Epic, or open `{slug}/03-design-amendments` via `wiki 读写 API(见 TERMINOLOGY)` (`_shared/gitea-write-patterns.md` Pattern 1).
|
||||
|
||||
**Efficiency optimization**: see `core/skills/_shared/review-pipeline-phases.md` Phase D (same rule — from round 2 onward ([org-internal #2598]), only spawn reviewers for FAIL/WARN/UNRESOLVED dimensions; full sweep every 2 rounds). Round ≥2 reviewer input is delta-scoped to the revised files + their neighbors.
|
||||
|
||||
<!-- inject: ../_shared/compaction-round-boundary.md -->
|
||||
|
||||
---
|
||||
|
||||
<!-- section:phase-e -->
|
||||
## Phase E — Final Report & Approval
|
||||
@@ -912,11 +686,11 @@ After the Developer completes revision:
|
||||
the findings JSONs are deleted at Tier 1 archive-at-close, so the final
|
||||
report is the ONLY durable carrier of round-1 findings — retrospective
|
||||
M7 (§2.9 first-round root-cause analysis) reads this table instead of
|
||||
relying on commit messages (retro 2026-08-21 / [org-internal #3120]).
|
||||
relying on commit messages (retro 2026-08-21 / [TT-3120]).
|
||||
|
||||
2.56. **Inline-ization — post the final round's findings as PR inline
|
||||
comments** (consumer of frozen contract
|
||||
`{epic-slug}/shared/review-inline-v1`, epic [org-internal #3533]; REQ-F-001/002/004).
|
||||
`{epic-slug}/shared/review-inline-v1`, epic [TT-3533]; REQ-F-001/002/004).
|
||||
After the final report page exists (step 1), post the FINAL round's
|
||||
findings as Gitea PR inline comments so review conclusions land
|
||||
line-level on the diff. Run the runner from the repo root:
|
||||
@@ -980,7 +754,7 @@ After the Developer completes revision:
|
||||
> THEN ask the human to approve. Approving before the reviewer is
|
||||
> registered produces `official: false` on the approval — the gate
|
||||
> treats the PR as unapproved and the approval must be re-done. See
|
||||
> `_shared/review-pipeline-phases.md` Phase E step 3.5. ([org-internal #1931]: audit
|
||||
> `_shared/review-pipeline-phases.md` Phase E step 3.5. ([TT-1931]: audit
|
||||
> R2→R3 re-loop + re-approve, ~30min wasted on exactly this ordering.)
|
||||
|
||||
```
|
||||
@@ -1058,7 +832,7 @@ To notify workflow completion, call the `signal_stage_done` tool.
|
||||
- Legacy design path (historical note, FLOW-F001 / audit-20260901): the
|
||||
design-document precondition row formerly in the DAG task-mode table
|
||||
(legacy `{slug}/03-design-index` / `{slug}/02-03-req-design` → node spec + frozen DAG
|
||||
copy) referenced the legacy design pipeline, archived 2026-08-21 with [org-internal #3072]
|
||||
copy) referenced the legacy design pipeline, archived 2026-08-21 with [TT-3072]
|
||||
phase 3 (see `<instance-root>/archive/skills/design/`); the live design baseline is
|
||||
the node spec + cross-session edge contracts in the frozen DAG copy
|
||||
`{epic-slug}/dag`.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# Code Review Output Artifacts
|
||||
|
||||
> Output tree for code review artifacts. Read on-demand for reference.
|
||||
> Output model ([org-internal #1988] Tier 1 migration): Tier 1 local files (raw dimension findings) + Tier 2 wiki pages (task prompts, revision summaries, final reports) + Tier 2 synthesis comment. Status tracking via commit status `pipeline/review-code`.
|
||||
> Output model ([TT-1988] Tier 1 migration): Tier 1 local files (raw dimension findings) + Tier 2 wiki pages (task prompts, revision summaries, final reports) + Tier 2 synthesis comment. Status tracking via commit status `pipeline/review-code`.
|
||||
|
||||
```
|
||||
<runs-root>/{slug}/reviews/code/
|
||||
|
||||
@@ -0,0 +1,240 @@
|
||||
> Extracted from review-code/SKILL.md (Phase C — Developer Revision +
|
||||
> Phase D — Re-review Loop) — moved verbatim; read on-demand when
|
||||
> `overall_verdict` is not PASS (skipped entirely on PASS, which jumps
|
||||
> straight to Phase E).
|
||||
|
||||
<!-- section:phase-c -->
|
||||
## Phase C — Developer Revision
|
||||
|
||||
If `overall_verdict` is PASS, skip to Phase E.
|
||||
|
||||
Otherwise:
|
||||
|
||||
**Orchestrator actions**:
|
||||
|
||||
1. Prepare the Developer's input as a structured task file,
|
||||
created as a wiki page via `wiki 读写 API(见 TERMINOLOGY)` (`_shared/gitea-write-patterns.md` Pattern 1)with page_name `{slug}/reviews/code/round{N}/task-developer`.
|
||||
|
||||
This file must contain:
|
||||
- Paths to all code files that need revision.
|
||||
- Reference to the synthesis comment on the ticket (posted via `工单评论 API(见 TERMINOLOGY)` in Phase B — Tier 2).
|
||||
- References to the Tier 1 finding files for dimensions that have FAIL or WARN
|
||||
verdicts (`<runs-root>/{slug}/reviews/code/round{N}/findings-{DIMENSION_CODE}.json`).
|
||||
- The Developer MUST NOT receive the full text of all reviewer findings
|
||||
inline — use finding-file path references only to avoid context explosion.
|
||||
- Convergence status: blockers/majors remaining vs. previous round.
|
||||
- **Revision survival ([TT-2601]) — primary path**: the task tool's completion
|
||||
output includes a `task_id`; passing it back resumes the SAME Developer
|
||||
subagent session instead of creating a fresh one. Round 1: persist the
|
||||
returned `task_id` with the round's working-notes entry (it must survive
|
||||
round-boundary compaction). Round ≥ 2: dispatch with `task_id` set to the
|
||||
previous revision round's — the Developer continues in-session with its
|
||||
prior diff/context; the round's task page then carries only the findings
|
||||
delta, not a full re-derivation. Reviewers are NEVER resumed — per-round
|
||||
freshness is their independence.
|
||||
- **Revision survival — fallback** (task_id lost to compaction before it
|
||||
was persisted): prepend the current `<runs-root>/{slug}/working-notes.md`
|
||||
content (run narrative memory — prior decisions, dead ends, reviewer
|
||||
feedback from earlier rounds) and reference the previous round's revision
|
||||
summary (`{slug}/reviews/code/round{N-1}/revision-summary`), stating
|
||||
explicitly that this revises code a prior round already wrote — do NOT
|
||||
re-read the full design/acceptance artifacts unless a finding requires
|
||||
them.
|
||||
|
||||
2. Spawn the Developer (Worker) with the prompt
|
||||
template at `core/skills/_shared/review-revision-prompt.md`, substituting:
|
||||
|
||||
- `{ROLE}`: Developer
|
||||
- `{TASK_FILE}`: task-developer
|
||||
- `{REVISION_SCOPE}`: Apply the Developer Revision Protocol (see Protocol
|
||||
subsection below) — evaluate each finding against codebase reality:
|
||||
Explorer reviewers are automated LLM sub-agents that can hallucinate
|
||||
citations, misapply rules, or miss design context. Verify cited code
|
||||
exists, the rule applies, and the fix does not break existing
|
||||
functionality. WAIVE technically-incorrect findings with justification
|
||||
(`WAIVED-{finding-id}` → one-line reason; canonical definition of the
|
||||
`WAIVED-{id}` convention, incl. the round-2+ cosmetic-MINOR waiver
|
||||
rule: `_shared/review-revision-prompt.md`). Revise code minimally and
|
||||
surgically — do NOT refactor unrelated code or introduce new behavior.
|
||||
- `{RESOLUTION_RULE}`: Do NOT silently deviate from the approved baseline
|
||||
(DAG task mode: the node spec + frozen cross-session contracts in
|
||||
`{epic-slug}/dag`; the legacy `{slug}/03-design-*` baseline is archived
|
||||
historical, [TT-3072] phase 3). If a finding exposes a design flaw, mark it
|
||||
as deferred with justification and suggest a design amendment — do not
|
||||
change the code against the baseline.
|
||||
- `{COSMETIC_MINOR_EXAMPLES}`: naming, comments, dead code, import
|
||||
ordering, style
|
||||
- `{WAIVED_EXAMPLE}`: `WAIVED-COR-R2-001`
|
||||
- `{CHECKLIST_REF}`: `core/checklists/code-review.md`
|
||||
- `{FILES_MODIFIED_LINE}`: {list}
|
||||
- `{RETURN_FILE}`:
|
||||
`<runs-root>/{slug}/reviews/code/round{N}/revision-return.md`
|
||||
(Tier 1 return persistence — [TT-2847],
|
||||
`_shared/worker-report-persistence.md`)
|
||||
|
||||
3. The Developer revises the code files in place. The Developer creates a
|
||||
revision summary as a wiki page via `wiki 读写 API(见 TERMINOLOGY)` (`_shared/gitea-write-patterns.md` Pattern 1)with page_name `{slug}/reviews/code/round{N}/revision-summary`,
|
||||
and persists its final return summary to
|
||||
`<runs-root>/{slug}/reviews/code/round{N}/revision-return.md` (Tier 1,
|
||||
worker-report persistence [TT-2847] — see
|
||||
`_shared/worker-report-persistence.md`) BEFORE returning. If the
|
||||
completion notification is lost, the Orchestrator recovers the revision
|
||||
outcome from the persisted return (wiki page for the full summary,
|
||||
Tier 1 file for the conclusion of record).
|
||||
|
||||
4. **Pre-handoff gate** — before reporting completion, the Developer MUST run
|
||||
the same mechanical gate the Orchestrator will re-run at Phase D re-entry
|
||||
(the tree-fingerprint cache turns the re-run into a cache hit — one real
|
||||
execution per tree state, no double-paying):
|
||||
- Run `bun core/skills/review-code/scripts/precondition-gate.ts {slug} --round {N}`
|
||||
from the worktree root (oxlint + typecheck + `test:changed`, CI-aligned —
|
||||
`bun run test:parallel` is verify's job, not a per-revision
|
||||
requirement ([TT-2598])).
|
||||
- Exit 0 required; a new test failure, lint error, or type error introduced
|
||||
by the revision must be fixed before the Orchestrator proceeds to Phase D.
|
||||
- Report the gate's per-check results in the revision summary.
|
||||
|
||||
---
|
||||
|
||||
### Phase C — Developer Revision: Protocol
|
||||
|
||||
The Developer applies this cognitive protocol before implementing any finding.
|
||||
**Core principle:** reviewer findings are claims to evaluate, not orders to
|
||||
execute. Verify before implementing. Technical correctness over performative
|
||||
agreement.
|
||||
|
||||
#### Response Pattern
|
||||
|
||||
1. **READ** — Load every FAIL/WARN dimension finding file
|
||||
(`<runs-root>/{slug}/reviews/code/round{N}/findings-{DIMENSION_CODE}.json`,
|
||||
Tier 1 local). Do not react item-by-item.
|
||||
2. **UNDERSTAND** — Restate each finding's requirement in your own words.
|
||||
If you cannot, the finding is unclear — see STOP rule below.
|
||||
3. **VERIFY** — Check the finding against codebase reality: does the cited
|
||||
code exist at the given file:line? Does the cited rule apply?
|
||||
4. **EVALUATE** — Is the finding technically correct for THIS codebase?
|
||||
Does the proposed fix break existing functionality? Does it conflict
|
||||
with the approved baseline (DAG task mode: the node spec + contracts in
|
||||
`{epic-slug}/dag`)?
|
||||
5. **RESPOND** — Fix it (correct), WAIVE it (`WAIVED-{finding-id}` →
|
||||
one-line reason), or flag it (unclear / design-level question).
|
||||
6. **IMPLEMENT** — One verified finding at a time, test each individually.
|
||||
|
||||
#### Evaluating Findings — 5-Check Gate
|
||||
|
||||
Before implementing any finding, run these checks:
|
||||
|
||||
1. **Cited code is real** — Open the file:line. Does the code exist and say
|
||||
what the finding claims?
|
||||
2. **Rule applies** — Does the cited checklist rule actually match this issue?
|
||||
3. **Reason for current implementation** — Is the flagged behavior
|
||||
intentional? Check the baseline (node spec + contracts in
|
||||
`{epic-slug}/dag` for DAG task mode) for rationale.
|
||||
4. **Fix does not break existing functionality** — Will the proposed change
|
||||
cause a regression?
|
||||
5. **Reviewer has full context** — Did the reviewer see the baseline (node
|
||||
spec + acceptance criteria) and the diff context? An isolated diff review
|
||||
can miss architectural intent.
|
||||
|
||||
```
|
||||
IF a finding seems wrong:
|
||||
WAIVE it: WAIVED-{finding-id} → <one-line technical reason>
|
||||
|
||||
IF you cannot easily verify a finding:
|
||||
State the limitation in revision_summary.md and request direction.
|
||||
|
||||
IF a finding conflicts with the approved design:
|
||||
Flag as a design-level question — do NOT silently change code against the design.
|
||||
```
|
||||
|
||||
#### Unclear Findings — STOP Rule
|
||||
|
||||
```
|
||||
IF any finding is unclear:
|
||||
STOP — do not implement ANY finding yet.
|
||||
Flag the unclear items in revision_summary.md and request clarification.
|
||||
|
||||
WHY: findings may be related. Partial understanding produces wrong
|
||||
implementation across multiple items.
|
||||
```
|
||||
|
||||
**Example:** The synthesis lists findings F1–F6. You understand F1, F2, F3, F6.
|
||||
F4 and F5 are ambiguous about what change is expected.
|
||||
- **WRONG:** implement F1, F2, F3, F6 now; ask about F4, F5 later.
|
||||
- **RIGHT:** "Understand F1, F2, F3, F6. Need clarification on F4, F5 before
|
||||
proceeding — they may interact with the same module."
|
||||
|
||||
#### YAGNI Check
|
||||
|
||||
```
|
||||
IF a reviewer suggests "implementing this properly" (full abstraction,
|
||||
generic API, configurable layer):
|
||||
Check actual usage (codegraph callers / grep) BEFORE expanding scope.
|
||||
|
||||
IF unused: WAIVE — "No call sites found. Leaving as-is (YAGNI)."
|
||||
IF used: Then implement properly.
|
||||
```
|
||||
|
||||
#### Forbidden Responses in revision_summary.md
|
||||
|
||||
**NEVER** write:
|
||||
- "You're absolutely right!" / "Great point!" / "Excellent catch!" — performative.
|
||||
- "Thanks for catching that!" / any gratitude expression.
|
||||
- "Let me implement that now" — before verification.
|
||||
|
||||
**INSTEAD:**
|
||||
- Restate the technical requirement concisely.
|
||||
- State the fix factually: `Fixed {finding-id}: <what changed> at <file:line>`.
|
||||
- Just fix it and show the result in the diff.
|
||||
|
||||
#### Gracefully Correcting a WAIVE
|
||||
|
||||
If you WAIVEd a finding and were wrong:
|
||||
```
|
||||
"Verified {finding-id} — the reviewer is correct. My initial read missed
|
||||
<reason>. Implementing now."
|
||||
```
|
||||
State the correction factually. No lengthy apology.
|
||||
|
||||
#### Implementation Order
|
||||
|
||||
For multi-finding revisions, after clarifying all unclear items:
|
||||
1. **Blocking issues** — security, data loss, breaks existing functionality.
|
||||
2. **Simple fixes** — typos, imports, naming, dead code.
|
||||
3. **Complex fixes** — logic changes, refactoring within minimal-surgical scope.
|
||||
Test each fix individually.
|
||||
|
||||
#### Rationalization-Anticipation Quick Reference
|
||||
|
||||
| Trap | Hold to |
|
||||
|------|---------|
|
||||
| "The reviewer flagged it as BLOCKER, so it must be real." | VERIFY cited code exists and rule applies before any edit. |
|
||||
| "Just fix everything to avoid a re-review round." | EVALUATE each finding; WAIVE the wrong ones with reasoning. |
|
||||
| "This finding looks plausible — I'll fix it without checking." | Open the file:line, confirm the behavior. |
|
||||
| "I'll implement the clear findings and ask about unclear ones later." | STOP. Clarify ALL unclear items before implementing any. |
|
||||
| "The reviewer wants it done 'properly' — full abstraction." | Check call sites first. If unused, WAIVE (YAGNI). |
|
||||
| "I shouldn't push back — the reviewer is probably right." | Push back with technical reasoning. The diff is the acknowledgment. |
|
||||
|
||||
---
|
||||
|
||||
<!-- section:phase-d -->
|
||||
## Phase D — Re-review Loop
|
||||
|
||||
After the Developer completes revision:
|
||||
|
||||
1. Increment the round counter (the Synthesizer updates the commit status in Phase B
|
||||
with the new round's results).
|
||||
2. Re-enter Phase A at step 2.5 — the mechanical-green gate re-runs on the
|
||||
revised tree before any reviewer spawn (a red gate blocks dispatch exactly
|
||||
as on round-1 entry) — then spawn the new round of reviewers against the
|
||||
revised files.
|
||||
|
||||
**Convergence criteria**: see `core/skills/_shared/review-pipeline-phases.md` Phase D for the canonical table (stop conditions). `{MAX_ROUNDS}` is per-skill — code review binds the routing budget: **2** rounds default, **3** for high risk (a BLOCKER survived a round, or the diff touches a frozen cross-session contract) — `<instance-root>/workflow-routing.yaml` `review.max_rounds` ([TT-3567]). The code-review-specific addition is inheritance of the shared INFO-disposition rule. The shared Round-3 Escalation Guardrail is scoped to the `review-artifact` skill targets only and does not apply here.
|
||||
|
||||
**Round budget (mandatory, [TT-3567])**: when `current_round` reaches the budget (2; 3 for high risk) without convergence, do NOT enter another round. STOP: register every remaining BLOCKER/MAJOR finding as TD registry rows (`rules/ticket-lifecycle.md`), record the verdict with the shared three-tier ladder (`core/schemas/synthesis.schema.json` `overall_verdict` + `core/skills/_shared/review-orchestrator-rules.md` rule 3): FAIL if any BLOCKER or FAIL dimension remains, else WARN, PASS only if every remaining dimension is PASS ([TT-4786]: the prior binary "else PASS" wording silently upgraded WARN-eligible outcomes to PASS), and close the loop. The debt is carried by the TD registry rows just registered, not by the recorded verdict. A review that cannot converge within budget is a design-level stall wearing review clothes (retro 2026-08-21 / [TT-3050]): in DAG task mode, map it to the DAG oversize signals (`<instance-root>/workflow-routing.yaml` `dag.size_derivation.oversize_signals`) and let the aggregator agent drive re-derivation + a `review-dag` re-run; otherwise record the design-level finding on the Epic, or open `{slug}/03-design-amendments` via `wiki 读写 API(见 TERMINOLOGY)` (`_shared/gitea-write-patterns.md` Pattern 1).
|
||||
|
||||
**Efficiency optimization**: see `core/skills/_shared/review-pipeline-phases.md` Phase D (same rule — from round 2 onward ([TT-2598]), only spawn reviewers for FAIL/WARN/UNRESOLVED dimensions; full sweep every 2 rounds). Round ≥2 reviewer input is delta-scoped to the revised files + their neighbors.
|
||||
|
||||
<!-- inject: ../_shared/compaction-round-boundary.md -->
|
||||
|
||||
---
|
||||
+26
-674
@@ -60,10 +60,10 @@ digraph verify {
|
||||
|
||||
## Agent Role
|
||||
|
||||
> **Progressive disclosure ([org-internal #3722], [org-internal #3734], [org-internal #3745])**: when dispatching a Verifier
|
||||
> **Progressive disclosure ([TT-3722], [TT-3734], [TT-3745])**: when dispatching a Verifier
|
||||
> scoped to one phase, pass `skills: ["verify:phase-2"]` (preamble + that
|
||||
> phase only) instead of the full body; multi-phase dispatches may union.
|
||||
> Phase 5 is subdivided ([org-internal #3734]): `phase-5` covers the report template only;
|
||||
> Phase 5 is subdivided ([TT-3734]): `phase-5` covers the report template only;
|
||||
> each mandatory filing subsection carries its own marker (`phase-5.5` tech
|
||||
> debt, `phase-5.55` baseline failures, `phase-5.56` flaky tests,
|
||||
> `phase-5.6` checklist sync, `phase-5.7` CI sync). Dispatch recipes:
|
||||
@@ -71,7 +71,7 @@ digraph verify {
|
||||
> / `phase-5.56` when baseline failures / flaky tests are present); PASS
|
||||
> close-out →
|
||||
> `"verify:phase-5,phase-5.5,phase-5.55,phase-5.56,phase-5.6,phase-5.7,phase-6"`.
|
||||
> The DAG branch is separately marked ([org-internal #3745]): `phase-6` narrows to
|
||||
> The DAG branch is separately marked ([TT-3745]): `phase-6` narrows to
|
||||
> Approval + Commit Gate, and the tail References rides `dag-branch` (same
|
||||
> tail rule as review-code's phase-e). Non-DAG dispatches thereby drop the
|
||||
> ~175-line DAG branch; DAG milestone/task verify → union `dag-branch` onto
|
||||
@@ -155,7 +155,7 @@ Before starting verification, confirm:
|
||||
node spec, its `acceptance_criteria` + `test_id` declarations, and the
|
||||
DoD slice. (Legacy tier rule — `{slug}/04-plan-*` wiki pages / issue
|
||||
comment, and the design-space + iteration-plan convergence checks that
|
||||
used to follow here — was archived 2026-08-21, [org-internal #3072] phase 3; historical
|
||||
used to follow here — was archived 2026-08-21, [TT-3072] phase 3; historical
|
||||
plan/AC pages stay readable via `_shared/gitea-read-patterns.md`.)
|
||||
- [ ] `core/checklists/verification.md` is accessible.
|
||||
- [ ] `slug` matches the run's slug (DAG: `{epic-slug}`).
|
||||
@@ -223,7 +223,7 @@ the DAG branch below for its read map):
|
||||
(The legacy `Size/*`-tiered locations — `{slug}/04-plan-*`,
|
||||
`{slug}/02-requirements-index`, `{slug}/02-03-req-design`,
|
||||
`{slug}/03-design-06-non-functional-design` — were archived 2026-08-21,
|
||||
[org-internal #3072] phase 3; historical pages stay readable for legacy-run verification
|
||||
[TT-3072] phase 3; historical pages stay readable for legacy-run verification
|
||||
via `_shared/gitea-read-patterns.md`.)
|
||||
|
||||
5. **Code review final report** — `{slug}/reviews/code/final/report`
|
||||
@@ -277,7 +277,7 @@ before. This section saves redundant typecheck/lint/security re-runs; it
|
||||
never weakens a gate.
|
||||
|
||||
**Second evidence source — the review-code precondition-gate cache
|
||||
(eff-gate-cache [org-internal #2598] / [org-internal #2990])**. The mechanical checks this phase would re-run
|
||||
(eff-gate-cache [TT-2598] / [TT-2990])**. The mechanical checks this phase would re-run
|
||||
(oxlint / typecheck / `test:changed`) are exactly the precondition-gate's
|
||||
check-set, and the gate caches GREEN results keyed on a tree fingerprint
|
||||
(HEAD + tracked diff + untracked contents) in
|
||||
@@ -394,8 +394,8 @@ For each DoD entry with verification method "Security scan":
|
||||
every failing test, run it on the last known-green commit (or the base
|
||||
branch) in isolation. **Never use `git stash` for this** — the stash stack
|
||||
is shared across all worktrees of this repo and a parallel session can
|
||||
overwrite your entry mid-flight (issue [org-internal #1655]). Instead, use the
|
||||
lifecycle-managed scratch-worktree script ([org-internal #2790]) — it registers the
|
||||
overwrite your entry mid-flight (issue [TT-1655]). Instead, use the
|
||||
lifecycle-managed scratch-worktree script ([TT-2790]) — it registers the
|
||||
worktree for the sweep backstop, symlinks `node_modules` from the source
|
||||
checkout when `bun.lock` matches (dropping the per-instance cost from
|
||||
~170k inodes to ~7k), and deregisters on removal:
|
||||
@@ -435,7 +435,7 @@ For each DoD entry with verification method "Security scan":
|
||||
### 2.7 — Browser Evidence Reference Validation (UI-touching PR)
|
||||
|
||||
For DoD entries of the「UI 主张 ↔ 可复现浏览器证据」type — contract
|
||||
`browser-evidence-4486/shared/evidence-ref-v1` (frozen 2026-09-10, [org-internal #4498]).
|
||||
`browser-evidence-4486/shared/evidence-ref-v1` (frozen 2026-09-10, [TT-4498]).
|
||||
Applicable ONLY to UI-touching PRs (changes under `packages/app`,
|
||||
`packages/ui`, or `packages/console/*` frontend surfaces):
|
||||
|
||||
@@ -493,7 +493,7 @@ Browser-evidence rows (UI-touching PRs only, Phase 2.7): ✅ PASS requires a
|
||||
mechanically validated, replayable pack-ref; `unregistered` / `manifest-missing` /
|
||||
`manifest-corrupt` / `not-replayable` / `over-limit` references are
|
||||
⚠️ UNVERIFIABLE at best — the reference channel fails explicitly, never
|
||||
silently green ([org-internal #4498] AC-4).
|
||||
silently green ([TT-4498] AC-4).
|
||||
|
||||
### Iteration Verdict
|
||||
|
||||
@@ -619,501 +619,20 @@ issue close) is performed later in Phase 5.6 — see
|
||||
`rules/issue-checklist-sync.md` § 归档动作.
|
||||
|
||||
<!-- section:phase-5.5 -->
|
||||
### Phase 5.5 — Tech Debt Registry Filing (mandatory before PASS)
|
||||
|
||||
Tech debt is filed **registry-first** (`core/rules/ticket-lifecycle.md`,
|
||||
[org-internal #3002] G1): new items become ROWS in the source ticket's `## TD 登记` comment;
|
||||
an independent ticket is created only at **promotion** (claim/schedule). There
|
||||
is no `tech-debt.md` file and no `{slug}/tech-debt` wiki page — both remain
|
||||
retired. The registry preserves the three guarantees of the old
|
||||
one-issue-per-item model: visible (the comment lives on a tracker ticket),
|
||||
individually closeable (row-level checkbox), de-duplicated across sessions
|
||||
(the TD index is stronger than title-keyword matching).
|
||||
|
||||
**Sprint-mode override ([org-internal #3002] G5/[org-internal #3007])**: read `filing.sprint-mode` from
|
||||
`<instance-root>/workflow-routing.yaml` at the START of this phase (no caching). When
|
||||
`true`, ALL severities file registry-only — registration rows are written as
|
||||
normal (severity included, nothing lost) but promotion to standalone tickets
|
||||
is FROZEN until the switch returns to `false`. Rationale: the 2026-08-12
|
||||
sprint zeroed fix capacity while filing kept running (the 125-fragment
|
||||
backlog's direct trigger); an explicit debt-side downshift beats hoping for
|
||||
discipline. BF/FT phases 5.55/5.56 are NOT covered by this switch — failure
|
||||
evidence must stay immediately visible. Flipping the switch is a human
|
||||
decision recorded on the sprint tracker; semantics in
|
||||
`rules/workflow-routing.md` §立案降档.
|
||||
|
||||
**Adjacency quota ([org-internal #3002] G3/[org-internal #3005])**: while collecting inputs, also check the
|
||||
AREAS this iteration touched (packages/modules with commits this iteration).
|
||||
If the source tickets for those areas carry applicable `## TD 登记` rows, at
|
||||
least ONE row must be taken along and disposed this iteration (fixed, or
|
||||
explicitly re-deferred with a reason — silence is not a disposition). Record
|
||||
`consumed X / applicable Y` (or `0 applicable`) in the TD report section;
|
||||
verification checklist §8.4 cross-checks it against the run's debt-quota
|
||||
record (historically the roadmap's per-chunk debt-quota line). This gives debt digestion a steady capacity source tied to
|
||||
touch, not to cleanup campaigns.
|
||||
|
||||
**Promotion quota + pull event ([org-internal #3061])**: promotion to a standalone ticket
|
||||
requires (a) a **pull event** — the row's Reactivation Trigger fired (state
|
||||
the observed event) OR a named claimer/schedule; "it seemed important" is not
|
||||
a pull event — recorded in the promotion body's `## 拉动事件 / Pull Event`
|
||||
section; and (b) the origin module's OPEN promoted-TD count is below the
|
||||
quota (**default 10** — counted **per origin module**: resolve the row's
|
||||
module from the ticket body's `Origin` field, then count that module's OPEN
|
||||
`tech-debt` tickets; retro §2.10 reports breaches). At or above quota →
|
||||
register-only until the count drops; before each Phase 5.5 promotion
|
||||
re-check the owning module's count, and a row whose module is at or above
|
||||
quota is NOT promoted — defer it and annotate the registry row with
|
||||
`quota-held` (re-checked on the next verify run, retro 2026-08-21). A row
|
||||
marked `[COLD]` by retrospective §2.10
|
||||
(unclaimed >3 retro cycles) promotes only after the pull event clears the
|
||||
mark.
|
||||
|
||||
**Collect inputs** — every tech-debt item to register this iteration:
|
||||
|
||||
1. Every UNVERIFIABLE row in the DoD matrix (Phase 3), with its Reactivation
|
||||
Trigger.
|
||||
2. Every ACCEPTED_RISK finding in the code-review final report
|
||||
(`{slug}/reviews/code/final/report`), with its Recommended Reactivation
|
||||
Trigger.
|
||||
3. Every `[OPEN: <short-id>]` marker the Developer left in code this iteration
|
||||
(per implementation checklist POST-6.2).
|
||||
|
||||
If the code-review final report does not exist, warn the user — ACCEPTED_RISK
|
||||
items cannot be captured. This is itself a process gap that must be flagged.
|
||||
|
||||
**Step 1 — De-duplicate against the registry index and promoted issues.**
|
||||
|
||||
1. Read the source ticket's `## TD 登记` comment (create the comment if this
|
||||
is its first row) and match each candidate against existing rows by
|
||||
`TD-NNN` and reactivation trigger. Same-source re-reporting is the
|
||||
anti-pattern this step exists to prevent (the visual-cluster incident: 18
|
||||
fragments from one source under the old keyword matching).
|
||||
2. Query OPEN promoted tech-debt issues for cross-source duplicates:
|
||||
|
||||
```
|
||||
工单 API 检索(见 TERMINOLOGY)
|
||||
(owner/repo 按实例绑定,labels="tech-debt", state="open")
|
||||
```
|
||||
|
||||
**Step 2 — Assign `TD-NNN` via the ledger mutex ([org-internal #3322]).** One script call
|
||||
per batch: `bash script/td-alloc.sh <count = new items> <source-slug>
|
||||
[--ticket N]` returns a contiguous range from the TD allocation ledger
|
||||
(append-only comments, earliest-comment-id wins; the seed comment pins the
|
||||
historical floor). Split the returned range across the Step 3 rows in order.
|
||||
**Any allocation — manual included — must land a `**td-alloc**` comment on
|
||||
the ledger before the registry row is written; hand-computed `max + 1` is
|
||||
forbidden** (the 2026-08-24 three-way collision). On exit 5 (retry
|
||||
exhaustion) abort this phase's filing and retry — never hand-assign. The id is **reserved for life**: promotion reuses it, never
|
||||
renumbers. Run `--check` (reconciliation) here if the last check predates
|
||||
this batch.
|
||||
|
||||
**Step 3 — Append one registry row per new item.** Append to the source
|
||||
ticket's `## TD 登记` comment (no source ticket → the owning Epic's tracker
|
||||
ticket; no Epic → the standing `TD 冷存档` tracker):
|
||||
|
||||
```markdown
|
||||
- [ ] TD-{NNN} · {UNVERIFIABLE | ACCEPTED_RISK | DEFERRED} · {HIGH | MEDIUM | LOW}
|
||||
· {origin chunk-id/iter-N} — {one-line summary}
|
||||
· trigger: {objectively verifiable reactivation condition — never "when ready";
|
||||
if no trigger can be defined this is NOT tech debt and the iteration verdict
|
||||
becomes FAIL}
|
||||
```
|
||||
|
||||
**Step 4 — Cross-link (adapted).** The registry comment already lives on the
|
||||
source issue — the source → debt navigation the old body-edit provided. When
|
||||
filing went to an Epic tracker or the 冷存档 (no source ticket), reference the
|
||||
originating slug in each row so the trail survives.
|
||||
|
||||
**Step 5 — Record the mapping in the verification report.** The report's
|
||||
"Tech Debt" section records `TD-NNN → registry row` (source `#NNNN` +
|
||||
`## TD 登记` comment); promoted items record `TD-NNN → #NNNN` as before.
|
||||
|
||||
**Promotion (认领升票) — when a row is scheduled or picked up.** Create the
|
||||
independent ticket THEN, carrying the reserved `TD-NNN`:
|
||||
|
||||
```
|
||||
POST <gitea-base-url>/api/v1/repos/Octopus/octopus/issues
|
||||
body: {"title":"[{origin}] Tech debt: {short description} (TD-{NNN})",
|
||||
"body":<promotion template below>,
|
||||
"labels":[tech_debt_label_id, severity_label_id]}
|
||||
```
|
||||
|
||||
- **Severity → label** (reuse the existing exclusive Priority set):
|
||||
|
||||
| Severity | Label |
|
||||
| -------- | ----------------- |
|
||||
| HIGH | `Priority/High` |
|
||||
| MEDIUM | `Priority/Medium` |
|
||||
| LOW | `Priority/Low` |
|
||||
|
||||
- **Promotion body template** (the pre-[org-internal #3002] issue template, now used only at
|
||||
promotion):
|
||||
|
||||
```markdown
|
||||
## Parent / 父级
|
||||
|
||||
{#source_issue carrying the ## TD 登记 row}
|
||||
|
||||
## Summary
|
||||
|
||||
{one-paragraph description of the debt}
|
||||
|
||||
| Field | Value |
|
||||
| -------- | ------------------------------------------- |
|
||||
| TD ID | TD-{NNN} (reserved at registration) |
|
||||
| Type | {UNVERIFIABLE \| ACCEPTED_RISK \| DEFERRED} |
|
||||
| Origin | {chunk-id/iter-N/phase or slug} |
|
||||
| Severity | {HIGH \| MEDIUM \| LOW} |
|
||||
|
||||
## Reactivation Trigger
|
||||
|
||||
{from the registry row}
|
||||
|
||||
## 拉动事件 / Pull Event
|
||||
|
||||
{trigger fired: {observed event} | claimed by {who} for {when}}
|
||||
|
||||
## Acceptance Criteria (how to close this issue)
|
||||
|
||||
- [ ] {specific action that resolves the debt}
|
||||
|
||||
## Context
|
||||
|
||||
- Verification report: `{slug}/05-verify-iteration-{N}`
|
||||
- Code review report: `{slug}/reviews/code/final/report` (if ACCEPTED_RISK)
|
||||
```
|
||||
|
||||
- After creating the promoted ticket: tick the registry row (`- [x]`) and
|
||||
append `→ #NNNN` to it.
|
||||
|
||||
If no new tech-debt items were found this iteration, the phase is a no-op —
|
||||
record "0 tech-debt items" in the report and proceed.
|
||||
|
||||
<!-- section:phase-5.55 -->
|
||||
### Phase 5.55 — Baseline-Failure Issue Registration (mandatory before PASS when pre-existing failures exist)
|
||||
|
||||
Pre-existing test failures (BF) are tracked as **root-cause family umbrella
|
||||
tickets** (`core/rules/ticket-lifecycle.md`, [org-internal #3002] G1; precedents [org-internal #2585]
|
||||
umbrella + [org-internal #2925] cluster) — one `BF-NNN` ticket per failure-signature family,
|
||||
labeled `baseline-failure`, with each occurrence's evidence attached as
|
||||
comments. There is no `baseline-failures.md` file and no
|
||||
`{slug}/baseline-failures` wiki page. A pre-existing failure does not block
|
||||
the iteration that _discovered_ it (it pre-dates that work), but it MUST be
|
||||
filed against (or into) a family; an un-filed baseline failure is a process
|
||||
gap and the iteration is NOT Done.
|
||||
|
||||
**Birth triage SLA ([org-internal #3061])**: a BF umbrella is born with `Kind/Bug` (it IS a
|
||||
bug — of the baseline) and must be triaged the SAME DAY it is filed:
|
||||
assigned, scheduled, or explicitly deferred with a reason on the ticket.
|
||||
Untriaged-next-day BF umbrellas are named individually in retro §2.10
|
||||
(compliance %), not averaged away.
|
||||
|
||||
**Collect inputs** — every pre-existing failure to register this iteration:
|
||||
|
||||
1. Every failure classified **pre-existing** in Phase 2.6 (fails on the base
|
||||
branch / last-green commit too).
|
||||
2. Any baseline-run failures noted in the brownfield pre-check (Greenfield vs.
|
||||
Brownfield section).
|
||||
|
||||
**Step 1 — De-duplicate by failure SIGNATURE against existing families (open
|
||||
AND closed), per `core/rules/testing.md`** (de-duplicate BEFORE filing,
|
||||
retro [org-internal #2696]). Query `baseline-failure` issues in ALL states:
|
||||
|
||||
```
|
||||
GET <gitea-base-url>/api/v1/repos/Octopus/octopus/issues?labels=baseline-failure&state=all&page=N&limit=50
|
||||
```
|
||||
|
||||
Match each candidate by **failure signature** — the error/assertion signature
|
||||
plus the affected surface, not just `file::test-name` (one root-cause family
|
||||
may span several tests; several tests failing with the same assertion shape
|
||||
are ONE family). On a signature hit, do NOT create a new ticket: attach the
|
||||
new run evidence (run, commit, failing output, sibling tests observed) as a
|
||||
comment on the FAMILY umbrella ticket. Filing a second ticket inside a known
|
||||
root-cause family is the anti-pattern this phase exists to prevent. If a
|
||||
tracked family is now FIXED by this iteration's work, close its umbrella with
|
||||
a comment citing the fixing commit (a bonus, not a requirement). If the query
|
||||
itself errors (API failure — not "no matches"), retry once; on the second
|
||||
failure proceed to file with the literal marker `dedup-unverified` in the
|
||||
umbrella's first evidence comment (query-failure ruling, [org-internal #3383] — fail-open,
|
||||
visible; rationale in `core/rules/ticket-lifecycle.md`).
|
||||
|
||||
**Step 2 — Assign the next `BF-NNN`** per `core/rules/testing.md`
|
||||
§ "Pre-existing test failures must be filed, not silently logged" (the L1 rule
|
||||
owns the repo-wide sequential numbering invariant — `max + 1`, duplicate ids
|
||||
forbidden incl. closed tickets). `BF-NNN` names the FAMILY; the Gitea issue
|
||||
number `#NNNN` is the tracker handle.
|
||||
|
||||
**Step 3 — Create one umbrella ticket per NEW root-cause family.** Only when
|
||||
no existing family matches the signature:
|
||||
|
||||
```
|
||||
POST <gitea-base-url>/api/v1/repos/Octopus/octopus/issues
|
||||
body: {"title":"[{origin}] Baseline failure: {test identifier} (BF-{NNN})",
|
||||
"body":<issue body template below>,
|
||||
"labels":[baseline_failure_label_id, severity_label_id, kind_bug_label_id]}
|
||||
```
|
||||
|
||||
- **Title**: `[{origin}] Baseline failure: {signature summary} (BF-{NNN})`
|
||||
where `{origin}` is `chunk-{id}/iter-{N}` or the bugfix slug, and
|
||||
`{signature summary}` is the family's error/assertion shape (not a single
|
||||
test name — sibling tests observed later join this umbrella as evidence
|
||||
comments).
|
||||
- **Severity → label** (reuse the existing exclusive Priority set; a failing
|
||||
test defaults to at least MEDIUM, HIGH if on a critical path):
|
||||
|
||||
| Severity | Label |
|
||||
| -------- | ----------------- |
|
||||
| HIGH | `Priority/High` |
|
||||
| MEDIUM | `Priority/Medium` |
|
||||
| LOW | `Priority/Low` |
|
||||
|
||||
- Also attach `Kind/Bug` so the failure is discoverable in the bug tracker
|
||||
alongside manually-reported bugs.
|
||||
- **Issue body template**:
|
||||
|
||||
````markdown
|
||||
## Parent / 父级
|
||||
|
||||
{#source_issue, or "no source issue — discovered during iteration baseline"}
|
||||
|
||||
## Summary
|
||||
|
||||
A test was already failing before this iteration's work began. It does not
|
||||
block the discovering iteration but must be tracked to closure.
|
||||
|
||||
| Field | Value |
|
||||
| -------------- | ---------------------------------------------- |
|
||||
| BF ID | BF-{NNN} (family) |
|
||||
| Signature | {error/assertion shape} |
|
||||
| Tests affected | `{file::test-name}`, … (initial members) |
|
||||
| Origin | {chunk-id/iter-N or slug} |
|
||||
| Severity | {HIGH \| MEDIUM \| LOW} |
|
||||
| First observed | {base commit / date the failure reproduces on} |
|
||||
|
||||
## Reproduction
|
||||
|
||||
```
|
||||
git checkout {base commit}
|
||||
(cd <harness-package> && bun test --timeout 120000 {test file}) # or project-equivalent
|
||||
```
|
||||
|
||||
Failing output:
|
||||
|
||||
```
|
||||
{paste the relevant assertion / error}
|
||||
```
|
||||
|
||||
## Acceptance Criteria (how to close this issue)
|
||||
|
||||
- [ ] The named test passes on a clean checkout of the target branch.
|
||||
- [ ] If the test is deleted/renamed, the replacement covers the same
|
||||
behavior and passes.
|
||||
|
||||
## Context
|
||||
|
||||
- Verification report: `{slug}/05-verify-iteration-{N}`
|
||||
````
|
||||
|
||||
**Step 4 — Cross-link to the source issue (mandatory).** Per the
|
||||
issue-cross-linking rule, every baseline-failure issue MUST link back to its
|
||||
source:
|
||||
|
||||
- The issue body already carries `## Parent` (above).
|
||||
- Update the source/parent issue body to reference each new baseline-failure
|
||||
issue by `#NNNN` in its task list (e.g.
|
||||
`- [ ] #NNNN — BF-{NNN} {test identifier}`), so reviewers can navigate from
|
||||
source → failure.
|
||||
|
||||
**Step 5 — Record the mapping in the verification report.** The
|
||||
`BF-NNN → #NNNN` mapping is written ONLY in the Phase 5 verification report's
|
||||
"Baseline Failures" section (and in the issue title itself). There is no local
|
||||
file to update.
|
||||
|
||||
If no new baseline failures were found this iteration, the phase is a no-op —
|
||||
record "0 baseline failures" in the report and proceed.
|
||||
|
||||
<!-- section:phase-5.56 -->
|
||||
### Phase 5.56 — Flaky-Test Issue Registration (mandatory before PASS when flaky tests are unfixed)
|
||||
|
||||
Flaky tests (intermittent pass/fail) are tracked as **root-cause family
|
||||
umbrella tickets** (`core/rules/ticket-lifecycle.md`, [org-internal #3002] G1) — one
|
||||
`FT-NNN` ticket per failure-signature family, labeled `flaky-test`, with each
|
||||
occurrence's evidence (run count, failure rate, commit) attached as comments.
|
||||
A flaky test that is not fixed within this iteration MUST be filed against
|
||||
(or into) a family; otherwise it evaporates at iteration end and the
|
||||
"compare flaky count against baseline" check (TST-2.5) has no persistent
|
||||
register to compare against. Filing does not block the verdict, but an unfixed
|
||||
flaky test left un-filed is a process gap and the iteration is NOT Done.
|
||||
|
||||
**Expiry SLA ([org-internal #3061])**: an FT umbrella is born with `Kind/Testing` and a
|
||||
**fix-or-isolate window** (default 7 days) recorded in its body (isolating =
|
||||
quarantining/skipping the test with the family id in the skip reason, which
|
||||
keeps the register comparable). Past the window without fix or isolation, the
|
||||
umbrella is escalated on the ticket (comment naming the owner); retro §2.10
|
||||
reports fix-or-isolate compliance per cycle.
|
||||
|
||||
**Collect inputs** — every flaky test to register this iteration:
|
||||
|
||||
1. Every flaky test surfaced in Phase 2.1 (intermittent pass/fail across
|
||||
reruns) that was NOT fixed by the Developer this iteration.
|
||||
2. Any flaky test carried over from a prior iteration's report that is still
|
||||
intermittently failing.
|
||||
|
||||
**Step 1 — De-duplicate by failure SIGNATURE against existing families (open
|
||||
AND closed), per `core/rules/testing.md`** (de-duplicate BEFORE filing,
|
||||
retro [org-internal #2696]). Query `flaky-test` issues in ALL states:
|
||||
|
||||
```
|
||||
GET <gitea-base-url>/api/v1/repos/Octopus/octopus/issues?labels=flaky-test&state=all&page=N&limit=50
|
||||
```
|
||||
|
||||
Match each candidate by **failure signature** — the flakiness mode (timeout /
|
||||
race / order-dependence / env-leak) plus the affected surface, not just
|
||||
`file::test-name` (one root cause may flake several tests). On a signature
|
||||
hit, do NOT create a new ticket: attach the new run evidence (run count,
|
||||
failure rate, commit, sibling tests) as a comment on the FAMILY umbrella
|
||||
ticket. Filing a second ticket inside a known root-cause family is the
|
||||
anti-pattern this phase exists to prevent. If a tracked family now passes
|
||||
deterministically, close its umbrella citing the fixing commit. If the query
|
||||
itself errors (API failure — not "no matches"), retry once; on the second
|
||||
failure proceed to file with the literal marker `dedup-unverified` in the
|
||||
umbrella's first evidence comment (query-failure ruling, [org-internal #3383] — fail-open,
|
||||
visible; rationale in `core/rules/ticket-lifecycle.md`).
|
||||
|
||||
**Step 2 — Assign the next `FT-NNN`** per `core/rules/testing.md`
|
||||
§ "Flaky tests must be filed, not silently tolerated" (the L1 rule owns the
|
||||
repo-wide sequential numbering invariant — `max + 1`, duplicate ids forbidden
|
||||
incl. closed tickets). `FT-NNN` names the FAMILY.
|
||||
|
||||
**Step 3 — Create one umbrella ticket per NEW root-cause family.** Only when
|
||||
no existing family matches the signature:
|
||||
|
||||
```
|
||||
POST <gitea-base-url>/api/v1/repos/Octopus/octopus/issues
|
||||
body: {"title":"[{origin}] Flaky test: {test identifier} (FT-{NNN})",
|
||||
"body":<issue body template below>,
|
||||
"labels":[flaky_test_label_id, severity_label_id, kind_testing_label_id]}
|
||||
```
|
||||
|
||||
- **Title**: `[{origin}] Flaky test: {signature summary} (FT-{NNN})` — the
|
||||
family's flakiness mode + surface (sibling tests join later as evidence
|
||||
comments, not new tickets).
|
||||
- **Severity** → a flaky test defaults to MEDIUM (HIGH if on a critical path
|
||||
or blocking CI); reuse the exclusive Priority set.
|
||||
- Also attach `Kind/Testing` so it is discoverable in the testing tracker.
|
||||
- **Issue body template**:
|
||||
|
||||
````markdown
|
||||
## Parent / 父级
|
||||
|
||||
{#source_issue, or "no source issue — discovered during iteration verification"}
|
||||
|
||||
## Summary
|
||||
|
||||
A test passes and fails intermittently across runs. It undermines the
|
||||
reliability of the suite and must be stabilized or quarantined.
|
||||
|
||||
| Field | Value |
|
||||
| ------------ | ------------------------- |
|
||||
| FT ID | FT-{NNN} (family) |
|
||||
| Signature | {flakiness mode + surface} |
|
||||
| Tests affected | `{file::test-name}`, … (initial members) |
|
||||
| Origin | {chunk-id/iter-N or slug} |
|
||||
| Severity | {HIGH \| MEDIUM \| LOW} |
|
||||
| Failure rate | {e.g. 3/10 runs} |
|
||||
|
||||
## Reproduction
|
||||
|
||||
```
|
||||
for i in $(seq 1 10); do (cd <harness-package> && bun test --timeout 120000 {test file}) || echo "run $i FAILED"; done
|
||||
```
|
||||
|
||||
## Acceptance Criteria (how to close this issue)
|
||||
|
||||
- [ ] The test passes deterministically across 10 consecutive runs.
|
||||
- [ ] If it cannot be stabilized, it is quarantined (`test.skip` /
|
||||
`test.todo` with a comment citing FT-{NNN}) and a stable replacement
|
||||
is filed as tech-debt (TD-NNN).
|
||||
|
||||
## Context
|
||||
|
||||
- Verification report: `{slug}/05-verify-iteration-{N}`
|
||||
````
|
||||
|
||||
**Step 4 — Cross-link to the source issue (mandatory).** Every flaky-test
|
||||
issue links back to its source via `## Parent`, and the source/parent issue
|
||||
task list references each by `#NNNN`
|
||||
(`- [ ] #NNNN — FT-{NNN} {test identifier}`).
|
||||
|
||||
**Step 5 — Record the mapping in the verification report.** The
|
||||
`FT-NNN → #NNNN` mapping is written ONLY in the Phase 5 report's "Flaky Tests"
|
||||
section (and the issue title). No local file.
|
||||
|
||||
If no unfixed flaky tests exist this iteration, the phase is a no-op — record
|
||||
"0 flaky tests" in the report and proceed.
|
||||
|
||||
<!-- section:phase-5.6 -->
|
||||
### Phase 5.6 — Issue Checklist Sync (final sweep, mandatory before PASS)
|
||||
|
||||
This is the **final** checklist sync — the last of the progressive sync
|
||||
points (requirements exit, design exit, plan exit, each iteration commit, PR
|
||||
creation, review convergence, CI transitions, and here — per the sync-point
|
||||
table in `core/rules/issue-checklist-sync.md`). Earlier syncs may have
|
||||
already checked off completed items; this phase catches everything remaining
|
||||
and ensures no `- [ ]` item is left without an annotation.
|
||||
|
||||
1. **Identify the source issue** per `core/rules/issue-checklist-sync.md`
|
||||
§ "How to sync (each point)" step 1 (find `Closes #N` / `Fixes #N` in the
|
||||
PR body or commit messages). If no source issue exists (e.g. standalone
|
||||
bugfix with no tracking issue), skip this phase.
|
||||
2. **Fetch the issue body** via `工单 API(见 TERMINOLOGY)get` (rule step 2).
|
||||
3. **Map every remaining `- [ ]` checklist item** to one of three states:
|
||||
- **Done** (missed by earlier syncs) → mark `- [x]` and append
|
||||
`_(PR #NNN: <file/component>)_`.
|
||||
- **Deferred** → keep `- [ ]` and append `_(Deferred: TD-NNN <reason>)_`.
|
||||
- **Pending** → keep `- [ ]` and append `_(Pending: <blocker>)_`.
|
||||
4. **Fold the `## 当前状态` live-status section** (if present). Rows that have
|
||||
a checklist counterpart (review, process-ACs) are already reflected as
|
||||
checklist annotations at their sync points. Rows with no checklist
|
||||
counterpart in a non-Epic issue (PR opened/merged) are folded as follow-up
|
||||
evidence on the issue narrative (e.g. `_(PR #NNN merged: <summary>)_` on the
|
||||
item it delivered, or in the report). Once every row is accounted for,
|
||||
remove the section from the issue body.
|
||||
5. **archive-at-close: mark the `## 工件索引` comment archived** (归档动作 — [org-internal #1929]). Issue
|
||||
closing IS the archive-at-close action; it is explicit, not implicit. Edit the index
|
||||
comment in place per `_shared/gitea-write-patterns.md` Pattern 10 Archive-at-close
|
||||
(mechanism — banner + every row's 重读 → ARCHIVE + invariants — is defined there,
|
||||
do not restate; sequence/actor per `rules/issue-checklist-sync.md` § 归档动作).
|
||||
- Skip if no source issue exists.
|
||||
- **Tier 1 run archive** ([org-internal #1988] two-tier artifacts — only if a Tier 1 run
|
||||
workspace exists): if `<runs-root>/{slug}/` exists (a stage in this run
|
||||
produced Tier 1 local artifacts, e.g. review-code findings), archive the
|
||||
run workspace per `core/rules/two-tier-artifacts.md` § Archive-at-close
|
||||
(the L1 rule is authoritative — do NOT restate its steps here).
|
||||
The archived bundle must pass
|
||||
`core/schemas/runs-bundle.schema.json` validation (the generator
|
||||
validates by default; a red exit blocks close).
|
||||
Verify deltas only: skip in milestone/task DAG mode (the aggregator agent
|
||||
performs it at Epic/task-ticket close — see the DAG branch below).
|
||||
6. **Update the issue body** via `工单 API(见 TERMINOLOGY)update` with the annotated
|
||||
checklist. Preserve all non-checklist content unchanged.
|
||||
7. **Verify**: re-read the issue and confirm no `- [ ]` item lacks an
|
||||
annotation. Every unchecked item MUST have a `(Deferred: ...)` or
|
||||
`(Pending: ...)` note explaining why it is not done.
|
||||
8. **Close the issue** (completes the archive-at-close loop): if the flow has
|
||||
no PR (no `Closes #N` on merge), the Verifier closes the issue after PASS
|
||||
approval via `工单 API(见 TERMINOLOGY)update(state="closed")` — the banner date is
|
||||
corrected to the actual close date if it differs from today. If a PR carries
|
||||
`Closes #N`, the merge closes it; no further action.
|
||||
|
||||
If a checklist item cannot be mapped to evidence, deferral, or pending
|
||||
status, the iteration is NOT Done — the item represents untracked scope.
|
||||
### Phase 5.5–5.6 — Issue Filing Protocols (TD registry / baseline / flaky / checklist sync)
|
||||
|
||||
> The four mandatory-before-PASS filing protocols — Phase 5.5 Tech-Debt
|
||||
> registry filing (sprint-mode override), Phase 5.55 baseline-failure
|
||||
> registration, Phase 5.56 flaky-test registration, Phase 5.6 issue
|
||||
> checklist final sweep — live in `reference/issue-filing.md`. Read each at
|
||||
> its boundary during Phase 5; PASS is blocked until all applicable filings
|
||||
> report completion. Phase 5.7 (CI state sync) stays inline below.
|
||||
|
||||
<!-- section:phase-5.7 -->
|
||||
### Phase 5.7 — CI State Transition Sync (progressive)
|
||||
|
||||
Process-type acceptance criteria (e.g. "ci.yml passes N consecutive runs",
|
||||
AC#3 in [org-internal #1668]) have no single moment of completion — their progress lives on
|
||||
AC#3 in [TT-1668]) have no single moment of completion — their progress lives on
|
||||
the issue. The `CI` row in `## 当前状态` is written by the `status-sync` poller
|
||||
(`.gitea/scripts/status-sync-poll.ts`), NOT this skill — do NOT manually
|
||||
`工单 API(见 TERMINOLOGY)update` it. When verification observes a CI state transition
|
||||
@@ -1121,7 +640,7 @@ the issue. The `CI` row in `## 当前状态` is written by the `status-sync` pol
|
||||
process-AC's progress note in place via `工单 API(见 TERMINOLOGY)update` (per the
|
||||
`issue-checklist-sync` L1 rule § Automated sync — the poller owns the CI row;
|
||||
the checklist annotation remains manual). Do NOT wait for Phase 5.6: a
|
||||
transition left unsynced for tens of minutes is exactly the staleness [org-internal #1689]
|
||||
transition left unsynced for tens of minutes is exactly the staleness [TT-1689]
|
||||
targets. Skip if no source issue exists.
|
||||
|
||||
---
|
||||
@@ -1213,181 +732,14 @@ To notify workflow completion, call the `signal_stage_done` tool.
|
||||
---
|
||||
|
||||
<!-- section:dag-branch -->
|
||||
## DAG branch (milestone + task modes)
|
||||
## DAG branch (milestone + task modes) — see `reference/dag-branch.md`
|
||||
|
||||
> This branch OVERRIDES the Preconditions table, Phase 1 read inputs, Phase 5
|
||||
> report index, Phase 5.5 ACCEPTED_RISK source, Phase 5.6 final sweep, and
|
||||
> Phase 6.5 commit gate for a DAG-ticket-pipeline Epic. It applies when the
|
||||
> routed Epic is DAG-shaped: a frozen DAG copy exists at `{epic-slug}/dag` and
|
||||
> the DAG's `task_route.keep_gates` includes `verify`. Legacy iteration verify
|
||||
> (the sections above) remains authoritative for non-DAG iterations. Spec:
|
||||
> `dag-pipeline/spec-05` §5. commit status stays
|
||||
> `pipeline/verify` in both modes.
|
||||
> This branch (milestone mode / task mode / no-milestone Epic gate) lives in
|
||||
> `reference/dag-branch.md`, read it on-demand when the Epic is DAG-shaped:
|
||||
> frozen DAG at `{epic-slug}/dag` + `task_route.keep_gates` includes `verify`.
|
||||
> Legacy iteration verify (the sections above) remains authoritative for
|
||||
> non-DAG iterations. Spec: `dag-pipeline/spec-05` §5.
|
||||
|
||||
### Milestone mode (verify runs on a milestone M when `all_incoming_done_and_green`)
|
||||
|
||||
A milestone node (`type: milestone`) has no implementation work and no ticket;
|
||||
its verify is the integration verification welded at a DAG convergence point
|
||||
(`cross_session_in ≥ 2`). Trigger: the aggregator agent (main
|
||||
session/Orchestrator) detects `all_incoming_done_and_green` — every fan-in
|
||||
source node at its terminal state (task source `done` / milestone source
|
||||
`green`) — and initiates this verify run; the milestone never self-triggers.
|
||||
|
||||
**Precondition replacements** (vs legacy iteration verify):
|
||||
|
||||
| Legacy verify precondition | Milestone-mode replacement |
|
||||
| ---------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| design-space review converged (`review status --stage design-space` success) | review-dag converged (`review status --stage review-dag` success) |
|
||||
| iteration-plan review converged | REMOVED (DAG has no plan review; the single review-dag gate replaces it) |
|
||||
| legacy iteration plan at `{slug}/04-plan-index` | DAG artifact + milestone fan-in slice (no `04-plan-*` page) |
|
||||
| legacy NFR targets from `{slug}/03-design-06-non-functional-design` | REMOVED (product NFRs live in node AC, handled by per-task review-code) |
|
||||
| upstream roadmap chunk done+verified | all milestone fan-in source nodes at terminal state (task source `done` / milestone source `green`, i.e. `all_incoming_done_and_green`) |
|
||||
| code review converged (`pipeline/review-code` success) | ALL fan-in node tickets review-code PASS + PR merged (implied by `done`) |
|
||||
| code review final report exists | REMOVED (no Epic-level final report; per-node review-code reports live on task tickets) |
|
||||
| carried items from previous iteration closed | REMOVED (vacuous — no iteration) |
|
||||
| `core/checklists/verification.md` accessible | KEEP (unconditional) |
|
||||
| Acceptance criteria exist | from DAG-slice-generated DoD matrix (fan-in node AC + integration/contract-conformance/regression/NFR-coverage items) |
|
||||
| `slug` matches the plan slug | N/A (output naming frozen to `{epic-slug}`) |
|
||||
|
||||
**Phase 1 read inputs** → the DAG slice: read the milestone's fan-in subgraph
|
||||
(fan-in nodes + their cross-session edges + contracts) from the frozen DAG copy
|
||||
`{epic-slug}/dag`, and generate the DoD matrix from it (integration items,
|
||||
contract-conformance items, regression items, NFR-coverage items) instead of
|
||||
reading `04-plan-*` pages.
|
||||
|
||||
**Output naming**: `{epic-slug}/05-verify-milestone-{M-id}` (distinct from
|
||||
iteration verify `05-verify-iteration-{N}`).
|
||||
|
||||
**Phase 5 report index**: append a `VERIFY-M-{M-id}` row to the `## 工件索引`
|
||||
comment with 重读 = `ON-DEMAND` (NOT `ARCHIVE`). The milestone verify does NOT
|
||||
edit the comment directly — it reports the row-payload to the aggregator agent
|
||||
(main session/Orchestrator), which is the SINGLE WRITER appending in place
|
||||
(`工单评论 API(见 TERMINOLOGY)`). `ARCHIVE` is never written by milestone verify
|
||||
(Epic close is the sole archive point).
|
||||
|
||||
**Phase 5.5 ACCEPTED_RISK source**: fan-in node task-ticket review-code reports
|
||||
(located in each task ticket's review annotations / `## 当前状态` review row),
|
||||
not an Epic-level final report. A missing Epic-level final report does NOT
|
||||
trigger the "code-review final report does not exist" warn (that warn is
|
||||
legacy-iteration-only). tech-debt / baseline-failure / flaky-test registration
|
||||
proceeds as usual, sourced from the milestone DoD matrix's regression /
|
||||
baseline-classification results.
|
||||
|
||||
**Phase 5.6 milestone mode** (restricted semantics — skip archive-at-close and
|
||||
issue close):
|
||||
|
||||
1. **Checklist final sweep** only — object = each fan-in task ticket's row 6
|
||||
(`verify里程碑`) + the milestone DoD matrix, NOT the Epic body checklist.
|
||||
Verify each fan-in node's row 6 is checked or annotated
|
||||
`_(Pending: M-{M-id} 未 green)_`. Do NOT flip a still-Pending row 6 — that
|
||||
flip belongs to the aggregator agent (main session/Orchestrator), which
|
||||
performs the node-ticket close action. Write the milestone DoD matrix final
|
||||
sweep to `{epic-slug}/05-verify-milestone-{M-id}`.
|
||||
2. **Do NOT fold/remove any Epic-body `## 当前状态` / `## DAG 状态` section** —
|
||||
milestone verify is read-only on Epic body state.
|
||||
3. **SKIP archive-at-close** (the `## 工件索引` archive banner + row-level
|
||||
`ARCHIVE`) and **SKIP issue close** — both belong to the aggregator agent at
|
||||
Epic close.
|
||||
4. **SKIP Tier 1 run archive** (Phase 5.6 step 5, Tier 1 run archive sub-bullet) — the aggregator agent
|
||||
performs it at Epic close.
|
||||
|
||||
**Milestone verify execution context (pinned)**: run the
|
||||
integration/regression/contract-conformance/NFR suite on a checkout CONTAINING
|
||||
all fan-in nodes' merged code — the aggregator agent syncs main (containing the
|
||||
merged fan-in PRs) into the execution worktree, or builds a temp verify worktree
|
||||
from main HEAD, before triggering; the verify report
|
||||
`{epic-slug}/05-verify-milestone-{M-id}` records the actual execution commit
|
||||
SHA.
|
||||
|
||||
**M→green status transition**: NOT done by milestone verify (read-only on Epic
|
||||
body). The aggregator agent (main session/Orchestrator) reads the verify report
|
||||
and sets the aggregator table M row 状态 = `green`, 重读 = `ON-DEMAND`, and
|
||||
syncs the frozen DAG copy `{epic-slug}/dag` node `status` to `green`.
|
||||
|
||||
**Phase 6.5 milestone mode**: vacuous skip — a milestone has no implementation
|
||||
commit. Commit existence is evidenced by the fan-in node verify PASS + PR
|
||||
merged (already implied by `all_incoming_done_and_green`).
|
||||
|
||||
**Milestone verify FAIL recovery**: FAIL → M `status` = `blocked`. Fix
|
||||
responsibility = the fan-in node owning the failing integration/regression item
|
||||
(the last-done fan-in node's session) or the Epic-level session (DAG author) if
|
||||
un-attributable. Re-run is triggered ONLY by a "fix-landed event" (fix commit
|
||||
merged + CI green, or an explicit re-done report from the owning session) —
|
||||
NOT status polling (done nodes are never reset; `all_incoming_done_and_green`
|
||||
stays true after FAIL). M stays `blocked` until a fix event, then returns to
|
||||
`pending` and verify re-runs. No review-dag re-run unless the fix changes a
|
||||
cross-session contract or the node/edge set.
|
||||
|
||||
### Task mode (verify on a task node ticket, because `task_route.keep_gates` includes `verify`)
|
||||
|
||||
Each task ticket closes only after its own verify run, but legacy verify
|
||||
preconditions do not hold in DAG mode — this node-level branch reuses the
|
||||
`verify` skill with the following node-scoped semantics (so the `verify` gate is
|
||||
not silently downgraded to CI-only).
|
||||
|
||||
**Verification object**: the node's own `acceptance_criteria` → the `test_id`
|
||||
suite (`file-path::test-name` / `MANUAL` / `BENCH:`) all passing fresh + that
|
||||
node's review-code PASS recorded + CI green. NOT milestone fan-in
|
||||
integration/contract/regression items (those are milestone verify's). Spec
|
||||
authority = the node in the frozen DAG copy `{epic-slug}/dag`.
|
||||
|
||||
**Precondition replacements** (task mode — mirror the milestone table, scoped to
|
||||
the node):
|
||||
|
||||
| Legacy verify precondition | Task-mode replacement |
|
||||
| ------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------- |
|
||||
| design-space review converged | review-dag converged (this Epic already passed the single gate; do NOT re-run it) |
|
||||
| iteration-plan review converged | REMOVED (DAG has no plan review) |
|
||||
| legacy iteration plan at `{slug}/04-plan-index` | the node in the frozen DAG copy `{epic-slug}/dag` (no `04-plan-*` page) |
|
||||
| legacy NFR targets from `{slug}/03-design-06-non-functional-design` | REMOVED (product NFRs live in node AC, handled by per-task review-code) |
|
||||
| upstream roadmap chunk done+verified | this node's cross-session in-edge source nodes at terminal state (task source `done` / milestone source `green`) |
|
||||
| code review converged (`pipeline/review-code` success) | this node's ticket review-code PASS + PR merged |
|
||||
| code review final report exists | REMOVED (this node's review-code report lives on the task ticket) |
|
||||
| carried items from previous iteration closed | REMOVED (vacuous — no iteration) |
|
||||
| `core/checklists/verification.md` accessible | KEEP |
|
||||
| Acceptance criteria exist | from node AC + `test_id` suite |
|
||||
| `slug` matches the plan slug | N/A (Tier 1 run slug = `{epic-slug}-task-{node-id}` — the same node-task run namespace review-code runs in and this mode's archive bundle uses below; the Phase 2 precondition-gate cache read MUST use this slug. Only the wiki output naming stays Epic-scoped: `{epic-slug}/05-verify-task-{node-id}`) |
|
||||
|
||||
**Phase 1 read inputs** → the node's AC + `test_id` suite from the frozen DAG
|
||||
copy `{epic-slug}/dag`, generating the DoD matrix.
|
||||
|
||||
**Output naming**: `{epic-slug}/05-verify-task-{node-id}`.
|
||||
|
||||
**Phase 5 report index**: append a `VERIFY-TASK-{node-id}` row, 重读 =
|
||||
`ON-DEMAND` (NOT `ARCHIVE`), via the aggregator agent as single writer (task
|
||||
verify does not edit the comment directly).
|
||||
|
||||
**Phase 5.5 task mode**: ACCEPTED_RISK source = this node's task-ticket
|
||||
review-code report (no Epic-level final report → no "does not exist" warn).
|
||||
tech-debt / baseline-failure / flaky-test registration proceeds as usual.
|
||||
|
||||
**Phase 5.6 task mode**: only checklist final sweep — object = this ticket's
|
||||
5-row checklist (NOT row 6 `verify里程碑` — row 6 is flipped ONLY by the
|
||||
aggregator agent). SKIP archive-at-close (`## 工件索引` row-level `ARCHIVE`) and
|
||||
issue close (both belong to the aggregator agent). SKIP Tier 1 run archive — the
|
||||
aggregator agent collects it cross-worktree at task-ticket close (archive to
|
||||
`<runs-root>/archive/{epic-slug}-task-{node-id}.json` and commit to the
|
||||
workflow branch). Do NOT fold Epic body status sections.
|
||||
|
||||
**Phase 6.5 task mode**: object = this node ticket's commit; semantics = "node
|
||||
implementation commit exists". Baseline = the task worktree's creation-commit
|
||||
SHA (`git log {creation-SHA}..HEAD`), NOT a generic base-branch (post-merge
|
||||
there are no new commits vs base). The task worktree is retained until ticket
|
||||
close (the aggregator agent removes it after collecting task-level Tier 1
|
||||
archive); the task session must NOT remove its own worktree.
|
||||
|
||||
**commit status**: still `pipeline/verify` in both modes.
|
||||
|
||||
### No-milestone DAG Epic-level verify gate
|
||||
|
||||
When the routed Epic's DAG has NO milestone (no `cross_session_in ≥ 2`
|
||||
convergence point), the Epic-level `keep_gates: verify` is satisfied
|
||||
AGGREGATELY by all task-ticket verify runs (each with commit status
|
||||
`pipeline/verify` success) — NO independent Epic-level verify run, NO
|
||||
`{epic-slug}/05-verify-milestone-{M-id}` artifact, NO `VERIFY-M-{M-id}` index
|
||||
row. The Epic close condition degenerates to "all task nodes `done`".
|
||||
|
||||
---
|
||||
|
||||
## References
|
||||
|
||||
|
||||
@@ -0,0 +1,180 @@
|
||||
> Extracted from verify/SKILL.md (section:dag-branch) — moved verbatim; read
|
||||
> on-demand ONLY when the routed Epic is DAG-shaped (frozen DAG at
|
||||
> `{epic-slug}/dag` and `task_route.keep_gates` includes `verify`).
|
||||
|
||||
<!-- section:dag-branch -->
|
||||
## DAG branch (milestone + task modes)
|
||||
|
||||
> This branch OVERRIDES the Preconditions table, Phase 1 read inputs, Phase 5
|
||||
> report index, Phase 5.5 ACCEPTED_RISK source, Phase 5.6 final sweep, and
|
||||
> Phase 6.5 commit gate for a DAG-ticket-pipeline Epic. It applies when the
|
||||
> routed Epic is DAG-shaped: a frozen DAG copy exists at `{epic-slug}/dag` and
|
||||
> the DAG's `task_route.keep_gates` includes `verify`. Legacy iteration verify
|
||||
> (the sections above) remains authoritative for non-DAG iterations. Spec:
|
||||
> `dag-pipeline/spec-05` §5. commit status stays
|
||||
> `pipeline/verify` in both modes.
|
||||
|
||||
### Milestone mode (verify runs on a milestone M when `all_incoming_done_and_green`)
|
||||
|
||||
A milestone node (`type: milestone`) has no implementation work and no ticket;
|
||||
its verify is the integration verification welded at a DAG convergence point
|
||||
(`cross_session_in ≥ 2`). Trigger: the aggregator agent (main
|
||||
session/Orchestrator) detects `all_incoming_done_and_green` — every fan-in
|
||||
source node at its terminal state (task source `done` / milestone source
|
||||
`green`) — and initiates this verify run; the milestone never self-triggers.
|
||||
|
||||
**Precondition replacements** (vs legacy iteration verify):
|
||||
|
||||
| Legacy verify precondition | Milestone-mode replacement |
|
||||
| ---------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| design-space review converged (`review status --stage design-space` success) | review-dag converged (`review status --stage review-dag` success) |
|
||||
| iteration-plan review converged | REMOVED (DAG has no plan review; the single review-dag gate replaces it) |
|
||||
| legacy iteration plan at `{slug}/04-plan-index` | DAG artifact + milestone fan-in slice (no `04-plan-*` page) |
|
||||
| legacy NFR targets from `{slug}/03-design-06-non-functional-design` | REMOVED (product NFRs live in node AC, handled by per-task review-code) |
|
||||
| upstream roadmap chunk done+verified | all milestone fan-in source nodes at terminal state (task source `done` / milestone source `green`, i.e. `all_incoming_done_and_green`) |
|
||||
| code review converged (`pipeline/review-code` success) | ALL fan-in node tickets review-code PASS + PR merged (implied by `done`) |
|
||||
| code review final report exists | REMOVED (no Epic-level final report; per-node review-code reports live on task tickets) |
|
||||
| carried items from previous iteration closed | REMOVED (vacuous — no iteration) |
|
||||
| `core/checklists/verification.md` accessible | KEEP (unconditional) |
|
||||
| Acceptance criteria exist | from DAG-slice-generated DoD matrix (fan-in node AC + integration/contract-conformance/regression/NFR-coverage items) |
|
||||
| `slug` matches the plan slug | N/A (output naming frozen to `{epic-slug}`) |
|
||||
|
||||
**Phase 1 read inputs** → the DAG slice: read the milestone's fan-in subgraph
|
||||
(fan-in nodes + their cross-session edges + contracts) from the frozen DAG copy
|
||||
`{epic-slug}/dag`, and generate the DoD matrix from it (integration items,
|
||||
contract-conformance items, regression items, NFR-coverage items) instead of
|
||||
reading `04-plan-*` pages.
|
||||
|
||||
**Output naming**: `{epic-slug}/05-verify-milestone-{M-id}` (distinct from
|
||||
iteration verify `05-verify-iteration-{N}`).
|
||||
|
||||
**Phase 5 report index**: append a `VERIFY-M-{M-id}` row to the `## 工件索引`
|
||||
comment with 重读 = `ON-DEMAND` (NOT `ARCHIVE`). The milestone verify does NOT
|
||||
edit the comment directly — it reports the row-payload to the aggregator agent
|
||||
(main session/Orchestrator), which is the SINGLE WRITER appending in place
|
||||
(`工单评论 API(见 TERMINOLOGY)`). `ARCHIVE` is never written by milestone verify
|
||||
(Epic close is the sole archive point).
|
||||
|
||||
**Phase 5.5 ACCEPTED_RISK source**: fan-in node task-ticket review-code reports
|
||||
(located in each task ticket's review annotations / `## 当前状态` review row),
|
||||
not an Epic-level final report. A missing Epic-level final report does NOT
|
||||
trigger the "code-review final report does not exist" warn (that warn is
|
||||
legacy-iteration-only). tech-debt / baseline-failure / flaky-test registration
|
||||
proceeds as usual, sourced from the milestone DoD matrix's regression /
|
||||
baseline-classification results.
|
||||
|
||||
**Phase 5.6 milestone mode** (restricted semantics — skip archive-at-close and
|
||||
issue close):
|
||||
|
||||
1. **Checklist final sweep** only — object = each fan-in task ticket's row 6
|
||||
(`verify里程碑`) + the milestone DoD matrix, NOT the Epic body checklist.
|
||||
Verify each fan-in node's row 6 is checked or annotated
|
||||
`_(Pending: M-{M-id} 未 green)_`. Do NOT flip a still-Pending row 6 — that
|
||||
flip belongs to the aggregator agent (main session/Orchestrator), which
|
||||
performs the node-ticket close action. Write the milestone DoD matrix final
|
||||
sweep to `{epic-slug}/05-verify-milestone-{M-id}`.
|
||||
2. **Do NOT fold/remove any Epic-body `## 当前状态` / `## DAG 状态` section** —
|
||||
milestone verify is read-only on Epic body state.
|
||||
3. **SKIP archive-at-close** (the `## 工件索引` archive banner + row-level
|
||||
`ARCHIVE`) and **SKIP issue close** — both belong to the aggregator agent at
|
||||
Epic close.
|
||||
4. **SKIP Tier 1 run archive** (Phase 5.6 step 5, Tier 1 run archive sub-bullet) — the aggregator agent
|
||||
performs it at Epic close.
|
||||
|
||||
**Milestone verify execution context (pinned)**: run the
|
||||
integration/regression/contract-conformance/NFR suite on a checkout CONTAINING
|
||||
all fan-in nodes' merged code — the aggregator agent syncs main (containing the
|
||||
merged fan-in PRs) into the execution worktree, or builds a temp verify worktree
|
||||
from main HEAD, before triggering; the verify report
|
||||
`{epic-slug}/05-verify-milestone-{M-id}` records the actual execution commit
|
||||
SHA.
|
||||
|
||||
**M→green status transition**: NOT done by milestone verify (read-only on Epic
|
||||
body). The aggregator agent (main session/Orchestrator) reads the verify report
|
||||
and sets the aggregator table M row 状态 = `green`, 重读 = `ON-DEMAND`, and
|
||||
syncs the frozen DAG copy `{epic-slug}/dag` node `status` to `green`.
|
||||
|
||||
**Phase 6.5 milestone mode**: vacuous skip — a milestone has no implementation
|
||||
commit. Commit existence is evidenced by the fan-in node verify PASS + PR
|
||||
merged (already implied by `all_incoming_done_and_green`).
|
||||
|
||||
**Milestone verify FAIL recovery**: FAIL → M `status` = `blocked`. Fix
|
||||
responsibility = the fan-in node owning the failing integration/regression item
|
||||
(the last-done fan-in node's session) or the Epic-level session (DAG author) if
|
||||
un-attributable. Re-run is triggered ONLY by a "fix-landed event" (fix commit
|
||||
merged + CI green, or an explicit re-done report from the owning session) —
|
||||
NOT status polling (done nodes are never reset; `all_incoming_done_and_green`
|
||||
stays true after FAIL). M stays `blocked` until a fix event, then returns to
|
||||
`pending` and verify re-runs. No review-dag re-run unless the fix changes a
|
||||
cross-session contract or the node/edge set.
|
||||
|
||||
### Task mode (verify on a task node ticket, because `task_route.keep_gates` includes `verify`)
|
||||
|
||||
Each task ticket closes only after its own verify run, but legacy verify
|
||||
preconditions do not hold in DAG mode — this node-level branch reuses the
|
||||
`verify` skill with the following node-scoped semantics (so the `verify` gate is
|
||||
not silently downgraded to CI-only).
|
||||
|
||||
**Verification object**: the node's own `acceptance_criteria` → the `test_id`
|
||||
suite (`file-path::test-name` / `MANUAL` / `BENCH:`) all passing fresh + that
|
||||
node's review-code PASS recorded + CI green. NOT milestone fan-in
|
||||
integration/contract/regression items (those are milestone verify's). Spec
|
||||
authority = the node in the frozen DAG copy `{epic-slug}/dag`.
|
||||
|
||||
**Precondition replacements** (task mode — mirror the milestone table, scoped to
|
||||
the node):
|
||||
|
||||
| Legacy verify precondition | Task-mode replacement |
|
||||
| ------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------- |
|
||||
| design-space review converged | review-dag converged (this Epic already passed the single gate; do NOT re-run it) |
|
||||
| iteration-plan review converged | REMOVED (DAG has no plan review) |
|
||||
| legacy iteration plan at `{slug}/04-plan-index` | the node in the frozen DAG copy `{epic-slug}/dag` (no `04-plan-*` page) |
|
||||
| legacy NFR targets from `{slug}/03-design-06-non-functional-design` | REMOVED (product NFRs live in node AC, handled by per-task review-code) |
|
||||
| upstream roadmap chunk done+verified | this node's cross-session in-edge source nodes at terminal state (task source `done` / milestone source `green`) |
|
||||
| code review converged (`pipeline/review-code` success) | this node's ticket review-code PASS + PR merged |
|
||||
| code review final report exists | REMOVED (this node's review-code report lives on the task ticket) |
|
||||
| carried items from previous iteration closed | REMOVED (vacuous — no iteration) |
|
||||
| `core/checklists/verification.md` accessible | KEEP |
|
||||
| Acceptance criteria exist | from node AC + `test_id` suite |
|
||||
| `slug` matches the plan slug | N/A (Tier 1 run slug = `{epic-slug}-task-{node-id}` — the same node-task run namespace review-code runs in and this mode's archive bundle uses below; the Phase 2 precondition-gate cache read MUST use this slug. Only the wiki output naming stays Epic-scoped: `{epic-slug}/05-verify-task-{node-id}`) |
|
||||
|
||||
**Phase 1 read inputs** → the node's AC + `test_id` suite from the frozen DAG
|
||||
copy `{epic-slug}/dag`, generating the DoD matrix.
|
||||
|
||||
**Output naming**: `{epic-slug}/05-verify-task-{node-id}`.
|
||||
|
||||
**Phase 5 report index**: append a `VERIFY-TASK-{node-id}` row, 重读 =
|
||||
`ON-DEMAND` (NOT `ARCHIVE`), via the aggregator agent as single writer (task
|
||||
verify does not edit the comment directly).
|
||||
|
||||
**Phase 5.5 task mode**: ACCEPTED_RISK source = this node's task-ticket
|
||||
review-code report (no Epic-level final report → no "does not exist" warn).
|
||||
tech-debt / baseline-failure / flaky-test registration proceeds as usual.
|
||||
|
||||
**Phase 5.6 task mode**: only checklist final sweep — object = this ticket's
|
||||
5-row checklist (NOT row 6 `verify里程碑` — row 6 is flipped ONLY by the
|
||||
aggregator agent). SKIP archive-at-close (`## 工件索引` row-level `ARCHIVE`) and
|
||||
issue close (both belong to the aggregator agent). SKIP Tier 1 run archive — the
|
||||
aggregator agent collects it cross-worktree at task-ticket close (archive to
|
||||
`<runs-root>/archive/{epic-slug}-task-{node-id}.json` and commit to the
|
||||
workflow branch). Do NOT fold Epic body status sections.
|
||||
|
||||
**Phase 6.5 task mode**: object = this node ticket's commit; semantics = "node
|
||||
implementation commit exists". Baseline = the task worktree's creation-commit
|
||||
SHA (`git log {creation-SHA}..HEAD`), NOT a generic base-branch (post-merge
|
||||
there are no new commits vs base). The task worktree is retained until ticket
|
||||
close (the aggregator agent removes it after collecting task-level Tier 1
|
||||
archive); the task session must NOT remove its own worktree.
|
||||
|
||||
**commit status**: still `pipeline/verify` in both modes.
|
||||
|
||||
### No-milestone DAG Epic-level verify gate
|
||||
|
||||
When the routed Epic's DAG has NO milestone (no `cross_session_in ≥ 2`
|
||||
convergence point), the Epic-level `keep_gates: verify` is satisfied
|
||||
AGGREGATELY by all task-ticket verify runs (each with commit status
|
||||
`pipeline/verify` success) — NO independent Epic-level verify run, NO
|
||||
`{epic-slug}/05-verify-milestone-{M-id}` artifact, NO `VERIFY-M-{M-id}` index
|
||||
row. The Epic close condition degenerates to "all task nodes `done`".
|
||||
|
||||
---
|
||||
@@ -0,0 +1,495 @@
|
||||
> Extracted from verify/SKILL.md (phase 5.5 / 5.55 / 5.56 / 5.6) — moved
|
||||
> verbatim; read on-demand during Phase 5 execution, before PASS. Each phase
|
||||
> is mandatory-before-PASS in its trigger condition; the main flow stops at
|
||||
> each boundary until the referenced protocol reports completion.
|
||||
|
||||
<!-- section:phase-5.5 -->
|
||||
### Phase 5.5 — Tech Debt Registry Filing (mandatory before PASS)
|
||||
|
||||
Tech debt is filed **registry-first** (`core/rules/ticket-lifecycle.md`,
|
||||
[TT-3002] G1): new items become ROWS in the source ticket's `## TD 登记` comment;
|
||||
an independent ticket is created only at **promotion** (claim/schedule). There
|
||||
is no `tech-debt.md` file and no `{slug}/tech-debt` wiki page — both remain
|
||||
retired. The registry preserves the three guarantees of the old
|
||||
one-issue-per-item model: visible (the comment lives on a tracker ticket),
|
||||
individually closeable (row-level checkbox), de-duplicated across sessions
|
||||
(the TD index is stronger than title-keyword matching).
|
||||
|
||||
**Sprint-mode override ([TT-3002] G5/[TT-3007])**: read `filing.sprint-mode` from
|
||||
`<instance-root>/workflow-routing.yaml` at the START of this phase (no caching). When
|
||||
`true`, ALL severities file registry-only — registration rows are written as
|
||||
normal (severity included, nothing lost) but promotion to standalone tickets
|
||||
is FROZEN until the switch returns to `false`. Rationale: the 2026-08-12
|
||||
sprint zeroed fix capacity while filing kept running (the 125-fragment
|
||||
backlog's direct trigger); an explicit debt-side downshift beats hoping for
|
||||
discipline. BF/FT phases 5.55/5.56 are NOT covered by this switch — failure
|
||||
evidence must stay immediately visible. Flipping the switch is a human
|
||||
decision recorded on the sprint tracker; semantics in
|
||||
`rules/workflow-routing.md` §立案降档.
|
||||
|
||||
**Adjacency quota ([TT-3002] G3/[TT-3005])**: while collecting inputs, also check the
|
||||
AREAS this iteration touched (packages/modules with commits this iteration).
|
||||
If the source tickets for those areas carry applicable `## TD 登记` rows, at
|
||||
least ONE row must be taken along and disposed this iteration (fixed, or
|
||||
explicitly re-deferred with a reason — silence is not a disposition). Record
|
||||
`consumed X / applicable Y` (or `0 applicable`) in the TD report section;
|
||||
verification checklist §8.4 cross-checks it against the run's debt-quota
|
||||
record (historically the roadmap's per-chunk debt-quota line). This gives debt digestion a steady capacity source tied to
|
||||
touch, not to cleanup campaigns.
|
||||
|
||||
**Promotion quota + pull event ([TT-3061])**: promotion to a standalone ticket
|
||||
requires (a) a **pull event** — the row's Reactivation Trigger fired (state
|
||||
the observed event) OR a named claimer/schedule; "it seemed important" is not
|
||||
a pull event — recorded in the promotion body's `## 拉动事件 / Pull Event`
|
||||
section; and (b) the origin module's OPEN promoted-TD count is below the
|
||||
quota (**default 10** — counted **per origin module**: resolve the row's
|
||||
module from the ticket body's `Origin` field, then count that module's OPEN
|
||||
`tech-debt` tickets; retro §2.10 reports breaches). At or above quota →
|
||||
register-only until the count drops; before each Phase 5.5 promotion
|
||||
re-check the owning module's count, and a row whose module is at or above
|
||||
quota is NOT promoted — defer it and annotate the registry row with
|
||||
`quota-held` (re-checked on the next verify run, retro 2026-08-21). A row
|
||||
marked `[COLD]` by retrospective §2.10
|
||||
(unclaimed >3 retro cycles) promotes only after the pull event clears the
|
||||
mark.
|
||||
|
||||
**Collect inputs** — every tech-debt item to register this iteration:
|
||||
|
||||
1. Every UNVERIFIABLE row in the DoD matrix (Phase 3), with its Reactivation
|
||||
Trigger.
|
||||
2. Every ACCEPTED_RISK finding in the code-review final report
|
||||
(`{slug}/reviews/code/final/report`), with its Recommended Reactivation
|
||||
Trigger.
|
||||
3. Every `[OPEN: <short-id>]` marker the Developer left in code this iteration
|
||||
(per implementation checklist POST-6.2).
|
||||
|
||||
If the code-review final report does not exist, warn the user — ACCEPTED_RISK
|
||||
items cannot be captured. This is itself a process gap that must be flagged.
|
||||
|
||||
**Step 1 — De-duplicate against the registry index and promoted issues.**
|
||||
|
||||
1. Read the source ticket's `## TD 登记` comment (create the comment if this
|
||||
is its first row) and match each candidate against existing rows by
|
||||
`TD-NNN` and reactivation trigger. Same-source re-reporting is the
|
||||
anti-pattern this step exists to prevent (the visual-cluster incident: 18
|
||||
fragments from one source under the old keyword matching).
|
||||
2. Query OPEN promoted tech-debt issues for cross-source duplicates:
|
||||
|
||||
```
|
||||
工单 API 检索(见 TERMINOLOGY)
|
||||
(owner/repo 按实例绑定,labels="tech-debt", state="open")
|
||||
```
|
||||
|
||||
**Step 2 — Assign `TD-NNN` via the ledger mutex ([TT-3322]).** One script call
|
||||
per batch: `bash script/td-alloc.sh <count = new items> <source-slug>
|
||||
[--ticket N]` returns a contiguous range from the TD allocation ledger
|
||||
(append-only comments, earliest-comment-id wins; the seed comment pins the
|
||||
historical floor). Split the returned range across the Step 3 rows in order.
|
||||
**Any allocation — manual included — must land a `**td-alloc**` comment on
|
||||
the ledger before the registry row is written; hand-computed `max + 1` is
|
||||
forbidden** (the 2026-08-24 three-way collision). On exit 5 (retry
|
||||
exhaustion) abort this phase's filing and retry — never hand-assign. The id is **reserved for life**: promotion reuses it, never
|
||||
renumbers. Run `--check` (reconciliation) here if the last check predates
|
||||
this batch.
|
||||
|
||||
**Step 3 — Append one registry row per new item.** Append to the source
|
||||
ticket's `## TD 登记` comment (no source ticket → the owning Epic's tracker
|
||||
ticket; no Epic → the standing `TD 冷存档` tracker):
|
||||
|
||||
```markdown
|
||||
- [ ] TD-{NNN} · {UNVERIFIABLE | ACCEPTED_RISK | DEFERRED} · {HIGH | MEDIUM | LOW}
|
||||
· {origin chunk-id/iter-N} — {one-line summary}
|
||||
· trigger: {objectively verifiable reactivation condition — never "when ready";
|
||||
if no trigger can be defined this is NOT tech debt and the iteration verdict
|
||||
becomes FAIL}
|
||||
```
|
||||
|
||||
**Step 4 — Cross-link (adapted).** The registry comment already lives on the
|
||||
source issue — the source → debt navigation the old body-edit provided. When
|
||||
filing went to an Epic tracker or the 冷存档 (no source ticket), reference the
|
||||
originating slug in each row so the trail survives.
|
||||
|
||||
**Step 5 — Record the mapping in the verification report.** The report's
|
||||
"Tech Debt" section records `TD-NNN → registry row` (source `#NNNN` +
|
||||
`## TD 登记` comment); promoted items record `TD-NNN → #NNNN` as before.
|
||||
|
||||
**Promotion (认领升票) — when a row is scheduled or picked up.** Create the
|
||||
independent ticket THEN, carrying the reserved `TD-NNN`:
|
||||
|
||||
```
|
||||
POST <gitea-base-url>/api/v1/repos/Octopus/octopus/issues
|
||||
body: {"title":"[{origin}] Tech debt: {short description} (TD-{NNN})",
|
||||
"body":<promotion template below>,
|
||||
"labels":[tech_debt_label_id, severity_label_id]}
|
||||
```
|
||||
|
||||
- **Severity → label** (reuse the existing exclusive Priority set):
|
||||
|
||||
| Severity | Label |
|
||||
| -------- | ----------------- |
|
||||
| HIGH | `Priority/High` |
|
||||
| MEDIUM | `Priority/Medium` |
|
||||
| LOW | `Priority/Low` |
|
||||
|
||||
- **Promotion body template** (the pre-[TT-3002] issue template, now used only at
|
||||
promotion):
|
||||
|
||||
```markdown
|
||||
## Parent / 父级
|
||||
|
||||
{#source_issue carrying the ## TD 登记 row}
|
||||
|
||||
## Summary
|
||||
|
||||
{one-paragraph description of the debt}
|
||||
|
||||
| Field | Value |
|
||||
| -------- | ------------------------------------------- |
|
||||
| TD ID | TD-{NNN} (reserved at registration) |
|
||||
| Type | {UNVERIFIABLE \| ACCEPTED_RISK \| DEFERRED} |
|
||||
| Origin | {chunk-id/iter-N/phase or slug} |
|
||||
| Severity | {HIGH \| MEDIUM \| LOW} |
|
||||
|
||||
## Reactivation Trigger
|
||||
|
||||
{from the registry row}
|
||||
|
||||
## 拉动事件 / Pull Event
|
||||
|
||||
{trigger fired: {observed event} | claimed by {who} for {when}}
|
||||
|
||||
## Acceptance Criteria (how to close this issue)
|
||||
|
||||
- [ ] {specific action that resolves the debt}
|
||||
|
||||
## Context
|
||||
|
||||
- Verification report: `{slug}/05-verify-iteration-{N}`
|
||||
- Code review report: `{slug}/reviews/code/final/report` (if ACCEPTED_RISK)
|
||||
```
|
||||
|
||||
- After creating the promoted ticket: tick the registry row (`- [x]`) and
|
||||
append `→ #NNNN` to it.
|
||||
|
||||
If no new tech-debt items were found this iteration, the phase is a no-op —
|
||||
record "0 tech-debt items" in the report and proceed.
|
||||
|
||||
<!-- section:phase-5.55 -->
|
||||
### Phase 5.55 — Baseline-Failure Issue Registration (mandatory before PASS when pre-existing failures exist)
|
||||
|
||||
Pre-existing test failures (BF) are tracked as **root-cause family umbrella
|
||||
tickets** (`core/rules/ticket-lifecycle.md`, [TT-3002] G1; precedents [TT-2585]
|
||||
umbrella + [TT-2925] cluster) — one `BF-NNN` ticket per failure-signature family,
|
||||
labeled `baseline-failure`, with each occurrence's evidence attached as
|
||||
comments. There is no `baseline-failures.md` file and no
|
||||
`{slug}/baseline-failures` wiki page. A pre-existing failure does not block
|
||||
the iteration that _discovered_ it (it pre-dates that work), but it MUST be
|
||||
filed against (or into) a family; an un-filed baseline failure is a process
|
||||
gap and the iteration is NOT Done.
|
||||
|
||||
**Birth triage SLA ([TT-3061])**: a BF umbrella is born with `Kind/Bug` (it IS a
|
||||
bug — of the baseline) and must be triaged the SAME DAY it is filed:
|
||||
assigned, scheduled, or explicitly deferred with a reason on the ticket.
|
||||
Untriaged-next-day BF umbrellas are named individually in retro §2.10
|
||||
(compliance %), not averaged away.
|
||||
|
||||
**Collect inputs** — every pre-existing failure to register this iteration:
|
||||
|
||||
1. Every failure classified **pre-existing** in Phase 2.6 (fails on the base
|
||||
branch / last-green commit too).
|
||||
2. Any baseline-run failures noted in the brownfield pre-check (Greenfield vs.
|
||||
Brownfield section).
|
||||
|
||||
**Step 1 — De-duplicate by failure SIGNATURE against existing families (open
|
||||
AND closed), per `core/rules/testing.md`** (de-duplicate BEFORE filing,
|
||||
retro [TT-2696]). Query `baseline-failure` issues in ALL states:
|
||||
|
||||
```
|
||||
GET <gitea-base-url>/api/v1/repos/Octopus/octopus/issues?labels=baseline-failure&state=all&page=N&limit=50
|
||||
```
|
||||
|
||||
Match each candidate by **failure signature** — the error/assertion signature
|
||||
plus the affected surface, not just `file::test-name` (one root-cause family
|
||||
may span several tests; several tests failing with the same assertion shape
|
||||
are ONE family). On a signature hit, do NOT create a new ticket: attach the
|
||||
new run evidence (run, commit, failing output, sibling tests observed) as a
|
||||
comment on the FAMILY umbrella ticket. Filing a second ticket inside a known
|
||||
root-cause family is the anti-pattern this phase exists to prevent. If a
|
||||
tracked family is now FIXED by this iteration's work, close its umbrella with
|
||||
a comment citing the fixing commit (a bonus, not a requirement). If the query
|
||||
itself errors (API failure — not "no matches"), retry once; on the second
|
||||
failure proceed to file with the literal marker `dedup-unverified` in the
|
||||
umbrella's first evidence comment (query-failure ruling, [TT-3383] — fail-open,
|
||||
visible; rationale in `core/rules/ticket-lifecycle.md`).
|
||||
|
||||
**Step 2 — Assign the next `BF-NNN`** per `core/rules/testing.md`
|
||||
§ "Pre-existing test failures must be filed, not silently logged" (the L1 rule
|
||||
owns the repo-wide sequential numbering invariant — `max + 1`, duplicate ids
|
||||
forbidden incl. closed tickets). `BF-NNN` names the FAMILY; the Gitea issue
|
||||
number `#NNNN` is the tracker handle.
|
||||
|
||||
**Step 3 — Create one umbrella ticket per NEW root-cause family.** Only when
|
||||
no existing family matches the signature:
|
||||
|
||||
```
|
||||
POST <gitea-base-url>/api/v1/repos/Octopus/octopus/issues
|
||||
body: {"title":"[{origin}] Baseline failure: {test identifier} (BF-{NNN})",
|
||||
"body":<issue body template below>,
|
||||
"labels":[baseline_failure_label_id, severity_label_id, kind_bug_label_id]}
|
||||
```
|
||||
|
||||
- **Title**: `[{origin}] Baseline failure: {signature summary} (BF-{NNN})`
|
||||
where `{origin}` is `chunk-{id}/iter-{N}` or the bugfix slug, and
|
||||
`{signature summary}` is the family's error/assertion shape (not a single
|
||||
test name — sibling tests observed later join this umbrella as evidence
|
||||
comments).
|
||||
- **Severity → label** (reuse the existing exclusive Priority set; a failing
|
||||
test defaults to at least MEDIUM, HIGH if on a critical path):
|
||||
|
||||
| Severity | Label |
|
||||
| -------- | ----------------- |
|
||||
| HIGH | `Priority/High` |
|
||||
| MEDIUM | `Priority/Medium` |
|
||||
| LOW | `Priority/Low` |
|
||||
|
||||
- Also attach `Kind/Bug` so the failure is discoverable in the bug tracker
|
||||
alongside manually-reported bugs.
|
||||
- **Issue body template**:
|
||||
|
||||
````markdown
|
||||
## Parent / 父级
|
||||
|
||||
{#source_issue, or "no source issue — discovered during iteration baseline"}
|
||||
|
||||
## Summary
|
||||
|
||||
A test was already failing before this iteration's work began. It does not
|
||||
block the discovering iteration but must be tracked to closure.
|
||||
|
||||
| Field | Value |
|
||||
| -------------- | ---------------------------------------------- |
|
||||
| BF ID | BF-{NNN} (family) |
|
||||
| Signature | {error/assertion shape} |
|
||||
| Tests affected | `{file::test-name}`, … (initial members) |
|
||||
| Origin | {chunk-id/iter-N or slug} |
|
||||
| Severity | {HIGH \| MEDIUM \| LOW} |
|
||||
| First observed | {base commit / date the failure reproduces on} |
|
||||
|
||||
## Reproduction
|
||||
|
||||
```
|
||||
git checkout {base commit}
|
||||
(cd <harness-package> && bun test --timeout 120000 {test file}) # or project-equivalent
|
||||
```
|
||||
|
||||
Failing output:
|
||||
|
||||
```
|
||||
{paste the relevant assertion / error}
|
||||
```
|
||||
|
||||
## Acceptance Criteria (how to close this issue)
|
||||
|
||||
- [ ] The named test passes on a clean checkout of the target branch.
|
||||
- [ ] If the test is deleted/renamed, the replacement covers the same
|
||||
behavior and passes.
|
||||
|
||||
## Context
|
||||
|
||||
- Verification report: `{slug}/05-verify-iteration-{N}`
|
||||
````
|
||||
|
||||
**Step 4 — Cross-link to the source issue (mandatory).** Per the
|
||||
issue-cross-linking rule, every baseline-failure issue MUST link back to its
|
||||
source:
|
||||
|
||||
- The issue body already carries `## Parent` (above).
|
||||
- Update the source/parent issue body to reference each new baseline-failure
|
||||
issue by `#NNNN` in its task list (e.g.
|
||||
`- [ ] #NNNN — BF-{NNN} {test identifier}`), so reviewers can navigate from
|
||||
source → failure.
|
||||
|
||||
**Step 5 — Record the mapping in the verification report.** The
|
||||
`BF-NNN → #NNNN` mapping is written ONLY in the Phase 5 verification report's
|
||||
"Baseline Failures" section (and in the issue title itself). There is no local
|
||||
file to update.
|
||||
|
||||
If no new baseline failures were found this iteration, the phase is a no-op —
|
||||
record "0 baseline failures" in the report and proceed.
|
||||
|
||||
<!-- section:phase-5.56 -->
|
||||
### Phase 5.56 — Flaky-Test Issue Registration (mandatory before PASS when flaky tests are unfixed)
|
||||
|
||||
Flaky tests (intermittent pass/fail) are tracked as **root-cause family
|
||||
umbrella tickets** (`core/rules/ticket-lifecycle.md`, [TT-3002] G1) — one
|
||||
`FT-NNN` ticket per failure-signature family, labeled `flaky-test`, with each
|
||||
occurrence's evidence (run count, failure rate, commit) attached as comments.
|
||||
A flaky test that is not fixed within this iteration MUST be filed against
|
||||
(or into) a family; otherwise it evaporates at iteration end and the
|
||||
"compare flaky count against baseline" check (TST-2.5) has no persistent
|
||||
register to compare against. Filing does not block the verdict, but an unfixed
|
||||
flaky test left un-filed is a process gap and the iteration is NOT Done.
|
||||
|
||||
**Expiry SLA ([TT-3061])**: an FT umbrella is born with `Kind/Testing` and a
|
||||
**fix-or-isolate window** (default 7 days) recorded in its body (isolating =
|
||||
quarantining/skipping the test with the family id in the skip reason, which
|
||||
keeps the register comparable). Past the window without fix or isolation, the
|
||||
umbrella is escalated on the ticket (comment naming the owner); retro §2.10
|
||||
reports fix-or-isolate compliance per cycle.
|
||||
|
||||
**Collect inputs** — every flaky test to register this iteration:
|
||||
|
||||
1. Every flaky test surfaced in Phase 2.1 (intermittent pass/fail across
|
||||
reruns) that was NOT fixed by the Developer this iteration.
|
||||
2. Any flaky test carried over from a prior iteration's report that is still
|
||||
intermittently failing.
|
||||
|
||||
**Step 1 — De-duplicate by failure SIGNATURE against existing families (open
|
||||
AND closed), per `core/rules/testing.md`** (de-duplicate BEFORE filing,
|
||||
retro [TT-2696]). Query `flaky-test` issues in ALL states:
|
||||
|
||||
```
|
||||
GET <gitea-base-url>/api/v1/repos/Octopus/octopus/issues?labels=flaky-test&state=all&page=N&limit=50
|
||||
```
|
||||
|
||||
Match each candidate by **failure signature** — the flakiness mode (timeout /
|
||||
race / order-dependence / env-leak) plus the affected surface, not just
|
||||
`file::test-name` (one root cause may flake several tests). On a signature
|
||||
hit, do NOT create a new ticket: attach the new run evidence (run count,
|
||||
failure rate, commit, sibling tests) as a comment on the FAMILY umbrella
|
||||
ticket. Filing a second ticket inside a known root-cause family is the
|
||||
anti-pattern this phase exists to prevent. If a tracked family now passes
|
||||
deterministically, close its umbrella citing the fixing commit. If the query
|
||||
itself errors (API failure — not "no matches"), retry once; on the second
|
||||
failure proceed to file with the literal marker `dedup-unverified` in the
|
||||
umbrella's first evidence comment (query-failure ruling, [TT-3383] — fail-open,
|
||||
visible; rationale in `core/rules/ticket-lifecycle.md`).
|
||||
|
||||
**Step 2 — Assign the next `FT-NNN`** per `core/rules/testing.md`
|
||||
§ "Flaky tests must be filed, not silently tolerated" (the L1 rule owns the
|
||||
repo-wide sequential numbering invariant — `max + 1`, duplicate ids forbidden
|
||||
incl. closed tickets). `FT-NNN` names the FAMILY.
|
||||
|
||||
**Step 3 — Create one umbrella ticket per NEW root-cause family.** Only when
|
||||
no existing family matches the signature:
|
||||
|
||||
```
|
||||
POST <gitea-base-url>/api/v1/repos/Octopus/octopus/issues
|
||||
body: {"title":"[{origin}] Flaky test: {test identifier} (FT-{NNN})",
|
||||
"body":<issue body template below>,
|
||||
"labels":[flaky_test_label_id, severity_label_id, kind_testing_label_id]}
|
||||
```
|
||||
|
||||
- **Title**: `[{origin}] Flaky test: {signature summary} (FT-{NNN})` — the
|
||||
family's flakiness mode + surface (sibling tests join later as evidence
|
||||
comments, not new tickets).
|
||||
- **Severity** → a flaky test defaults to MEDIUM (HIGH if on a critical path
|
||||
or blocking CI); reuse the exclusive Priority set.
|
||||
- Also attach `Kind/Testing` so it is discoverable in the testing tracker.
|
||||
- **Issue body template**:
|
||||
|
||||
````markdown
|
||||
## Parent / 父级
|
||||
|
||||
{#source_issue, or "no source issue — discovered during iteration verification"}
|
||||
|
||||
## Summary
|
||||
|
||||
A test passes and fails intermittently across runs. It undermines the
|
||||
reliability of the suite and must be stabilized or quarantined.
|
||||
|
||||
| Field | Value |
|
||||
| ------------ | ------------------------- |
|
||||
| FT ID | FT-{NNN} (family) |
|
||||
| Signature | {flakiness mode + surface} |
|
||||
| Tests affected | `{file::test-name}`, … (initial members) |
|
||||
| Origin | {chunk-id/iter-N or slug} |
|
||||
| Severity | {HIGH \| MEDIUM \| LOW} |
|
||||
| Failure rate | {e.g. 3/10 runs} |
|
||||
|
||||
## Reproduction
|
||||
|
||||
```
|
||||
for i in $(seq 1 10); do (cd <harness-package> && bun test --timeout 120000 {test file}) || echo "run $i FAILED"; done
|
||||
```
|
||||
|
||||
## Acceptance Criteria (how to close this issue)
|
||||
|
||||
- [ ] The test passes deterministically across 10 consecutive runs.
|
||||
- [ ] If it cannot be stabilized, it is quarantined (`test.skip` /
|
||||
`test.todo` with a comment citing FT-{NNN}) and a stable replacement
|
||||
is filed as tech-debt (TD-NNN).
|
||||
|
||||
## Context
|
||||
|
||||
- Verification report: `{slug}/05-verify-iteration-{N}`
|
||||
````
|
||||
|
||||
**Step 4 — Cross-link to the source issue (mandatory).** Every flaky-test
|
||||
issue links back to its source via `## Parent`, and the source/parent issue
|
||||
task list references each by `#NNNN`
|
||||
(`- [ ] #NNNN — FT-{NNN} {test identifier}`).
|
||||
|
||||
**Step 5 — Record the mapping in the verification report.** The
|
||||
`FT-NNN → #NNNN` mapping is written ONLY in the Phase 5 report's "Flaky Tests"
|
||||
section (and the issue title). No local file.
|
||||
|
||||
If no unfixed flaky tests exist this iteration, the phase is a no-op — record
|
||||
"0 flaky tests" in the report and proceed.
|
||||
|
||||
<!-- section:phase-5.6 -->
|
||||
### Phase 5.6 — Issue Checklist Sync (final sweep, mandatory before PASS)
|
||||
|
||||
This is the **final** checklist sync — the last of the progressive sync
|
||||
points (requirements exit, design exit, plan exit, each iteration commit, PR
|
||||
creation, review convergence, CI transitions, and here — per the sync-point
|
||||
table in `core/rules/issue-checklist-sync.md`). Earlier syncs may have
|
||||
already checked off completed items; this phase catches everything remaining
|
||||
and ensures no `- [ ]` item is left without an annotation.
|
||||
|
||||
1. **Identify the source issue** per `core/rules/issue-checklist-sync.md`
|
||||
§ "How to sync (each point)" step 1 (find `Closes #N` / `Fixes #N` in the
|
||||
PR body or commit messages). If no source issue exists (e.g. standalone
|
||||
bugfix with no tracking issue), skip this phase.
|
||||
2. **Fetch the issue body** via `工单 API(见 TERMINOLOGY)get` (rule step 2).
|
||||
3. **Map every remaining `- [ ]` checklist item** to one of three states:
|
||||
- **Done** (missed by earlier syncs) → mark `- [x]` and append
|
||||
`_(PR #NNN: <file/component>)_`.
|
||||
- **Deferred** → keep `- [ ]` and append `_(Deferred: TD-NNN <reason>)_`.
|
||||
- **Pending** → keep `- [ ]` and append `_(Pending: <blocker>)_`.
|
||||
4. **Fold the `## 当前状态` live-status section** (if present). Rows that have
|
||||
a checklist counterpart (review, process-ACs) are already reflected as
|
||||
checklist annotations at their sync points. Rows with no checklist
|
||||
counterpart in a non-Epic issue (PR opened/merged) are folded as follow-up
|
||||
evidence on the issue narrative (e.g. `_(PR #NNN merged: <summary>)_` on the
|
||||
item it delivered, or in the report). Once every row is accounted for,
|
||||
remove the section from the issue body.
|
||||
5. **archive-at-close: mark the `## 工件索引` comment archived** (归档动作 — [TT-1929]). Issue
|
||||
closing IS the archive-at-close action; it is explicit, not implicit. Edit the index
|
||||
comment in place per `_shared/gitea-write-patterns.md` Pattern 10 Archive-at-close
|
||||
(mechanism — banner + every row's 重读 → ARCHIVE + invariants — is defined there,
|
||||
do not restate; sequence/actor per `rules/issue-checklist-sync.md` § 归档动作).
|
||||
- Skip if no source issue exists.
|
||||
- **Tier 1 run archive** ([TT-1988] two-tier artifacts — only if a Tier 1 run
|
||||
workspace exists): if `<runs-root>/{slug}/` exists (a stage in this run
|
||||
produced Tier 1 local artifacts, e.g. review-code findings), archive the
|
||||
run workspace per `core/rules/two-tier-artifacts.md` § Archive-at-close
|
||||
(the L1 rule is authoritative — do NOT restate its steps here).
|
||||
The archived bundle must pass
|
||||
`core/schemas/runs-bundle.schema.json` validation (the generator
|
||||
validates by default; a red exit blocks close).
|
||||
Verify deltas only: skip in milestone/task DAG mode (the aggregator agent
|
||||
performs it at Epic/task-ticket close — see the DAG branch below).
|
||||
6. **Update the issue body** via `工单 API(见 TERMINOLOGY)update` with the annotated
|
||||
checklist. Preserve all non-checklist content unchanged.
|
||||
7. **Verify**: re-read the issue and confirm no `- [ ]` item lacks an
|
||||
annotation. Every unchecked item MUST have a `(Deferred: ...)` or
|
||||
`(Pending: ...)` note explaining why it is not done.
|
||||
8. **Close the issue** (completes the archive-at-close loop): if the flow has
|
||||
no PR (no `Closes #N` on merge), the Verifier closes the issue after PASS
|
||||
approval via `工单 API(见 TERMINOLOGY)update(state="closed")` — the banner date is
|
||||
corrected to the actual close date if it differs from today. If a PR carries
|
||||
`Closes #N`, the merge closes it; no further action.
|
||||
|
||||
If a checklist item cannot be mapped to evidence, deferral, or pending
|
||||
status, the iteration is NOT Done — the item represents untracked scope.
|
||||
@@ -2,7 +2,7 @@
|
||||
name: writing-skills
|
||||
description: Use ONLY when creating, editing, or evaluating an octopus skill — writing the SKILL.md body, deciding whether a skill needs baseline testing, or running a blind A/B eval of a behavior-shaping technique. Use BEFORE first deployment of any skill that must hold a process gate under pressure.
|
||||
triggers:
|
||||
# High-discrimination phrases only ([org-internal #4525]). We deliberately do NOT use:
|
||||
# High-discrimination phrases only ([TT-4525]). We deliberately do NOT use:
|
||||
# - bare "skill" / 技能 — collides with every skill discussion. Worse: the
|
||||
# hard skill gate folds the previous assistant turn into its match text on
|
||||
# approval turns, so any model reply containing 技能 (e.g. a gate
|
||||
|
||||
Reference in New Issue
Block a user