Problem
gardener start daemon currently can only run the sync sweep in two modes:
- default:
gardener sync (detect only, no side effects)
--sync-apply: gardener sync --apply (opens one aggregated tree PR)
There is no way to configure the daemon to run gardener sync --open-issues, which is the mode that opens one tree issue per drift proposal (then breeze picks them up and dispatches gardener draft-node → per-proposal tree PR). This is the issue-first workflow we've been testing end-to-end since #277.
So the issue-first chain (source PR → tree issue → breeze → draft-node PR) cannot be kept running autonomously. The only option today is to run sync --open-issues by hand or via a side cron — the daemon doesn't help.
Proposal
Refactor the daemon sync-sweep flag into a single enum, replacing --sync-apply:
--sync-mode <detect|apply|open-issues>
detect Default. Run `gardener sync` only. No writes.
apply Run `gardener sync --apply`. One aggregated tree PR.
open-issues Run `gardener sync --open-issues`. One tree issue per drift
proposal, assignees resolved from NODE.md owners by default.
Keep --sync-apply as a deprecated alias of --sync-mode apply for one minor version (warn on use, remove in next minor).
Also add:
--sync-assignee USER
Optional. Override NODE.md-resolved owners for every issue opened by
`--sync-mode open-issues`. Matches the semantics of `gardener sync
--open-issues --assignee USER`. Intended for testing against third-party
open-source repos where you don't want to ping real domain owners.
When omitted, issues assign to NODE.md owners (production default).
Why enum over independent flags
--sync-apply and a hypothetical --sync-open-issues can't both run in the same sweep — they produce two overlapping tree-write workflows (one aggregated PR + N draft-node PRs for the same proposals), which would conflict. Making them modes of a single --sync-mode flag makes the mutual exclusion structural instead of a runtime check.
Why --sync-assignee as a separate flag
--sync-mode open-issues is the only mode that takes an assignee (detect/apply don't). Gating it behind open-issues in the parser prevents the user from passing it in the wrong mode.
Implementation sketch
Files to touch (all under `src/products/gardener/`):
- `engine/commands/start.ts` — CLI parsing: add `--sync-mode` + `--sync-assignee`; deprecate `--sync-apply` as alias with a warning; update USAGE string.
- `engine/daemon/config.ts` — Extend `DaemonConfig`: replace `syncApply: boolean` with `syncMode: 'detect' | 'apply' | 'open-issues'`; add `syncAssignee?: string`. Keep `syncApply` in the raw config parser for backward compat (maps to `syncMode: 'apply'`, logs deprecation warning).
- `engine/daemon/loop.ts` — Where `syncApply` is read (line ~169), switch on `syncMode`:
- `detect` → no extra args
- `apply` → push `--apply`
- `open-issues` → push `--open-issues`; if `syncAssignee` set, also push `--assignee `
- `skills/first-tree/references/onboarding.md` — Step 6.x: document `gardener start --sync-mode open-issues` as the way to keep the issue-first chain running autonomously.
- `skills/gardener/SKILL.md` — same.
Expected change: ~30-50 lines code + ~100-200 lines tests.
Acceptance criteria
E2E testing requirement
The implementation PR must include a genuine end-to-end test, not just unit tests on the parser / loop:
This test can extend `tests/gardener/sync-open-issues.test.ts` + `tests/gardener/daemon/*`. A mock of the GitHub + breeze surface is fine as long as it exercises the real daemon loop path (not just the CLI parse layer).
Why this matters
Without this, the autonomous issue-first workflow (the one documented in onboarding.md Step 6 and tested end-to-end in v0.2.14/v0.2.15) requires the user to run `sync --open-issues` manually or via a side cron. That defeats the purpose of having a `gardener start` daemon.
Env / context
/cc @serenakeyitan
Problem
gardener startdaemon currently can only run the sync sweep in two modes:gardener sync(detect only, no side effects)--sync-apply:gardener sync --apply(opens one aggregated tree PR)There is no way to configure the daemon to run
gardener sync --open-issues, which is the mode that opens one tree issue per drift proposal (then breeze picks them up and dispatchesgardener draft-node→ per-proposal tree PR). This is the issue-first workflow we've been testing end-to-end since #277.So the issue-first chain (source PR → tree issue → breeze → draft-node PR) cannot be kept running autonomously. The only option today is to run
sync --open-issuesby hand or via a side cron — the daemon doesn't help.Proposal
Refactor the daemon sync-sweep flag into a single enum, replacing
--sync-apply:Keep
--sync-applyas a deprecated alias of--sync-mode applyfor one minor version (warn on use, remove in next minor).Also add:
Why enum over independent flags
--sync-applyand a hypothetical--sync-open-issuescan't both run in the same sweep — they produce two overlapping tree-write workflows (one aggregated PR + N draft-node PRs for the same proposals), which would conflict. Making them modes of a single--sync-modeflag makes the mutual exclusion structural instead of a runtime check.Why
--sync-assigneeas a separate flag--sync-mode open-issuesis the only mode that takes an assignee (detect/apply don't). Gating it behindopen-issuesin the parser prevents the user from passing it in the wrong mode.Implementation sketch
Files to touch (all under `src/products/gardener/`):
Expected change: ~30-50 lines code + ~100-200 lines tests.
Acceptance criteria
E2E testing requirement
The implementation PR must include a genuine end-to-end test, not just unit tests on the parser / loop:
This test can extend `tests/gardener/sync-open-issues.test.ts` + `tests/gardener/daemon/*`. A mock of the GitHub + breeze surface is fine as long as it exercises the real daemon loop path (not just the CLI parse layer).
Why this matters
Without this, the autonomous issue-first workflow (the one documented in onboarding.md Step 6 and tested end-to-end in v0.2.14/v0.2.15) requires the user to run `sync --open-issues` manually or via a side cron. That defeats the purpose of having a `gardener start` daemon.
Env / context
gardener sync --open-issues --assignee <user>to override NODE.md owners for testing #302 (`--assignee` flag on sync), docs(onboarding): default to breeze-first setup; drop push/pull framing #326 (onboarding.md breeze-first rewrite)./cc @serenakeyitan