Skip to content

Project Tools


create_project

Create a new project. Owner only.

Writes to: 02. Projects

Parameters:

ParamRequiredDescription
requesting_user_slack_id
project_nameUnique project name
project_type"Retainer" | "T&M" | "Fixed Price" | "Pro Bono" | "Agile" | "Internal" — never defaulted
client_nameCond.Client org — created automatically if new. Omit for Internal projects — VERA assigns the implicit "Internal" client automatically
contract_valueCond.Required for Fixed Price
hours_budgetCond.Required for Retainer (annual hours). Optional for others.
billing_rateHourly rate billed to client
deadlineYYYY-MM-DD
notes
project_categoryDefaults to "client"

Rules:

  • Never assume a default project type — always ask
  • client_name is not required for Internal projects — the Internal client is implicit
  • Fixed Price requires a positive contract_value — the endpoint rejects creation with ❌ contract_value is required for Fixed Price projects if it's missing or ≤ 0. Fixed Price revenue is % complete × contract_value, so without it the project would recognise $0 revenue forever.
  • For Agile parents: no contract_value or hours_budget on the parent itself
  • After Agile parent creation, offer to set up Sprint 1
  • "Create a retainer" means create_project with project_type="Retainer" — this tool creates the parent engagement. The first period child is auto-created by create_project. Use create_retainer_period only when adding a new period to an existing retainer parent (e.g. "create the June period for Acme Retainer").
  • On creation, the Project Management task is automatically enabled on the new project so it starts with at least one enabled task — you can allocate hours immediately, and use Edit tasks to add more (Design, Development, etc.). If the tenant has archived or renamed its Project Management task, the project is simply created with no default task (no error).


rename_project

Rename a project and update all references. Owner only.

Updates: 02. Projects, 01. Time Entries

Parameters:

ParamRequiredDescription
requesting_user_slack_id
old_name
new_name

Protected projects: the internal time-off projects PTO, Sick, and Leave can be neither renamed nor cancelled (cancel_project carries the same guard) — both return a 403 ("…is a protected time-off project and cannot be renamed/cancelled") to keep time-off logging intact. Other internal/overhead projects are unaffected.


update_project

Update one or more fields on an existing project. Owner or Manager.

Updates: 02. Projects

Parameters:

ParamRequiredDescription
requesting_user_slack_id
project_nameCurrent project name
new_nameRename the project
statusactive | completed | cancelled
is_billableBoolean
alert_threshold% at which to flag the budget (default 80)
notesFree-text notes
deadlineYYYY-MM-DD
contract_valueOwner only. Setting this as a Manager returns ❌ Failed: Only owners can change a project's contract_value…
billing_rateOwner only. Same gate as contract_value.
hours_budgetOwner only. Same gate as contract_value.

Role notes:

  • Managers can set new_name, status, is_billable, alert_threshold, notes, and deadline.
  • contract_value, billing_rate, and hours_budget are owner-only on write, mirroring the read-side isolation in get_project_info. A manager attempting to set any of these gets a 403.

Deterministic routing (updated #1090): Field-bearing phrasings now route to update_project in the extractor instead of being hijacked by edit_entry or set_rate. The extractor has an update_project entry with object_nouns: ['contract value', 'billing rate', 'status', 'notes', 'billable', 'is billable'].

Deterministic owner execution (updated #1091): contract_value, billing_rate, and hours_budget now execute via DET confirm→fire gates (no model turn). Both colon form ("update CityCore App Development: contract value 130000") and preposition form ("set the contract value for CityCore App Development to 130000") resolve the project and present a clean confirm. Owner-only denial is also deterministic. Missing-value inputs fall through to the model.


list_projects

List all projects (filtered by role).

Reads from: 02. Projects, 04. Clients, 03. Users

Returns: name, client, type, pm_name, status, deadline (Owner/Manager only)


get_project_info

Full project details. Always call this first when checking project status — it tells you the type, which determines whether to follow up with get_project_status or get_retainer_status.

Reads from: 02. Projects, 04. Clients, 03. Users

Returns: name, client, type, budget_hours, status, pm_name, deadline (Owner/Manager), contract_value (Owner), billing_rate (Owner)


get_project_status

Task-level budget status for non-retainer projects.

Reads from: 01. Time Entries, 06. Project_Tasks, 02. Projects

Returns per task: hours_logged, budget_hours, % used, alert status, committed hours (logged + allocated)

Do not use for retainers — use get_retainer_status instead.


get_project_health

Burn rate health for retainer projects, with envelope-aware forecast.

Reads from: 01. Time Entries, 02. Projects, 07. Budgets

Returns: hours_logged, days_elapsed, pace_per_day, projected_eom_hours, allocated_remaining, forecast_with_allocations, variance, utilisation%, status

Status values: critical_overpace, warning_overpace, on_track, warning_underpace, critical_underpace


get_my_projects

Projects where the requesting user is the PM (or all projects if Owner).

Parameters: requesting_user_slack_id


delete_project

Permanently hard-delete a project. Owner only. Only allowed when the project is completely empty: no time entries, no allocation envelopes (any status), no vendor liabilities, and no period/sprint children. Use cancel_project for anything with history.

Writes to: 02. Projects

Parameters:

ParamRequiredDescription
requesting_user_slack_id
project_nameName of the project
project_idID of the project (alternative to name)

Returns 400 if the project has time entries, budgets (any status), liabilities, or child periods/sprints — with a message pointing to cancel_project as the correct affordance. The protected time-off projects (PTO, Sick, Leave) return 403. This action is irreversible.

Returns: project_id, name, message


set_project_budget

Set the project-level hours budget (Tier 1). Owner only.

Updates: 02. Projects col D

Parameters:

ParamRequiredDescription
requesting_user_slack_id
project_name
budget_hoursTotal hours cap

set_project_deadline

Set the project delivery date. Owner or PM of the project (Managers who are not the PM get a deterministic denial).

Updates: 02. Projects

Parameters:

ParamRequiredDescription
requesting_user_slack_id
project_name
deadlineYYYY-MM-DD

Deterministic routing: natural-language date inputs ("set the deadline for X to next Friday") resolve the date and show a confirm with the concrete ISO date before writing — no model round-trip. A non-PM manager gets a deterministic denial: ❌ Failed: Only owners or <project>'s PM can set its deadline. ISO date inputs ("set the deadline for X to 2027-01-16") fall through to the model.


list_tasks

All task types with billability flag.

Reads from: 05. Tasks


create_task

Create a new global task type. Owner only.

Writes to: 05. Tasks

Parameters: requesting_user_slack_id, task_name, is_billable (true/false)


rename_task

Rename a task type globally. Owner only.

Updates: 05. Tasks

Parameters: requesting_user_slack_id, old_name, new_name


archive_task

Archive a task type so it no longer appears in menus or as a write target. Owner only. Historical time entries are preserved. Use unarchive_task to restore.

Writes to: 05. Tasks

Parameters: requesting_user_slack_id, task_name

Hard fails (409) if the task is enabled on any active project — disable it from those projects first.

Returns: task_id, task_name


unarchive_task

Restore an archived task so it appears in menus again. Owner only.

Writes to: 05. Tasks

Parameters: requesting_user_slack_id, task_name

Returns: task_id, task_name


get_project_tasks

All enabled tasks for a project, with budget and hours logged.

Reads from: 06. Project_Tasks, 05. Tasks, 01. Time Entries

Returns per task: task_name, is_billable, budget_hours, alert_threshold, hours_logged, % used, budget_summary

budget_summary includes:

  • tasks_without_budget: count of enabled tasks with no budget set
  • over_project_budget: whether task totals exceed the project budget
  • unallocated_hours: project budget minus sum of task budgets

enable_task_for_project

Enable a task on a project with optional budget. Owner or project PM.

Writes to: 06. Project_Tasks

Parameters:

ParamRequiredDescription
requesting_user_slack_id
project_name
task_name
budget_hoursOptional hours budget for this task
alert_thresholdPercent — defaults to 80

disable_task_for_project

Disable a task on a project (deletes the row from 06. Project_Tasks). Owner or project PM.

Parameters: requesting_user_slack_id, project_name, task_name


get_retainer_status

Monthly burn rate for a retainer project. See Retainers for interpretation guide.

Reads from: 01. Time Entries, 02. Projects, 07. Budgets

Parameters: requesting_user_slack_id, project_name

Returns: budget_hours, hours_logged, hours_remaining, days_elapsed, days_remaining, pace_per_day, projected_eom_hours, allocated_remaining, forecast_with_allocations, variance, utilisation_percent, exceed_date, unused_hours, unused_value, status


get_pm_retainer_summary

All retainer projects assigned to a PM, with burn status for each. Manager/Owner.


create_sprint

Create a new sprint under an Agile parent. Owner only.

Writes to: 02. Projects

Parameters:

ParamRequiredDescription
requesting_user_slack_id
parent_project_nameThe Agile parent project
contract_valueMust be asked explicitly — never derived
hours_budgetSprint hours estimate

Sprint number is auto-incremented — do not specify manually.


get_agile_summary

All sprints under an Agile project with revenue recognition.

Reads from: 02. Projects, 01. Time Entries

Returns per sprint: sprint_name, sprint_number, status, contract_value (Owner), hours_budget, hours_logged, recognised_revenue (Owner)


update_sprint_status

Transition a sprint from planned to active. Owner only. No confirmation prompt needed.

Updates: 02. Projects col L

Parameters: requesting_user_slack_id, sprint_id, new_status ("active")