Skip to content

v3.138.4 — Resilience Arc — Pipeline Failure Intelligence (v3.138.4)

Latest

Choose a tag to compare

@GeoffGodwin GeoffGodwin released this 02 May 03:55
· 1 commit to main since this release

Resilience Arc — Pipeline Failure Intelligence (v3.138.4)

One intent. Many hands.

This release lands the Resilience Arc: thirteen connected milestones
(M126–M138) that turn Tekhton's failure path into a first-class system. UI
gate execution becomes deterministic, build-fix gets a real adaptive
continuation loop instead of a single short attempt, failure context grows
into a v2 schema with explicit primary/secondary causes, recovery routing
reads that context, RUN_SUMMARY.json and tekhton --diagnose finally
report root cause instead of symptom, and an end-to-end integration harness
keeps the chain honest. CI environments now configure themselves.

The arc was driven by real-world failure traces seen while running Tekhton
against bifl-tracker and structural-divergence-indexer — interactive
Playwright HTML reporters hanging gates, mixed-log classification
over-escalating to code fixes, max-turns symptoms masking environment root
causes, and stale LAST_FAILURE_CONTEXT.json contaminating succeeding
runs.

A --migrate script lifts existing projects to config v3.2 in one step,
and four follow-up patches close TUI, --report, and artifact-location
bugs surfaced during the arc's own dogfooding.

Highlights

Resilience Arc (M126–M138)

  • M126 — Deterministic UI gate execution. UI test commands like
    Playwright's npx playwright test could enter an interactive HTML report
    server (Serving HTML report at http://localhost:9323. Press Ctrl+C to quit.) and never terminate, hitting UI_TEST_TIMEOUT with a useless
    exit-124. The gate now normalises the env (PLAYWRIGHT_HTML_OPEN=never,
    CI=1, PW_TEST_HTML_REPORT_OPEN=never and friends) before invocation,
    detects the interactive-reporter signature in output, and re-runs once
    with a hardened non-interactive profile when configured to. New
    TEKHTON_UI_GATE_FORCE_NONINTERACTIVE, UI_GATE_ENV_RETRY_ENABLED, and
    UI_GATE_ENV_RETRY_TIMEOUT_FACTOR config keys.
  • M127 — Mixed-log classification hardening. classify_build_errors_all
    no longer defaults every unmatched line to code|code||Unclassified,
    which used to drag pipelines into build-fix coder routing whenever test
    output contained a few stray npm warnings or ANSI fragments.
    Classification now produces a per-bucket confidence score; mixed-uncertain
    outputs route to a single retry-then-save_exit path instead of burning
    build-fix turns on environment failures dressed up as code errors. New
    BUILD_FIX_CLASSIFICATION_REQUIRED toggle to revert pre-M130 behaviour.
  • M128 — Build-fix continuation loop with adaptive turn budgeting.
    Replaced the single-attempt base/3 build-fix in stages/coder.sh with
    a bounded continuation loop owned by stages/coder_buildfix.sh. The loop
    retries up to BUILD_FIX_MAX_ATTEMPTS (default 3), allocates an adaptive
    per-attempt budget capped by BUILD_FIX_TOTAL_TURN_CAP (default 120),
    and gates retries on a progress signal — if attempt N≥2 reports
    unchanged or worsened, the loop halts immediately. Per-attempt
    postmortems land in BUILD_FIX_REPORT.md. New keys:
    BUILD_FIX_ENABLED, BUILD_FIX_MAX_ATTEMPTS,
    BUILD_FIX_BASE_TURN_DIVISOR, BUILD_FIX_MAX_TURN_MULTIPLIER,
    BUILD_FIX_REQUIRE_PROGRESS, BUILD_FIX_TOTAL_TURN_CAP,
    BUILD_FIX_REPORT_FILE.
  • M129 — Failure context schema v2. LAST_FAILURE_CONTEXT.json grew
    from a flat record to a schema-versioned document with explicit
    primary_cause and secondary_cause objects (each with
    category/subcategory/evidence). Pipeline state, diagnose rules, and
    recovery routing now read consistent keys instead of the old
    best-effort field-by-field probing. The schema preserves backward
    compatibility for v1 readers.
  • M130 — Causal-context-aware recovery routing. _classify_failure in
    lib/orchestrate_recovery.sh now consults the schema-v2 failure context
    (and the M132 causal log) before branching. ENVIRONMENT/test_infra
    failures whose primary cause is a UI-gate timeout retry once with
    non-interactive env (instead of unconditional save_exit); max-turns
    symptoms whose root cause is environmental are routed by root cause, not
    symptom. Recovery decisions are stamped on _ORCH_RECOVERY_ROUTE_TAKEN,
    _ORCH_ENV_GATE_RETRIED, and _ORCH_MIXED_BUILD_RETRIED for downstream
    consumers.
  • M131 — Preflight UI test framework config audit. Detection moves
    ahead of the gate. The preflight layer scans Playwright, Cypress, Jest,
    and Vitest config for known interactive-mode settings (reporter: 'html'
    with open: 'always', watch-mode defaults, etc.), warns the operator,
    and — when PREFLIGHT_UI_CONFIG_AUTO_FIX=true — patches the offending
    config in place with a backup under .claude/preflight_bak/. Emits
    structured findings consumed by M126 and M130. New keys:
    PREFLIGHT_UI_CONFIG_AUDIT_ENABLED, PREFLIGHT_UI_CONFIG_AUTO_FIX,
    PREFLIGHT_BAK_DIR, PREFLIGHT_BAK_RETAIN_COUNT.
  • M132 — RUN_SUMMARY causal fidelity enrichment. RUN_SUMMARY.json
    now carries the M128/M129/M130/M131 signals (build_fix.attempts,
    failure_context.primary_cause, recovery.route_taken,
    preflight.ui_interactive_config_detected, etc.) instead of a flat
    error_classes_encountered list. Watchtower and any external consumers
    see root cause without re-scraping logs.
  • M133 — Diagnose rule enrichment. tekhton --diagnose learned five
    new resilience-arc failure modes:
    UI_GATE_INTERACTIVE_REPORTER, BUILD_FIX_EXHAUSTED,
    PREFLIGHT_INTERACTIVE_CONFIG, MIXED_UNCERTAIN_CLASSIFICATION, and
    MAX_TURNS_ENV_ROOT. Diagnose-only — no behavioural change to gates,
    preflight, recovery, or context writes; consumes existing artifacts.
  • M134 — Resilience Arc integration test harness. End-to-end fixtures
    exercise the full chain (preflight scan → gate normalisation → timeout
    detection → classification → build-fix loop → failure context write →
    recovery routing → RUN_SUMMARY enrichment → --diagnose output) so
    cross-cutting bugs that escape per-milestone unit tests get caught.
  • M135 — Artifact lifecycle management. LAST_FAILURE_CONTEXT.json is
    now cleared on successful runs (no more stale-failure diagnoses on
    succeeding projects), BUILD_RAW_ERRORS.txt is removed on success, and
    .claude/preflight_bak/ is pruned to the most recent
    PREFLIGHT_BAK_RETAIN_COUNT entries (default 10).
  • M136 — Config defaults and validation hardening. All thirteen
    arc-introduced operator keys are declared in lib/config_defaults.sh,
    picked up by pipeline.conf overrides, validated by
    tekhton --validate-config, and documented in
    templates/pipeline.conf.example. Mis-typed numeric values now error
    loudly instead of silently being ignored.
  • M137 — V3.2 migration script. migrations/031_to_032.sh lifts
    existing projects (config version 3.13.2): adds the thirteen
    arc keys to pipeline.conf with sane defaults, registers new artifact
    paths in .gitignore, and stamps TEKHTON_CONFIG_VERSION=3.2. Run via
    tekhton --migrate.
  • M138 — Runtime CI environment auto-detection. When Tekhton starts
    inside GitHub Actions, GitLab CI, Jenkins, CircleCI, Travis, or any
    environment exporting $CI=1, and the operator hasn't explicitly set
    TEKHTON_UI_GATE_FORCE_NONINTERACTIVE in pipeline.conf, the variable
    is auto-set to 1. Explicit values — including =0 — always win.
    Eliminates the silent-failure-in-CI footgun that motivated the arc.

Bug fixes and polish

  • tekhton --report printed literal ANSI escape sequences like
    \033[0;32msuccess\033[0m on the Outcome / Coder / Security / Reviewer
    / Tester lines. Root cause: color constants in lib/common.sh are
    stored as literal strings; _out_color in lib/output_format.sh was
    emitting them via printf '%s' instead of printf '%b'. Fixed without
    touching the constants — %b interprets the backslash sequences and
    the surrounding helpers (out_banner, out_section, out_kv, …) keep
    working unchanged.
  • HUMAN_ACTION_REQUIRED.md and other artifacts written to project
    root.
    A handful of pipeline files were still being written to the
    pre-.tekhton/ location. The fix relocates the writers and ships
    migrations/032_to_033.sh + tests/test_migrate_033.sh so existing
    projects move root-level artifacts into .tekhton/ (merging into any
    existing canonical file rather than overwriting silently).
  • TUI sidecar silent death in tekhton --human --complete. The
    per-iteration reset path could leave the sidecar dead while the parent
    loop kept writing status updates that nothing was rendering. Added
    lib/tui_liveness.sh with a sampled liveness probe
    (_tui_check_sidecar_liveness) that detects a dead sidecar and
    surfaces a visible warning instead of silently no-op'ing. lib/tui.sh
    shrinks back below the 300-line ceiling.
  • TUI status bar shows working directory. The top status bar now
    appends · /<project_dir> after the Pass counter, transforming
    fix-nb · Pass 1/5 into fix-nb · Pass 1/5 · /name-of-folder — useful
    when running multiple Tekhton invocations against different projects in
    adjacent terminals.
  • Thirty open non-blocking notes addressed. A focused sweep through
    .tekhton/NON_BLOCKING_LOG.md resolved every open item: M127's magic
    literal promoted to a named constant, M128's vestigial BUILD_GATE_RETRY
    guard removed, M129's unsafe echo "$sub_block" replaced with
    printf '%s ', M133's docstring/code numbering mismatch corrected, plus
    smaller inconsistencies across tests, fixtures, and documentation.

Why it matters

  • Failures now produce signal, not noise. Before the arc, a
    Playwright HTML reporter hang surfaced as MAX_TURNS_EXHAUSTED after
    Tekhton burned a build-fix attempt on what was actually an environment
    problem. After the arc, the same failure surfaces as
    UI_GATE_INTERACTIVE_REPORTER in --diagnose, retries once with a
    hardened env, and either succeeds or save_exits with the root cause
    in RUN_SUMMARY.json. No more chasing symptoms.
  • CI gets the right defaults for free. The
    TEKHTON_UI_GATE_FORCE_NONINTERACTIVE footgun — the most common cause
    of opaque CI hangs in the arc's failure traces — is closed without any
    per-project YAML edits. M138 detects the CI environment at runtime and
    defaults appropriately.
  • Build-fix has a real budget. A single base/3-turn attempt was
    too brittle for any non-trivial fix. The continuation loop now spends
    up to three attempts inside a BUILD_FIX_TOTAL_TURN_CAP envelope,
    halts the moment progress stalls, and writes a per-attempt postmortem
    for inspection.
  • Existing projects upgrade in one command. Two migration scripts
    ship together: 031_to_032.sh for the resilience arc config keys and
    032_to_033.sh for the artifact-relocation fix. tekhton --migrate
    walks both, stamping TEKHTON_CONFIG_VERSION=3.2 and merging any stale
    root-level artifacts into .tekhton/.

Upgrade notes

  • Run tekhton --migrate once after upgrading. The migration is
    idempotent and safe to re-run. It adds thirteen new keys to
    pipeline.conf with conservative defaults (everything in the arc
    defaults to "on" with budgets matching the prior implicit behaviour),
    registers new gitignore entries, and moves any stale root-level
    HUMAN_ACTION_REQUIRED.md into .tekhton/.
  • No breaking config changes. Every arc behaviour is gated behind a
    config key with the same default as the prior implicit behaviour where
    one existed. To revert mixed-log routing to pre-M130 behaviour, set
    BUILD_FIX_CLASSIFICATION_REQUIRED=false. To opt out of the
    M126 env-gate retry, set UI_GATE_ENV_RETRY_ENABLED=false. To opt
    out of CI auto-detection, set TEKHTON_UI_GATE_FORCE_NONINTERACTIVE=0
    explicitly in pipeline.conf.
  • .tekhton/BUILD_FIX_REPORT.md is a new artifact. It's added to
    the migration's gitignore additions; if you don't run --migrate you
    may want to add it manually.
  • Brew tap users will pick up the release on next brew upgrade tekhton.

Release: v3.138.4