haft

repository·main·Indexed 23 days ago

https://github.com/m0n0x41d/haft

A governance substrate designed to make software repositories 'harnessable' for AI-assisted engineering. Using the First Principles Framework (FPF), haft turns engineering decisions and evidence into auditable artifacts, providing a structured layer between LLM agents and the codebase. It features an MCP server for programmatic access, a set of agent skills (e.g., h-reason, h-decide), and Open-Sleigh, a local engineering agent runner.

Tokens
114.8K
Snippets
114
Records
503
Agent score
80%

What's inside haft

  1. Identify Open-Sleigh non-goals

    main

    To avoid scope creep, Open-Sleigh explicitly excludes the following responsibilities:

    • Not a CI system: It invokes existing CI rather than running tests itself.
    • Not a code reviewer: It gates work; it does not perform the review (Codex/Claude performs the review).
    • Not a replacement for Haft: Haft remains the FPF authority and object store.
    • Not a reasoning engine: It orchestrates reasoning agents but does not perform reasoning itself beyond structural/pattern checks.
    • Not Linear-specific: External projection targets are optional.
    • Not Codex-specific long-term: It is designed for Agent.Adapter parity.
  2. Understand the Open-Sleigh technology stack

    main

    Open-Sleigh is built on the Elixir/OTP stack to leverage BEAM supervision trees for process isolation and failure recovery. The architecture follows a functional core/imperative shell pattern where logic is pure (L1–L3) and side effects are isolated to the outermost adapter layer (L4).

    Core Stack Components:

    • Language: Elixir (OTP 26+)
    • Concurrency: Plain OTP (GenServer, Task.Supervisor, Supervisor)
    • Type Checking: Dialyzer with @spec annotations
    • MCP Client: Hand-rolled JSON-RPC 2.0 over stdio
    • HTTP Client: Finch (used for Tracker adapters)
    • Agent Adapters: JSON-RPC over stdio via BEAM Port (e.g., for Codex CLI or Claude Code)
    • Storage (MVP-1): In-RAM orchestrator state with per-ticket Write-Ahead Log (WAL) as JSON-Lines files. haft.sqlite is used by the haft serve child process.
    • CLI: Managed via Mix tasks (mix open_sleigh.start, mix open_sleigh.canary)
    • Telemetry: :telemetry library with an ETS-backed ObservationsBus.
  3. Identify Haft stakeholders and use cases

    main

    Haft is designed for engineers and technical roles to make repositories 'harnessable' through formal specs, decision tracking, and evidence-backed execution.

    Primary Users

    • Engineers using AI agents: Need repositories with formal specs and honest comparisons to enable agentic workflows.
    • Host Agents (e.g., Claude Code, Codex): Require clean tool interfaces and fast responses without workflow interference.
    • Solo Engineers: Need cross-project recall and accumulated judgment in a local-first environment.
    • Tech Leads: Need architectural consistency, decision audit trails, and drift detection.
    • CI/CD Pipelines: Use haft check to verify that decisions are fresh and evidence is current.
    • PR Reviewers: Benefit from seeing .haft/decisions/*.md files directly in diffs to understand rationale alongside code.

    Key Constraints and Design Principles

    • Local-first: Operates without server or cloud services.
    • Solo-first: Designed to be valuable for a single engineer before scaling to teams.
    • Spec-first: Formal target/enabling specs are the required entry point for harness work.
    • Desktop-first: The Desktop App is the primary human interface.
    • Plugin-compatible: The MCP plugin is the primary integration channel (supporting Claude Code and Codex).
    • Single binary: A single haft binary provides the Desktop app, MCP server, CLI, and harness runtime.
  4. Understand Haft's core technology stack

    main

    Haft is built as a local-first, single-binary tool. Its architecture is composed of the following layers:

    • Backend: Go 1.25 (for fast compilation and concurrency).
    • Desktop Frontend: TypeScript + React, wrapped in Tauri v2 (providing a native WebView shell).
    • TUI (Terminal UI): TypeScript + Ink.
    • Database: SQLite (using modernc.org/sqlite for a pure Go, zero-dependency implementation).
    • Search: FTS5 (SQLite built-in) for full-text search and route-aware tiered retrieval.
    • Protocol: MCP (Model Context Protocol) via JSON-RPC over stdin/stdout.
    • Code Analysis: Uses go/parser for Go, tree-sitter (go-tree-sitter) for AST-level symbol hashing, and compile_commands.json for C/C++ module detection.
  5. Understand the Haft System Context and Purpose

    main

    Haft is a project harnessability cockpit and commissioned execution system designed for AI-assisted software delivery. It aims to solve the problem of 'evaporating decisions' and 'rotting evidence' in AI-driven workflows by providing a reasoning persistence layer and formal project specifications.

    Core Workflow (FPF - First Principles Framework): Users operate through five primary modes:

    1. Understand: Grasp the current state.
    2. Explore: Investigate alternatives.
    3. Choose: Make a decision.
    4. Execute: Perform the work.
    5. Verify: Confirm the outcome. (Plus Note for quick captures).

    Key Distinction:

    • Haft owns the semantic authority (decisions, specifications, commissions, and evidence).
    • Open-Sleigh (the current runtime implementation) owns the execution mechanics (orchestration, retries, and agent adapters).
  6. Identify required human confirmation points

    main

    Haft is designed with explicit human-in-the-loop checkpoints. A human principal must explicitly approve the following:

    • Target-system role and environment-change statements.
    • Boundary and out-of-scope statements.
    • Term definitions carrying product or architecture meaning.
    • Creation of active DecisionRecords from spec drafts.
    • WorkCommission scope widening.
    • AutonomyEnvelope approval (for batch/YOLO execution).
    • One-way-door actions (merge, release, tag, external terminal status).
  7. Understand the Haft Artifact Ontology

    main

    Haft uses an ontology of specialized artifact kinds to manage the lifecycle of engineering work, from specification to execution and verification. These artifacts are organized into a Directed Acyclic Graph (DAG) that links requirements (Specs) to problems (ProblemCards), choices (DecisionRecords), execution (WorkCommissions), and proof (EvidencePacks).

    Core Artifact Kinds

    KindPurposeLifecycle
    ProjectSpecificationSetGoverning parseable spec set, term map, and workflow policyDraft → Active → Stale → Superseded/Deprecated
    SpecSectionStable-id unit inside a specificationDraft → Active → Stale → Superseded/Deprecated
    SpecCoverageEdgeLink from spec sections to reasoning artifacts, code, or evidenceActive → Stale/Superseded
    ProblemCardFrames what is broken: signal, constraints, and acceptanceBacklog → In Progress → Addressed
    SolutionPortfolioContains multiple variants for comparisonActive → Superseded/Deprecated
    DecisionRecordRecords rationale, invariants, claims, and rollback plansPending → Shipped → Active → Stale → Superseded/Deprecated
    EvidencePackMeasurement data with a verdict and validity periodActive → Superseded
    NoteMicro-decision with rationaleActive → (auto-expires 90 days) → Deprecated
    RefreshReportImmutable log of lifecycle actions (e.g., waive, reopen)Active

    Execution Records (vNext Model)

    These records represent the integration between Haft and Open-Sleigh for executing decisions.

    RecordPurposeLifecycle
    ImplementationPlanDAG of WorkCommissions with dependencies and evidence requirementsDraft → Approved → Running → Partially Blocked → Completed/Cancelled
    WorkCommissionBounded authorization to execute a DecisionRecord in a specific scopeDraft → Queued → Ready → Preflighting → Running → Completed/CompletedWithProjectionDebt/Failed/Blocked/Cancelled/Expired
    RuntimeRunA single execution attempt against a WorkCommissionClaimed → Running → Passed/Failed/Cancelled/Stalled
    ExternalProjectionIdempotent external tracker for observersDesired → Drafted → Published → Synced/Drifted/Blocked/ProjectionDebt
    AutonomyEnvelopeHuman-defined permission bounds for batch/YOLO executionDraft → Approved → Active → Exhausted/Revoked/Expired
  8. Understand the Core Domain Artifacts

    main

    Haft operates on an artifact graph where every reasoning object is a persisted Artifact. When working with the system, use these specific types to ensure semantic consistency:

    • ProblemCard: Frames what is broken (signals, constraints, optimization targets, acceptance criteria, etc.).
    • SolutionPortfolio: Contains 2+ distinct variants for a problem, including comparison dimensions and results.
    • DecisionRecord: Records what was chosen and why (selected variant, rationale, invariants, claims, rollback, etc.).
    • EvidencePack: Measurement data attached to a decision (type, verdict, congruence level, valid_until).
    • Note: A micro-decision artifact for quick rationale validation. These auto-expire in 90 days.
    • RefreshReport: Documents lifecycle actions like waive, reopen, supersede, or deprecate.

    Note: Do not use these terms interchangeably with generic terms like 'issue', 'ticket', 'plan', or 'comment'.

  9. Configure and Implement Gates

    main

    Gates are functions used to validate transitions between phases. They are defined as PhaseOutcome.t() → GateResult.t(). There are three distinct GateKind types:

    1. StructuralGate: A pure L2 function that checks for field presence, type shape, or graph-level invariants. It does not call LLMs or humans.
    2. SemanticGate: An effectful L2 contract invoked via a JudgeClient. It returns a result containing {verdict, cl, rationale}.
    3. HumanGate: A gate that is triggered rather than computed. It blocks a transition until an external /approve signal is received.

    When implementing or evaluating gates, use JudgeCalibration (golden-set evidence) to measure performance (FP rate, FN rate, CL) against a GoldenSet (a hand-labelled corpus of $\ge 20$ artifacts).

  10. Handle In-RAM state loss on crash

    main

    In the current MVP-1 version, all Orchestrator state is stored in-process Erlang maps.

    What is lost on crash/restart:

    • In-flight AgentWorker state.
    • Unwritten Haft artifacts (though these are mitigated by the Write-Ahead Log (WAL) as defined in HAFT_CONTRACT.md §3).

    What is recovered:

    • Haft remains the authoritative object store for WorkCommissions and persistent evidence.
    • Workers will automatically respawn on the next poll tick if the commission remains runnable.

    Note: SQLite persistence for engine state is planned for MVP-2.

  11. Handle uncertain reasoning in h-explore results

    main

    To prevent the operator from rubber-stamping potentially incorrect reasoning, bucket your arguments by confidence level. Lead with the uncertain items.

    Bucketing Strategy:

    • ⚠ Uncertain — scrutinize: Arguments you are not sure are correct or load-bearing. Surface these FIRST and prominently.
    • Helpful (secondary) / overlaps the obvious: Arguments that are secondary or obvious. List these compactly for skimming.

    Rule: Never hide a low-confidence argument in the 'helpful' bucket just to look tidy. If nothing is uncertain, explicitly state that.

  12. Surface context assumptions using FRAME-04

    main

    To prevent reasoning from collapsing when reality differs from expectations, explicitly state context assumptions (K). This includes:

    • Given Information: Environment, prior behavior, or operating regimes taken as fact.
    • Falsification Criteria: Identify what specific observation would prove an assumption false.