On the 1st of each month, a cron job updates your salary issue with the previous month's billing summary and posts comments so you can submit your invoice.
If HR identifies an issue after the invoice is sent, they'll contact you by email to request a corrected invoice.
Your salary issue description always shows the current summary table — this is the source of truth for what was billed and why.
Example — normal month:
| Metric | Value |
|---|---|
| Approved Hours | 16h |
| Paid Leave | 2 days (16h) |
| Bug Hours | 9h (7h current + 2h carry-forward) |
| Dispute Credits | 4h |
| Expenses | $15.00 (2 items) |
| Net Payout | $150.00 |
Example — zero-PR month with bug attributions:
| Metric | Value |
|---|---|
| Approved Hours | 0h |
| Paid Leave | 0h |
| Bug Hours | 5h |
| Carry-forward | 5h (into following month) |
| Net Payout | $0.00 |
If required fields are missing from profile.yaml when you open your
invoice link, the page shows an error instead of a partial invoice, listing
every missing field by name:
Invoice unavailable
Your contractor profile is incomplete. Add the following fields to profile.yaml
in your HR repo and re-open this link:
• first_name
• residential_address
See setup instructions: https://wizard.holdex.io/docs/....
Add the missing fields to profile.yaml in your HR repo and re-open the
invoice link.
Invoice janedoe-2026-05-31 Issue Date: 5 Jun 2026
Due Date: 30 Jun 2026
Period: 1–31 May 2026
From: Jane Doe Bill to: billing@holdex.io
jane@example.com
Address: 123 Main Street, Springfield, IL 62701, US
────────────────────────────────────────────────────────────────────
Description Qty Unit Price Amount
────────────────────────────────────────────────────────────────────
Product development (hours billed) 16h $5.00 $80.00
Paid leave (2 days × 8h) 16h $5.00 $80.00
Quality Adjustment (7h + 2h fwd) 9h −$5.00 −$45.00
Dispute Resolution Credit 4h $5.00 $20.00
AWS hosting (10 May) 1 $10.00 $10.00
Domain registration (15 May) 1 $5.00 $5.00
────────────────────────────────────────────────────────────────────
Total due $150.00
Payment Details
───────────────
Bank Account 1
Bank: First National Bank
Account Name: Jane Doe
Account Number: 1234567890
SWIFT/BIC: FNBAUS12XXX
Bank Account 2
Bank: Second National Bank
Account Name: Jane Doe
IBAN: GB29NWBK60161331926819
Crypto Wallet
Network: Ethereum
Token: USDT (ERC-20)
Address: 0x742d35Cc6634C0532925a3b8D4C9b5A93b2c4D1f
Verify: https://wizard.holdex.io/invoices/janedoe-2026-05-31?token=<hmac>
Durations on both pages are rendered humanized — 30m, 1h, 1h30m —
rather than as raw decimal hours.
PR references are clickable links to GitHub.
# Breakdown
Merged PRs
────────────────────────────────────────────────────────────────────────────────
Org Repository PR Hours Amount
────────────────────────────────────────────────────────────────────────────────
holdex wizard #1201 feat(ui): play music 4h $20.00
holdex wizard #1198 fix(api): mute sound 3h $15.00
holdex wizard #1195 docs(sdk): open door 5h $25.00
holdex wizard #1190 feat(db): close window 4h $20.00
────────────────────────────────────────────────────────────────────────────────
Subtotal 16h $80.00
Bug Attributions
────────────────────────────────────────────────────────────────────────────────
Org Repository PR Hours Amount
────────────────────────────────────────────────────────────────────────────────
holdex wizard #1201 feat(ui): play music 4h −$20.00
holdex wizard #1198 fix(api): mute sound 3h −$15.00
Carry-forward from April 2026 2h −$10.00
────────────────────────────────────────────────────────────────────────────────
Quality Adjustment 9h −$45.00
Dispute Resolutions
────────────────────────────────────────────────────────────────────────────────
Org Repository PR Hours Amount
────────────────────────────────────────────────────────────────────────────────
holdex wizard #1201 feat(ui): play music 4h $20.00
────────────────────────────────────────────────────────────────────────────────
Dispute Resolution Credit 4h $20.00
Net (PR work) 11h $55.00
The invoice is rendered on demand from current data — nothing is stored. The same signed link works at any time for any past month.
| Variable | Source |
|---|---|
| Invoice number | {login}-{YYYY}-{MM}-{DD} (last day of billing month) |
| Billing period | First–last day of the billing month |
| Billing month | Month the PR was merged |
| Issue date | Date you generate the PDF |
| Due date | Last day of the month following the billing period |
| Contractor name | profile.yaml → first_name + last_name |
| Contractor email | profile.yaml → email |
| Contractor address | profile.yaml → residential_address |
| Billing manager | team-members.json → billing_manager: true |
| HR team | team-members.json → hr_team |
| Total approved hours | Sum of your submitted hours for PRs merged in the billing month |
| Paid leave hours | 8h per approved paid leave day taken in the month (leave.yaml) |
| Hourly rate (per PR) | profile.yaml rate history (rate effective for the billing month) |
| Bug hours | Hours from PRs attributed to you as bugs, or PRs you approved that were later reported as bugs |
| Carry-forward | Excess bug hours from a prior month where payout hit $0 |
| Dispute Resolution Credit hours | Hours from successfully disputed bug attributions |
| Per-PR org, repo, number, title, hours | Your merged PRs for the month |
| Monthly hours cap | profile.yaml → max_cap |
| Approved expenses | expenses.yaml entries with date in the billing month |
| Profile | profile.yaml |
The Quality Adjustment follows the formula in the Standard Terms:
payout = max(0, (totalHours - bugHours) × hourlyRate)