Empirical/ ReferenceBack to guide

Empirical protocol 0.29

Shared contract

Schema 5 uses strict runtime schemas from empirical-sdd/protocol. CLI, MCP, skills, storage, and the TypeScript API share the same workflow, phase, risk, receipt, authorization, impact, policy, and completion definitions. Canonical JSON and prefixed SHA-256 digests make durable documents independently verifiable.

Every current action is an ActionPacket bound to one feature and exact revision. Its essential fields are:

{
  "kind": "action",
  "protocol": "empirical-sdd",
  "schemaVersion": 5,
  "feature": "add-team-invitations",
  "profile": "complex",
  "mode": "normal",
  "riskFloor": "behavioral",
  "interaction": { "questions": "concise" },
  "review": {
    "mode": "bot",
    "reviewerTokenEnv": "EMPIRICAL_REVIEWER_TOKEN"
  },
  "phase": "verify",
  "status": "waiting",
  "revision": 5,
  "completionLevel": { "highest": "implemented" },
  "tracker": {
    "health": "synced",
    "provider": "linear",
    "url": "https://linear.app/example/issue/ENG-42",
    "committedRevision": 5,
    "lastSyncedRevision": 5,
    "pendingRevision": null,
    "changeType": "feature",
    "ticketRequirement": "required",
    "failure": null
  },
  "completion": {
    "available": true,
    "mcpTool": "empirical_complete",
    "requiredFields": ["revision", "outcome", "summary", "receiptIds"]
  }
}

All mutations require the exact revision. A stale caller receives STALE_REVISION; it cannot overwrite newer state.

Project Schema 5 stores interaction.questions as concise | detailed. Action packets always expose the normalized effective value. Missing fields in existing Schema-5 configuration normalize to detailed without a read-time rewrite; new recommended setup explicitly persists concise.

Project Schema 5 also stores review.mode as bot | fresh-context and review.reviewerTokenEnv as an uppercase environment-variable name. New recommended setup persists bot and EMPIRICAL_REVIEWER_TOKEN. A historical Schema-5 config with no review block normalizes to fresh-context without a read-time rewrite. Credential values are runtime-only and never configuration or tool input.

Routing and modes

Routing calculates the strongest matching floor:

contract-neutral < behavioral < sensitive < migration
                 < integration < delivery < publication

Only contract-neutral requests may use Fast. Every other floor promotes to Complex. Normal and YOLO share the same risk classifier and safety floors. YOLO additionally records one immutable authorization document bound to the repository, feature, request digest, ceiling, target branch, agent permission, and optional expiry. Publication cannot be inferred or granted by YOLO.

Workflows

Fast is contract-neutral:

implement → done (verified)

Complex is contract-bearing:

specify → design → plan → implement → context (when repository knowledge is invalid) → verify → review → integrate
                                                            ├─→ done (integrated)
                                                            └─→ deliver → done (delivered)

Delivery exists only when Policy v2 and standing authorization cover it. Publication is a separate explicit, immutable operation after delivery. implemented, verified, integrated, delivered, and published are derived states; callers cannot assert them directly.

Outcomes are passed, failed, awaiting_human, and blocked. Fast failure promotes the same feature to Complex Specify. Verify or Review failure returns to Implement within the configured repair limit. Review permits two automatic repair rounds; a third failure becomes awaiting_human.

Impact and capabilities

Complex Specify freezes a digested impact manifest. Behavioral work must name capabilities and provide valid ADDED, MODIFIED, or REMOVED delta documents. Non-behavioral work must name no capability and provide a regression rationale.

Behavioral capabilities are claimed below the repository Git common directory, so linked worktrees see the same ownership. A claim records each capability's base digest. Integrate replays the reviewed delta against the current target, detects conflicts, validates the candidate in an independent worktree, commits the canonical projection transactionally, and writes an immutable receipt. Direct Schema-4 Archive is retired.

Evidence receipts

empirical_evidence_execute runs one exact Policy v2 argv without a shell. empirical_evidence_collect fingerprints repository-contained artifacts. Both produce immutable receipts containing criteria, evidence kinds, source provenance, command or artifact results, timestamps, and a canonical digest.

empirical_qa_plan derives a canonical verification matrix from the approved criteria, routed risk floor, impact capabilities/surfaces, and Policy v2 command checks. Rows select focused unit, integration, adapter-contract, fault-injection, package-consumer, clean-clone, end-to-end, cross-platform, fresh-context, live, and full-CI acceptance only when applicable. Each criterion must have an executable command or explicit human route; unavailable rows remain visible and block verification.

empirical_qa_execute and empirical_qa_record create the additive qa receipt variant. It binds the matrix, workflow revision, Git commit, source tree, specification, policy, repository, feature, platform/runtime, bounded command or human attempt, duration, artifacts, cleanliness, and every retry/anomaly. A failed, timed-out, cancelled, skipped, unsupported, missing-environment, dirty, mutating, or retried attempt cannot silently become verified. Fresh-context QA does not carry review evidence and cannot replace independent review.

Completion accepts receipt IDs only. It validates digests, criterion coverage, required test/review/UI kinds, artifact containment, source binding, and phase applicability. A copied boolean such as passed: true is never evidence. Integrate, Deliver, and Publish additionally require an explicit passing full-ci QA receipt for their exact current workflow revision, Git commit, and source tree before the first overlay or remote effect.

Code-review evidence additionally requires empirical_review. Its preparation form returns a packet bound to the exact committed base...HEAD diff, ordered criteria, and accepted decisions. Its recording form accepts a structured result from an isolated reviewer invocation and renders one canonical body: verdict heading, one ordered PASS/FAIL bullet per criterion, security/correctness, then design/maintainability. Bot mode first uses one readiness definition to require a runtime credential, repository access, and a login distinct from the author. Fresh-context mode uses no second credential and does not claim independent forge approval.

Authorized delivery opens source and evidence PRs as drafts and returns an exact remote review packet before either can become ready. Request changes leave the PR draft. Approval is current-head-bound; bot mode accepts GitHub reviewDecision == APPROVED or an effective latest non-author approval with no superseding changes requested, covering repositories where the aggregate decision remains empty. Draft, stale-head, failed-check, force, and admin merge paths remain forbidden.

After Implement, Empirical inspects Manifest v2. Source-neutral work advances normally; source changes that leave knowledge stale, missing, invalid, or placeholder-only route to the persisted context phase. Context completion requires an explicit refresh, evidence-backed topic refinement, managed-marker removal, and a second refresh whose report has empty stale, missing, and refinementRequired lists.

External tracker projection

Tracker setup is an optional sidecar to Schema 5. An absent file means no setup choice has been recorded and retains historical local-only runtime behavior; the strict { "schemaVersion": 1, "mode": "disabled" } record means the user explicitly chose No tracking. Neither state triggers a workflow schema migration or provider access. Tracker Policy v1/v2 records choose one GitHub, Linear, or Jira target, store the complete normalized specification, planned, in-progress, verification, review, blocked, and done map, and reference fallback credentials by environment-variable name only. Credential names use the strict uppercase runtime grammar. Policy stores neither values, OAuth connection identity, tokens, nor provider authorization.

Authentication is a runtime-only concern. A trusted host OAuth resolver is queried first and returns only a strictly typed, in-memory provider credential. When authorization is needed, its secret-free descriptor may cross MCP only by explicitly negotiated URL-mode elicitation. Form elicitation and ordinary tool input/output are never credential channels. If OAuth is unavailable or declined, resolution checks one complete injected environment source, then one complete guarded user secrets file source; it never combines a partial Jira identity across sources. The fallback file is outside the repository at ${XDG_CONFIG_HOME:-$HOME/.config}/empirical/secrets.env on POSIX or %APPDATA%\Empirical\secrets.env on Windows. Never paste credentials into chat.

Policy v1 remains readable and byte-preserved. Its effective behavior is manual ticket binding plus the legacy provider projection. Policy v2 adds ticket as off | manual | ensure and visibility as blockers-final | milestones | revisions. off performs no provider access. ensure binds one valid request reference, one exact stable-marker match, or a newly created ticket only after a complete zero-match reconciliation. Ambiguity is durable failure state, never a selection heuristic.

Policy v2 may add a strict complete ticketRules matrix only when ticket is ensure:

{
  "ticketRules": {
    "feature": { "fast": "required", "quick": "required", "complex": "required" },
    "fix": { "fast": "optional", "quick": "required", "complex": "required" },
    "chore": { "fast": "optional", "quick": "optional", "complex": "optional" }
  }
}

Each cell is required, optional, or off. Resolution uses the persisted workflow profile and the same request classifier as worktree routing. Required uses the existing attach/reconcile/guarded-create path. Optional attaches one explicit reference but, with none, returns local-only before credential or provider resolution. Off returns before provider access. Rule-less v2 and all v1 policies keep their prior semantics. Rule-backed status adds changeType and ticketRequirement without changing the existing ticket field.

Discovery is ephemeral and provider-neutral: strict input names a provider and fallback credential-variable names, while runtime resolution remains OAuth-first; output contains canonical/display identities, parent relationships, state semantics/positions, capabilities, completeness, and a digest. Mapping suggestions rank provider semantics and lifecycle position before name refinements, allow shared provider states, and leave tied primary ranks unresolved. Preview repeats discovery and validates the entire selected hierarchy and map before atomic policy persistence.

The local journal commits first. A tracker sync then writes a checksummed feature-local pending operation keyed by feature and revision, converges one target-bound ticket, and advances the binding only after remote success. Policy v2 pending records additionally acknowledge deterministic state-transition, milestone-comment, and artifact effects separately. Effect keys bind provider target, feature, revision, sorted receipt digest, kind, and artifact digest, so partial retry skips confirmed effects. The binding and pending operation retain digests of the exact provider target and effective policy. Reconfiguring the target therefore fails locally instead of combining an old remote identity with a new destination. Changing the status map for the same target invalidates the synchronized fast path and reprojects the committed revision through the new mapping.

Durable pending work is the reconciliation source after interruption. Normal retry resumes that exact operation before deriving newer work. A persisted dispatched flag separates a create that has never been sent from one that may have reached the provider. Sync may send the initial create only while the intent is durably undispatched. Once it is marked dispatched, retry performs a bounded lookup for the exact persisted create marker and never sends that attempt again automatically; without one unique match, explicit attachment is required unless the caller confirms a new attempt while accepting duplicate risk.

Policy v2 milestone comments append phase, revision, progress, completion, summary, blocker, and reviewable artifacts without editing human descriptions. Artifacts can originate only in committed immutable collected receipts and are rechecked for digest, containment, symlinks, media type, secret-like path, count, and size before upload or a commit-pinned durable link. Artifact bytes and credential values are never persisted in tracker state. Existing v1/v2 policy bytes and valid names such as LINEAR_API_KEY remain compatible; only new Linear setup suggests LINEAR_SECRET_KEY.

The remote system is never read as workflow authority. Provider failures therefore change only tracker health (pending or failed) and cannot alter the phase, revision, criteria, or completion level. Status reports policy behavior, remaining effects, committed/last-synchronized/pending revisions, and bounded credential-safe failure context without contacting the provider.

Persistence

.empirical/config.json                         # Schema 5
.empirical/policy.json                         # Policy v2
.empirical/tracker.json                        # disabled setup record or Tracker Policy v1/v2
.empirical/context/manifest.json               # Manifest v2
.empirical/capabilities/<capability>/spec.md
.empirical/specs/<feature>/state.json
.empirical/specs/<feature>/impact.json
.empirical/specs/<feature>/evidence/receipts/executed-<id>.json
.empirical/specs/<feature>/evidence/receipts/collected-<id>.json
.empirical/specs/<feature>/evidence/receipts/qa-<id>.json
.empirical/specs/<feature>/tracker/binding.json
.empirical/specs/<feature>/tracker/pending.json
.empirical/specs/<feature>/events/snapshot.json
.empirical/specs/<feature>/events/NNNNNNNN.json

Events contain sequence, previous-event digest, before/after state digests, and the resulting state. Terminal completion transactionally promotes a verified snapshot and retains one linked compaction-boundary event. State JSON remains a recoverable projection of that authoritative chain.

Isolation and handoff

An unrelated request returns a read-only worktree proposal bound to the base commit, branch, path, active feature, and integrity token. Creation requires literal approval and revalidation. Successful creation records work started and returns continueWithoutApproval: true; that approval is sufficient to enter the checkout and resume the returned action across a host restart without a second "go" prompt. The initial journal still commits before tracker sync, and its early specification/design/plan projection is In Progress. Agent handoff likewise proposes exact cwd, prompt, argv, capability class, and approval token; Empirical never launches the process itself.