Skip to content

D: stop renaming a parent of a nested gitlink during the run #99

Closed

Description

@mchwang

Lane D follow-up to #81.

Why

#81 puts an empty read-only tmpfs at every gitlink path for execute and fix (--mount type=tmpfs,target=/work/<path>,readonly,tmpfs-mode=0555,tmpfs-size=4096). A top-level gitlink is fully protected: an agent cannot write into it, remove it or rename it (EROFS, EBUSY).

A gitlink below the top level (for example deps/inner) is not fully protected during the run. Tested in real Docker:

  1. The agent renames a parent directory: mv deps deps2. This succeeds, and the mount moves to /work/deps2/inner.
  2. The agent creates deps/inner again and writes anything there, including a full nested checkout with its own .git.

The inspection after the run reports this as nestedGitlinkContent, and the task goes to needs human. So nothing is committed. But docs/plan-format.md ("Submodules in version 1") asks for the protection during the invocation. #81 amended that section to record this gap.

Proposed

Find a mount layout or check that stops this during the run, then remove the exception from plan-format.md. Options to evaluate:

  • Mount each parent directory of a nested gitlink so that it cannot be renamed, while its other children stay writable.
  • Refuse execute and fix for heads with nested gitlinks, if no layout works.

Done when

  • A real-Docker test renames a parent of a nested gitlink during an execute run, and the write at the old path fails (or the launch is refused).
  • docs/plan-format.md and docs/implementation/agent-isolation.md no longer list the exception.

Refs: #81, docs/plan-format.md ("Submodules in version 1").

Activity

  1. mchwang commented on Oct 2, 2026

    @mchwang
    ContributorAuthor

    Spike result (Docker 27.4, tmpfs work volume held by a keeper, as in production):

    Mount the work volume again at each directory above a nested gitlink: --mount type=volume,source=<work volume>,target=/work/<dir>,volume-subpath=<dir>. A mountpoint cannot be renamed or removed, so the gitlink's read-only mount can no longer be carried away with its parent.

    Action (agent user, no capabilities) Result
    mv or rmdir of a directory above a nested gitlink (a, a/deps) refused (EBUSY)
    write or mkdir in the gitlink (a/deps/inner) refused (EROFS, from #81)
    create a file or directory inside a pinned directory allowed
    rename a sibling directory (a/other) allowed
    mv of a file into a pinned directory allowed (copied across the mount)
    hard link across a pinned directory refused (EXDEV)

    The subpath mounts keep the volume's nosuid and nodev, and writes land on the same volume with the same limits. volume-subpath needs Docker 26 or later.

    Decision: implement this rather than refuse heads with nested gitlinks. The work is stacked on #100.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions