Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
83 commits
Select commit Hold shift + click to select a range
fbc8c7b
fix: atomically set updatedAt=auditedAt in saveAuditResult (WL-0MTHRW…
Sep 1, 2026
e0e1946
WL-0MTHRY9NP004R9MC: Implementation complete
Sep 1, 2026
afb2142
WL-0MTHRYRU1004GCH8: Implementation complete
Sep 1, 2026
351d3a4
feat(herdr): add machine-wide coordination dir resolver (F1)
Sep 1, 2026
8526545
feat(herdr): shared machine-wide coordination file with worklogRoot (F2)
Sep 1, 2026
e47fe11
feat(herdr): single machine-wide leader lock/lease (F3)
Sep 1, 2026
a45ad00
feat(herdr): cross-root tier dispatch including critical (F4)
Sep 1, 2026
81cb5b3
feat(herdr): global slot budget single cap source with cross-root pro…
Sep 1, 2026
1ac5126
feat(herdr): safe migration + legacy retirement + log decision (F6)
Sep 1, 2026
9fd5440
docs(herdr): machine-wide downtime docs for F7
Sep 1, 2026
5be3d5b
WL-0MTJDX4M4007YH5U: Implementation complete
Sep 2, 2026
8a92b74
WL-0MTJDZY5E003D6CO: Implement critical override pre-tier check
Sep 2, 2026
1fb20ce
WL-0MTJE0FXC006WAOX: Implementation complete
Sep 2, 2026
0d248fa
fix(herdr): suppress stale immediate refresh and add trailing coalesc…
Sep 2, 2026
a0f565d
test(herdr): fair dispatch integration — alternation, critical overri…
Sep 2, 2026
7dfc902
docs: fair-scheduling contract — round-robin, critical override, curs…
Sep 2, 2026
de883b2
docs: fair-scheduling contract — round-robin, critical override, curs…
Sep 2, 2026
fcad93d
WL-0MTL4PC0Y005GXTI: Pause log carries underlying wl error on three-s…
Sep 3, 2026
9284144
fix(herdr): truncate list-mode header to terminal width (WL-0MSNI6TQ5…
Sep 4, 2026
d9ebf67
WL-0MTHSHN5V008R5L0: auto-disable dispatching when sprint is complete
Sep 4, 2026
8002159
feat: add daily standup to scheduled prompts (interval 1 day)
Sep 4, 2026
7306823
WL-0MTIAL65N004T22F: exclude needsProducerReview items from downtime …
Sep 4, 2026
b90c0f2
Merge branch 'wl-WL-0MTIAL65N004T22F-exclude-producer-review' into dev
Sep 4, 2026
c5bdc90
feat: add dispatchAt time field for time-of-day scheduled prompts (WL…
Sep 4, 2026
5594bbb
WL-0MTK1ILM2009QYB2 F1: dispatcher consumes Herdr list head (filters …
Sep 4, 2026
cae8ea8
fix: show child critical items in worklist selection list
Sep 4, 2026
1a3ff89
feat: wire getHerdrListHead to fetchNextItems (AC1-3)
Sep 5, 2026
dfbc6a4
fix: reorder active-audit check before dispatched-filter in dispatchF…
Sep 5, 2026
93259f3
WL-0MTIAL65N004T22F: docs: document needsProducerReview exclusion, fi…
Sep 5, 2026
d8da405
WL-0MTOBZZNU0009MW1: Implementation complete
Sep 5, 2026
c2a0529
WL-0MTOC12CR000NULW: Implementation complete
Sep 5, 2026
6c9e6de
WL-0MT1KJNMV0018SWP: Implementation complete
Sep 5, 2026
03be563
WL-0MT26TE72002FLKX: Implementation complete
Sep 5, 2026
379de73
WL-0MTOCBP1D009P4U3: Implementation complete
Sep 5, 2026
c134b21
WL-0MTOC170J001QMIT: Implementation complete
Sep 5, 2026
4113d58
WL-0MTOC1CHO007TXCL: Implementation complete
Sep 5, 2026
d749b19
WL-0MTOTCETU004YYIU: propagate wl error details through all mute wl-e…
Sep 5, 2026
e773731
WL-0MTK1ILM2009QYB2: coordination leader consumes Herdr head (F3) + a…
Sep 6, 2026
d60f408
WL-0MTHRW3770014H51: Implementation complete
Sep 6, 2026
40a387f
WL-0MTHRSZJK008ATDB: Implementation complete
Sep 6, 2026
227a512
WL-0MTHRY9NP004R9MC: Implementation complete
Sep 6, 2026
5f3a6de
WL-0MSLPM5ZB003TADT: Implementation complete
Sep 6, 2026
716d8b1
WL-0MSLPM5ZB003TADT: fix inReviewBucket no-audit guard and fetcher au…
Sep 6, 2026
b76d422
WL-0MTOTCETU004YYIU: bounded SQLITE_BUSY retry for downtime wl-CLI so…
Sep 6, 2026
e3a8cf6
WL-0MTGDW58X007UJDS: Implementation complete
Sep 6, 2026
112ece6
WL-0MTGDW58X007UJDS: Implementation complete
Sep 6, 2026
a3e1a25
fix(herdr): wire round-robin cursor into dispatchFromCoordination (WL…
Sep 6, 2026
3d52541
WL-0MTQ14W7L003II5A: Implementation complete
Sep 6, 2026
4e1de82
WL-0MTQL3U3H0089SIJ: Implementation complete
Sep 7, 2026
abeed4d
WL-0MTQL53QG00136SK: Implementation complete
Sep 7, 2026
893d6d2
WL-0MTR2CD4X006XI7U: Implementation complete
Sep 7, 2026
69ae52f
WL-0MTR2HLLJ009PTPJ: Implementation complete
Sep 7, 2026
c7620f1
WL-0MTR2JOTE006T3XT: Implementation complete
Sep 7, 2026
1984cd2
WL-0MTMPSCL8000O45H: Implementation complete
Sep 7, 2026
4f6f13a
chore: remove in_progress from stage defaults (WL-0MTQWB5WB0088MEH)
Sep 7, 2026
3dd6682
feat: remove in_progress from theme entries and docs (WL-0MTQZ6ZIW006…
Sep 7, 2026
e7aa330
feat: update grouping logic to remove in_progress from Group N (WL-0M…
Sep 7, 2026
6f1cb21
feat: add doctor migration for stage=in_progress rows (WL-0MTQZ801900…
Sep 7, 2026
72342a2
docs: remove stage in_progress from tutorials (WL-0MTQZ8PLC0036K7E)
Sep 7, 2026
df43c88
feat: remove in_progress from validation, delegate-helper, CLI help (…
Sep 7, 2026
a267e47
docs: harden Dispatcher anchor invariant + fix stale stage tests (WL-…
Sep 7, 2026
984419a
fix: drop duplicate ID row from herdr metadata panel data section (WL…
Sep 7, 2026
d3fe223
Merge branch 'dev' of github.com:TheWizardsCode/ContextHub into wl-WL…
Sep 7, 2026
eda87f1
feat(downtime): gate non-critical implement tier on review-queue dept…
Sep 8, 2026
f814cdb
WL-0MSJ2JFMO007PGQ6: colour code work items by priority in selection …
Sep 8, 2026
fafaf7d
WL-0MSJ2JFMO007PGQ6: add priority/stage colour tests (CLI + Herdr + s…
Sep 8, 2026
b32e6f4
WL-0MTSAAYEV007NLK3: Tests for bounded concurrent dispatch (F1 - red …
Sep 8, 2026
8cd160c
fix(herdr,cli): colour code work item IDs by priority and fix medium/…
Sep 8, 2026
0bfe3d9
WL-0MTSAB0QU003KTLA: add downtimeMaxConcurrentDispatches setting (F2)
Sep 8, 2026
cc0eaf2
WL-0MTSAB5RR0023799: implement bounded concurrent downtime dispatches…
Sep 8, 2026
f2aa167
fix: keep selected-row reverse highlight across inner colour resets (…
Sep 8, 2026
b9ab195
Merge branch 'wl-WL-0MTGDW58X007UJDS-replace-binary-author-identity-g…
Sep 8, 2026
a125868
docs: update COLOUR-MAPPING.md and icons-design.md to priority-based …
Sep 8, 2026
d00a6de
Merge wl-WL-0MSJ2JFMO007PGQ6-colour-code-work-items-by-priority-in-se…
Sep 8, 2026
bc92957
WL-0MTTSWC1X005P4VD: Implementation complete
Sep 9, 2026
e65011c
feat(herdr): dispatch risk-effort evaluation for plan_complete items …
Sep 9, 2026
f4875fc
feat(herdr): allow herdr shortcuts to optionally focus the new pane (…
Sep 9, 2026
861eb4d
Merge docs update for WL-0MTJE0X8O0061KSD into dev
Sep 9, 2026
d94d0e5
Merge scheduled-prompts time-of-day dispatch (WL-0MTMN7W63001FCQR) in…
Sep 9, 2026
c90a2f4
Merge tests for bounded concurrent dispatch (WL-0MTSAAYEV007NLK3) int…
Sep 9, 2026
3c09380
Bump version to v1.0.14
Sep 9, 2026
322beb2
Update CHANGELOG.md for v1.0.14
Sep 9, 2026
c0329e8
Merge origin/dev into main (automated)
Sep 9, 2026
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
8 changes: 3 additions & 5 deletions .worklog/config.defaults.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,14 @@ stages:
label: Intake Complete
- value: plan_complete
label: Plan Complete
- value: in_progress
label: In Progress
- value: in_review
label: In Review
- value: done
label: Done
statusStageCompatibility:
open: [idea, intake_complete, plan_complete, in_progress]
in-progress: [intake_complete, plan_complete, in_progress]
input_needed: [idea, intake_complete, plan_complete, in_progress]
open: [idea, intake_complete, plan_complete]
in-progress: [intake_complete, plan_complete]
input_needed: [idea, intake_complete, plan_complete]
blocked: [idea, intake_complete, plan_complete]
completed: [in_review, done]
deleted: [idea, intake_complete, plan_complete, done]
27 changes: 27 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,32 @@
# Changelog

## v1.0.14 (2026-09-09)
### Features
- Single machine-wide downtime leader across all worklogs (replace per-worklog elections) (WL-0MTF0KLO10043YAN)
- indent group headings in children list (WL-0MTCP0ILG008YV84)
- Auto-disable dispatching when sprint is complete (WL-0MTHSHN5V008R5L0)
- Downtime dispatch panes all spawn in the leader's workspace regardless of project (C0: anchor-by-ID into dedicated Dispatcher workspace) (WL-0MTR01EU7005SYZG)
- Downtime dispatcher: exclude items needing producer review from selection (WL-0MTIAL65N004T22F)
- Sort in_review items (WL-0MSLPM5ZB003TADT)
- Allow herdr shortcuts to optionally give the new pane focus (WL-0MT70LC6B009TL3Q)
- Audit freshness: keep audit valid after post-audit comments; persist auditedAt atomically; remove audit-content comments (WL-0MT8KTE3E001Q1D9)
- Replace binary author-identity gate with configurable author whitelist (WL-0MTGDW58X007UJDS)
### Bug Fixes
- counts in Herdr selection list are incorrect (WL-0MT26TE72002FLKX)
- Downtime: fetchAuditItemById ignores cwd — cross-root contamination causes 3-strike pause on foreign offers (WL-0MTQ14W7L003II5A)
- Downtime dispatches land in Podcast workspace instead of Dispatcher workspace (WL-0MTRBOU0Y002M2CX)
- Downtime dispatcher: make wl-error pauses debuggable (log per-strike stderr/exitCode/timeout and probe context) (WL-0MTJPYM53003ORCV)
- Downtime pause log should include underlying wl error details (WL-0MTL4PC0Y005GXTI)
- fix: worklist-integration truncate hides Item title (▸ + colour makes line overflow 80cols) (WL-0MTSOASC6009N9O9)
- Downtime dispatch: gate non-critical implement tier on review-queue depth (WL-0MT2UQWOR007CYY9)
### Other
- Enable automatic crash reporting and review existing crash dumps (WL-0MT1KJNMV0018SWP)
- Remove the in_progress stage (WL-0MTOHS5B4001Y9FX)
- Herdr metadata panel: drop duplicate ID row from data section (WL-0MSHIJR7T007Q9R7)
- Shorten coordination check-in and re-offer immediately after dispatch (WL-0MTMPSCL8000O45H)
- Update Priority in selection list does not instantly update the list (WL-0MTFRJ2V6005IMW1)
- Colour code work items by priority in selection lists (CLI + Herdr) (WL-0MSJ2JFMO007PGQ6)

## v1.0.13 (2026-09-01)

## v1.0.12 (2026-08-25)
Expand Down
19 changes: 12 additions & 7 deletions DATA_SYNCING.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,11 +72,14 @@ Set in `.worklog/config.yaml` (local) or `.worklog/config.defaults.yaml` (team d
- Git remote used for sync
- `syncBranch` (string, default `refs/worklog/data`)
- Git ref used for the canonical JSONL file
- `syncAllowForeignAuthor` (boolean, default false)
- Allow merging commits authored by a different identity than the store's
configured `user.email` (see [Author-Identity Gate](#author-identity-gate)).
The CLI flag `wl sync --allow-foreign-author` takes precedence over this
config value.
- `syncAllowedAuthors` (allow-list, default `[]`)
- Emails allowed to merge during `wl sync` besides the local `user.email`.
`[]` = only `user.email`; `['a@x','b@y']` = plus listed emails
(case-insensitive, trimmed); `null`/`true` = allow any author.
See [Author-Identity Gate](#author-identity-gate). Empty-author commits
are always refused. CLI flag `wl sync --allow-foreign-author` overrides
to allow-all. Legacy `syncAllowForeignAuthor: true` still works as a
deprecated alias when `syncAllowedAuthors` is absent.

### Author-Identity Gate

Expand All @@ -91,8 +94,10 @@ local database untouched:
(e.g. a store whose git `user.email` is unset) is never merged, even with
`--allow-foreign-author`.
- **Foreign author email** → refused by default when it differs from the repo's
configured `user.email`; allowed when `wl sync --allow-foreign-author` is
passed or `syncAllowForeignAuthor: true` is set in config.
configured `user.email` and is not in `syncAllowedAuthors`; allowed when
the email is in the whitelist, `syncAllowedAuthors` is `null`/`true`,
`wl sync --allow-foreign-author` is passed, or legacy
`syncAllowForeignAuthor: true` is set (allow-all fallback when whitelist absent).
- **`user.email` unset** → the foreign-email comparison is skipped (only the
empty-email gate applies).

Expand Down
12 changes: 11 additions & 1 deletion docs/AUDIT_STATUS.md
Original file line number Diff line number Diff line change
Expand Up @@ -169,12 +169,22 @@ Fields:
- It avoids accidental status inference from arbitrary prose.
- It makes validation errors precise and actionable.

## Audit Freshness

- `isAuditFresh(auditedAt, updatedAt)` (`packages/shared/src/icons.ts`, used by the herdr TUI) returns `auditedAt > updatedAt - 60s`.
- Freshness is **atomic**: `saveAuditResult` — the path behind both `wl audit-set` and `wl update --audit-text` (see `packages/shared/src/persistent-store.ts`) — writes the `audit_results` row and sets `workitems.updatedAt = auditedAt` in the same transaction, so `isAuditFresh` is true immediately after an audit (WL-0MT8KTE3E001Q1D9 / WL-0MTHRW3770014H51).
- Flag-only flips of `needsProducerReview` do not bump `updatedAt` (WL-0MSN6ZCTN0027U2R); comments do bump `updatedAt`, but the 60 s grace keeps the audit fresh until real content changes advance `updatedAt` beyond the window.

## Canonical Source of Truth

The `audit_results` row is the **sole consumer** of the audit verdict. No flow parses audit-content comments: heartbeat, ship gate, TUI, and implement all read `auditResult`/`auditedAt` from the record. Audit verdicts duplicated into work-item comments are deprecated/legacy and must not be added by audit flows — they only harm freshness by bumping `updatedAt`.

## Operational Notes

- Config: `auditWriteEnabled` controls whether audit writes are allowed.
- Storage: audit data is stored in the `audit_results` table with foreign key constraints and CASCADE DELETE semantics.
- Migration: Use `wl doctor upgrade --confirm` to apply schema migrations on existing databases.
- Tests: Unit and integration tests cover valid first-line parsing, invalid first-line errors, redaction, whitespace handling, CRUD operations on the `audit_results` table, migration backfill, and legacy column removal.
- Tests: Unit and integration tests cover valid first-line parsing, invalid first-line errors, redaction, whitespace handling, CRUD operations on the `audit_results` table, migration backfill, legacy column removal, and the atomic `updatedAt = auditedAt` freshness guarantee (`tests/database.test.ts` — audit-then-comment ordering and audit-text parity).

### Error Behavior

Expand Down
98 changes: 51 additions & 47 deletions docs/COLOUR-MAPPING.md
Original file line number Diff line number Diff line change
@@ -1,43 +1,56 @@
# Colour Mapping for Work Items

This document describes the colour-coding system used for work item titles in the CLI and TUI.
This document describes the colour-coding system used for work item titles and ids in the CLI and Herdr.

## Overview

Work item titles are colour-coded based on their **stage** using a progression colour scheme (gray → blue → cyan → yellow → green → white), with a **red override for blocked items** that takes priority regardless of stage. When a work item has `status: blocked`, it always displays in red.
Work item **titles and ids** are colour-coded based on their **priority** using a consistent scheme
(critical → red, high → orange, medium → yellow, low → white). The same mapping is used in both the
CLI (`src/theme.ts`, chalk) and the Herdr worklist (`packages/shared/src/icons.ts`, ANSI 256).

## Colour Mapping Table
There is **no blocked override**: blocked items display their natural priority colour like every other
item (per clarification Q3b on WL-0MSJ2JFMO007PGQ6).

### Stage Progression Colours
> **Revision note (2026-09-08):** the original scheme specified `medium → white`, `low → dimmed`, with
> ids coloured by **stage**. A producer review of the first delivery changed this: medium is **yellow**
> (better contrast than white), low is **white** (dim was too low-contrast), and ids share the title's
> priority colour for a consistent visual cue. The docs, code comments and tests reflect the revised
> scheme.

| Stage | CLI Colour | Colour Name | Description |
|-------|-----------|-------------|-------------|
| `idea` | Gray | `gray` | Initial ideation phase |
| `intake_complete` | Blue | `blue` | Intake process completed |
| `plan_complete` | Cyan | `cyan` | Planning phase completed |
| `in_progress` | Yellow | `yellow` | Work in progress |
| `in_review` | Green | `green` | Under review |
| `done` | White | `white` | Work completed |
## Colour Mapping Table

### Blocked Override
### Priority Colours (titles and ids)

| Condition | CLI Colour | Colour Name | Description |
|-----------|-----------|-------------|-------------|
| `status: blocked` | Red Bright | `red` | Always red, overriding any stage colour |
| Priority | CLI Colour (chalk) | Herdr ANSI 256 | Colour Name | Description |
|----------|--------------------|----------------|-------------|-------------|
| `critical` | `chalk.red` | `196` | Red | Immediate attention |
| `high` | `chalk.hex('#FFA500')` | `208` | Orange | Important |
| `medium` | `chalk.yellow` | `220` | Yellow | Standard/default |
| `low` | `chalk.white` | `15` | White | Recedes |

### Default Fallback

| Condition | CLI Colour | Colour Name | Description |
|-----------|-----------|-------------|-------------|
| No stage, not blocked | Gray | `gray` | Falls back to idea/gray colour |
| Condition | CLI Colour | Herdr ANSI 256 | Description |
|-----------|------------|----------------|-------------|
| Unknown/missing priority | Medium (yellow) | `220` | Falls back to medium/yellow |

## Priority Rules
### Stage Colours (unchanged — used by the stage filter dialog and separators)

1. **Blocked override**: When a work item has `status: blocked`, it always displays in red, regardless of its stage value
2. **Stage progression**: When a work item has a stage set, the stage progression colour is used
3. **Default**: When no stage is set (or stage is empty/unknown) and status is not blocked, the default gray colour (idea) is used
| Stage | CLI Colour | Colour Name |
|-------|-----------|-------------|
| `idea` | Gray | `gray` |
| `intake_complete` | Blue | `blue` |
| `plan_complete` | Cyan | `cyan` |
| `in_progress` | Yellow | `yellow` |
| `in_review` | Green | `green` |
| `done` | White | `white` |

## Priority Rules

1. **Priority colour**: A work item's title and id are coloured by its priority (critical/high/medium/low).
2. **No blocked override**: Blocked items display their natural priority colour — there is no unconditional
red override for `status: blocked`.
3. **Default fallback**: When priority is missing or unknown, the medium/yellow colour is used.

## Accessibility

Expand All @@ -59,36 +72,27 @@ The colour-coding system is designed with accessibility in mind:

### Files

- `src/theme.ts` - Theme definitions for CLI and TUI colours (stage progression and blocked override)
- `src/commands/helpers.ts` - Helper functions for title rendering
- `src/theme.ts` — canonical priority colour mapping (chalk) for the CLI
- `src/commands/helpers.ts` — `titleColorForPriority`, `renderTitle`, `formatTitleAndId` (both title and id by priority)
- `packages/shared/src/icons.ts` — `priorityColor(priority)` / `applyPriorityColour(text, priority)` (ANSI 256) for Herdr
- `packages/herdr/src/worklist.ts` — `formatItemLine` (title and id both via priority colour)

### Functions

- `titleColorForStage(stage)` - Returns Chalk function for stage-based colour
- `renderTitle(item)` - Renders title with appropriate colour; checks blocked status first

### Changing the Colour Mapping

To modify colours:

1. Edit `src/theme.ts`: Update `theme.stage` objects or `theme.blocked`
2. The colour functions in `src/commands/helpers.ts` automatically pick up theme changes

### Adding New Stages
- `titleColorForPriority(priority)` — Returns Chalk function for priority colour (unknown → medium/yellow)
- `renderTitle(item)` — Renders title coloured by priority (no blocked override)
- `priorityColor(priority)` / `applyPriorityColour(text, priority)` — Herdr ANSI 256 equivalents

To add a new stage colour:
### Keeping CLI and Herdr Colours Consistent

1. Add the entry to `theme.stage` in `src/theme.ts`
2. Add a case to `titleColorForStage` in `src/commands/helpers.ts`
The CLI uses chalk named/hex colours and Herdr renders raw ANSI 256 escape codes. The two maps must stay
consistent: `critical` ≈ red (196), `high` ≈ orange (208), `medium` ≈ yellow (220), `low` ≈ white (15).
When changing colours, update both `src/theme.ts` and `packages/shared/src/icons.ts`.

## Testing

Tests are located in `tests/unit/colour-mapping.test.ts`:
Tests are located in:

- Theme structure verification (stage colours, blocked override)
- Stage-based colour mapping
- Blocked status override (always red regardless of stage)
- Default/fallback behaviour (gray when no stage, not blocked)
- Accessibility (preserving text labels)
- Fallback behaviour (colours disabled)
- Visual regression tests (snapshot-like)
- `tests/unit/colour-mapping.test.ts` — CLI helpers colour mapping (titles and ids by priority, blocked items show priority, unknown fallback)
- `packages/shared/src/icons-priority-colour.test.ts` — Herdr `priorityColor` / `applyPriorityColour` ANSI 256 mapping
- `packages/herdr/src/worklist.test.ts` (see `formatItemLine — priority title + stage id` describe block) — Herdr row colouring
7 changes: 4 additions & 3 deletions docs/FILE_PATH_CONVENTION.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

The `wl next --groups/-g` grouping feature determines parallel-work safety by
extracting file paths from work item descriptions. To make this work reliably,
all `in_progress`, `intake_complete`, and `plan_complete` work items **should** include a
all `intake_complete` and `plan_complete` work items **should** include a
`**Key Files:**` or `## Key Files` section
listing the files the work item will touch.

Expand Down Expand Up @@ -113,7 +113,8 @@ Section exists but no valid paths:
| Stage | Required? |
|---|---|
| `idea` | No (optional) |
| `in_progress` | **Should** include (groups items into `Group N`) |
| `plan_complete` | **Should** include (groups items into `Group N`) |
| `intake_complete` | **Should** include (groups items into `Group N`) |
| `intake_complete` | **Should** include (groups items into `Group N`) |
| `plan_complete` | **Should** include (groups items into `Group N`) |
| `in_review` | No |
Expand All @@ -123,7 +124,7 @@ Section exists but no valid paths:
`wl next -n N` displays groups in this order (WL-0MSAK8YLB0025EGW):

1. **Critical Group N** — `critical` priority items partitioned by file-path conflicts (items sharing a file path land in different groups; items with unknown paths get singleton groups).
2. **Group N** — non-critical `in_progress` + `plan_complete` + `intake_complete` items partitioned by file-path conflicts. Within each group, `in_progress` items appear first, then `plan_complete`, then `intake_complete` items (no headings between sub-groups), each sorted by priority (high → medium → low). The same within-group stage sub-sort applies inside each `Critical Group N`.
2. **Group N** — non-critical `plan_complete` + `intake_complete` items partitioned by file-path conflicts. Within each group, `plan_complete` items appear first, then `intake_complete` items (no headings between sub-groups), each sorted by priority (high → medium → low). The same within-group stage sub-sort applies inside each `Critical Group N`.
3. **Idea** — single group, sorted by priority.
4. **Other** — single group for all remaining items (safety net for unknown/custom stages and stale stage/status combinations; empty for all canonical stages in the default selection list).
5. **In Review** — single group (last).
Expand Down
48 changes: 36 additions & 12 deletions docs/SYNC_IDENTITY_GATE.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,20 @@ refused, surfaced to the operator, and never re-exported or pushed back.
- Before any merge/import, `wl sync` runs
`git log <remoteTrackingRef> --format=%h%x09%ae --not <lastSyncedRef>` and
inspects every incoming commit's author email.
- **Empty author email** → unconditional refusal. `--allow-foreign-author`
never bypasses this.
- **Foreign author email** (differs from the repo's `git config user.email`)
→ refused by default; allowed with `wl sync --allow-foreign-author` or
`syncAllowForeignAuthor: true` in `.worklog/config.yaml`.
- **Empty author email** → unconditional refusal. No whitelist or flag ever
bypasses this.
- **Whitelist `syncAllowedAuthors`** (new, WL-0MTGDW58X007UJDS) — the canonical
gate setting in `.worklog/config.yaml` / `config.defaults.yaml`:
- `[]` (default) — only the local `user.email` is allowed (strict).
- `['a@x', 'b@y']` — `user.email` plus any listed email (case-insensitive,
trimmed). Foreign commit allowed only if its email is in the list.
- `null` or `true` — allow any author (allow-all, equivalent to the flag).
- **Legacy `syncAllowForeignAuthor: true`** still works as a deprecated alias
that maps to allow-all when `syncAllowedAuthors` is absent; when
`syncAllowedAuthors` is explicitly set it takes precedence.
- **CLI `--allow-foreign-author`** still works and overrides the config to
allow-all for that invocation (help: `wl sync --help` explains the
whitelist model).
- **`user.email` unset locally** → the foreign-email comparison is skipped;
only the empty-email gate applies.
- The last-known sync point is stored in `.worklog/last-synced-ref` after each
Expand Down Expand Up @@ -73,18 +82,33 @@ wl sync --no-push --allow-foreign-author
wl sync --no-push --allow-foreign-author
```

## Config flag
## Config — whitelist `syncAllowedAuthors`

`syncAllowForeignAuthor` (default `false`) in `.worklog/config.yaml` (or
`.worklog/config.defaults.yaml` for team defaults) allows foreign-email
commits without a CLI flag:
Canonical (WL-0MTGDW58X007UJDS) — `syncAllowedAuthors` in `.worklog/config.yaml`
(or `config.defaults.yaml` for team defaults):

```yaml
syncAllowForeignAuthor: true
# strict (default): only user.email
syncAllowedAuthors: []

# allow specific collaborators / bot
syncAllowedAuthors:
- alice@company.com
- ci-bot@company.com

# allow any author (e.g. shared repo)
syncAllowedAuthors: null # or true
```

The CLI flag `wl sync --allow-foreign-author` takes precedence over the config
value. Neither ever bypasses the empty-author-email gate.
Invalid types (e.g. number, `false`, list with non-string entries) are
rejected with a clear error (`Invalid config: syncAllowedAuthors …`).

### Legacy `syncAllowForeignAuthor`

`syncAllowForeignAuthor: true` still works as a deprecated alias that maps to
allow-all when `syncAllowedAuthors` is absent. When `syncAllowedAuthors` is
explicitly set it wins. The CLI flag `wl sync --allow-foreign-author` always
wins over either config key. Nothing ever bypasses the empty-author gate.

## Recovery for a polluted ref

Expand Down
Loading
Loading