docs: add Work Selection Rule for LLM operating rules (#272) #273
@@ -229,6 +229,34 @@ Legacy environment-only setups keep working unchanged until migrated.
|
|||||||
Each runbook names the **profile role** it runs under, the steps, and a safe
|
Each runbook names the **profile role** it runs under, the steps, and a safe
|
||||||
prompt. Confirm the active profile first (`gitea_get_profile` / `gitea_whoami`).
|
prompt. Confirm the active profile first (`gitea_get_profile` / `gitea_whoami`).
|
||||||
|
|
||||||
|
## Work Selection Rule for LLMs
|
||||||
|
|
||||||
|
Before starting any issue or PR work, acquire or verify a work lease. Do not
|
||||||
|
begin coding, reviewing, fixing, branching, committing, pushing, commenting,
|
||||||
|
or creating a PR until you prove the target is not already being worked.
|
||||||
|
|
||||||
|
Required checks:
|
||||||
|
|
||||||
|
1. List open PRs.
|
||||||
|
2. Search for PRs linked to the target issue.
|
||||||
|
3. Search local and remote branches for the issue number.
|
||||||
|
4. Search registered worktrees for the issue branch.
|
||||||
|
5. Check dirty worktrees.
|
||||||
|
6. Check active leases or recent handoffs.
|
||||||
|
7. Check whether the issue was already completed by a merged PR.
|
||||||
|
|
||||||
|
If another active LLM/session owns the lease, stop. Allowed responses:
|
||||||
|
continue as the lease owner; review the existing PR if reviewer capability
|
||||||
|
allows; produce a handoff; request takeover after lease expiry; stop with
|
||||||
|
"work already claimed."
|
||||||
|
|
||||||
|
Never create a parallel branch or PR for the same issue unless the old branch
|
||||||
|
is proven abandoned and the takeover is recorded.
|
||||||
|
|
||||||
|
Gitea-Tools lease gates: `gitea_lock_issue` (fail-closed before author
|
||||||
|
mutations), `status:in-progress`, and claim comments. Full portable wording:
|
||||||
|
[`skills/llm-project-workflow/SKILL.md`](../skills/llm-project-workflow/SKILL.md).
|
||||||
|
|
||||||
## Branch worktree isolation
|
## Branch worktree isolation
|
||||||
|
|
||||||
All LLM implementation and review work happens in an isolated branch worktree
|
All LLM implementation and review work happens in an isolated branch worktree
|
||||||
|
|||||||
@@ -14,6 +14,9 @@
|
|||||||
|
|
||||||
## Step 2: Implement issues (author profile)
|
## Step 2: Implement issues (author profile)
|
||||||
|
|
||||||
|
0. Work Selection Rule — verify a work lease before any mutations (open PRs,
|
||||||
|
issue-linked PRs, branches, worktrees, dirty worktrees, active leases/
|
||||||
|
handoffs, merged-PR completion). Stop if another session owns the lease.
|
||||||
1. `gitea_resolve_task_capability` for the author task.
|
1. `gitea_resolve_task_capability` for the author task.
|
||||||
2. `gitea_lock_issue` before implementation mutations.
|
2. `gitea_lock_issue` before implementation mutations.
|
||||||
3. Claim with `gitea_mark_issue` / `status:in-progress` label.
|
3. Claim with `gitea_mark_issue` / `status:in-progress` label.
|
||||||
|
|||||||
@@ -3460,11 +3460,27 @@ _GUIDE_RULES = {
|
|||||||
"Conflicting or stale PR state (e.g. prior said merged but live open, or head/updated mismatch) is a hard blocker: report it explicitly and stop until live state is unambiguous.",
|
"Conflicting or stale PR state (e.g. prior said merged but live open, or head/updated mismatch) is a hard blocker: report it explicitly and stop until live state is unambiguous.",
|
||||||
"After merge, re-list PRs and re-view the PR (plus verify master contains the merge) before claiming completion.",
|
"After merge, re-list PRs and re-view the PR (plus verify master contains the merge) before claiming completion.",
|
||||||
],
|
],
|
||||||
|
"work_selection": (
|
||||||
|
"Before any issue or PR work, acquire or verify a work lease. Do not "
|
||||||
|
"code, review, branch, commit, push, comment, or open a PR until you "
|
||||||
|
"prove the target is not already being worked. Required checks: list "
|
||||||
|
"open PRs; search PRs linked to the issue; search local/remote "
|
||||||
|
"branches for the issue number; search worktrees for the issue "
|
||||||
|
"branch; check dirty worktrees; check active leases or recent "
|
||||||
|
"handoffs; check whether a merged PR already completed the issue. If "
|
||||||
|
"another session owns the lease, stop (continue as owner, review the "
|
||||||
|
"existing PR, hand off, request takeover after expiry, or report "
|
||||||
|
"'work already claimed'). Never create a parallel branch/PR unless "
|
||||||
|
"the old branch is proven abandoned and takeover is recorded. "
|
||||||
|
"gitea_lock_issue is the fail-closed author lease gate."),
|
||||||
}
|
}
|
||||||
|
|
||||||
_COMMON_WORKFLOWS = [
|
_COMMON_WORKFLOWS = [
|
||||||
"task routing: resolve task capability via gitea_resolve_task_capability "
|
"task routing: resolve task capability via gitea_resolve_task_capability "
|
||||||
"to check required permission/role kind and identify the safe next action.",
|
"to check required permission/role kind and identify the safe next action.",
|
||||||
|
"work selection: acquire or verify a work lease before any issue/PR work "
|
||||||
|
"(open PRs, linked PRs, branches, worktrees, dirty worktrees, leases, "
|
||||||
|
"merged completion); stop if another session owns the lease.",
|
||||||
"issue authoring: verify identity, create/claim the issue, keep scope "
|
"issue authoring: verify identity, create/claim the issue, keep scope "
|
||||||
"explicit (remote/org/repo).",
|
"explicit (remote/org/repo).",
|
||||||
"implementation: claim issue, branch from fresh master, implement only "
|
"implementation: claim issue, branch from fresh master, implement only "
|
||||||
|
|||||||
@@ -53,6 +53,42 @@ Additional issue-first rules:
|
|||||||
owner decision.** Do not create a new repository or a new tracker unless
|
owner decision.** Do not create a new repository or a new tracker unless
|
||||||
explicitly approved by the owner.
|
explicitly approved by the owner.
|
||||||
|
|
||||||
|
## Work Selection Rule for LLMs
|
||||||
|
|
||||||
|
Before starting any issue or PR work, acquire or verify a work lease.
|
||||||
|
|
||||||
|
Do not begin coding, reviewing, fixing, branching, committing, pushing,
|
||||||
|
commenting, or creating a PR until you prove the target is not already being
|
||||||
|
worked.
|
||||||
|
|
||||||
|
Required checks:
|
||||||
|
|
||||||
|
1. List open PRs.
|
||||||
|
2. Search for PRs linked to the target issue.
|
||||||
|
3. Search local and remote branches for the issue number.
|
||||||
|
4. Search registered worktrees for the issue branch.
|
||||||
|
5. Check dirty worktrees.
|
||||||
|
6. Check active leases or recent handoffs.
|
||||||
|
7. Check whether the issue was already completed by a merged PR.
|
||||||
|
|
||||||
|
If another active LLM/session owns the lease, stop.
|
||||||
|
|
||||||
|
Allowed responses:
|
||||||
|
|
||||||
|
- continue as the lease owner,
|
||||||
|
- review the existing PR if reviewer capability allows,
|
||||||
|
- produce a handoff,
|
||||||
|
- request takeover after lease expiry,
|
||||||
|
- stop with "work already claimed."
|
||||||
|
|
||||||
|
Never create a parallel branch or PR for the same issue unless the old branch
|
||||||
|
is proven abandoned and the takeover is recorded.
|
||||||
|
|
||||||
|
For Gitea-Tools: `gitea_lock_issue` is the fail-closed lease gate before author
|
||||||
|
mutations; `status:in-progress` and claim comments are supporting lease signals.
|
||||||
|
Use `review_proofs.classify_issue_for_selection` when reporting fresh issue
|
||||||
|
selection (#188).
|
||||||
|
|
||||||
## B. Isolated worktree rule
|
## B. Isolated worktree rule
|
||||||
|
|
||||||
**Never implement or review in the main checkout.** The main checkout is for
|
**Never implement or review in the main checkout.** The main checkout is for
|
||||||
@@ -142,6 +178,8 @@ Worktree folder = branch with `/` replaced by `-`
|
|||||||
|
|
||||||
## E. Start-work workflow
|
## E. Start-work workflow
|
||||||
|
|
||||||
|
0. Acquire or verify a work lease (Work Selection Rule) — complete all seven
|
||||||
|
checks before any claim, branch, or PR work.
|
||||||
1. Verify the orchestration checkout (right repo, clean tree).
|
1. Verify the orchestration checkout (right repo, clean tree).
|
||||||
2. Fetch/prune: `git fetch <remote> --prune`.
|
2. Fetch/prune: `git fetch <remote> --prune`.
|
||||||
3. Confirm local `master` equals remote `master` (`git rev-list --left-right --count <remote>/master...master` → `0 0`).
|
3. Confirm local `master` equals remote `master` (`git rev-list --left-right --count <remote>/master...master` → `0 0`).
|
||||||
|
|||||||
@@ -13,6 +13,15 @@ Rules (llm-project-workflow):
|
|||||||
- Do not self-review or self-merge.
|
- Do not self-review or self-merge.
|
||||||
|
|
||||||
Steps:
|
Steps:
|
||||||
|
0. Work Selection Rule — before any claim, branch, or file edits, acquire or
|
||||||
|
verify a work lease. Required checks: list open PRs; search PRs linked to
|
||||||
|
the target issue; search local/remote branches for the issue number; search
|
||||||
|
registered worktrees for the issue branch; check dirty worktrees; check
|
||||||
|
active leases or recent handoffs; check whether a merged PR already
|
||||||
|
completed the issue. If another session owns the lease, stop (continue only
|
||||||
|
as lease owner, review the existing PR, hand off, request takeover after
|
||||||
|
expiry, or report "work already claimed"). Never open a parallel branch/PR
|
||||||
|
unless the old branch is proven abandoned and takeover is recorded.
|
||||||
1. Identity Checklist: Before claiming work, verify and state:
|
1. Identity Checklist: Before claiming work, verify and state:
|
||||||
- Required identity/profile for this task: author (allowed to push branches / create PRs)
|
- Required identity/profile for this task: author (allowed to push branches / create PRs)
|
||||||
- Current authenticated identity (from whoami): <username>
|
- Current authenticated identity (from whoami): <username>
|
||||||
|
|||||||
@@ -132,7 +132,8 @@ class TestControlPlaneGuide(GuideTestBase):
|
|||||||
rules = g["rules"]
|
rules = g["rules"]
|
||||||
for key in ("hard_stops", "fail_closed", "head_sha_pinning",
|
for key in ("hard_stops", "fail_closed", "head_sha_pinning",
|
||||||
"merge_confirmation", "redaction", "separation",
|
"merge_confirmation", "redaction", "separation",
|
||||||
"profile_switching", "identity_verification"):
|
"profile_switching", "identity_verification",
|
||||||
|
"work_selection"):
|
||||||
self.assertIn(key, rules)
|
self.assertIn(key, rules)
|
||||||
self.assertIn("MERGE PR", json.dumps(rules["merge_confirmation"]))
|
self.assertIn("MERGE PR", json.dumps(rules["merge_confirmation"]))
|
||||||
self.assertTrue(rules["hard_stops"])
|
self.assertTrue(rules["hard_stops"])
|
||||||
|
|||||||
@@ -1051,6 +1051,8 @@ class TestControllerHandoff(unittest.TestCase):
|
|||||||
self.assertIn("## Controller Handoff", skill)
|
self.assertIn("## Controller Handoff", skill)
|
||||||
self.assertIn("assess_controller_handoff", skill)
|
self.assertIn("assess_controller_handoff", skill)
|
||||||
self.assertIn("issue #182", skill)
|
self.assertIn("issue #182", skill)
|
||||||
|
self.assertIn("## Work Selection Rule for LLMs", skill)
|
||||||
|
self.assertIn("work already claimed", skill)
|
||||||
|
|
||||||
def test_handoff_rejects_none_workspace_mutations_when_local_edits_exist(self):
|
def test_handoff_rejects_none_workspace_mutations_when_local_edits_exist(self):
|
||||||
# 1. Workspace mutations: none is rejected when local_edits is True
|
# 1. Workspace mutations: none is rejected when local_edits is True
|
||||||
|
|||||||
Reference in New Issue
Block a user