Skip to content

Envelope Tools

All envelope tools require Manager or Owner role unless noted. See Envelopes for conceptual background.


allocate_hours

Create a per-person hour envelope on a project.

Writes to: 07. Budgets

Parameters:

ParamRequiredDescription
requesting_user_slack_id
project_name
user_name or user_slack_idPerson receiving the envelope
allocated_hoursHours for this envelope
task_id or task_nameWork-category tag — must be enabled for the project

Task constraint: The task must be enabled for the target project (via Edit tasks / enable_task_for_project). A project with no enabled tasks cannot receive any envelope. A task that is globally active but not enabled for the project is rejected with a 400 error listing which tasks are enabled.

Returns: envelope id (use for updates/cancellations), and overbooked: true if the person is over capacity.

If overbooked: true is returned, always surface the warning: "⚠️ [Name] is overbooked by Xh."

Both word orders accepted: allocate 20h to Apex for Rachel as Design (natural: to <project> for <person>) and allocate 20h to Rachel on Apex for Design (legacy: to <person> on <project>) resolve identically. VERA binds each name to the slot matching what it actually is — no re-asking when all slots are present.


update_allocation

Change the hours or task on an existing envelope.

Updates: 07. Budgets col D (hours), col I (task)

Parameters:

ParamRequiredDescription
requesting_user_slack_id
allocation_idThe envelope's ID
new_allocated_hoursNew hours value
new_task_id or new_task_nameNew task category

To find the envelope ID, call get_allocations or get_person_allocation_summary first.

Restrictions: Cannot target a Retainer or Agile parent project — envelopes must reference the active period or sprint child. The error message names the active period to guide the user.

Audit: The audit message shows exactly what changed (e.g. "40h → 50h" or "task: Design → Development").

Deterministic routing (M-ENV-U): Natural language like "update Sarah's envelope on Acme to 50h" resolves the target envelope directly from the entity pipeline. If the envelope resolves unambiguously and new hours are present, VERA shows a before→after confirm gate ("Change … (40h) to 50h? Reply 1 to confirm.") — no model round-trip. If the user holds two envelopes on the same project (e.g. Design + Development), VERA shows a numbered disambiguation menu; the model never picks the candidate.


cancel_allocation

Mark an envelope as cancelled. The record is kept for audit purposes. Cancellation is terminal — VERA does not track lineage between a cancelled envelope and any replacement.

Updates: 07. Budgets col F (status → "cancelled")

Parameters: requesting_user_slack_id, allocation_id

Deterministic routing (M-ENV-D): Natural language like "cancel Sarah's envelope on Acme" resolves and always shows a terminal confirm gate ("Cancel … ? This is terminal — reply 1 to confirm.") before executing. Ambiguous → disambiguation menu. The model never cancels without explicit user confirmation.


reactivate_allocation

Restore a cancelled envelope to active. Use when an envelope was cancelled by mistake.

Updates: 07. Budgets col F (status → "active")

Parameters: requesting_user_slack_id, allocation_id

No uniqueness check is performed — multiple active envelopes for the same user/project/task are allowed.

Audit: ♻️

Deterministic routing (M-ENV-D undo): Natural language like "reactivate Sarah's envelope on Acme" fires instantly when the cancelled envelope resolves unambiguously — no confirm gate (non-destructive). Ambiguous → disambiguation menu; the digit fires the reactivation directly. No model invocation.


get_allocations

List envelopes with optional filters.

Reads from: 07. Budgets, 03. Users, 02. Projects, 05. Tasks

Parameters:

ParamDescription
requesting_user_slack_id
user_idFilter by person
project_idFilter by project
status"active" (default) or "cancelled"
include_usage"true" to add usage enrichment (see below). Default omits it.

Returns: Each allocation includes user_name, project_name, and task_name (the resolved task label, or null if no task is tagged).

When include_usage=true, envelopes are bucketed by (user_id, project_id, task_id) before enrichment. Multiple envelopes sharing the same triple collapse into one bucket row; allocated_hours is summed and time entries are attributed once — no double-counting. Each bucket row includes:

FieldDescription
allocation_idThe single envelope's id if the bucket has exactly one envelope; null for multi-envelope buckets
envelope_idsArray of all envelope IDs in this bucket
envelopesArray of constituent envelope objects { allocation_id, allocated_hours } — used for per-envelope Edit/Cancel modals
display_project_id / display_project_nameThe parent project for retainer/agile period children, otherwise the project itself
project_deadlineThe period's period_end, or the project's deadline, or the parent's deadline
hours_loggedHours attributed to this bucket (partitioned, not duplicated across buckets)
budget_remainingallocated_hours − hours_logged (not floored — negative values are meaningful)
pct_usedround(hours_logged / allocated_hours × 100), or null if allocated_hours is 0 and hours have been logged
project_statusThe status (active, cancelled, completed, etc.) of the display project (parent for retainer/agile periods, otherwise the project itself)

Used by the web console's top-level Envelopes overview (/console/envelopes).


get_my_allocations

The requesting user's active envelopes.

Parameters: requesting_user_slack_id


get_my_assignments

"What should I work on?" — returns active envelopes for the requesting user with remaining hours.

This is the primary tool for Users to understand their current workload. It shows:

  • Projects they're allocated to
  • Hours allocated vs. hours logged
  • Hours remaining in each envelope

Parameters: requesting_user_slack_id

Any active user. Assignment = having an active envelope. Anyone can log time to any project regardless of assignment — envelopes are a planning tool, not a gate.


get_project_assignments

Who is allocated to a project. Manager/Owner.

Reads from: 07. Budgets, 03. Users

Returns: user_id, user_name, allocated_hours, hours_logged, hours_remaining, task_id (if tagged), status

Permission: Owners see all. Managers see only their assigned projects.


get_person_allocation_summary

All envelopes for one person across all their projects.

Reads from: 07. Budgets, 02. Projects

Parameters: requesting_user_slack_id, user_name

Returns per envelope: project_name, allocated_hours, hours_logged, hours_remaining, status, overdraw flag


get_project_allocation_summary

All envelopes for one project, bucketed by (user_id, project_id, task_id).

Reads from: 07. Budgets, 03. Users, 01. Time Entries, 05. Tasks

Parameters: requesting_user_slack_id, project_name

Multiple envelopes for the same person+task collapse into one row (see bucket model above). hours_logged is attributed once per entry — no double-counting when a person has two envelopes on the same task.


get_team_availability

Remaining hours per person across all active envelopes.

Reads from: 07. Budgets, 01. Time Entries, 03. Users

Returns per person: available_hours, allocated_hours, remaining_hours, overbooked flag

Use this for a quick capacity snapshot before adding new work.


get_estimates_vs_actuals

Compare allocated hours (the plan) against logged hours (the actuals).

Reads from: 07. Budgets, 01. Time Entries

Parameters:

ParamDescription
requesting_user_slack_id
week_start"this week", "last week", or YYYY-MM-DD
user_nameOptional — filter to one person
project_nameOptional — filter to one project

Returns: per person/project: allocated_hours, actual_hours, delta

  • delta > 0 = over plan (more hours worked than allocated)
  • delta < 0 = under plan (fewer hours than allocated)

Surface meaningful divergences (delta ≥ ±20%) as insights. Never show estimates vs actuals for future weeks — redirect to get_allocations instead.


check_capacity

Can the team absorb new work? Takes discipline requirements and a timeline.

Parameters:

ParamDescription
requesting_user_slack_id
discipline_requirementsArray of {discipline, hours_needed}
start_dateYYYY-MM-DD
end_dateYYYY-MM-DD

Returns per discipline:

  • fte_sufficient: FTE has headroom — names and available hours
  • fte_partial: FTE bench partially covers — gap amount
  • contractor_required: No FTE capacity — hours of contractor coverage needed
  • Contractor conflicts flagged if any contractors are double-booked

get_capacity_forecast

N-week rolling capacity outlook.

Parameters:

ParamDescription
requesting_user_slack_id
weeksNumber of weeks to forecast (default 4, max 12)

Returns per week:

  • week_start, utilisation_percent, unallocated_hours
  • uncovered_projects: projects with no one allocated that week
  • overbooked users: name + hours over

Interpretation:

  • < 70% utilisation → plenty of headroom
  • 70–90% → healthy
  • 90% → nearly full, be careful

  • uncovered_projects → flag immediately — no coverage that week