@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.
- package/README-zh-TW.md +82 -6
- package/README.md +99 -7
- package/bin/maggie.js +30 -3
- package/bundled-contracts/maggie-clone/interaction-state-v1.schema.json +26 -0
- package/bundled-contracts/maggie-content/provenance-v1.schema.json +20 -0
- package/bundled-contracts/maggie-design/brand-kit-v1.schema.json +18 -0
- package/bundled-contracts/maggie-design/browser-interactions-v1.schema.json +27 -0
- package/bundled-contracts/maggie-design/css-utility-evidence-v1.schema.json +10 -0
- package/bundled-contracts/maggie-design/dashboard-surface-v1.schema.json +11 -0
- package/bundled-contracts/maggie-design/progressive-enhancement-v1.schema.json +12 -0
- package/bundled-contracts/maggie-design/sample-surface-v1.schema.json +13 -0
- package/bundled-contracts/maggie-design/style-editing-v1.schema.json +35 -0
- package/bundled-contracts/maggie-media/image-generation-policy-v1.json +28 -0
- package/bundled-contracts/maggie-media/video-generation-policy-v1.json +40 -0
- package/bundled-contracts/maggie-media/video-job-v1.schema.json +20 -0
- package/bundled-contracts/maggie-media/video-playback-evidence-v1.schema.json +15 -0
- package/bundled-contracts/maggie-ops/npm11-preflight-v1.schema.json +17 -0
- package/bundled-contracts/maggie-scaffold/host-scaffold-v1.schema.json +25 -0
- package/bundled-contracts/maggie-seo/gsc-readiness-v1.schema.json +19 -0
- package/bundled-contracts/maggie-seo/privacy-origin-evidence-v1.schema.json +11 -0
- package/bundled-contracts/maggie-service-booking/delivery-provider-default-v1.json +8 -0
- package/bundled-contracts/maggie-service-booking/delivery-provider-v1.schema.json +16 -0
- package/bundled-contracts/maggiedash/booking-access-v1.json +5 -4
- package/bundled-contracts/maggiedash/booking-customer-surface-v1.json +12 -1
- package/bundled-contracts/maggiedash/booking-email-templates-v1.json +2 -0
- package/bundled-contracts/maggiedash/booking-host-adapter-v1.json +14 -2
- package/bundled-contracts/maggiedash/booking-runtime.v1.json +41 -0
- package/bundled-contracts/maggiedash/browser-session-v1.schema.json +18 -0
- package/bundled-contracts/maggiedash/content-overrides-v1.schema.json +19 -0
- package/bundled-contracts/maggiedash/execution-board.json +526 -26
- package/bundled-contracts/maggiedash/host-capabilities-v1.schema.json +10 -0
- package/bundled-contracts/maggiedash/public-session-cache-v1.schema.json +17 -0
- package/bundled-contracts/maggiedash/site-structure-v1.schema.json +13 -0
- package/bundled-references/browser-inspection.md +21 -0
- package/bundled-references/maggiedash-booking/ARCHITECTURE.md +218 -0
- package/bundled-references/maggiedash-booking/CURRENT-STATE.md +92 -0
- package/bundled-references/maggiedash-booking/DATA-FLOW.md +143 -0
- package/bundled-references/maggiedash-booking/DATA-MODEL.md +367 -0
- package/bundled-references/maggiedash-booking/DECISIONS.md +94 -0
- package/bundled-references/maggiedash-booking/EXECUTION-BOARD.json +2387 -0
- package/bundled-references/maggiedash-booking/HOST-ADAPTER.md +314 -0
- package/bundled-references/maggiedash-booking/ORAWELLNESS-INTEGRATION-AUDIT.md +227 -0
- package/bundled-references/maggiedash-booking/PAYMENT-GATEWAY.md +267 -0
- package/bundled-references/maggiedash-booking/PRD.md +228 -0
- package/bundled-references/maggiedash-booking/PROGRESS.md +2434 -0
- package/bundled-references/maggiedash-booking/QA-TEST-PLAN.md +235 -0
- package/bundled-references/maggiedash-booking/README.md +271 -0
- package/bundled-references/maggiedash-booking/RUNTIME-OPERATIONS.md +152 -0
- package/bundled-references/maggiedash-booking/SECURITY-COMPLIANCE.md +158 -0
- package/bundled-references/maggiedash-booking/SKILLS-AND-CLI.md +542 -0
- package/bundled-references/maggiedash-booking/STRIPE-INTEGRATION.md +129 -0
- package/bundled-references/maggiedash-booking/TASK-RUNBOOK.md +107 -0
- package/bundled-references/maggiedash-booking/TASKS.md +137 -0
- package/bundled-references/maggiedash-booking/USER-JOURNEYS.md +224 -0
- package/bundled-references/maggiedash-booking/diagrams/booking-dfd.excalidraw +1 -0
- package/bundled-references/maggiedash-booking/diagrams/booking-dfd.mmd +16 -0
- package/bundled-references/maggiedash-booking/diagrams/booking-dfd.png +0 -0
- package/bundled-references/maggiedash-booking/diagrams/booking-dfd.svg +1 -0
- package/bundled-references/maggiedash-booking/diagrams/booking-state-machine.mmd +19 -0
- package/bundled-references/maggiedash-booking/diagrams/booking-state-machine.png +0 -0
- package/bundled-references/maggiedash-booking/diagrams/booking-state-machine.svg +1 -0
- package/bundled-references/maggiedash-booking/diagrams/manager-journey.excalidraw +1 -0
- package/bundled-references/maggiedash-booking/diagrams/manager-journey.mmd +11 -0
- package/bundled-references/maggiedash-booking/diagrams/manager-journey.png +0 -0
- package/bundled-references/maggiedash-booking/diagrams/manager-journey.svg +1 -0
- package/bundled-references/maggiedash-booking/diagrams/payment-sequence.mmd +20 -0
- package/bundled-references/maggiedash-booking/diagrams/payment-sequence.png +0 -0
- package/bundled-references/maggiedash-booking/diagrams/payment-sequence.svg +1 -0
- package/bundled-references/maggiedash-booking/diagrams/system-context.excalidraw +1 -0
- package/bundled-references/maggiedash-booking/diagrams/system-context.mmd +10 -0
- package/bundled-references/maggiedash-booking/diagrams/system-context.png +0 -0
- package/bundled-references/maggiedash-booking/diagrams/system-context.svg +1 -0
- package/bundled-skills/maggie-blog/SKILL.md +12 -0
- package/bundled-skills/maggie-blog-bootstrap/SKILL.md +39 -0
- package/bundled-skills/maggie-booking/SKILL.md +112 -18
- package/bundled-skills/maggie-clone/SKILL.md +13 -0
- package/bundled-skills/maggie-deployment/SKILL.md +6 -0
- package/bundled-skills/maggie-design/SKILL.md +64 -3
- package/bundled-skills/maggie-ops/SKILL.md +12 -0
- package/bundled-skills/maggie-seo-geo/SKILL.md +45 -0
- package/bundled-skills/maggie-service-booking/SKILL.md +14 -0
- package/bundled-tools/clis/maggie_analytics.py +43 -1
- package/bundled-tools/clis/maggie_booking.py +161 -26
- package/bundled-tools/clis/maggie_browser_audit.py +99 -3
- package/bundled-tools/clis/maggie_clone.py +46 -1
- package/bundled-tools/clis/maggie_contracts.py +393 -0
- package/bundled-tools/clis/maggie_dash.py +22 -6
- package/bundled-tools/clis/maggie_design.py +84 -12
- package/bundled-tools/clis/maggie_service_booking.py +50 -1
- package/bundled-tools/clis/maggie_workflows.py +387 -0
- package/bundled-tools/clis/site_audit.py +77 -1
- package/bundled-tools/integrations/analytics.md +14 -0
- package/bundled-tools/runtime/site_baseline.py +3 -0
- package/package.json +1 -1
- 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 [`../../
|
|
17
|
-
[`TASKS.md`](../../
|
|
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`](../../
|
|
29
|
-
and [`TASK-RUNBOOK.md`](../../
|
|
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`](../../
|
|
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
|
|
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
|
|
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.
|
|
160
|
-
|
|
161
|
-
|
|
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.
|
|
175
|
-
middleware
|
|
176
|
-
|
|
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.
|
|
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`](../../
|
|
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
|
-
|
|
99
|
-
|
|
100
|
-
and
|
|
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):
|