Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions GLOSSARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ One invocation of the factory with no **Issue URL**: a **Security audit** of the
_Avoid_: Fencing (former name), Secure run (it reads as a run that is secure), audit run, security pass

**Pass**:
An **Architect run**, a **Pickup run** or a **Security run**: a **Command** started with no **Issue URL**, which decides before any work whether it is skipped.
An **Architect run**, a **Pickup run**, a **Security run**, or a **Custom process** started with no issue: a **Command** started with no **Issue URL**, which decides before any work whether it is skipped. A Custom process started with no issue is skipped while another Pass on the same repository is still running on the machine, its Spec run or Ticket run included, and it does not take an Architect run's Ready-issue or Architect-idea gates. A Custom process started with an issue is not a Pass.
_Avoid_: tick, cycle

### Architecture
Expand Down Expand Up @@ -259,7 +259,7 @@ _Avoid_: cron log, output log, run log (a **Ticket run** is one kind of command)
The retained Command logs and Session traces available to list on a machine, each naming an exact file under the User config's log folder. A Command's referenced Session traces may include files outside that inventory.

**Activity log**:
One running record per repository of what the factory did there: a line when a **Ticket run**, **Spec run**, **Architect run**, **Pickup run** or **Security run** starts work, naming its **Command log**, a line when it is given a **Stop** or a **Dismissal**, or a Dismissal is taken back, naming who asked and whether from the CLI or the **Console**, and a line when it ends, with its outcome. A skipped Architect run, Pickup run or Security run writes a line only when its reason differs from the last one recorded for its kind, so a repository that sits idle shows one line, not one per pass. It is what thirdshift writes about a scheduled pass, in place of output to the scheduler.
One running record per repository of what the factory did there: a line when a **Ticket run**, **Spec run**, **Architect run**, **Pickup run** or **Security run** starts work, naming its **Command log**, a line when it is given a **Stop** or a **Dismissal**, or a Dismissal is taken back, naming who asked and whether from the CLI or the **Console**, and a line when it ends, with its outcome. A skipped Architect run, Pickup run or Security run writes a line only when its reason differs from the last one recorded for its kind, so a repository that sits idle shows one line, not one per pass. A skipped Custom process started with no issue writes `Process <name> skipped: <reason>` when that is not already the last Process line. It is what thirdshift writes about a scheduled pass, in place of output to the scheduler.
_Avoid_: cron log, pass log, history

**Command record**:
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ Use `thirdshift help` for the command reference, or read [Ticket run behavior](d
| A security audit | `thirdshift secure` | A [Security run](docs/guide.md#security-runs) records findings privately; fixing a reproduced finding is optional. |
| Merged factory work | `thirdshift score` | A [Scoring run](docs/guide.md#scoring-runs) samples and grades it, and proposes Bug origins; `thirdshift scores --json` lists samples, five criterion Scores, calibration and proposals by week; `thirdshift scores <pull request> --mine` records yours before revealing the model's. |
| One skill | `thirdshift skill <skill> [issue <issue>]` | A [standalone skill](docs/guide.md#standalone-skills) runs headlessly and prints its final message. |
| A Custom process | `thirdshift process <name> [issue <issue>]` | An experimental [Custom process](docs/guide.md#custom-processes) runs skill or command Steps from `~/.thirdshift/processes/<name>.toml`, in named throwaway worktrees when the file declares them. An optional Step can fail without stopping the process. `issue <issue>` gives every session Step that issue. |
| A Custom process | `thirdshift process <name> [issue <issue>]` | An experimental [Custom process](docs/guide.md#custom-processes) runs skill or command Steps from `~/.thirdshift/processes/<name>.toml`, in named throwaway worktrees when the file declares them. An optional Step can fail without stopping the process. `issue <issue>` gives every session Step that issue. With no issue it is a Pass and skips while another Pass on the repository is running. |

Each Architect, Pickup or Security run makes one pass. Use cron or another operating system scheduler to repeat it. See [scheduling](docs/guide.md#on-a-schedule), [Architect runs every few minutes](docs/guide.md#architect-runs-every-few-minutes) and [Security runs on a schedule](docs/guide.md#security-runs-on-a-schedule-with-fixing-allowed).

Expand Down
8 changes: 5 additions & 3 deletions docs/guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ A [Ticket run](#what-a-ticket-run-does), one issue in and one pull request out,
- **[Pickup run](#pickup-runs)**, `thirdshift pickup`: takes the lowest-numbered **Ready issue** by default, the highest-numbered with `pickup.order = "highest-first"` or `highest-first` on the command, and runs it.
- **[Security run](#security-runs)**, `thirdshift secure`: audits the **Base branch** and records each **Security finding** privately. It is report-only by default; with fixing allowed, it fixes one finding it reproduced.

Architect, Pickup and Security runs are **Passes**: they take no Issue URL, so your operating system's scheduler can start them. See [A Pickup run on a schedule](#a-pickup-run-on-a-schedule), [Architect runs every few minutes](#architect-runs-every-few-minutes) for Architect runs, and [Security runs on a schedule, with fixing allowed](#security-runs-on-a-schedule-with-fixing-allowed) for Security runs.
Architect, Pickup and Security runs are **Passes**, as is a Custom process started with no issue: they take no Issue URL, so your operating system's scheduler can start them. A Custom process started with an issue is not a Pass. See [A Pickup run on a schedule](#a-pickup-run-on-a-schedule), [Architect runs every few minutes](#architect-runs-every-few-minutes) for Architect runs, and [Security runs on a schedule, with fixing allowed](#security-runs-on-a-schedule-with-fixing-allowed) for Security runs.

Every session runs on the **Harness** you choose: Claude Code by default, or Codex, Antigravity CLI, Grok Build, Muse Code or OpenCode. See [Harness, Model and Effort](#harness-model-and-effort).

Expand Down Expand Up @@ -1003,6 +1003,8 @@ command that exits non-zero is failed, and the line names its exit status.
Stop and Ctrl-C interrupt a command Step the way they interrupt a session,
and `[resources]` is checked before each Step.

A Custom process started with no issue is a [Pass](#one-at-a-time). While another Pass on the repository is still running, its Spec run or Ticket run included, `thirdshift process <name>` is skipped: it prints `another Pass is already running on <owner>/<repo>`, prints nothing on stdout, exits `0` and sends no Run notification. It creates no worktree and starts no Step. While it runs, a Pickup run on the same repository is skipped. It does not take an Architect run's Ready-issue or Architect-idea gates, so a Ready issue or an Architect idea waiting for triage does not skip it. The Command record's outcome is `skipped`, and its cause is that reason. The Activity log records `Process <name> skipped: <reason>` when that is not already the last Process line. With `activity.quiet_skips` set, a skipped Process prints nothing. `thirdshift process <name> issue <issue>` is not a Pass: this rule does not skip it, and it does not hold the lock.

### User config

A **User config** at `~/.thirdshift/config.toml` sets this machine's defaults for every Ticket run. It is optional: with no file, or one that says nothing about a setting, a Ticket run does only what its command asks for.
Expand Down Expand Up @@ -1411,7 +1413,7 @@ When a Command that produces a [Run notification](#run-notifications) ends, its

A Resume is logged as its session's kind plus `-resume`, e.g. `implement-resume.logs.jsonl`.

A **Command log** is everything one command printed, stderr and stdout in the order printed, while the terminal still shows all of it. Its folder is the command typed: `thirdshift <Issue URL>`, a Ticket run or a Spec run, in `issue/`, `thirdshift pickup` in `pickup/`, named for the issue it took, and `thirdshift architect` in `architect/`. A Spec run's covers its Tickets' runs, a Ticket run's covers its [Base fix](#base-fix), and a Pass's covers the Spec run or Ticket run it dispatched: none of those keeps one of its own. So `ls -t ~/.thirdshift/logs/acme/widgets/commands/pickup/*.log | head` lists the recent passes on acme/widgets that took an issue. A command keeps its Command log once it starts work: a Pass skipped before doing any work keeps none, nor does a Ticket run that fails before it starts work, as on the [Origin match](#what-a-ticket-run-does), and `setup`, `email-test`, `update`, `version` and `help` never keep one. Lines printed before the Command log's name is known, such as a Pickup run's lines on the issues it [passed over](#why-an-issue-was-passed-over) before it took one, are written first, and once it is created a progress line says `logging this command to <path>`. A Command log that can't be written produces one `warning:` line on stderr. A failure confined to the Command log leaves the outcome, stdout and exit code unchanged; if the shared folder also prevents writing a Session trace, the Ticket run fails before starting that session.
A **Command log** is everything one command printed, stderr and stdout in the order printed, while the terminal still shows all of it. Its folder is the command typed: `thirdshift <Issue URL>`, a Ticket run or a Spec run, in `issue/`, `thirdshift pickup` in `pickup/`, named for the issue it took, and `thirdshift architect` in `architect/`. A Spec run's covers its Tickets' runs, a Ticket run's covers its [Base fix](#base-fix), and a Pass's covers the Spec run or Ticket run it dispatched: none of those keeps one of its own. So `ls -t ~/.thirdshift/logs/acme/widgets/commands/pickup/*.log | head` lists the recent passes on acme/widgets that took an issue. A command keeps its Command log once it starts work: a Pickup run, Architect run or Security run skipped before doing any work keeps none, nor does a Ticket run that fails before it starts work, as on the [Origin match](#what-a-ticket-run-does). A Custom process started with no issue that is skipped keeps a Command record whose outcome is `skipped`, beside the Command log of the lines it held. `setup`, `email-test`, `update`, `version` and `help` never keep one. Lines printed before the Command log's name is known, such as a Pickup run's lines on the issues it [passed over](#why-an-issue-was-passed-over) before it took one, are written first, and once it is created a progress line says `logging this command to <path>`. A Command log that can't be written produces one `warning:` line on stderr. A failure confined to the Command log leaves the outcome, stdout and exit code unchanged; if the shared folder also prevents writing a Session trace, the Ticket run fails before starting that session.

The stamp is the local time the command started, with its UTC offset, as in `20261003T120000-0400`, in the machine's time zone, or `TZ`'s if set, so it agrees with `date` and `ls -l`. A command's Command log and all of its Session traces, its Tickets' runs' and its Base fix's included, share that one stamp, so they sort together and each can be found from the other. When a Ticket run fails, stderr ends with the path of the Session trace of the session its cause came from, the place to start looking, then that of its Command log. A failed implement session, Spec review or Repair names its own log, as does a [Security review](#security-review) whose hold is reported only after later Repairs. A cause that came from no session, such as red CI with the Repairs used up, a Declined CI fix, the upstream-move budget, a Harness check or a git or GitHub error, names the most recent Session trace. A Spec run whose Tickets are not done names the Session trace of the one Ticket whose Ticket run failed, and none if several did, as no single session caused it; each failed Ticket's line gives its own. The Command log's closing `session trace:` line and the [Run notification](#run-notifications) give the same path.

Expand Down Expand Up @@ -1653,7 +1655,7 @@ The rule doesn't ask whether anything will take the Ready issue. A `ready-for-ag

A **Pass** is a command started with no Issue URL that decides before any work whether it is skipped. Only one Pass per repository runs at a time on a machine. A Pass started while another on the same repository is still running, the Spec run or Ticket run it dispatched included, is **skipped**: it prints `another Pass is already running on <owner>/<repo>` as a progress line on stderr, prints nothing on stdout, and exits `0`. Skipped is not a failure. A skipped Pass does nothing else: no launch pull, no worktree, no agent session, and no issue filed or labelled. This holds for every Pass, however it was started, so two never build one repository at once.

The repository is the one `origin` names, so two clones of one repository count as the same, and Passes on different repositories run at the same time. A Ticket run or a Spec run started on an **Issue URL** is never skipped this way, and never makes a Pass skip.
The repository is the one `origin` names, so two clones of one repository count as the same, and Passes on different repositories run at the same time. A Ticket run or a Spec run started on an **Issue URL** is never skipped this way, and never makes a Pass skip. A Custom process started with an issue is the same. A Custom process started with no issue is a Pass for this rule only: it does not take an Architect run's Ready-issue or Architect-idea gates. Its skip keeps a Command record whose outcome is `skipped`.

thirdshift holds the rule with an operating-system lock on a file under `~/.thirdshift/architect-locks/`, shared by every kind of Pass, which the Pass's process takes without waiting, after its checks in step 1, and holds until it exits. The directory keeps its original name so older thirdshift versions share the lock too. The operating system releases the lock when that process ends for any reason, a crash, a kill or a reboot included, so there is never a stale lock to clear: the next Pass on the repository runs normally. The file itself stays, and means nothing on its own. A review worktree that a killed Architect run left behind is removed by the next one.

Expand Down
4 changes: 2 additions & 2 deletions site/architecture/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -478,8 +478,8 @@ <h1>Architecture</h1>
<div class="wrap">
<div class="sec-head"><p class="eyebrow">Figure 5 · <code>thirdshift pickup</code>, <code>architect</code>, <code>secure</code></p><h2 id="passes-title">The Passes: the factory finds its own work</h2></div>
<p>Before selecting a Ready issue, Pickup files one ordinary bug Ticket when the Base branch's latest push CI failed more than 30 minutes ago and no CI-red Ticket is open. Concurrent hosts reserve filing on origin. CI read failures warn and leave Pickup running; this check does not hold Self-merges.</p>
<p>Once a Pass knows its repository, it replaces that kind's last-fired time under the repository's log folder, before launch checks or the local Pass lock. Repeated skips update the time without adding Activity log lines. <code>thirdshift status</code>, <code>thirdshift cronjobs</code> and their Console views read the same per-repository times; no reader starts work.</p>
<p class="lede">A <strong>Pass</strong> takes no Issue URL, so your operating system's scheduler can start it; thirdshift never schedules itself. Only one Pass runs on a repository at a time, and a Pass with nothing to do is skipped, not failed. Architect and Security runs wait while a Ready issue is open, so work you shaped goes first. Your scheduler can start <a href="/docs/#architect-runs-every-few-minutes">Architect runs every few minutes</a> and <a href="/docs/#security-runs-on-a-schedule-with-fixing-allowed">Security runs on a schedule, with fixing allowed</a>.</p>
<p>Once a Pickup run, an Architect run or a Security run knows its repository, it replaces that kind's last-fired time under the repository's log folder, before launch checks or the local Pass lock. Repeated skips update the time without adding Activity log lines. <code>thirdshift status</code>, <code>thirdshift cronjobs</code> and their Console views read the same per-repository times; no reader starts work. A Custom process started with no issue shares the lock and does not record a last-fired time.</p>
<p class="lede">A <strong>Pass</strong> takes no Issue URL, so your operating system's scheduler can start it; thirdshift never schedules itself. Only one Pass runs on a repository at a time, and a Pass with nothing to do is skipped, not failed. Architect and Security runs wait while a Ready issue is open, so work you shaped goes first. A Custom process started with no issue is a Pass for that one-at-a-time rule and does not wait on a Ready issue or an Architect idea. One started with an issue is not a Pass. Your scheduler can start <a href="/docs/#architect-runs-every-few-minutes">Architect runs every few minutes</a> and <a href="/docs/#security-runs-on-a-schedule-with-fixing-allowed">Security runs on a schedule, with fixing allowed</a>.</p>
<figure class="arch-fig">
<div class="arch-scroll" tabindex="0" role="group" aria-label="Figure 5, scrolls sideways on narrow screens"><svg class="arch-svg" viewBox="0 0 1000 334" role="img" aria-labelledby="fig-passes-title" aria-describedby="fig-passes-desc"><title id="fig-passes-title">The three Passes</title><desc id="fig-passes-desc">The operating system’s scheduler starts three kinds of Pass, each taking no Issue URL. A Pickup run sweeps closed issues, respects the Claim limit and runs the lowest-numbered Ready issue by default. An Architect run reviews the architecture and either publishes a plan, which it builds with a Ticket run or Spec run, or files an idea for the Day shift to triage. A Security run audits the Base branch, reproduces findings, records each privately and, when fixing is allowed, files a fix issue and runs it. Its target code may run only inside an OS-enforced sandbox, as the Security audit skill requires.</desc><defs><marker id="fig-passes-ink" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="6" markerHeight="6" orient="auto-start-reverse"><path class="mk ink" d="M0 0 10 5 0 10z"/></marker><marker id="fig-passes-faint" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="6" markerHeight="6" orient="auto-start-reverse"><path class="mk faint" d="M0 0 10 5 0 10z"/></marker><marker id="fig-passes-acc" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="6" markerHeight="6" orient="auto-start-reverse"><path class="mk acc" d="M0 0 10 5 0 10z"/></marker><marker id="fig-passes-agent" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="6" markerHeight="6" orient="auto-start-reverse"><path class="mk agent" d="M0 0 10 5 0 10z"/></marker></defs>
<path class="vm" d="M2 2H998V326H2Z"/>
Expand Down
Loading
Loading