Skip to content

Company Navigator ​

One machine-readable interface over Company OS capabilities for agents. It is a projection plus a receipt-backed action lifecycle; it owns no table, no dashboard, and no execution path. Everything lands in the canonical ledger: tenant admission, SCOPE_TASKS authority, create_task_tx, and governance_events.

Source: src/company_os/company_navigator/ (mod.rs catalogue and router, context.rs entity resolver, lifecycle.rs action lifecycle and gaps, coverage.rs freshness map, tests.rs database-backed contracts). Outcome Radar integration lives in src/company_os/outcome_radar.rs; Capability Home embeds the coverage map in src/company_os/capability_home.rs.

All routes sit under /api/company/companies/{company_id}/navigator and require a company-bound principal token. POST routes additionally pass the standard mutation admission (SCOPE_TASKS).

Routes ​

MethodPathPurpose
GET/capabilitiesCatalogue: input/output schemas, effect, risk, approval, prerequisites, entity types, idempotency, examples, readiness, expected receipts, lowering.
GET/capabilities/{id}/explainexplain step: what a capability does, what it needs, who approves, which receipts prove it ran. Records nothing.
GET/context?ref=<domain>:<selector> or ?q=<text>Cross-domain entity context with aliases, related entities, and store coverage.
GET/coverageCoverage and freshness map: domains, connectors, business sources, mail queue, open capability gaps, what cannot be performed and why.
GET/actionsRecent actions with derived status and next action.
POST/actions/planplan step. Body: {capability_id?, input, owner_persona?, priority?, due_at?, business_impact?}.
GET/actions/{action_id}Current envelope of one action.
POST/actions/{action_id}/previewpreview step: the exact task that would be created.
POST/actions/{action_id}/approveapprove step. Body: {decision: approve|reject, note?}.
POST/actions/{action_id}/executeexecute step: one canonical task through create_task_tx.
POST/actions/{action_id}/verifyverify step: proves task and receipts are bound.

Action lifecycle ​

explain → plan → preview → approve → execute → verify

  • The action_id is the SHA-256 of the canonical plan input (company, capability, intent, sorted entity bindings, sorted evidence refs). Same input, same action; re-planning never writes a second receipt.
  • Every step is a governance_events row with subject_type = navigator_action and subject_id = action_id. Receipt actions: company_navigator_action_planned, _previewed, _approved or _rejected, _executed, _verified. Task creation adds task_created.
  • Approval requires an active owner/admin who is not the planning principal (separation of duties). Rejected actions cannot execute.
  • Execute is idempotent: the executed receipt carries the task id, and the task is deduplicated by navigator:<action_id>. Outcome Radar's acceptance of a navigator: proposal calls the same execute_action_tx.
  • Global safe mode returns the plan as a blocked_safe_mode envelope without writing anything.

Every step returns one envelope (hsm.company_os.navigator_action.v1): action_id, capability_id, step, status, entity_bindings, changed_state (task id, display number, state, task preview), evidence (evidence refs, receipts, verification checks), receipt_ids, approval, and next_action.

Entity references ​

<domain>:<selector>. Selectors: a UUID, #<display_number> for tasks, email:<address>, external:<id>, or a bare natural key.

Domains with a canonical store: client (company_customers), request (customer_requests), task (tasks), message and thread (company_email_operator_queue), order, ticket, invoice (company_*), action (navigator receipts). opportunity is computed by Outcome Radar.

Domains with no store in Company OS: property, unit, lease, resident, vendor, inspection, incident, compliance, deal, visit, document, case. These bind by reference. The lowered task carries {"kind":"label","ref":"entity:<domain>:<selector>"} in capability_refs, so /context?ref=property:velora-12 still joins to its tasks and actions through the ledger.

Capability gaps ​

When plan receives no capability id (or an unknown one), the navigator records company_navigator_capability_gap with subject_type = capability_gap and subject_id = fingerprint. The fingerprint hashes the requested capability, the entity kinds, and the normalized intent terms, so rewordings of the same ask collapse. Frequency is the receipt count per fingerprint. Each receipt keeps the attempted intent, the missing tool or data, business impact, DRI, and suggested catalogue capabilities.

Open gaps appear in /coverage and in Outcome Radar as gap:<first receipt id>. Accepting one creates the deduplicated missing-capability task (dedupe key capability-gap:<fingerprint>).

Outcome Radar sources added ​

Proposal ids keep the <prefix>:<uuid> convention:

PrefixSourceProposal
connectorcompany_connectors in error/degraded or failed after last successRepair connector
sourcecompany_business_sources degraded/error or non-manual and stale over 7 daysRefresh source
mailcompany_email_operator_queue pending over 24 hoursAnswer waiting email
navigatorplanned actions with an approval and no execution/rejectionExecute approved action (accept executes it)
gapcapability gaps grouped by fingerprintClose capability gap

Property operations pack ​

Nine capabilities under company_os_property_operations_pack: property.portfolio.context, property.lease.renewal, property.resident.followup, property.maintenance.triage, property.vendor.coordinate, property.inspection.schedule, property.finance.review, property.compliance.deadline, property.incident.respond. Each lowers to one canonical task through the lifecycle with approval required; property entities bind by reference.

Verification ​

cargo test --lib -- company_navigator:: outcome_radar:: capability_home:: with DATABASE_URL set. The database-backed tests cover the read gate, the full lifecycle, the Radar hand-off, gap deduplication, safe mode, and the entity resolver.

Company OS documentation — built with VitePress