Skip to content

Pipeline map (printable)

The full picture of gitoma run and its variants (gitoma docs, future verticals), with every layer that sits between the LLM output and a committed patch. Designed to be printed to one or two pages and kept next to the keyboard.

Top level

mermaid
flowchart TD
  Start([gitoma run / gitoma docs])
  PreFlight[Pre-flight<br/>config + GH access + LM Studio health]
  Phase1[PHASE 1 - ANALYSIS<br/>11 metric analyzers run]
  Phase2[PHASE 2 - PLANNING]
  Phase3[PHASE 3 - EXECUTION<br/>per subtask]
  Phase4[PHASE 4 - PULL REQUEST<br/>push + open PR]
  Phase5[PHASE 5 - SELF-REVIEW<br/>adversarial critic on PR diff]
  Phase6[PHASE 6 - CI WATCH<br/>optional fix-ci]

  Start --> PreFlight --> Phase1 --> Phase2 --> Phase3 --> Phase4 --> Phase5 --> Phase6

PHASE 2 — Planning (deep)

The LLM planner is sandwiched between three deterministic layers. Audit-side filter narrows what the planner sees; post-plan filters clean what it emits.

mermaid
flowchart TD
  Audit[MetricReport from PHASE 1<br/>11 metrics]
  ScopeM{GITOMA_SCOPE<br/>set?}
  ScopeMet[scope.metrics_filtered<br/>keep only docs+readme<br/>for gitoma docs]

  Occam1[Occam GET /repo/fingerprint<br/>declared deps + frameworks + entrypoints]
  Occam2[Occam GET /repo/agent-log<br/>since=24h limit=20]

  PlannerLLM[planner.plan LLM call<br/>prompt: report + brief + fingerprint + prior_runs<br/>+ HARD RULE README + scope rules]

  LayerA[Layer-A synthesize_real_bug_task<br/>if test_results=fail and no plan task<br/>touches source under test, prepend T000]
  Layer2[Layer-2 rewrite_plan_in_place<br/>map T001 file_hints test paths to source]
  LayerB[Layer-B banish_readme_only_subtasks<br/>drop subtasks whose only file_hint is README]
  G9[G9 occam filter<br/>since=7d limit=200<br/>drop subtasks failed N+ times]
  ScopeP{GITOMA_SCOPE<br/>set?}
  ScopePlan[scope.plan_filtered<br/>drop subtasks with non-doc file_hints<br/>for gitoma docs]

  FinalPlan[Final TaskPlan]

  Audit --> ScopeM
  ScopeM -->|no| Occam1
  ScopeM -->|yes docs| ScopeMet --> Occam1
  Occam1 --> Occam2 --> PlannerLLM
  PlannerLLM --> LayerA --> Layer2 --> LayerB --> G9 --> ScopeP
  ScopeP -->|no| FinalPlan
  ScopeP -->|yes docs| ScopePlan --> FinalPlan

PHASE 3 — Worker apply pipeline (deep)

Per subtask, the worker calls the LLM, applies patches, then runs each guard in order. Any guard fail = revert + retry with feedback. Only after every guard passes does the patch commit.

mermaid
flowchart TD
  WorkerLLM[worker LLM call<br/>prompt: subtask + scope rules + axioms<br/>+ retry feedback if any]
  Repair[LLM-side JSON repair<br/>1 markdown fence strip<br/>2 trailing comma<br/>3 bare quote escape<br/>4 bare newline]
  Patcher[patcher.apply_patches<br/>G1 manifest hard-block<br/>denylist + containment + size cap]
  G10[G10 schema validator<br/>JSON Schema for ESLint Prettier tsconfig<br/>github-workflow Cargo etc]
  G11[G11 content grounding<br/>doc framework mentions<br/>vs fingerprint declared]
  G12[G12 config grounding<br/>JS config package refs<br/>vs npm declared]
  G13[G13 doc preservation<br/>code-block char loss<br/>literal newline corruption]
  G14[G14 URL grounding<br/>DNS plus HEAD for added URLs<br/>filesystem for added paths]
  G7[G7 AST-diff<br/>Python top-level def preservation]
  G2[G2 syntax check<br/>TOML JSON YAML Python parse]
  Build[BuildAnalyzer<br/>cross-file compile check]
  G8[G8 test regression gate<br/>baseline pass set must stay green]
  Psi[Psi-lite gate optional<br/>Gamma grounding minus lambda Omega slop<br/>opt-in via GITOMA_PSI_LITE]
  Commit[git commit]
  Observation[POST /observation to Occam<br/>outcome + failure_modes + touched_files]

  WorkerLLM --> Repair --> Patcher --> G10 --> G11 --> G12 --> G13 --> G14 --> G7 --> G2 --> Build --> G8 --> Psi --> Commit --> Observation

  Patcher -.fail.-> Revert[revert touched + retry with feedback]
  G10 -.fail.-> Revert
  G11 -.fail.-> Revert
  G12 -.fail.-> Revert
  G13 -.fail.-> Revert
  G14 -.fail.-> Revert
  G7 -.fail.-> Revert
  G2 -.fail.-> Revert
  Build -.fail.-> Revert
  G8 -.fail.-> Revert
  Psi -.fail.-> Revert

PHASES 4-5 — PR + critics

mermaid
flowchart TD
  Push[git push origin branch]
  OpenPR[gh pr create<br/>structured body with metrics before/after<br/>per-task per-subtask status]
  Panel[Critic Panel review<br/>3 personas dev arch contributor<br/>advisory only]
  Devil[Devil critic<br/>adversarial single-pass]
  Refiner[Refiner propose patch<br/>same guards G2 G7 G10-14 applied to refiner output]
  MetaEval[Meta-eval LLM judge<br/>refiner v1 vs v0 winner]
  QA[Q&A self-consistency<br/>3 Pareto questions Defender answers<br/>gated apply via BuildAnalyzer]
  SelfCritic[Self-critic adversarial<br/>posts review comment on PR]

  Push --> OpenPR --> Panel --> Devil --> Refiner --> MetaEval --> QA --> SelfCritic

Verticals (current + planned)

GITOMA_SCOPE=<vertical> activates audit + plan filters. Today only docs is shipped; the others are planned with the same shape.

mermaid
flowchart LR
  Run[gitoma run<br/>full pipeline]
  Docs[gitoma docs<br/>SHIPPED<br/>scope=docs<br/>md mdx rst txt + docs/]
  Quality[gitoma quality<br/>PLANNED<br/>scope=quality<br/>linter + format configs]
  Tests[gitoma tests<br/>PLANNED<br/>scope=tests<br/>tests/** add only]
  Fix[gitoma fix --issue N<br/>PLANNED<br/>scope=issue<br/>files cited in issue body]
  Migrate[gitoma migrate --to vitepress<br/>PLANNED<br/>scope=docs + template]

  Run --- Docs --- Quality --- Tests --- Fix --- Migrate

Occam Observer — companion side

Occam is the optional ground-truth + cross-run learning gateway gitoma consumes when OCCAM_URL is set. Three reads + one write per gitoma run; everything else fail-open.

Occam internals

mermaid
flowchart TB
  subgraph Occam["Occam Observer process - Go"]
    Gateway["HTTP Gateway port 9999<br/>FastAPI-equivalent in Go"]

    subgraph Handlers["Coordination handlers"]
      H1["GET /repo/fingerprint<br/>parse Cargo.toml package.json<br/>pyproject.toml go.mod<br/>infer frameworks from deps"]
      H2["GET /repo/agent-log<br/>SELECT from observations<br/>filtered by since + limit + run_id"]
      H3["POST /observation<br/>INSERT into observations<br/>closed-set outcome + failure_modes"]
      H4["GET /repo/context<br/>git ls-files languages<br/>+ git log churn<br/>+ stable files"]
      H5["GET /repo/blame and churn<br/>git wrappers"]
      H6["GET /file/imports and exports<br/>Python AST analyzer"]
      H7["claim endpoints<br/>multi-agent file lock"]
    end

    subgraph Storage["Persistence"]
      DB[("SQLite WAL<br/>observations table<br/>claims table")]
      State["occam_state.json<br/>+ snapshots.db<br/>filesystem snapshots"]
    end

    subgraph Engine["telemetry_observer.sh"]
      Watcher["bash engine<br/>fswatch or inotify<br/>debounced file watcher"]
    end

    Filesystem[("target repo<br/>read-only")]

    Gateway --> H1
    Gateway --> H2
    Gateway --> H3
    Gateway --> H4
    Gateway --> H5
    Gateway --> H6
    Gateway --> H7

    H2 -->|read| DB
    H3 -->|write| DB
    H7 -->|read and write| DB

    H1 -->|read| Filesystem
    H4 -->|git CLI| Filesystem
    H5 -->|git CLI| Filesystem
    H6 -->|read| Filesystem

    Watcher -->|writes| State
    Gateway -->|spawns| Watcher
  end

  Client["gitoma client<br/>OccamClient.py"] -->|HTTP| Gateway

Per-run gitoma ↔ Occam wire (sequence)

mermaid
sequenceDiagram
  autonumber
  participant Run as gitoma run
  participant Cli as OccamClient
  participant Gw as Occam Gateway
  participant Db as SQLite TSDB

  Note over Run,Db: PHASE 2 — PLANNING
  Run->>Cli: get_repo_fingerprint(target)
  Cli->>Gw: GET /repo/fingerprint?target=...
  Gw->>Gw: parse manifests + infer frameworks
  Gw-->>Cli: {commit_sha, langs, stack, declared_deps,<br/>declared_frameworks, entrypoints, manifests}
  Cli-->>Run: fingerprint dict

  Run->>Cli: get_agent_log(since=24h limit=20)
  Cli->>Gw: GET /repo/agent-log?since=24h&limit=20
  Gw->>Db: SELECT * FROM observations WHERE ts >= ...
  Db-->>Gw: rows
  Gw-->>Cli: [observations]
  Cli-->>Run: prior_runs list

  Run->>Run: planner.plan(report+brief+fingerprint+prior_runs)
  Run->>Run: Layer-A real-bug synth + Layer-B + scope filter

  Run->>Cli: get_agent_log(since=7d limit=200)
  Cli->>Gw: GET /repo/agent-log?since=7d&limit=200
  Gw->>Db: SELECT (wider window)
  Db-->>Gw: rows
  Gw-->>Cli: [observations]
  Cli-->>Run: agent_log_g9
  Run->>Run: G9 occam_filter drops failing-history subtasks

  Note over Run,Db: PHASE 3 — EXECUTION (per subtask)
  loop every subtask
    Run->>Run: worker apply + guards
    alt subtask done success
      Run->>Cli: post_observation({outcome:success, ...})
    else subtask failed
      Run->>Cli: post_observation({outcome:fail, failure_modes:[...]})
    end
    Cli->>Gw: POST /observation
    Gw->>Db: INSERT INTO observations
    Db-->>Gw: id
    Gw-->>Cli: {id}
  end

Occam endpoints — what gitoma uses + what's available

EndpointMethodUsed by gitomaReturns
/repo/fingerprint?target=GETplanner prompt + G11/G12/G14 + Ψ-lite Γsnapshot dict
/repo/agent-log?since=&limit=&run_id=&agent=GETplanner prior-runs block + G9 filterlist of observations
/observationPOSTafter every subtask outcome{id}
/repo/context?target=GET(available, not currently consumed)langs + churn + stable files
/repo/blame/<path>?target=GET(available)per-line blame + reverted_by
/repo/churn/<path>?target=&since=GET(available)mods + reverts count
/diff?target=&base=&branch=GET(available)ast_top_level_delta
/file/fingerprint?path=GET(available, file-level)ast_hash + content_hash
/file/imports?path=GET(available, Python AST)imports list
/file/exports?path=GET(available, Python AST)exports list
/symbol?path=&name=GET(available)signature + callers
/agent/identity/<commit>GET(available)which agent committed
/contractGET(available)gateway contract spec
/claimGET/POST/DELETE(available, multi-agent lock)claim state
/healthz /readyz /metricsGET(operational)liveness + Prometheus

Fail-open contract

Every OccamClient method returns a benign default on:

  • HTTP timeout (2s default)
  • Connection refused / DNS fail
  • 4xx / 5xx response
  • Schema mismatch (wrong shape)
  • JSON parse error

Defaults: None for fingerprint/context, [] for agent-log, None for observation id. The gitoma pipeline NEVER raises because Occam is unavailable — the integration is purely additive.

Layer reference table

LayerLives inFires whenAction on fail
Audit metric filterplanner/scope_filter.pyGITOMA_SCOPE setdrop non-relevant metrics from MetricReport
Planner LLM callplanner/planner.py + planner/llm_client.pyalwaysretry with JSON repair, surface LLMError
Layer-A real-bug synthplanner/real_bug_filter.pytest_results.status == failprepend T000 task
Layer-2 test→source rewriteplanner/test_to_source.pyT001 file_hints all test filesrewrite hints to source
Layer-B README banishplanner/real_bug_filter.pysubtask file_hints == README onlydrop subtask
G9 Occam filterplanner/occam_filter.pysubtask file_hints failed N+ timesdrop subtask
Plan scope filterplanner/scope_filter.pyGITOMA_SCOPE setdrop non-scope subtasks
LLM JSON repairplanner/llm_client.py _attempt_json_repairjson.loads raisesstrip fence + trailing comma + bare quote + bare newline
G1 manifest blockworker/patcher.pymanifest edit not in file_hintsreject patch
Patcher denylist + containmentworker/patcher.pypath in denylist or escapes rootreject patch
G10 schema validatorworker/schema_validator.pyfile matches PATH_MATCHERSrevert+retry on schema fail
G11 content groundingworker/content_grounding.pydoc file modifiedrevert+retry on framework mention not in fingerprint
G12 config groundingworker/config_grounding.pyJS config file modifiedrevert+retry on npm ref not in package.json
G13 doc preservationworker/doc_preservation.pydoc file modifiedrevert+retry on code-block loss or literal \n
G14 URL groundingworker/url_grounding.pydoc file modifiedrevert+retry on added URL DNS/HEAD fail OR added path missing
G7 AST-diffworker/patcher.pyPython file modifiedrevert+retry on top-level def missing
G2 syntax checkworker/patcher.pyalwaysrevert+retry on parser error
BuildAnalyzeranalyzers/build.pyalwaysrevert+retry on cross-file compile fail
G8 test regressionworker/worker.pylanguage has runnerrevert+retry on previously-passing test now failing
Ψ-lite scoring + gateworker/psi_score.pyGITOMA_PSI_LITE=onrevert+retry on Ψ < threshold
Critic Panelcritic/panel.pyalways after commitadvisory only, never blocks
Devil criticcritic/devil.pyalways after paneladvisory + feeds refiner
Refinercritic/refiner.pydevil produced findingsre-emit patch, same guards as worker
Meta-eval judgecritic/meta_eval.pyrefiner produced patchchoose v0 vs v1, no apply
Q&A self-consistencycritic/qa.pyalways after meta-evalapply revision gated by BuildAnalyzer
Self-criticreview/self_critic.pyafter PR openpost review comment

Trace events emitted

EventWhenCarries
run.beginstart of runrepo URL + branch + base
run.exit_cleanend of runexit code
scope.metrics_filtereddocs verticalkept + dropped metric names
scope.plan_filtereddocs verticaldropped subtasks + reasons
plan.real_bug_synthesizedLayer-A firedfailing tests + source files
plan.readme_banishedLayer-B fireddropped subtasks
plan.occam_rewriteLayer-2 firedbefore/after file_hints
plan.occam_filterG9 fireddropped subtasks + threshold
worker.subtask.failedany subtask failtask_id + subtask_id + error
critic_syntax_check.failG2 firedpath + error + phase
critic_schema_check.failG10 firedpath + error + phase
critic_content_grounding.failG11 firedpath + error + phase
critic_config_grounding.failG12 firedpath + error + phase
critic_doc_preservation.failG13 firedpath + error + phase
critic_url_grounding.failG14 firedpath + error + phase
critic_ast_diff.failG7 firedpath + missing defs
critic_test_regression.failG8 firedfailing tests + phase
critic_build_retry.failBuildAnalyzer failerror + attempt
critic_build_retry.successretry recoveredsubtask_id + attempt
psi_lite.scoredΨ-lite enabledpsi + weakest_file
critic_psi_lite.failΨ-lite blockedpsi + weakest_file + reason
critic_panel.review.endpanel doneduration + findings_count + verdict
critic_devil.review.enddevil doneduration + findings_count
critic_refiner.keptrefiner keptpath
critic_refiner.revertedrefiner revertedrationale
critic_qa.crashedQ&A crashedreason → PR body annotation

Operational env vars (cheat sheet)

VariableDefaultEffect
GITHUB_TOKENrequiredfine-grained PAT with contents:write + pull-requests:write
LM_STUDIO_BASE_URLhttp://localhost:1234/v1LLM endpoint
LM_STUDIO_MODELgemma-4-e2b-itmodel name
LM_STUDIO_TIMEOUT120per-call HTTP timeout, clamped 10-600
LM_STUDIO_DISABLE_THINKINGunsetappend /no_think (Qwen3 family)
LM_STUDIO_DISABLE_THINKING_TEMPLATE_KWARGunsetsend chat_template_kwargs={enable_thinking:false} (GLM/Gemma/vLLM)
OCCAM_URLunsetOccam Observer gateway, fail-open if unreachable
GITOMA_OCCAM_FILTER_THRESHOLD2G9 drop threshold
GITOMA_PSI_LITEunsetenable Ψ-lite gate
GITOMA_PSI_LITE_THRESHOLD0.5reject when Ψ below
GITOMA_PSI_ALPHA1.0Γ weight
GITOMA_PSI_LAMBDA1.0Ω weight
GITOMA_URL_GROUNDING_OFFLINEunsetskip G14 DNS/HEAD (sandboxed CI)
GITOMA_SCOPEunsetactivate vertical mode (set by gitoma docs)
CRITIC_PANEL_DEVILoffenable devil critic
CRITIC_PANEL_QAoffenable Q&A self-consistency
CRITIC_PANEL_QA_APPLY_REVISIONoffgate-apply Defender revision
CRITIC_PANEL_DEVIL_BASE_URL / _MODELinheritroute devil to a different endpoint

Printing

VS Code: open this file in preview, Cmd-P → "Markdown PDF: Export (pdf)" (install the Markdown PDF extension if missing).

Or via CLI with mermaid-cli + pandoc:

bash
npm i -g @mermaid-js/mermaid-cli
brew install pandoc basictex
pandoc docs/architecture/pipeline-map.md -o pipeline-map.pdf \
  -F mermaid-filter \
  --pdf-engine=xelatex

The mermaid blocks render as embedded SVG. Layout is portrait A4 with the table sections naturally fitting one column each.

Released under the MIT License. Local-first by design. No telemetry.