Determinism Tier 2: remediation must be atomic and idempotent under partial failure
Maintainers usually reply within 1 day
Nobody has claimed this yet.
Assessment
- Difficulty
- 5/5
- Estimated time
- Over a week
- Newbie friendliness
- 35/100
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
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_handlerreturns INCONCLUSIVE with
requires_execution: Truebut 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--
exechandler forghcommands (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=Truemarks 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
ghcommand 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.jsonor via a new
RemediationLogStoreProtocol -- 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
- No Dockerfile or Docker Compose file
- Has a pull request template
- Read the contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from darnitdevorg/darnit
-
needs triage
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
darnitdevorg/darnit#589 ·
Maintainers usually reply within 1 day
-
needs triage
Difficulty 2/5 1-3 hours Newbie friendliness 83/100
darnitdevorg/darnit#587 ·
Maintainers usually reply within 1 day
-
needs triage
Difficulty 2/5 1-3 hours Newbie friendliness 65/100
darnitdevorg/darnit#585 ·
Maintainers usually reply within 1 day
-
quality
Difficulty 2/5 1-3 hours Newbie friendliness 66/100
darnitdevorg/darnit#523 ·
Maintainers usually reply within 1 day
-
documentation good first issue
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
darnitdevorg/darnit#516 ·
Maintainers usually reply within 1 day
All issues in darnitdevorg/darnit
Similar issues
-
enhancement from-review
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
khuisman/mcp-gee-sweet#1010 ·
Maintainers usually reply within 1 day
-
bug confirmed issue
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
open-webui/open-webui#32333 · 2 comments ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
ll7/robot_sf_ll7#10368 ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 62/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
flop-labs/technocore-chat#982 ·
Maintainers usually reply within 1 day