@topy-ai/maggie 0.7.38 → 0.7.41

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 (95) hide show
  1. package/README-zh-TW.md +82 -6
  2. package/README.md +99 -7
  3. package/bin/maggie.js +30 -3
  4. package/bundled-contracts/maggie-clone/interaction-state-v1.schema.json +26 -0
  5. package/bundled-contracts/maggie-content/provenance-v1.schema.json +20 -0
  6. package/bundled-contracts/maggie-design/brand-kit-v1.schema.json +18 -0
  7. package/bundled-contracts/maggie-design/browser-interactions-v1.schema.json +27 -0
  8. package/bundled-contracts/maggie-design/css-utility-evidence-v1.schema.json +10 -0
  9. package/bundled-contracts/maggie-design/dashboard-surface-v1.schema.json +11 -0
  10. package/bundled-contracts/maggie-design/progressive-enhancement-v1.schema.json +12 -0
  11. package/bundled-contracts/maggie-design/sample-surface-v1.schema.json +13 -0
  12. package/bundled-contracts/maggie-design/style-editing-v1.schema.json +35 -0
  13. package/bundled-contracts/maggie-media/image-generation-policy-v1.json +28 -0
  14. package/bundled-contracts/maggie-media/video-generation-policy-v1.json +40 -0
  15. package/bundled-contracts/maggie-media/video-job-v1.schema.json +20 -0
  16. package/bundled-contracts/maggie-media/video-playback-evidence-v1.schema.json +15 -0
  17. package/bundled-contracts/maggie-ops/npm11-preflight-v1.schema.json +17 -0
  18. package/bundled-contracts/maggie-scaffold/host-scaffold-v1.schema.json +25 -0
  19. package/bundled-contracts/maggie-seo/gsc-readiness-v1.schema.json +19 -0
  20. package/bundled-contracts/maggie-seo/privacy-origin-evidence-v1.schema.json +11 -0
  21. package/bundled-contracts/maggie-service-booking/delivery-provider-default-v1.json +8 -0
  22. package/bundled-contracts/maggie-service-booking/delivery-provider-v1.schema.json +16 -0
  23. package/bundled-contracts/maggiedash/booking-access-v1.json +5 -4
  24. package/bundled-contracts/maggiedash/booking-customer-surface-v1.json +12 -1
  25. package/bundled-contracts/maggiedash/booking-email-templates-v1.json +2 -0
  26. package/bundled-contracts/maggiedash/booking-host-adapter-v1.json +14 -2
  27. package/bundled-contracts/maggiedash/booking-runtime.v1.json +41 -0
  28. package/bundled-contracts/maggiedash/browser-session-v1.schema.json +18 -0
  29. package/bundled-contracts/maggiedash/content-overrides-v1.schema.json +19 -0
  30. package/bundled-contracts/maggiedash/execution-board.json +526 -26
  31. package/bundled-contracts/maggiedash/host-capabilities-v1.schema.json +10 -0
  32. package/bundled-contracts/maggiedash/public-session-cache-v1.schema.json +17 -0
  33. package/bundled-contracts/maggiedash/site-structure-v1.schema.json +13 -0
  34. package/bundled-references/browser-inspection.md +21 -0
  35. package/bundled-references/maggiedash-booking/ARCHITECTURE.md +218 -0
  36. package/bundled-references/maggiedash-booking/CURRENT-STATE.md +92 -0
  37. package/bundled-references/maggiedash-booking/DATA-FLOW.md +143 -0
  38. package/bundled-references/maggiedash-booking/DATA-MODEL.md +367 -0
  39. package/bundled-references/maggiedash-booking/DECISIONS.md +94 -0
  40. package/bundled-references/maggiedash-booking/EXECUTION-BOARD.json +2387 -0
  41. package/bundled-references/maggiedash-booking/HOST-ADAPTER.md +314 -0
  42. package/bundled-references/maggiedash-booking/ORAWELLNESS-INTEGRATION-AUDIT.md +227 -0
  43. package/bundled-references/maggiedash-booking/PAYMENT-GATEWAY.md +267 -0
  44. package/bundled-references/maggiedash-booking/PRD.md +228 -0
  45. package/bundled-references/maggiedash-booking/PROGRESS.md +2434 -0
  46. package/bundled-references/maggiedash-booking/QA-TEST-PLAN.md +235 -0
  47. package/bundled-references/maggiedash-booking/README.md +271 -0
  48. package/bundled-references/maggiedash-booking/RUNTIME-OPERATIONS.md +152 -0
  49. package/bundled-references/maggiedash-booking/SECURITY-COMPLIANCE.md +158 -0
  50. package/bundled-references/maggiedash-booking/SKILLS-AND-CLI.md +542 -0
  51. package/bundled-references/maggiedash-booking/STRIPE-INTEGRATION.md +129 -0
  52. package/bundled-references/maggiedash-booking/TASK-RUNBOOK.md +107 -0
  53. package/bundled-references/maggiedash-booking/TASKS.md +137 -0
  54. package/bundled-references/maggiedash-booking/USER-JOURNEYS.md +224 -0
  55. package/bundled-references/maggiedash-booking/diagrams/booking-dfd.excalidraw +1 -0
  56. package/bundled-references/maggiedash-booking/diagrams/booking-dfd.mmd +16 -0
  57. package/bundled-references/maggiedash-booking/diagrams/booking-dfd.png +0 -0
  58. package/bundled-references/maggiedash-booking/diagrams/booking-dfd.svg +1 -0
  59. package/bundled-references/maggiedash-booking/diagrams/booking-state-machine.mmd +19 -0
  60. package/bundled-references/maggiedash-booking/diagrams/booking-state-machine.png +0 -0
  61. package/bundled-references/maggiedash-booking/diagrams/booking-state-machine.svg +1 -0
  62. package/bundled-references/maggiedash-booking/diagrams/manager-journey.excalidraw +1 -0
  63. package/bundled-references/maggiedash-booking/diagrams/manager-journey.mmd +11 -0
  64. package/bundled-references/maggiedash-booking/diagrams/manager-journey.png +0 -0
  65. package/bundled-references/maggiedash-booking/diagrams/manager-journey.svg +1 -0
  66. package/bundled-references/maggiedash-booking/diagrams/payment-sequence.mmd +20 -0
  67. package/bundled-references/maggiedash-booking/diagrams/payment-sequence.png +0 -0
  68. package/bundled-references/maggiedash-booking/diagrams/payment-sequence.svg +1 -0
  69. package/bundled-references/maggiedash-booking/diagrams/system-context.excalidraw +1 -0
  70. package/bundled-references/maggiedash-booking/diagrams/system-context.mmd +10 -0
  71. package/bundled-references/maggiedash-booking/diagrams/system-context.png +0 -0
  72. package/bundled-references/maggiedash-booking/diagrams/system-context.svg +1 -0
  73. package/bundled-skills/maggie-blog/SKILL.md +12 -0
  74. package/bundled-skills/maggie-blog-bootstrap/SKILL.md +39 -0
  75. package/bundled-skills/maggie-booking/SKILL.md +112 -18
  76. package/bundled-skills/maggie-clone/SKILL.md +13 -0
  77. package/bundled-skills/maggie-deployment/SKILL.md +6 -0
  78. package/bundled-skills/maggie-design/SKILL.md +64 -3
  79. package/bundled-skills/maggie-ops/SKILL.md +12 -0
  80. package/bundled-skills/maggie-seo-geo/SKILL.md +45 -0
  81. package/bundled-skills/maggie-service-booking/SKILL.md +14 -0
  82. package/bundled-tools/clis/maggie_analytics.py +43 -1
  83. package/bundled-tools/clis/maggie_booking.py +161 -26
  84. package/bundled-tools/clis/maggie_browser_audit.py +99 -3
  85. package/bundled-tools/clis/maggie_clone.py +46 -1
  86. package/bundled-tools/clis/maggie_contracts.py +393 -0
  87. package/bundled-tools/clis/maggie_dash.py +22 -6
  88. package/bundled-tools/clis/maggie_design.py +84 -12
  89. package/bundled-tools/clis/maggie_service_booking.py +50 -1
  90. package/bundled-tools/clis/maggie_workflows.py +387 -0
  91. package/bundled-tools/clis/site_audit.py +77 -1
  92. package/bundled-tools/integrations/analytics.md +14 -0
  93. package/bundled-tools/runtime/site_baseline.py +3 -0
  94. package/package.json +1 -1
  95. package/references/browser-inspection.md +21 -0
@@ -11,22 +11,30 @@ for importing a provider's service catalogue. The existing
11
11
  right choice for provider-backed services, prices, durations, booking links,
12
12
  and factual provider validation.
13
13
 
14
+ ## Project memory
15
+
16
+ Before changing a host project, follow the shared
17
+ [`memory-hook.md`](../../references/memory-hook.md) instructions for reading
18
+ relevant project preferences and known pitfalls. After a verified fix or a
19
+ durable host decision, record only the generalizable learning; never promote a
20
+ temporary project detail, secret, or unverified guess into active memory.
21
+
14
22
  ## Contract and safety boundary
15
23
 
16
- Read [`../../docs/maggiedash-booking/README.md`](../../docs/maggiedash-booking/README.md),
17
- [`TASKS.md`](../../docs/maggiedash-booking/TASKS.md), and the task's linked
24
+ Read [`../../bundled-references/maggiedash-booking/README.md`](../../bundled-references/maggiedash-booking/README.md),
25
+ [`TASKS.md`](../../bundled-references/maggiedash-booking/TASKS.md), and the task's linked
18
26
  reference before changing code. MaggieDash owns the manager UI and versioned
19
27
  contracts. The host owns routes, traditional email/password sessions,
20
28
  PostgreSQL connection/transaction lifetime, tenant authorization, provider
21
29
  credentials, payment webhooks, notifications, and deployment. MaggieDash also
22
- ships a tenant-scoped PostgreSQL manager repository for catalogue, availability,
30
+ ships a tenant-scoped PostgreSQL manager repository for catalogue, treatment packages, availability,
23
31
  booking, customer, configuration, schedule, health, audit, hold, and lifecycle
24
32
  persistence; it does not replace host connection ownership or payment/public-
25
33
  checkout adapters.
26
34
 
27
35
  For implementation work, use the leaf board and runbook:
28
- [`EXECUTION-BOARD.json`](../../docs/maggiedash-booking/EXECUTION-BOARD.json)
29
- and [`TASK-RUNBOOK.md`](../../docs/maggiedash-booking/TASK-RUNBOOK.md). Do not
36
+ [`EXECUTION-BOARD.json`](../../bundled-references/maggiedash-booking/EXECUTION-BOARD.json)
37
+ and [`TASK-RUNBOOK.md`](../../bundled-references/maggiedash-booking/TASK-RUNBOOK.md). Do not
30
38
  mark a task passed until its implementation gate, docs update, and evidence
31
39
  record are complete.
32
40
 
@@ -69,7 +77,7 @@ It applies the host-only evidence rule; fixture, test, and local environments
69
77
  cannot satisfy a required operational release artifact.
70
78
 
71
79
  For local CLI regression, the sanitized no-customer fixture is
72
- [`fixtures/maggiedash/booking-runtime.v1.json`](../../fixtures/maggiedash/booking-runtime.v1.json).
80
+ [`fixtures/maggiedash/booking-runtime.v1.json`](../../bundled-contracts/maggiedash/booking-runtime.v1.json).
73
81
 
74
82
  Install the first-party workspace and the host integration through the stable
75
83
  Booking installer:
@@ -93,9 +101,23 @@ Astro host it also adds the compatible `@astrojs/node` SSR adapter and the
93
101
  portable server config; an existing `astro.config.*` and deployment adapter
94
102
  remain host-owned.
95
103
 
104
+ For a new host with an approved database migration, `--ready` combines the two
105
+ explicit setup mutations into one command:
106
+
107
+ ```bash
108
+ maggie booking install --project . --confirm --ready
109
+ ```
110
+
111
+ It installs only missing host packages, generates `BOOKING_TOKEN_SECRET` when
112
+ needed, and applies the installed idempotent Booking schema. It still does not
113
+ create the owner, configure Stripe, send email, enable a scheduler, or deploy.
114
+ Use `--schedule systemd` or `--schedule cron` with `--ready` only to generate a
115
+ reviewable scheduler artifact; enabling it remains an operator action after
116
+ backup, migration, and release evidence checks.
117
+
96
118
  The default installer source is the public MaggieDash `0.2.8` distribution. It
97
- contains the released Astro `hostBootstrap` manifest and 40-route Booking
98
- source. A fresh public-source install, `maggie booking inspect`, and
119
+ contains the released Astro `hostBootstrap` manifest and 47-route Booking
120
+ source, including the tenant-scoped treatment package catalogue. A fresh public-source install, `maggie booking inspect`, and
99
121
  `astro build` are the release evidence; a local-source result alone is not.
100
122
 
101
123
  For a new host with a reviewed `DATABASE_URL`, the explicit one-command
@@ -114,6 +136,21 @@ characters fails closed. External secret stores must provision the same key
114
136
  separately. Bootstrap still does not create the owner, configure Stripe, send
115
137
  email, or deploy.
116
138
 
139
+ Generate the reviewed worker scheduler artifact as part of the same install,
140
+ or after an existing install:
141
+
142
+ ```bash
143
+ maggie booking install --project . --confirm --bootstrap --schedule systemd
144
+ # or, for a host without systemd:
145
+ maggie booking worker-schedule --project . --scheduler cron --confirm
146
+ ```
147
+
148
+ This writes `deploy/maggie-booking-worker.service` plus `.timer`, or a
149
+ reviewable `deploy/maggie-booking-worker.cron`. It does not edit the crontab,
150
+ enable systemd, start a process, or expose secrets. Review the generated
151
+ artifact, set an unprivileged service user, then enable it only after the
152
+ schema, backup/restore, and release evidence gates pass.
153
+
117
154
  Before changing host configuration, run the safe first-run checklist:
118
155
 
119
156
  ```bash
@@ -149,16 +186,34 @@ Validate the tenant-scoped Resend template boundary independently:
149
186
  maggie booking email-templates-contract
150
187
  ```
151
188
 
152
- This freezes the seven supported Booking events, approved `{{variable}}`
189
+ This freezes the ten supported Booking events, approved `{{variable}}`
153
190
  placeholders, owner/admin/manager access, audit and idempotency requirements,
154
191
  and the server-only provider/recipient privacy boundary. It does not connect to
155
192
  Resend, send a message, or expose customer data.
156
193
 
194
+ The selected transactional delivery boundary is Resend for email and Twilio
195
+ for SMS. Validate the host policy before wiring provider adapters:
196
+
197
+ ```bash
198
+ maggie booking-delivery \
199
+ --policy .maggie/booking-delivery-policy.json
200
+ ```
201
+
202
+ The policy requires provider acknowledgement before a booking can display a
203
+ confirmed state, uses a bounded exponential-jitter retry with an idempotency
204
+ key per booking event and channel, and moves exhausted work to a dead-letter
205
+ queue. Replay is an explicit manager action and must be audited. `RESEND_API_KEY`
206
+ and `TWILIO_AUTH_TOKEN` remain server-only host secrets; this gate never sends
207
+ email or SMS.
208
+
157
209
  After the first owner signs in, the Booking Overview includes the same
158
210
  secret-safe readiness path: Stripe connection status, test/live mode, and a
159
- copyable `/api/maggie/booking/webhooks/stripe` URL. It gives the operator the
160
- next secret-store action without accepting or storing Stripe credentials in the
161
- browser or Booking database.
211
+ copyable `/api/maggie/booking/webhooks/stripe` URL. The preferred path is still
212
+ the deployment secret store. For a single-business host, an owner or manager
213
+ may submit both Stripe values over HTTPS from this screen; the server verifies
214
+ them first, stores only authenticated AES-256-GCM ciphertext derived from
215
+ `BOOKING_TOKEN_SECRET`, and never returns the raw values. Deployment
216
+ `STRIPE_SECRET_KEY` takes precedence over dashboard-managed credentials.
162
217
 
163
218
  For an Astro host, framework detection installs missing email/password login,
164
219
  first-owner registration, manager/public Booking routes, PostgreSQL/Stripe
@@ -171,9 +226,11 @@ the UI. Use `--host astro` to make detection explicit;
171
226
  use `--host none` when only the source distribution is wanted. The
172
227
  distribution keeps the content admin at `./_maggie/admin` and Booking source at
173
228
  `./_maggie/booking`. Existing files, including an existing `src/middleware.ts`,
174
- are preserved unless `--force` is explicitly supplied. A conventional Astro
175
- middleware receives the rewrite block automatically; unsupported middleware is
176
- preserved and reported by `maggie booking inspect` until integrated manually.
229
+ are preserved unless `--force` is explicitly supplied. Conventional Astro
230
+ middleware using either `defineMiddleware((context, next) => {})` or a
231
+ destructured context such as `defineMiddleware(({ url, request }, next) => {})`
232
+ receives the rewrite block automatically; unsupported middleware is preserved
233
+ and reported by `maggie booking inspect` until integrated manually.
177
234
  Installation does not apply SQL, create an owner, or enable a payment provider.
178
235
  The standard Booking migration must create
179
236
  `maggiedash_booking_user_roles`; do not move that table into a project-only
@@ -233,18 +290,48 @@ allocation by the same time delta, checks each staff/resource interval, and
233
290
  preserves the original total duration. Single-treatment requests and legacy
234
291
  rows remain compatible. Public DTOs expose only safe segment fields.
235
292
 
293
+ When a tenant has multiple online-bookable locations, the public catalogue must
294
+ return a safe `locations` list and the customer page must let the customer pick
295
+ one. Include the selected `locationId` in availability, waitlist, hold,
296
+ checkout, and reschedule requests. Availability must validate that the
297
+ location belongs to the tenant, is active and online-bookable, use its
298
+ timezone, and filter conflicts by that location. Keep the legacy first
299
+ `locationId` field during migration so older hosts remain compatible; never
300
+ fall back to `location-1` or another fixture ID.
301
+
302
+ After a confirmed package purchase, the public page may carry the opaque
303
+ `packageEntitlementId` into the hold and checkout requests. The server resolves
304
+ the customer from the submitted email, validates tenant ownership, active
305
+ status, expiry, currency, and every selected treatment balance, then locks the
306
+ entitlement and item rows while creating the booking and redemption ledger.
307
+ Public package redemption is all-or-nothing for a multi-treatment selection;
308
+ it confirms a fully covered booking at zero price and does not trust the
309
+ browser to decide the balance.
310
+
236
311
  Every `staff` account must also be linked to a Booking staff profile. The host
237
312
  passes that `staff_id` into the server context, and the PostgreSQL repository
238
313
  filters bookings, calendar, availability, customer summaries, staff/resources,
239
314
  schedule, and lifecycle mutations by that assignment. An unlinked staff
240
315
  session fails closed. This is a data-security rule, not a UI convention.
316
+ The administrator access registry must stay identical to the route-handler
317
+ capabilities: calendar, bookings, customers, waitlist, catalogue, packages,
318
+ staff, resources, schedule, locations, payments, refunds, notifications,
319
+ settings, reports, and audit. If `permissions_json` is absent on a legacy role,
320
+ apply the safe role defaults server-side; never treat a missing object as full
321
+ read access. Explicitly granted staff capabilities must be honored by the
322
+ route handler, while staff mutations remain limited to approved lifecycle
323
+ transitions. Keep the access contract, Astro host, reference host, ORA mirror,
324
+ and CLI validator synchronized whenever a route capability changes.
241
325
  The bootstrap now uses the host's server-side Resend configuration to send
242
326
  single-use invitation and password-reset links; raw tokens are never stored.
243
327
  The Resend worker separately delivers booking notifications. The default
244
328
  worker cycle includes `match-waitlist` and `enqueue-reminders`. The waitlist
245
329
  matcher orders eligible entries by priority/FIFO, requires explicit service and
246
330
  location scope, persists the offered slot, and queues one
247
- `booking.waitlist.available` notification. It never auto-creates or reserves a
331
+ `booking.waitlist.available` notification. Package purchase fulfillment and
332
+ provider-confirmed package refunds also queue the allowlisted
333
+ `package.purchase.confirmed`/`package.purchase.refunded` Resend events linked to
334
+ the package purchase, without appointment manage links. It never auto-creates or reserves a
248
335
  booking. The reminder job queues one `booking.reminder`
249
336
  email for each confirmed booking in the next 24 hours; the existing Resend
250
337
  dispatcher resolves the customer address at delivery time. Reminder queueing
@@ -280,7 +367,9 @@ installed host is:
280
367
  node scripts/maggie-booking-schema.mjs --dry-run
281
368
  node scripts/maggie-booking-schema.mjs --apply --confirm
282
369
  # open /_maggie/register and create the first owner
283
- # add Stripe and Resend secrets through the deployment secret store
370
+ # preferred: add Stripe and Resend secrets through the deployment secret store
371
+ # alternative: owner/manager can enter the Stripe key pair in Booking Overview;
372
+ # the host verifies it and stores only encrypted ciphertext
284
373
  node scripts/maggie-booking-worker.mjs --write --confirm
285
374
  ```
286
375
 
@@ -379,7 +468,7 @@ Follow the task board rather than building a disconnected calendar first:
379
468
  signed duplicate/out-of-order webhooks before enabling capture.
380
469
  7. Run the UI source gate, contract gate, host runtime conformance, browser
381
470
  journeys, and release gate. Record each command in
382
- [`PROGRESS.md`](../../docs/maggiedash-booking/PROGRESS.md).
471
+ [`PROGRESS.md`](../../bundled-references/maggiedash-booking/PROGRESS.md).
383
472
 
384
473
  8. Verify the scheduled worker queues and delivers a reminder once for a
385
474
  confirmed booking inside the 24-hour window. Check the notification
@@ -442,6 +531,11 @@ short-lived while customer-manage tokens are 30-day links. A redirect is never
442
531
  payment proof.
443
532
  Run `npm run booking:customer-flow:test` in MaggieDash before wiring the
444
533
  adapter, and retain real host/runtime/browser evidence as a separate gate.
534
+ If the host already has a legacy `/book` request form, keep it as a fallback
535
+ until the Booking schema is ready; expose the new customer route only after a
536
+ schema-aware readiness check, and preserve any existing treatment hint when
537
+ linking into the new flow. Do not replace a working host booking form with a
538
+ route that can only show an unconfigured Booking error.
445
539
  The manager Booking UI also exposes the tenant-scoped waitlist queue. Managers
446
540
  can filter entries, notify/cancel/reprioritize them, or select a concrete slot
447
541
  and staff/resource allocation to create a real booking transaction linked by
@@ -41,6 +41,19 @@ Each run persists `manifest.json`, `state.json`, and phase outputs under
41
41
  `failed` and must be resumed after the defect is fixed; an incomplete run must
42
42
  not be presented as a successful clone.
43
43
 
44
+ Replay approved interaction states with the same manifest used by
45
+ `maggie browser-audit`:
46
+
47
+ ```bash
48
+ maggie clone interactions --project <project-root> --run-id <stable-run-id> \
49
+ --browse <browse-cli> --interactions .maggie/browser-interactions.json
50
+ ```
51
+
52
+ The adapter replays at desktop, tablet, and mobile viewports and writes a
53
+ redacted `maggie-clone-interaction-state.v1` evidence file. It never stores
54
+ typed values, credentials, or raw provider payloads. A clone is not
55
+ interaction-complete until every approved step passes at all three viewports.
56
+
44
57
  An exported local HTML file is also a valid source, for example:
45
58
 
46
59
  ```text
@@ -414,3 +414,9 @@ both units being enabled in systemd. Data-dependent releases additionally
414
414
  require `rollback.backupId` and `rollback.restoreCommand` in
415
415
  `.maggie/deployment/data-release.json`, because switching code alone does not
416
416
  restore incompatible data.
417
+
418
+ `maggie update --help` is read-only. Help flags must be handled before project
419
+ discovery, install-manifest writes, or file synchronization. For fixture-backed
420
+ browser QA, the host owns the isolated dev server and data source; document a
421
+ second port/process and fixture mode in the host runbook instead of making the
422
+ shared updater or deployment CLI start an unmanaged daemon.
@@ -95,9 +95,20 @@ fallback. Mobile evidence must not assume that `preload="none"` will emit
95
95
  `canplaythrough` without user interaction. Record poster visibility, playback
96
96
  state, console errors, network errors, and a screenshot per viewport.
97
97
 
98
- This contract is provider-neutral. It does not claim that Maggie can generate
99
- video assets; generated-video planning, continuation, safety review, retries,
100
- and cost approval remain separate product/provider work.
98
+ The playback contract is provider-neutral, while the selected generation
99
+ policy is Google Gemini: `gemini-omni-1.1-flash` for the default hero-video
100
+ route and `veo-3.1-generate-preview` for specialized continuation/frame
101
+ control. Validate the policy and job evidence separately:
102
+
103
+ ```bash
104
+ maggie media video-policy \
105
+ --policy contracts/maggie-media/video-generation-policy-v1.json
106
+ maggie media video-job --job .maggie/video-job.json
107
+ ```
108
+
109
+ Generation remains host-owned. The host must supply cost budget, rights and
110
+ moderation evidence, idempotency, object storage, and a redacted provenance
111
+ record before a generated asset is used in a release.
101
112
 
102
113
  ## Automatic memory hook
103
114
 
@@ -182,6 +193,20 @@ unconfirmed writes. Generated copy and media must be marked authored rather
182
193
  than source-observed. Implementation must still capture responsive screenshots
183
194
  and run accessibility/build validation before publication.
184
195
 
196
+ Author jobs are resumable design jobs even though their plan is stored beside
197
+ the author brief at `.maggie/design/author-<id>.json`. Use the same progress
198
+ commands as an in-place job; `status` and `step` resolve both supported job
199
+ locations:
200
+
201
+ ```bash
202
+ maggie design status author-<id> --project .
203
+ maggie design step author-<id> --project . \
204
+ --step inspect-shell --evidence .maggie/evidence/inspect-shell.json
205
+ ```
206
+
207
+ An author plan is not complete until every `requiredSteps` entry has matching
208
+ evidence and the explicit approval step is recorded.
209
+
185
210
  ## Content UI initialization
186
211
 
187
212
  Use content UI initialization when `maggie-blog` or
@@ -496,3 +521,39 @@ Follow the shared [Maggie Decision Loop](../../references/decision-loop.md) for
496
521
  6. Require explicit final confirmation before any mutation or external write.
497
522
 
498
523
  If a decision is not relevant, record it as `skipped` with a reason. Do not silently assume a missing choice, and do not treat an existing output as permission to skip required work.
524
+
525
+ ## Contract checks for dashboards, samples, and progressive enhancement
526
+
527
+ Run these stable evidence checks after implementation:
528
+
529
+ ```bash
530
+ maggie design progressive-check --evidence .maggie/progressive.json
531
+ maggie design css-check --html dist/index.html --css dist/assets/app.css
532
+ maggie design css-cascade-check --evidence .maggie/css-cascade.json
533
+ maggie design dash-init --project . --route /_maggie/admin --confirm
534
+ maggie design dash-validate --plan .maggie/design/dashboard/*/plan.json --evidence .maggie/dashboard-evidence.json
535
+ maggie design sample-init --project . --route /layout-sample --purpose "layout exploration" --confirm
536
+ maggie design sample-validate --plan .maggie/design/sample/*/plan.json --evidence .maggie/sample-evidence.json
537
+ ```
538
+
539
+ The checks cover smallest-region swaps, stable DOM identities, third-party
540
+ requests, stale responsive Tailwind utilities, and unlayered CSS winning over
541
+ utilities. Dashboard plans require operator journeys and desktop/tablet/mobile,
542
+ collapsed-rail, mobile-drawer, and modal evidence. Sample plans require
543
+ noindex, sitemap exclusion, a visible sample banner, placeholders, and a
544
+ finish checklist.
545
+
546
+ For generated or converted pages, run the markup gate before handing the page
547
+ to a host editor:
548
+
549
+ ```bash
550
+ maggie design markup-check --html src/pages/about.astro --require-content-keys
551
+ maggie design style-check --manifest .maggie/style-editing.json
552
+ ```
553
+
554
+ Editable copy uses stable `data-maggie-content-key` values. Never key prices,
555
+ durations, opening times, contact details, entity identifiers, or mixed markup
556
+ without an explicit host contract. Decode HTML entities exactly once; unknown
557
+ or double-escaped entities stop the check. Optional empty attributes such as
558
+ `style=""` must be omitted. Codemods using compiler positions must anchor at
559
+ the opening `<tag` before slicing source text.
@@ -60,6 +60,18 @@ requires HTTP 200, a readable square image, and an engine-supported ICO, PNG,
60
60
  or GIF response. A logo-shaped source filename is only an unverified source
61
61
  candidate; it is never evidence that the public favicon route works.
62
62
 
63
+ For npm 11 installation or package release work, run the safe preflight before
64
+ an install mutation:
65
+
66
+ ```bash
67
+ maggie npm11 --project . --output .maggie/npm11-preflight.json
68
+ ```
69
+
70
+ The gate records the observed Node/npm versions, lockfile policy, lifecycle
71
+ script policy, and an ignore-scripts-first smoke boundary. A project with
72
+ `install`, `preinstall`, or `postinstall` scripts requires an explicit
73
+ maintainer decision; Maggie never runs an untrusted install script implicitly.
74
+
63
75
  If the user does not name a mode, inspect the project and propose the smallest
64
76
  mode that satisfies the request. Do not rebuild the public blog or change its
65
77
  framework just to add Ops.
@@ -104,6 +104,29 @@ The strict flag is for a review window where a crawler request is expected; it
104
104
  fails only when the supplied log contains no sitemap request. Never upload raw
105
105
  logs or include IPs, credentials, or query data in feedback or reports.
106
106
 
107
+ ### GSC readiness release gate
108
+
109
+ GSC readiness is part of the existing analytics release gate, not an implied
110
+ result of having a sitemap. Produce redacted evidence for the property,
111
+ verification, canonical origin, robots, sitemap, read-only authorization,
112
+ query/readback, and production smoke:
113
+
114
+ ```bash
115
+ maggie analytics gsc-readiness \
116
+ --gsc-evidence .maggie/gsc-readiness.json
117
+ maggie analytics release-gate --project . --environment staging \
118
+ --contract .maggie/analytics-contract.json \
119
+ --render-report .maggie/analytics-browser.json \
120
+ --network-report .maggie/analytics-network.json \
121
+ --provider-report .maggie/analytics-provider.json \
122
+ --smoke-report .maggie/analytics-smoke.json \
123
+ --gsc-evidence .maggie/gsc-readiness.json --require-gsc
124
+ ```
125
+
126
+ Use `contracts/maggie-seo/gsc-readiness-v1.schema.json` as the evidence
127
+ boundary. Credentials and mutation scopes remain host-owned; a passing local
128
+ contract is not proof of property ownership or live readback.
129
+
107
130
  ## Freeze and compare a reviewed site
108
131
 
109
132
  ```bash
@@ -381,3 +404,25 @@ backed by a content-change/source-revision event; operational sync, pull,
381
404
  deploy, or `updated_at` timestamps are rejected. The agent-file command emits
382
405
  locale-aware `llms.txt`, `sitemap.md`, and `insights.md` from the same route
383
406
  inventory; non-indexable routes are omitted.
407
+
408
+ For every release, audit third-party privacy origins:
409
+
410
+ ```bash
411
+ maggie seo privacy-check --evidence .maggie/privacy-origin-evidence.json
412
+ ```
413
+
414
+ The site audit also records `primary_navigation_indexability` and flags a
415
+ same-origin page linked from primary navigation when it is `noindex`,
416
+ `nofollow`, or `none`. The privacy check fails in both directions: an embedded
417
+ origin missing from the policy, or a policy origin never observed in rendered
418
+ pages, requires review.
419
+
420
+ Noindex pages are still audited structurally. The crawl reports
421
+ `indexabilityIfIndexed` with title, description, canonical, heading, and
422
+ JSON-LD checks that would fail if the route became indexable. This is
423
+ diagnostic evidence only; it does not change robots directives or sitemap
424
+ membership. Baseline drift recapture requires a reviewer reason and records an
425
+ expiring acknowledgement (`--reason-ttl-days`, default 30 days).
426
+
427
+ Internal-link extraction is DOM-only. Text inside `script`, `style`,
428
+ `noscript`, and comments is never treated as an anchor or link target.
@@ -502,3 +502,17 @@ later sync are marked `archived`, retained for reconciliation, and excluded
502
502
  from active category context and public fact gates. After every sync, run
503
503
  `fact-audit`, `category-context`, the category hash/render/audit sequence, and
504
504
  the aggregate `maggie_release.py` gate.
505
+
506
+ ### Treatment groups
507
+
508
+ Keep one treatment catalogue entry and put length/price choices in its
509
+ `variants` array. Imports emit `treatmentGroup` with variant count, duration
510
+ range, and a from-price summary. Run the gate before rendering service cards:
511
+
512
+ ```bash
513
+ maggie service treatment-group-audit --project .
514
+ ```
515
+
516
+ This prevents a 30/60/90/120-minute treatment from becoming four unrelated
517
+ products and gives catalogue, detail, booking, and pricing surfaces one stable
518
+ identity.
@@ -48,6 +48,33 @@ def load_json(path: Path, label: str) -> tuple[dict | None, list[str]]:
48
48
  return value, []
49
49
 
50
50
 
51
+ def gsc_checks(evidence: dict) -> dict[str, bool]:
52
+ required = {
53
+ "property": isinstance(evidence.get("property"), dict) and bool(evidence["property"].get("siteUrl")),
54
+ "verification": isinstance(evidence.get("verification"), dict) and evidence["verification"].get("passed") is True,
55
+ "canonical": isinstance(evidence.get("canonical"), dict) and evidence["canonical"].get("passed") is True,
56
+ "robots": isinstance(evidence.get("robots"), dict) and evidence["robots"].get("passed") is True,
57
+ "sitemap": isinstance(evidence.get("sitemap"), dict) and evidence["sitemap"].get("passed") is True,
58
+ "authorization": isinstance(evidence.get("authorization"), dict) and evidence["authorization"].get("readOnly") is True and evidence["authorization"].get("authorized") is True,
59
+ "query-readback": isinstance(evidence.get("queryReadback"), dict) and evidence["queryReadback"].get("passed") is True,
60
+ "production-smoke": isinstance(evidence.get("productionSmoke"), dict) and evidence["productionSmoke"].get("passed") is True,
61
+ }
62
+ return required
63
+
64
+
65
+ def gsc_readiness(args: argparse.Namespace) -> int:
66
+ evidence, errors = load_json(Path(args.evidence).resolve(), "gsc evidence")
67
+ checks = gsc_checks(evidence or {})
68
+ failed = [name for name, passed in checks.items() if not passed]
69
+ errors.extend(failed)
70
+ if evidence and evidence.get("schemaVersion") != "maggie-gsc-readiness.v1":
71
+ errors.append("schemaVersion must be maggie-gsc-readiness.v1")
72
+ result = {"schemaVersion": "maggie-gsc-readiness-report.v1", "passed": not errors, "checks": checks, "failedChecks": failed, "errors": errors, "readOnly": True}
73
+ return_code = 0 if result["passed"] else 1
74
+ print(json.dumps(result, indent=2, ensure_ascii=False))
75
+ return return_code
76
+
77
+
51
78
  def release_gate(args: argparse.Namespace) -> int:
52
79
  project = Path(args.project).resolve()
53
80
  checks: dict[str, dict] = {}
@@ -87,6 +114,14 @@ def release_gate(args: argparse.Namespace) -> int:
87
114
  errors.extend(provider_errors)
88
115
  smoke, smoke_errors = load_json(Path(args.smoke_report).resolve(), "smoke-report")
89
116
  errors.extend(smoke_errors)
117
+ if args.gsc_evidence:
118
+ gsc, gsc_errors = load_json(Path(args.gsc_evidence).resolve(), "gsc-evidence")
119
+ errors.extend(gsc_errors)
120
+ checks.update({f"gsc-{name}": {"passed": passed, "evidence": "maggie-gsc-readiness.v1"} for name, passed in gsc_checks(gsc or {}).items()})
121
+ if gsc and gsc.get("schemaVersion") != "maggie-gsc-readiness.v1":
122
+ errors.append("gsc-evidence-schema")
123
+ elif args.require_gsc:
124
+ errors.append("gsc-evidence-required")
90
125
  if browser:
91
126
  check("browser-schema", browser.get("schemaVersion") == "maggie-analytics-browser.v1", "versioned browser evidence", checks)
92
127
  check("browser-render", browser.get("passed") is True and isinstance(browser.get("routes"), list) and bool(browser["routes"]), "routes rendered without a browser failure", checks)
@@ -144,7 +179,7 @@ def release_gate(args: argparse.Namespace) -> int:
144
179
 
145
180
  def main() -> int:
146
181
  parser = argparse.ArgumentParser()
147
- parser.add_argument("command", nargs="?", choices=("release-gate", "traffic-audit"))
182
+ parser.add_argument("command", nargs="?", choices=("release-gate", "traffic-audit", "gsc-readiness"))
148
183
  parser.add_argument("--project", default=".")
149
184
  parser.add_argument("--environment", choices=("development", "staging", "production"), default="staging")
150
185
  parser.add_argument("--env-file", help="optional env file; values are never printed")
@@ -154,8 +189,15 @@ def main() -> int:
154
189
  parser.add_argument("--network-report", help="redacted network evidence for release-gate")
155
190
  parser.add_argument("--provider-report", help="read-only provider evidence for release-gate")
156
191
  parser.add_argument("--smoke-report", help="production smoke evidence for release-gate")
192
+ parser.add_argument("--gsc-evidence", help="versioned GSC readiness evidence for release-gate")
193
+ parser.add_argument("--require-gsc", action="store_true", help="require GSC readiness evidence in release-gate")
157
194
  parser.add_argument("--events", help="redacted JSON array of analytics events for traffic-audit")
158
195
  args = parser.parse_args()
196
+ if args.command == "gsc-readiness":
197
+ if not args.gsc_evidence:
198
+ parser.error("gsc-readiness requires --gsc-evidence")
199
+ args.evidence = args.gsc_evidence
200
+ return gsc_readiness(args)
159
201
  if args.command == "release-gate":
160
202
  required = ("contract", "render_report", "network_report", "provider_report", "smoke_report")
161
203
  if any(not getattr(args, name) for name in required):