Skip to content

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:

TermWhat it isWho sets itWhere it lives
BudgetTotal project hours — the whole pieOwner02. Projects.budget_hours
EnvelopeOne person's slice of that pieManager or Owner07. 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.


The envelope is the approval ​

VERA has no separate sign-off step for recorded time — a Manager doesn't review and click "approve" on every timesheet. Instead:

  • Time logged inside an active envelope that still has room is approved automatically. Nothing is queued and nobody is asked — the Manager already approved this work when they created the envelope, and logging against it is executing a decision that was already made.
  • Time that is not covered by any envelope, or that pushes an envelope past its allocated hours, is surfaced as an exception on the Needs you page's Unresolved tab for a Manager to look at.

All recorded time counts in every report, approved or not. No dashboard, LER, margin, burn-up, or P&L figure is ever filtered by approval state — this is a queue for a Manager's attention, not a gate on what's real.

Internal, PTO, sick, and leave time is exempt — those categories are evergreen and don't carry envelopes by design, so none of it generates an exception. A person's repeated logging against the same over-full or uncovered situation creates one open item, not one per entry — it stays open until a Manager resolves or dismisses it.

Time recorded on a company holiday is treated the same way — it isn't refused (VERA doesn't second-guess a genuine reason to work a holiday, like a launch or a client emergency), but it surfaces as its own exception so a Manager sees it. Logging more than once on the same holiday doesn't pile up separate items — the first one covers the day.


Natural-language phrasing ​

VERA accepts two word orders when creating an envelope — both are equivalent:

StyleExample
Natural (to <project> for <person>)allocate 20h to Apex for Rachel as Design
Legacy (to <person> on <project>)allocate 20h to Rachel on Apex for Design

Either way, VERA binds each name to the slot matching what it actually is (person or project) in one turn — no follow-up questions when all slots are present in the opening sentence.

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 — Period 4"
       ↓
Envelope is stored against project_id 47 (the April period), not project_id 12 (the parent)

This matters because:

  1. Utilization 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.
  2. 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.
  3. hours_logged is 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_logged would 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.

In the console, this rule is surfaced on the period's own page rather than discovered as an error. A Retainer parent's project-detail page (/console/p/:id) shows a Periods card listing every period, and each period's dates link to that period's own page — the only place its envelopes are added, cancelled, or reactivated (the parent's own page carries no envelope list or Add-envelope control at all). Opening a period and adding an envelope there always targets that period's own id — a PM never types one by hand — and works whether the period is currently active or not yet started (planned), so there is no "no active period" state for the control to be hidden behind.

A new period inherits enabled tasks automatically ​

An envelope's task_id can only reference a task enabled for the project it targets (see Envelope fields below), and for a Retainer or Agile project that target is always the period child, not the parent. A brand-new period is created with the same tasks already enabled that its source had, so it can be staffed immediately with no manual step:

  • The first period of a new Retainer/Agile project inherits its enabled tasks from the parent.
  • Every later period, created via create_retainer_period, inherits from the most recently created period — the same source its budget and contract terms already inherit from — falling back to the parent if this is the first period.

Tasks are copied, not shared with the parent — enabling or disabling a task on one period never changes another period or the parent. If a period's tasks need to differ from what it inherited, an owner or the project's PM can correct them afterward from the console, on that period's own page (open it from the ID column of the parent's Periods card), in its Enabled tasks card. The parent's own page has no Enabled tasks section for a retainer, since its tasks live on each period.

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 — Period 4",
  "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 — Period 4"
  allocated: 60h  logged: 42h  remaining: 18h

Envelope fields ​

Each envelope has:

FieldDescription
idPermanent sequential ID — use this to update or cancel
user_idThe person this envelope belongs to
project_idThe project or period child it targets
allocated_hoursHours budgeted for this person on this project/period
task_idOptional: work category tag (links to a task type)
statusactive or cancelled
created_byManager or Owner who created the envelope
created_atDate created

The task_id tag constrains which task type the envelope can be created with: only tasks enabled for the project (via Edit tasks / enable_task_for_project) are valid at allocation time. A project with no enabled tasks cannot receive any envelope. The tag is planning metadata — it does not restrict what tasks the person logs against once work begins.


Multiple envelopes on the same task ​

A person can have more than one active envelope for the same project and task type. This happens when an allocation is topped up by creating a new envelope rather than updating the existing one.

VERA uses a bucket model to avoid double-counting logged hours in this situation. All envelopes sharing the same (person, project, task) triple are grouped before any usage figure is computed, so a logged hour is counted toward the group once, never twice — this holds regardless of how many envelopes share the triple.

Within that group, VERA attributes hours as specifically as it can:

  • A time entry logged from the web console can name the exact envelope it belongs to. That envelope's own Logged and Remaining (allocated − own logged) reflect only its own hours.
  • A time entry with no envelope named — logged from Slack (which has no way to ask which envelope is meant), or predating this attribution — is unattributed: it counts toward the group but isn't credited to any single envelope. VERA never guesses which envelope it belongs to, and never splits it across several.

In the web console, each envelope in the group renders as its own row with its own ID, Allocated, Logged, and Remaining. If the group has any unattributed hours, they get one additional row labelled "Unattributed" showing just that figure — shown honestly rather than folded into an envelope or hidden. Each envelope retains its own Edit and Cancel modal so individual envelopes can still be adjusted.


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. The log that crosses the line also opens an envelope_overrun item in the unresolved items queue (see The envelope is the approval) — its top resolution option raises the envelope to cover what's already logged.


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_week

Time-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 typeEnvelope scopeNotes
T&MProject lifetimeCovers all time logged to the project
Fixed PriceProject lifetimeCovers all time logged to the project
Pro BonoProject lifetimeNo revenue; envelope tracks effort only
InternalProject lifetimeOverhead/admin; no financial tracking
RetainerActive period childNew envelope required each period; error if no active period
AgileActive sprint childNew 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 ​

QuestionTool
"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