Skip to content

Managed headless lineage state blocks implementation bootstrap_clone #5258

Closed

Description

@Trecek

Managed headless lineage state blocks implementation bootstrap_clone

Problem

In commissioning attempt 38073152913 for PR #5255, the implementation pipeline
halted before planning. Its managed headless launch stored lineage records in
the sandbox source checkout; the default bootstrap_clone clean-check reported
those untracked runtime files and the orchestrator followed its failure route.
This report concerns that observed default-gate failure, not a claim that every
launch necessarily halts at clone.

Reproduction and live evidence

The first run's e2e-implementation-38073152913-1 artifact contains
out/envelope.json with the exact L3 failure:

bootstrap_clone blocked: uncommitted_changes in source_dir=/workspace/sandbox
(?? .autoskillit/managed-headless-session-lineage/).
Recipe clone on_failure routes to escalate_stop.
Pipeline terminated before plan/implement.

out/result.json records passed=false, outcome=failed, and no expected
findings. The session summary records MiniMax-M3, AutoSkillit 0.10.1266,
Claude Code 2.1.280, normal session completion, and exit code 0. The outer fleet
envelope reports fleet_l3_startup_or_crash; its L3 payload is more specific.

Sandbox installation and baseline tests completed before fleet dispatch. No issue
claim, implementation PR, or owned branch was created. The seed remains OPEN
without an in-progress label.

Source evidence

  • src/autoskillit/execution/session/_managed_headless_session_lineage.py:28
    sets _NAMESPACE to .autoskillit/managed-headless-session-lineage.
  • src/autoskillit/workspace/clone/_detect.py:94 reads all nonempty
    git status --porcelain lines in detect_uncommitted_changes.
  • The clone gate therefore treats the launcher's own lineage directory as a
    source modification before the implementation recipe can create its clone.

The quoted CI reason is the retained L3 payload parsed from stdout, not a
preserved raw git status response. The small production-code probe below
independently reproduces the runtime-file/clean-check interaction.

clone_repo documents explicit strategy=proceed and strategy=clone_local
retry choices. Run 2's summary records two bootstrap_clone calls and later
planning, but does not retain their arguments/results. Therefore this report
does not identify which strategy made that run proceed.

Additional launch-path evidence at the tested commit:

  • fleet/dispatch/_lineage.py:151-207 resolves the authoritative launch cwd.
  • fleet/_native_shell_capture/_lineage.py:152-170,357-365 creates the
    FOOD_TRUCK lineage through the store using that anchor.
  • execution/session/_managed_headless_session_lineage_records.py:131-149,185-190
    creates the namespace directories and writes the durable record.

Expected behavior and scope

A clean source checkout must remain usable by bootstrap_clone after managed
headless launch. Runtime lineage persistence and source-isolation checks need to
agree about generated state, while retaining rejection of actual user edits.
Rerun the PR #5255 implementation scenario twice against the same seed after the
repair, then continue its pending commissioning checks.

This is distinct from the bounded output_dir mismatch fixed by #5257 / #5256.
The fixed plan and prepare_pr dispatches pass Docker admission checks, and the
rebased worktree passes its full configured local gate. Full implementation
success and an accepted concurrency peak have not been measured.

The automatic failure reporter also hits the already-tracked unsupported
gh issue create --json flag (#5249). That secondary defect is outside this issue.

Refs #5233 and PR #5255. Classification: bug, recipe:remediation.

Reproduction prerequisites

Pinned source: 021beadb687a96882fd717dabf36171732a97598, AutoSkillit 0.10.1266,
Claude Code 2.1.280, and that commit's scripts/docker/Dockerfile toolchain.
The harness uses MiniMax-M3[1m] at https://api.minimax.io/anthropic, with
CLAUDE_CODE_MAX_CONCURRENT_SUBAGENTS=6; the observed native model was MiniMax-M3.

Host prerequisites are Git, authenticated gh, uv and task for the
worktree/probes, and Docker with a working Buildx builder for the local image.
Check docker buildx version before that build.

Live CI requires repository write access, Actions secrets MINIMAX_API_KEY and
E2E_SANDBOX_TOKEN, and repository variable E2E_IMPLEMENTATION_ISSUE_URL set to
https://github.com/TalonT-Org/autoskillit-e2e-sandbox/issues/1. The sandbox token
must support issue claim/release, branch push/delete, PR open/close and CI reads.
Keep the seed OPEN and unclaimed, and preserve the unchanged sandbox baseline.
Observed sandbox main: d6c143d2494488deeb6680d7d5cf2e55e3e01732.

The fixture asks for normalize_whitespace in sandbox/text.py, focused unittest
cases, task test-check, and an open PR targeting main. The harness's MiniMax
settings-file setup matters; a host provider profile alone is not an equivalent
fleet-launch setup. The earlier local planning-only probe hit a managed-join
scope error; that local result is separate from this CI failure.

Replay the exact CI event

gh run rerun 38073152913 -R TalonT-Org/AutoSkillit
gh run view 38073152913 -R TalonT-Org/AutoSkillit \
  --json headSha,attempt,status,conclusion,url

GitHub reruns preserve the original GITHUB_SHA and GITHUB_REF; reruns are
available for 30 days. GitHub rerun documentation.

For a fresh dispatch, create a unique verification ref at the tested commit.
The following is for a Bash session with repository write access; execute the
GitHub ref creation and workflow dispatch as separate tool calls when using an
agent, retaining the displayed variable values between calls.

set -euo pipefail
REPRO_DIR="$PWD/.autoskillit/temp/investigate-lineage-38073152913"
mkdir -p "$REPRO_DIR"
REPRO_SHA=021beadb687a96882fd717dabf36171732a97598
SANDBOX_SHA=d6c143d2494488deeb6680d7d5cf2e55e3e01732
test "$(gh api -X GET repos/TalonT-Org/autoskillit-e2e-sandbox/git/ref/heads/main --jq .object.sha)" = "$SANDBOX_SHA"
VERIFY_REF="verify-issue-5258-$(date -u +%Y%m%d-%H%M%S)"
gh api -X POST repos/TalonT-Org/AutoSkillit/git/refs \
  -f ref="refs/heads/$VERIFY_REF" -f sha="$REPRO_SHA" \
  --jq .object.sha > "$REPRO_DIR/verify-ref.sha" 2> "$REPRO_DIR/verify-ref.err"
test "$(cat "$REPRO_DIR/verify-ref.sha")" = "$REPRO_SHA"

Then dispatch that exact ref:

sleep 1
gh workflow run e2e.yml -R TalonT-Org/AutoSkillit \
  --ref "$VERIFY_REF" -f tests=implementation
gh run list -R TalonT-Org/AutoSkillit --workflow e2e.yml \
  --branch "$VERIFY_REF" --event workflow_dispatch --limit 1 \
  --json databaseId,headSha,status,url > "$REPRO_DIR/dispatched-run.json" 2>&1

Once the run appears, confirm its headSha is $REPRO_SHA before treating its
result as a reproduction of this source. If the sandbox baseline check fails,
restore an authorized fixture baseline or use a separately owned equivalent
sandbox; a changed fixture is not the recorded reproduction environment.

The E2E queue serializes scenarios. Model behavior varies: the other commissioning
attempt stopped at a different gate. Capture the actual first failure; identical
model output is not guaranteed.

Retrieve attempt 1 evidence

From an AutoSkillit checkout:

REPRO_DIR="$PWD/.autoskillit/temp/investigate-lineage-38073152913"
mkdir -p "$REPRO_DIR"
gh run download 38073152913 -R TalonT-Org/AutoSkillit \
  --name e2e-implementation-38073152913-1 --dir "$REPRO_DIR/artifact"
gh run view 38073152913 -R TalonT-Org/AutoSkillit --attempt 1 --log-failed \
  > "$REPRO_DIR/failed.log" 2>&1

The artifact name pins attempt 1; use the new attempt suffix for reruns. The
workflow retains artifacts for 14 days, so download them while available.
Inspect out/result.json, out/envelope.json, out/ownership.json,
out/session-concurrency.json and the cited logs/sessions/<session_id>/summary.json.
Inspect the envelope's l3_payload and diagnostic_result; the outer fleet reason
can be less specific than the actual failure.

Verified small probe

Save the complete Python block below as $REPRO_DIR/lineage_clone_probe.py. Obtain the
pinned code and configured environment without initializing a worktree project:

REPRO_SHA=021beadb687a96882fd717dabf36171732a97598
git fetch https://github.com/TalonT-Org/AutoSkillit.git "$REPRO_SHA" \
  > "$REPRO_DIR/fetch.log" 2>&1
git worktree add --detach "$REPRO_DIR/source" "$REPRO_SHA"
(cd "$REPRO_DIR/source" && task install-worktree) \
  > "$REPRO_DIR/install.log" 2>&1

Use task install-worktree, not autoskillit init, inside the worktree.

import json
import sys
import uuid
from pathlib import Path

from autoskillit.core import (
    ManagedHeadlessSessionKind,
    NativeShellCaptureMode,
    resolve_native_shell_capture_decision,
)
from autoskillit.execution.session import DefaultManagedHeadlessSessionLineageStore
from autoskillit.workspace.clone import detect_uncommitted_changes

source = Path(sys.argv[1]).resolve()
before = detect_uncommitted_changes(str(source))
assert before == [], before
lineage = DefaultManagedHeadlessSessionLineageStore().create(
    lineage_anchor=source,
    launch_id=uuid.uuid4().hex,
    decision=resolve_native_shell_capture_decision(NativeShellCaptureMode.CAPTURE),
    backend="claude-code",
    session_kind=ManagedHeadlessSessionKind.FOOD_TRUCK,
    dispatch_id=str(uuid.uuid4()),
)
after = detect_uncommitted_changes(str(source))
assert any(".autoskillit/managed-headless-session-lineage/" in row for row in after), after
print(json.dumps({"before": before, "after": after,
                  "lineage_anchor": lineage.reference.lineage_anchor}, indent=2))

Run against a fresh sandbox clone with no user edits:

git clone --quiet https://github.com/TalonT-Org/autoskillit-e2e-sandbox.git \
  "$REPRO_DIR/sandbox"
SANDBOX_SHA=d6c143d2494488deeb6680d7d5cf2e55e3e01732
git -C "$REPRO_DIR/sandbox" checkout --detach "$SANDBOX_SHA" \
  > "$REPRO_DIR/sandbox-baseline.log" 2>&1
test "$(git -C "$REPRO_DIR/sandbox" rev-parse HEAD)" = "$SANDBOX_SHA"
"$REPRO_DIR/source/.venv/bin/python" "$REPRO_DIR/lineage_clone_probe.py" \
  "$REPRO_DIR/sandbox" > "$REPRO_DIR/probe.json" 2>&1

Verified exit 0: before=[],
after=["?? .autoskillit/managed-headless-session-lineage/"].
This demonstrates the production lineage-store/clean-check mismatch without a
model call or test suite. It does not execute bootstrap_clone or a full pipeline.
Preserve the generated record and compare porcelain status before/after; adding a
broad ignore rule would mask the behavior being investigated.

Local Docker reproduction and retained files

This mirrors the tested CI user-image build/harness invocation. Supply
MINIMAX_API_KEY and E2E_SANDBOX_TOKEN through the environment. It was not
separately rerun as part of preparing this issue; the small probe above was.
REPRO_DIR is the temp directory established above.

REPRO_SHA=021beadb687a96882fd717dabf36171732a97598
mkdir -p "$REPRO_DIR"/{build-context,e2e/out,e2e/data,e2e/upload}
git fetch https://github.com/TalonT-Org/AutoSkillit.git "$REPRO_SHA" \
  > "$REPRO_DIR/fetch.log" 2>&1
git archive "$REPRO_SHA" | tar -x -C "$REPRO_DIR/build-context"
docker buildx build --load --target user --tag autoskillit-commission-repro:021beadb \
  --file "$REPRO_DIR/build-context/scripts/docker/Dockerfile" \
  "$REPRO_DIR/build-context" > "$REPRO_DIR/build.log" 2>&1
chmod 0777 "$REPRO_DIR/e2e/out" "$REPRO_DIR/e2e/data" "$REPRO_DIR/e2e/upload"
SANDBOX_SHA=d6c143d2494488deeb6680d7d5cf2e55e3e01732
test "$(gh api -X GET repos/TalonT-Org/autoskillit-e2e-sandbox/git/ref/heads/main --jq .object.sha)" = "$SANDBOX_SHA"
export E2E_IMPLEMENTATION_ISSUE_URL=https://github.com/TalonT-Org/autoskillit-e2e-sandbox/issues/1
REPRO_CONTAINER="autoskillit-commission-repro-$(date -u +%Y%m%d-%H%M%S)"
if docker run --name "$REPRO_CONTAINER" \
  --env MINIMAX_API_KEY --env E2E_SANDBOX_TOKEN --env E2E_IMPLEMENTATION_ISSUE_URL \
  --volume "$REPRO_DIR/build-context/scripts/e2e:/opt/e2e:ro" \
  --volume "$REPRO_DIR/e2e/out:/artifacts" \
  --volume "$REPRO_DIR/e2e/data:/home/autoskillit/.local/share/autoskillit" \
  autoskillit-commission-repro:021beadb \
  python3 /opt/e2e/e2e_harness.py run --test implementation --out /artifacts \
  > "$REPRO_DIR/e2e/out/local-run.log" 2>&1; then
  REPRO_EXIT=0
else
  REPRO_EXIT=$?
fi
printf '%s\n' "$REPRO_EXIT" > "$REPRO_DIR/e2e/out/local-run.exit"

The scenario budget is 7,200 seconds. The conditional records the expected
nonzero failure without aborting an errexit shell before file recovery. Retain the
container name and inspect the files before cleanup. The missing --rm is
intentional: the stopped container preserves workspace files omitted by CI upload.
For this reported pre-clone failure, recover /workspace/sandbox for the
lineage records. The post-clone plan-recovery command is documented in #5259:

docker cp "$REPRO_CONTAINER:/workspace/sandbox" \
  "$REPRO_DIR/retained-sandbox" > "$REPRO_DIR/recover-sandbox.log" 2>&1

The first directory is the harness source. /workspace/autoskillit-runs exists
only after clone succeeds: skip its recovery command for the reported pre-clone
failure in #5258. For the observed #5259 failure route, implementation.yaml
registers the clone with status: error, and the clone registry preserves error
clones. Thus a retained stopped container should contain its generated plans.
If they are nevertheless absent, record that unexpected cleanup and perform a
new run with failure-workspace preservation configured before launch.
docker cp cannot recover an already deleted clone; the summaries alone cannot
establish the exact original plan-format defect.

Before sharing new harness output, use the same artifact redactor as CI:

docker run --rm --env MINIMAX_API_KEY --env E2E_SANDBOX_TOKEN \
  --volume "$REPRO_DIR/build-context/scripts/e2e:/opt/e2e:ro" \
  --volume "$REPRO_DIR/e2e:/e2e" \
  autoskillit-commission-repro:021beadb \
  python3 /opt/e2e/e2e_harness.py redact --dest /e2e/upload \
    --secret-env MINIMAX_API_KEY --secret-env E2E_SANDBOX_TOKEN \
    /e2e/out /e2e/data/logs > "$REPRO_DIR/redact.log" 2>&1

Keep raw recovered workspaces local; that redactor covers harness output/session
logs rather than arbitrary recovered checkout files. After investigation, verify
the seed remains OPEN/unclaimed and clean up each proven run-owned PR and branch.
At direct remote-ref inspection (snapshot saved 2026-10-10 19:26 UTC), these
fixture refs both pointed to d6c143d2494488deeb6680d7d5cf2e55e3e01732:

refs/heads/e2e-implementation-fixture-normalize-whitespace/1
refs/heads/e2e-implementation-fixture-normalize-whitespace/1-2

This is an inventory observation, not proof that this commissioning run created
both refs. Both ownership artifacts report branches: []. The seed was OPEN with
the fail label and without in-progress; it was not unlabeled. The second run's
peak/coverage report omitted its known planning children. These harness-evidence
gaps are recorded on PR #5255 and are separate from this issue's production cause.
Inspect current refs with gh api -X GET repos/TalonT-Org/autoskillit-e2e-sandbox/git/matching-refs/heads/.

Share only the redacted $REPRO_DIR/e2e/upload output. Fetch, install, build,
recovery and redactor logs outside that tree are raw and stay local. The local run
log is now under e2e/out, so the documented redaction includes it.

After recovering the files and after the Actions run is finished, remove the
stopped container you created:

docker rm "$REPRO_CONTAINER"

If the fresh-ref method was used, also remove that investigator-owned verification
ref after the run completes. In an agent session, use the literal recorded ref
from the creation step when issuing this single mutation:

sleep 1
gh api -X DELETE "repos/TalonT-Org/AutoSkillit/git/refs/heads/$VERIFY_REF"

If the sandbox harness left resources, supply RUN_OWNED_PR and RUN_OWNED_BRANCH
only after proving their identity from that run's PR, branch and head evidence.
Omit the PR command when that run created no PR; recheck the branch head against
the captured head before deleting it. Do not use the two inventory names above as
ownership proof. These are separate mutating commands:

gh pr close "$RUN_OWNED_PR" -R TalonT-Org/autoskillit-e2e-sandbox
sleep 1
gh api -X DELETE "repos/TalonT-Org/autoskillit-e2e-sandbox/git/refs/heads/$RUN_OWNED_BRANCH"

Source at the tested commit

Investigation

Investigated 2026-10-10 against develop 265f1e00e, which is identical to the tested commit 021beadb68 for everything under src/. The findings were challenged by three adversarial validators and each challenge was re-checked against source, git history, and the attempt-1 artifact. Citations below are relative to src/autoskillit/ unless they start with tests/, scripts/ or .github/.

Root Cause

The lineage store places session runtime state at the .autoskillit/ root with no keep-out, and the guards that enforce the keep-out rule cannot see a directory created by a runtime path. The clone gate is working as designed.

  1. The writer puts state in the source checkout. _NAMESPACE = Path(".autoskillit") / "managed-headless-session-lineage" (execution/session/_managed_headless_session_lineage.py:28); _prepare_root creates it under the anchor (execution/session/_managed_headless_session_lineage_records.py:131-149). For fleet dispatch the anchor is tool_ctx.project_dir (fleet/dispatch/_lineage.py:190-202) — the cwd of autoskillit fleet run (cli/fleet/_fleet_run.py:83), or AUTOSKILLIT_PROJECT_DIR / the git toplevel on the MCP dispatch path. Creation is not gated on backend and precedes child dispatch (fleet/_native_shell_capture/_lineage.py:357-365). A prior-success short-circuit and pre-launch failures return before any record is created; a verified resume reuses the existing one.
  2. The namespace has no keep-out. It is not in _AUTOSKILLIT_GITIGNORE_ENTRIES (core/io/io.py:707-716), not under temp/, and the store writes no ignore file.
  3. The gate is unfiltered and inspects the checkout that holds the anchor. detect_uncommitted_changes returns every non-blank git status --porcelain line (workspace/clone/_detect.py:94-108) and runs whenever strategy == "" (workspace/clone/__init__.py:286-296). The bundled clone step passes no strategy (recipes/implementation.yaml:355-368). In this run source_dir=/workspace/sandbox was passed explicitly and was also the fleet process cwd.
  4. The existing guards cannot see it. See Test Gap.

This is not a regression from PR #5255: its diff against develop touches .github/workflows/e2e.yml, scripts/e2e/ and tests/infra/ only. The sandbox is correctly configured: at baseline d6c143d2 it tracks .autoskillit/.gitignore with exactly the canonical entries, and its root .gitignore covers what the harness's pre-dispatch task install-worktree and task test-check produce.

The gate response is deterministic when the dispatch reaches launch, the anchor lies inside the checkout the gate inspects, no ignore rule already covers the namespace, and the clone call uses the default strategy. Whether the pipeline then halts depends on the orchestrator following on_failure: escalate_stop.

Reproduced on develop HEAD with the production store and detector in commit-free throwaway repositories:

Sequence detect_uncommitted_changes
Empty repo []
+ one FOOD_TRUCK store.create(...) ["?? .autoskillit/"]
+ a .gitignore containing * inside the namespace []
+ a second create and load_reference with that file present [], both succeed
Empty repo + ensure_project_temp + create + the same * file ["?? .autoskillit/"] (the untracked .autoskillit/.gitignore)

Adjacent Defects

  • The outer failure reason is erased. _MANAGED_CAPTURE_DIAGNOSTIC_MARKERS includes "managed-headless-session-lineage" (fleet/_outcome.py:40-50); _sanitize_managed_capture_diagnostics drops every line containing a marker (:61-67); when nothing is left the classifier substitutes FLEET_L3_STARTUP_OR_CRASH (:155-158). The attempt-1 out/envelope.json has a single-line l3_payload.reason naming the directory, and the sanitizer returns an empty string for it. That is why the outer envelope reported fleet_l3_startup_or_crash.
  • ensure_project_temp is a second trigger of the same gate. Every dispatch that reaches execution calls it before launch (fleet/dispatch/_api.py:531 → fleet/sidecar.py:63-64). It creates .autoskillit/.gitignore when absent and appends missing entries when present (core/io/io.py:751-765). A project that has never committed that file, or whose tracked copy predates a new entry, hits the clone gate independently of lineage. It did not contribute to this run. The untracked case was reproduced; the modified-tracked-file case is derived from the code and was not run.
  • .autoskillit/.state.yaml (cli/_init_helpers.py:266-273) has no keep-out either.

Exposure

  • Recipes reaching the gate with the default strategy: implementation, remediation, implementation-groups (via bootstrap_clone) and merge-prs (via python: autoskillit.workspace.clone.clone_repo, recipes/merge-prs.yaml:104-113). No bundled recipe passes a strategy.
  • run_skill creates lineage at the skill session cwd only when backend.capabilities.session_dir_persistent is true, which is Codex only. In that case the directory lands in clones and worktrees, where these consumers do not exclude it: the merge dirty checks (server/git.py:359-376, :599-613), main_repo_guard and commit_guard (recipe/cmd_rpc/_cmd_rpc_guards.py), and detect_zero_changes (smoke_utils/_git.py:145-156), where an untracked lineage directory would mask a zero-change session. The directory has been seen untracked in worktrees; no resulting failure or leaked commit was found.

Test Gap

  • Lineage-store tests anchor at a bare tmp_path and never use a git repository.
  • Uncommitted-changes-gate tests mock subprocess.run or use a user-style untracked.txt; the bootstrap_clone tool tests use a mocked clone manager.
  • No test combines lineage creation or a managed launch with a clean-tree assertion.
  • tests/infra/test_release_sanity.py:58-62 skips directories and inspects only the repository's own .autoskillit/; tests/cli/test_init.py:531-566 encodes the directory rule but exercises only ensure_project_temp and _create_secrets_template.
  • The existing headless-smoke E2E recipe never calls bootstrap_clone; the implementation scenario in PR Add seeded sandbox implementation E2E validation #5255 is the first to exercise fleet → bootstrap_clone.
  • It stayed latent because fleet and fleet_headless_run are experimental and default-off, internal live-gate fixtures ignore .autoskillit/ wholesale, and an orchestrator can retry the clone with an explicit strategy.

Historical Context

This is the third occurrence of the class, so it is a candidate for architectural remediation rather than another point fix.

Recommendations

  1. The lineage writer guarantees its namespace is invisible to git without touching a tracked file — a self-ignoring directory (.gitignore containing *, written before any record), as ensure_project_temp does for temp/. This clears every git status consumer at once, backfills existing directories the next time the root is prepared, and leaves the clone gate unfiltered so real user edits still block. Constraints: the shared helper must be narrow (calling ensure_project_temp would reintroduce the tracked-file rewrite); core/io/io.py is at 743 budget lines against a 750 cap; a failed ignore write inside _prepare_root fails lineage creation, so the failure policy should be chosen deliberately.
  2. Decide the namespace's tier. Staying at the root or moving under .autoskillit/temp/ is a design decision, not a prerequisite for clearing the gate. For moving: the Rectify: Session-Bridge File Misplaced Outside temp/ #751 precedent; the sibling shell-capture state already lives at a hardcoded .autoskillit/temp/shell_capture (hooks/_capture/_authority.py:61); fleet resume reads the lineage reference from state that is itself under temp/. Costs: store and hook must change path together, existing directories at the old location keep tripping the gate until removed or migrated, and in-flight resumes fall back to the invalid-lineage path.
  3. Enforce the invariant. A real-git init contract test that runs the launch-time sequence and asserts the tree stays clean while a genuine user change still trips the gate; extend the root guard to directories (this repository tracks .autoskillit/evidence/, skills/ and waivers/, which must be registered first); give doctor's gitignore_completeness the self-ignoring-directory exemption the init test already has.
  4. Completed in Fix remaining runtime-state visibility and failure reporting #5263: failure-reason sanitizing, launch-time tracked-ignore mutation, and .state.yaml keep-out were addressed together; no separate tickets were opened.

Considered and rejected: adding the namespace to the ignore entry list only (the append lands in a tracked file and is itself reported by the gate); excluding .autoskillit/ in detect_uncommitted_changes (hides real edits to committed config and recipes); filtering only this namespace at the clone gate (leaves the other consumers exposed); having recipes pass strategy: proceed (removes the protection for every run).

Open Questions

  • Run 2's bootstrap_clone arguments were not retained, so which strategy let it proceed is unknown.
  • The raw bootstrap_clone tool result for attempt 1 is not in the artifact; "the lineage directory was the only dirty path" rests on the L3-authored reason, the sandbox ignore rules, and the probe in this issue.
  • Whether Codex run_skill lineage directories in clones or worktrees have caused a merge, commit, stash, or zero-change misroute in practice.
  • Why the store was placed outside temp/ is not documented anywhere.

Completion evidence — 2026-10-11

Runtime-state Git invisibility and all three adjacent fixes are merged in #5261/#5263. The acceptance-policy int_map/default=0 registration is merged in #5264 (20a4cc85be2ff369c676520247c5a91e97633589). Final code checks passed 51,233 tests on 5854498a6f980782aa0b9f883b1e90a282c7f8f3; the registration gate passed 11,771 tests on 3a0a9f8eae7a4d84a7e14d8b0b899ea76b30bd07, against its actual dictionary-shaped base.

Both post-merge runs used 959603ece0ba5f1bc5f81cf6551a0545cf36bc16, descended from verified integration 53ab68d2472153bf5667fce48f25913369527d8e containing runtime repairs #5263 and policy registration #5264. The default bootstrap_clone from /workspace/sandbox succeeded in both runs against unchanged sandbox base d6c143d2494488deeb6680d7d5cf2e55e3e01732.

  • Run 1: https://github.com/TalonT-Org/AutoSkillit/actions/runs/38170521660, attempt 1. Clone receipt at 2026-10-11T20:05:01.170Z, tool call call_01a12c9191907360b2a092bf, clone /workspace/autoskillit-runs/impl-20261011-200500-587134; planning and plan-set binding followed. The full workflow failed with fleet_l3_no_result_block and incomplete lifecycle measurements.
  • Run 2: https://github.com/TalonT-Org/AutoSkillit/actions/runs/38170536595, attempt 1. Clone receipt at 2026-10-11T20:19:11.028Z, tool call call_01a12c9e881f74f585bec830, clone /workspace/autoskillit-runs/impl-20261011-201910-273707. The full workflow failed with degraded_tool_response; its L3 summary identifies kitchen intent-fingerprint/tracker dependency handling after clone and branch publication.

E-3's narrow clone-admission criterion passes twice on actual successful tool receipts. Both full workflow conclusions remain failure; no successful #5255 commissioning, accepted concurrency peak, or official re-audit GO is claimed. Run 1's missing final L3 payload is preserved as a failure and is not used to infer clone success.

GitHub could not rebase the original #5255 branch (PullRequest::RebaseConflictError). Its final scenario changes were applied with a three-way patch on a replay branch in the same existing worktree, preserving the original branch. Only a README overlap required combining documentation. The replay branch suppresses automatic failure tickets for this exact verification ref. The configured local gate passed on the actual integration base: 15,955 passed, 207 skipped, 12 xfailed; pre-commit passed.

The sandbox seed remains OPEN/unclaimed with its original body, original fail label, and unchanged main commit. No sandbox PR was opened. The two newly created run-owned branches (.../1-3, .../1-4) were proven by their publication receipts and deleted; the pre-existing .../1 and .../1-2 refs were preserved. The harness ownership manifests missed those published branches, so teardown was independently verified instead of relying on the empty manifest lists. No new tracking tickets or review comments were posted.

The runtime-state issue is complete. The remaining failed full-commissioning outcomes are recorded in the existing #5255 PR, whose acceptance criteria remain separate.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugExisting behavior is brokenin-progressIssue is being actively worked onrecipe:remediationRoute: investigate/decompose before implementation

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions