Repository navigation
fix(release): route Scoop manifest update through a PR instead of a direct push - #226
Conversation
…irect push to master master's enforce_admins is now on, so the admin PAT push (GH006) fails — this job route via branch + PR + auto-merge instead, which works regardless of enforce_admins.
📝 WalkthroughWalkthroughThe release workflow now updates the Scoop manifest by creating and automatically merging a pull request from a versioned branch, with expanded pull request permissions and an early exit when no manifest changes are detected. ChangesScoop manifest update
Estimated code review effort: 2 (Simple) | ~10 minutes Sequence Diagram(s)sequenceDiagram
participant update_scoop as update-scoop job
participant manifest as bucket/agentflare.json
participant github as GitHub repository
update_scoop->>manifest: Check for manifest changes
update_scoop->>github: Push scoop-manifest-${VERSION} branch
update_scoop->>github: Create pull request targeting master
update_scoop->>github: Auto-squash merge and delete branch
Possibly related PRs
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.github/workflows/release.yml:
- Around line 198-200: Update the release workflow permissions block to grant
the token used by CLA_SIGNATURES_TOKEN pull-request write access, while
retaining contents write access. Ensure the relevant pull-request permission is
configured for the fine-grained PAT documented in the CLA workflow.
- Around line 263-266: Update the release workflow around the gh pr create and
gh pr merge commands to make the approval requirement explicit: either provision
a trusted, distinct approver so auto-merge can complete hands-off, or
remove/defer automatic merging and add a manual approval step before merging the
generated Scoop manifest PR.
- Around line 258-266: Update the Scoop release flow around the branch variable
and gh pr create/merge commands to detect an existing open PR for the
scoop-manifest-${VERSION} branch, reuse its PR number or reference, and skip
creation when found. For a new branch PR, retain the current creation behavior;
in both cases, invoke gh pr merge on the existing PR head with the current auto,
squash, and delete-branch options.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: ff7f9da1-8e80-479e-9b88-3e9b1facd2ca
📒 Files selected for processing (1)
.github/workflows/release.yml
| permissions: | ||
| contents: write | ||
| pull-requests: write |
There was a problem hiding this comment.
🩺 Stability & Availability | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/usr/bin/env bash
set -euo pipefail
rg -n -C3 'CLA_SIGNATURES_TOKEN|Contents:' \
.github/workflows/cla.yml .github/workflows/release.ymlRepository: getappz/agentflare
Length of output: 2168
🏁 Script executed:
#!/usr/bin/env bash
set -euo pipefail
sed -n '180,220p' .github/workflows/release.yml
printf '\n----\n'
sed -n '250,275p' .github/workflows/release.yml
printf '\n----\n'
sed -n '30,45p' .github/workflows/cla.ymlRepository: getappz/agentflare
Length of output: 3756
🌐 Web query:
GitHub fine-grained personal access token permissions create pull request pull requests write contents write gh pr create
💡 Result:
To use the GitHub CLI (gh) command gh pr create with a fine-grained personal access token (PAT), you must configure specific repository permissions [1]. For the most basic pull request creation, you require the following minimum permissions: 1. Pull Requests: Read and write [1] 2. Metadata: Read-only (This is automatically added as a mandatory requirement when you select 'Pull Requests: Read and write') [1] While the core functionality for creating a PR is covered by these, users often encounter errors (such as inability to access repository metadata or branch references) if their token lacks broader access [1]. If you encounter errors like "Resource not accessible by personal access token," it is recommended to also include: - Contents: Read-only (or Read and write, depending on your broader workflow needs) [1] Additional notes: - Using 'write' access automatically includes 'read' access for that permission [2]. - If you use features like --project (adding a PR to a project), you will need additional permissions such as Project (read) [3][4]. - The GitHub CLI does not always explicitly inform you which specific fine-grained permission is missing due to API limitations [1]. If a command fails unexpectedly, verify your token's configured permissions in your GitHub settings under Personal Access Tokens [2].
Citations:
- 1: Detect missing fine grain permission scopes, notify user on steps to take to refresh scopes cli/cli#9403
- 2: https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens
- 3: https://cli.github.com/manual/gh%5Fpr%5Fcreate
- 4: Cannot use fine-grained PATs to add labels to pull requests cli/cli#9166
Grant CLA_SIGNATURES_TOKEN pull-request access. gh pr create and gh pr merge use GH_TOKEN, so the job’s permissions block only affects GITHUB_TOKEN. The fine-grained PAT documented in .github/workflows/cla.yml needs Pull Requests: write in addition to Contents: write.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/release.yml around lines 198 - 200, Update the release
workflow permissions block to grant the token used by CLA_SIGNATURES_TOKEN
pull-request write access, while retaining contents write access. Ensure the
relevant pull-request permission is configured for the fine-grained PAT
documented in the CLA workflow.
| BRANCH="scoop-manifest-${VERSION}" | ||
| git checkout -b "$BRANCH" | ||
| git commit -m "scoop manifest: agentflare ${VERSION}" | ||
| git push origin "$BRANCH" | ||
|
|
||
| gh pr create --base master --head "$BRANCH" \ | ||
| --title "scoop manifest: agentflare ${VERSION}" \ | ||
| --body "Automated Scoop manifest update for release ${GITHUB_REF_NAME}." | ||
| gh pr merge "$BRANCH" --auto --squash --delete-branch |
There was a problem hiding this comment.
🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/usr/bin/env bash
set -euo pipefail
VERSION="${1:?usage: $0 <version>}"
BRANCH="scoop-manifest-${VERSION}"
git ls-remote --heads origin "refs/heads/${BRANCH}"
gh pr list --repo getappz/agentflare --base master --head "${BRANCH}" \
--state open --json number,url,headRefOidRepository: getappz/agentflare
Length of output: 195
🏁 Script executed:
#!/usr/bin/env bash
set -euo pipefail
# Locate the workflow and inspect the relevant section with line numbers.
git ls-files '.github/workflows/release.yml'
wc -l .github/workflows/release.yml
sed -n '230,290p' .github/workflows/release.ymlRepository: getappz/agentflare
Length of output: 2372
🏁 Script executed:
#!/usr/bin/env bash
set -euo pipefail
# Inspect the workflow around the manifest publishing steps.
sed -n '1,230p' .github/workflows/release.ymlRepository: getappz/agentflare
Length of output: 8557
🏁 Script executed:
#!/usr/bin/env bash
set -euo pipefail
tmp="$(mktemp -d)"
trap 'rm -rf "$tmp"' EXIT
git init --bare "$tmp/remote.git" >/dev/null
git clone "$tmp/remote.git" "$tmp/a" >/dev/null
cd "$tmp/a"
git config user.name "bot"
git config user.email "bot@example.com"
mkdir -p bucket
echo '{"version":"1.2.3"}' > bucket/agentflare.json
git add bucket/agentflare.json
git commit -m "scoop manifest: agentflare 1.2.3" >/dev/null
git branch -M master
git push origin master:scoop-manifest-1.2.3 >/dev/null
git clone "$tmp/remote.git" "$tmp/b" >/dev/null
cd "$tmp/b"
git config user.name "bot"
git config user.email "bot@example.com"
git checkout -b master origin/master >/dev/null
mkdir -p bucket
echo '{"version":"1.2.3"}' > bucket/agentflare.json
git add bucket/agentflare.json
git commit -m "scoop manifest: agentflare 1.2.3" >/dev/null
set +e
git push origin HEAD:scoop-manifest-1.2.3
code=$?
set -e
echo "exit=$code"Repository: getappz/agentflare
Length of output: 1122
🏁 Script executed:
#!/usr/bin/env bash
set -euo pipefail
tmp="$(mktemp -d)"
trap 'rm -rf "$tmp"' EXIT
git init --bare "$tmp/remote.git" >/dev/null
git clone "$tmp/remote.git" "$tmp/repo" >/dev/null
cd "$tmp/repo"
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]`@users.noreply.github.com`"
# Base branch that mimics the workflow checkout.
echo base > README.md
git add README.md
git commit -m "base" >/dev/null
git branch -M master
git push origin master >/dev/null
make_commit() {
rm -rf bucket
mkdir -p bucket
printf '%s\n' '{"version":"1.2.3","hash":"sha256:abc"}' > bucket/agentflare.json
git add bucket/agentflare.json
git commit -m "scoop manifest: agentflare 1.2.3" >/dev/null
git rev-parse HEAD
}
git checkout -b scoop-manifest-1.2.3 master >/dev/null
sha1="$(make_commit)"
git push origin HEAD:scoop-manifest-1.2.3 >/dev/null
git checkout master >/dev/null
git branch -D scoop-manifest-1.2.3 >/dev/null
git checkout -b scoop-manifest-1.2.3 master >/dev/null
sha2="$(make_commit)"
set +e
git push origin HEAD:scoop-manifest-1.2.3
push_exit=$?
set -e
printf 'sha1=%s\nsha2=%s\npush_exit=%s\n' "$sha1" "$sha2" "$push_exit"Repository: getappz/agentflare
Length of output: 1098
🌐 Web query:
gh pr create existing branch already has a pull request behavior open source documentation
💡 Result:
When using the GitHub CLI (gh), the gh pr create command is designed to prevent the creation of duplicate pull requests [1][2]. If an open pull request already exists for the same head branch and base branch, the command will fail and output an error message containing the URL of the existing pull request [1][3][4]. Because gh pr create does not automatically "upsert" (update) an existing pull request, users seeking to maintain or update an existing PR typically employ one of the following strategies in their scripts: 1. Manual Update: If a PR already exists, the intended changes are usually pushed via git push (or git push --force if necessary), which automatically updates the open pull request associated with that branch [3][5]. 2. Conditional Logic: Scripts often check for an existing PR before running the create command [3][5]. A common pattern is to attempt to list the PR for the current branch first; if one is found, the script can then use gh pr edit to update metadata (such as the title or body) instead of trying to create a new one [3][5]. The command does not currently provide a specific flag to automatically update an existing PR, nor does it return a unique exit code specifically for an "already exists" state, making it necessary to parse the error output or check for the PR existence programmatically if automated handling is required [3][5].
Citations:
- 1: https://github.com/cli/cli/blob/trunk/pkg/cmd/pr/create/create.go
- 2:
pr createshoud fail faster if a PR already exists cli/cli#649 - 3: gh pr create should detect and update already existing pull requests cli/cli#5792
- 4: gh pr create duplicate even if different bases cli/cli#718
- 5: Different exit code for
gh pr createif pull request already exists cli/cli#13571
Reuse the existing Scoop PR on reruns. The branch recreation already lands on the same commit, but gh pr create will fail once an open PR exists for scoop-manifest-${VERSION}. Look up that PR and reuse it, then enable merge on the existing head instead of creating a new one.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/release.yml around lines 258 - 266, Update the Scoop
release flow around the branch variable and gh pr create/merge commands to
detect an existing open PR for the scoop-manifest-${VERSION} branch, reuse its
PR number or reference, and skip creation when found. For a new branch PR,
retain the current creation behavior; in both cases, invoke gh pr merge on the
existing PR head with the current auto, squash, and delete-branch options.
| gh pr create --base master --head "$BRANCH" \ | ||
| --title "scoop manifest: agentflare ${VERSION}" \ | ||
| --body "Automated Scoop manifest update for release ${GITHUB_REF_NAME}." | ||
| gh pr merge "$BRANCH" --auto --squash --delete-branch |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | 🏗️ Heavy lift
🧩 Analysis chain
🏁 Script executed:
#!/usr/bin/env bash
set -euo pipefail
gh api repos/getappz/agentflare/branches/master/protection/required_pull_request_reviews \
--jq '{required_approving_review_count,require_code_owner_reviews,require_last_push_approval}'Repository: getappz/agentflare
Length of output: 390
🏁 Script executed:
#!/usr/bin/env bash
set -euo pipefail
# Show the relevant workflow section with line numbers.
sed -n '190,280p' .github/workflows/release.yml | cat -n
# Look for repository-side branch protection / ruleset config.
git ls-files .github | sed -n '1,200p'
rg -n "required_approving_review_count|require_code_owner_reviews|require_last_push_approval|review|auto-merge|gh pr merge|master" .github -SRepository: getappz/agentflare
Length of output: 5008
🏁 Script executed:
#!/usr/bin/env bash
set -euo pipefail
# Inspect the exact lines around the PR creation/merge logic.
nl -ba .github/workflows/release.yml | sed -n '200,270p'
# Search for any repo-local branch protection/ruleset config.
git ls-files | rg '(^|/)(branch-protection|ruleset|protection|settings)\.|\.github/.+(rules|protection)|CODEOWNERS$'
rg -n "required_approving_review_count|require_code_owner_reviews|require_last_push_approval|auto-merge|gh pr merge|gh pr create|master" -S .github . 2>/dev/nullRepository: getappz/agentflare
Length of output: 196
gh pr merge --auto still depends on a separate approval. .github/workflows/release.yml already notes that master requires an approved PR plus passing checks, so this PR will remain pending until a distinct reviewer approves it. If this is meant to be hands-off, provision a trusted approver; otherwise make manual approval an explicit release step.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/release.yml around lines 263 - 266, Update the release
workflow around the gh pr create and gh pr merge commands to make the approval
requirement explicit: either provision a trusted, distinct approver so
auto-merge can complete hands-off, or remove/defer automatic merging and add a
manual approval step before merging the generated Scoop manifest PR.
…fmt/LOC gate cargo fmt --check was flagging the job-failure message line as over the 100-char width, and work.rs is already pinned at the frozen 2100-line cap, so wrapping it would have failed the LOC gate instead. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Agentflare-Agent: claude-code Agentflare-Branch: task/226-item-claim-doesn-t-check-item-state-a-st Agentflare-Item: 226 Agentflare-Session: 7bda56eb-8cf5-4c3f-ba3e-b060851a47ec
… items (item #226) A job queued (or queued-for-retry) against an item survives daemon restarts on disk in agent_jobs with no state check of its own, and claim() doesn't guard against reopening a cancelled/completed item either (intentionally, since a human re-claiming via redispatch is legitimate). That let a stale automatic retry silently reopen an already-cancelled item and spawn a fresh session. Extend the execution-time re-resolve in fresh_dispatch_pair to also surface the item's current state group, and have WorkItemExecutor refuse to dispatch (fatal, no retry) when that group is cancelled or completed. Test moved to a separate include file to stay under the work.rs LOC gate. Agentflare-Agent: claude-code Agentflare-Branch: task/226-item-claim-doesn-t-check-item-state-a-st Agentflare-Item: 226 Agentflare-Session: 093ada26-9f05-466b-99c3-d1bc149ff840
…fmt/LOC gate cargo fmt --check was flagging the job-failure message line as over the 100-char width, and work.rs is already pinned at the frozen 2100-line cap, so wrapping it would have failed the LOC gate instead. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Agentflare-Agent: claude-code Agentflare-Branch: task/226-item-claim-doesn-t-check-item-state-a-st Agentflare-Item: 226 Agentflare-Session: 7bda56eb-8cf5-4c3f-ba3e-b060851a47ec
…n silently reopen a cancelled item and re-run it (#662) * fix(dispatcher): refuse stale queued jobs against cancelled/completed items (item #226) A job queued (or queued-for-retry) against an item survives daemon restarts on disk in agent_jobs with no state check of its own, and claim() doesn't guard against reopening a cancelled/completed item either (intentionally, since a human re-claiming via redispatch is legitimate). That let a stale automatic retry silently reopen an already-cancelled item and spawn a fresh session. Extend the execution-time re-resolve in fresh_dispatch_pair to also surface the item's current state group, and have WorkItemExecutor refuse to dispatch (fatal, no retry) when that group is cancelled or completed. Test moved to a separate include file to stay under the work.rs LOC gate. Agentflare-Agent: claude-code Agentflare-Branch: task/226-item-claim-doesn-t-check-item-state-a-st Agentflare-Item: 226 Agentflare-Session: 093ada26-9f05-466b-99c3-d1bc149ff840 * fix(dispatcher): shorten item #226 state-gate message to satisfy rustfmt/LOC gate cargo fmt --check was flagging the job-failure message line as over the 100-char width, and work.rs is already pinned at the frozen 2100-line cap, so wrapping it would have failed the LOC gate instead. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Agentflare-Agent: claude-code Agentflare-Branch: task/226-item-claim-doesn-t-check-item-state-a-st Agentflare-Item: 226 Agentflare-Session: 7bda56eb-8cf5-4c3f-ba3e-b060851a47ec --------- Co-authored-by: shiva <shiva@gosysinfo.tech>
…limit cooldown never fires for autonomous dispatch (#664) * Both call sites (the two identified in the bug report as the root cause) are fixed, and there are no other callers of `finish_workflow_failed` left unpatched. Summary of verification: - Both `finish_workflow_failed` call sites in `execute_workflow` now fold the failing step's `last_error` into the error message, exactly as prescribed. - `crates/flare-workflow` full test suite passes (I reran it, including the new `workflow_level_error_preserves_the_failed_steps_real_reason` regression test). - The main `agentflare` binary compiles and its 3 `classify_and_cooldown` tests pass (I ran this myself — the implementer's own session ended without ever confirming this, having only started it as a background task and then stopping without waiting for the result, which is exactly the kind of unverified completion this process asks reviewers to catch). - Fallback behavior (`state_store.load(...).ok()`) is safe if the store read fails — degrades to the generic message rather than panicking. - No other `finish_workflow_failed` call sites were missed. REVIEW_APPROVED Agentflare-Agent: claude-code_2-1-268_agent Agentflare-Branch: task/229-workflow-level-failure-discards-the-real Agentflare-Item: 229-workflow-level-failure-discards-the-real * wip(sdd-loop): task 0 checkpoint (#665) Agentflare-Agent: claude-code_2-1-268_agent Agentflare-Branch: task/219-borrow-notis-handoff-recursion-guard Agentflare-Item: 219-borrow-notis-handoff-recursion-guard Co-authored-by: shiva <shiva@gosysinfo.tech> * fix(auth): detect and surface expired agent auth instead of silent retries (#666) Root-cause of item #164's 15h incident: diagnostic_suffix preferred stdout over stderr, discarding real CLI error text; the only failure classifier was rate-limiting, so an expired-auth failure fell through to cooldown-and-retry against a credential that fails identically every time. - diagnostic_suffix now always includes a non-empty stderr tail alongside stdout instead of only falling back to it when stdout is empty - auth_runner::is_auth_expired + ExitKind::AuthExpired classify expired-auth failures distinctly from rate limits; the interactive retry loop now prompts for re-auth instead of rotating profiles - cli::work::handle_auth_expired (split into work_auth_expiry.rs to stay under work.rs's frozen LOC limit) intercepts before classify_and_cooldown, fails the job immediately (fatal: true, no retry-budget burn), applies an idempotent auth-expired label, logs the alert to both stderr and the job's own log file, and reuses notify_human_gate for immediate alerting - work_item_pipeline's sdd_loop map_err sites short-circuit their own RetryPolicy via StepResult::Failed instead of a generic Err Agentflare-Agent: claude-code Agentflare-Branch: task/173-implement-detect-and-surface-agent-auth Agentflare-Item: 173 Agentflare-Session: d168de95-65a5-4e8c-b013-83e56df9cc97 Co-authored-by: shiva <shiva@gosysinfo.tech> * ## Summary (#667) Implemented identity-scoped hook state for item #220: - Added `optimize::runtime::scoped_session_key(agent, session_id)` → `"{agent}:{session_id}"`. - `hook::pre_tool_use` and `hook::prompt_submit` now key `RuntimeState::sessions` and `staleness_checked_sessions` by this scoped key (using the already-normalized `agent` param each already received) instead of the bare session id. - `hook_completion_gate::post_tool_use` uses the same scoped key for its `sessions` lookups and for `invalidate_verification`/`invalidate_review`. - `hook::post_tool_failure`'s `nudge_pace` key is now `vent-nudge:{agent}:{topic_key}` instead of `vent-nudge:{topic_key}`. - Audited the rest of the hook path: `hook_redirect.rs` has no session-keyed state, and `coaching/store.rs`'s nudge_pace keys are rule-id-based, not session-scoped, so out of scope per the task. Single-agent behavior is unchanged since the scoped key is just `agent:session_id`, and `prune_stale_sessions` naturally prunes stale scoped entries the same way it always did. **Tests:** `cargo test hook` → 117 passed. `cargo test optimize` → 97 passed, 1 pre-existing unrelated failure (`mcp_prompts::tests::optimize_review_returns_full_skill_body`, a skill-body text assertion in `mcp_prompts.rs` unrelated to hook state) — confirmed by stashing my changes and re-running against unmodified HEAD, same failure. Added `scoped_session_key_differs_by_agent_for_same_session_id` regression test. **Concern:** this environment's `cargo` (via the configured `sccache` rustc-wrapper + this worktree's on-disk `target/`) fails all builds with a spurious "Read-only file system" error on writing `.d` dep-info files — unrelated to this change, reproducible on a clean build with no edits. I worked around it by building/testing with `--target-dir /tmp/... --config 'build.rustc-wrapper=""'`. Worth flagging separately since it'll block any `cargo build`/`cargo test` in this worktree until fixed. Agentflare-Agent: claude-code_2-1-268_agent Agentflare-Branch: task/220-borrow-notis-identity-scoped-hook-state Agentflare-Item: 220-borrow-notis-identity-scoped-hook-state Co-authored-by: shiva <shiva@gosysinfo.tech> * wip(sdd-loop): task 0 checkpoint (#668) Agentflare-Agent: claude-code_2-1-268_agent Agentflare-Branch: task/217-borrow-notis-memory-recall-dedup-cache Agentflare-Item: 217-borrow-notis-memory-recall-dedup-cache Co-authored-by: shiva <shiva@gosysinfo.tech> * chore: item::claim() doesn't check item state — a stale queued job can silently reopen a cancelled item and re-run it (#662) * fix(dispatcher): refuse stale queued jobs against cancelled/completed items (item #226) A job queued (or queued-for-retry) against an item survives daemon restarts on disk in agent_jobs with no state check of its own, and claim() doesn't guard against reopening a cancelled/completed item either (intentionally, since a human re-claiming via redispatch is legitimate). That let a stale automatic retry silently reopen an already-cancelled item and spawn a fresh session. Extend the execution-time re-resolve in fresh_dispatch_pair to also surface the item's current state group, and have WorkItemExecutor refuse to dispatch (fatal, no retry) when that group is cancelled or completed. Test moved to a separate include file to stay under the work.rs LOC gate. Agentflare-Agent: claude-code Agentflare-Branch: task/226-item-claim-doesn-t-check-item-state-a-st Agentflare-Item: 226 Agentflare-Session: 093ada26-9f05-466b-99c3-d1bc149ff840 * fix(dispatcher): shorten item #226 state-gate message to satisfy rustfmt/LOC gate cargo fmt --check was flagging the job-failure message line as over the 100-char width, and work.rs is already pinned at the frozen 2100-line cap, so wrapping it would have failed the LOC gate instead. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Agentflare-Agent: claude-code Agentflare-Branch: task/226-item-claim-doesn-t-check-item-state-a-st Agentflare-Item: 226 Agentflare-Session: 7bda56eb-8cf5-4c3f-ba3e-b060851a47ec --------- Co-authored-by: shiva <shiva@gosysinfo.tech> --------- Co-authored-by: shiva <shiva@gosysinfo.tech>
* wip(sdd-loop): task 0 checkpoint Agentflare-Agent: claude-code_2-1-268_agent Agentflare-Branch: task/218-borrow-notis-pre-handoff-secret-scan Agentflare-Item: 218-borrow-notis-pre-handoff-secret-scan * wip(sdd-loop): task 0 checkpoint Agentflare-Agent: claude-code_2-1-268_agent Agentflare-Branch: task/218-borrow-notis-pre-handoff-secret-scan Agentflare-Item: 218-borrow-notis-pre-handoff-secret-scan * chore: item::claim() doesn't check item state — a stale queued job can silently reopen a cancelled item and re-run it (#662) * fix(dispatcher): refuse stale queued jobs against cancelled/completed items (item #226) A job queued (or queued-for-retry) against an item survives daemon restarts on disk in agent_jobs with no state check of its own, and claim() doesn't guard against reopening a cancelled/completed item either (intentionally, since a human re-claiming via redispatch is legitimate). That let a stale automatic retry silently reopen an already-cancelled item and spawn a fresh session. Extend the execution-time re-resolve in fresh_dispatch_pair to also surface the item's current state group, and have WorkItemExecutor refuse to dispatch (fatal, no retry) when that group is cancelled or completed. Test moved to a separate include file to stay under the work.rs LOC gate. Agentflare-Agent: claude-code Agentflare-Branch: task/226-item-claim-doesn-t-check-item-state-a-st Agentflare-Item: 226 Agentflare-Session: 093ada26-9f05-466b-99c3-d1bc149ff840 * fix(dispatcher): shorten item #226 state-gate message to satisfy rustfmt/LOC gate cargo fmt --check was flagging the job-failure message line as over the 100-char width, and work.rs is already pinned at the frozen 2100-line cap, so wrapping it would have failed the LOC gate instead. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Agentflare-Agent: claude-code Agentflare-Branch: task/226-item-claim-doesn-t-check-item-state-a-st Agentflare-Item: 226 Agentflare-Session: 7bda56eb-8cf5-4c3f-ba3e-b060851a47ec --------- Co-authored-by: shiva <shiva@gosysinfo.tech> * ci: Workflow-level failure discards the real per-step error, so rate-limit cooldown never fires for autonomous dispatch (#664) * Both call sites (the two identified in the bug report as the root cause) are fixed, and there are no other callers of `finish_workflow_failed` left unpatched. Summary of verification: - Both `finish_workflow_failed` call sites in `execute_workflow` now fold the failing step's `last_error` into the error message, exactly as prescribed. - `crates/flare-workflow` full test suite passes (I reran it, including the new `workflow_level_error_preserves_the_failed_steps_real_reason` regression test). - The main `agentflare` binary compiles and its 3 `classify_and_cooldown` tests pass (I ran this myself — the implementer's own session ended without ever confirming this, having only started it as a background task and then stopping without waiting for the result, which is exactly the kind of unverified completion this process asks reviewers to catch). - Fallback behavior (`state_store.load(...).ok()`) is safe if the store read fails — degrades to the generic message rather than panicking. - No other `finish_workflow_failed` call sites were missed. REVIEW_APPROVED Agentflare-Agent: claude-code_2-1-268_agent Agentflare-Branch: task/229-workflow-level-failure-discards-the-real Agentflare-Item: 229-workflow-level-failure-discards-the-real * wip(sdd-loop): task 0 checkpoint (#665) Agentflare-Agent: claude-code_2-1-268_agent Agentflare-Branch: task/219-borrow-notis-handoff-recursion-guard Agentflare-Item: 219-borrow-notis-handoff-recursion-guard Co-authored-by: shiva <shiva@gosysinfo.tech> * fix(auth): detect and surface expired agent auth instead of silent retries (#666) Root-cause of item #164's 15h incident: diagnostic_suffix preferred stdout over stderr, discarding real CLI error text; the only failure classifier was rate-limiting, so an expired-auth failure fell through to cooldown-and-retry against a credential that fails identically every time. - diagnostic_suffix now always includes a non-empty stderr tail alongside stdout instead of only falling back to it when stdout is empty - auth_runner::is_auth_expired + ExitKind::AuthExpired classify expired-auth failures distinctly from rate limits; the interactive retry loop now prompts for re-auth instead of rotating profiles - cli::work::handle_auth_expired (split into work_auth_expiry.rs to stay under work.rs's frozen LOC limit) intercepts before classify_and_cooldown, fails the job immediately (fatal: true, no retry-budget burn), applies an idempotent auth-expired label, logs the alert to both stderr and the job's own log file, and reuses notify_human_gate for immediate alerting - work_item_pipeline's sdd_loop map_err sites short-circuit their own RetryPolicy via StepResult::Failed instead of a generic Err Agentflare-Agent: claude-code Agentflare-Branch: task/173-implement-detect-and-surface-agent-auth Agentflare-Item: 173 Agentflare-Session: d168de95-65a5-4e8c-b013-83e56df9cc97 Co-authored-by: shiva <shiva@gosysinfo.tech> * ## Summary (#667) Implemented identity-scoped hook state for item #220: - Added `optimize::runtime::scoped_session_key(agent, session_id)` → `"{agent}:{session_id}"`. - `hook::pre_tool_use` and `hook::prompt_submit` now key `RuntimeState::sessions` and `staleness_checked_sessions` by this scoped key (using the already-normalized `agent` param each already received) instead of the bare session id. - `hook_completion_gate::post_tool_use` uses the same scoped key for its `sessions` lookups and for `invalidate_verification`/`invalidate_review`. - `hook::post_tool_failure`'s `nudge_pace` key is now `vent-nudge:{agent}:{topic_key}` instead of `vent-nudge:{topic_key}`. - Audited the rest of the hook path: `hook_redirect.rs` has no session-keyed state, and `coaching/store.rs`'s nudge_pace keys are rule-id-based, not session-scoped, so out of scope per the task. Single-agent behavior is unchanged since the scoped key is just `agent:session_id`, and `prune_stale_sessions` naturally prunes stale scoped entries the same way it always did. **Tests:** `cargo test hook` → 117 passed. `cargo test optimize` → 97 passed, 1 pre-existing unrelated failure (`mcp_prompts::tests::optimize_review_returns_full_skill_body`, a skill-body text assertion in `mcp_prompts.rs` unrelated to hook state) — confirmed by stashing my changes and re-running against unmodified HEAD, same failure. Added `scoped_session_key_differs_by_agent_for_same_session_id` regression test. **Concern:** this environment's `cargo` (via the configured `sccache` rustc-wrapper + this worktree's on-disk `target/`) fails all builds with a spurious "Read-only file system" error on writing `.d` dep-info files — unrelated to this change, reproducible on a clean build with no edits. I worked around it by building/testing with `--target-dir /tmp/... --config 'build.rustc-wrapper=""'`. Worth flagging separately since it'll block any `cargo build`/`cargo test` in this worktree until fixed. Agentflare-Agent: claude-code_2-1-268_agent Agentflare-Branch: task/220-borrow-notis-identity-scoped-hook-state Agentflare-Item: 220-borrow-notis-identity-scoped-hook-state Co-authored-by: shiva <shiva@gosysinfo.tech> * wip(sdd-loop): task 0 checkpoint (#668) Agentflare-Agent: claude-code_2-1-268_agent Agentflare-Branch: task/217-borrow-notis-memory-recall-dedup-cache Agentflare-Item: 217-borrow-notis-memory-recall-dedup-cache Co-authored-by: shiva <shiva@gosysinfo.tech> * chore: item::claim() doesn't check item state — a stale queued job can silently reopen a cancelled item and re-run it (#662) * fix(dispatcher): refuse stale queued jobs against cancelled/completed items (item #226) A job queued (or queued-for-retry) against an item survives daemon restarts on disk in agent_jobs with no state check of its own, and claim() doesn't guard against reopening a cancelled/completed item either (intentionally, since a human re-claiming via redispatch is legitimate). That let a stale automatic retry silently reopen an already-cancelled item and spawn a fresh session. Extend the execution-time re-resolve in fresh_dispatch_pair to also surface the item's current state group, and have WorkItemExecutor refuse to dispatch (fatal, no retry) when that group is cancelled or completed. Test moved to a separate include file to stay under the work.rs LOC gate. Agentflare-Agent: claude-code Agentflare-Branch: task/226-item-claim-doesn-t-check-item-state-a-st Agentflare-Item: 226 Agentflare-Session: 093ada26-9f05-466b-99c3-d1bc149ff840 * fix(dispatcher): shorten item #226 state-gate message to satisfy rustfmt/LOC gate cargo fmt --check was flagging the job-failure message line as over the 100-char width, and work.rs is already pinned at the frozen 2100-line cap, so wrapping it would have failed the LOC gate instead. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Agentflare-Agent: claude-code Agentflare-Branch: task/226-item-claim-doesn-t-check-item-state-a-st Agentflare-Item: 226 Agentflare-Session: 7bda56eb-8cf5-4c3f-ba3e-b060851a47ec --------- Co-authored-by: shiva <shiva@gosysinfo.tech> --------- Co-authored-by: shiva <shiva@gosysinfo.tech> --------- Co-authored-by: shiva <shiva@gosysinfo.tech>
The `Update Scoop` job in release.yml pushed the manifest straight to `master` using an admin PAT, relying on `enforce_admins` being off. It's now on (`gh api repos/getappz/agentflare/branches/master/protection` confirms it), so both the v1.3.1 and v1.4.0 releases hit `GH006: Protected branch update failed`.
Fix: the job now creates a branch, opens a PR, and auto-merges it (0 required approvals, so it merges as soon as required checks pass) — same end result, but goes through the normal PR flow instead of trying to bypass branch protection. Still uses the owner PAT (`CLA_SIGNATURES_TOKEN`) since `GITHUB_TOKEN`-authored branch pushes don't trigger the required CI checks.
Summary by CodeRabbit