The Person's Agent and Prompt
One visible agent per person (ADR-0019)
- Every human personnel record has exactly one agent persona (
type = agent, a singleAgentConfig,responsible_id= the human). It is created together with the workspace. - The agent can start background tasks and subagents; subagents can call other subagents (depth, concurrency and budget limits by policy). They are not personnel, they are runs.
- The sidebar shows work, not agents: current and recent sessions/runs and their state.
- Authority does not grow. A subagent's authority is a subset of its parent's; each run receives a short-lived token derived from its parent's that can only narrow. The policy engine still decides at every tool call.
- Every audit event carries
person,session,run_id,parent_run_idand a free-textrole; even when the agent fans out, the run tree can be reconstructed.
"My area"
A permanent view opened with one key: company context (vision, mission, values, goals), department goals, the person's role and job description (Personnel.job_description), the applicable policies in plain language and what the agent will not do, and why. If a request is refused or held for approval, the reply says which rule it is and offers "propose a change".
Layered context
From low to high precedence: base rules → policies (company ∪ department ∪ person ∪ agent) → company → department → the person's job → what the agent has learned. Policies win; the agent can only add restrictions.
Self-learning is visible and one-way: learning is only from the person's own messages and corrections (never from tool results, documents or web content); what is learned is versioned and inspectable, and reverted with one key.
Token-budgeted prompt (ADR-0020)
The prompt is assembled from named and counted sections (Section). The budget is PROMPT_BUDGET_TOKENS (default 2000, a starting value). If the budget is exceeded, optional sections drop in a fixed order: knowledge, memory, department, job, company. identity, rules, closing never drop.
- Stable first, per-turn changing last: so that the provider's prompt cache can use the long common prefix.
- Policies appear in the prompt only as names (at most 20). Real enforcement happens at tool-call time; leaving detail out costs helpfulness, not safety.
- Token counts are estimates (no tokenizer); they are for watching growth, not for billing.
- Every real prompt writes its section names and sizes to the log (
prompt_assembled); the text is never written.
Intent classification (TypeSafe Jev)
The user's first message of a session is classified by task type, whether company knowledge is needed, sensitivity and (if departments exist) domain. The result only narrows the prompt; for example a non-work greeting drops all optional sections. The same record becomes a tag for work review.
Constraints (all tested):
- Never a security control. Intent cannot add sections or widen authority.
- Fast and fail-open. 1.5 s timeout, no retry; any error means "no intent", that is the full prompt.
- Cost gate. About 520 input tokens per call. It runs only on large enough prompts (
INTENT_MIN_PROMPT_TOKENS, default 1500). - Only the first turn of a session; so that the prefix does not change and break the cache, and continuing messages such as "ok" are not treated as chat.
- Without text in the audit: the
intent_classifiedevent writes tags, skipped sections and token counts; never the message. - It leaves the company, so it is off by default:
TYPESAFE_API_KEYand AppConfigintent.enabledare needed together.
Measurement with real Jev (29 September 2026): 0/48 real work wrongly trimmed, p50 0.24 s. There is no local fallback classifier; without Jev the result is the full prompt.