Hacktoberfest 2026: the issues maintainers tagged for October, open and beginner-friendly. Browse Hacktoberfest issues

Determinism Tier 2: remediation must be atomic and idempotent under partial failure

Open
#420 0 comments 0 reactions 0 assignees View on GitHub

Maintainers usually reply within 1 day

Nobody has claimed this yet.

Assessment

Difficulty
5/5
Estimated time
Over a week
Newbie friendliness
35/100
Issue type
Feature
Clarity
Mostly clear
Activity status
Quiet
Tech stack
git, github, python
Domain
backend, devtools

Research direction

Start by reading builtin_handlers.py around lines 233–240 and 806–836, then orchestrator.py around lines 409–410 to trace how remediation outcomes are handled. Identify existing handler and audit-run storage conventions before choosing how to record attempts. Done means retries can detect already-applied API state, failures warn about possible partial state, and a later run can warn about prior attempts.

Written by the indexing model from the issue text.

Description

module-core

Summary

Remediation actions with side effects (GitHub API calls, gh
subprocess invocations, git push) currently have no atomicity
guarantee and no idempotency check. A network drop mid-action can
leave the repo or upstream in a partial state that darnit does not
detect on the next run.

This is Determinism Tier 2 as applied to the remediation phase --
side effects are expected but half-applied side effects must be
surfaced, not hidden.

Concrete gaps

  • packages/darnit/src/darnit/sieve/builtin_handlers.py:806-836 --
    api_call_handler returns INCONCLUSIVE with
    requires_execution: True but has no idempotency key. If a network
    drop kills the process after the API call succeeded but before
    darnit recorded the outcome, a subsequent run will re-fire the
    same call.
  • packages/darnit/src/darnit/sieve/builtin_handlers.py:233-240 --
    exec handler for gh commands (branch protection PATCH, ruleset
    creation) captures failure but doesn't record whether partial
    state was left on GitHub. A rule set half-applied can hide behind
    a subsequent "already exists" error on retry.
  • packages/darnit-baseline/src/darnit_baseline/remediation/orchestrator.py:409-410
    -- needs_review=True marks unsafe handlers but doesn't track
    partial-failure state across runs. Same handler failing on run N
    and re-attempted on run N+1 has no persisted "we tried this
    before" signal.

Scope

  • For api_call_handler: add a pre-execution check that reads the
    target resource (idempotency key: URL + method + relevant payload
    hash). If the desired state is already present, skip and log
    "already applied."
  • For gh command remediation: on failure, log a WARN with the
    specific state that may be partial (e.g., "branch protection
    attempted; verify at https://github.com/owner/repo/settings/branches").
  • Persist a per-audit-run remediation attempt log
    (.darnit/remediation-attempts.json or via a new
    RemediationLogStore Protocol -- consider whether to piggyback on
    the feature 033 store abstraction). Next run reads this log to
    detect stale-retry situations and warn operator.

Non-goals for v0

  • Full transactional rollback (out of scope for shell-out
    remediations; document the risk instead).
  • Retrying failed remediations automatically (masks the underlying
    gap; leave to operator).
  • Adding a new store Protocol for remediation logs (may be worth it;
    defer to spec time).

Constitution alignment

  • II. Conservative-by-Default: an unknown partial state is worse
    than a clean failure. Loud logging of partial-state risk preserves
    the operator's ability to reason about their repo's actual state.
  • III. TOML-First: any per-handler idempotency-key configuration
    belongs in the handler TOML.

Related

  • #418 (Determinism Tier 1) -- atomic file writes handled there.
  • #419 (Determinism Tier 2 audit-side) -- same problem in the audit
    phase.
  • Determinism Tier 3 (LLM remediation review checkpoint, filed
    alongside this one) -- separate concern from atomicity but same
    phase.
Dominant language
Python
Stars
22
Forks
27
Avg merge
2d 28m
Merged PRs (30d)
40

Getting set up

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from darnitdevorg/darnit

All issues in darnitdevorg/darnit

Similar issues

More Python issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.