Skip to content

Glossary#

Every domain term used in Ticket Board, with a one-line definition and a pointer to the deeper explanation. Sorted alphabetically.

When a term has both a colloquial meaning and a specific schema meaning here, the schema meaning wins.

A#

Activity event
A user-visible event in a ticket's history (state change, assignment, comment, etc.). Implemented as a Pydantic read-model projection over audit_event rows where category='activity'. There is no activity_event table. See ADR-0006.
Actor
The identity that initiated a request. Resolved by middleware to a CurrentActor object regardless of transport. May be a human or a bot. See Auth and identity.
Allowlist
The list of project_id values a bot may access. Stored as bot_project_allowlist on user. Reads are filtered by it implicitly; writes outside it raise auth.forbidden (details.reason = "project_not_in_allowlist").
Argon2id
The hash algorithm used to store bot tokens at rest. Tuned via ARGON2_TIME_COST, ARGON2_MEMORY_COST, ARGON2_PARALLELISM in .env.
Audit event
A row in audit_event. The system-wide append-only log of every write, including auth and admin events. Superset of activity events. Never deleted by application code.
Audit-only event
An audit_event row with category='audit_only'. Recorded for forensics but not surfaced in any per-ticket activity feed. Examples: auth.login.failure, bot.token.rotated, bot.tool_invoked, auth.bot.write_attempt_in_read_mode.

B#

Backlinks
The set of wiki pages whose body contains a resolved [[wikilink]] pointing at a given page. Computed from the wiki_link table.
Bcrypt
The hash algorithm used to store human password hashes at rest. Cost is tuned via AUTH_BCRYPT_COST in .env (default 12).
Bot
A User of type bot. Authenticates via a token used both in its MCP URL and as the REST X-API-Key. Scoped to a project allowlist with a read or write mode. Created and managed by humans only.
Bot mode
The bot's write capability: read or write. Stored as user.bot_mode. Write tools are rejected for read-mode bots at the MCP dispatch layer and at the REST router.
Bot token
The argon2id-hashed credential for a bot. One active token per bot at a time. Plaintext is shown once at creation or rotation and never echoed thereafter. Stored in bot_token; rotations and revocations modify in place.

C#

Caddy
The reverse proxy fronting both the Next.js UI and the FastAPI backend on a single origin. Required for the SameSite session cookie to work. See Caddyfile and Docker Compose.
Category (audit event)
The discriminator on audit_event separating user-visible activity from forensics-only audit rows. Values: activity, audit_only. Stored at write time, not inferred. See ADR-0006.
Comment
Markdown discussion attached to a ticket. Editable by the author with retained edit_history. Soft-deletable; the deletion audit event captures the full body + history.
Cursor
The opaque base64-encoded pagination token returned by collection endpoints. The generic list cursor carries {id, created_at}; the /search cursor additionally embeds a filter-hash guard. Portable between REST and MCP.
CurrentActor
The Python dataclass representing the resolved identity of the current request. Carries user_id, workspace_id, type (human or bot), and bot-specific fields (bot_mode, bot_project_allowlist).

D#

Display id
The {PROJECT_KEY}-{counter} form of a ticket id (e.g. PROJ-123). Generated atomically per project at insert time. Independent of the UUIDv7 primary key. Accepted anywhere a single ticket is addressed by URL.

E#

Envelope
The fixed JSON shape used for errors ({ "error": { "code", "message", "details" } }) and for paginated responses ({ "data": [...], "page": { "next_cursor", "has_more" } }).
Epic
A ticket of type epic. Top of the hierarchy; cannot have a parent. May contain stories.
ETag
A weak HTTP entity tag emitted on GET for tickets and wiki pages: W/"<updated_at_unix_ms>-<short_id>". Honored on PATCH and DELETE when sent as If-Match. See Optimistic concurrency.

F#

FastMCP
The MCP server library mounted at /mcp/bot/{token} inside the FastAPI process. Provides JSON-RPC over HTTP, tool catalog discovery, and the tools/list / tools/call / resources/list / resources/read endpoints.
Filter hash
A 16-character sha256 prefix of the canonicalized filter params, embedded inside the /search cursor only. Mismatched filter hashes between cursor and request fail with 400 validation.invalid_field (details.reason = "cursor_filter_mismatch"). No other list endpoint enforces this guard in v1.
FTS
Full-text search. Implemented via Postgres tsvector + GIN indexes on tickets (title + body + recent comments) and wiki pages (title + body). Exposed via the q query param on list endpoints and the dedicated /search endpoint.

G#

GIN
The Postgres index type used for the tsvector full-text-search columns and the jsonb_path_ops opclass on payload.
Global wiki page
A wiki page with project_id = NULL. Visible to every actor in the workspace, including bots whose allowlist would otherwise be empty.

H#

Hard delete
Deletion that removes the row. Used for entities with no archival value or no incoming foreign keys: StickyNote, Label, WorkflowState, TicketRelation, Watcher, Webhook. See ADR-0005.
Human
A User of type human. Authenticates via username + bcrypt password + HttpOnly session cookie. Has full read/write within the workspace. Admin-only endpoints are humans-only.

I#

Idempotency key
A client-chosen string (UUIDv4 recommended) sent as Idempotency-Key on resource-create POSTs. Causes the server to replay the original response on retry with the same fingerprint, or fail with 409 resource.conflict (reason=idempotency_mismatch) on a different request body. Stored in idempotency_record, purged after IDEMPOTENCY_KEY_TTL_HOURS.
If-Match
The HTTP request header carrying an ETag for optimistic concurrency. Accepted on PATCH and DELETE for tickets and wiki pages.

J#

JSON-RPC
The wire protocol the MCP transport speaks (over HTTP). Bots send { "method": "tools/call", "params": { ... } } envelopes; the server returns { "result": ... } or { "error": ... }. See MCP error mapping.

L#

Label
A per-project tag with a color, attached to tickets via the ticket_label join table. Hard-deleted; removal cascades to all tickets.

M#

MCP
Model Context Protocol. The transport bots use from inside an LLM client. Each bot gets a unique mount at /mcp/bot/{token} exposing the bot-accessible tool catalog. See MCP server.
Mode
Synonym for Bot mode. The bot's read or write capability.

O#

Operation id
The <resource>.<verb> identifier on every route in the OpenAPI document (e.g. tickets.create, bots.tokens.rotate). Drives method names in generated TypeScript and Python clients.
OpenAPI
The OpenAPI 3 document FastAPI generates at /api/v1/openapi.json. The contract between the REST surface and any client. See OpenAPI spec.
Optimistic concurrency
The conflict-detection pattern used on PATCH and DELETE of tickets and wiki pages: the client sends If-Match: <etag>; mismatches return 409 resource.conflict (reason=etag_mismatch). See Optimistic concurrency.

P#

Pagination
Opaque cursor pagination, same envelope on REST and MCP. Defaults: limit=50 on REST (max 200) and limit=50 on MCP (max 100). Cursors are portable between the two transports.
Plaintext token
The unhashed bot token shown once at creation or rotation (tkb_...). Never stored; never echoed in subsequent reads. The argon2id hash is what is stored.
Project
A named container for tickets, with a short key (e.g. PROJ) used in ticket display ids. Owns its own workflow state set, labels, and per-project counter. Soft-deletable.
Project allowlist
See Allowlist.

R#

Rate limit
In v1 only the login endpoint is rate-limited: 5 attempts per IP and per username within a 15-minute sliding window. Per-actor REST/MCP limits are planned; the user.rate_limit_per_minute column and DEFAULT_RATE_LIMIT_PER_MINUTE setting are reserved for that future middleware. See Rate limiting.
Read-only bot
A bot with bot_mode = read. Write tools and write endpoints reject it with auth.read_only_bot.
Request id
A UUID generated per request, echoed back as X-Request-Id, attached to every audit event and log line for correlation.
Resource (MCP)
A read-only context attachment addressable by URI in the MCP transport. v1 schemes: ticket://{display_id} and wiki://page/{slug}. Listed via resources/list (capped at 500), read via resources/read. See MCP resources.

S#

Sweeper
A background retention job that purges expired rows: Session after absolute timeout, IdempotencyRecord after TTL, ToolInvocationLog after TOOL_INVOCATION_LOG_RETENTION_DAYS.
Service layer
The Python module group (services/) that holds business rules and authorization. Both REST routers and MCP tools call into services; services do not know which transport invoked them.
Session
A row in session representing an authenticated human's browser session. Backed by the tb_session HttpOnly cookie. Purged by the sweeper after the absolute timeout.
Soft delete
Deletion that sets deleted_at instead of removing the row. Used for Ticket, WikiPage, Project, Comment. Reads filter WHERE deleted_at IS NULL by default; ?include_deleted=true (humans only) surfaces deleted rows. See ADR-0005.
Sticky note
A markdown scratchpad, either personal (creator-only) or project-scoped (workspace-visible). Hard-deletable. Convertible to a ticket via POST /sticky-notes/{id}/convert-to-ticket.
Story
A ticket of type story. May have an epic as parent and may have subtasks as children.
Subtask
A ticket of type subtask. Must have a story as parent.

T#

Ticket
The unit of work. Polymorphic via type ∈ {epic, story, subtask}. Carries a display_id of the form {PROJECT_KEY}-{counter}. Soft-deletable.
Ticket relation
A typed edge between two tickets: blocks, relates_to, duplicates. Stored in ticket_relation. Hard-deleted; the edge's removal is the deletion.
Token-in-path
The MCP authentication mechanism: the bot's plaintext token is embedded in the URL (/mcp/bot/{token}/...). The URL is treated as a bearer secret; access logs redact it. See ADR-0002.
Tool
A named, typed function in the MCP tool catalog. Tools take typed arguments, call into the service layer, and return typed results. The v1 catalog has 29 tools across seven groups. See MCP tool catalog.
Tool invocation log
A row in tool_invocation_log carrying the per-call detail of an MCP tool invocation: redacted arguments_json, result_status, error_message, duration_ms. Paired with a pointer audit_event row. Purged after TOOL_INVOCATION_LOG_RETENTION_DAYS (default 90). See ADR-0008.
Tsvector
The Postgres FTS column type. Used on ticket title/body/comments and wiki page title/body, maintained by triggers, indexed by GIN.

U#

Unit of work
The per-request abstraction that holds the SQLAlchemy session, the resolved CurrentActor, the request id, and the deferred event queue. After-commit hooks fire the event emitter.
User
An actor in the system, either a human or a bot. One table, one discriminator column. See ADR-0003.
UUIDv7
The time-ordered UUID variant used for every primary key. Generated in the application via the uuid6 package; gives sortable inserts without leaking volume the way bigserial would.

W#

Watcher
A row in ticket_watcher representing a user's subscription to a ticket's activity. Hard-deleted; removal is "unsubscribe me."
Webhook
A workspace-level outbound HTTP endpoint with event filters, HMAC-signed payloads, and best-effort retry. Hard-deletable; past WebhookDelivery rows survive deletion.
Webhook delivery
A row in webhook_delivery for one attempted delivery, including HTTP status and retry state. Append-only.
Wiki link
A row in the resolved [[wikilink]] graph used to compute backlinks. Records both resolved targets and unresolved (broken) links.
Wiki page
A markdown document, globally or project-scoped, identified by slug. Soft-deletable. Editing creates a WikiRevision snapshot.
Wiki revision
A full snapshot of a wiki page taken on every save. Append-only; survives soft-deletion of the page.
Workflow state
A named, ordered state a ticket can occupy, scoped to one project. Has a category ∈ {backlog, active, done} for board grouping and reporting. Hard-deletable, but only when no live ticket references it (409 resource.conflict with reason=state_in_use otherwise).
Workspace
The top-level container for everything. v1 has exactly one, modeled but not exposed in the UI. All entities carry workspace_id so multi-workspace is a future config flip, not a migration. See ADR-0007.

X#

X-API-Key
The HTTP request header carrying a bot's plaintext token on the REST surface. The same token is also the path segment of the bot's MCP URL.
X-Request-Id
The HTTP response header carrying the per-request UUID for log correlation.