fix(linkedin-studio): S13 harden calendar — concrete Reschedule snippet + correct camelCase exports

Reschedule action was under-determined vs its sibling actions: prose-only with
no bash snippet, referencing snake_case queue_update_status/queue_add that don't
match the exports (queueUpdateStatus/queueAdd). Replaced with a concrete queueAdd
one-liner using the same id (re-add moves the post in place, no duplicate).
Axes a/b/c/d all PASS post-fix; lint 81/0/0, counts 29/19 unchanged.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016qgzo6rxthw7KuxHjn5vyE
This commit is contained in:
Kjell Tore Guttormsen 2026-06-18 20:19:31 +02:00
commit 270e99d002
2 changed files with 59 additions and 3 deletions

View file

@ -165,9 +165,15 @@ First Hour:
If they choose to reschedule:
1. Ask which post (by number or hook preview)
2. Ask for new date and time
3. Update queue.json via queue_update_status + queue_add with new date
4. Show updated calendar
2. Ask for the new date and time
3. Re-add the entry with the **same id** and new date/time — `queueAdd` replaces any
existing entry with that id, so the post moves in place (no duplicate). Carry the
unchanged fields (draft_path, pillar, format, hook preview, char count) from the
entry shown in Step 2:
```bash
node --input-type=module -e "import { queueAdd } from '${CLAUDE_PLUGIN_ROOT}/hooks/scripts/queue-manager.mjs'; console.log(queueAdd('[post-id]', '[draft_path]', '[new-YYYY-MM-DD]', '[new-HH:MM]', '[pillar]', '[format]', '[hook preview]', [charCount]));"
```
4. Show the updated calendar
### Action: Cancel

View file

@ -1074,3 +1074,53 @@ functionally safe but mis-labelled "(Step 3b)". Root cause: conflating "the phas
post-fix.
---
## Session 13 — Hardening (`calendar`)
> S13 status: read-and-show of every mechanical dependency against the actual `queue-manager.mjs` +
> `state-updater.mjs` BEFORE talk. Class agreed steps 12: **stateful queue / publish command**
> view + manage the scheduling queue + run the publish action. **NOT post-emitting / feed-draft.**
> It loads the queue (`queueToday/Upcoming/Overdue/Count/FormatSummary`), renders a 14-day view,
> offers actions (mark-published / reschedule / cancel / view-draft), and on publish does
> `queueUpdateStatus('published')``updatePostTracking` (state) → a quick first-hour plan that
> defers the full sprint to `/linkedin:firsthour` + `post-feedback-monitor`. It DISPLAYS hook previews
> of already-queued drafts → it emits no feed content → the feed-format predicates (hook 110140,
> 1,2001,800 band, no-body-link, buzzwords, rotation) do NOT apply. Axis-a/d heavy.
**WHAT VERIFIED CLEAN (no change).**
- Queue wiring (axis-a/d): Step 1 (`queueToday/Upcoming/Overdue/Count/FormatSummary`), 3c + Cancel
(`queueUpdateStatus`) all match exports in `queue-manager.mjs:41112` exactly.
- State-writer (axis-d): `updatePostTracking(stateContent, { postDate, postTopic, hookText, charCount,
format })` (`state-updater.mjs:55`) + `writeState` (`:346`) — signature matches Step 3d's call verbatim.
- Agent wiring (axis-d): `subagent_type: linkedin-studio:post-feedback-monitor` (`:156`) namespaced,
agent file present, `Task` in `allowed-tools`. Hand-off to `/linkedin:firsthour` (`:138`) = S12 chain.
- Graceful degradation (axis-d): missing/corrupt queue → `ensureQueue()` + `readQueue()` try/catch → `[]`
(`queue-manager.mjs:1227`); the "No posts scheduled" branch (`:106111`) covers the empty case.
- Algorithm bar (axis-b): the quick first-hour plan (`:151` "15+ engagements in first 60 min", check at
30/60) is deliberately light and delegates the full sprint to `/linkedin:firsthour`. No ~70%-reach
misattribution (the S12 bug is absent here). SSOT `:81` golden window 6090 min / first 1530 min — not
contradicted. PASS.
- Content-quality (axis-c): emits no feed content; the hook "preview" is a truncated display of an
existing draft, not a generated hook → feed predicates N/A → PASS.
**THE FIX (1 finding, 1 surgical edit, confined to the Reschedule action).**
1. [REWORK · axis-a/d] The **Reschedule** action (`:164170`) was under-determined vs its sibling actions:
prose-only with NO bash snippet (unlike Cancel `:177180` and publish 3c `:116118`), and it referenced
`queue_update_status + queue_add`**snake_case that does not match the exports** `queueUpdateStatus` /
`queueAdd` (`queue-manager.mjs:63,82`). An agent executing it had no concrete command and the names
would not resolve if copied literally. Fix: replaced step 3 with a concrete `queueAdd` one-liner using
the **same id** (since `queueAdd` filters out the prior id first, `:64`, re-adding moves the post in
place — no duplicate), carrying the unchanged fields from the Step-2 entry. Mirrors the Cancel snippet
pattern.
**VERIFY.**
- Re-grepped the final file: no `queue_update_status` / `queue_add` remains; the `queueAdd` reschedule
snippet is at `:174`; every `queue*` reference in the file is now camelCase and matches an export.
- `bash scripts/test-runner.sh``Passed: 81 · Failed: 0 · Warnings: 0`, **exit 0**; counts **29/19**
unchanged (.md-only edit, node/analytics tests not triggered — unchanged from S12).
- **One NICE left (anti-gold-plating):** the quick first-hour plan could name the SSOT "first 1530 min"
sub-window, but it deliberately defers to `/linkedin:firsthour`; duplicating it would be scope creep —
left.
- Disposition: **FIXED** (1 edit in `commands/calendar.md`) · 0 deferrals · axes a/b/c/d all PASS post-fix.
---