Appearance
Envelopes
Envelopes are how Managers plan and distribute work. They are a planning tool — they do not gate who can log time.
What is an envelope?
An envelope is a per-person hour budget on a specific project — or, for Retainer and Agile projects, on a specific period within that project.
Think of it literally: you have a project with 200 hours in its budget. As a Manager, you put 60 hours in an envelope for Alice, 80 hours for Bob, and 60 hours for Carol. Each person's envelope is their planned share of the work.
- Alice's envelope: 60 hours on Nike Rebrand
- Bob's envelope: 80 hours on Nike Rebrand
- Carol's envelope: 60 hours on Nike Rebrand
The underlying data lives in the 07. Budgets sheet (despite the sheet name, it stores per-person envelopes, not project budgets). Tool names use "allocation" — e.g. allocate_hours, get_allocations — but the concept is always an envelope.
Envelopes vs. budgets
These two words are often confused. In VERA they mean different things:
| Term | What it is | Who sets it | Where it lives |
|---|---|---|---|
| Budget | Total project hours — the whole pie | Owner | 02. Projects.budget_hours |
| Envelope | One person's slice of that pie | Manager or Owner | 07. Budgets |
Owners and Managers can have envelopes too. Any active user — regardless of role — can receive an envelope. An Owner or Manager asking "create an envelope for me on Project X" is a completely valid request. PM assignment and envelopes are separate concerns: being a PM means you manage the project; having an envelope means your hours on that project are tracked against a plan. These are independent.
The sum of all envelopes on a project should not exceed the project's total budget. VERA will warn you if it does, but it won't hard-block the creation.
Envelopes vs. assignments
These terms are also used interchangeably in conversation, but they have a precise meaning in VERA:
- Assignment: the state of having an envelope on a project — i.e. having at least one active envelope row
- Envelope: the specific record (with an hours amount and optional task tag)
When someone asks "who is on this project?", the answer is: everyone with an active envelope.
When someone asks "what should I work on?", the answer is: your active envelopes — the projects you have envelopes on, with hours remaining.
Envelopes do not gate time logging
This is the most important thing to understand about envelopes:
Anyone can log time to any active project, regardless of whether they have an envelope.
Envelopes are a planning and visibility tool. They answer "how was the work supposed to be distributed?" — they are not an access control mechanism.
If a User logs time to a project they don't have an envelope on, VERA records it. If they log more hours than their envelope, VERA records it (and flags the overdraw). The system trusts that Managers are monitoring envelopes and responding to alerts.
Lifetime vs. period-scoped envelopes
For most project types, an envelope is a project-lifetime budget: it covers the entire duration of that project, from start to finish.
For Retainer and Agile projects the model is different — and intentionally so.
Retainer and Agile envelopes are per-period
Retainer and Agile projects run as a series of periods (monthly retainer periods, or sprint periods). Time entries are logged against the active period child, not the parent project directly. Envelopes follow the same pattern.
When you allocate hours to a Retainer or Agile project, VERA automatically routes the envelope to the active period child:
allocate_hours(project="Nike Retainer", user=Alice, hours=60)
↓
VERA finds the active period: "Nike Retainer — April 2026"
↓
Envelope is stored against project_id 47 (the April period), not project_id 12 (the parent)This matters because:
- Utilisation is per-period. A retainer engagement aims for ~100% burn each month. An envelope scoped to the full retainer parent would never be exhaustible in a meaningful way — 60 hours against a two-year retainer means nothing. 60 hours against April means everything.
- Commitment changes between periods. In April a client takes 60 hours; in May they scale up to 80. Each new period can have its own envelope, reflecting the actual contracted commitment.
hours_loggedis calculated correctly. Time entries reference the period child. If the envelope also references the period child, the logged vs. allocated comparison works. If the envelope were on the parent,hours_loggedwould always read as zero.
What happens at period rollover
When you close an April period and open a May period, the April envelopes remain — they're cancelled or archived when the period closes. To assign work in May, create new envelopes against the now-active May period.
If there is no active period, allocate_hours returns an error. Create the next period first (create_retainer_period or create_sprint), then allocate.
Both allocate_hours and update_allocation reject attempts to target a Retainer or Agile parent directly. The error message names the active period to guide the user toward the correct target.
Envelope responses for Retainer/Agile
When an envelope is created on a Retainer or Agile project, the response includes both the parent and period context:
json
{
"project_id": 47,
"project_name": "Nike Retainer",
"parent_project_id": 12,
"period_id": 47,
"period_name": "Nike Retainer — April 2026",
"allocated_hours": 60
}project_name is always the parent (what you asked about). period_name tells you which period the hours are committed to. project_id is the period child (where time entries are written).
What you see when querying your own envelopes
get_my_allocations and get_my_assignments always show parent project names. The period_name field is populated alongside when the envelope is period-scoped, so you can see which month or sprint it covers:
Nike Retainer ← project_name (always the parent)
period_name: "Nike Retainer — April 2026"
allocated: 60h logged: 42h remaining: 18hEnvelope fields
Each envelope has:
| Field | Description |
|---|---|
id | Permanent sequential ID — use this to update or cancel |
user_id | The person this envelope belongs to |
project_id | The project or period child it targets |
allocated_hours | Hours budgeted for this person on this project/period |
task_id | Optional: work category tag (links to a task type) |
status | active or cancelled |
created_by | Manager or Owner who created the envelope |
created_at | Date created |
The optional task_id tag is not a constraint on what tasks the person can log — it's metadata saying "this envelope is intended for Design work" (or whichever task type). It helps with estimates-vs-actuals breakdowns.
Budget overdraw
When a person has logged more hours than their allocated budget on a project, that is a budget overdraw.
VERA surfaces overdraws in morning and evening summaries, and via get_estimates_vs_actuals. A delta > 0 means over-plan. Example:
"⚠️ Bob has logged 45h on Nike Rebrand but only has 40h in his envelope — 5h over."
Overdraw doesn't block logging. It's a signal for the Manager to either update the envelope or have a scope conversation with the client.
Capacity and overbooking
Team availability is the aggregate view: for each person, how many hours are they allocated vs. how many are free.
Overbooking happens when a person's total envelopes across all their projects exceed their available capacity.
How capacity is calculated:
VERA calculates available capacity from two sources: the user's individual hours_per_week setting, and the calendar. The formula is:
available hours = (working days × hours_per_day) − company holidays − time off
where: hours_per_day = user.hours_per_week ÷ work_days_per_weekTime-off hours (sick, leave, PTO) are capped at the user's hours_per_day per entry. This ensures a sick day logged at a standard 8-hour block doesn't over-subtract from a contractor whose working day is shorter.
hours_per_week is set per person:
- FTE: defaults to 40. No need to specify when adding a user.
- Contractor: must be set explicitly when adding the user. A contractor doing 3 days a week at standard hours would be 24. VERA will ask for this when you add a contractor.
- Vendor: placeholder value of 40. Vendor capacity is not tracked meaningfully — cost is governed by liabilities, not hours.
The work week schedule (which days count, and how many hours per day for the base calculation) is configured at the tenant level via set_work_week, defaulting to Mon–Fri. Company holidays from 12. Company_Calendar and approved time off already logged are both subtracted.
The overbooking check uses a rolling 90-day window from today. This means capacity is compared against available working time in the next 3 months, not against a single day or week.
VERA detects overbooking when you create or update an envelope via allocate_hours. If the envelope would put someone over capacity in the 90-day window, VERA returns overbooked: true and flags the person and hours over. This doesn't block the creation — it's a warning.
Use get_team_availability to see everyone's headroom across all projects. Use check_capacity when evaluating whether the team can take on new work.
Envelope lifecycle
allocate_hours → active envelope
↓
update_allocation → change hours (up or down)
↓
cancel_allocation → envelope marked cancelled (not deleted)Cancelled envelopes are kept for audit trail purposes. When you query envelopes, VERA returns only active ones by default.
Envelope model by project type
| Project type | Envelope scope | Notes |
|---|---|---|
| T&M | Project lifetime | Covers all time logged to the project |
| Fixed Price | Project lifetime | Covers all time logged to the project |
| Pro Bono | Project lifetime | No revenue; envelope tracks effort only |
| Internal | Project lifetime | Overhead/admin; no financial tracking |
| Retainer | Active period child | New envelope required each period; error if no active period |
| Agile | Active sprint child | New envelope required each sprint; error if no active sprint |
For Retainer and Agile, the parent project acts as a roll-up label. All time and envelopes live on the individual period/sprint children.
Common envelope queries
| Question | Tool |
|---|---|
| "What should I work on?" | get_my_assignments |
| "What are Alice's envelopes?" | get_person_allocation_summary |
| "Who is on the Nike project?" | get_project_assignments |
| "How much headroom does the team have?" | get_team_availability |
| "How did plan vs actual compare last week?" | get_estimates_vs_actuals |
| "Can we take on new work in April?" | check_capacity |
| "What's the 4-week capacity outlook?" | get_capacity_forecast |