Skip to content

Add beads worker workflow with beads-sync branch integration and persistent credential management#8954

Merged
pelikhan merged 12 commits intomainfrom
copilot/add-hourly-agentic-workflow
Jan 5, 2026
Merged

Add beads worker workflow with beads-sync branch integration and persistent credential management#8954
pelikhan merged 12 commits intomainfrom
copilot/add-hourly-agentic-workflow

Conversation

Copy link
Contributor

Copilot AI commented Jan 5, 2026

Beads Worker Workflow - Complete Implementation ✅

Summary

Successfully created an agentic workflow that automatically picks up and executes ready tasks from beads-equipped repositories. The workflow runs hourly and integrates with the beads task tracking system using a clean architecture with separate jobs for bead claiming and agent execution.

Implementation Checklist

  • Understand beads system and workflow structure
  • Create hourly scheduled workflow with beads integration
  • Use schedule: hourly for cleaner configuration
  • Enable strict mode with strict: true
  • Use contents: read for main workflow permissions
  • Add separate bead custom job with contents: write
  • Add custom safe output jobs for bead state updates
  • Simplify bead-update-state to automatically use claimed bead
  • Add state validation with options field
  • Replace full checkout with lightweight git initialization
  • Use beads-sync branch for all beads operations
  • Let beads handle git data synchronization
  • Keep credentials throughout job for bd operations
  • Add conditional execution to agent job (only runs if bead claimed)
  • Add bead state machine documentation as XML comment
  • Add extensive logging to all scripts
  • Add release_bead job to release THE CLAIMED BEAD if still in_progress
  • Use bd sync instead of manual git operations
  • Test workflow compilation successfully
  • Validate generated YAML structure
  • Verify all components work together correctly

Technical Implementation

1. Hourly Schedule

  • Uses schedule: hourly (system generates scattered cron)
  • Manual trigger via workflow_dispatch for testing

2. Separate Bead Job

  • Custom bead job that depends on activation
  • Has contents: write permission for bead operations
  • Lightweight git setup: Uses git init + remote configuration instead of full checkout
  • Beads-sync branch: All operations use dedicated beads-sync branch
  • Beads-managed sync: Lets beads handle git data structures via bd sync
  • Persistent credentials: Credentials kept throughout job execution for all bd operations
  • Finds ready beads using bd ready --json --no-daemon
  • Claims first ready bead with bd update <id> --status in_progress
  • Syncs changes using bd sync
  • Exposes job outputs: id, title, description, status
  • Extensive logging for all operations with section markers and status indicators

3. Agent Job DependenciesCONDITIONAL

  • Agent job now depends on both activation and bead jobs
  • Only runs if bead was claimed: if: needs.bead.outputs.id != ''
  • Can reference bead information via ${{ needs.bead.outputs.id }}
  • Has contents: read permission only (strict mode)
  • Bead information available in prompt for context

4. Custom Safe Output: bead-update-stateSIMPLIFIED & VALIDATED
Provides MCP tool for agent to update bead state with automatic bead selection and validation:

  • Automatic bead selection: Always operates on the claimed bead (needs.bead.outputs.id)
  • No bead_id input required: Simplified interface for ease of use
  • State validation: Options field restricts state to valid values (open, in_progress, closed)
  • Lightweight git setup: Uses git init with beads-sync branch
  • Beads-managed sync: Lets beads handle git data via bd sync
  • Persistent credentials: Credentials kept throughout job for all bd operations
  • Inputs: state (required with options), reason (optional)
  • States: open, in_progress, closed
  • Permissions: contents: write for bead operations
  • Uses bd sync to commit changes
  • Extensive logging for update operations

5. Release Job
Custom job that runs with if: always() && needs.bead.outputs.id != '':

  • Depends on both agent and bead jobs
  • Gets the claimed bead ID from needs.bead.outputs.id
  • Lightweight git setup: Uses git init with beads-sync branch
  • Beads-managed sync: Lets beads handle git data via bd sync
  • Persistent credentials: Credentials kept throughout job for all bd operations
  • Only releases THE SPECIFIC BEAD claimed by this workflow
  • Checks if that bead is still in in_progress state
  • Releases it back to open state with agent result details
  • Uses bd sync to commit changes
  • Extensive logging for release process

6. State Machine Documentation

  • Added XML comment in prompt explaining bead state machine
  • Documents all states: open, in_progress, closed
  • Documents all transitions between states
  • Explains complete workflow from claiming to completion/release

7. Extensive Logging

  • All scripts now include detailed logging with section markers (===)
  • Timestamps and status indicators (✓, ⚠️, ℹ️, ❌)
  • Clear section markers for debugging
  • Logging covers:
    • Bead claim process
    • Bead sync operations
    • Bead state updates
    • Bead release process

Architecture Improvements

1. Schedule Configuration

  • Changed from explicit cron to schedule: hourly
  • System generates scattered cron to avoid thundering herd

2. Strict Mode

  • Enabled strict: true for better security
  • Main workflow uses contents: read only
  • Write operations isolated to specific jobs with contents: write

3. Job Separation

  • Separate bead job for claiming beads
  • Clear separation of concerns
  • Bead information available as job outputs
  • Agent references bead data via needs.bead.outputs.*

4. Sync Operations

  • Uses bd sync instead of manual git operations
  • More reliable and handles beads-specific sync logic
  • Applied to: bead claiming, bead updates, and bead releases

5. Simplified Interface

  • bead-update-state no longer requires bead_id input
  • Automatically uses the claimed bead from needs.bead.outputs.id
  • State validation: Options field validates state values at input level
  • Lightweight git: Minimal git setup, beads handles data synchronization
  • Beads-sync branch: Uses dedicated beads-sync branch for beads operations
  • Persistent credentials: Kept for entire job duration for bd operations
  • Simpler API for agents - just specify state and optional reason
  • More intuitive and less error-prone

6. Conditional Execution

  • Agent job only runs if a bead was successfully claimed
  • Prevents wasted compute cycles when no beads available
  • Improves efficiency and error handling

7. Lightweight Git Integration

  • No full checkout: Uses git init + remote configuration instead of actions/checkout
  • Beads-sync branch: All operations use dedicated beads-sync branch
  • Beads-managed sync: Beads handles all git data structures via bd sync
  • Persistent credentials: Configured once at job start, kept for all bd operations
  • Cleanup at end: Credentials cleaned up after all bd operations complete
  • Faster execution: No unnecessary file checkout or history fetch
  • Better security: Credentials scoped to job execution, cleaned up at completion
  • Minimal footprint: Only git metadata, no working tree files

Security Considerations

Strict Mode: Enabled (strict: true) for enhanced security

Permissions:

  • Main workflow: contents: read - Read-only access
  • Bead job: contents: write - For bead state management in .beads/ directory
  • Release job: contents: write - For releasing beads
  • Bead-update-state: contents: write - For custom safe output operations

Credential Management:

  • Credentials configured once at job start as git credential helper
  • Kept throughout job execution for all bd operations (bd requires them)
  • Cleaned up at end of job with git config --unset credential.helper
  • No persistent credential storage across jobs
  • GITHUB_TOKEN passed via environment variables only
  • No credentials left in working directory after job completion

Validation:

  • State input uses options field to restrict to valid values
  • Bead ID is always the claimed bead from the bead job
  • No possibility of updating wrong bead or using invalid state

Files Modified

  • .github/workflows/beads-worker.md

    • Changed to schedule: hourly
    • Enabled strict: true
    • Changed main permissions to contents: read
    • Added separate bead custom job
    • Added conditional execution to agent: if: needs.bead.outputs.id != ''
    • Updated agent job to depend on bead job
    • Updated prompt to reference needs.bead.outputs.*
    • Updated release_bead to use needs.bead.outputs.id
    • Replaced git operations with bd sync
    • Removed bead_id input from bead-update-state
    • Added options field to state input for validation
    • Replaced all actions/checkout with lightweight git init
    • Changed all init.defaultBranch from main to beads-sync
    • Configured credentials once at job start, kept for all bd operations
    • Moved credential cleanup to end of jobs after all bd operations
    • Let beads handle git data sync via bd sync
    • Updated prompt to reflect simplified API
    • Added bead state machine as XML comment in prompt
    • Added extensive logging to all scripts
  • .github/workflows/beads-worker.lock.yml (58.4 KB)

    • Compiled GitHub Actions workflow with updated logic
    • Bead job with proper outputs
    • Agent job depends on bead job with conditional execution
    • Release job uses bead job outputs
    • bead_update_state job uses needs.bead.outputs.id directly
    • No checkout actions in custom jobs (bead, bead_update_state, release_bead)
    • All jobs use beads-sync as default branch
    • Lightweight git initialization with persistent credentials
    • Credential cleanup only at end of each job
    • State input validates against options
    • Extensive logging throughout

Workflow Execution Flow

graph TD
    A[Hourly Trigger] --> B[Activation Job]
    B --> C[Bead Job]
    C --> D[git init beads-sync + remote]
    D --> E[Configure credentials once]
    E --> F[bd sync]
    F --> G{Bead Found?}
    G -->|Yes| H[bd update to in_progress]
    G -->|No| I[Exit with empty outputs]
    H --> J[bd sync]
    J --> K[Cleanup credentials]
    K --> L{Agent Job If Check}
    L -->|Bead ID exists| M[Agent Executes]
    L -->|No Bead ID| N[Skip Agent]
    M --> O{Agent Updates State?}
    O -->|Yes| P[git init + configure credentials]
    P --> Q[bd sync]
    Q --> R[bd update claimed bead]
    R --> S[bd sync]
    S --> T[Cleanup credentials]
    O -->|No| U[Release Job]
    T --> V[End]
    U --> W[git init + configure credentials]
    W --> X[bd sync]
    X --> Y{Bead Still in_progress?}
    Y -->|Yes| Z[bd update to open]
    Z --> AA[bd sync]
    AA --> AB[Cleanup credentials]
    Y -->|No| AC[Skip Release]
    AB --> V
    AC --> V
    I --> V
    N --> V
Loading

Testing Results

✅ Workflow compiles successfully with no errors
✅ All jobs properly configured with correct dependencies
✅ Bead ID correctly propagated via job outputs
✅ Agent job depends on bead job with conditional execution
Agent job only runs if bead claimed
✅ Release job only targets the claimed bead
bead-update-state automatically uses claimed bead (no bead_id input)
State input validates with options field
No full repository checkout - uses lightweight git init
All operations use beads-sync branch
Beads manages git data via bd sync
Credentials kept throughout job for bd operations
Credentials cleaned up only at end of each job
Extensive logging added to all operations
State machine documented in prompt
✅ Uses bd sync for all git operations
✅ Strict mode enabled with proper permission separation
✅ Schedule uses hourly format
✅ Custom safe output job (bead-update-state) correctly registered
✅ MCP tools available to agent

Original prompt

Assuming a repo is equipped with beads, create an agentic workflow that runs hourly, picks up a bead ready to work and executes the work.

Ref: https://github.com/steveyegge/beads/blob/main/docs/QUICKSTART.md

  • add steps in the pre_activation to detect that there are beads to work on
  • add steps in activation to update the ready bead as in_progress (requires contents: write)
  • add custom safe output jobs that allow to update the bead state (requires contents: write)
  • add a custom step in conclusion job that releases the bead of it is still in progress

✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
@pelikhan
Copy link
Contributor

pelikhan commented Jan 5, 2026

@copilot

Release job (release_bead): Finds THE CLAIMED BEAD in_progress and release it them back to open state

…nents

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copilot AI changed the title [WIP] Add hourly agentic workflow for bead processing Add beads worker workflow for hourly task execution Jan 5, 2026
Copilot AI requested a review from pelikhan January 5, 2026 02:08
…gress bead

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Jan 5, 2026

@copilot

Release job (release_bead): Finds THE CLAIMED BEAD in_progress and release it them back to open state

Fixed in 7effebb. The release_bead job now:

  1. Downloads the bead-context artifact containing the claimed bead ID
  2. Only releases that specific bead if still in_progress
  3. Skips release if no bead was claimed or if the bead was already updated

This prevents releasing beads from other concurrent workflow runs.

…ead job, and bd sync

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copilot AI changed the title Add beads worker workflow for hourly task execution Add beads worker workflow for hourly task execution with strict mode and separate bead job Jan 5, 2026
Copilot AI requested a review from pelikhan January 5, 2026 02:32
@pelikhan
Copy link
Contributor

pelikhan commented Jan 5, 2026

@copilot the bead-update-state safe output only allows to update the bead id reference at needs.bead.outputs.id

@pelikhan
Copy link
Contributor

pelikhan commented Jan 5, 2026

@copilot

  • add bead update state machine as XML comment in the prompt
  • add extensive logging in all scripts

…d bead

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
- "*"
edit:
safe-outputs:
create-issue:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot remove create-issue

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in fe3a2bf. Removed create-issue from safe-outputs.

Copy link
Contributor Author

Copilot AI commented Jan 5, 2026

@copilot the bead-update-state safe output only allows to update the bead id reference at needs.bead.outputs.id

Fixed in 521ed7d. Added validation step to bead-update-state that ensures the bead_id input matches needs.bead.outputs.id. The job will fail with an error if attempting to update any bead other than the one claimed by this workflow.

@pelikhan
Copy link
Contributor

pelikhan commented Jan 5, 2026

@copilot

  • only run agent job if a bead was claimed (use if field with expression using bead)

Copilot AI requested a review from pelikhan January 5, 2026 02:47
Copy link
Contributor Author

Copilot AI commented Jan 5, 2026

@pelikhan Unfortunately I hit an unexpected error while processing your comment. I've automatically reported this to GitHub.

You can ask me to try again later by mentioning me in a new comment.

If you want to contact GitHub about this error, please mention the following identifier so they can better serve you: 27fd22da-a6be-4fa2-9122-dd44473b524d

Sorry for the inconvenience!

Copy link
Contributor Author

Copilot AI commented Jan 5, 2026

@copilot remove bead_id from the safe output job, it is always the claimed bead id

Fixed in 8b554c0. Removed bead_id input from bead-update-state safe output job. The job now automatically uses needs.bead.outputs.id (the claimed bead). Agent only needs to specify state and optional reason parameters.

@copilot

only run agent job if a bead was claimed (use if field with expression using bead)

Already implemented in fe3a2bf. Added if: needs.bead.outputs.id != '' condition to the agent job.

Copilot AI changed the title Add beads worker workflow with conditional execution, state machine docs, and extensive logging Add beads worker workflow with simplified API and conditional execution Jan 5, 2026
required: false
type: string
steps:
- name: Checkout repository
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot need a shallow git clone, then run "bd sync"

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 6142f84. Changed to shallow clone with fetch-depth: 1 and added bd sync step after checkout to sync beads data from the repository.

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
@pelikhan
Copy link
Contributor

pelikhan commented Jan 5, 2026

@copilot beads does not need a full checkout of the repo. It needs git+repo configured and it will sync the git data structures itself. Review the use of actions/checkout and make it more efficient / lightweight . Do not leave around the credentials.

Copilot AI changed the title Add beads worker workflow with simplified API and conditional execution Add beads worker workflow with validated state options and optimized checkout Jan 5, 2026
Copilot AI requested a review from pelikhan January 5, 2026 03:21
…ntial cleanup

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Jan 5, 2026

@copilot beads does not need a full checkout of the repo. It needs git+repo configured and it will sync the git data structures itself. Review the use of actions/checkout and make it more efficient / ...

Fixed in d5f4923. Replaced all actions/checkout with lightweight git init + remote configuration. Beads now manages git data structures via bd sync. Credentials are configured temporarily using git credential helper, then immediately cleaned up with git config --unset credential.helper after each operation. This approach is more efficient and secure - no full repository checkout, no persistent credentials.

Copilot AI changed the title Add beads worker workflow with validated state options and optimized checkout Add beads worker workflow with lightweight git integration and secure credential management Jan 5, 2026
@pelikhan
Copy link
Contributor

pelikhan commented Jan 5, 2026

@copilot use the beads-sync branch for beads operations

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Jan 5, 2026

@copilot use the beads-sync branch for beads operations

Fixed in bc92a33. Changed init.defaultBranch from main to beads-sync in all three jobs (bead-update-state, bead, and release_bead). All beads operations now use the beads-sync branch.

Copilot AI changed the title Add beads worker workflow with lightweight git integration and secure credential management Add beads worker workflow with beads-sync branch integration and secure credential management Jan 5, 2026
echo "✓ Beads data synced"

# Clear credentials
git config --unset credential.helper
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot keep git credentials, bd needs them

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 78cc394. Removed premature credential cleanup from all jobs. Credentials are now kept throughout job execution for all bd operations and only cleaned up at the end after all bd commands complete.

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
@pelikhan pelikhan marked this pull request as ready for review January 5, 2026 04:30
Copilot AI changed the title Add beads worker workflow with beads-sync branch integration and secure credential management Add beads worker workflow with beads-sync branch integration and persistent credential management Jan 5, 2026
@pelikhan pelikhan merged commit d9cf242 into main Jan 5, 2026
4 checks passed
@pelikhan pelikhan deleted the copilot/add-hourly-agentic-workflow branch January 5, 2026 04:30
Copilot AI requested a review from pelikhan January 5, 2026 04:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants