Skip to main content
Restricted Access: This documentation is only accessible to @tenzo.ai and @salv.ai email addresses.

Architecture

Who writes a stage, who does module work, and who follows a link is the chosen shape. V1 runtime below still uses today’s adapters (JobWorkflowCoordinator.START_AI_INTERVIEW, TenzoStageOrchestrator, Resume Review continue_handoff activating Interview). Allowed hops come from the compile. The Admin → Modules walkthrough is unchanged. Existing application-stage consumers read the TenzoStage compatibility projection. The inner click-in canvas is the code-owned ModuleDefinition compile (TenzoStage hops).

V1 workflow

V1 authoring is Admin → Templates Bank → Modules: named journey templates as the landing list, then a graph whose cards show each exit already wired (Pass → AI Interview, Resume Rejected → Stop). Change a destination from the dropdown on that exit. Drag a card corner to widen it. A fixed Ingest card sits left of the first module and shows its mapped ATS stages. Click a module to open the right panel and map ATS stages onto Ingest or a module start (saved only; not live routing). Hover a module start label to see that map without opening the drawer. Double-click a card or choose Open inner graph to replace the map with that module’s Tenzo-stage flow; the breadcrumb {template} / {module} returns to the journey map. Click any stage to attach extra actions in the drawer (email, SMS, ATS note, custom field, ATS stage). Those sit outside the regular graph and are not extra stages. Outreach cannot take email or SMS because that stage already reaches out; ATS updates still work there. A job gets exactly one template. The coordinator reads the job’s snapshot; if Interview is off that snapshot, handoff does not call Interview activate. Until a snapshot exists, the job still compiles from AI Resume Review Only. See Job module composition. The coordinator starts Resume Review, waits for a handoff-capable terminal result, evaluates the global gates, and then starts AI Interview when Interview is on the compiled list. A result that closes or holds the workflow does not start the next module. Resume Review and AI Interview are both module-native behind the same module_owned_resume_review flag. When Interview is on the compiled list, the coordinator still returns START_AI_INTERVIEW and the Interview orchestrator creates the durable run. The existing Tenzo writers (OUTREACH, SKIP_OUTREACH, AI_INTERVIEW_SCHEDULED, CALL_COMPLETED) remain the compatibility projection. Flag-off enrollment still jumps straight to OUTREACH and does not create an Interview row.

Two graphs

The journey map is composition only: Ingest is not a card, modules stay compact (start / continue / end / hold), and Stop is the shared terminal. Card ports come from the compiled module definition so the outer handles cannot drift from the click-in. The click-in is how a module interprets Tenzo stages, grouped by what the candidate is doing: Going through, Paused, Needs a person, and Not continuing. Resume Review sits on AWAITING_RESUME_REVIEW, can leave through Pass (REVIEW_PASSED) or end on Resume Rejected, and shows Re-review as a hold. AI Interview enters at OUTREACH and walks a short spine through invites, scheduled, and Call Completed, with a couple of pause forks and one dashed line into each destination group. Parks and stops stay inside the module, not extra journey cards. The click-in already reads the compiled inner graph. Inner edges are not persisted. The module run FSM (pending / evaluating / passed on Resume Review, pending / outreach / scheduled / completed on Interview) is lease and scoring progress only. It is not a sit-able stage language and is not what the click-in draws. A small run ↔ sit-able map keeps today’s module rows working: Resume Review pending/evaluating sit on AWAITING_RESUME_REVIEW; Interview pending enters at OUTREACH. Allowed module hops come from the compile. Runtime still applies a hop through TenzoStageOrchestrator. Switching that orchestrator onto compiled TransitionPlan execution is a later slice. Inner edges stay compiled, not persisted, on named journey templates.

Durable authority

Module state is the authority for progress inside a module. Global workflow state is the authority for progress between modules. TenzoStage remains available as a compatibility projection for existing UI, filtering, ATS, and automation consumers. Allowed module hops come from the compile; the run FSM is work progress, not a second hop table. A projection can combine module and global state when there is no one-to-one legacy stage. Updating the projection must not create a second workflow authority. Every local transition writes current module state and append-only module history atomically. Closing Resume Review results (rejected, a rejecting override) also project onto TenzoStage in that same transaction via the compatibility-projection hook, so a projection CAS miss rolls the module write back. Continuing handoff (passed / bypassed / passing override → AI Interview) is not an atomic next-module insert. V1 has no separate global workflow row. Resume Review continue_handoff activates the native Interview run, which then writes OUTREACH or SKIP_OUTREACH through the existing Tenzo helpers. If that writer call fails, the Resume Review run stays terminal so a recovery scan can retry: scoring terminals while CCI is still AWAITING_RESUME_REVIEW, and a passing override while CCI is still RESUME_REJECTED or RE_REVIEW_REQUESTED. Handoff is therefore eventually consistent, idempotent, and retryable. Readers never observe a new local stage without its module-history event. They may briefly observe a continuing local terminal whose compatibility stage has not yet moved to OUTREACH or SKIP_OUTREACH.

Configuration snapshot

The workflow captures an immutable configuration snapshot when the application enters the module sequence. Module orchestrators and the coordinator read that snapshot for every attempt and retry. Edits to live job or organization settings apply to later workflows; they do not change the meaning of an in-flight decision. The snapshot contains the versioned inputs needed to reproduce module policy and handoff behavior. Runtime outputs and lease metadata remain separate from configuration.

Leases and retries

Runnable work is claimed with a bounded lease. A claim records the worker, lease expiry, and attempt against the durable module state. Only the current lease holder may publish work for that claim. If a worker exits or its lease expires, another worker can reclaim the same stage. The retry reloads the persisted stage and configuration snapshot, then repeats the idempotent operation. A worker whose lease is stale cannot commit after a newer claim or transition. Delivery count is diagnostic; it is not workflow state. External effects use stable idempotency keys derived from the application, module execution, and effect. A retry may confirm an existing effect, but it must not send or apply it twice.

Coordinator gates

The workflow coordinator evaluates global gates immediately before a handoff. These gates cover conditions that apply across modules, such as cancellation, a terminal application decision, or a global hold. A module reports its local result; it does not bypass these gates or start the next module directly. V1 does not have a separate global workflow-history row. A blocked handoff remains inspectable through the durable module terminal and the current global TenzoStage; a later module migration can add a dedicated cross-module history contract.

Module contract

What a module may change is why the split. Where a continue goes is endings and custom pathways. Resume Review and AI Interview implement activate, claim, transition, and a continue-or-hold terminal. Transition still applies a hop through TenzoStageOrchestrator. See Shared skeleton. A candidate’s place is the module instance, the sit-able stage, and any overlay. The recruiter stage is derived from that place. A move inside the module is decided from the sit-able stage, not from the derived recruiter stage. V1 modules still also provide:
  • a leased, idempotent retry entry point;
  • a compatibility projection contribution; and
  • today’s coordinator-facing result (START_AI_INTERVIEW until TEN-1315).
See Module and stage-orchestrator contract, Resume Review, AI Interview, and Job module composition.