68 Commits
Author SHA1 Message Date
Mervin PraisonandClaude Opus 5.5 514531e19d fix(ci): stop FINAL reviews deadlocking on outsider-flagged PRs (#6101)
On an outsider-flagged PR Claude answered the FINAL request with a
security-only comment (no Phase 1 table). The gate only counts a reply with
the Phase 1 / 'Final architecture review' heading, and a FINAL requested after
HEAD is not 'stale', so recovery never re-asked: 9 PRs sat on 'FINAL Claude not
complete on HEAD' with green CI.

- merge-gate.js: a FINAL that Claude answered without the review is stale, so
  the hourly recovery re-requests it (max 3 per HEAD).
- claude.yml: the outsider preamble tells Claude to keep the requested FINAL
  format and add security findings as an extra section.

Co-authored-by: Claude Opus 5.5 (1M context) <[email protected]>
2026-10-28 11:50:31 +01:00
Mervin PraisonandClaude Opus 5.5 0be88481af fix(ci): outsider flagging counts only what the run changed; writers can clear a wrong flag (#6007)
* fix(ci): outsider flagging counts only what the run changed; writers can clear a wrong flag

Every automation acts as the App, so 'the App touched it during an outsider run' also caught routine pipeline label syncs on unrelated PRs (e.g. #5901/#5907 flagged by run 39229895860, whose transcript never mentions them), and the sticky rule then cascaded flags through references (#5945/#5947 -> #5949/#5950). touchedByRun now counts only content-changing App events (comments, reviews, pushes, title/body edits, creating the item, adding the claude label) inside the run window; replaying the real run flags only its own PR. A person with write access can clear a wrong flag by removing the label; bots cannot.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>

* fix(ci): count gate-loosening label changes and bound the outsider window by the Claude job's end

Addresses review on #6007: removing no-auto-merge or a manual-only label (or adding an
override) is a touch; the flag step passes claude-response's completed_at as the upper bound.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>

* fix(ci): match reusable-workflow job names in jobCompletedAt

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <[email protected]>
2026-10-26 11:40:43 +01:00
Mervin PraisonandClaude Opus 5.5 5c623203f3 fix(ci): a mentioned number that names nothing here is not outsider influence (#5994)
* fix(ci): a mentioned number that names nothing here is not outsider influence

Docs issues cite upstream PraisonAI PRs as bare #N. Those numbers 404 in the repo being checked, and the fail-closed rule for unavailable issues turned every such run outsider-origin (28 Docs PRs labelled, each paying for an extra security review). Referenced (mentioned) numbers that 404 are now ignored: there is no content to inject. Deleted issues (410) and unavailable SOURCE issues still fail closed.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>

* fix(ci): referenced issues keep the sticky outsider flag

Review finding: referencedIssueReasons dropped the wasLabelled check the PR path used to run, so deleting an outsider comment on a referenced maintainer issue made it look trusted again.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>

* fix(ci): only a missing issue may be ignored, not a later 404

Review finding: missingOk covered the whole lookup, so a 404 from listComments after the issue was found would skip the outsider-comment check (fail open). Now only the issue lookup itself may come back missing.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <[email protected]>
2026-10-26 09:45:08 +01:00
c42eb2cac6 feat(ci): independent security layer for outsider-origin work (#5872)
* feat(ci): independent security layer for outsider-origin work

Claude keeps working on outsiders' issues and reviewing fork PRs, with an
extra layer before anything they influenced can merge:

- outsider-review.js: provenance (fork, non-writer author, source issue or
  comments by non-writers), build/CI/dependency paths held for a maintainer,
  deterministic risk flags.
- Merge gate: an independent read-only Opus security review for
  outsider-origin PRs; its verdict becomes the commit status
  security/outsider-review set with github.token, which no Claude run gets,
  and the merge step requires it on HEAD.
- Local actions, scripts and prompts run only from a copy of main taken
  before any PR checkout; .github/actions|scripts|prompts are sensitive.
- Merge gate verdicts count only from the gate's automation (anyone could
  post an APPROVE that overrode an Opus BLOCK); a comment with both is BLOCK;
  a PR-committed .claude-assess-output.jsonl is deleted before parsing.
- claude.yml: untrusted-input rules for outsider issues and influenced PRs,
  security checklist in fork reviews; fork PRs get the automatic FINAL again.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>

* fix(ci): close the gaps an adversarial review found in the outsider layer

- Trusted copies: git checkout silently replaces ignored files a branch
  tracks, so a PR carrying .trusted* paths could swap them. Refuse such PRs,
  load scripts/prompts from RUNNER_TEMP, and treat .trusted* as sensitive.
- claude.yml: the GH_TOKEN/App steps after Claude now run in a separate job
  on a fresh runner with scripts from main (Claude can run commands).
- Merge decision comes from a same-run artifact written by a deterministic
  step (Opus's own comment on this PR or its final answer; security PASS
  when outsiders were involved), bound to the reviewed HEAD; pulls.merge
  pins sha. PR comments can no longer carry a merge.
- Verdict parsing: only add_issue_comment on this PR, errored calls ignored,
  never text inside tool results; the relay uses the same parser.
- Provenance: every Fixes/Closes reference, PR sources, bot PRs without a
  traceable source, and a sticky origin/outsider label (timeline-based).
- maintainer-security-reviewed counts only when a writer added it after HEAD.
- Exact review-bot logins; rm -rf for a planted output path.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>

* fix(ci): remaining outsider-layer review findings

- Security/merge verdict comments count only after a successful
  add_issue_comment tool_result (a timed-out post is no verdict).
- Verdict is not bound to the saved SHA if HEAD was force-pushed during
  the review (closes A -> B -> A, not just a moved HEAD).
- Renamed files are checked by their previous path too.
- Permission lookups treat only 404 as non-writer; other API errors
  propagate (claude.yml falls back to the stricter outsider prompt).

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(ci): second-round hardening of the outsider layer

- Claude Code loaded a PR checkout's .claude/settings.json (hooks, env,
  apiKeyHelper) and project MCP servers in -p mode (verified locally). The
  action now runs with --setting-sources user --strict-mcp-config and an
  explicit --mcp-config file; PRs that change .claude/, .mcp.json or
  CLAUDE.md are refused for Claude runs and are sensitive paths.
- Merge gate never checks out the PR: assess and the security review read it
  through the GitHub API with GitHub tools only, so no PR code or config runs
  and nothing on the runner is readable.
- claude.yml checks out the default branch explicitly (review events used
  the PR merge ref) and after-claude checks out that exact recorded commit.
- Maintainer override = an APPROVED review by a writer on the HEAD commit
  (labels and commit dates can be set by others).
- Provenance: GitHub closingIssuesReferences plus Fixes:/owner/repo#/URL
  forms; PRs the App opens during an outsider run are flagged; 410 tolerated.
- Exact automation logins in FINAL-reply and pusher checks.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>

* fix(ci): bind the merge verdict to the reviewed HEAD like the security verdict

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>

* fix(ci): third-round hardening of the outsider layer

Flag every issue/PR touched during an outsider run (also when the run fails), sticky flag for issues, issues referenced in the request count, AGENTS.md read from main and sensitive for outsider PRs, more auto-run files sensitive, closing-issue lookup fails closed, assess checkout without persisted credentials.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>

* fix(ci): review findings: unavailable sources fail closed, no sticky flag on lookup failure, merge-only honours maintainer approval

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>

* fix(ci): honour the maintainer override in the assess job too

Without it a security FAIL makes the assess model BLOCK, so the merge-step
override was never reached.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(ci): flag only what the outsider run itself acted on

Flagging every issue/PR updated in the run window also swept up unrelated maintainer and bot work, permanently. touchedByRun now attributes: created by the App, App activity in the timeline, commits pushed, or App edits to the text (GraphQL userContentEdits). Lookup failures still flag (fail closed).

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <[email protected]>
Co-authored-by: MervinPraison <[email protected]>
2026-10-17 09:26:32 +01:00
Mervin PraisonandClaude Opus 5.5 5049ce93f4 fix(ci): never run Claude on fork PR code (#5843)
* fix(ci): never run Claude on fork PR code

Claude Assistant checked out a fork PR's head and then ran the local
claude-code-action from that tree, with the App, OAuth and GH tokens in
reach, and the review chain posted the FINAL @claude on fork PRs
automatically. A fork could therefore swap the action or have its own code
run next to the tokens without any maintainer choosing to.

- claude.yml: fork PRs keep the trusted checkout; Claude reviews the diff
  via gh and comments only. A deleted fork (head.repo null) counts as a fork.
- pr-review-chain.js, ci-failure-claude.js, merge-conflict-claude.yml: no
  automatic @claude on fork PRs; a maintainer can still invoke it by hand.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>

* fix(ci): fork reviews get GitHub tools only

Address review: the comment-only rule for fork PRs is now enforced by disallowed_tools (no shell, file, subagent or web tools, so nothing in the runner is readable), and the fork prompt no longer carries the implement/test/PR steps.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>

* fix(ci): fork reviews cannot edit issues

Address review: deny mcp__github__update_issue for fork PRs, leaving only GitHub read tools and add_issue_comment.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <[email protected]>
2026-10-15 08:57:32 +01:00
082838e465 fix(ci): require write access to invoke @claude; stop App-token CI-fix requests stranding PRs (#5839)
* fix(ci): require write access to invoke @claude; stop App-token CI-fix requests stranding PRs

Security: claude-response accepted @claude from any non-bot GitHub user and
the vendored claude-code-action performs no actor permission check.
- Job if: comment/review triggers require author_association OWNER, MEMBER or
  COLLABORATOR (github-actions[bot] and the triage-bot label path unchanged).
- New first step, before any App/OAuth token is created, re-checks the
  requester's permission via the collaborators API and fails unless write or
  admin.

CI-fix loop: pipeline-status label sync (run by the merge gate under the App
token) posted 'CI failed on HEAD' as praisonai-triage-agent[bot]. claude.yml
ignores that account, so Claude never ran, and the claude-ci-fix-pending label
it added made every later real request skip ('ci fix pending'). 0 of 6 bot
requests since 2026-10-07 ever ran (#5800 stuck since 2026-10-13 21:16).
- Label sync no longer posts CI-fix requests; ci-failure-claude.yml (maintainer
  token) remains the only poster.
- The pending label no longer blocks when the newest request came from an
  account claude.yml ignores, so stranded PRs recover on the next scan.

Selftests: ci-failure-claude 18, pipeline-status 15, merge-gate 124.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>

* fix: only treat CI-fix requests from ignored bots as stranded

Another write-access collaborator's request does reach Claude, so the
pending label must still block it (greptile P2).

Co-Authored-By: Claude Opus 5.5 <[email protected]>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <[email protected]>
Co-authored-by: MervinPraison <[email protected]>
2026-10-15 08:28:20 +01:00
ae338052b9 fix(ci): stop merge-gate starvation — hold out PRs BLOCKed on unchanged HEAD, ask Claude to fix (#5805)
* fix(ci): stop merge-gate starvation — hold out PRs BLOCKed on unchanged HEAD, ask Claude to fix

Candidates are scanned oldest-first and capped at 3. #5766, #5769 and #5774
are BLOCKed for real P1s on HEADs unchanged since 2026-10-11, yet every scan
re-assessed them (170 identical Opus BLOCK verdicts), so newer ready PRs such
as #5803 were never looked at again.

- evaluatePipelineQuiescent: a PR whose newest verdict on HEAD is BLOCK is
  held out (new reason + pipeline/blocked:merge-gate label) until a commit
  lands, a check completes after the verdict, or 24h pass.
- The scan asks Claude, once per HEAD and at most 3 times per PR, to fix the
  BLOCK findings; posted with GH_TOKEN like FINAL triggers so claude.yml
  accepts it, and worded so it is neither a FINAL trigger nor verdict noise.
- Assess prompt: CI was verified from check runs by the scan;
  get_pull_request_status only returns legacy commit statuses, and pending
  smoke / main (3.11) are not blockers once test-core is green. Two verdicts
  had blocked on "no green CI" while every check run had passed.

Replay on open PRs: 5766/5769/5774 held out with a fix request; 5803 (blocked
only because smoke was still running) becomes eligible again.
Selftests: merge-gate 116, pipeline-status 15, pr-review-chain 20, others green.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>

* fix(ci): trust only gate-authored BLOCK/fix-request comments, keep held-out PRs reachable

- latestMergeGateVerdictComment: ignore verdicts not posted by gate automation
  (anyone could forge MERGE_GATE_VERDICT: BLOCK and hold a PR out for 24h).
- blockFixRequestDue: count only maintainer/github-actions comments carrying
  the exact HTML-comment marker, so forged markers cannot burn the cap.
- listPrNumbersForMergeGateScan: also scan pipeline/blocked:merge-gate PRs;
  label sync swaps merge-ready for that label, which hid them from fix requests.
- Targeted dispatch path now carries head_sha/block_fix_due.
- Fix-request step re-evaluates the PR (HEAD unchanged, still blocked) before
  posting and skips with a warning when GH_TOKEN is missing instead of posting
  an inert request that consumes the per-HEAD slot.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(ci): exact gate-author logins, serialize fix requests, keep fallback scan reachable

Addresses review comments posted after e65d1793:
- latestMergeGateVerdictComment trusted any login containing
  'praisonai-triage'; only praisonai-triage-agent[bot] / github-actions[bot]
  may now post a verdict that holds a PR out (CodeRabbit).
- Fix requests are posted only from scheduled scans, which share one
  non-cancelling concurrency group, so parallel runs cannot double-post
  (CodeRabbit).
- listPrNumbersForMergeGateScan returned early when only held-out PRs were
  labelled, hiding unlabelled ready PRs from the oldest-open fallback
  (Greptile).

Selftests: merge-gate 123 ok (look-alike login, both listing cases).

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>

* test(ci): await the async listing selftests before exit

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <[email protected]>
Co-authored-by: MervinPraison <[email protected]>
2026-10-13 15:37:19 +01:00
17c378e5fd fix(ci): unblock auto-merge — recognise the FINAL review reply, expire the recovery debounce (#5794)
* fix(ci): unblock auto-merge — recognise the FINAL review reply, expire the recovery debounce

Nothing has auto-merged since 2026-10-08. Two defects combined into a
permanent deadlock:

1. On 2026-10-09 (0ab9f91f6a) claude.yml moved from
   anthropics/claude-code-action, which posted a "Claude finished" tracking
   comment, to the local composite action, which posts the review itself.
   isClaudeFinalReplyComment only matched "Claude finished", so every FINAL
   since then looked incomplete and every PR "stale FINAL". It now also
   accepts the review reply's mandatory "Phase 1 — AGENTS.md review" table
   and "Final architecture review" title, still only from automation logins.

2. shouldSkipStaleFinalRecovery skipped re-posting the FINAL when the head was
   pushed within 15 min of the FINAL trigger. That relation never changes, so
   the skip was permanent. It now holds only while the push is settling
   (30 min), after which recovery re-posts the FINAL.

The stale/missing-FINAL sweep moves from 4x/day to hourly; at push time the
debounce correctly holds back, and the sweep is what re-posts once the push
has settled. Replaying the fixed logic on the 18 open PRs: FINAL current on
HEAD goes from 2/18 to 13/18, and the 5 genuinely stale ones now get a
re-posted FINAL instead of a permanent skip. merge-gate-selftest: 101 ok.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>

* fix: FINAL trigger is not a completion; stale-FINAL recovery can re-post

- isClaudeFinalReplyComment ignores @claude requests: the FINAL trigger
  embeds the Phase 1 heading and is posted by an automation login, so it
  counted as its own completion (CodeRabbit).
- claudeFinalReady accepts staleRecovery to bypass the already-triggered
  check; both stale-recovery call sites pass it, otherwise recovery never
  posted (Greptile).

Co-Authored-By: Claude Opus 5.5 <[email protected]>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <[email protected]>
Co-authored-by: MervinPraison <[email protected]>
2026-10-12 19:46:35 +01:00
MervinPraisonandCursor e41bb37943 fix(pipeline): surface wrong-repo blocks for core vendor tools
Add pipeline/core-vendor-tool tag and pipeline/blocked:wrong-repo blocker (mirrors external-example pattern) so PRs like #5661 show explicit PraisonAI-Tools routing in the label list.

Co-authored-by: Cursor <[email protected]>
2026-10-08 18:28:02 +01:00
MervinPraisonandCursor 1fda108cd8 fix(ci): block new vendor tools in core and tighten Claude FINAL routing
FINAL/merge-gate prompts and AGENTS.md now treat legacy bundled *_tools.py as non-precedent; gate blocks added praisonaiagents/tools/*_tools.py and stale wrong Approve verdicts (e.g. #5661).

Co-authored-by: Cursor <[email protected]>
2026-10-08 15:59:04 +01:00
praisonai-triage-agent[bot]andMervin Praison b6672c21f6 fix(ci): tighten merge-gate cooldown bypass (SHA + newer @claude)
Address CodeRabbit/Greptile: require exact HEAD-after-finish (no 60s slack)
and keep the 35m @claude cooldown when a newer non-FINAL @claude request was
posted after the completion we rely on, until that request also completes.

Co-authored-by: Mervin Praison <[email protected]>
2026-10-08 11:09:27 +00:00
MervinPraisonandCursor 8c3beda7bd fix(ci): cut merge-gate idle wait after FINAL on HEAD
Skip the 35min @claude cooldown when FINAL completed on current HEAD
(no push after Claude finished). Raise agents-core shard timeout to 45m
to avoid cancel/rerun loops that add ~30m per PR.

Co-authored-by: Cursor <[email protected]>
2026-10-08 12:00:47 +01:00
Mervin Praison 08e1841c91 fix(ci): allow triage bot PRs when author_association is CONTRIBUTOR (#5699)
Check trusted automation authors before association so merge gate does not
mis-label triage PRs as maintainer-only.
2026-10-07 16:52:32 +01:00
Mervin Praison 1b71e29bbf fix(ci): fleet merge gate — core-green pending checks + maintainer-only authors (#5697)
* fix(ci): fleet-wide merge gate — core-green pending + maintainer-only authors

Ignore slow Optimized Suite jobs (smoke, main 3.11) while test-core is green
so the fleet is not stuck on blocked:ci. Restrict auto-merge to triage bot and
maintainer allowlist; external and first-time contributors stay manual-only.

* fix(ci): ignore pending GitGuardian when test-core is green
2026-10-07 16:45:11 +01:00
praisonai-triage-agent[bot]andMervin Praison 25c3bfc8f4 fix: harden merge-gate FINAL completion ordering and oauth tertiary fallback
- finalClaudeCompletedOnSha: require the Claude finished reply to follow BOTH
  the latest FINAL trigger and HEAD. No longer rejects a FINAL solely because
  its trigger predates HEAD (fix-commit sequence), and an older reply can no
  longer satisfy a newer FINAL trigger.
- isStaleFinalAfterPush: apply the same max(FINAL, HEAD) floor so a reply
  predating HEAD cannot suppress stale-FINAL recovery.
- oauth-pick-token.sh: fallback now honors the operator-selected preference
  (primary/secondary/tertiary) before falling back to other configured tokens.
- Add merge-gate self-tests for the fix-commit and old-reply-before-new-FINAL
  sequences.

Co-authored-by: Mervin Praison <[email protected]>
2026-10-07 11:23:47 +00:00
MervinPraisonandCursor 4ff26e62d6 ci: unblock auto-merge pipeline and harden Claude OAuth wiring
Merge gate ignores queued Auto PR Comment checks when test-core is green,
skips scans on low GitHub API quota, and ties FINAL completion to HEAD.
Pipeline sync uses a lower PR cap and the same rate-limit guard.
OAuth pick action adds tertiary token support for merge gate and fleet sync.

Co-authored-by: Cursor <[email protected]>
2026-10-07 12:02:11 +01:00
MervinPraisonandCursor 4b4265b317 Fix pipeline label sync for fork PR heads.
Scheduled Pipeline Status Sync skipped fork PRs entirely, so labels such as pipeline/external-example never applied on cross-repo contributions like #5355.

Co-authored-by: Cursor <[email protected]>
2026-09-29 10:18:19 +01:00
MervinPraisonandCursor 84c322b7c8 Block auto-merge for external-only example PRs.
Label diffs confined to examples/tools/external/, keep them off merge-ready unless maintainers opt in, and teach FINAL review to redirect to PraisonAI-Tools.

Co-authored-by: Cursor <[email protected]>
2026-09-29 09:54:26 +01:00
MervinPraisonandCursor 79343b01c0 feat(ci): dual OAuth pre-flight probe and failover (v1.1.8)
Pick CLAUDE_CODE_OAUTH_TOKEN / _B before Claude runs; honour
CLAUDE_OAUTH_ACTIVE and fail over on 401/429.

Co-authored-by: Cursor <[email protected]>
2026-09-15 07:49:31 +01:00
MervinPraisonandCursor 6a48550618 fix(ci): merge-only waits for Opus verdict on busy PRs
merge-only skipped APPROVE merges when verdict comments sat beyond page 1
of issue comments or landed after the 25-minute lookup window. Paginate
comments explicitly and poll for MERGE_GATE_VERDICT on HEAD before merging.

Co-authored-by: Cursor <[email protected]>
2026-09-11 18:48:40 +01:00
Mervin PraisonandCursor 2e3ec6d516 fix(ci): harden merge gate dispatch and stop false merge-ready labels (#4754)
Stop scan kickoff text from counting as APPROVE, require Claude finished after
FINAL, dedupe scan comments, disable re-dispatch from scan, and skip dispatch
when GitHub core rate limit is low.

Co-authored-by: Cursor <[email protected]>
2026-09-03 09:03:20 +01:00
praisonai-triage-agent[bot]andMervin Praison decded7879 test(ci): cover workflow_run probe exclusion in merge-gate pending count
Extract countSubstantiveMergeGateRuns helper and add direct regression
tests so a reload of workflow_run probes into the pending cap is caught
by the self-test (addresses Greptile coverage gap on PR #4534).

Co-authored-by: Mervin Praison <[email protected]>
2026-08-28 07:23:30 +00:00
MervinPraisonandCursor 5e610d8cf5 fix(ci): exclude workflow_run probes from merge-gate pending count
Auto-dispatch probe runs were counted toward the max-pending cap, blocking
repository_dispatch for merge-ready PRs even when no assess job was queued.

Co-authored-by: Cursor <[email protected]>
2026-08-28 08:19:25 +01:00
MervinPraisonandCursor d8932275b7 fix(ci): require SDK Value table in FINAL reviews and extend TS merge-gate parity
FINAL architecture reviewer prompt now mandates the Phase 1 table with an
explicit SDK value row and TS AGENTS.md routing. Merge-gate helpers treat
src/praisonai-ts/ as SDK scope for test enforcement and CI check patterns.

Co-authored-by: Cursor <[email protected]>
2026-08-28 07:51:38 +01:00
MervinPraisonandCursor da1ec9b9df fix(ci): dedupe merge gate dispatches under CI fan-out
Serialize workflow_run auto-dispatch, skip dispatch when a gate is already active or the queue is saturated, and reuse the guard in pipeline label sync.

Co-authored-by: Cursor <[email protected]>
2026-08-27 14:25:27 +01:00
MervinPraisonandCursor 629e7add5e fix(ci): stop Claude workflow failing on review-chain kick
Use the GitHub App token for post-issue CodeRabbit/Qodo kicks, treat kick failures as non-fatal, and recognise triage-bot kick comments for idempotency.

Co-authored-by: Cursor <[email protected]>
2026-08-27 12:59:28 +01:00
MervinPraisonandCursor 70c8665919 Fix TS routing: implement in monorepo src/praisonai-ts, not praisonai-js.
Remove praisonai-js from merge-gate FINAL prompt, Claude STEP 3-ALT, and
tsMirrorPathReasons block. Hub issues and fixes stay in the same repo.

Co-authored-by: Cursor <[email protected]>
2026-08-26 19:31:35 +01:00
MervinPraisonandCursor 4ab1ed280d Implement Option B hub intake for praisonai-js TypeScript issues.
Accept TS/JS issues on PraisonAI, route fixes to praisonai-js via Claude
STEP 3-ALT, block direct src/praisonai-ts/ PRs unless sync from praisonai-js,
and document routing in CONTRIBUTING, bug template, and SECURITY.

Co-authored-by: Cursor <[email protected]>
2026-08-26 18:41:27 +01:00
MervinPraison 8315e72a0c fix(ci): recognise Claude replies and unblock stale-FINAL after rebase
Align merge-gate stale-FINAL recovery with PraisonAI-Tools: accept MervinPraison
Claude finished comments and bypass the 15-minute debounce when HEAD moves after
a conflict rebase without a fresh FINAL trigger.
2026-08-15 13:33:25 +01:00
MervinPraisonandClaude Fable 5 0ca67c6b47 ci(release): harden the pipeline and add first-class single-package releases
Multi-agent gap review of the release pipeline surfaced 17 findings across
the gate, the workflow, and the bump script. This fixes the confirmed ones.

Gate (release-gate.js + nightly-release-gate.yml):
- A pypi-release run stuck in `waiting` (environment approval) blocked all
  auto-releases with no age limit -- GitHub only auto-fails unapproved
  deployments after 30 days, and exactly this stalled releases for 16h this
  week. Waiting runs older than 6h are now ignored (with a warning linking
  the run); in_progress/queued runs still block unconditionally, and the
  stuck run is never cancelled -- if later approved, the concurrency group
  serializes it and pypi_exists no-ops anything already published.
- PACKAGE_PATHS covered 3 of 9 published packages, so a change landing only
  in e.g. praisonai-bot was never auto-released. Now lists all nine.
- The 3-day dedupe counted any successful run -- including dry_run=true,
  which publishes nothing -- blocking real releases for 3 days after a dry
  run. Dedupe now keys on v* GitHub releases, which only real releases create.
- The nightly path required last-green-Core-Tests SHA == HEAD exactly; a
  docs-only or [skip ci] commit at the tip (the release safety-net commit
  itself!) stalled the cron path indefinitely. A green ancestor with no
  package-path changes since is now accepted.
- Replaced the dead 'Bump praisonai' workflow_run filter (those commits no
  longer exist) with 'chore(release):', and wired the previously never-run
  release-gate selftest into the gate as a step.

Workflow (pypi-release.yml):
- New `only` input: a dedicated single-package release is one dropdown pick
  instead of eight skip flags. A "Resolve effective skips" step is the single
  source of truth; the 19 publish/wait conditions are untouched (they gate
  via the seeded pypi_exists outputs).
- PyPI existence probes now distinguish 404 (publish) from outages (fail the
  run before anything is published) instead of treating any error as "not
  published" and then dying on duplicate upload midway.
- The token-refresh step is continue-on-error and its consumer only swaps
  tokens on success -- a failed re-mint previously overwrote a possibly-valid
  token with an empty string, guaranteeing the safety net could not push.
- The safety net now (a) reverts uncommitted wrapper-side rewrites when the
  wrapper release didn't complete, so a wrapper version that never reached
  PyPI is not committed and then skipped past forever, and (b) retries
  rebase+push 3x preferring the version bumps on conflict -- losing that
  commit deadlocks future auto-releases ("already published" forever).
- "Verify PyPI versions" actually probes PyPI now; it previously echoed
  checkmarks derived from input flags for publishes that may never have run.
- Dedicated releases get per-package tags (praisonai-mcp-v0.0.12) since the
  wrapper's "Release v..." tag doesn't exist on that path; only packages
  confirmed on PyPI are tagged.
- uv publish --check-url makes re-uploads idempotent (partial-upload
  recovery); dry-run summary now includes sandbox/deploy and the effective
  skip plan.

Bump script (bump_and_release.py):
- A conflicted `git pull --rebase` previously printed "trying to continue"
  and proceeded from a mid-rebase detached HEAD -- tagging the wrong commit
  and cascading conflict markers into the safety net. It now aborts, retries
  preferring the release commit, and exits before pushing if that fails.
- Commit failures are no longer swallowed (only "nothing to commit" is
  tolerated), so the tag can't silently point at the previous HEAD.
- `gh release create` is idempotent (view-then-create), unblocking reruns
  after a transient failure between push and wrapper publish.
- Tag push is scoped to the release's own tag; `git push --tags -f` could
  force-move historical tags.

Verified: node selftest (10 checks incl. new stale-waiting/dry-run-dedupe
cases), py_compile, YAML parse, actionlint (same 3 pre-existing SC2129
style warnings as main, nothing new), and the rebase-conflict retry logic
exercised against a scratch remote (bump wins, upstream commit preserved).

Co-Authored-By: Claude Fable 5 (1M context) <[email protected]>
2026-08-05 07:52:22 +01:00
MervinPraison 316893a91e fix(release): 3-day patch cadence and explicit PyPI __token__ auth
Extend release-gate dedupe from daily to every 3 days and configure uv publish with UV_PUBLISH_USERNAME=__token__ per PyPI API token guidance.
2026-07-25 18:24:10 +01:00
praisonai-triage-agent[bot]andMervin Praison f7d1aa027a fix: keep pending check runs in bestRunsByName to prevent premature merge
A completed cancelled run (rank 1) could override an in-progress run
(conclusion=null, rank 0) of the same name, hiding a still-running check
from allChecksGreenOnSha and allowing the merge gate to pass early.
Prioritize any non-completed run so pending checks always block.

Co-authored-by: Mervin Praison <[email protected]>
2026-07-21 12:31:47 +00:00
MervinPraison 15b1ffa777 fix: unblock auto-merge when smoke/windows cancel but core CI passes
Treat cancelled smoke and test-windows as non-blocking when all test-core
shards succeeded on HEAD, dedupe check runs by best conclusion, and raise
smoke (12m) and Windows (10m) job timeouts to reduce timeout cancellations.
2026-07-21 13:26:26 +01:00
MervinPraison 0b78778943 fix(ci): ask FINAL Claude to fix self-identified gaps, not only reviewer findings 2026-07-15 16:46:39 +01:00
praisonai-triage-agent[bot]andMervin Praison 353c0ae7dd fix(ci): auto-skip Copilot on required-reviewer timeout; forward options in FINAL gate
Addresses reviewer feedback on PR #3034:
- Gemini: claudeFinalReady got stuck awaiting Copilot when a required
  reviewer timed out. Now short-circuits Copilot when prior.requiredTimeout.
- Gemini: maybeTriggerClaudeFinal now spreads all options into claudeFinalReady
  so requiredWaitMs/skipCopilot are honored. It already injects prCreatedAt from
  the fetched PR, so the fallback workflow caller activates the 30m timeout
  without passing prCreatedAt (Greptile concern).
- Update self-tests to assert auto-skip without explicit skipCopilot.

Co-authored-by: Mervin Praison <[email protected]>
2026-07-15 03:01:00 +00:00
MervinPraison f976962447 fix(ci): post FINAL @claude after 30m when required reviewers are silent
Unblock bot PRs when CodeRabbit or Greptile never respond, without duplicating an existing FINAL trigger.
2026-07-15 03:57:03 +01:00
MervinPraison 75602ebc3a Fix release gate: max one patch release per UTC day.
Port hasSuccessfulReleaseToday from PraisonAIUI — the monorepo gate was
releasing on every green Core Tests push to main (4 releases today).
Also skip release-gate on Release/Bump bot commits to avoid cascades.
2026-07-08 11:50:47 +01:00
MervinPraison 8146af8c80 docs(ci): add sandbox backend routing to Claude prompts 2026-07-08 11:22:25 +01:00
praisonai-triage-agent[bot]andMervin Praison 391c18e238 fix(ci): renumber FINAL_CLAUDE_REVIEW_BODY phases to avoid duplicate item numbers
Phase 2 restarted at 5 after Phase 1 gained a 6th (repo-routing) item,
colliding with Phase 1 items 5-6. Renumber Phase 2 to 7-9 and Phase 3
to 10-11 so the prompt has a single monotonic list.

Co-authored-by: Mervin Praison <[email protected]>
2026-07-08 10:11:28 +00:00
MervinPraison 40144a415f fix(ci): clarify Tools vs Plugins routing in Claude prompts
Agent-callable integrations belong in PraisonAI-Tools; lifecycle plugins
in PraisonAI-Plugins. Update issue creation, FINAL review, merge gate,
and CI-fix prompts so PRs like Composio (#2771) are caught early.
2026-07-08 11:06:11 +01:00
MervinPraison 0d3b331c59 feat(ci): auto-trigger Claude on CI failures with SDK-safe fix prompt
Post structured @claude comments when internal PRs fail Core Tests, with
extracted pytest failures, critical review verdict requirements, and SDK
guardrails against weakening tests. Hooks into pipeline label sync and
workflow_run for fast response.
2026-07-07 20:05:49 +01:00
praisonai-triage-agent[bot]andMervin Praison 92f23f7872 fix: sync automated-fallback marker and null-safe options in merge-gate
- isAutomatedFallbackVerdict now matches shared 'Automated fallback —' marker
  so new-format BLOCK fallback comments are filtered by excludeAutomatedFallback
- null-safe options destructuring in findMergeGateVerdict
- selftest covers new-format fallback BLOCK and explicit null options

Co-authored-by: Mervin Praison <[email protected]>
2026-07-07 12:59:56 +00:00
MervinPraison f475df5c4c Require Opus verdict before merge gate can approve or merge.
Remove automated fallback APPROVE, fail assess when Opus does not post MERGE_GATE_VERDICT, and ignore fallback comments at merge time.
2026-07-07 12:12:07 +01:00
MervinPraison be440bcfbc Speed up merge gate by using App token and scanning merge-ready PRs first.
Raise MAX_CANDIDATES to 3, route scan/merge/pipeline-sync through the GitHub App token to avoid PAT rate limits, and stop scanning once enough candidates are found.
2026-07-07 11:44:22 +01:00
MervinPraisonandCursor fd1ec99b6f fix(ci): unblock merge gate after rebase and cancelled conflict scans
Treat an existing Claude FINAL reply as sufficient after rebase-only
updates, ignore superseded detect-and-trigger cancellations in CI
green checks, and scope merge-conflict workflow concurrency per PR.

Co-authored-by: Cursor <[email protected]>
2026-07-07 09:04:12 +01:00
MervinPraisonandCursor 0d903ec225 fix(ci): skip Copilot in review chain, post Claude FINAL after prior bots
Copilot is unreliable; proceed to @claude FINAL once CodeRabbit/Greptile
(or optional Qodo/Gemini wait) complete. Set REVIEW_CHAIN_SKIP_COPILOT=1.

Co-authored-by: Cursor <[email protected]>
2026-07-03 12:09:40 +01:00
MervinPraisonandCursor 6b0b15d2d2 fix(ci): unblock review chain when Gemini posts pull reviews only
Detect Gemini in pull request reviews (not just issue comments), re-trigger
Copilot on Gemini review events, and advance the fallback/sweep to post @copilot
before @claude so PRs no longer stall on optional Gemini waits.

Co-authored-by: Cursor <[email protected]>
2026-07-03 11:15:31 +01:00
MervinPraisonandCursor 4e5bd8fcf1 fix: complete C8 TUI hybrid imports and stabilise CI selftests
Add wrapper tui package init to merge app.py with praisonai-code widgets,
use relative timestamps in merge-gate conflict selftests, and skip PraisonAI
PR reviewer when GitHub App secrets are not configured.

Co-authored-by: Cursor <[email protected]>
2026-07-03 07:22:42 +01:00
MervinPraisonandCursor 55d77a23a9 fix(ci): auto-post Claude FINAL on all PRs including fork PRs
Allow Claude after Copilot timeout when prior reviewers finished, use
pull_request_target for fork secret access, and sweep open PRs for missing
FINAL @claude on schedule and workflow_dispatch.

Co-authored-by: Cursor <[email protected]>
2026-07-02 22:40:43 +01:00
MervinPraisonandCursor 4ee3ed9c6d fix(ci): enforce review order CodeRabbit/Greptile → Copilot → Claude
Add pr-review-chain gating so @copilot waits for CodeRabbit and Greptile,
and @claude FINAL only posts after Copilot responds. Remove early Gemini
Claude trigger and cap stale-FINAL recovery via existing merge-gate guards.

Co-authored-by: Cursor <[email protected]>
2026-07-02 15:08:22 +01:00