Empirical/ ReferenceBack to guide

Architecture

Empirical 0.29 is a TypeScript library, Node.js CLI, stdio MCP server, one explicit global Init skill, and a repository-local automatic workflow over one Schema 5 model.

Boundaries

Legacy discovery, decision, agent handoff, selector, setup, and worktree modules remain focused owners of those boundaries.

Ownership model

Git common directory
└── capability claims shared by all linked checkouts

repository checkout
├── Schema-5 config + Policy v2 + Manifest v2
├── marker-owned automatic workflow dispatchers and local skills
├── optional disabled setup record or secret-free Tracker Policy v1/v2
├── living capability projections
├── discovery records
└── selected feature
    ├── spec + design + decisions + plan + impact + deltas
    ├── optional tracker binding + durable transition/comment/artifact ledger
    ├── immutable evidence/integration/delivery receipts
    └── state projection + hash journal + terminal snapshot

Checkout selection lives in the checkout's absolute Git directory. Claims live under the common directory. This separation prevents two linked worktrees from selecting each other's workflow state while still serializing changes to the same living capability.

Transition integrity

A workflow transition acquires an ownership-aware feature lock, verifies the exact revision and immutable artifacts, prepares any rollback-capable effect, appends a linked event, writes the state projection atomically, and releases only its own lock. Terminal paths compact the chain to a verified snapshot and boundary. Stale-lock recovery checks age, process liveness, inode/device identity, and ownership token.

Migration stages, markers, and backups use reserved top-level names. Before a marker exists, candidate transform/validation failure removes the exact owned stage. After a marker exists, recovery alone controls stage/backup promotion. Knowledge, evidence hashing, and source overlays exclude these transaction trees; Doctor reports unmarked survivors without deleting them.

Integration adds a second transaction boundary. It verifies Git repository identity, replays deltas from captured bases, temporarily projects candidates into a different worktree, overlays committed feature changes since the merge base plus bounded working changes, detects independent target divergence, runs every exact Policy command there, restores the target, then promotes source capability projections with rollback and records a receipt. The feature is not integrated until that receipt and state transition both succeed.

External tracking is a separate one-way projection boundary. Every workflow transition commits its local journal and state projection first. A later tracker sync resumes durable pending work or snapshots that committed revision into a checksummed pending record. A pure resolver combines the existing request change classifier with the persisted workflow profile. Required work validates a request reference, performs complete stable-marker reconciliation, and creates only on one proven zero-match path; optional unreferenced work and off work branch before authentication. It then converges provider state, append-only milestone comments, and receipt-approved evidence through individually acknowledged deterministic effects before advancing the binding. Policy v2 Linear updates never include description content. Binding target drift, incomplete pagination, marker ambiguity, or unsafe evidence fails closed; provider failure cannot roll back, demote, or block the local state machine.

Tracker Policy v2 can explicitly change that last availability choice for required work with enforcement: strict. The provider still has no inbound state authority: a pure gate is derived from locally configured policy, deterministic ticket requirement, validated binding, current/acknowledged revision, and durable pending effects. The same gate drives action packets and core mutation guards. Initial identity state remains local-first for exact idempotency; every later revision closes the gate until sync. Terminal journals can be synchronized by exact feature id, and Begin performs a bounded local preflight so a crash cannot hide an unresolved strict final projection. The preflight uses a sticky secret-free per-feature obligation marker, so enabling strict later does not retroactively gate historical best-effort work.

Authentication remains outside that durable projection. A trusted host OAuth resolver provides an ephemeral typed credential and, when needed, a validated secret-free URL handoff. MCP uses the handoff only for explicitly negotiated URL-mode elicitation. Resolution then falls back atomically to injected host environment values and a guarded per-user secrets file; none of those values enter policy, workflow state, tool results, or chat. Jira's typed request context keeps OAuth Bearer/cloud API traffic distinct from tenant-origin Basic fallback traffic across every adapter path.

Delivery and publication

Delivery requires Policy v2, repository-bound authorization, a verified integration, an exact target branch, and declared checks. It converges a draft source PR, returns an exact remote review packet, accepts only a canonical current-head bot or fresh-context result, makes an approved head ready, and merges it without admin or force. It then creates a source-merge binding and repeats the draft/review gate for the evidence PR. Request changes keep the PR draft and route at most two repair rounds before a human is required. Both merge commits and command receipts are digested in the delivery receipt.

Publication is intentionally outside the workflow's inferred path. A caller must explicitly provide an exact package, semantic version, dist-tag, merged commit, literal approval, and an authorization bound to that exact request. Empirical independently inspects and then re-inspects remote Git, GitHub, and npm state. Conflicting tags, releases, versions, or dist-tags stop instead of being replaced.

Repository release automation preserves that invariant with a different, explicit authorization source. Ordinary source/evidence delivery targets develop. A read-only Release Gate runs on the exact GitHub merge candidate for the sole develop to main release PR and validates branch provenance, versions, packed contents, changelog/migration structure, remote state, clean CI, and a clean tracked tree. An unchanged exact protected merge with no effective CHANGES_REQUESTED review then supplies narrow authorization for that PR number, merge commit, derived version/tag/notes, package integrity, and latest; it does not alter the generic Empirical publish operation or make arbitrary main pushes publishable.

The ordinary authorizer exhaustively paginates GitHub's review history and reduces each reviewer's latest decisive state. Failed pagination, malformed records, duplicate identities, or an effective change request fail before immutable effects; comments cannot clear a prior change request.

An administrator-only emergency branch remains disabled unless an exact repository Actions variable is enabled and the protected npm environment has admitted the workflow run. It adds an explicit incident audit boundary: a short-lived canonical receipt binds actor, open incident, PR, protected two-parent merge, version, integrity, required checks, justification, and nonce. The adapter proves those live facts, denies CHANGES_REQUESTED and historical v0.29.0, and writes pre/post audit comments. Closed-PR events and ordinary dispatches cannot select this branch implicitly.

The existing trusted-publisher identity, .github/workflows/publish.yml, owns the complete remote sequence so it does not depend on a GitHub Release created with GITHUB_TOKEN recursively starting a second workflow. Its jobs recompute the same candidate at the exact commit and split permissions:

merged release PR / exact manual retry
├── ordinary authorize (protected merge + contents/PR read + clean CI)
└── explicit emergency authorize (npm environment + policy + admin/incident/check receipt)
    └── exact authorization selector (no permissions)
        └── GitHub prefix (contents write, no OIDC)
        ├── annotated v<version> tag
        └── non-draft Release with exact changelog body
            └── npm preflight (read-only, complete clean CI, no OIDC)
                └── authorized-SRI tarball publish (minimal read + OIDC)
                    └── provenance verification (read-only, no OIDC)
                        └── emergency incident outcome audit (issues write only)

Remote state is the retry journal. The deterministic planner accepts only absent-all, exact tag, exact tag-plus-Release, or fully converged states. Every effect is re-observed after a success or error, so a lost response becomes an existing exact prefix rather than a duplicate request. Gaps, conflicts, malformed observations, missing provenance, or divergent latest stop without delete, edit, force, replacement, or token-based repair. Manual dispatch names only the original PR and merge SHA; all release identity is re-derived.

Knowledge and diagnostics

Manifest v2 records normalized source fingerprints and generated-page source sets. Retrieval returns only fresh, semantically refined pages. Managed or exact legacy placeholder topics in a nonempty repository are reported through refinementRequired and withheld from usable context. After source-changing Implement work, the state machine conditionally inserts Context: the host agent refreshes inventory, refines topics from inspected evidence, removes managed markers, and refreshes again before Verify or Done. Doctor reports stale, missing, invalid, and refinement-required knowledge without mutation. For a completed Schema 5 setup it also reports missing, drifted, or unsafe project integrations; explicit Init performs the ownership-aware repair and Doctor then verifies readiness.

Package surface

The supported exports are the main library, ./protocol, ./mcp, and ./integrations. The build emits Node-compatible ESM and declarations. CI tests supported Node lines 22, 24, and 26 and enforces distribution, consumer, registry-consistency, aggregate coverage, and per-module coverage gates.

The public lifecycle CLI exposes Install, Update, and Uninstall. Uninstall owns only catalog-derived global skill paths, valid owner-stamped selection metadata, and the global package. Repository discovery and project .empirical or MCP mutation are outside that command's authority.

The installed global skill is empirical-init, which is explicit-only where a host supports invocation policy metadata and narrowly setup-scoped everywhere else. Initialization writes the detailed empirical workflow into project skill directories and short dispatchers into supported repository instruction files. Those dispatchers activate only for change requests when Schema 5 config is valid and setup is complete; read-only requests and uninitialized repositories stay outside the state machine.