Skip to content
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ checkpoint, and status-only commits are intentionally omitted.
### Added

- Added conservative, add-only `good first issue` labeling for unlocked, small, current-main reproduced bugs with a high-confidence repair prompt and validation steps and no linked-PR, feature, config, product, security, protected-label, or maintainer-opt-out blocker.
- Added durable maintainer decision packets whose exact question, rationale, options, recommendation, and likely owner come from Codex structured review output while deterministic code only validates and persists the result. Thanks @brokemac79.
- Added close-candidate quality telemetry to apply status while keeping reporting separate from close eligibility and comment-only sync. Thanks @brokemac79.
- Added the PR-only `stalled_unproven_pr` close reason: external D/F-rated pull requests whose requested real-behavior proof stayed missing, mock-only, or insufficient can close after 14 idle days, guarded by live checks that the proof request itself was visible for 14 days plus proof-label, draft, head-commit, and human-engagement gates.
- Added the PR-only `abandoned_pr` close reason: external pull requests idle for 30 days that are still drafts, waiting on their author, or failing checks on the live head can close, while high-quality proven work stays open for repair/adopt paths. See `docs/stalled-pr-close-policies.md`.
Expand Down
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,15 @@ commenting or closing anything. Closed or already-closed reports move to
`records/<repo-slug>/closed/<number>.md`; reopened archived items move back to
`items/` as stale work.

Apply and artifact replay also maintain Codex-authored decision packet JSON at
`records/<repo-slug>/decision-packets/<number>.json` for reports that need a
maintainer ruling. Codex supplies the exact question, rationale, options,
recommendation, and likely owner as structured review output. Deterministic
code validates that intent, persists it, refreshes item state, and removes stale
packets; labels and report prose do not reconstruct the decision. Pass
`--decision-packets-dir` to write those packet files somewhere other than the
profile's default records directory.

Generated state lives on the `state` branch of `openclaw/clawsweeper-state`:
durable `records/`, `jobs/`, `results/`, audit output, workflow status JSON,
repair ledgers, and the rendered dashboard. The state repo `main` branch is the
Expand Down
8 changes: 8 additions & 0 deletions VISION.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,14 @@ Durable records, dashboard output, labels, and comments are operational history.
They should be reproducible, link back to source records, and never expose
secrets, private artifacts, or unredacted security-sensitive details.

### 7. Models propose maintainer decisions; deterministic code enforces them

Models decide whether a maintainer choice exists and produce the question,
rationale, options, recommendation, and likely owner. Deterministic code
validates and persists that structured intent, refreshes live state, and blocks
unsafe or stale mutations. It must fail closed when required intent is missing
or malformed; it must not invent product judgment from hard-coded heuristics.

## Security

ClawSweeper is a maintenance automation tool, not the security response owner.
Expand Down
12 changes: 12 additions & 0 deletions prompts/review-item.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,18 @@ one short sentence for `changeSummary`, `workReason`, `bestSolution`, and
`changeSummary` or `workReason` into an automerge/autofix status update; merge
automation is reported by the command/status comment and hidden markers.

Put maintainer-intent reasoning in `maintainerDecision`; do not expect labels,
report prose, or deterministic code to reconstruct it later. Set `required:
true` only when automation should pause for a real human choice. State the
exact item-specific question, why maintainer intent is required, one to three
concrete options, exactly one recommended option, and the most likely decision
owner. `likelyOwner.person` must exactly match a person in `likelyOwners`.
Choose the recommendation from the evidence even when the final authority stays
human. Use `kind: "none"`, empty question/rationale, `options: []`, and an empty
owner with low confidence when no maintainer decision is required. Do not use a
generic question such as “What should happen next?” and do not create a packet
for routine contributor follow-up that the review already specifies.

For PRs, do not let labels be the only place that merger risk is visible. If a
merge can intentionally make an existing user's setup stop working, fail closed,
lose a fallback path, require a migration, or require operator action, state that
Expand Down
76 changes: 76 additions & 0 deletions schema/clawsweeper-decision.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"likelyOwners",
"risks",
"bestSolution",
"maintainerDecision",
"triagePriority",
"impactLabels",
"mergeRiskLabels",
Expand Down Expand Up @@ -172,6 +173,81 @@
"type": "string",
"description": "The best possible product/code/docs direction for this item, whether the item should close or stay open. Do not repeat the change summary, workReason, or risk list."
},
"maintainerDecision": {
"type": "object",
"additionalProperties": false,
"required": ["required", "kind", "question", "rationale", "options", "likelyOwner"],
"properties": {
"required": {
"type": "boolean",
"description": "True only when automation should pause for a maintainer choice that Codex can state precisely."
},
"kind": {
"type": "string",
"enum": [
"none",
"product_direction",
"security_boundary",
"proof_sufficiency",
"release_inclusion",
"merge_risk",
"manual_review"
],
"description": "The human decision category. Use none when required is false."
},
"question": {
"type": "string",
"description": "The exact item-specific question the maintainer should answer, or an empty string when required is false."
},
"rationale": {
"type": "string",
"description": "Why model judgment cannot safely resolve this choice without maintainer intent, or an empty string when required is false."
},
"options": {
"type": "array",
"maxItems": 3,
"description": "One to three item-specific choices when required is true; [] otherwise. Exactly one choice must be recommended when required is true.",
"items": {
"type": "object",
"additionalProperties": false,
"required": ["title", "body", "recommended"],
"properties": {
"title": {
"type": "string",
"description": "Short decision option title."
},
"body": {
"type": "string",
"description": "One concrete sentence explaining the outcome or tradeoff."
},
"recommended": {
"type": "boolean",
"description": "True for exactly one option when a decision is required."
}
}
}
},
"likelyOwner": {
"type": "object",
"additionalProperties": false,
"required": ["person", "reason", "confidence"],
"properties": {
"person": {
"type": "string",
"description": "The likely decision owner selected from likelyOwners, or an empty string when required is false."
},
"reason": {
"type": "string",
"description": "Why this person is the best available owner for this choice, or an empty string when required is false."
},
"confidence": {
"type": "string",
"enum": ["high", "medium", "low"]
}
}
}
}
},
"triagePriority": {
"type": "string",
"enum": ["P0", "P1", "P2", "P3", "none"],
Expand Down
Loading