Skip to content

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:

ParamDescription
requesting_user_slack_id
project_nameProject to query
as_ofYYYY-MM-DD — defaults to today. Past dates clip entries; future dates use locked-in entries + deterministic liability accrual.

Returns:

  • revenue_recognised — earned revenue as of as_of per project type (see below)
  • labour_cost — hours × effective cost rate for each logged entry on or before as_of
  • liability_cost — pro-rata vendor fixed payment agreement cost: agreed_amount × elapsed_days / total_days
  • total_costlabour_cost + liability_cost
  • netrevenue_recognised − total_cost
  • breakdown.liability_overrides — per-vendor: agreed_amount, accrued_cost, description
  • breakdown.per_user — per-person labor detail: user_id, total_hours, total_cost, rate_changed, segments[] (one per rate period; each segment has rate, hours, cost, effectiveFrom)
  • breakdown.rate_adjustedtrue if any user's cost rate changed during the period

Revenue rules by project type:

TypeRevenue formula
T&Mhours_logged × billing_rate
Fixed Price(hours_logged / hours_budget) × contract_value, capped at 100%
Retainer / AgileSum 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_of omitted (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:

ParamDescription
requesting_user_slack_id
monthYYYY-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:

ParamDescription
start_date / end_dateFilter entries inclusively at both ends (YYYY-MM-DD). Available from both Slack and the console.
project_idScope 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:

FieldDescription
entry_idTime entry's own id
dateEntry date (YYYY-MM-DD)
user_idStable 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
personThe person's current name, resolved from user_id; "Unknown" if the user record can't be found
projectProject name, or "Unknown"
taskTask name, or "Unknown"
hoursHours logged
billable"TRUE" / "FALSE", from the task's billable flag
hourly_costThe 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.
costhours × 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_basisHow 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)
notesEntry 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:

TypeSeverityTrigger
burn_ratecritical / warningRetainer pacing over/under budget
stale_itemwarningUnresolved item open > N days
allocation_gapinfoProject with no coverage in upcoming weeks

Interpretation:

  • critical → immediate action required
  • warning → action needed soon
  • info → 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:

ParamDescription
requesting_user_slack_id
status"open" (default), "resolved", "dismissed"

Item types:

  • sick_conflict — user sick while they have active project envelopes
  • leave_conflict — leave logged while they have active project envelopes
  • pto_conflict — PTO approved while they have active project envelopes
  • time_off_request — pending time off request awaiting approval
  • unallocated_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_holidays first.


get_work_week

Return the current work week configuration. Any role.

Returns work_week.days (array of day abbreviations: MonSun) 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: MonSun), 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