Repository navigation
Description
What to build
Deepen Cron job interpretation so Cron jobs, Launch directory discovery and Console “Run now” choices obtain their facts through one interface. Today a maintainer has to follow separate interpretations of the same shell text to understand why an entry is shown, has a Command kind, identifies a repository or offers a start choice. Recent directory-changing-command fixes and the follow-up sharing of literal argument trimming show this friction in active code.
Keep the current recognition rules and visible results. This is one standalone Ticket: the interpretation, three callers, glossary addition and verification fit one fresh context window.
Acceptance criteria
- One Cron job interpretation module owns command-text recognition, Cron’s command/stdin split, literal shell tokenization, Command-kind classification, Launch facts, output-log extraction and parsing of the possible start command. Callers consume domain facts; shell words, redirect trimming and compound scanning are private implementation.
- Entry inclusion remains independent of successful shell or CLI parsing: unknown arguments, malformed quoting and display-only expressions can still appear in Cron jobs. Original schedule/command text, stable repository ordering and duplicate entries are retained.
- The independent projections satisfy the compatibility table below. In particular, a recognized Command kind does not imply a Launch directory or “Run now”, and directory discovery does not imply a recognized kind or start choice.
- The interpretation preserves first-unescaped-
%handling even inside quotes; literal-path restrictions; dollar/backtick rejection where currently applied; directory-changing-command detection including its recognized launch forms; attached numeric redirect tokens; standalone numeric CLI arguments; and the existing stdout-only output-log selection. - Launch directory resolution retains canonicalization, GitHub-origin validation, configured-directory merging/deduplication and output-log selection. Missing or unsuitable checkouts stay unresolved; discovery executes no Cron command.
- Cron jobs CLI/JSON, owning-machine Console responses, Fleet inventories and Console start choices retain their existing field shapes, labels, scopes and metadata ownership, including legacy entries with absent repository/kind metadata. Request construction and submission still apply their existing supported-Pass and CLI validation.
- A behavior table tested through the interpretation interface checks the related facts together. Existing command and Console/browser regressions remain, with cross-projection characterization for accepted compounds, environment launchers and malformed entries where current coverage is separate or missing.
- Add Cron job to
GLOSSARY.md: an entry in a machine account’s operating-system crontab that mentions thirdshift; its recorded schedule and command are shown even when its Launch directory or Command kind cannot be recognized, and a displayed entry need not offer a Console start choice. Update the domain-to-code index to locate the interpretation and its tests. - Final local validation uses
scripts/affected-tests main, including the selected Console/browser checks.
Compatibility table: assume a literal absolute or home-relative initial path resolves to a GitHub checkout unless stated otherwise.
| Cron command text | Shown | Command kind | Launch directory | Run now |
|---|---|---|---|---|
Direct thirdshift pickup, no initial cd |
Yes | Pickup run | None | Omitted |
Initial literal cd, then plain thirdshift pickup |
Yes | Pickup run | Resolved | Offered |
Initial literal cd, then env X=1 thirdshift pickup |
Yes | Unknown | Resolved | Omitted |
Initial literal cd, then thirdshift status --json or unknown arguments |
Yes | Unknown | Resolved | Omitted |
Initial literal cd, CLI arguments containing dollar/backtick expansion |
Yes | Unknown | Can resolve | Omitted |
| Plain Pickup text with a missing/non-GitHub initial checkout | Yes | Pickup run | Unresolved | Omitted |
| A recognized directory-changing command before the selected thirdshift command | Yes | Unknown | Unresolved | Omitted |
Initial literal cd, then plain Pickup followed by another && command |
Yes | Unknown | Resolved | Offered for the selected Pickup, as today |
Initial literal cd, then targeted Fix/Review, or Triage |
Yes | Fix/Review/Triage run | Resolved | Omitted |
| Text mentioning thirdshift with malformed shell quoting | Yes | Unknown | Unresolved | Omitted |
Blocked by
None (can start immediately). #1998 adds quota estimates to Fleet schedules, but does not gate this behavior-preserving deepening.
Decisions
The design tree is settled in three rounds. Dependencies are: scope → ownership/interface → projections/caller migration → tests; compatibility constraints → adapters/error handling → tests; naming → glossary work. Each branch below is settled.
Round 1 — scope and ownership
- Deepen interpretation, in one Ticket. Consolidate the roughly 200 lines of literal parsing plus classification used by the three callers. This earns depth because it absorbs compound selection, expansion rejection, redirect distinctions and independent recognition policies; a mere shared trimming helper already exists and still leaves callers coordinating the rest. Deleting the proposed module would put those decisions back into multiple callers. No release or host step gates this refactor.
- Keep the implementation under the Cron jobs module, reached through its existing crate interface. Launch directory discovery and Console start choices depend on that interpretation instead of obtaining lexical operations from Launch directory discovery. Cron jobs owns Cron syntax; Launch directory discovery owns filesystem/repository resolution. This concentrates knowledge without inventing another top-level module.
- Use existing dependencies and seams. The CLI parser remains the authority on thirdshift arguments, and home expansion uses the existing rules with the home path supplied by the caller. The interpretation is in-process and performs no filesystem reads or process execution. Existing local command adapters still read the crontab and Git origin; no new trait or replaceable shell adapter is justified.
Round 2 — interface, compatibility and migration
- Create one owned interpretation from command text. It exposes entry recognition, optional Command kind and Launch facts projected with an explicit home path supplied only by callers that need directory facts. Launch facts contain the literal directory, selected output-log path and optionally the parsed CLI Command. Text-only recognition/classification acquires no new configuration or home-directory dependency. Tokenize once per interpretation and keep tokens private. Lexical entry recognition survives failed tokenization, so malformed-but-visible entries are representable. Use the existing owned CLI Command by reference for classification and consume it when constructing a start request; no Clone requirement or new wire type is needed.
- Preserve independent recognition policies inside that interface. Kind classification accepts a direct thirdshift invocation or one initial literal directory change, rejects environment launchers and shell compounds, then uses the existing CLI parser. Launch facts require an initial literal directory change, retain the current scan through compound pieces and stop at recognized directory-changing commands. Environment-launcher words stay attached for start parsing, so discovery can identify the checkout without offering a start that drops its environment. A failed CLI parse can therefore coexist with valid Launch facts.
- Keep start eligibility in Console start choices. The interpretation supplies the parsed candidate; the Console retains its supported-Pass matching, flag/request conversion, Harness selection and submission validation. Kind recognition covers more commands than “Run now”; combining those policies would change behavior. Preserve current selected-command handling for compounds rather than adding shell execution or broadening support.
- Keep path/origin checks in Launch directory discovery. Canonicalize and resolve supplied Launch facts there, retaining the current checks for start candidates and the existing configured-directory precedence. The interpreter supplies a possible path, not an assertion that a checkout exists. Keep command/stdin separation and all redirect rules private to interpretation; output-log extraction remains narrower than argument redirect trimming because stderr-only redirects are not the Console output log.
- Migrate all three callers and remove their lexical coordination. Inventory inclusion/classification, Launch directory discovery and Console start choices all consume the new facts. Retire the exported Cron-only shell-word, argument-trimming and raw-text interpretation helpers. Crontab reads, inventory assembly, rendering and request construction retain their current responsibilities. This provides leverage to all callers while avoiding an unrelated snapshot/caching refactor.
- Preserve failure and transport behavior. Unrecognized text produces absent facts rather than failing an otherwise displayable entry. Missing
crontaband other read errors continue through their existing caller-specific handling. Keep repository-label validation, remote/legacy deserialization, owning-machine metadata and read/run scope checks where they already live; remote inventories are not reinterpreted on the receiving machine. These are established contracts, not design choices reopened by this refactor.
Round 3 — verification and documentation
- The interface is the test surface. Table-driven tests exercise a full interpretation’s recognition, kind, Launch facts, log and parsed command together, rather than testing token transformations. Keep command regressions using the existing crontab/Git fixtures and browser tests for “Run now” requests, numeric options and display-only entries. Add joint checks against the same fake crontab for inventory metadata, discovered directories and start options, including the compatibility table’s policy differences. Existing production and fake command adapters already supply the integration seam; no new mock interface is needed.
- Name the existing concept and record its location. Add the Cron job definition and update the domain-to-code index in this Ticket’s implementation, because the glossary currently lacks that term. No ADR change is warranted: this reversible ownership change preserves ADR 0009’s operating-system scheduling and the Console parity/owning-machine rules in the applicable ADR 0026.
Architecture review
Strength: Strong · Dependencies: in-process
Files: src/cronjobs.rs, new src/cronjobs/command.rs, src/launch_directories.rs, src/console/start_controls.rs, tests/console/cronjobs.rs, tests/console/start.rs, console/tests/start.test.cjs, GLOSSARY.md, docs/code-navigation.md
Before — interpretation calls
flowchart LR
C["Cron jobs module"] --> K["Command kind"]
C --> L["Launch directory module"]
L --> D["Launch facts"]
R["Console start choices module"] --> D
K -.-> S["Literal shell parsing"]
D -.-> S
R -.-> S
K --> A["CLI parser module"]
R --> A
classDef leak stroke:#dc2626,stroke-width:2px;
class K,D,R leak
After — interpretation calls
flowchart LR
C["Cron jobs module"] --> I
L["Launch directory module"] --> I
R["Console start choices module"] --> I
subgraph I["Cron job interpretation module"]
S["Literal shell parsing"] --> K["Command kind"]
S --> D["Launch facts"]
K --> A["CLI parser module"]
D --> A
end
classDef deep stroke-width:3px;
class I deep
Problem: Cron job interpretation has a shallow interface of exposed lexical operations, spreading its implementation across the seam between inventory, Launch directory discovery and Console start choices.
Evidence: command_kind borrows Launch directory lexical operations, cron_invocation selects an invocation independently, and Console start choices parse the selected arguments again; 56743643 shared trimming without owning those policies.
Solution: Deepen one Cron job module whose interface owns literal interpretation and independent recognition facts, retaining the existing CLI parser and command adapter.
Wins
- Depth: interpretation behind one interface
- Locality: one interpretation policy
- Leverage: three callers share facts
- Tests cross the same seam
Covered by: None; the titles and bodies of all 167 open issues were checked, then the list was refreshed before publication. #1998 adds schedule/quota estimates, #1960 adds Pass skip history, and #301 concerns cron setup; none proposes this deepening.
Activity