Skip to content

Projects and workspaces

octomate.config.projects

ProjectsConfig

ProjectsConfig = dict[str, Create]

octomate.config.mirrors

How project mirrors are synced, and the identity on the commits Octomate makes.

GitIdentity pydantic-model

Bases: BaseModel

The identity on commits Octomate itself makes — a directory mirror's sync commits today, thread-branch turn commits later. The machine's by default, so its record-keeping is never attributed to whoever's dotfiles are installed, and a fresh server commits without a git config --global first.

Fields:

Source code in octomate/config/mirrors.py
class GitIdentity(BaseModel):
    """The identity on commits Octomate itself makes — a directory mirror's sync
    commits today, thread-branch turn commits later. The machine's by default, so
    its record-keeping is never attributed to whoever's dotfiles are installed,
    and a fresh server commits without a `git config --global` first."""

    name: str = "octomate"
    # example.com because it is the domain RFC 2606 reserves for exactly this:
    # a real-looking address that is guaranteed to belong to nobody.
    email: EmailStr = "octomate@example.com"

    @property
    def commit_flags(self) -> tuple[str, ...]:
        """The `-c` flags that make a commit this identity's.

        Passed per invocation rather than written with `git config`, so nothing
        persists into a repository for whatever Octomate makes from it next to
        inherit. Signing is off: these commits are the machine's record-keeping,
        and nothing a host's signing key should be vouching for.
        """
        return (
            "-c",
            f"user.name={self.name}",
            "-c",
            f"user.email={self.email}",
            "-c",
            "commit.gpgsign=false",
        )

name pydantic-field

name: str = 'octomate'

email pydantic-field

email: EmailStr = 'octomate@example.com'

commit_flags property

commit_flags: tuple[str, ...]

The -c flags that make a commit this identity's.

Passed per invocation rather than written with git config, so nothing persists into a repository for whatever Octomate makes from it next to inherit. Signing is off: these commits are the machine's record-keeping, and nothing a host's signing key should be vouching for.

MirrorsConfig pydantic-model

Bases: BaseModel

How project mirrors are synced.

Fields:

Source code in octomate/config/mirrors.py
class MirrorsConfig(BaseModel):
    """How project mirrors are synced."""

    freshness_window: float = Field(
        default=0.0,
        ge=0.0,
        description=(
            "Seconds within which a synced mirror is current enough to fork "
            "without asking the upstream again. Zero on purpose: a failed fetch "
            "already degrades to the stale mirror, so this is purely a "
            "performance knob, and there is no number to set it to before the "
            "fetch cost is measured where the server actually runs."
        ),
    )
    identity: GitIdentity = Field(
        default_factory=GitIdentity,
        description="The identity on commits Octomate itself makes.",
    )

freshness_window pydantic-field

freshness_window: float = 0.0

Seconds within which a synced mirror is current enough to fork without asking the upstream again. Zero on purpose: a failed fetch already degrades to the stale mirror, so this is purely a performance knob, and there is no number to set it to before the fetch cost is measured where the server actually runs.

identity pydantic-field

identity: GitIdentity

The identity on commits Octomate itself makes.

octomate.config.workspaces

Workspace reclamation: how long a thread's fork may sit idle, and how often the sweep looks.

WorkspacesConfig pydantic-model

Bases: BaseModel

When a thread's workspace is reclaimed.

Fields:

Source code in octomate/config/workspaces.py
class WorkspacesConfig(BaseModel):
    """When a thread's workspace is reclaimed."""

    idle_window: float = Field(
        default=24 * 60 * 60.0,
        gt=0.0,
        description=(
            "Seconds a workspace goes unused before the sweep may reclaim it, "
            "measured from the last turn that ran in it. Generous by default: "
            "every turn leaves its work in the mirror, so reclaiming early costs "
            "a resume and never the work — but a resume is a fork and a checkout, "
            "and a fork nobody has touched for a day is what the disk is for. "
            "Shorten it on a host tight for space, not to tidy up."
        ),
    )
    sweep_interval: float = Field(
        default=60 * 60.0,
        gt=0.0,
        description=(
            "Seconds between sweeps. Every idle workspace is snapshotted again to "
            "prove the mirror already has it, so this is work proportional to how "
            "many are lying around; there is nothing to gain by looking often."
        ),
    )

idle_window pydantic-field

idle_window: float = 24 * 60 * 60.0

Seconds a workspace goes unused before the sweep may reclaim it, measured from the last turn that ran in it. Generous by default: every turn leaves its work in the mirror, so reclaiming early costs a resume and never the work — but a resume is a fork and a checkout, and a fork nobody has touched for a day is what the disk is for. Shorten it on a host tight for space, not to tidy up.

sweep_interval pydantic-field

sweep_interval: float = 60 * 60.0

Seconds between sweeps. Every idle workspace is snapshotted again to prove the mirror already has it, so this is work proportional to how many are lying around; there is nothing to gain by looking often.