Repository navigation
fix(engine): apply code-review findings for the integration and recorded-diff hardening - #44
Merged
Conversation
- Drop GIT_EXEC_PATH, GIT_TEMPLATE_DIR, GIT_CONFIG_GLOBAL, GIT_CONFIG_SYSTEM and the pathspec/attr-source variables from both scrubbed environments, and resolve the git binary once per process instead of through the inherited PATH on every call. The tests now assert the variables that matter. - Build integrateGit on gitCommandHooksOff and add -c commit.gpgsign=false, so the engine's one git write no longer runs a signing program named in the executor-writable repository config. - Probe --config-env support once and emit no hook flags on a git that predates it, instead of failing every command with an unknown option. - Memoize the hook-flag listing per directory for the process lifetime so each git read no longer forks a second git. - Pass --keep-redundant-commits so a chain whose first commit already landed by hand integrates instead of aborting on the empty pick. - Pin core.quotePath, diff.noprefix and diff.mnemonicPrefix so diff headers keep the a/ b/ shape the parser expects. - Read the eight sequencer and grafts paths with one rev-parse over one table.
…in step comments - Drop C0/C1 controls and ANSI escape sequences from comment bodies on both the plain and the glamour path, so a body cannot forge a header at column 0 through a carriage return or a cursor sequence; the forgery test now covers those bytes. - Accept ZWNJ, ZWJ, soft hyphen, word joiner, variation selectors and ideographic variation selectors in a step comment when they follow a visible character, so Persian, Hindi conjuncts, emoji sequences and text-presentation glyphs post; they stay refused in blank-rendering positions. - Scope the QA detached-saga wait to this suite's binary, fail loudly without pgrep or on timeout, and hook run_stdin the same way as run and run_env.
… read once - Write the --no-conditions waiver note inside the close transaction so a close on a run that already rolled up to done no longer commits and then reports failure. - Propagate every error other than no-open-dispatch from the open-dispatch read so the unfiled-conditions check refuses instead of silently passing. - Assemble condition voters from rows rather than splitting a joined string, so a voter name holding a comma stays one voter. - Compare a park against its own activity instant rather than the step row's last write, and check rows.Err on the retry-eligible dedupe read. - Load a run's steps and relations once and share them between the retry, unexpanded and held advisories; record missing retry-eligible events in one transaction after one read. - Keep sweeping stranded sagas when one step's lock cannot be taken, and name the right verb in the hold attribution refusal.
…ate writes - planIntegration now refuses when the range probe cannot answer, with the same refusal the annotation would give after the pick, so the shared branch never moves for a step that could not then be annotated. - AnnotateIntegration shape-checks the recorded writer chain before building a git command from it, as the integrate path already does. - Load a run's step definitions once across the planning loop. - State in the annotate help, the file header and the --skip-integration-check help which three forms an integrated sha is accepted in, and that any other hand resolution needs the per-close waiver.
…s gate stages - Decide whether an oversize diff section is binary by probing the first 8000 bytes of both blobs (or the worktree file when the after side is unstored) for a NUL, instead of only trusting a first hunk that starts at the top, so a binary changed below its header is capped rather than recorded whole. - Parse the diff --git header with C-unquoting and a same-path split, so quoted, noprefix and ' b/'-containing paths still reach generated-file elision; take the counts of an already-capped section from its marker. - Compare the --worktree against the run's exec root after resolving symlinks, so a symlinked spelling of the shared checkout is not bound as a separate live worktree; read the exec root once per completion. - Return a recorded-head read error from the gate and diff stages instead of measuring the live worktree. - Hold one scratch checkout per resume and share it across the completion gates; the diff stage keeps its own fresh tree. - Make saga's patch-id helpers projections of the integration-range ones, and name the engine-reserved artifact kinds in one place.
erikreinert
added this pull request to stack #45
October 23, 2026 00:51
erikreinert
added a commit
that referenced
this pull request
Oct 23, 2026
…ded-diff hardening (#44) * fix(engine): close the gaps in the hardened git runner - Drop GIT_EXEC_PATH, GIT_TEMPLATE_DIR, GIT_CONFIG_GLOBAL, GIT_CONFIG_SYSTEM and the pathspec/attr-source variables from both scrubbed environments, and resolve the git binary once per process instead of through the inherited PATH on every call. The tests now assert the variables that matter. - Build integrateGit on gitCommandHooksOff and add -c commit.gpgsign=false, so the engine's one git write no longer runs a signing program named in the executor-writable repository config. - Probe --config-env support once and emit no hook flags on a git that predates it, instead of failing every command with an unknown option. - Memoize the hook-flag listing per directory for the process lifetime so each git read no longer forks a second git. - Pass --keep-redundant-commits so a chain whose first commit already landed by hand integrates instead of aborting on the empty pick. - Pin core.quotePath, diff.noprefix and diff.mnemonicPrefix so diff headers keep the a/ b/ shape the parser expects. - Read the eight sequencer and grafts paths with one rev-parse over one table. * fix(render): strip control bytes from comment bodies; accept joiners in step comments - Drop C0/C1 controls and ANSI escape sequences from comment bodies on both the plain and the glamour path, so a body cannot forge a header at column 0 through a carriage return or a cursor sequence; the forgery test now covers those bytes. - Accept ZWNJ, ZWJ, soft hyphen, word joiner, variation selectors and ideographic variation selectors in a step comment when they follow a visible character, so Persian, Hindi conjuncts, emoji sequences and text-presentation glyphs post; they stay refused in blank-rendering positions. - Scope the QA detached-saga wait to this suite's binary, fail loudly without pgrep or on timeout, and hook run_stdin the same way as run and run_env. * fix(engine): make dispatch close and retry advisories fail closed and read once - Write the --no-conditions waiver note inside the close transaction so a close on a run that already rolled up to done no longer commits and then reports failure. - Propagate every error other than no-open-dispatch from the open-dispatch read so the unfiled-conditions check refuses instead of silently passing. - Assemble condition voters from rows rather than splitting a joined string, so a voter name holding a comma stays one voter. - Compare a park against its own activity instant rather than the step row's last write, and check rows.Err on the retry-eligible dedupe read. - Load a run's steps and relations once and share them between the retry, unexpanded and held advisories; record missing retry-eligible events in one transaction after one read. - Keep sweeping stranded sagas when one step's lock cannot be taken, and name the right verb in the hold attribution refusal. * fix(engine): refuse an unanswerable carriage probe before step integrate writes - planIntegration now refuses when the range probe cannot answer, with the same refusal the annotation would give after the pick, so the shared branch never moves for a step that could not then be annotated. - AnnotateIntegration shape-checks the recorded writer chain before building a git command from it, as the integrate path already does. - Load a run's step definitions once across the planning loop. - State in the annotate help, the file header and the --skip-integration-check help which three forms an integrated sha is accepted in, and that any other hand resolution needs the per-close waiver. * fix(engine): cap binaries by their bytes and share one checkout across gate stages - Decide whether an oversize diff section is binary by probing the first 8000 bytes of both blobs (or the worktree file when the after side is unstored) for a NUL, instead of only trusting a first hunk that starts at the top, so a binary changed below its header is capped rather than recorded whole. - Parse the diff --git header with C-unquoting and a same-path split, so quoted, noprefix and ' b/'-containing paths still reach generated-file elision; take the counts of an already-capped section from its marker. - Compare the --worktree against the run's exec root after resolving symlinks, so a symlinked spelling of the shared checkout is not bound as a separate live worktree; read the exec root once per completion. - Return a recorded-head read error from the gate and diff stages instead of measuring the live worktree. - Hold one scratch checkout per resume and share it across the completion gates; the diff stage keeps its own fresh tree. - Make saga's patch-id helpers projections of the integration-range ones, and name the engine-reserved artifact kinds in one place.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes for 31 verified findings from a full review of #43. The five commits sit directly on top of
fix/run-postmordem(82e5959), so this merges as a fast-forward. Each commit builds and vets on its own.What changed
Hardened git runner (
internal/engine/integrate_git.go,internal/config/gitctx.go)GIT_EXEC_PATH,GIT_TEMPLATE_DIR,GIT_CONFIG_GLOBAL,GIT_CONFIG_SYSTEMand the pathspec/attr-source variables from both scrubbed environments; resolve the git binary once per process instead of through the inheritedPATHon every call. Tests now assert the variables that matter.integrateGit(the one git write) is built ongitCommandHooksOffand adds-c commit.gpgsign=false, so a signing program named in the executor-writable repository config no longer runs during the conductor's pick.--config-envsupport is probed once; a git older than 2.31 gets no hook flags instead of failing every command.cherry-pickpasses--keep-redundant-commits, so a chain whose first commit already landed by hand integrates instead of aborting.core.quotePath,diff.noprefixanddiff.mnemonicPrefixare pinned so diff headers keep thea/ b/shape.rev-parseover one table.Diff recording and elision (
internal/engine/diff_elide.go,saga.go)issue.diffand every packet.diff --githeader is parsed with C-unquoting and a same-path split, so quoted,noprefixand' b/'-containing paths still reach generated-file elision; an already-capped section reports the counts from its marker.Recorded head and gate stages (
recorded_head.go,saga.go,pregate_scratch.go)--worktreeis compared against the run's exec root after resolving symlinks, so a symlinked spelling of the shared checkout is not bound as a separate live worktree; the exec root is read once per completion.worktree add/removeper completion becomes 2.step integrate / annotate (
step_integrate.go,annotate_integration.go, CLI help)planIntegrationrefuses an unanswerable carriage probe before any write, with the same refusal the annotation would give afterwards, so the shared branch never moves for a step that could not then be annotated.AnnotateIntegrationshape-checks the recorded writer chain before building a git command from it.--skip-integration-checkhelp state the three accepted forms for an integrated sha and route everything else to the waiver.Dispatch close and retry advisories (
dispatch.go,dispatch_conditions.go,retry_eligible.go,unexpanded.go,hold.go,saga_detached.go,cli/run_status.go)--no-conditionswaiver note is written inside the close transaction, so a close on a run that already rolled up to done no longer commits and then reports failure.activity_msrather than the row's last write;rows.Erris checked on the dedupe read.Comments, rendering, QA (
step_comment.go,render/detail.go,scripts/qa/helpers.sh)pgrepor on timeout, andrun_stdingets the same hook.Not applied
proposals.updated_at >= dispatch open): the inter-dispatch gap is the contract the feature's own test asserts, and closing it needs a seal timestamp the schema does not have. Left as a design question.Notes
GIT_CONFIG_GLOBALfrom the scrubbed environment means engine git now reads the host's global config. The-c commit.gpgsign=falseis what keeps the suite green on a host that setscommit.gpgsign, so those two changes should stay together.Validation
gofmt,go build ./...,go vet ./..., staticcheck v0.7.0 clean.go test ./...passes on every package;internal/workflowpasses withDOCKET_SWEEP_WORKFLOWS_DIRpointed at the CI corpus as the workflow does.scripts/qa.shthrough section ZG: 1380/1380.