Browse docs: Commands

Commands

Every command you can give Wizard in a GitHub issue or pull request comment, grouped by what it acts on. Commands start with @holdex.

How commands work

All commands follow the pattern:

@holdex <object> <action> [arguments...]

Arguments can be provided as:

  • Flags: --key=value or --key="value with spaces"
  • Positional arguments: Some commands accept positional arguments (values without flags)

Usage notes

  1. Command Execution Location: Each command has specific location restrictions (see each command below). Commands can be restricted to:

    • Issue comments only: Cannot be executed in pull request comments
    • Goal & draft goal issue comments only: Must be executed in a goal or draft goal issue (not a regular issue or pull request)
    • Bug issue comments only: Must be executed in a bug issue (not a regular issue or pull request)
    • Client card issue comments only: Must be executed on a Client card (issue title starts with Client:)
    • Pull request comments only: Can only be executed in pull request comments
    • Issue and pull request comments: Can be executed in both issue and pull request comments All commands require an organization context (they must be run in a repository that belongs to an organization).
  2. Command Pattern: Commands must follow the exact pattern @holdex <object> <action> [arguments...]. The object and action are case-insensitive and will be normalized to lowercase.

  3. Error Handling: If a command fails, the bot will post a comment with error details, including the specific error message to help with troubleshooting.

  4. Success Indication: Successful commands will add a reaction to your comment:

    • 👀 (eyes) reaction indicates the command was successfully parsed and triggered
    • 🚀 (rocket) reaction indicates the command task completed successfully
  5. Asynchronous Execution: Commands are executed asynchronously. After parsing and validation, the command is triggered and runs in the background. The initial reaction (👀) indicates the command was accepted, while the final reaction (🚀) indicates completion.

  6. Positional Arguments: Some commands support positional arguments as a convenience - they can be used instead of flags for common parameters. Positional arguments are captured for arguments that don't start with --.

  7. Default Values: Some optional parameters have default values. Check each command below for details. If a parameter is not provided and has no default, it will be omitted.

  8. Value Formatting:

    • Use quotes for values with spaces: --key="value with spaces" or --key='value with spaces'
    • Values without spaces don't need quotes: --key=value
    • Single or double quotes are supported
    • Values are parsed exactly as provided (case-sensitive for values)
  9. Code Fences: Commands inside fenced code blocks (```...```) are excluded and will not be executed. This prevents accidental execution when showing command examples in documentation or comments.

Pull requests

Log the time you spent on a pull request. See Submit time on a pull request.

pr submit-time

Submits or updates the total time spent on a pull request. Use this to set your total time, or to correct a previous submission. Accepted while the PR is open. After merge, must be submitted within 24 hours. Rejected if the PR was closed without merging.

Location: Pull request comments only

Command:

@holdex pr submit-time <time> | --time=<time>

Arguments

Arguments:

Property Description Type
time (*) Time spent on the PR in format like 15m, 1h, 2h30m, or 1.5h string (min length: 1)

(*) Required.

Example:

@holdex pr submit-time 2h30m

pr add-time

Adds time on top of any previously submitted time for a pull request. Accepted while the PR is open. After merge, must be submitted within 24 hours. Rejected if the PR was closed without merging.

Location: Pull request comments only

Command:

@holdex pr add-time <time> | --time=<time>

Arguments

Arguments:

Property Description Type
time (*) Time to add on top of any previous submission, e.g. 15m, 1h, 2h30m, or 1.5h string (min length: 1)

(*) Required.

Example:

@holdex pr add-time 1h15m

Bugs

Set the ETA of a Bug issue, and attribute or dispute a bug on a fix: pull request. See Report and dispute bugs.

bug set-eta

Updates the ETA of the current Bug and syncs it to the Oracle Board.

Location: Bug issue comments only

Command:

@holdex bug set-eta <eta> | --eta=<eta>

Arguments

Arguments:

Property Description Type
eta (*) Estimated completion date in DD-MMM-YYYY format (e.g., 01-Jan-2026) or relative days from today: +5d for calendar days, +5wd for working days (Mon to Fri) string (min length: 1)

(*) Required.

Example:

@holdex bug set-eta 01-Jan-2026
@holdex bug set-eta +5d
@holdex bug set-eta +5wd

bug commit

Report the commit and author that introduced a bug. Use this when fixing a bug to attribute it to the original source. Only the topmost bug report comment on the PR is recognized. Before merge, edit or delete that comment to change the report. The commit URL must be a valid GitHub commit link. See Report and dispute bugs for the full workflow.

Command Pattern:

@holdex bug commit <commit-url> && bug author @<username>

Example:

@holdex bug commit https://github.com/holdex/my-repo/commit/1234567890 && bug author @johndoe

bug dispute

Dispute a previous bug report after the PR has been merged. Use this to correct an incorrect bug attribution. After merge, editing or deleting the original report no longer works — use dispute instead. See Report and dispute bugs for the full workflow.

Command Pattern:

@holdex bug dispute <commit-url> && bug author @<username>

Example:

@holdex bug dispute https://github.com/holdex/my-repo/commit/1234567890 && bug author @johndoe

Goals and specs

Set the ETA of a Goal and create its spec file or Google Document. See Write a Goal and Spec files and Google Docs.

goal create-spec

Creates docs/specs/<name>.md on main and links it under Spec. Only when Spec has no URL yet.

The file name is derived from the Goal title (e.g. Goal: Spec workflow → spec-workflow.md); if taken, -2, -3, … are used. The Spec link stays the same if the Goal title changes later.

If main is protected, Wizard retries after granting itself access when it can; for org-level rules, follow the comment on the Goal to add Wizard as a bypass, then run this command again.

See Spec files and Google Docs for full details.

Location: Goal & draft goal issue comments only

Command:

@holdex goal create-spec

Example:

@holdex goal create-spec

goal create-google-doc

Creates a Google Doc under Stakeholders Interview section for current Goal.

Location: Goal & draft goal issue comments only

Command:

@holdex goal create-google-doc

Example:

@holdex goal create-google-doc

goal attach-google-doc

Attaches a Google Doc to current Goal under Stakeholders Interview section.

Location: Goal & draft goal issue comments only

Command:

@holdex goal attach-google-doc <doc> | --doc=<doc>

Arguments

Arguments:

Property Type
doc (*) string (min length: 1)

(*) Required.

Example:

@holdex goal attach-google-doc https://docs.google.com/document/d/1234567890

goal set-eta

Updates the ETA of the current Goal and syncs it to the Oracle Board. Updates the ETA: line in Deadline section.

Location: Goal & draft goal issue comments only

Command:

@holdex goal set-eta <eta> | --eta=<eta>

Arguments

Arguments:

Property Description Type
eta (*) Estimated completion date in DD-MMM-YYYY format (e.g., 01-Jan-2026) or relative days from today: +5d for calendar days, +5wd for working days (Mon to Fri) string (min length: 1)

(*) Required.

Example:

@holdex goal set-eta 01-Jan-2026
@holdex goal set-eta +5d
@holdex goal set-eta +5wd

Calendar

Create booking links and reserve meeting slots from a GitHub comment. See Share a booking link and Reserve slots for an Attio contact.

Creates a team availability booking link, with the commenter as its creator, and replies with the link to share. --with names other Holdex teammates (comma-separated, not the guest) whose calendars are checked and who must already have a connected Google Calendar; the commenter is always included, and naming them in --with has no effect. --optional names a subset of --with to mark optional on the calendar invite once a slot is booked. Each person is checked against their default availability (the form at /calendar/bookings/new can pick another schedule when someone has more than one). --days, --length, --buffer and --notice are optional and default to a 10 business day lookahead, 30 minute slots, no buffer and no minimum notice (--notice is the business days before the first bookable slot).

Location: Issue comments only (not in pull requests)

Command:

@holdex calendar create-link [--with=<with>] [--optional=<optional>] [--name=<name>] [--days=<days>] [--length=<length>] [--buffer=<buffer>] [--notice=<notice>]

Arguments

Arguments:

Property Type
with string
optional string
name string
days number (int, >0)
length number (int, >0)
buffer number (int, ≥0)
notice number (int, ≥0)

All properties are optional.

Example:

@holdex calendar create-link --with=teammate1,teammate2 --optional=teammate2 --name="Intro call"

calendar reserve-slots

Reserves up to 10 candidate meeting slots for an external contact (identified by their Attio People record id) by placing a tentative hold for each on the creator's calendar and any teammates named with --with. Replies with a copy-ready, dual-timezone message and a pick-link the creator shares themselves — Wizard never sends it. --with names must already have connected Google Calendar with write consent. --optional names a subset of --with to mark optional on the calendar invite once a slot is booked.

Location: Issue comments only (not in pull requests)

Command:

@holdex calendar reserve-slots <attioPersonId> | --attioPersonId=<attioPersonId> [--with=<with>] [--optional=<optional>] [--days=<days>] [--per_day=<per_day>] [--extra=<extra>] [--length=<length>] [--order=<order>] [--guest_tz=<guest_tz>] [--buffer=<buffer>]

Arguments

Arguments:

Property Type
attioPersonId (*) string (min length: 1)
with string
optional string
days number (int, >0)
per_day number (int, >0)
extra number (int, ≥0)
length number (int, >0)
order 'spread' | 'earliest' | 'latest'
guest_tz string
buffer number (int, ≥0)

(*) Required.

Example:

@holdex calendar reserve-slots 018f2c3a-... --with=teammate1,teammate2 --optional=teammate2 --days=3 --per_day=3 --length=30 --order=spread --guest_tz=Australia/Sydney --buffer=15

calendar release-slots

Cancels the pending calendar reservation opened by @holdex calendar reserve-slots in this same issue thread — releases every held slot without booking any. Only the reservation's own creator can release it.

Location: Issue comments only (not in pull requests)

Command:

@holdex calendar release-slots

Arguments

Arguments:

Property Type

All properties are optional.

Example:

@holdex calendar release-slots

Guidelines

Flag code that breaks a project guideline.

Guideline violation

Report a guideline violation by referencing its ID (e.g., G123). Use this to flag code that violates project guidelines.

Command Pattern:

@holdex G<number>

Example:

@holdex G123

Member and admin commands

These commands onboard people and clients and change organization and repository settings. Each one lists the access it needs. Permissions are checked based on:

  • Organization role: Requires the user to have a specific role (Administrator or Member) in the organization. The organization used for validation is either the organization explicitly specified in the command (for example, via an org argument) or, if not provided, the organization where the command is executed.
  • Repository permission: Requires the user to have a specific permission level (admin, maintain, write, triage, or read) in the repository. The repository used for validation is the repository provided in the command (for example, via a repository or owner/repo argument).

Permissions are automatically checked by the bot based on the GitHub user's actual role and permissions in the resolved organization or repository.

payroll sync

Reconciles standing Salary issues with the configured payroll Goal. Run only on that Goal, with write access. Pass --reportOnly=true to preview without changing HR issues or opening a roster PR. Quiet successful apply runs post nothing; changes and items needing HR are reported. Every apply run updates the last-sync line in the Goal description. Failure reports published on the Goal mention both payroll teams.

Access: Repository write permission required (also available with: admin, maintain)

Location: Issue comments only (not in pull requests)

Command:

@holdex payroll sync [--reportOnly=<reportOnly>]

Arguments

Arguments:

Property Type Default
reportOnly 'true' | 'false' 'false'

All properties are optional.

Example:

@holdex payroll sync --reportOnly=false
@holdex payroll sync --reportOnly=true

payroll receive

Records the date the billing inbox received a member's valid invoice for a month. Run on the member's Salary issue; only founders-team can run it. The date falls after the month ends and no later than today. When Wizard had billed nothing for the month by the 10th of the next month, add --amount with the USD total of the Contractor's provisional invoice; the date is then from the 10th of the next month. Posting again replaces the date and amount until a pay run approval or payment covers the invoice; after that it is refused. A provisional invoice stays the one to pay even after Wizard bills the month; correct it with --amount. Wizard replies with what it recorded.

Access: Organization member role required (also available to: admin)

Location: Issue comments only (not in pull requests)

Command:

@holdex payroll receive --month=<month> --date=<date> [--amount=<amount>]

Arguments

Arguments:

Property Type
month (*) string
date (*) string
amount string

(*) Required.

Example:

@holdex payroll receive --month=2026-10 --date=2026-11-02

payroll balance

Records the treasury balance in USD before a pay run. Run on the payroll Goal; only founders-team can run it. Wizard replies with what it recorded.

Access: Organization member role required (also available to: admin)

Location: Issue comments only (not in pull requests)

Command:

@holdex payroll balance --amount=<amount>

Arguments

Arguments:

Property Type
amount (*) string

(*) Required.

Example:

@holdex payroll balance --amount=4000.00

payroll approve

Approves a pay run: every invoice with a received date that no earlier approval covered, and every Employee's wages for months before this one. Run on the payroll Goal after payroll balance; only founders-team can run it. Wizard replies with what the approval covers, the total and any shortfall against the balance.

Access: Organization member role required (also available to: admin)

Location: Issue comments only (not in pull requests)

Command:

@holdex payroll approve

Arguments

Arguments:

Property Type

All properties are optional.

Example:

@holdex payroll approve

payroll paid

Confirms a member's month as paid, with the amount, currency, the date the money moved and the payment reference. Run on the member's Salary issue; only founders-team can run it. The currency is the billed one: USD for a Contractor invoice, HKD for Employee wages. A different amount, or a month no pay run approval covered, is recorded and flagged. A month already paid is refused until payroll returned, except an Employee's underpaid wages, which are topped up as a separate payment. Wizard replies with what it recorded.

Access: Organization member role required (also available to: admin)

Location: Issue comments only (not in pull requests)

Command:

@holdex payroll paid --month=<month> --amount=<amount> --currency=<currency> --date=<date> --reference=<reference>

Arguments

Arguments:

Property Type
month (*) string
amount (*) string
currency (*) string
date (*) string
reference (*) string

(*) Required.

Example:

@holdex payroll paid --month=2026-10 --amount=252.68 --currency=USD --date=2026-11-05 --reference=https://etherscan.io/tx/0xabc

payroll returned

Records that a payment came back, so its month is unpaid again. Run on the member's Salary issue with the reference of that payment; only founders-team can run it. Pay again and post payroll paid once the member confirms their payment details. Wizard replies with what it recorded.

Access: Organization member role required (also available to: admin)

Location: Issue comments only (not in pull requests)

Command:

@holdex payroll returned --month=<month> --reference=<reference>

Arguments

Arguments:

Property Type
month (*) string
reference (*) string

(*) Required.

Example:

@holdex payroll returned --month=2026-10 --reference=https://etherscan.io/tx/0xabc

org add-user

Adds a user to a GitHub organization with a specified role.

Access: Organization admin role required

Location: Issue and pull request comments

Command:

@holdex org add-user <username> | --username=<username> --role=<role> [--org=<org>]

Arguments

Arguments:

Property Type
org string
username (*) string (min length: 1)
role (*) 'admin' | 'member'

(*) Required.

Example:

@holdex org add-user johndoe --org=holdex --role=member

repo apply-settings

Applies repository settings including visibility, branch protection, and merge settings, then posts a checklist for turning off issue auto-close.

Access: Repository admin permission required

Location: Issue and pull request comments

Command:

@holdex repo apply-settings <repo> | --repo=<repo> --visibility=<visibility> [--deleteBranchOnMerge=<deleteBranchOnMerge>] [--allowUpdateBranch=<allowUpdateBranch>]

Arguments

Arguments:

Property Type Default
repo (*) string (min length: 1)
visibility (*) 'private' | 'public'
deleteBranchOnMerge string 'true'
allowUpdateBranch string 'true'

(*) Required.

Example:

@holdex repo apply-settings holdex/my-repo --visibility=private --deleteBranchOnMerge=true --allowUpdateBranch=true

repo sync-labels

Synchronizes issue types and labels for a repository according to the ledger configuration.

Access: Repository write permission required (also available with: admin, maintain)

Location: Issue and pull request comments

Command:

@holdex repo sync-labels <repo> | --repo=<repo>

Arguments

Arguments:

Property Type
repo (*) string (min length: 1)

(*) Required.

Example:

@holdex repo sync-labels holdex/my-repo

issue request-kyc

Creates a Didit identity verification (KYC) session and posts the verification link as a GitHub issue comment.

Access: Organization admin role required (validated in organization holdex)

Location: Issue and pull request comments

Command:

@holdex issue request-kyc [<issueUrl> | --issueUrl=<issueUrl>] [--assigneeUsername=<assigneeUsername>]

Arguments

Arguments:

Property Type
issueUrl string
assigneeUsername string

All properties are optional.

Example:

@holdex issue request-kyc https://github.com/holdex/johndoe-hr/issues/1 --assigneeUsername=johndoe

member onboard

Onboards a new contractor to the GitHub HR system. Creates a private HR repository, README, invites the user, syncs labels, assigns the HR team, and creates six sub-issues: HR Card, Identity Verification Problem, Agreement Problem, Social Profile Problem, Salary, and One-on-One. Also opens the Special Terms PR pre-filled with any supplied fields, and opens a PR to team-members.json recording the new member. Posts an onboarding comment with links to all issues. Any <!-- NEW_FIELD --> placeholder from the Special Terms template can be passed as a flag (e.g. --newField=value) without a code change. Pass --isExternal=true for a client-side member with no Holdex agreement and no Holdex pay: this skips identity verification, the agreement issue and Special Terms PR, the social profile issue, the salary issue, and the One-on-One issue, names the repo hr-external-_ instead of hr-member-_, and never adds them to the org or invites them to the repo. Regular members receive read access to their HR repo; hr-team and founders-team receive write access. Required permission failures stop onboarding.

Access: Organization admin role required (validated in organization holdex)

Location: Issue and pull request comments

Command:

@holdex member onboard --firstname=<firstname> --lastname=<lastname> --githubUsername=<githubUsername> [--primaryCapacity=<primaryCapacity>] [--gmailEmail=<gmailEmail>] [--commencementDate=<commencementDate>] [--idNumber=<idNumber>] [--ratePerHour=<ratePerHour>] [--regAddress=<regAddress>] [--phoneNumber=<phoneNumber>] [--dateOfBirth=<dateOfBirth>] [--isExternal=<isExternal>]

Arguments

Arguments:

Property Type Default
firstname (*) string (min length: 1)
lastname (*) string (min length: 1)
githubUsername (*) string (min length: 1)
primaryCapacity string
gmailEmail string
commencementDate string
idNumber string
ratePerHour string
regAddress string
phoneNumber string
dateOfBirth string
isExternal string 'false'

(*) Required.

Example:

@holdex member onboard --firstname=John --lastname=Doe --githubUsername=johndoe --gmailEmail=johndoe@gmail.com --commencementDate=01-Jan-2026 --isExternal=false

member offboard

Prepares a reviewed offboarding roster PR and appends one editable checklist to a private HR issue. Runs only in the private HR repository configured by TEAM_MEMBERS_SOURCE. Requires an HR Manager, --username and --endDate in DD-MMM-YYYY format. Reminder mute and manager-role removal take effect after merge and redeployment, even for future end dates; billing follows the end date. Access revocation and final payment stay manual. Requires MEMBER_OFFBOARD_ENABLED=true; disabled by default.

Access: Holdex manager required (isManager: true in team-members config)

Location: Issue comments only (not in pull requests)

Command:

@holdex member offboard --username=<username> --endDate=<endDate>

Arguments

Arguments:

Property Type
username (*) string (regex: /^[a-z\d](?:[a-z\d-]{0,37}[a-z\d])?$/i)
endDate (*) string

(*) Required.

Example:

@holdex member offboard --username=alice --endDate=16-Oct-2026

member show-worked-hours

Replies with the hours a member worked, as logged per HKT day, against their contracted weekly_hours (profile.yaml) less leave in leave.yaml. Time counts on the day each add-time or submit-time was posted, on any PR, merged or not. These are not the billable hours contractors are paid for: billing still counts merged PRs only. Without a login it reports every member with weekly_hours. The range defaults to last Monday to Sunday; --group sets the table rows (day, week or month) and defaults to day up to 14 days, week beyond.

Access: Any of: Holdex manager required (isManager: true in team-members config); Organization admin role required (validated in organization holdex); Bot github-actions[bot]

Location: Issue comments only (not in pull requests)

Repositories: holdex/hr-internal only

Command:

@holdex member show-worked-hours [<login> | --login=<login>] [--from=<from>] [--to=<to>] [--group=<group>]

Arguments

Arguments:

Property Type
login string (regex: /^@?[A-Za-z0-9-]+$/)
from string (regex: /^\d{4}-\d{2}-\d{2}$/)
to string (regex: /^\d{4}-\d{2}-\d{2}$/)
group 'day' | 'week' | 'month'

All properties are optional.

Example:

@holdex member show-worked-hours octocat --from=2026-09-01 --to=2026-09-30 --group=week

client onboard

Creates a private client-[name] repository from a Client card, seeds agreement and proposal files from the source repo, configures the repo, creates the Agreement Problem (and optional Wizard install Problem), transfers existing sub-issues then the Client card (children first), links those Problems under the card, waits for GitHub to restore hierarchy, and opens a lead deletion PR.

Optional --org records the client GitHub org in config.yaml and the README when Wizard can reach it; otherwise opens a Problem to install Wizard there.

Managers only.

Lead folder limits: each file must be ≤1 MB; total size of docs/leads/[name] must be ≤25 MB.

Fails if another lead file would also become docs/proposals/initial-proposal.md (e.g. an existing proposals/initial-proposal.md while --proposal points elsewhere).

Access: Holdex manager required (isManager: true in team-members config)

Location: Client card issue comments only (title starts with Client:)

Command:

@holdex client onboard <name> | --name=<name> --doc=<doc> --proposal=<proposal> [--org=<org>]

Arguments

Arguments:

Property Type
name (*) string (min length: 1, regex: /^[a-z0-9]+(?:-[a-z0-9]+)*$/)
doc (*) string (min length: 1)
proposal (*) string (min length: 1)
org string (min length: 1)

(*) Required.

Example:

@holdex client onboard amulet --doc=https://docs.google.com/document/d/abc123 --proposal=https://github.com/holdex/partners-pipeline/blob/main/docs/leads/amulet/proposals/amulet-proposal.md --org=amulet