From 3be998b372e0a0ed4a466fb09e5bbc7e613c0fb9 Mon Sep 17 00:00:00 2001 From: "mintlify[bot]" <109931778+mintlify[bot]@users.noreply.github.com> Date: Tue, 2 Jun 2026 07:12:19 +0000 Subject: [PATCH 1/2] docs: document approval-gated worklog flow and Worklogs view --- docs.json | 1 + guides/worklogs.mdx | 141 ++++++++++++++++++++++++++++++++++++++++++++ reference/cli.mdx | 43 ++++++++++++++ 3 files changed, 185 insertions(+) create mode 100644 guides/worklogs.mdx diff --git a/docs.json b/docs.json index 2645d1b..6768dd7 100644 --- a/docs.json +++ b/docs.json @@ -43,6 +43,7 @@ "guides/github-linear", "guides/mcp-setup", "guides/dashboard", + "guides/worklogs", "guides/querying-data" ] }, diff --git a/guides/worklogs.mdx b/guides/worklogs.mdx new file mode 100644 index 0000000..909391b --- /dev/null +++ b/guides/worklogs.mdx @@ -0,0 +1,141 @@ +--- +title: "Review and Approve Worklogs Before They Post to Jira" +sidebarTitle: "Worklogs" +description: "Use the Worklogs view in the Meridian dashboard to review, edit, and approve drafted worklogs — the only path that posts time to your tracker." +--- + +Meridian's PM-worklog stage synthesises one worklog per ticket per hour from your classified sessions. **Nothing reaches Jira automatically.** The daemon only ever *drafts* worklogs; you review, edit, and approve each one in the dashboard's **Worklogs** view, and a separate post sweep writes the approved entries to Jira within about a minute. + +Use this guide when you want to keep an automated record of your time without giving up the final say over what lands on a ticket. + +## When to use this + +Turn to the Worklogs view if you want to: + +- Capture per-ticket time logs from your real activity without writing them by hand. +- Keep a human in the loop — every comment posted to Jira is something you explicitly approved. +- Edit auto-generated comments before they go out, or dismiss drafts that don't represent useful work. + +The flow assumes Jira is already connected. See [Connect Meridian to Jira Cloud](/guides/jira) if you haven't set up the connector yet. + +## The drafted → approved → posted state machine + +Every worklog moves through a small set of states: + +``` +drafted ──(UI edit)──▶ drafted ──(UI approve)──▶ approved ──(post sweep)──▶ posted + │ + terminal (empty / < 60s) └──▶ failed +``` + +| State | What it means | +|---|---| +| `drafted` | The hourly driver synthesised a worklog from your sessions. It is **not** in Jira. Edit it, approve it, or dismiss it. | +| `approved` | You approved the draft in the Worklogs view. It is queued for the next post sweep but has **not** been posted yet. You can still un-approve it to hold it back. | +| `posted` | The post sweep wrote the comment to Jira. The state is terminal; Meridian records the Jira worklog ID alongside the row. | +| `skipped` | You dismissed the draft. It will not be posted and the hour is considered handled. | +| `failed` | The post sweep tried to write to Jira and got an error (auth, network, validation). The error is shown on the card; fix the cause and re-approve to retry. | + +Approval is the **only** way a worklog reaches your tracker. A driver re-run can never clobber an `approved` or `posted` row, so a human decision is never silently overwritten. + + + `time_spent` always comes from your actual idle-discounted activity for the hour (capped at one hour). The language model writes the comment, not the duration. + + +## The Worklogs view + +Open the dashboard at [http://localhost:3000](http://localhost:3000) and select **Worklogs** in the sidebar (keyboard shortcut `4`). + +The header shows the day you're reviewing and a running count of drafts, approved, and posted worklogs. Use the `←` / `→` arrows to step through previous days; you can't step past today. + +Each worklog is rendered as a card containing: + +- The ticket key, the hour the worklog covers, and the time spent in that hour. +- A confidence ring and any risk flags raised during synthesis (e.g. `low_confidence`, `thin_evidence`). +- The editable comment that will be posted to Jira. +- Optional supporting detail — the underlying bullets and suggested next steps — collapsed by default behind **show supporting detail**. +- The current state badge (`Draft`, `Approved`, `Posted`, `Dismissed`, `Failed`). + +The view polls every 30 seconds, so when the post sweep flips an `approved` row to `posted` (or `failed`) you'll see it update without reloading. + +## Approving, editing, and dismissing drafts + +Each card on a non-posted worklog has three actions: + + + + Marks the worklog as `approved`. The post sweep picks it up within about 60 seconds and writes it to Jira. + + + Opens the comment in an inline textarea. Saving re-drafts the worklog (you'll need to approve it again before it posts). The `edited` badge appears on cards you've touched. + + + Marks the worklog as `skipped`. It will not be posted and won't show up in the unapproved queue again. + + + +If a card is already `approved` but hasn't posted yet, the primary button becomes **Hold (un-approve)** so you can pull it back before the next sweep. + +When every draft on the page looks good, use **Approve all N drafts** at the top of the view to approve them in one click. Empty drafts (no synthesised comment) are skipped automatically. + +## The post sweep + +A background sweep in the daemon runs approximately every 60 seconds and posts every `approved` worklog it finds to Jira, marking each one `posted` on success or `failed` (with the error message) otherwise. This sweep is the **sole** path that writes to your tracker. + +If you can't wait for the next sweep — for example, you just approved a batch at the end of the day and want them all posted now — run: + +```bash +meridian worklog-post-approved +``` + +The command runs exactly the same sweep on demand and exits when it's done. + +## Inspecting the day from the CLI + +For a no-SQL summary of a given day, including hours done, pending, and stuck, plus rows grouped by state and a flagged list of low-confidence or risk-flagged drafts to inspect first, use: + +```bash +meridian worklog-status --day 2026-05-30 +``` + +Omit `--day` to see today. + +## Configuration + +The PM-worklog stage runs inside the Rust daemon and uses the MLX server's synthesis endpoint to write each draft comment. Beyond connecting Jira, you typically don't need to set anything. A few optional tunables in `~/.meridian/.env`: + +| Variable | Default | Purpose | +|---|---|---| +| `PM_WORKLOG_INTERVAL_HOURS` | `1.0` | How often the driver runs a drafting pass. Clamped to a 60-second floor. | +| `PM_WORKLOG_MIN_CONFIDENCE` | `0.65` | Below this, drafts are flagged `low_confidence` for extra scrutiny. | +| `PM_WORKLOG_READINESS_AGING_MIN` | `90` | Maximum minutes the driver will wait for an hour to settle before drafting anyway. | + + + There is no environment variable that enables automatic posting. The previous `PM_WORKLOG_POST_ENABLED` switch has been removed — approval in the Worklogs view is the only gate. + + +## Troubleshooting + + + + Drafts are produced once an hour by the daemon and only for tickets you have classified sessions against. Confirm with: + + ```bash + meridian worklog-status + ``` + + If `hours done` is `0`, check that `meridian status` shows the daemon and MLX server running, and that Jira is connected (`meridian doctor`). + + + The post sweep runs roughly every 60 seconds. If a row hasn't posted after a minute or two, run the sweep manually to surface any error: + + ```bash + meridian worklog-post-approved + ``` + + If the row flips to `Failed`, the card will display the underlying Jira error. Fix the cause (commonly a stale API token or a closed ticket) and approve again to retry. + + + If synthesis couldn't produce a useful comment — for example, the hour had too little signal — the draft renders as `(empty — nothing to post; edit to add a comment)`. Approve is disabled for empty drafts; either edit the comment yourself or dismiss the card. + + diff --git a/reference/cli.mdx b/reference/cli.mdx index db9553e..55c37fc 100644 --- a/reference/cli.mdx +++ b/reference/cli.mdx @@ -187,6 +187,49 @@ Without Screen Recording permission, screenpipe cannot capture frames and Meridi + + +```bash +meridian pm-worklog [--day YYYY-MM-DD] +``` + +Runs one pass of the PM-worklog drafter on the given day (defaults to today). For each ticket with classified sessions in a settled hour, Meridian collects the activity, calls the MLX server's synthesis endpoint, grounds the result against the evidence, and writes a `drafted` row to the database. **This command never posts to Jira** — every draft awaits approval in the dashboard's Worklogs view. + +The hourly daemon driver runs the same logic automatically. Run this command manually when you want to backfill drafts for an earlier day or replay drafting after fixing classification. + +See [Review and Approve Worklogs](/guides/worklogs) for the full approval flow. + + + + + +```bash +meridian worklog-post-approved +``` + +Runs the post sweep on demand: finds every worklog you have marked `approved` in the dashboard's Worklogs view and writes it to Jira, flipping the row to `posted` (or `failed` with the underlying error). This is the same sweep the daemon runs automatically every ~60 seconds — use this command when you want to flush approvals immediately rather than wait for the next tick. + +This is the **only** path Meridian uses to write worklogs to Jira. + + + + + +```bash +meridian worklog-status [--day YYYY-MM-DD] +``` + +Prints a human-readable summary of the PM-worklog stage for the given day (defaults to today), without touching SQL: + +- Hours done, pending, and stuck for the day. +- Counts of worklogs by state (`drafted`, `approved`, `posted`, `skipped`, `failed`). +- A per-ticket table with the synthesised Jira comment. +- A **flagged** list of low-confidence or risk-flagged drafts to inspect before approving. + +Run this command to triage the day before opening the Worklogs view. + + + ```bash From 6e19c1e890c138c00d40bda116acd574d6a0ee09 Mon Sep 17 00:00:00 2001 From: "mintlify[bot]" <109931778+mintlify[bot]@users.noreply.github.com> Date: Thu, 4 Jun 2026 07:15:55 +0000 Subject: [PATCH 2/2] docs: document dismiss attribution picker in Worklogs review --- guides/worklogs.mdx | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/guides/worklogs.mdx b/guides/worklogs.mdx index 909391b..3094559 100644 --- a/guides/worklogs.mdx +++ b/guides/worklogs.mdx @@ -70,7 +70,7 @@ Each card on a non-posted worklog has three actions: Opens the comment in an inline textarea. Saving re-drafts the worklog (you'll need to approve it again before it posts). The `edited` badge appears on cards you've touched. - Marks the worklog as `skipped`. It will not be posted and won't show up in the unapproved queue again. + Marks the worklog as `skipped` after asking *where the time should have gone* — see [Dismissing a draft and correcting attribution](#dismissing-a-draft-and-correcting-attribution). @@ -78,6 +78,22 @@ If a card is already `approved` but hasn't posted yet, the primary button become When every draft on the page looks good, use **Approve all N drafts** at the top of the view to approve them in one click. Empty drafts (no synthesised comment) are skipped automatically. +## Dismissing a draft and correcting attribution + +When you click **Dismiss** on a draft, the card expands into an attribution picker asking *"Where should this time have gone?"*. You're not just rejecting the worklog — you're labelling what the classifier got wrong. Pick one of: + +- **Another open ticket** — the work belonged to a different task. Meridian records the corrected `task_key` as the ground truth for that hour. +- **Untracked / personal** — the activity wasn't billable work at all. Meridian records that the hour should not have produced any worklog. +- **Just dismiss — not sure** — you don't have a clear answer; the worklog is dismissed with no attribution label. + +After choosing, click **Dismiss worklog** to confirm. The worklog moves to `skipped` and the correction is stored alongside the existing edit history as immutable review feedback. + +Every approve, reject, and un-approve action is recorded the same way — not just edits — so Meridian retains a complete history of how each draft was reviewed even though only the latest state is shown on the card. This feedback feeds the classifier evaluation pipeline; over time, drafts you reject with corrections help Meridian get attribution right on similar sessions. + + + No external system is told about the correction — it's stored locally in your Meridian database for evaluation only. + + ## The post sweep A background sweep in the daemon runs approximately every 60 seconds and posts every `approved` worklog it finds to Jira, marking each one `posted` on success or `failed` (with the error message) otherwise. This sweep is the **sole** path that writes to your tracker.