ktg-plugin-marketplace/plugins/linkedin-studio/docs/remediation/review.md
Kjell Tore Guttormsen 8c52bdb2e4 fix(linkedin-studio): S15 — UX finish §6c (B1 onboarding inline-draft + B3 carousel full-deck clipboard)
B2 (router tiering) was already delivered in S14, so S15 = B1 + B3 only.
No surface/count/version change -> within-v4.1.0 refinement (S11-S13 precedent).

- B1 (commands/onboarding.md): replace the "Run /linkedin:first-post" dead-end
  hand-off in Phase 3 with the first-post drafting steps embedded inline (3.1 topic
  -> 3.2 3-line draft -> 3.3 QC -> 3.4 present+clipboard -> 3.5 state-update that sets
  first_post_date). Wizard now yields a draft in-flow; 0 dead-end strings. Stays within
  the existing allowed-tools (Read/Bash/AskUserQuestion); UI-brief §12b scope-guard
  honored (no provider seams / progressive-disclosure added).
- B3 (commands/carousel.md): Step 6 now assembles the ENTIRE deck (every slide's copy
  + the caption) into the clipboard payload, not just the caption; full-deck assembly
  precedes the clipboard-helper.mjs call.

Independent /trekreview (2 Opus reviewers): brief-conformance 0 findings; code-correctness
1 MAJOR that is PRE-EXISTING and out of S15 scope (onboarding Phase 2 saves need Write in
allowed-tools; lines 142/157, untouched by the S15 diff) -> DEFERRED to next session per
"ekte design-funn -> neste sesjon". Verdict ALLOW for the delivered scope (not a WARN-override).

Gate: test-runner.sh 74/0/0; node --test 98/98; commands=29; v4.1.0 unchanged.
See docs/remediation/review.md for the full record (ALLOW + 1 deferred MAJOR).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-30 21:44:34 +02:00

143 lines
8.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
type: trekreview
review_version: "1.0"
task: "S15 — UX finish §6c on the final 29-command set: B1 onboarding inline-draft + B3 carousel full-deck clipboard (B2 router-tiering already delivered in S14)"
slug: remediation
project_dir: docs/remediation/
brief_path: docs/remediation/brief.md
scope_sha_start: baca30f
scope_sha_end: baca30f
reviewed_files_count: 2
verdict: ALLOW
mode: default
effort: standard
profile: premium
findings: []
---
# Review — linkedin-studio S15 (UX finish §6c: B1 onboarding inline + B3 carousel full-deck)
## Executive Summary
**Verdict: ALLOW** for S15's delivered scope — 0 BLOCKER, 0 MAJOR, 0 MINOR, 0 SUGGESTION
**attributable to the S15 diff**. Two independent reviewers (brief-conformance,
code-correctness) ran COLD, without cross-feeding, on the as-delivered uncommitted
working tree (HEAD `baca30f` + the S15 delta = two command files).
- **brief-conformance-reviewer:** 0 findings. B1 and B3 both trace to delivered code; the
binding §12b scope-guard is honored (no extensibility / provider-seam / progressive-
disclosure / detect-and-offer language entered the diff); no version/count drift
(19/29/25/6 intact, v4.1.0 untouched); no files outside the two in scope.
- **code-correctness-reviewer:** 1 MAJOR — but **pre-existing and outside S15's scope**
(see Findings). The S15 changes themselves are correct: branches all terminate, the
state-updater + clipboard snippets mirror the established `first-post.md` pattern
exactly, `${CLAUDE_PLUGIN_ROOT}` is the established path var, and the larger carousel
clipboard payload introduces no new failure mode over the uniform plugin pattern.
S15 = **B1 + B3 only**. B2 (router tiering) was already delivered in S14 (the finish-plan
S15 body still lists B2, but the S14 amendment + the session-state label supersede it);
its absence here is correct, not a gap.
## Coverage
Scope: HEAD `baca30f` (S14's commit) + the **uncommitted S15 working-tree delta**
(annotated `[uncommitted]` — a brief-level contract; the brief's Assumptions allow
uncommitted review). 2 files = the operator's own changes. The 3 untracked not-mine files
(`docs/linkedin-studio-persona-brief.md`, `…-ui-brief.md`, `docs/voyage-build/progress.json`)
are explicitly excluded from scope and from the commit. **No silent skips.**
| Treatment | Count | Notes |
|-----------|-------|-------|
| `deep-review` | 0 | neither file is under `hooks/**` / `auth/**` / `crypto/**` / `**/security/**` |
| `summary-only` | 2 | `commands/onboarding.md` (Phase 3 rewrite + 1 Phase-4 summary line), `commands/carousel.md` (Step 6 clipboard) |
| `skip` | 0 | no lockfiles / svg / generated / dist |
**B1/B3 acceptance checks (orchestrator-run greps):**
- B1: `grep -E "[Rr]un \`?/linkedin:first-post" commands/onboarding.md` → **0 dead-end strings**;
inline draft steps 3.13.5 present (topic → 3-line draft → QC → present+clipboard → state-update that sets `first_post_date`).
- B3: full-deck assembly block at `carousel.md:191` precedes the `clipboard-helper.mjs` call at `:211`; payload contains slide text; caption-only `<CAROUSEL_CAPTION>` removed.
**Cross-cutting execution criteria:** `scripts/test-runner.sh` → **74 passed / 0 failed /
0 warnings**, exit 0. `node --test hooks/scripts/__tests__/*.test.mjs`**98/98** (no hook
logic changed). `ls commands/*.md`**29** (no surface-count change; no version bump —
consistent with S11S13 precedent: within-scope refinements stay at the current version).
## Findings
**0 findings attributable to the S15 diff.** One MAJOR was raised by code-correctness; on
inspection it is **pre-existing and out of S15's scope**, and is routed to the next session
per the finish-plan's locked constraint ("fix-in-next-session for any review finding") and
the operator rule "ekte design-funn → neste sesjon" (in-session fix is reserved for the
session's *own* lockstep misses). It is recorded below and propagated to STATE.md — **not
dropped, not silenced.**
### [MAJOR — DEFERRED to next session] onboarding Phase 2 file-saves need `Write`, not in `allowed-tools`
*Raised by code-correctness (`PLAN_EXECUTE_DRIFT`), `commands/onboarding.md:142` (and `:157`).*
`onboarding.md` frontmatter grants `allowed-tools: [Read, Bash, AskUserQuestion]` — no
`Write`. **Phase 2** instructs "Save the responses to `assets/voice-samples/authentic-voice-samples.md`"
(`:142`, with a REPLACE-vs-append rule) and "Save to `config/user-profile.local.md`" (`:157`).
Persisting those profile files is a file write; the plugin's accepted pattern is the `Write`
tool, and the sibling `first-post.md` (same voice-save) declares `Write` (`first-post.md:9-14`).
With only Read/Bash/AskUserQuestion the agent cannot honor the two "Save to …" instructions
(the only scripted Bash writes are the `node -e` state and clipboard snippets). **Real defect.**
**Why DEFERRED, not fixed in S15:**
- **Pre-existing.** The gap exists identically at HEAD `baca30f` *before* the S15 edits —
`git show HEAD:…/onboarding.md` shows `allowed-tools: [Read, Bash, AskUserQuestion]` already.
- **Out of S15's diff scope.** The S15 hunks are `@@ -166` (Phase 3) and `@@ -201` (Phase 4
summary line); lines 142/157 (Phase 2) are untouched. S15's *own* inline steps (3.13.5)
stay within Read/Bash/AskUserQuestion and need no `Write` (3.4 clipboard = Bash, 3.5
state-update = Bash `node -e`).
- **Not introduced or worsened by S15.** The reviewer's "now owns the save flow" framing does
not hold on inspection: Phase 2's saves are reached identically before and after S15, and
the removed `/linkedin:first-post` hand-off was about *post creation* (Phase 3), not Phase 2's
profile saves. S15 added no save-flow that needs `Write`.
- **Operator governance.** Fixing a Phase-2 tool-contract bug inside an S15 (B1+B3) push would
be exactly the "rydd opp i pre-existing som del av en bugfix" / scope-expansion the operator's
rules forbid; the documented default for out-of-scope items is **defer** (record, route to
next session) — not silently fix, not silently drop.
**Recommended action (next session):** add `Write` to `onboarding.md`'s `allowed-tools`
(matching `first-post.md:9-14`), or replace the two "Save to …" instructions with a `node -e`
Bash write so the steps stay within the declared Bash grant. Natural home: fold into S16 (which
already opens the onboarding/saves surface) or the S17 triage pass.
## Remediation Summary
**Gate: ALLOW** for S15's delivered scope (B1 + B3). Both reviewers confirm the two changes
are conformant (brief) and correct (code); the binding §12b scope-guard held; no version/count
drift; the inline first-post flow and the full-deck clipboard both function within the existing
tool grants and established patterns. The single MAJOR is a **pre-existing, out-of-scope**
tool-contract gap in Phase 2 that S15 neither introduced nor worsened; per the operator's
explicit "ekte design-funn → neste sesjon" rule it is **deferred and recorded**, not fixed
as scope creep. This is a genuine ALLOW of the scoped delivery — **not** a WARN-override (there
is no open finding *against* S15's diff).
Per Handover 6, this `review.md` is consumable by `/trekplan --brief …`. With an ALLOW verdict
on the delivered scope and the one deferred finding routed forward, S15 may commit + push, and
the finish-plan continues at S16 (with the deferred `Write` gap reconciled there or in S17).
```json
{
"verdict": "ALLOW",
"verdict_scope": "S15 delivered changes (B1 + B3); 2 files",
"scope": { "sha_start": "baca30f", "sha_end": "baca30f", "reviewed_files_count": 2, "uncommitted_delta": true },
"counts": { "BLOCKER": 0, "MAJOR": 0, "MINOR": 0, "SUGGESTION": 0 },
"findings": [],
"deferred_findings": [
{
"severity": "MAJOR",
"title": "onboarding Phase 2 file-saves need Write, not in allowed-tools",
"file": "commands/onboarding.md",
"line": 142,
"rule_key": "PLAN_EXECUTE_DRIFT",
"status": "pre-existing, out of S15 scope (Phase 2; S15 diff = Phase 3 + Phase 4 line)",
"routed_to": "next session (S16 onboarding/saves surface, or S17 triage)",
"recommended_action": "add Write to onboarding.md allowed-tools (match first-post.md:9-14), or replace the two 'Save to ...' instructions with a node -e Bash write"
}
],
"dropped_findings": []
}
```