@se-studio/skills 1.5.10 → 1.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (24) hide show
  1. package/CHANGELOG.md +12 -1
  2. package/package.json +1 -1
  3. package/references/agent-session/customer-agents-block.md +10 -0
  4. package/references/agent-session/manifest.template.yaml +2 -0
  5. package/references/agent-session/projects.registry.json +2 -1
  6. package/references/agent-session/refuse-customer-patches.md +58 -0
  7. package/references/agent-session/smoke-deploy-failure-playbook.md +80 -0
  8. package/references/contentful-cms-editor-playbooks/PATTERNS.md +22 -1
  9. package/references/contentful-cms-editor-playbooks/PROJECT-ROLLOUT.md +10 -3
  10. package/references/contentful-cms-editor-playbooks/SOURCE-READINESS.md +96 -0
  11. package/references/contentful-cms-editor-playbooks/examples/brightline-learning-hub-article-shaped.md +48 -0
  12. package/references/contentful-cms-editor-playbooks/examples/headwater-news-shaped.md +48 -0
  13. package/references/contentful-cms-editor-playbooks/examples/om1-resource-case-study-shaped.md +52 -0
  14. package/references/contentful-cms-editor-playbooks/examples/pedestal-publication-shaped.md +50 -0
  15. package/references/contentful-cms-editor-playbooks/examples/se-case-study-meet-makers-shaped.md +51 -0
  16. package/references/contentful-cms-editor-playbooks/examples/se-case-study-om1-shaped.md +70 -0
  17. package/references/deployment-smoke-feature-branch-skip/README.md +66 -0
  18. package/references/deployment-smoke-feature-branch-skip/workflow-snippet.yml +38 -0
  19. package/references/deps-update/projects.registry.json +3 -4
  20. package/references/lockfile-sync/README.md +2 -1
  21. package/skills/contentful-cms-create-editor-playbooks/SKILL.md +15 -1
  22. package/skills/se-marketing-sites-smoke-test-setup/SKILL.md +56 -2
  23. package/skills/site-workflows-agent-session/SKILL.md +30 -1
  24. package/skills/site-workflows-deps-update/SKILL.md +2 -2
package/CHANGELOG.md CHANGED
@@ -1,11 +1,22 @@
1
1
  # @se-studio/skills
2
2
 
3
+ ## 1.6.0
4
+
5
+ ### Minor Changes
6
+
7
+ - Add source readiness review as a core editor task, wire create-from-document / create-article / preview-verify to faithful package intake (no copy rewrite), and ship SOURCE-READINESS plus multi-site input examples for playbook authors.
8
+
9
+ ## 1.5.11
10
+
11
+ ### Patch Changes
12
+
13
+ - Document smoke/deploy failure playbook and refuse-customer-patches guardrails (agent-session Step 3b).
14
+
3
15
  ## 1.5.10
4
16
 
5
17
  ### Patch Changes
6
18
 
7
19
  - Document lockfile sync enforcement (scripts, CI snippet, deps-update and smoke-test skill updates).
8
- - 2359f69: Add `site-workflows-stale-files-cleanup` skill and `references/stale-files-cleanup/` for repository hygiene audits on SE Studio marketing sites.
9
20
 
10
21
  ## 1.5.8
11
22
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@se-studio/skills",
3
- "version": "1.5.10",
3
+ "version": "1.6.0",
4
4
  "description": "SE Studio agent skills for marketing site development with Contentful CMS",
5
5
  "repository": {
6
6
  "type": "git",
@@ -22,6 +22,16 @@ Before non-trivial code, run the placement checklist (in the skill). Summary:
22
22
 
23
23
  If the checklist says **core**, stop and switch to core-first mode — do not patch `@se-studio` behaviour in this repo.
24
24
 
25
+ ### Deploy smoke failed?
26
+
27
+ Do **not** change `baseUrl`, discovery routes, or add `getRequestBaseUrl()` to unblock Vercel Deployment Checks. That fix belongs in `@se-studio/site-check` (core-first).
28
+
29
+ 1. Follow the smoke/deploy failure playbook in `se-core-product` — `packages/skills/references/agent-session/smoke-deploy-failure-playbook.md`
30
+ 2. Bump `@se-studio/site-check@2.9.4+` after npm publish (`discovery.urlOrigin: auto`)
31
+ 3. Customer-only: curate new URLs in `smoke.cases.json` when CMS routes go live — not package assertion hacks
32
+
33
+ Record `placement.decision` in `work/active/<feature>.yaml` before smoke/server-config commits aimed at deploy smoke.
34
+
25
35
  ### Core release order
26
36
 
27
37
  When work depends on a new `@se-studio/*` npm release:
@@ -19,6 +19,8 @@ placement:
19
19
  rationale: One-site hero layout tied to OM1 Figma
20
20
  extract_to_core: null # pending | null
21
21
  extract_rationale: null
22
+ # Required before smoke/server-config commits for deploy-smoke goals (agent-session Step 3b):
23
+ # smoke_edit: null # curated-urls | blocked-on-core | defer-extract
22
24
 
23
25
  blocked_on: null # e.g. "@se-studio/core-ui@2.1.0"
24
26
  cms_session: null # set to feature slug when doing parallel CMS edits
@@ -73,7 +73,8 @@
73
73
  "path": "~/source/customers/hopskipdrive/hsd-extended-port",
74
74
  "branch": "extended-port",
75
75
  "type": "customer",
76
- "wip": true,
76
+ "contentfulSpaceIds": ["gqa3p93n5wse"],
77
+ "hostedMcp": ["cms-edit-hsd"],
77
78
  "validate": "pnpm validate"
78
79
  }
79
80
  ]
@@ -0,0 +1,58 @@
1
+ # Refuse customer patches (site-first guardrails)
2
+
3
+ Agents in **site-first** mode must **refuse** customer-repo changes that belong in **`se-core-product`** (`@se-studio/*`), unless the user explicitly approves **`defer-extract`** in the manifest with `extract_to_core: pending` and a dated extraction plan.
4
+
5
+ Run this table **in addition to** the placement checklist (`site-workflows-agent-session` Step 3) when the task touches smoke, deploy checks, shared packages, or infra.
6
+
7
+ ## Refusal triggers
8
+
9
+ | Symptom, file, or request | Correct owner | Agent action (site-first) |
10
+ |---------------------------|---------------|---------------------------|
11
+ | Deploy / `smoke-test:live` failure after bumping `@se-studio/*` | **core** — fix package behaviour | **Stop.** Switch to core-first or set `blocked_on: "@se-studio/<pkg>@<version>"`. Customer only bumps after npm publish. |
12
+ | Discovery smoke (`llms.txt`, `markdown-index.txt`, `cms.txt`, `site-info.md`) origin mismatch on `*.vercel.app` | **core** — `@se-studio/site-check` (`discovery.urlOrigin`) | **Refuse** per-request origin hacks (`getRequestBaseUrl`, `headers()` for `baseUrl`). Bump `site-check@2.9.4+`. |
13
+ | Patching `@se-studio/site-check` expectations in app code | **core** `site-check` | **Refuse.** Open core PR + changeset. |
14
+ | Forking converter / link logic already in `contentful-rest-api` | **core** | **Refuse.** Fix converter or API in core. |
15
+ | `pnpm patch`, `patchedDependencies`, or overrides to fork `@se-studio/*` | **forbidden** | **Refuse** (see root `AGENTS.md`). |
16
+ | New smoke assertion that should apply to all marketing sites | **core** `site-check` | **Refuse** site-only assertion helpers; extend site-check. |
17
+ | `route-build-policy.json` change to hide a core regression (e.g. allow new `ƒ` on CMS routes) | **core** + site routing fix | **Refuse** policy-only workaround; fix why route went dynamic. |
18
+
19
+ ## Allowed customer-only smoke edits
20
+
21
+ | Change | When |
22
+ |--------|------|
23
+ | Add/remove **curated URLs** in `smoke.cases.json` | New CMS pages, article types, tags/people go live — follow `se-marketing-sites-smoke-test-setup` |
24
+ | Set `discovery` flags to `false` | Site-specific infra (e.g. CloudFront not routing discovery paths yet) |
25
+ | `cmsIntegrity.routing` mapping | Per-site URL calculators — not a package bug |
26
+ | Security **probe** cases (`category: probe`) | Site-specific hardening (see brightline reference) |
27
+
28
+ ## `defer-extract` (escape hatch)
29
+
30
+ Use only when the user **explicitly** accepts short-term customer code with a core extraction ticket:
31
+
32
+ 1. Manifest `placement.decision: defer-extract`
33
+ 2. `extract_to_core: pending` + `extract_rationale` (what moves to which package)
34
+ 3. Add `work/tracker.yaml` rollout or `attention` item if multi-site
35
+ 4. **Do not** merge to customer `develop` if it blocks other sites on a shared package fix
36
+
37
+ ## Manifest gate
38
+
39
+ Before committing customer changes to any of:
40
+
41
+ - `smoke.cases.json`, `route-build-policy.json`
42
+ - `src/lib/server-config.ts`, discovery route handlers (`llms.txt`, `markdown-index.txt`, …)
43
+ - `scripts/smoke-test-*.ts`, `.github/workflows/deployment-smoke.yml`
44
+
45
+ …when the **stated goal** is “fix deploy smoke” or “fix site-check failure”:
46
+
47
+ 1. Record `placement.decision` and `placement.rationale` in `work/active/<feature>.yaml`
48
+ 2. If decision is `core`: **do not commit customer workaround** — switch mode
49
+ 3. If decision is `customer`: user must confirm in chat (legitimate site-only URL curation)
50
+ 4. If decision is `defer-extract`: user must confirm extraction plan in chat
51
+
52
+ ## Emergency bypass (temporary only)
53
+
54
+ - `SMOKE_TEST_IGNORE=true` on a single deploy
55
+ - `workflow_dispatch` deployment smoke against a known-good URL
56
+ - Skip Vercel Deployment Check with **human** approval
57
+
58
+ Never treat emergency bypass as permission to land a permanent customer patch for `@se-studio/*` behaviour.
@@ -0,0 +1,80 @@
1
+ # Smoke / deploy failure playbook
2
+
3
+ When **local smoke**, **`smoke-test:live`**, or **Vercel Deployment Checks** fail, follow this sequence. Do **not** patch customer origin/URL logic to satisfy `@se-studio/site-check` assertions.
4
+
5
+ Full refusal rules: [`refuse-customer-patches.md`](./refuse-customer-patches.md).
6
+
7
+ ## 1. Classify the failure
8
+
9
+ Read the failing step and package:
10
+
11
+ | Failure mentions | Likely owner |
12
+ |------------------|--------------|
13
+ | `discovery`, `llms.txt`, `markdown-index.txt`, `urlOrigin`, canonical origin | `@se-studio/site-check` |
14
+ | `article link integrity`, `cmsIntegrity` | `@se-studio/site-check` + site `routing` config (customer OK) or `contentful-rest-api` (core) |
15
+ | `route-build-policy`, `mustBeSsgOrStatic`, `ƒ` on CMS route | Site introduced dynamic APIs — fix site routing/layout **or** core if shared helper caused it |
16
+ | HTML 404/500 on a **curated** smoke path | Site content/routing or CMS — usually **customer** |
17
+ | Lockfile / install on Vercel | Customer lockfile sync — see `lockfile-sync` reference, not site-check |
18
+
19
+ ## 2. If `@se-studio/*` behaviour is wrong → core-first
20
+
21
+ 1. Set manifest `mode: core-first` (or stop and ask user to switch).
22
+ 2. Fix in `packages/<pkg>/`, add **changeset**, run package tests.
23
+ 3. Push `dev` → wait for CI npm publish.
24
+ 4. Add/update `work/tracker.yaml` **rollout** for customer bumps.
25
+ 5. Set customer manifest `blocked_on: "@se-studio/<pkg>@<version>"` until npm confirms.
26
+
27
+ **Customer repo during wait:** only dependency bump via `pnpm update` — no `baseUrl` / origin / assertion hacks.
28
+
29
+ ## 3. If site content/routing is wrong → site-first
30
+
31
+ Examples: wrong slug in `smoke.cases.json`, page unpublished, new article type needs a case.
32
+
33
+ 1. Confirm placement `customer`.
34
+ 2. Refresh cases from production sitemap (`se-marketing-sites-smoke-test-setup` skill).
35
+ 3. Run `pnpm smoke-test:run` locally; `pnpm smoke-test:preview` against develop preview if needed.
36
+
37
+ ## 4. Discovery canonical origin (known anti-pattern)
38
+
39
+ **Symptom:** Deploy smoke hits `https://<project>-<hash>.vercel.app` but `llms.txt` / `markdown-index.txt` list `https://www.example.com/...` links. Smoke fails origin check.
40
+
41
+ **Wrong fix (refuse):**
42
+
43
+ - `getRequestBaseUrl()` from request headers in `server-config` or discovery routes
44
+ - Rewriting discovery output to match deployment host permanently
45
+
46
+ **Right fix:**
47
+
48
+ 1. Core: `@se-studio/site-check@2.9.4+` with `discovery.urlOrigin: auto` (default in smoke runner).
49
+ 2. Customer: `pnpm update @se-studio/site-check@2.9.4 -r`, keep canonical `baseUrl` in app config.
50
+ 3. Tracker rollout: `site-check-discovery-canonical` in `work/tracker.yaml`.
51
+
52
+ ## 5. Emergency unblock (human or agent with explicit approval)
53
+
54
+ | Action | Use when |
55
+ |--------|----------|
56
+ | `workflow_dispatch` deployment smoke | Re-test after core fix + customer bump |
57
+ | `SMOKE_TEST_IGNORE=true` | One-off deploy; document in manifest notes |
58
+ | Human approves blocked Deployment Check | Production promotion already reviewed |
59
+
60
+ Record what was bypassed and the real fix still required (core PR / npm bump).
61
+
62
+ ## 6. Validate before customer push
63
+
64
+ | Check | Command |
65
+ |-------|---------|
66
+ | Local HTTP smoke | `pnpm smoke-test:run` |
67
+ | Preview smoke | `pnpm smoke-test:preview` (develop URL + bypass token) |
68
+ | After core bump | `pnpm update @se-studio/site-check@<version> -r` then re-run smoke |
69
+ | Route policy | `pnpm validate:routes` when Contentful creds available in CI |
70
+
71
+ Deployment checks stay **HTTP-only** — never enable `cmsIntegrity` on Vercel live smoke.
72
+
73
+ ## 7. Handoff
74
+
75
+ Include in manifest / handoff:
76
+
77
+ - Root cause (core vs customer)
78
+ - Published package versions required
79
+ - Tracker rollout id
80
+ - Whether any emergency bypass was used
@@ -122,15 +122,36 @@ Fetch live markdown when `website.markdownAccess` is enabled: `https://<prod><pa
122
122
 
123
123
  - `people.md` — `enablePerson=false`; clinicians covered by `provider-pages.md` on Brightline
124
124
 
125
+ ## Article create pipeline (all sites)
126
+
127
+ When agents build articles or long pages from an **external package** (doc, Drive, Figma, zip):
128
+
129
+ ```text
130
+ task-source-readiness-review → soft-proof + light human yes
131
+ → task-create-from-document / task-create-article
132
+ → task-preview-verify (multi-block QA when relevant)
133
+ ```
134
+
135
+ **Core principles** (also in `SOURCE-READINESS.md`):
136
+
137
+ 1. **No copy rewrite** — faithful structure only
138
+ 2. **Source sequence** beats CMS convenience
139
+ 3. **Do not invent pair/side-by-side layouts** unless the source is a true pair
140
+ 4. **Placeholders** for missing art (GO-WITH-GAPS) rather than silent reordering
141
+ 5. **Merge continuous prose** — avoid body-only section spam
142
+
143
+ Site `articles.md` must name **this site’s** body components. Do not paste SE multi-block / Case study rich text stacks onto brands that use a single Article rich text body.
144
+
125
145
  ## Other playbook types
126
146
 
127
147
  | File | When |
128
148
  |------|------|
129
- | `articles.md` / `ARTICLES.md` | Article types, tag rules, featuredImage vs visuals |
149
+ | `articles.md` / `ARTICLES.md` | Article types, tag rules, featuredImage vs visuals, readiness pointer |
130
150
  | `people.md` | `enablePerson=true` — team profiles, author import |
131
151
  | `blog-tag-matrix.md` | Complex tag governance (Brightline) |
132
152
  | `site-facts.json` | Canonical support email, phone — becomes `site-facts` resource |
133
153
  | `tasks/*.md` only | Overrides for core tasks (e.g. `import-blog-tag-matrix`) |
154
+ | `case-study-from-package.md` (SE) | Optional specialized multi-block package playbook + hosted example |
134
155
 
135
156
  ## Generator behaviour
136
157
 
@@ -178,12 +178,14 @@ Skill: **`contentful-cms-create-editor-playbooks`**
178
178
  | Action | Rationale |
179
179
  |--------|-----------|
180
180
  | **Tighten** existing `pages.md` | Ensure reference table, component mapping, and out-of-scope are current |
181
- | **Tighten** `articles.md` | Work / video / blog rules, case study picks in **Article browser** collections |
181
+ | **Tighten** `articles.md` | Work / video / blog rules; **multi-block Case study / Blog rich text**; **source readiness** + faithful sequence (demote inventing Separated pairs); lab ports |
182
+ | **Add** `case-study-from-package.md` + task stub | Hosted soft-proof example + package intake for work multi-block |
182
183
  | **Avoid** many specialized page playbooks | No `/providers/`-style families |
183
- | Optional `work-case-study-pages.md` | If editors frequently add case studies |
184
184
  | Optional `demo-landing-pages.md` | Campaign clones from `/demo-landing` |
185
185
  | **Do not** add `people.md` | Use articles + Team grid Person guidance inside `pages.md` |
186
186
 
187
+ See also: `SOURCE-READINESS.md` and `examples/se-case-study-*.md` in this references folder.
188
+
187
189
  ### SE website editor guardrails (put in `pages.md`)
188
190
 
189
191
  - New marketing pages: clone `/about`, `/services`, or `/demo-landing` — not blank canvas
@@ -196,6 +198,10 @@ Skill: **`contentful-cms-create-editor-playbooks`**
196
198
 
197
199
  ---
198
200
 
201
+ ## PointMe note
202
+
203
+ When `docs/cms-editor/pointme/` is created, add the shared **source readiness + faithful structure** paragraph to `articles.md` (see other sites’ light-touch pattern). No SE multi-block stacks.
204
+
199
205
  ## Per-project audit checklist
200
206
 
201
207
  Copy into working notes for each site:
@@ -209,8 +215,9 @@ Copy into working notes for each site:
209
215
  [ ] capabilities.json reviewed
210
216
  [ ] P0 playbook list approved by user
211
217
  [ ] pages.md hub links all specialized playbooks
218
+ [ ] articles.md points at task-source-readiness-review (faithful structure, no copy rewrite)
212
219
  [ ] task stub per specialized playbook
213
- [ ] editor-pack regenerated
220
+ [ ] editor-pack regenerated (after @se-studio/contentful-cms bump when new core tasks)
214
221
  [ ] project doctor clean
215
222
  [ ] pushed to develop
216
223
  ```
@@ -0,0 +1,96 @@
1
+ # Source readiness review (generic)
2
+
3
+ Canonical agent guidance for **package intake before CMS create**. Hosted MCP surfaces the short task as `cms-edit://customer/task-source-readiness-review` (from `@se-studio/contentful-cms` editor-tasks). This file is the fuller reference for playbook authors and coding agents.
4
+
5
+ ## Pipeline
6
+
7
+ ```text
8
+ Intake → inventory → beat sheet → verdict → soft-proof → light human yes → create → preview QA
9
+ ```
10
+
11
+ Never skip readiness for non-trivial external packages (Drive, Figma, multi-file zip, long brief).
12
+
13
+ ## Non-negotiables
14
+
15
+ | Rule | Meaning |
16
+ |------|---------|
17
+ | **No copy rewrite** | cms-edit structures and places source text only |
18
+ | **Sequence from design/source** | Do not invent order |
19
+ | **No invented pairs** | Side-by-side collections only when the source is a true pair |
20
+ | **Placeholders beat reordering** | Keep missing slots labeled |
21
+ | **Merge continuous prose** | Don’t split body-only blocks without a layout break |
22
+ | **Light human yes** | Accept “yes” / “go” / “proceed” |
23
+
24
+ ## Verdict threshold
25
+
26
+ ### NO-GO (any one)
27
+
28
+ - Sequence unknown
29
+ - Narrative incomplete for the content type
30
+ - Building would invent structure (pairs, titles, order)
31
+ - Conflicting sources with no owner decision
32
+
33
+ ### GO-WITH-GAPS
34
+
35
+ - Sequence clear + narrative usable as written
36
+ - Missing art **≤ 3** slots **or** **≤ ~25%** of visual beats, each named with placeholder strategy
37
+
38
+ ### GO
39
+
40
+ - GO-WITH-GAPS plus art complete for the soft-proof (or explicit CMS asset reuse)
41
+
42
+ ## Artifact templates
43
+
44
+ ### Inventory
45
+
46
+ | # | Role | Source file / ref | Status | CMS mapping |
47
+ |---|------|-------------------|--------|-------------|
48
+ | 1 | Hero | `hero.jpg` | ready | article `featuredImage` |
49
+ | 2 | Product UI | — | missing | body visual + placeholder label |
50
+
51
+ ### Beat sheet
52
+
53
+ | Order | Beat | Source | Block type | Notes |
54
+ |-------|------|--------|------------|-------|
55
+ | 1 | Open | Doc §1 | Body RTF | merge paras |
56
+ | 2 | Product | `ui.png` | Body + visual | width per playbook |
57
+
58
+ ### Soft-proof (human yes)
59
+
60
+ ```text
61
+ Verdict: GO-WITH-GAPS
62
+ Gaps: #3 left pair art missing → labeled placeholder
63
+ 1. …
64
+ 2. …
65
+ Copy: unchanged from source
66
+ ```
67
+
68
+ ## Site playbooks
69
+
70
+ When authoring `docs/cms-editor/<projectKey>/articles.md`:
71
+
72
+ 1. Point create-from-package flows at `task-source-readiness-review`
73
+ 2. State **faithful structure only**
74
+ 3. Describe **this site’s** body components (do not paste SE multi-block stacks onto other brands)
75
+ 4. Optionally link or embed one condensed example (hosted MCP cannot read skills package paths)
76
+
77
+ ## Worked examples
78
+
79
+ See `examples/` in this folder:
80
+
81
+ | File | Flavour |
82
+ |------|---------|
83
+ | `se-case-study-om1-shaped.md` | SE multi-block work, GO-WITH-GAPS |
84
+ | `se-case-study-meet-makers-shaped.md` | SE simpler multi-block, GO |
85
+ | `om1-resource-case-study-shaped.md` | OM1 resource URL + single body RTF |
86
+ | `brightline-learning-hub-article-shaped.md` | Brightline learning hub |
87
+ | `pedestal-publication-shaped.md` | Pedestal publication |
88
+ | `headwater-news-shaped.md` | Headwater news (GO vs thin NO-GO) |
89
+
90
+ ## Anti-patterns
91
+
92
+ - Defaulting every two images to a pair/side-by-side collection
93
+ - Rewriting client copy “for tone”
94
+ - Dropping missing art and renumbering
95
+ - One body block per paragraph with no visual between (gappy section shells on some sites)
96
+ - Building before soft-proof + yes on a multi-asset package
@@ -0,0 +1,48 @@
1
+ # Example — Brightline learning hub article (readiness + tags)
2
+
3
+ **Site:** Brightline · **Family:** learning hub / blog · **Verdict:** GO-WITH-GAPS
4
+
5
+ ## Scenario
6
+
7
+ > “Turn this clinical-education brief and 2 images into a learning hub article. Follow tag matrix rules.”
8
+
9
+ ## Sources
10
+
11
+ | Source | Notes |
12
+ |--------|--------|
13
+ | Editorial brief | Title + body sections |
14
+ | 2 images | Hero + inline |
15
+ | Tag guidance | blog-tag-matrix / site playbook |
16
+
17
+ ## Inventory
18
+
19
+ | # | Role | Status | Mapping |
20
+ |---|------|--------|---------|
21
+ | 1 | Hero | ready | featuredImage |
22
+ | 2 | Body | ready | Article body per Brightline ARTICLES playbook |
23
+ | 3 | Inline figure | **missing** | placeholder or omit only if human says skip |
24
+ | 4 | Tags | needs human | matrix-constrained |
25
+
26
+ ## Verdict
27
+
28
+ **GO-WITH-GAPS** if body + hero ready and only optional inline missing with a named plan; **NO-GO** if tags/topic cannot be chosen without inventing clinical categories.
29
+
30
+ ## Soft-proof
31
+
32
+ ```text
33
+ Verdict: GO-WITH-GAPS
34
+ 1. Hero + SEO fields from brief (no claim invention)
35
+ 2. Body RTF — source sections in order
36
+ 3. Inline image slot — placeholder or deferred
37
+ 4. Tags — proposed from matrix; human yes required
38
+ ```
39
+
40
+ ## What not to do
41
+
42
+ - Invent tags outside matrix
43
+ - Soften clinical language without human request
44
+ - Clone wrong template family
45
+
46
+ ## Copy policy
47
+
48
+ Faithful structure only; clinical tone left as provided.
@@ -0,0 +1,48 @@
1
+ # Example — Headwater news (GO vs thin NO-GO)
2
+
3
+ **Site:** Headwater Science · **Type:** news · **Verdicts:** GO or NO-GO
4
+
5
+ ## Scenario A — GO
6
+
7
+ > “Publish this press note: full short body (3 paras), date, logo/hero.”
8
+
9
+ ### Inventory
10
+
11
+ | # | Role | Status |
12
+ |---|------|--------|
13
+ | 1 | Headline + body | ready |
14
+ | 2 | Date | ready |
15
+ | 3 | Hero/logo | ready |
16
+
17
+ ### Soft-proof
18
+
19
+ ```text
20
+ Verdict: GO
21
+ 1. News article type + slug
22
+ 2. Title/date/description from source
23
+ 3. Body RTF — three paras as written
24
+ 4. featuredImage
25
+ ```
26
+
27
+ ## Scenario B — NO-GO
28
+
29
+ > “Make a news post from this one-line LinkedIn blurb and no assets.”
30
+
31
+ ### Why NO-GO
32
+
33
+ - Narrative incomplete (no usable body)
34
+ - No art and no permission to ship without
35
+ - Building would invent paragraphs
36
+
37
+ ### Agent response
38
+
39
+ Stop. List blockers. Do not invent body copy. Ask for full release text or explicit human-written draft.
40
+
41
+ ## What not to do
42
+
43
+ - Expand a one-liner into a fake press release
44
+ - Borrow SE case-study multi-block patterns
45
+
46
+ ## Copy policy
47
+
48
+ Only structure what was given.
@@ -0,0 +1,52 @@
1
+ # Example — OM1 resource case study (single body, readiness still applies)
2
+
3
+ **Site:** OM1 · **URL family:** `/resources/case-studies/{topic}/{slug}/` · **Verdict:** GO
4
+
5
+ OM1 does **not** use SE multi-block CSRT stacks. Body is typically **one Article rich text** (+ optional quote/callout). Readiness still runs so agents don’t invent structure or rewrite.
6
+
7
+ ## Scenario
8
+
9
+ > “Create a case study article from this approved PDF/narrative and hero image. Topic tag AI.”
10
+
11
+ ## Sources
12
+
13
+ | Source | Notes |
14
+ |--------|--------|
15
+ | Approved narrative PDF/doc | Full article copy |
16
+ | Hero landscape | featuredImage |
17
+ | Primary topic | `ai` (must match URL segment) |
18
+ | Clone ref | Existing case-studies article from playbook |
19
+
20
+ ## Inventory
21
+
22
+ | # | Role | Status | Mapping |
23
+ |---|------|--------|---------|
24
+ | 1 | Hero | ready | `featuredImage` |
25
+ | 2 | Body | ready | Article rich text (single) |
26
+ | 3 | Authors | ready | Person links |
27
+ | 4 | Primary tag | ready | drives `{topic}` |
28
+
29
+ ## Verdict
30
+
31
+ **GO** — narrative complete, hero present, topic decided. No multi-ART invent.
32
+
33
+ ## Soft-proof
34
+
35
+ ```text
36
+ Verdict: GO
37
+ 1. [template] Article hero fields from entry
38
+ 2. Article rich text — full body from doc (as written)
39
+ 3. Optional quote only if present in source
40
+ Slug/topic/type per resource-article-pages playbook
41
+ ```
42
+
43
+ ## What not to do
44
+
45
+ - Import SE “Case study rich text” multi-block pattern
46
+ - Invent Separated visuals
47
+ - Rewrite clinical claims
48
+ - Wrong primary tag (breaks URL)
49
+
50
+ ## Copy policy
51
+
52
+ Unchanged; structure into one body RTF (+ embeds only if source has them).
@@ -0,0 +1,50 @@
1
+ # Example — Pedestal publication (poster + download fields)
2
+
3
+ **Site:** Pedestal Health · **Type:** publications · **Verdict:** GO
4
+
5
+ ## Scenario
6
+
7
+ > “Add this publication: title, abstract, poster image, and PDF download.”
8
+
9
+ ## Sources
10
+
11
+ | Source | Notes |
12
+ |--------|--------|
13
+ | Title + abstract | From publisher brief |
14
+ | Poster image | Landscape/portrait per playbook |
15
+ | PDF file | Download asset |
16
+ | Clone ref | Recent publication from playbook |
17
+
18
+ ## Inventory
19
+
20
+ | # | Role | Status | Mapping |
21
+ |---|------|--------|---------|
22
+ | 1 | Listing/hero art | ready | featuredImage / poster field per playbook |
23
+ | 2 | Abstract | ready | summary / body fields as site defines |
24
+ | 3 | PDF | ready | download / media field |
25
+ | 4 | Tags/type | ready | publications type + routing |
26
+
27
+ ## Verdict
28
+
29
+ **GO** when PDF + poster + abstract present. **NO-GO** if PDF missing and playbook requires download (don’t fake a link).
30
+
31
+ ## Soft-proof
32
+
33
+ ```text
34
+ Verdict: GO
35
+ 1. Article type publications + slug
36
+ 2. Fields: title, date, description from abstract (no rewrite)
37
+ 3. Poster / featured image
38
+ 4. PDF asset linked
39
+ 5. Body only if playbook expects more than abstract
40
+ ```
41
+
42
+ ## What not to do
43
+
44
+ - Invent abstract from title alone
45
+ - Skip PDF and ship empty download
46
+ - Apply SE multi-block case-study layout
47
+
48
+ ## Copy policy
49
+
50
+ Abstract and titles as provided.
@@ -0,0 +1,51 @@
1
+ # Example — SE case study (Meet the Makers–shaped, GO)
2
+
3
+ **Site:** SE Studio · **Type:** work · **Verdict:** GO
4
+
5
+ Smaller multi-block set; good first lab target. Production public path pattern: `/work/{client}/{title-slug}/` (lab: `lab/…`).
6
+
7
+ ## Scenario
8
+
9
+ > “Port this simpler case study multi-block for lab. Faithful art order; don’t invent pairs.”
10
+
11
+ ## Sources
12
+
13
+ | Source | Notes |
14
+ |--------|--------|
15
+ | Ordered image list from human / Figma | Clear sequence |
16
+ | Short narrative | Intro, process, outcome |
17
+ | Existing assets in CMS or Drive | All present |
18
+
19
+ ## Inventory (excerpt)
20
+
21
+ | # | Role | Status | Mapping |
22
+ |---|------|--------|---------|
23
+ | 1 | Hero | ready | featuredImage |
24
+ | 2 | Intro copy | ready | CSRT body (merge) |
25
+ | 3 | Maker portraits sequence | ready | CSRT visuals or Visuals only if design is a grid |
26
+ | 4 | Closing copy | ready | CSRT body |
27
+
28
+ ## Verdict
29
+
30
+ **GO** — sequence known, art complete, copy usable as written.
31
+
32
+ ## Soft-proof
33
+
34
+ ```text
35
+ Verdict: GO
36
+ 1. Hero (template)
37
+ 2. CSRT body — intro
38
+ 3. CSRT visual / stacked media per design (not inventing Separated)
39
+ 4. CSRT body — close
40
+ Lab flags on
41
+ ```
42
+
43
+ ## What not to do
44
+
45
+ - Force Separated because “there are two portraits”
46
+ - Add section headings the source doesn’t have
47
+ - Touch production entry — always new lab draft
48
+
49
+ ## Copy policy
50
+
51
+ Unchanged from source.
@@ -0,0 +1,70 @@
1
+ # Example — SE case study from package (OM1-shaped, GO-WITH-GAPS)
2
+
3
+ **Site:** SE Studio (`se2026`) · **Type:** work case study · **Verdict used:** GO-WITH-GAPS
4
+
5
+ Synthetic package shaped like a real multi-block work port (Drive zip + Figma sequence + narrative). Names are illustrative.
6
+
7
+ ## Scenario
8
+
9
+ > “Build a lab case study from this Drive folder and the Figma OM1 frame. Keep copy as written.”
10
+
11
+ ## Sources provided
12
+
13
+ | Source | Notes |
14
+ |--------|--------|
15
+ | Figma frame (ordered art direction) | Sequence + pair moments + widths |
16
+ | Drive zip (~11 files) | Photos, UI grabs, 2 decorative videos |
17
+ | Narrative doc | Origin → challenge → approach → close |
18
+ | Production ref | Other SE work pieces for hero/template only |
19
+
20
+ ## Inventory (excerpt)
21
+
22
+ | # | Role | File | Status | Mapping |
23
+ |---|------|------|--------|---------|
24
+ | 1 | Hero | `OM1_Hero.jpg` | ready | article `featuredImage` |
25
+ | 2 | Website UI | `OM1_websiteImage.png` | ready | CSRT `visual` ~80% |
26
+ | 3L | Pair left | — | **missing** | Separated left + **placeholder** |
27
+ | 3R | Pair right | `OM1_BlueModel.jpg` | ready | Separated right |
28
+ | 4 | Origin copy | Doc §1–2 | ready | CSRT body only (merge paras) |
29
+ | 5 | Hands photo | `OM1_HandsWithScreen.jpg` | ready | CSRT visual 100% |
30
+ | 6L | Pair left | `OM1_ManAndPatterns.jpg` | ready | Separated left |
31
+ | 6R | Pair right dialogs | — | **missing** | Separated right + **placeholder** |
32
+ | 7 | Challenge copy | Doc §3 | ready | CSRT body only |
33
+ | 8 | Landscape demo | `…LandscapeBlue….mp4` | ready | CSRT visual; autoplay+loop |
34
+ | … | … | … | … | … |
35
+
36
+ ## Verdict
37
+
38
+ **GO-WITH-GAPS** — sequence clear from Figma; narrative complete; **2 missing visual slots** (≤3), each placeholder-labeled. Do not invent substitute art or drop slots.
39
+
40
+ ## Soft-proof (structure only; copy unchanged)
41
+
42
+ ```text
43
+ Verdict: GO-WITH-GAPS
44
+ 1. [template] Article hero — title/subtitle from doc; featuredImage hero
45
+ 2. CSRT media — website UI 80%
46
+ 3. Separated visuals — placeholder left | blue model right
47
+ 4. CSRT body — origin paras (merged)
48
+ 5. CSRT media — hands 100%
49
+ 6. Separated — man/patterns | placeholder dialogs
50
+ 7. CSRT body — challenge
51
+ 8. CSRT media — landscape video autoplay+loop ~70%
52
+ 9. CSRT body — approach
53
+ 10. CSRT media — mobile screens
54
+ 11. Quote — as in source
55
+ 12. Separated or CSRTs — pattern | orange demo (only if Figma is a true pair)
56
+ 13. CSRT body — close
57
+ Lab: slug lab/…, hidden, unindexed
58
+ ```
59
+
60
+ ## What not to do
61
+
62
+ - Invent Separated for stacked single images
63
+ - Rewrite narrative “for flow”
64
+ - Reorder to put all text first
65
+ - Use article `visuals` as a dump for body art
66
+ - Skip placeholders and renumber
67
+
68
+ ## Copy policy
69
+
70
+ **Unchanged.** Meta `description` drafted from existing claims only; human **yes** on soft-proof.
@@ -0,0 +1,66 @@
1
+ # Deployment smoke — skip on feature branches
2
+
3
+ Vercel **Deployment Checks** wait for a GitHub status from the smoke workflow. On feature-branch previews the `smoke` job `if` excludes the branch, so **no job runs and no status is posted** — Vercel stays on "Waiting for checks" and the PR blocks.
4
+
5
+ **Fix:** add a `skip-smoke-outside-integration-branches` job that posts **success** when the deploy ref is not an integration/production branch. Real smoke still runs only on integration preview + production.
6
+
7
+ ## Requirements
8
+
9
+ 1. Workflow file must exist on the repo **default branch** (`develop`, `dev`, or registry override) — `repository_dispatch` runs workflows from default branch, not the feature branch.
10
+ 2. `permissions.statuses: write` on the workflow.
11
+ 3. `CHECK_NAME` must match the status name registered in Vercel → Settings → Deployment Checks (exact string).
12
+ 4. `smoke` job `if` must already limit runs to integration + production (do not run smoke on feature branches).
13
+
14
+ ## Integration branch names
15
+
16
+ | Repo type | Preview smoke ref | Production smoke ref |
17
+ |-----------|-------------------|----------------------|
18
+ | Most customer sites | `develop` | `main` |
19
+ | HopSkipDrive extended-port | `extended-port` | `main` (if production checks enabled) |
20
+ | se-core-product apps | `dev` | `main` |
21
+
22
+ Use `client_payload.git.ref` (branch name, not `refs/heads/...` — verify per project in a test dispatch).
23
+
24
+ ## Copy-paste
25
+
26
+ See [`workflow-snippet.yml`](workflow-snippet.yml). One skip job per Vercel project / workflow file (monorepos with multiple marketing apps need one skip job each).
27
+
28
+ ## cms-edit host (optional)
29
+
30
+ Feature-branch PRs also trigger cms-edit Vercel projects. Skip builds outside integration branches via `ignoreCommand` in `cms-edit/host/vercel.json`:
31
+
32
+ ```json
33
+ "ignoreCommand": "if [ \"$VERCEL_GIT_COMMIT_REF\" != \"develop\" ] && [ \"$VERCEL_GIT_COMMIT_REF\" != \"main\" ]; then exit 0; fi; git diff HEAD^ HEAD --quiet -- . ../ ../../pnpm-lock.yaml ../../pnpm-workspace.yaml ../../package.json || exit 1; exit 0"
34
+ ```
35
+
36
+ Replace `develop` with your integration branch (e.g. `extended-port`).
37
+
38
+ ## Rollout status
39
+
40
+ | Repo | Skip job on feature branches | cms-edit ignore |
41
+ |------|------------------------------|-----------------|
42
+ | brightline-sites | done (both apps) | done |
43
+ | se-website-2026 | pending → M4 branch | pending |
44
+ | om1-website | audit | audit |
45
+ | pedestal-sites | audit | audit |
46
+ | pointme | audit | audit |
47
+ | hsd-extended-port | audit | n/a |
48
+
49
+ Update this table when applying the pattern.
50
+
51
+ ## Emergency unblock (one PR)
52
+
53
+ If the skip job is not yet on default branch, post success manually:
54
+
55
+ ```bash
56
+ gh api "repos/<owner>/<repo>/statuses/<commit-sha>" \
57
+ -f state=success \
58
+ -f context="Vercel - <project-name>: deployment smoke" \
59
+ -f description="Skipped — deployment smoke runs only on develop and main"
60
+ ```
61
+
62
+ ## Verify
63
+
64
+ 1. Merge skip job to default branch.
65
+ 2. Open a feature PR — Vercel preview should complete without pending deployment smoke.
66
+ 3. Push to `develop` — deployment smoke should run and gate aliasing as before.
@@ -0,0 +1,38 @@
1
+ # Add BEFORE the smoke job in each deployment-smoke workflow.
2
+ # Replace <vercel-project-name> and integration/production refs as needed.
3
+
4
+ jobs:
5
+ skip-smoke-outside-integration-branches:
6
+ if: |
7
+ github.event_name == 'repository_dispatch' &&
8
+ github.event.client_payload.project.name == '<vercel-project-name>' &&
9
+ github.event.client_payload.git.ref != 'develop' &&
10
+ github.event.client_payload.git.ref != 'main'
11
+ runs-on: ubuntu-latest
12
+ steps:
13
+ - name: Skip deployment smoke on feature branches
14
+ env:
15
+ CHECK_NAME: 'Vercel - <vercel-project-name>: deployment smoke'
16
+ DEPLOYMENT_SHA: ${{ github.event.client_payload.git.sha }}
17
+ GH_TOKEN: ${{ github.token }}
18
+ run: |
19
+ gh api "repos/${GITHUB_REPOSITORY}/statuses/${DEPLOYMENT_SHA}" \
20
+ -f state=success \
21
+ -f context="${CHECK_NAME}" \
22
+ -f description="Skipped — deployment smoke runs only on develop and main" \
23
+ -f target_url="${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID}"
24
+
25
+ smoke:
26
+ if: |
27
+ (github.event_name == 'workflow_dispatch') ||
28
+ (
29
+ github.event_name == 'repository_dispatch' &&
30
+ github.event.client_payload.project.name == '<vercel-project-name>' &&
31
+ (
32
+ (github.event.client_payload.git.ref == 'develop' &&
33
+ github.event.client_payload.environment == 'preview') ||
34
+ (github.event.client_payload.git.ref == 'main' &&
35
+ github.event.client_payload.environment == 'production')
36
+ )
37
+ )
38
+ # ... existing smoke steps unchanged ...
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "canonicalPatchesScript": "~/source/se/se-core-product/scripts/check-no-pnpm-patches.mjs",
3
3
  "pinOverrides": {
4
- "next": "^15.5.19",
5
- "@types/node": "^24.13.2"
4
+ "next": "^15.5.21",
5
+ "@types/node": "^24.13.3"
6
6
  },
7
7
  "pnpm": {
8
8
  "major": 11,
@@ -72,8 +72,7 @@
72
72
  "displayName": "HopSkipDrive Extended Port",
73
73
  "path": "~/source/customers/hopskipdrive/hsd-extended-port",
74
74
  "branch": "extended-port",
75
- "wip": true,
76
- "wipNote": "Parity port from legacy GraphQL/Netlify site onto @se-studio packages. Work on extended-port only — not develop/production. Defer routine deps bumps until parity snags are under control unless explicitly requested.",
75
+ "wipNote": "Parity port complete (2026-07-07). Work on extended-port only — not develop/production until cutover. Rollouts tracked in work/tracker.yaml.",
77
76
  "validate": "pnpm validate",
78
77
  "workspace": false,
79
78
  "hasPinOverrides": false
@@ -48,7 +48,8 @@ Apply the full stack when touching deps or CI in each repo:
48
48
  | brightline-sites | yes | yes | yes | yes |
49
49
  | pedestal-sites | — | partial | — | no |
50
50
  | om1-website | — | — | — | — |
51
- | se-website-2026 | — | — | — | — |
51
+ | se-website-2026 | yes | yes | yes | yes |
52
52
  | pointme | — | — | — | — |
53
+ | hsd-extended-port | yes | yes (extended-port) | n/a | yes |
53
54
 
54
55
  Update this table as repos adopt the pattern.
@@ -11,8 +11,10 @@ Use this skill when a customer site needs **hosted MCP editor playbooks** — th
11
11
 
12
12
  | File | Purpose |
13
13
  |------|---------|
14
- | `.agents/references/contentful-cms-editor-playbooks/PATTERNS.md` | Two-file pattern, sections, naming, Brightline examples |
14
+ | `.agents/references/contentful-cms-editor-playbooks/PATTERNS.md` | Two-file pattern, sections, naming, Brightline examples, article create pipeline |
15
15
  | `.agents/references/contentful-cms-editor-playbooks/PROJECT-ROLLOUT.md` | Rollout queue (Pedestal → OM1 → PointMe → SE website) and per-site audit hints |
16
+ | `.agents/references/contentful-cms-editor-playbooks/SOURCE-READINESS.md` | Package intake, GO / GO-WITH-GAPS / NO-GO, faithful structure (no copy rewrite) |
17
+ | `.agents/references/contentful-cms-editor-playbooks/examples/` | Worked input packages (SE, OM1, Brightline, Pedestal, Headwater) |
16
18
 
17
19
  ## When to use
18
20
 
@@ -139,6 +141,18 @@ See `PATTERNS.md` for the full Brightline hub example.
139
141
 
140
142
  **Do not** put task stubs in the root — only under `tasks/`.
141
143
 
144
+ ### Articles playbooks (article-heavy sites)
145
+
146
+ When writing or tightening `articles.md` / `ARTICLES.md`:
147
+
148
+ 1. Point external package creates at **`task-source-readiness-review`** (core task from `@se-studio/contentful-cms`)
149
+ 2. State **faithful structure only — do not rewrite source copy**
150
+ 3. Composition follows **source sequence**; do **not** invent pair/side-by-side layouts unless the design is a true pair
151
+ 4. Name **this site’s** body components only (never paste SE Case study rich text multi-block onto other brands)
152
+ 5. Optional: one condensed example or link to a specialized package playbook for high-traffic types
153
+
154
+ See `SOURCE-READINESS.md` and `examples/`.
155
+
142
156
  ### Specialized playbook sections
143
157
 
144
158
  Each `<topic>.md` should include:
@@ -56,6 +56,8 @@ Example `package.json` entries:
56
56
 
57
57
  **Vercel Deployment Check (live URL)** — GitHub Action on `vercel.deployment.ready` tests `client_payload.url` before production domains alias. Workflow must live on the repo **default branch**. Register the status `name` in Vercel → Settings → Build and Deployment → Deployment Checks.
58
58
 
59
+ **Feature branches must not run smoke** — limit the `smoke` job to integration preview (`develop` + `preview`) and production (`main` + `production`). Feature-branch previews still fire `repository_dispatch`; without a matching job, Vercel waits forever on "Waiting for checks". Add a `skip-smoke-outside-integration-branches` job that posts **success** for non-integration refs. Full rollout guide: [`references/deployment-smoke-feature-branch-skip/`](../../references/deployment-smoke-feature-branch-skip/README.md). Monorepos: one skip job per Vercel project workflow. Non-`develop` integration branches (e.g. HSD `extended-port`): adjust ref checks in both jobs.
60
+
59
61
  Filter on `client_payload.environment == 'production'` when Deployment Checks target production only. Vercel also dispatches for preview and custom environments (`preview`, `develop`, etc.); skip those to avoid duplicate CI runs. Use `workflow_dispatch` without an environment filter for manual smoke against any URL.
60
62
 
61
63
  ```yaml
@@ -67,11 +69,45 @@ on:
67
69
  types:
68
70
  - vercel.deployment.ready
69
71
 
72
+ permissions:
73
+ contents: read
74
+ actions: read
75
+ statuses: write
76
+
70
77
  jobs:
71
- smoke:
78
+ skip-smoke-outside-integration-branches:
72
79
  if: |
80
+ github.event_name == 'repository_dispatch' &&
73
81
  github.event.client_payload.project.name == '<vercel-project-name>' &&
74
- github.event.client_payload.environment == 'production'
82
+ github.event.client_payload.git.ref != 'develop' &&
83
+ github.event.client_payload.git.ref != 'main'
84
+ runs-on: ubuntu-latest
85
+ steps:
86
+ - name: Skip deployment smoke on feature branches
87
+ env:
88
+ CHECK_NAME: 'Vercel - <vercel-project-name>: deployment smoke'
89
+ DEPLOYMENT_SHA: ${{ github.event.client_payload.git.sha }}
90
+ GH_TOKEN: ${{ github.token }}
91
+ run: |
92
+ gh api "repos/${GITHUB_REPOSITORY}/statuses/${DEPLOYMENT_SHA}" \
93
+ -f state=success \
94
+ -f context="${CHECK_NAME}" \
95
+ -f description="Skipped — deployment smoke runs only on develop and main" \
96
+ -f target_url="${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID}"
97
+
98
+ smoke:
99
+ if: |
100
+ (github.event_name == 'workflow_dispatch') ||
101
+ (
102
+ github.event_name == 'repository_dispatch' &&
103
+ github.event.client_payload.project.name == '<vercel-project-name>' &&
104
+ (
105
+ (github.event.client_payload.git.ref == 'develop' &&
106
+ github.event.client_payload.environment == 'preview') ||
107
+ (github.event.client_payload.git.ref == 'main' &&
108
+ github.event.client_payload.environment == 'production')
109
+ )
110
+ )
75
111
  runs-on: ubuntu-latest
76
112
  steps:
77
113
  - uses: vercel/repository-dispatch/actions/checkout@v1
@@ -377,6 +413,24 @@ Commit `route-build-policy.json` beside `smoke.cases.json`. Start from `@se-stud
377
413
 
378
414
  **HubSpot bootstrap:** use `createHubSpotBootstrapScript()` with no args in root layout — not `headers()` + middleware pathname.
379
415
 
416
+ ## Deploy / live smoke failure playbook
417
+
418
+ When **`pnpm smoke-test:live`**, Vercel Deployment Checks, or preview smoke fail after a dependency bump, **do not** patch customer `baseUrl`/origin logic to satisfy `@se-studio/site-check`.
419
+
420
+ **Playbook:** [`packages/skills/references/agent-session/smoke-deploy-failure-playbook.md`](../../references/agent-session/smoke-deploy-failure-playbook.md)
421
+
422
+ **Refusal rules:** [`packages/skills/references/agent-session/refuse-customer-patches.md`](../../references/agent-session/refuse-customer-patches.md) (agent-session Step 3b)
423
+
424
+ Quick sequence:
425
+
426
+ 1. **Classify** — discovery/origin → `site-check`; broken slug → customer `smoke.cases.json`; new `ƒ` route → fix dynamic APIs.
427
+ 2. **Core-first** if package behaviour is wrong — changeset, push `dev`, tracker rollout, customer `blocked_on` until npm.
428
+ 3. **Customer-only** if curating URLs — refresh from sitemap; one case per **enabled** article-type segment.
429
+ 4. **Discovery canonical origin** — bump `site-check@2.9.4+`; never add `getRequestBaseUrl()` (tracker rollout `site-check-discovery-canonical`).
430
+ 5. **Emergency** — `SMOKE_TEST_IGNORE` or `workflow_dispatch` smoke; not a permanent site patch.
431
+
432
+ Record `placement.decision` in manifest before smoke/server-config commits aimed at unblocking deploy.
433
+
380
434
  ## Reference
381
435
 
382
436
  - HTTP + integrity example: `apps/example-empty/smoke.cases.json` and `scripts/smoke-test-run.ts` (monorepo).
@@ -78,6 +78,16 @@ If the user works only in a customer repo with no core checkout, still create/up
78
78
 
79
79
  **One feature = one manifest.** Do not append unrelated work to an existing manifest.
80
80
 
81
+ ### Cross-site tracker (`work/tracker.yaml`)
82
+
83
+ For work that spans repos (core npm rollouts, deployment gates, “bump on all sites”):
84
+
85
+ 1. Add or update a `rollouts` entry in `work/tracker.yaml` when a `@se-studio/*` release needs customer adoption
86
+ 2. Add `attention` items for human-only gates (blocked Vercel deploy, hosted MCP smoke, merge decisions)
87
+ 3. Run `pnpm work:tracker` from se-core-product to refresh `work/TRACKER.md`
88
+
89
+ Humans glance at **`work/TRACKER.md`** for the dashboard; agents edit `tracker.yaml` + manifests.
90
+
81
91
  ---
82
92
 
83
93
  ## Step 3 — Placement checklist (before non-trivial code)
@@ -105,6 +115,25 @@ Run before implementing anything beyond a one-line fix. Record results in manife
105
115
 
106
116
  **Core-first guard:** If checklist says `customer`, implement in customer repo (read-only probe in core example apps only if useful).
107
117
 
118
+ ### Step 3b — Refuse customer patches (mandatory)
119
+
120
+ After the placement checklist, run the **refusal table** when the task involves deploy smoke, `smoke.cases.json`, discovery routes, `server-config`, or “fix site-check / unblock Vercel.”
121
+
122
+ **Reference:** [`packages/skills/references/agent-session/refuse-customer-patches.md`](../../references/agent-session/refuse-customer-patches.md)
123
+
124
+ | If the fix would… | Agent must |
125
+ |-------------------|------------|
126
+ | Patch `@se-studio/*` behaviour in the customer repo | **Refuse** — core-first + changeset |
127
+ | Add `getRequestBaseUrl` or per-request origin for discovery smoke | **Refuse** — bump `@se-studio/site-check@2.9.4+` (`discovery.urlOrigin: auto`) |
128
+ | Change `route-build-policy.json` only to hide a new `ƒ` CMS route | **Refuse** — fix dynamic usage (Biome / layout) |
129
+ | Add curated URLs or site-only probe cases | **Allow** — placement `customer`; follow smoke-test skill |
130
+
131
+ **Deploy / live smoke failed?** Follow [`smoke-deploy-failure-playbook.md`](../../references/agent-session/smoke-deploy-failure-playbook.md) — classify failure → core vs customer → `blocked_on` if waiting on npm. Emergency: `SMOKE_TEST_IGNORE` or human Deployment Check approval — **not** permanent site hacks.
132
+
133
+ **Manifest gate:** Before committing customer changes to smoke config, discovery routes, or `server-config` for deploy-smoke goals, record `placement.decision` in `work/active/<feature>.yaml`. If `core`, do not commit customer workaround.
134
+
135
+ **`defer-extract`:** Only when the user explicitly approves in chat. Set `extract_to_core: pending` + rationale; add tracker rollout if multi-site.
136
+
108
137
  ---
109
138
 
110
139
  ## Step 4 — Git isolation
@@ -274,6 +303,6 @@ Agent must load this skill, write manifest, run placement checklist, confirm bra
274
303
  | `om1` | `develop` | customer |
275
304
  | `pointme` | `develop` | customer |
276
305
  | `pedestal` | `develop` | customer monorepo |
277
- | `hsd-extended-port` | `extended-port` | customer (WIP) |
306
+ | `hsd-extended-port` | `extended-port` | customer |
278
307
 
279
308
  Full paths and MCP keys: `projects.registry.json`.
@@ -51,11 +51,11 @@ Run that locally **before push** whenever `package.json`, lockfile, or overrides
51
51
  | `om1` | OM1 Website | `develop` |
52
52
  | `pointme` | PointMe Marketing Site | `develop` |
53
53
  | `pedestal` | Pedestal Sites | `develop` |
54
- | `hsd-extended-port` | HopSkipDrive Extended Port **(WIP)** | `extended-port` |
54
+ | `hsd-extended-port` | HopSkipDrive Extended Port | `extended-port` |
55
55
 
56
56
  User may name a key (`update deps in om1`) or ask to run through all projects sequentially.
57
57
 
58
- **WIP:** `hsd-extended-port` is an active parity port — branch `extended-port`, not `develop`. Prefer standards alignment and targeted `@se-studio/*` catch-up over full `pnpm update -r --latest` until the snag list is stable.
58
+ **HSD extended-port:** Parity complete (2026-07-07). Branch `extended-port`, not `develop`, until production cutover. Rollouts tracked in `work/tracker.yaml` — prefer targeted `@se-studio/*` bumps per rollout before full `pnpm update -r --latest`.
59
59
 
60
60
  ---
61
61