Reports, Alerts & Calendar Tools
get_project_accrual_basis
Revenue recognized, cost accrued, and net for a project as of any date. Manager/Owner.
Use this tool for any question involving:
- "What's the accrual basis for [project]?"
- "What will the P&L be on [date]?"
- "How much revenue have we recognized?"
- "What's the accrued cost so far?"
Reads from: 01. Time Entries, 02. Projects, 03. Users, 13. Rate_History, 14. Liabilities
Parameters:
| Param | Description |
|---|---|
requesting_user_slack_id | |
project_name | Project to query |
as_of | YYYY-MM-DD — defaults to today. Past dates clip entries; future dates use locked-in entries + deterministic liability accrual. |
Returns:
revenue_recognised— earned revenue as ofas_ofper project type (see below)labour_cost— hours × effective cost rate for each logged entry on or beforeas_ofliability_cost— pro-rata vendor fixed payment agreement cost:agreed_amount × elapsed_days / total_daystotal_cost—labour_cost + liability_costnet—revenue_recognised − total_costbreakdown.liability_overrides— per-vendor:agreed_amount,accrued_cost,descriptionbreakdown.per_user— per-person labor detail:user_id,total_hours,total_cost,rate_changed,segments[](one per rate period; each segment hasrate,hours,cost,effectiveFrom)breakdown.rate_adjusted—trueif any user's cost rate changed during the period
Revenue rules by project type:
| Type | Revenue formula |
|---|---|
| T&M | hours_logged × billing_rate |
| Fixed Price | (hours_logged / hours_budget) × contract_value, capped at 100% |
| Retainer / Agile | Sum across active period/sprint children: (child_hours / child_budget) × child_contract_value |
| Pro Bono | $0 |
| Internal | $0 |
Future dates: revenue reflects only entries already in the system — VERA never extrapolates from pace. Liability cost grows deterministically to the project deadline regardless of allocations.
Example queries:
- "What's the accrual basis for the Humbug project?" →
as_ofomitted (defaults to today) - "What will the accrual basis be two weeks from today?" →
as_of = <today + 14 days> - "What was the P&L on March 15th?" →
as_of = 2026-03-15
generate_monthly_report
Portfolio P&L for the current (or specified) month. Owner/Manager — role-filtered results.
Reads from: 01. Time Entries, 02. Projects, 22. Projects Master, 13. Rate_History, 14. Liabilities
Parameters:
| Param | Description |
|---|---|
requesting_user_slack_id | |
month | YYYY-MM — defaults to current month |
Returns:
- Per-project: name, hours_logged, budget_hours, utilization%, burn_rate_status, revenue (Owner), cost (Owner), margin (Owner)
total_revenue_overrun: revenue at risk from over-budget projects (Owner)open_items_total: unresolved items count- Summary: over_budget_count, under_utilized_count
Status emojis: 🚨 critical_overpace | ⚠️ warning_overpace | ✅ on_track | 📉 warning_underpace | 🔴 critical_underpace | ➖ no status
get_export_data
Raw export of time entries in denormalized format, for external analysis or P&L reconciliation. Owner only.
Reads from: time entries, projects, users, tasks, rate history, liabilities
Parameters:
| Param | Description |
|---|---|
start_date / end_date | Filter entries inclusively at both ends (YYYY-MM-DD). Available from both Slack and the console. |
project_id | Scope to a single project — and, for a Retainer or Agile parent, its period/sprint children as well, since entries are always logged against the child. Console-only — not a parameter Claude can set from Slack. Absent or non-numeric → no project filter. |
On the console's /console/reports Export form, the From/To dates and the Project select build these three parameters into the CSV download's query string, so the file can be cut to a single project and date range instead of always being tenant-wide and all-time. The filename reflects the scope, e.g. vera-export-<tenant>-acme-rebrand-2026-01-01-to-2026-06-30.csv.
Returns an entries array; each row has:
| Field | Description |
|---|---|
entry_id | Time entry's own id |
date | Entry date (YYYY-MM-DD) |
user_id | Stable id of the person who logged the entry — added because a person's display name can change (display-name auto-sync), so an external consumer needs a key that never moves |
person | The person's current name, resolved from user_id; "Unknown" if the user record can't be found |
project | Project name, or "Unknown" |
task | Task name, or "Unknown" |
hours | Hours logged |
billable | "TRUE" / "FALSE", from the task's billable flag |
hourly_cost | The cost rate in effect on the entry's own date (the same rule selectCurrentRate uses for the console's headline rate — see docs/reference/schema/index.md for the underlying rule). Empty when cost_basis is vendor_liability or no_rate. |
cost | hours × hourly_cost, rounded to 2dp. Empty under the same conditions as hourly_cost. Never 0 as a stand-in for "unknown" — an empty value means the cost genuinely can't be attributed to this entry, which is different from a $0 cost. |
cost_basis | How to read the two columns above: rate (the normal case), vendor_liability (this entry's user has an active fixed-fee vendor liability on this project — their cost is a project-level, time-based accrual and can't be attributed per entry, so both columns are blank), or no_rate (no cost rate exists on or before the entry's date, so both columns are blank rather than guessed at) |
notes | Entry notes |
Row cap: capped at 500 rows by default (truncated: true, truncated_at: 500, plus a note when the cap is hit). The limit parameter overrides this — limit=0 removes the cap entirely; a positive integer sets a custom cap; anything else falls back to the default 500. limit is console-only — it exists solely for the web console's CSV export (which always asks for limit=0 so a downloaded reconciliation file is never silently incomplete) and is not exposed as a parameter Claude can set from Slack.
This is also triggered automatically when a user asks to "export" or requests a CSV in conversation — that path always uses the default 500-row cap.
get_proactive_alerts
Current alerts across burn rate, stale items, and envelope gaps. Manager/Owner.
No parameters required (beyond requesting_user_slack_id).
Returns grouped by type:
| Type | Severity | Trigger |
|---|---|---|
burn_rate | critical / warning | Retainer pacing over/under budget |
stale_item | warning | Unresolved item open > N days |
allocation_gap | info | Project with no coverage in upcoming weeks |
Interpretation:
critical→ immediate action requiredwarning→ action needed sooninfo→ worth reviewing
Never auto-resolve alerts — always let the Manager decide the action.
get_pace_forecast
One pace signal per active client project the requester is responsible for — how it's tracking against its plan, and which direction it's trending. Manager/Owner.
Console-only — not reachable from Slack; use the web console.
Parameters: requesting_user_slack_id
Returns per project: project_name, client_name, type, period_label (for a retainer period or sprint), budget, total_hours, pct_used, hours_remaining, the last three 7-day windows of hours logged (w0_hours/w1_hours/w2_hours), a trend (accelerating/steady/slowing/stalling/new_activity/no_activity), a projected exhaustion_date, deadline, deviation_pct, direction (over/under), severity (ok/warning/critical), and basis (planned/linear).
A project is measured against its own shaped envelope plan when one exists (basis: "planned"), and against straight-line elapsed-schedule expectation otherwise (basis: "linear"). Severity bands symmetrically on how far off that plan a project is — warning at 10% deviation, critical at 20%, in either direction. Sorted most off-course first. Projects with no way to define a schedule line at all (no start, no end, or an end on or before the start) are excluded rather than shown with a meaningless number.
get_unresolved_items
Open operational issues that need attention. Manager/Owner.
Reads from: 11. Unresolved_Items, 02. Projects, 03. Users
Parameters:
| Param | Description |
|---|---|
requesting_user_slack_id | |
status | "open" (default), "resolved", "dismissed" |
Item types:
sick_conflict— user sick while they have active project envelopesleave_conflict— leave logged while they have active project envelopespto_conflict— PTO approved while they have active project envelopestime_off_request— pending time off request awaiting approvalunallocated_time— time logged where the person holds no active envelope for that project/task (issue #1822 — see Allocations)envelope_overrun— a log that takes an envelope past its allocated hours (issue #1822)
Managers see only items for their assigned projects. Owners see all.
resolve_item
Mark an unresolved item as resolved — use when the Manager has taken action (e.g. reassigned work, updated envelopes). Manager/Owner.
Console-only — not reachable from Slack; use the web console.
Updates: 11. Unresolved_Items cols G:I
Parameters: requesting_user_slack_id, item_id, resolution_summary
dismiss_item
Dismiss an unresolved item without action — use when the Manager acknowledges the issue but decides no action is needed. Manager/Owner.
Console-only — not reachable from Slack; use the web console.
Updates: 11. Unresolved_Items col G (status → "dismissed")
Parameters: requesting_user_slack_id, item_id
get_resolution_options
Ranked list of resolution options for an unresolved item, with consequences. Manager/Owner.
Parameters: requesting_user_slack_id, item_id
Returns: ranked options, each with:
- Action description
- Consequence
- Tools needed to execute
Options are ranked by disruption level (lowest disruption first). Always present consequences to the Manager before asking them to choose. Never auto-execute an option.
For envelope_overrun, the top-ranked option raises the envelope's allocated hours to cover what's already logged (a real update_allocation call) — this is the one item type where an option can actually fix the condition rather than just acknowledge it. For unallocated_time, the top-ranked option is creating a covering envelope (allocate_hours). Both types also offer a dismiss option.
add_company_holiday
Add a holiday or company event to the calendar. Owner only.
Console-only — not reachable from Slack; use the web console.
Writes to: 12. Company_Calendar
Parameters: requesting_user_slack_id, date, name, type ("holiday" or "company_event")
Only "holiday" entries block PTO requests and are excluded from leave date ranges.
list_company_holidays
All calendar entries.
Reads from: 12. Company_Calendar
Parameters: requesting_user_slack_id
remove_company_holiday
Delete a calendar entry by ID. Owner only.
Console-only — not reachable from Slack; use the web console.
Deletes from: 12. Company_Calendar
Parameters: requesting_user_slack_id, holiday_id
To find the holiday ID, call
list_company_holidaysfirst.
get_work_week
Return the current work week configuration. Any role.
Returns work_week.days (array of day abbreviations: Mon–Sun) and work_week.hours_per_day. If the tenant has never called set_work_week, the defaults are returned: Mon–Fri, 8 hours/day.
set_work_week
Configure the tenant's working days. Owner only.
Console-only — not reachable from Slack; use the web console.
Parameters: requesting_user_slack_id, days (array of abbreviations: Mon–Sun), hours_per_day (number)
Default is Monday–Friday, 8 hours/day. Work week settings affect:
- Leave date range calculations (weekends skipped)
- PTO hour defaults
- Capacity forecast calculations