Architecture

Cross-Cutting Layer

The control plane that keeps Testonaut understandable, auditable, and safe to run in an unattended pipeline. Agents may reason, retrieve, explore, and repair — but every hand-off and every consequential action must leave a structured trail.
Cross-cutting flow: the four agent phases feed validated artifacts, the audit log, the cost ledger, redaction, and Langfuse telemetry
Every phase boundary is constrained by validated artifacts, provenance, audit, cost governance, redaction, and telemetry.

What the layer provides

ConcernWhy it existsMain implementation
Bounded artifactsPrevents agent output from becoming an unreviewable black box.Zod schemas plus per-artifact writers.
ProvenanceShows where evidence, scenarios, uploads, and tool calls came from.provenance.tools[], source evidence, retrieval citations, evidence graph.
WarningsKeeps non-fatal issues visible without crashing the whole run.warnings[] on phase artifacts.
Audit logRecords consequential actions for governance and review.Append-only audit.jsonl.
Cost ledgerTracks per-run and per-day spend.Append-only cost-ledger.jsonl.
Budget gatePrevents unattended runs from overspending.policy.budgets in .agents/testonaut.config.json.
Langfuse telemetryTracks LLM calls, sessions, tokens, cost, latency, inputs, outputs, and phase metadata.OpenTelemetry + OpenInference export to Langfuse.
RedactionPrevents secrets and PII from leaking into logs, telemetry, audit, or comments.Built-in redactor plus policy.redactPatterns.

Zod artifacts

Zod artifacts are the main contract between phases. Each phase emits a structured JSON artifact that must validate before it is written or passed forward. This gives Testonaut three properties:

  • Determinism at the boundary: the next phase receives a known shape, not arbitrary model text.
  • Traceability: scenarios, source evidence, links, warnings, and tool calls remain inspectable after the run.
  • Versioning: each artifact carries schemaVersion, so future migrations can be handled intentionally.
Artifact lifecycle: agent output is validated against a Zod schema before being written and passed forward
The artifact lifecycle: phase output must validate against its Zod schema before it is written or handed to the next phase.

Main artifacts

ArtifactProduced byWritten as
ContextPackPhase 1 Researcherout/<KEY>/context.json and context.md
TestDesignPackPhase 2 Test Design Agenttest-design.json, test-design.md, feature files, optional manual-tests.md
ImplementationPackPhase 3 Code Agentimplementation.json and implementation.md
LearningRecordSetPhase 4 Learning EngineProposed guideline changes
ReadinessReportReadiness checksCLI output/report
EvalReportEvaluation harnessCLI output/report

Why JSON plus Markdown

Each major pack is written twice: JSON is the machine-readable source of truth for the next phase and for audits; Markdown is the human-readable companion for review, pipeline artifacts, and debugging.

Each artifact is written as machine-readable JSON and a human-readable Markdown companion
Every pack lands twice: JSON for machines and audits, Markdown for humans.

Audit log

The audit log records consequential actions as append-only JSONL — used for governance and review, not as input to future decisions. Default path out/audit.jsonl, overridable with TESTONAUT_AUDIT_LOG. Each line is one event:

{
  "at": "2026-06-17T12:00:00.000Z",
  "action": "pr.raised",
  "actor": "implement-tests",
  "target": "FINT-1056",
  "detail": {
    "status": "raised",
    "url": "https://...",
    "branch": "testonaut/FINT-1056"
  }
}
ActionMeaning
run.startedA CLI workflow started.
design.createdA validated TestDesignPack was created.
xray.uploadedTests were uploaded or applied to Xray.
pr.raisedA pull request was raised, updated, found, skipped, or failed.
pr.fix-appliedPhase 4 applied or attempted a PR feedback fix.
rule.proposedPhase 4 proposed a Markdown guideline learning PR.
budget.breachedA run or day cost budget was exceeded.
run.completedA workflow completed and wrote final status.

Reading the audit log

testonaut audit
testonaut audit --target FINT-1056
testonaut audit --action pr.raised --limit 20
testonaut audit --json

Redaction before audit

Audit entries pass through the redactor before they are appended, protecting common secret and PII shapes: OpenAI and Anthropic API keys, GitHub tokens, Slack tokens, AWS access key ids, bearer/basic auth headers, private keys, email addresses, and password / secret / token / api_key style values. Project-specific patterns can be added:

{
  "policy": {
    "redactPatterns": [
      "customer-[0-9]{6}",
      "internal-account-[A-Za-z0-9-]+"
    ]
  }
}

Invalid custom regex patterns are skipped rather than crashing the run.

Cost ledger and budgets

Testonaut tracks LLM spend in an append-only cost ledger at out/cost-ledger.jsonl (override with TESTONAUT_COST_LEDGER). Each entry records the timestamp, calendar day, measured or estimated run cost, issue key, and the CLI command that produced the cost.

BudgetBehavior
maxCostPerRunUsdCompares the current run cost against the per-run limit.
maxCostPerDayUsdSums today's entries from the ledger and compares against the daily limit.
BreachEmits budget.breached to the audit log and warns or halts depending on workflow stage.

How costs are calculated

Testonaut prefers exact cost when the SDK provides it. When exact cost is unavailable, it estimates from token counts and a model price table. The estimator understands uncached input tokens, cached input tokens, Anthropic cache-creation tokens, output tokens, and reasoning tokens where reported. Custom or Azure deployment names can be priced with:

Cost calculation: exact SDK cost preferred, otherwise a cache-aware estimate from token counts and the model price table
Cost resolution: exact SDK cost when available, otherwise a cache-aware estimate from token counts and the model price table.
TESTONAUT_MODEL_PRICES='{"my-azure-deployment":{"input":1.75,"cachedInput":0.175,"output":14}}'

Langfuse observability

Testonaut uses OpenTelemetry and OpenInference instrumentation, exported to Langfuse. Telemetry is optional; when disabled, the same workflows run without loading the OpenTelemetry stack. Minimum environment:

OTEL_ENABLED=true
OTEL_PROVIDER=langfuse
OTEL_PUBLIC_KEY=<langfuse-public-key>
OTEL_SECRET_KEY=<langfuse-secret-key>
OTEL_ENDPOINT=https://cloud.langfuse.com
OTEL_PROJECT_NAME=testonaut

If OTEL_SESSION_ID is not provided, ticket workflows use the Jira issue key as the session id — jira:<ISSUE-KEY> — grouping the Researcher, Test Design, Implementation, and Feedback spans for one ticket into one Langfuse session.

What Langfuse receives

Langfuse telemetry: sessions per Jira issue with workflow, phase, model, token, cost, and latency attributes
One session per Jira issue groups the spans of every phase, with model, token, cost, and latency attributes on each generation.
DataWhere it appears
Session and user idsession.id, user.id and Langfuse equivalents.
Workflow, issue, phaseworkflow.issue, workflow.phase (implementation, healing, PR feedback fix).
Model and tokensModel name plus input, output, cached-input, cache-creation, and reasoning tokens.
Cost and latencyExact SDK cost or cache-aware estimate via cost_details; span duration.
LLM input/outputText-client spans include prompt and response payloads for design/research calls.

Why Langfuse and artifacts are both needed

  • Langfuse answers operational questions: how many LLM calls per ticket, which phase spent the most tokens, did cached input reduce cost, how long did each call take.
  • Artifacts answer product and audit questions: which Jira comments and Confluence pages were used, which AC produced this scenario, which Xray tests were created, which files changed, which warnings were attached.
Langfuse answers operational questions while artifacts answer product and audit questions
Two complementary records: Langfuse for operational questions, artifacts for product and audit questions.

Redaction and secret handling

The layer assumes secrets may appear in tool responses, command output, environment-derived values, or reviewer comments. Before text leaves the process, Testonaut applies redaction to logs, telemetry span payloads, audit entries, written artifacts, and PR comments. MCP server configuration also supports environment-variable expansion so API tokens can live in .env or pipeline secret variables rather than in repository config.

Redaction pipeline: built-in and project-specific patterns applied before logs, telemetry, audit entries, artifacts, and PR comments leave the process
The redactor sits in front of every outbound surface: logs, telemetry, audit entries, artifacts, and PR comments.

Configuration summary

Repository config

{
  "schemaVersion": "1.0.0",
  "product": "example-product",
  "policy": {
    "gates": {
      "acCoverage": "required",
      "riskCoverage": "warn",
      "humanReviewBeforeUpload": true,
      "humanReviewBeforePr": false
    },
    "budgets": {
      "maxCostPerRunUsd": 5,
      "maxCostPerDayUsd": 25
    },
    "redactPatterns": []
  },
  "pr": {
    "mention": "@testonaut",
    "maxIterationsPerPr": 5
  }
}

This config is itself Zod-validated. Invalid JSON or invalid fields fail fast with readable validation errors.

Runtime environment

VariablePurpose
OTEL_ENABLEDEnables telemetry.
OTEL_PROVIDER=langfuseSelects Langfuse export.
OTEL_PUBLIC_KEYLangfuse public key.
OTEL_SECRET_KEYLangfuse secret key.
OTEL_ENDPOINTLangfuse endpoint. Defaults to Langfuse Cloud when omitted.
OTEL_PROJECT_NAMEProject name shown in telemetry.
OTEL_SESSION_IDOptional fixed session id. Otherwise the Jira issue session is used.
OTEL_USER_IDOptional user attribution. Pipeline user variables are also detected.
TESTONAUT_AUDIT_LOGOptional audit log path override.
TESTONAUT_COST_LEDGEROptional cost ledger path override.
TESTONAUT_MODEL_PRICESOptional JSON price table override.

Failure and safety behavior

SituationBehavior
Artifact does not validateThe phase fails before hand-off.
Optional context fetch failsThe run records a warning and continues when possible.
Audit write failsThe audit helper swallows the write error so the run is not failed by a logging problem.
Cost ledger missingDay cost reads as 0; future writes recreate the ledger.
Budget breachedEmits budget.breached; implementation can halt before overspending further.
Langfuse disabledNo telemetry stack is initialized.
Langfuse flush failsWarning is printed; process still exits.
Missing Langfuse keysLangfuse telemetry configuration fails loudly when enabled.
Invalid redaction regexPattern is skipped; run continues.

Why this layer matters

Artifacts make agent work reviewable; audit logs make consequential actions accountable; cost controls make unattended execution safe; Langfuse makes behavior observable; and redaction protects sensitive data. Together, these controls turn the four-phase agent into a governed workflow — flexible enough to research, design, implement, and learn, but bounded enough to audit, operate, and trust.