feat(linkedin-studio): N13 — publiserings-slots + vacancy-varsel + WIP-roll-up + slot-default [skip-docs]
A1-10 + D-5. The queue answers "what is scheduled"; nothing answered "is the week covered, and what is still being written". N13 makes both readable at session start. - Publishing slots are operator config: profile/publishing-slots.json in the per-user data dir, schema + OPT-IN template in config/publishing-slots.template.json. The plugin ships no publishing times and writes the grid for nobody; absent config means every slot surface stays silent (same never-nag discipline as the trend/brain nudges). Data dir rather than the state file, which is machine-written and whose frontmatter reader does not parse lists. - hooks/scripts/slots.mjs (new): one implementation behind four surfaces. Zero-dep (a SessionStart hook must not spawn tsx), pure core (dates in as strings, no clock), imported by the commands exactly as queue-manager.mjs already is — so session-start's vacancy warning and Step 10's slot default cannot drift apart. - Coverage counts the short-form queue (scheduled/published; cancelled frees the slot) AND editions-register rows claiming that date, counted per date, so long-form and short-form cannot be double-booked and a two-slot day needs two posts. - Session start gains "## Editions in Flight" (series, phase, next action, claimed slot, days in flight) and "## Publishing Slots" (next open slot, open count in 14 days, and how to fill it when the gap is <=3 days). The existing discovery nudge is untouched. - /linkedin router + /linkedin:calendar surface the same roll-up; calendar documents the opt-in copy. /linkedin:newsletter Step 10 defaults to the next open slot (one confirmation, not an interview) and writes --slot onto the register row. - D-5: references/scheduling-strategy.md marked "confidence: low / directional" per the algorithm reference's own standard, deferring to the operator's grid and their own analytics. Neutral example time replaces the operator-specific one in the N12 docs. TDD: red proven first (module absent; 5 session-start behaviours failing). hooks 140 -> 174 · test-runner 184 -> 197 (Section 16t: 13 unconditional greps incl. a de-niche check that no publishing time is hardcoded in the slot path and no operator grid is committed, + non-vacuity self-test; anti-erosion floor 166 -> 179). Suites green: trends 300/0 · brain 134/0 · editions 72/0 · specifics-bank 45/0 · tests 35/0 · render 60/0. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QxvWAjte7vPcF79QeSRvRJ
This commit is contained in:
parent
657539ef09
commit
677eab9294
14 changed files with 1069 additions and 19 deletions
10
CHANGELOG.md
10
CHANGELOG.md
|
|
@ -49,6 +49,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
- **Deterministic, no clock in the core** — every mutation takes `now` as an argument (`--at` / `--now` at the CLI edge), as the distillate takes `lockedAt`. Idempotent where a re-run is legitimate (a repeated transition logs once; completing twice keeps the first `completedAt`), *not* where it is real work (a phase recurring after another one is logged again — a pivot back through cleared gates is production time that happened). Missing facts are refused at the edge rather than defaulted: a row naming the wrong phase is worse than no row.
|
||||
- Suites: editions 27 → 72; test-runner 173 → 184 (Section 16s: 11 unconditional greps incl. a 16-phase coverage sweep + non-vacuity self-test; anti-erosion floor 155 → 166). `tsc --noEmit` clean. Domain-general throughout.
|
||||
|
||||
### Added — publishing slots + vacancy warning + WIP roll-up (N13 / A1-10, D-5)
|
||||
|
||||
- **Publishing slots are operator config (`profile/publishing-slots.json`)** — a recurring weekly grid (`{day, time, label}`) in the per-user data dir, with a schema + **opt-in** template at `config/publishing-slots.template.json`. The plugin writes it for nobody and ships no publishing times: while the file is absent every slot surface stays silent, exactly like the trend and brain nudges. It lives in the data dir rather than the state file because the state file is machine-written (rollover, pruning, post tracking) and its frontmatter reader does not parse lists — user config does not belong in a file the plugin rewrites.
|
||||
- **Vacancy at session start** — the SessionStart hook now names the next publishing slot **nothing covers**, how many are open in the next 14 days, and — when the gap is ≤3 days — how to fill it. Coverage counts both the short-form queue (status `scheduled`/`published`; a cancelled entry frees the slot again) **and** editions-register rows whose slot claims that date, so long-form and short-form can never be booked on top of each other. A day carrying two slots needs two posts to be full.
|
||||
- **Work in progress is surfaced, not searched for** — `## Editions in Flight` at session start, plus the same roll-up in the `/linkedin` router and `/linkedin:calendar`: series, edition, current phase, the one next action, claimed slot, and days in flight. The N12 register made this measurable; N13 makes it *visible without asking*.
|
||||
- **`hooks/scripts/slots.mjs` — one implementation, four surfaces** — zero-dep (a SessionStart hook must not spawn tsx), pure core (dates in as strings, no clock), and imported by the commands the same way `queue-manager.mjs` already is. The hook's vacancy warning and the slot `/linkedin:newsletter` defaults to therefore cannot disagree.
|
||||
- **`/linkedin:newsletter` Step 10 defaults to the next open slot** — scheduling is one confirmation instead of an interview, and the transition now writes `--slot` onto the register row so a scheduled edition stops reading as an open slot. Unconfigured grid or a full horizon ⇒ the old ask, unchanged.
|
||||
- **D-5: the shipped schedule is marked for what it is** — `references/scheduling-strategy.md` now carries the same epistemic standard as the algorithm reference (**confidence: low / directional**, practitioner heuristic, no primary source) and defers to the operator's own grid, tested against their own analytics. The tables are a starting point, not a finding about anyone's audience.
|
||||
- Suites: hooks 140 → 174 (25 slot-core + 9 session-start tests); test-runner 184 → 197 (Section 16t: 13 unconditional greps incl. a de-niche check that no publishing time is hardcoded in the slot path and no operator grid is committed, + non-vacuity self-test; anti-erosion floor 166 → 179).
|
||||
|
||||
### Built feedback (awaiting consumer-side proof)
|
||||
|
||||
- **MR-F9** (demand-sweep «innenfra og ut») — built; the (a)/(b)/(c) evidence gate is a runtime demonstration, proven consumer-side (plugin agents don't resolve in the dev repo).
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue