@topy-ai/maggie 0.7.47 → 0.7.49
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 +2 -2
- package/README.md +76 -15
- package/bin/maggie.js +23 -6
- package/bundled-contracts/google-integrations/capability-report-v2.schema.json +2 -1
- package/bundled-contracts/maggie-content/email-localization-v1.schema.json +89 -0
- package/bundled-contracts/maggie-content/lifecycle-email-v1.schema.json +76 -0
- package/bundled-contracts/maggie-deployment/readiness-v1.schema.json +6 -1
- package/bundled-contracts/maggie-design/palette-roles-v1.schema.json +47 -0
- package/bundled-contracts/maggie-marketplace/template-content-v1.schema.json +103 -0
- package/bundled-contracts/maggie-ops/marketing-run-v1.schema.json +89 -0
- package/bundled-contracts/maggie-ops/notification-catalogue-example-v1.json +941 -0
- package/bundled-contracts/maggie-ops/notification-catalogue-v1.schema.json +273 -0
- package/bundled-contracts/maggie-service-booking/fact-provenance-v1.schema.json +128 -0
- package/bundled-contracts/maggie-service-booking/import-stages-v1.schema.json +191 -0
- package/bundled-contracts/maggiedash/booking-browser-evidence-v1.json +21 -0
- package/bundled-contracts/maggiedash/booking-browser-evidence-v2.json +191 -0
- package/bundled-contracts/maggiedash/booking-email-templates-v1.json +3 -1
- package/bundled-contracts/maggiedash/booking-voucher-lifecycle-v1.json +85 -0
- package/bundled-contracts/maggiedash/execution-board.json +4629 -1553
- package/bundled-contracts/maggiedash/stripe-booking-capabilities-v1.json +1 -0
- package/bundled-marketplace/README.md +17 -0
- package/bundled-marketplace/catalog.json +56 -7
- package/bundled-references/browser-inspection.md +25 -0
- package/bundled-references/google-integrations-runbook.md +54 -0
- package/bundled-references/maggiedash-booking/CURRENT-STATE.md +128 -10
- package/bundled-references/maggiedash-booking/EXECUTION-BOARD.json +4629 -1553
- package/bundled-references/maggiedash-booking/HOST-ADAPTER.md +5 -0
- package/bundled-references/maggiedash-booking/ORAWELLNESS-INTEGRATION-AUDIT.md +64 -21
- package/bundled-references/maggiedash-booking/PRD.md +9 -1
- package/bundled-references/maggiedash-booking/PROGRESS.md +244 -2399
- package/bundled-references/maggiedash-booking/QA-TEST-PLAN.md +37 -6
- package/bundled-references/maggiedash-booking/README.md +23 -6
- package/bundled-references/maggiedash-booking/RUNTIME-OPERATIONS.md +64 -8
- package/bundled-references/maggiedash-booking/SKILLS-AND-CLI.md +11 -2
- package/bundled-references/maggiedash-booking/STRIPE-INTEGRATION.md +66 -2
- package/bundled-references/maggiedash-booking/TASK-RUNBOOK.md +1 -1
- package/bundled-references/maggiedash-booking/TASKS.md +44 -3
- package/bundled-references/maggiedash-booking/VOUCHERS.md +47 -0
- package/bundled-references/provider-adapter-contract.md +33 -0
- package/bundled-skills/maggie-booking/SKILL.md +8 -0
- package/bundled-skills/maggie-clone-to-template/SKILL.md +26 -0
- package/bundled-skills/maggie-content-localization/SKILL.md +17 -1
- package/bundled-skills/maggie-content-localization/references/email-and-lifecycle.md +83 -0
- package/bundled-skills/maggie-deployment/SKILL.md +141 -7
- package/bundled-skills/maggie-deployment/references/vps.md +74 -1
- package/bundled-skills/maggie-design/SKILL.md +154 -0
- package/bundled-skills/maggie-feedback/SKILL.md +67 -1
- package/bundled-skills/maggie-marketplace/SKILL.md +91 -0
- package/bundled-skills/maggie-ops/SKILL.md +37 -0
- package/bundled-skills/maggie-ops/references/notifications-operations.md +154 -0
- package/bundled-skills/maggie-qa-workflow/SKILL.md +41 -1
- package/bundled-skills/maggie-service-booking/SKILL.md +82 -0
- package/bundled-skills/maggie-social-share/SKILL.md +56 -7
- package/bundled-skills/maggie-social-share/references/marketing-run.md +57 -0
- package/bundled-skills/maggie-social-share/references/queue-and-connections.md +152 -0
- package/bundled-skills/maggie-template/SKILL.md +57 -3
- package/bundled-skills/maggie-template/references/template-content-v1.example.json +34 -0
- package/bundled-tools/clis/maggie_booking.py +199 -26
- package/bundled-tools/clis/maggie_booking_vouchers.py +185 -0
- package/bundled-tools/clis/maggie_clone_to_template.py +14 -0
- package/bundled-tools/clis/maggie_deployment.py +307 -18
- package/bundled-tools/clis/maggie_deployment_auth_canary.py +216 -0
- package/bundled-tools/clis/maggie_deployment_collect.py +225 -0
- package/bundled-tools/clis/maggie_deployment_readiness.py +53 -3
- package/bundled-tools/clis/maggie_design.py +17 -0
- package/bundled-tools/clis/maggie_design_lint.py +277 -0
- package/bundled-tools/clis/maggie_design_verify.py +359 -0
- package/bundled-tools/clis/maggie_docs.py +82 -4
- package/bundled-tools/clis/maggie_email_localization.py +382 -0
- package/bundled-tools/clis/maggie_feedback.py +115 -5
- package/bundled-tools/clis/maggie_icon_glyph_check.py +382 -0
- package/bundled-tools/clis/maggie_icon_release_gate.py +28 -1
- package/bundled-tools/clis/maggie_localization.py +5 -0
- package/bundled-tools/clis/maggie_marketing_run.py +272 -0
- package/bundled-tools/clis/maggie_marketplace.py +199 -5
- package/bundled-tools/clis/maggie_notifications.py +528 -0
- package/bundled-tools/clis/maggie_ops.py +87 -0
- package/bundled-tools/clis/maggie_palette.py +280 -0
- package/bundled-tools/clis/maggie_qa_workflow.py +156 -1
- package/bundled-tools/clis/maggie_schedule.py +12 -2
- package/bundled-tools/clis/maggie_service_import.py +520 -0
- package/bundled-tools/clis/maggie_social_queue.py +442 -0
- package/bundled-tools/clis/maggie_social_share.py +46 -9
- package/bundled-tools/clis/maggie_template_package.py +1141 -0
- package/bundled-tools/runtime/google_ads.py +306 -0
- package/bundled-tools/runtime/google_capabilities.py +18 -2
- package/bundled-tools/runtime/google_remediation.py +152 -0
- package/package.json +1 -1
- package/references/browser-inspection.md +25 -0
- package/references/google-integrations-runbook.md +54 -0
- package/references/provider-adapter-contract.md +33 -0
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
name: maggie-feedback
|
|
3
3
|
description: Collect, review, and explicitly submit privacy-safe feedback about a Maggie skill run, workflow result, bug, or feature request.
|
|
4
4
|
metadata:
|
|
5
|
-
version: 1.
|
|
5
|
+
version: 1.2.0
|
|
6
6
|
---
|
|
7
7
|
|
|
8
8
|
# Maggie Feedback
|
|
@@ -70,6 +70,15 @@ with one shared correlation ID instead of losing their relationship:
|
|
|
70
70
|
|
|
71
71
|
maggie feedback batch --project . --batch-file ./feedback-batch.json
|
|
72
72
|
|
|
73
|
+
For long cross-feature reviews, prefer the batch file over repeated `collect`
|
|
74
|
+
calls: JSON strings carry multiline text, backticks, and command names without
|
|
75
|
+
shell escaping. `--batch-file -` reads the same JSON from stdin, so a quoted
|
|
76
|
+
heredoc (`<<'EOF'`) never interpolates command substitutions:
|
|
77
|
+
|
|
78
|
+
maggie feedback batch --project . --batch-file - <<'EOF'
|
|
79
|
+
{"batchId": "review-2026-10", "skill": "maggie-deployment", "items": [...]}
|
|
80
|
+
EOF
|
|
81
|
+
|
|
73
82
|
The batch file contains 1–50 items and may provide shared `skill`, `runId`,
|
|
74
83
|
`phase`, `priority`, and `affectedCli` values. An item can override those
|
|
75
84
|
fields and supplies the normal `type`, `summary`, `expected`, `actual`,
|
|
@@ -118,6 +127,63 @@ Example:
|
|
|
118
127
|
]
|
|
119
128
|
}
|
|
120
129
|
|
|
130
|
+
## Feedback types
|
|
131
|
+
|
|
132
|
+
- `bug`: the skill or CLI did something wrong.
|
|
133
|
+
- `quality`: the result works but falls short (unclear output, weak defaults).
|
|
134
|
+
- `feature`: a missing capability.
|
|
135
|
+
- `improvement`: a concrete proposal to change an existing skill or CLI
|
|
136
|
+
(a new flag, a better default, a guidance section).
|
|
137
|
+
- `general`: anything else.
|
|
138
|
+
|
|
139
|
+
The hosted endpoint accepts `bug`, `feature`, `quality`, and `general`. An
|
|
140
|
+
`improvement` draft keeps its type locally and is submitted as `feature` with
|
|
141
|
+
`subtype: "improvement"`, so maintainers can still filter it.
|
|
142
|
+
|
|
143
|
+
## Draft a batch from a working session
|
|
144
|
+
|
|
145
|
+
After a long session, draft batch items from the commits made since a known
|
|
146
|
+
point instead of writing them by hand:
|
|
147
|
+
|
|
148
|
+
```bash
|
|
149
|
+
maggie feedback session-summary --project . \
|
|
150
|
+
--repo . --since v1.4.0 \
|
|
151
|
+
--batch-id social-session-2026-10 --skill maggie-social-share
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
The helper reads commit subjects only (no diffs, paths, or file contents) and
|
|
155
|
+
redacts secrets and local paths. `fix:` commits become fixed `bug` items with a
|
|
156
|
+
`commit:<sha>` evidence reference; `feat:`, `perf:` and `refactor:` commits
|
|
157
|
+
become `improvement` candidates; other commits are skipped and counted. It also
|
|
158
|
+
adds one placeholder for an open ask. It writes a draft batch file under
|
|
159
|
+
`.maggie/feedback/batches/` and does not create or submit feedback.
|
|
160
|
+
|
|
161
|
+
Review the file: delete items that concern the project rather than a Maggie
|
|
162
|
+
skill or CLI, and replace every `REVIEW:` field (expected, actual, validation).
|
|
163
|
+
`maggie feedback batch` rejects a file that still contains `REVIEW:`
|
|
164
|
+
placeholders. Then continue with `batch`, `batch-review`, and explicit
|
|
165
|
+
`submit` as usual.
|
|
166
|
+
|
|
167
|
+
## Check release and rollout claims before reporting "fixed"
|
|
168
|
+
|
|
169
|
+
A fixed report is only as good as the release state it points to. Two
|
|
170
|
+
read-only checks catch the drift that previous reports had to find by hand:
|
|
171
|
+
|
|
172
|
+
python3 scripts/validate_docs_freshness.py --release-metadata
|
|
173
|
+
maggie docs rollout-status --project .
|
|
174
|
+
|
|
175
|
+
The first (Maggie source repository) fails when `VERSION`, the CLI package
|
|
176
|
+
version, the newest `CHANGELOG.md` heading, and the README current-version text
|
|
177
|
+
disagree, so a published version cannot ship without its release notes. The
|
|
178
|
+
second scans `docs/` for rollout item IDs (default pattern `ABC-12`, override
|
|
179
|
+
with `--id-pattern`) and fails when one document says an item is complete while
|
|
180
|
+
another says it is pending or in progress. When `docs/rollout-status.json`
|
|
181
|
+
(`maggie-rollout-status.v1`: `items[]` with `id`, `status` of `planned`,
|
|
182
|
+
`in_progress`, `blocked`, or `complete`, and `evidence` for complete items)
|
|
183
|
+
exists, it is canonical and every document must agree with it. Mark superseded
|
|
184
|
+
documents with `<!-- documentation-status: historical-snapshot -->` instead of
|
|
185
|
+
leaving contradictory claims current.
|
|
186
|
+
|
|
121
187
|
## Submit explicitly
|
|
122
188
|
|
|
123
189
|
The CLI never submits automatically. After reviewing the draft:
|
|
@@ -52,6 +52,18 @@ maggie tool maggie_marketplace.py apply \
|
|
|
52
52
|
--id medical-spa-landing-30 --project /path/to/astro-project
|
|
53
53
|
```
|
|
54
54
|
|
|
55
|
+
Package-quality commands (read-only unless `--write`/`--record`/`--approve`):
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
maggie tool maggie_marketplace.py audit-package <id> # all package-quality gates, JSON report
|
|
59
|
+
maggie tool maggie_marketplace.py measure-design <id> --write # palette roles + fonts from homepage CSS
|
|
60
|
+
maggie tool maggie_marketplace.py repair-assets <id> --write # list unlisted assets honestly; add file extensions
|
|
61
|
+
maggie tool maggie_marketplace.py identity <id> --display-name "Olive Atelier" \
|
|
62
|
+
--display-description "A light editorial beauty homepage with olive accents."
|
|
63
|
+
maggie tool maggie_marketplace.py image-plan <id> --unit-cost 0.04 --currency USD
|
|
64
|
+
maggie tool maggie_marketplace.py image-review <id> [--approve --reviewer NAME | --flag assets/x.png]
|
|
65
|
+
```
|
|
66
|
+
|
|
55
67
|
The native installer exposes the same operation as
|
|
56
68
|
`maggie marketplace add <template-url> clone <preview-url> --rename <id>`.
|
|
57
69
|
|
|
@@ -95,6 +107,55 @@ validator before it is reported complete. If the validator has changed or the
|
|
|
95
107
|
artifact drifted, the job becomes `STALE` and must be resumed or rebuilt; do
|
|
96
108
|
not treat an old readiness flag as proof of current validity.
|
|
97
109
|
|
|
110
|
+
## Package quality gates
|
|
111
|
+
|
|
112
|
+
`validate` and the completion checkpoint include five package-quality gates.
|
|
113
|
+
`audit-package` runs only these, without the mutating cleanup that `validate`
|
|
114
|
+
performs, so it is safe on any checkout.
|
|
115
|
+
|
|
116
|
+
1. **Screenshots decode and fit a pixel budget.** Every file in
|
|
117
|
+
`screenshots/` must fully decode (PNG chunk CRCs and inflated size, JPEG
|
|
118
|
+
frame/end markers, WebP header; Pillow is used too when installed). A
|
|
119
|
+
corrupt capture shows as glitch noise and is reported as
|
|
120
|
+
`recapture-required`; recapture it with `maggie_clone_to_template.py
|
|
121
|
+
review` — never hand-edit or keep it. The budget is 40 MP per image and
|
|
122
|
+
16383 px per edge, well under sharp's default `limitInputPixels`
|
|
123
|
+
(268,402,689 px) and Pillow's decompression-bomb guard, so consumers never
|
|
124
|
+
need to disable those limits. Ship full-page captures as tiles no taller
|
|
125
|
+
than 4096 px (`desktop-full-01.png`, `desktop-full-02.png`, …) or as a
|
|
126
|
+
compressed WebP preview; keep `desktop.png`/`tablet.png`/`mobile.png` at
|
|
127
|
+
viewport height. `audit-package --record` stores the per-file result in
|
|
128
|
+
`template.json` `screenshotReview`.
|
|
129
|
+
2. **`DESIGN.md` palette is measured, not inherited.** The palette and fonts
|
|
130
|
+
come from the template's own CSS: Tailwind config colours and fonts,
|
|
131
|
+
arbitrary utilities (`bg-[#…]`), the Tailwind neutral scales, body rules,
|
|
132
|
+
inline and stylesheet declarations, and Google Fonts links.
|
|
133
|
+
`measure-design --write` rewrites the `### Reference palette` and
|
|
134
|
+
typography lines, stores `designTokens` (the nine
|
|
135
|
+
`maggie-palette-roles-v1` roles plus fonts and missing font links) in
|
|
136
|
+
`template.json`, and fills empty `styleTags` with measured tags
|
|
137
|
+
(`light-canvas`, `serif-display`, `warm-neutral`, …). Every declared colour
|
|
138
|
+
must exist in the page CSS and Background/Text primary must match the
|
|
139
|
+
measured canvas/text; derived contrast-safe roles are labelled `derived`.
|
|
140
|
+
Check the result against the screenshots before overriding anything.
|
|
141
|
+
3. **Every asset has provenance.** Every image under `assets/` must be listed
|
|
142
|
+
in `generated-asset-manifest.json` with a provider and role. Captured
|
|
143
|
+
source images are listed as `provider: captured-source`, `reuse: false`,
|
|
144
|
+
`replacementRequired: true`; files without a generation record are
|
|
145
|
+
`provider: unrecorded`, `reuse: false`, `provenanceReview: required`. Both
|
|
146
|
+
block publishing. Files without an extension are rejected;
|
|
147
|
+
`repair-assets --write` sniffs the type, renames the file, and rewrites
|
|
148
|
+
`homepage.html` and `image-inventory.json`.
|
|
149
|
+
4. **Neutral display identity.** `template.json` carries a customer-facing
|
|
150
|
+
`displayName` and `displayDescription` that are separate from the ID,
|
|
151
|
+
`name`, and `sourceMetadata`. The name must not repeat a distinctive word
|
|
152
|
+
from the source title, must not be a counter such as `Beauty Studio 20
|
|
153
|
+
001`, and must be unique in the catalogue. Completion derives one from the
|
|
154
|
+
measured design (accent hue, display typeface, industry) when none is
|
|
155
|
+
given; prefer a reviewed, designed name. `list`, `suggest`, and the catalogue
|
|
156
|
+
show `displayName`; source titles never appear in customer-facing pickers.
|
|
157
|
+
5. **Generated images pass a no-text review.** See step 4 below.
|
|
158
|
+
|
|
98
159
|
Each import also creates `tasks.json`. It is the workflow ledger: it stores
|
|
99
160
|
source/output inventories for logos, icons, images, headings, links, buttons,
|
|
100
161
|
visible copy, and Tailwind, plus evidence and status for source analysis,
|
|
@@ -222,6 +283,32 @@ role, provider, date, and prompt in `generated-asset-manifest.json`. Validate
|
|
|
222
283
|
that every PNG/JPEG decodes. Never apply text replacement tools to binary
|
|
223
284
|
assets.
|
|
224
285
|
|
|
286
|
+
Report cost before and after every generation run, and review every output
|
|
287
|
+
for text. A "no text, no labels" prompt is not a guarantee: product bottles,
|
|
288
|
+
signage, and packaging routinely come back with readable words.
|
|
289
|
+
|
|
290
|
+
```bash
|
|
291
|
+
# before generating: planned image count and estimated cost
|
|
292
|
+
maggie tool maggie_marketplace.py image-plan <id> --unit-cost <price-per-image> --currency USD
|
|
293
|
+
# after generating: actual count/cost, contact sheet, and text review
|
|
294
|
+
maggie tool maggie_marketplace.py image-review <id>
|
|
295
|
+
# a person checked image-review/contact-sheet.html and found no text
|
|
296
|
+
maggie tool maggie_marketplace.py image-review <id> --approve --reviewer <name>
|
|
297
|
+
# or record a failure, regenerate that asset, and review again
|
|
298
|
+
maggie tool maggie_marketplace.py image-review <id> --flag assets/maggie-hero.png
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
`image-plan` counts inventory occurrences marked `needs-generation`, pending
|
|
302
|
+
roles, and captured-source assets awaiting replacement. Take the unit cost from
|
|
303
|
+
the provider's current price list; when omitted, the estimate is recorded as
|
|
304
|
+
unknown rather than guessed. `image-review` writes the post-run count and cost,
|
|
305
|
+
`image-review/contact-sheet.html`, and a per-image `textReview` in
|
|
306
|
+
`image-generation-report.json`. When `tesseract` is installed, OCR flags any
|
|
307
|
+
image with readable words; otherwise the review stays `pending-human-review`
|
|
308
|
+
until `--approve`. Completion and `validate` block until the review is
|
|
309
|
+
`passed` and covers every generated asset. These commands make no model or
|
|
310
|
+
paid API calls themselves.
|
|
311
|
+
|
|
225
312
|
Before generating anything, create `image-inventory.json` from the final
|
|
226
313
|
section structure. Include one record for every logo and image occurrence:
|
|
227
314
|
`id`, source occurrence/line, semantic role, composition, dimensions/aspect
|
|
@@ -315,6 +402,10 @@ image references. It also verifies the generated asset roles used by the
|
|
|
315
402
|
sample. A mismatch blocks `apply` and publish until the template is repaired
|
|
316
403
|
or an explicitly approved `--sample` contract is selected.
|
|
317
404
|
|
|
405
|
+
The validator also runs the package quality gates above (screenshot
|
|
406
|
+
integrity and budget, measured palette, asset provenance, neutral display
|
|
407
|
+
identity, generated-image text review).
|
|
408
|
+
|
|
318
409
|
Also parse all JSON and JSON-LD, require exactly one canonical, verify `en-GB`,
|
|
319
410
|
decode every local image, scan for source brand/person/place/phone/social URL
|
|
320
411
|
remnants, confirm no Iconify/platform runtime remains, and inspect desktop,
|
|
@@ -96,10 +96,47 @@ prints these safe identifiers and scopes before any separate provider adapter
|
|
|
96
96
|
is allowed to perform a write. A v1 report is rejected because it cannot prove
|
|
97
97
|
that the browser/session is on the intended Google account and property.
|
|
98
98
|
|
|
99
|
+
When a check fails, add an optional `failure` (`code`, `reason`, `httpStatus`;
|
|
100
|
+
never a token or payload) to the row. The validator maps it to one failed
|
|
101
|
+
prerequisite and one safe next action under `remediation`. For a single error,
|
|
102
|
+
`maggie ops google-diagnose --code SERVICE_DISABLED --http-status 403` prints the
|
|
103
|
+
same mapping.
|
|
104
|
+
|
|
105
|
+
For Google Ads, run the read-only adapter before any keyword research:
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
maggie ops google-ads-preflight --customer-id 123-456-7890 \
|
|
109
|
+
[--login-customer-id 999-888-7777] [--probe-keyword-planner]
|
|
110
|
+
maggie ops google-ads-keyword-ideas --customer-id 123-456-7890 \
|
|
111
|
+
--keyword "day spa" --language 1000 --geo-target 2826 --currency GBP
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
Credentials come from `GOOGLE_ADS_ACCESS_TOKEN` and
|
|
115
|
+
`GOOGLE_ADS_DEVELOPER_TOKEN` (names overridable); values are never printed.
|
|
116
|
+
The adapter only allows `listAccessibleCustomers`, `googleAds:search`, and
|
|
117
|
+
`generateKeywordIdeas`, so it cannot mutate Ads state.
|
|
118
|
+
|
|
99
119
|
The result separates `read`, `report`, `edit`, and `publish` for each
|
|
100
120
|
provider/resource. Write and publish remain `not_tested` until the operator
|
|
101
121
|
explicitly confirms the exact mutation and a successful read-back is captured.
|
|
102
122
|
|
|
123
|
+
## Website notifications
|
|
124
|
+
|
|
125
|
+
For website email, in-app, and SMS operations, follow
|
|
126
|
+
[Website notification operations](references/notifications-operations.md):
|
|
127
|
+
a catalogue with consent, retention, and delivery rules, template drift
|
|
128
|
+
against a paginated provider export, a Resend preflight by variable name
|
|
129
|
+
only, aggregate queue health with operator alerts, and a dry-run retention
|
|
130
|
+
plan. All `maggie ops notifications` commands are offline and read-only, and
|
|
131
|
+
none of them sends a message.
|
|
132
|
+
|
|
133
|
+
```bash
|
|
134
|
+
maggie ops notifications catalogue validate --project . --catalogue docs/notifications/catalogue.json
|
|
135
|
+
maggie ops notifications templates drift --project . --catalogue docs/notifications/catalogue.json --local src/emails --provider-export exports/page-1.json
|
|
136
|
+
maggie ops notifications preflight --project . --env-file .env.production --catalogue docs/notifications/catalogue.json
|
|
137
|
+
maggie ops notifications health --project . --snapshot .maggie/notifications-health.json
|
|
138
|
+
```
|
|
139
|
+
|
|
103
140
|
## Required preflight
|
|
104
141
|
|
|
105
142
|
1. Inspect `.maggie/analysis.json` and `.maggie/bootstrap-state.json`.
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
# Website notification operations
|
|
2
|
+
|
|
3
|
+
A provider-neutral operating contract for website email, in-app, and SMS
|
|
4
|
+
notifications: what each message is, which consent it needs, how templates
|
|
5
|
+
stay in sync with the provider, how delivery is kept durable, how the queue is
|
|
6
|
+
watched, and how notification data expires. Every command below is offline and
|
|
7
|
+
read-only. None of them call a provider API, send a message, or print secret
|
|
8
|
+
values or recipient addresses.
|
|
9
|
+
|
|
10
|
+
## 1. Catalogue every message
|
|
11
|
+
|
|
12
|
+
Keep one machine-readable catalogue in the project (for example
|
|
13
|
+
`docs/notifications/catalogue.json`) using
|
|
14
|
+
`contracts/maggie-ops/notification-catalogue-v1.schema.json`. The packaged
|
|
15
|
+
example `contracts/maggie-ops/notification-catalogue-example-v1.json` covers the
|
|
16
|
+
seven sections a website normally needs:
|
|
17
|
+
|
|
18
|
+
| Section | Typical entries |
|
|
19
|
+
|---|---|
|
|
20
|
+
| `identity-security` | email verification, password reset (often provider-owned), sign-in alert, credential/2FA/passkey change, account deletion |
|
|
21
|
+
| `account` | welcome, onboarding reminder, preference update, saved-item digest |
|
|
22
|
+
| `business` | listing/claim status, verification, team invite/approval, import or sync result, publish/domain readiness |
|
|
23
|
+
| `billing` | checkout/subscription active, payment failed, receipt (often provider-owned), plan change, cancellation, trial ending |
|
|
24
|
+
| `support` | contact/waitlist receipt, team copy of a contact, case reply/closure, feedback request |
|
|
25
|
+
| `marketing` | opt-in confirmation, newsletter welcome, content digest, recommendation, gift/voucher interest follow-up, merchant lead digest, re-engagement |
|
|
26
|
+
| `deliverability-ops` | bounce/complaint, suppression, worker failure, dead-letter growth, template drift, sender-domain health, queue health |
|
|
27
|
+
|
|
28
|
+
Each entry records trigger, audience, category (`transactional`, `support`,
|
|
29
|
+
`marketing`), consent boundary, locales and markets, variables, CTA route,
|
|
30
|
+
idempotency-key template, retention days, provider, channels, delivery mode
|
|
31
|
+
(`outbox`, `direct`, `provider`), queue, and status (`implemented`,
|
|
32
|
+
`provider-owned`, `reserved`, `missing`). The status column turns the
|
|
33
|
+
catalogue into a planning asset: `missing` lists what the site still lacks.
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
maggie ops notifications catalogue validate --project . --catalogue docs/notifications/catalogue.json
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
The validator enforces the cross-field rules a schema cannot:
|
|
40
|
+
|
|
41
|
+
- Marketing messages require `consent: opt-in-required`, `unsubscribe: true`
|
|
42
|
+
(preference-centre and unsubscribe links), and the `marketing` queue.
|
|
43
|
+
- `deliverability-ops` alerts use the `operations` queue. An alert about a
|
|
44
|
+
failing provider or queue must not travel through that same queue.
|
|
45
|
+
- External-recipient lead email (`lead: true`: contact, waitlist, gift or
|
|
46
|
+
voucher interest) must use durable `outbox` delivery. A direct send that
|
|
47
|
+
only logs a failure can silently lose a business lead.
|
|
48
|
+
- CTA routes are site paths or `https://` URLs with a fixed host.
|
|
49
|
+
|
|
50
|
+
## 2. Durable delivery for lead email
|
|
51
|
+
|
|
52
|
+
Contact, waitlist, and interest messages are acquisition signals. Route them
|
|
53
|
+
through the same outbox as transactional mail: an idempotency key per
|
|
54
|
+
submission, lease-based claiming, bounded retries, a dead-letter state with
|
|
55
|
+
recorded-reason replay, and provider webhook reconciliation. The visitor's
|
|
56
|
+
request succeeds once the outbox row is committed; delivery failure is an
|
|
57
|
+
operations alert, not a visitor-facing error.
|
|
58
|
+
|
|
59
|
+
## 3. Template lifecycle and drift
|
|
60
|
+
|
|
61
|
+
Template work moves through these stages, each producing reviewable evidence:
|
|
62
|
+
|
|
63
|
+
1. **Discover/scaffold**: derive the template matrix (alias × locale) from the
|
|
64
|
+
catalogue's `implemented` email entries.
|
|
65
|
+
2. **Preview**: render HTML and plain text from fixtures only, never live
|
|
66
|
+
customer data.
|
|
67
|
+
3. **Lint**: every placeholder is a declared variable; CTA routes resolve.
|
|
68
|
+
4. **Localize**: every catalogue locale exists in HTML and plain text, with
|
|
69
|
+
the same variables (see `maggie-content-localization`).
|
|
70
|
+
5. **Approve**: record who approved which template version.
|
|
71
|
+
6. **Sync dry run**: compute the provider diff without writing.
|
|
72
|
+
7. **Publish**: apply the reviewed diff with an explicit confirmation.
|
|
73
|
+
8. **Rollback**: keep the previous provider version ID to restore.
|
|
74
|
+
9. **Verify**: re-run drift; any real send uses a provider test mode or an
|
|
75
|
+
allow-listed internal recipient, behind an explicit confirmation.
|
|
76
|
+
|
|
77
|
+
Before every deploy, compare the catalogue, local templates, and a provider
|
|
78
|
+
export. Export **every** page of the provider's template list to JSON first
|
|
79
|
+
(list endpoints paginate; a single call with a page limit can miss templates):
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
maggie ops notifications templates drift --project . \
|
|
83
|
+
--catalogue docs/notifications/catalogue.json \
|
|
84
|
+
--local src/emails/templates \
|
|
85
|
+
--provider-export exports/templates-page-1.json \
|
|
86
|
+
--provider-export exports/templates-page-2.json
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
`--local` accepts a directory of `<alias>.<locale>.<ext>` files (placeholders
|
|
90
|
+
`{{ name }}` are extracted) or a `maggie-notification-templates.v1` manifest.
|
|
91
|
+
The report lists missing local/provider templates, extra provider or local
|
|
92
|
+
aliases, locale gaps, undeclared or unused variables, and local/provider
|
|
93
|
+
version drift. It exits non-zero on drift, and when the last export page still
|
|
94
|
+
reports `has_more: true`. A runtime fallback to locally rendered email protects
|
|
95
|
+
delivery but hides drift, so treat drift as a deploy blocker.
|
|
96
|
+
|
|
97
|
+
## 4. Provider preflight (Resend)
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
maggie ops notifications preflight --project . --env-file .env.production \
|
|
101
|
+
--catalogue docs/notifications/catalogue.json
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
Checks, by variable name only: API key, sender (`RESEND_EMAIL`, `RESEND_FROM`,
|
|
105
|
+
or `RESEND_SENDER`), worker secret, support recipients, webhook secret, and
|
|
106
|
+
the template map. Template IDs are not printed. Only the map's alias keys are
|
|
107
|
+
compared with implemented Resend catalogue entries. Add project-specific names
|
|
108
|
+
with `--require NAME`. Presence is not proof of delivery: after deploy, the
|
|
109
|
+
release still needs sender-domain verification, webhook reachability, timer
|
|
110
|
+
health, and an authenticated synthetic delivery recorded as redacted evidence.
|
|
111
|
+
|
|
112
|
+
## 5. Queue health and alerts
|
|
113
|
+
|
|
114
|
+
Have the host worker or a read-only SQL job write an aggregate snapshot
|
|
115
|
+
(`maggie-notification-queue-snapshot.v1`) with counts (`pending`,
|
|
116
|
+
`processing`, `deadLetter`, `awaitingWebhook`), `oldestPendingAt`,
|
|
117
|
+
`expiredLeases`, `lastWebhookAt`, `lastSuccessfulRunAt`, optional `rates`
|
|
118
|
+
(`bounce`, `complaint`), and `senderDomainVerified`. Snapshots must not contain
|
|
119
|
+
addresses; the check rejects them if they do.
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
maggie ops notifications health --project . --snapshot .maggie/notifications-health.json \
|
|
123
|
+
--max-oldest-pending-minutes 30 --max-dead-letter 0
|
|
124
|
+
maggie ops notifications alerts
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
`health` exits non-zero when any threshold is exceeded, so it can run from a
|
|
128
|
+
systemd timer or CI after the worker. A timer can be active while the worker
|
|
129
|
+
never succeeds, so `lastSuccessfulRunAt` is required. `alerts` prints the
|
|
130
|
+
operator alert templates (severity, owner, recovery action, escalation). Send
|
|
131
|
+
alerts through an operations channel that is independent of the notification
|
|
132
|
+
queue and provider being monitored.
|
|
133
|
+
|
|
134
|
+
## 6. Privacy, retention, and suppression
|
|
135
|
+
|
|
136
|
+
The catalogue's `retention` block sets days for `webhook-payload`,
|
|
137
|
+
`delivery-record`, `rendered-snapshot`, and `template-variables`. Store
|
|
138
|
+
minimized webhook fields (event type, provider message ID, status, time), not
|
|
139
|
+
the full raw payload. Keep suppression entries as a hashed address with
|
|
140
|
+
reason and time. Recovery from suppression (for example, a fixed mailbox)
|
|
141
|
+
needs an explicit operator action with a recorded reason.
|
|
142
|
+
|
|
143
|
+
Plan purges from aggregate counts only:
|
|
144
|
+
|
|
145
|
+
```bash
|
|
146
|
+
maggie ops notifications retention plan --project . \
|
|
147
|
+
--catalogue docs/notifications/catalogue.json \
|
|
148
|
+
--inventory .maggie/notifications-inventory.json
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
The plan is always a dry run. Rows tied to an open support case or legal hold
|
|
152
|
+
are reported as held. Apply purges through the host's reviewed job or
|
|
153
|
+
migration, and handle account deletion by purging that user's delivery
|
|
154
|
+
records and snapshots and keeping only the hashed suppression entry.
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
name: maggie-qa-workflow
|
|
3
3
|
description: Run scenario-based browser QA with explicit evidence, fix/retest lifecycle, and release-gate decisions for web projects.
|
|
4
4
|
metadata:
|
|
5
|
-
version: 1.
|
|
5
|
+
version: 1.3.0
|
|
6
6
|
---
|
|
7
7
|
|
|
8
8
|
# Maggie QA Workflow
|
|
@@ -74,6 +74,46 @@ the host browser adapter. The adapter owns console, network, authentication,
|
|
|
74
74
|
URL, viewport, and screenshot capture; this skill stores only a relative path,
|
|
75
75
|
URL reference, and hash when a local file exists.
|
|
76
76
|
|
|
77
|
+
## Protect production data
|
|
78
|
+
|
|
79
|
+
Declare which API the build under test talks to, and mark scenarios that
|
|
80
|
+
write data with `"mutates": true` in the scenario manifest:
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
maggie qa start --project . --run-id local-qa-002 \
|
|
84
|
+
--environment local --base-url http://localhost:4321 \
|
|
85
|
+
--api-base https://api.example.com \
|
|
86
|
+
--production-api https://api.example.com
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
When the API base is a production API, mutating scenarios start as `blocked`
|
|
90
|
+
and `record` refuses a pass or fail result for them. Run those scenarios
|
|
91
|
+
against a non-production API, or start a run with `--allow-production-writes`
|
|
92
|
+
only after the user explicitly consents and a restore path exists. Overriding
|
|
93
|
+
`window.fetch` from the page does not stop a bundled API client from sending
|
|
94
|
+
requests; use network-layer interception as described in the
|
|
95
|
+
[browser inspection contract](../../references/browser-inspection.md).
|
|
96
|
+
|
|
97
|
+
## Check CORS for every method the client uses
|
|
98
|
+
|
|
99
|
+
Before a release that adds or changes API calls from a browser or webview,
|
|
100
|
+
preflight every HTTP method the client sends through the public edge, not only
|
|
101
|
+
the origin server:
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
maggie qa cors-preflight --project . \
|
|
105
|
+
--url https://api.example.com/v1/setup \
|
|
106
|
+
--origin https://app.example.com \
|
|
107
|
+
--method GET,POST,PUT,PATCH,DELETE \
|
|
108
|
+
--request-header content-type,authorization \
|
|
109
|
+
--output .maggie/qa-runs/cors-preflight.json
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
The command sends only `OPTIONS` requests and fails when a method, origin, or
|
|
113
|
+
request header is not allowed. A method missing from the edge allow-list
|
|
114
|
+
fails in the browser with a generic network error (Safari: "Load failed") and
|
|
115
|
+
leaves no request in server logs, so it is easy to misdiagnose.
|
|
116
|
+
|
|
77
117
|
## Assert the requirement at runtime
|
|
78
118
|
|
|
79
119
|
Do not use a source class, edited markup fragment, or implementation detail as
|
|
@@ -231,6 +231,65 @@ The contract is documented in
|
|
|
231
231
|
It is provider-neutral and does not accept credentials, provider response
|
|
232
232
|
bodies, or arbitrary filesystem paths in the poll reference.
|
|
233
233
|
|
|
234
|
+
### Long-running import stages, readiness, and fact provenance
|
|
235
|
+
|
|
236
|
+
Inside the `import` workflow, a provider import runs four stages: `source`,
|
|
237
|
+
then `enrichment` and `research` in parallel, then `verification`. Validate a
|
|
238
|
+
redacted snapshot with:
|
|
239
|
+
|
|
240
|
+
```bash
|
|
241
|
+
maggie service import-stages-validate --project . \
|
|
242
|
+
--manifest .maggie/booking/import-stages.json --output docs/import-stages.json
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
The `maggie-service-import-stages.v1` contract
|
|
246
|
+
(`contracts/maggie-service-booking/import-stages-v1.schema.json`) requires a
|
|
247
|
+
stage key per stage prefixed with the import ID and reused on retry, bounded
|
|
248
|
+
attempts, `{done, total}` progress (a succeeded stage is complete), and a
|
|
249
|
+
`heartbeatAt` for running stages. A running stage without a heartbeat for more
|
|
250
|
+
than `staleAfterSeconds` makes the import `stale` with an explicit
|
|
251
|
+
`nextAction`. Parallel stages may complete in any order, but a stage may not
|
|
252
|
+
start before its dependencies finish, and a downstream result built from a
|
|
253
|
+
superseded `source.resultRevision` must be marked `resultDiscarded` instead of
|
|
254
|
+
applied. Cancellation must reach every stage; results completed after
|
|
255
|
+
`cancellation.requestedAt` are discarded. The declared import state must match
|
|
256
|
+
the state derived from its stages (`partial` when retries are exhausted after
|
|
257
|
+
some stages succeeded).
|
|
258
|
+
|
|
259
|
+
Before queuing a long-running provider job, run the worker readiness preflight
|
|
260
|
+
on the worker host. It fails — and the job must not be queued — when a Python
|
|
261
|
+
module is not importable, a browser or matching WebDriver is missing, a crawler
|
|
262
|
+
setting is absent (checked by environment variable name; values are never
|
|
263
|
+
printed), the runtime is not UTF-8, or a country label cannot be normalized to
|
|
264
|
+
ISO 3166 (locale display names and mis-decoded text such as `Königreich` are
|
|
265
|
+
repaired first). A rate-limit probe is a single HEAD request and runs only when
|
|
266
|
+
requested:
|
|
267
|
+
|
|
268
|
+
```bash
|
|
269
|
+
maggie service import-readiness --project . --python-module selenium \
|
|
270
|
+
--browser --webdriver --env MAPS_CRAWLER_KEY --country "United Kingdom" \
|
|
271
|
+
--output docs/import-readiness.json
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
Imported business facts keep field-level provenance in
|
|
275
|
+
`maggie-service-fact-provenance.v1`
|
|
276
|
+
(`contracts/maggie-service-booking/fact-provenance-v1.schema.json`). A
|
|
277
|
+
user-entered value is authoritative and always wins; provider values carry a
|
|
278
|
+
source, confidence, and reference. Providers that agree corroborate a value;
|
|
279
|
+
providers that disagree above `minConfidence` produce a `needs-review` conflict
|
|
280
|
+
with the policy's proposed choice (`fieldPrecedence` can, for example, prefer
|
|
281
|
+
the website for `websiteUrl`). A provider error is recorded under
|
|
282
|
+
`unavailableSources` and never blocks other providers or fields:
|
|
283
|
+
|
|
284
|
+
```bash
|
|
285
|
+
maggie service fact-provenance --project . \
|
|
286
|
+
--facts .maggie/booking/fact-provenance.json --output docs/fact-merge.json
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
The command exits 1 while conflicts need review; the host review UI reads the
|
|
290
|
+
`maggie-service-fact-merge.v1` artifact and records the reviewer's choice as a
|
|
291
|
+
user-entered value.
|
|
292
|
+
|
|
234
293
|
`convert-page` imports a normal page as a draft service without inventing
|
|
235
294
|
booking facts. `match-pages` reads filesystem pages plus `docs/pages.json` and
|
|
236
295
|
`docs/page-content.json`, writes candidate evidence to both `.maggie/booking`
|
|
@@ -427,6 +486,29 @@ FAQ helper from the first category implementation; it is a known gap and must
|
|
|
427
486
|
remain marked incomplete until each FAQ record is independently AI-authored and
|
|
428
487
|
reviewed.
|
|
429
488
|
|
|
489
|
+
## Payments: Stripe live setup and gift vouchers
|
|
490
|
+
|
|
491
|
+
Service pages often lead to first-party payments. When the host takes money
|
|
492
|
+
through MaggieDash Booking (rather than the external provider), follow the
|
|
493
|
+
read-only live setup runbook in `docs/maggiedash-booking/STRIPE-INTEGRATION.md`:
|
|
494
|
+
|
|
495
|
+
- verify live state with list/retrieve (`GET`) calls only; never use a create
|
|
496
|
+
call as a probe — a probe expected to fail can create a real live object;
|
|
497
|
+
- the owner installs webhook and Connect event-destination signing secrets
|
|
498
|
+
with a no-echo command (`read -rs … | <secret store>`); the agent never sees
|
|
499
|
+
them;
|
|
500
|
+
- thin-event destination signing secrets cannot be retrieved via the API;
|
|
501
|
+
roll them in the Dashboard if they were not captured;
|
|
502
|
+
- the Stripe Dashboard may be unusable under browser automation, so hand
|
|
503
|
+
Dashboard-only steps to the owner and confirm them with read-only calls.
|
|
504
|
+
|
|
505
|
+
Gift vouchers (online and at the till, partial redemption, undo, void, expiry,
|
|
506
|
+
refunds, buyer/recipient emails, merchant ledger) follow the host-owned
|
|
507
|
+
`contracts/maggiedash/booking-voucher-lifecycle-v1.json` contract described in
|
|
508
|
+
`docs/maggiedash-booking/VOUCHERS.md`. Do not invent a separate voucher model;
|
|
509
|
+
replay the host's sanitized ledger with
|
|
510
|
+
`maggie booking voucher-contract --ledger FIXTURE`.
|
|
511
|
+
|
|
430
512
|
## Gates
|
|
431
513
|
|
|
432
514
|
The workflow stops when any gate fails:
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
name: maggie-social-share
|
|
3
3
|
description: Turn approved AI CMO articles and content assets into platform-native social drafts, scheduled posts, and measured distribution. Use for Social Share planning, LinkedIn/Facebook copy, CTA mapping, calendars, approvals, publish retries, or social performance readback.
|
|
4
4
|
metadata:
|
|
5
|
-
version: 1.
|
|
5
|
+
version: 1.1.0
|
|
6
6
|
---
|
|
7
7
|
|
|
8
8
|
# Maggie Social Share
|
|
@@ -30,6 +30,33 @@ maggie tool maggie_social_share.py validate .maggie/social-share-plan.json
|
|
|
30
30
|
The CLI does not generate copy or publish. It validates identity, canonical
|
|
31
31
|
URL, channel limits, UTM links, approval state, and provider post state.
|
|
32
32
|
|
|
33
|
+
Before connecting providers or scheduling, check the adapter, connection,
|
|
34
|
+
campaign, and queue contracts (shapes and rules in
|
|
35
|
+
[queue and connections](references/queue-and-connections.md)):
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
maggie tool maggie_social_share.py adapters .maggie/social-adapters.json
|
|
39
|
+
maggie tool maggie_social_share.py connections .maggie/social-connections.json
|
|
40
|
+
maggie tool maggie_social_share.py campaigns .maggie/social-campaigns.json
|
|
41
|
+
maggie tool maggie_social_share.py queue .maggie/social-queue.json --slots 14
|
|
42
|
+
maggie tool maggie_social_share.py reconcile .maggie/social-attempts.json
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
A publishing adapter also declares limits, media rules, pending behaviour,
|
|
46
|
+
retry classes (a timeout is an unknown outcome, never retryable), idempotency,
|
|
47
|
+
and readback. `reconcile` turns the attempt log plus provider readback into
|
|
48
|
+
adopt / await / retry-with-the-same-key / fail decisions, so a
|
|
49
|
+
timeout-after-success never creates a duplicate post.
|
|
50
|
+
|
|
51
|
+
When social work is part of a wider campaign, record it in a
|
|
52
|
+
[marketing run](references/marketing-run.md) with named schedule layers
|
|
53
|
+
(infrastructure, content calendar, campaign flight, measurement window) and,
|
|
54
|
+
for regulated content, a review that gates only external publication:
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
maggie tool maggie_marketing_run.py validate .maggie/marketing-runs/<runId>.json
|
|
58
|
+
```
|
|
59
|
+
|
|
33
60
|
1. Select an approved or explicitly shareable source article/content asset.
|
|
34
61
|
2. Read Project Context and the selected social tone/template.
|
|
35
62
|
3. Extract one clear content atom: insight, statistic, process, story, or
|
|
@@ -37,10 +64,14 @@ URL, channel limits, UTM links, approval state, and provider post state.
|
|
|
37
64
|
4. Create platform-native variants with the platform's current limits and a
|
|
38
65
|
clear CTA. Preserve the source canonical URL and apply the configured UTM
|
|
39
66
|
policy.
|
|
40
|
-
5. Store drafts as
|
|
41
|
-
|
|
67
|
+
5. Store drafts as queue items with source ID, platform, version, approval,
|
|
68
|
+
optional `not_before`, and local/remote status. Posting hours are slots;
|
|
69
|
+
do not persist a fixed `scheduled_at` per post (it goes stale and strands
|
|
70
|
+
overdue posts). Campaign ideas stay in the idea stage until written, and a
|
|
71
|
+
campaign starts only through the Start gate.
|
|
42
72
|
6. Publish only after the required approval and entitlement checks. Record the
|
|
43
|
-
publication attempt and provider ID;
|
|
73
|
+
publication attempt and provider ID; reconcile unknown outcomes against
|
|
74
|
+
readback and retry only with the original idempotency key.
|
|
44
75
|
7. Read back clicks, engagement, assisted conversions, and failures separately
|
|
45
76
|
from article SEO/GEO metrics.
|
|
46
77
|
|
|
@@ -48,12 +79,30 @@ URL, channel limits, UTM links, approval state, and provider post state.
|
|
|
48
79
|
|
|
49
80
|
```text
|
|
50
81
|
source_content_id, canonical_url, platform, format, hook, body, cta,
|
|
51
|
-
hashtags_or_mentions,
|
|
82
|
+
hashtags_or_mentions, not_before, queue_position, campaign_id, approval_state,
|
|
83
|
+
tracking_url
|
|
52
84
|
```
|
|
53
85
|
|
|
86
|
+
`not_before` is optional and only a lower bound; the slot planner assigns the
|
|
87
|
+
actual publish slot.
|
|
88
|
+
|
|
54
89
|
Start with LinkedIn and Facebook adapters. Add other platforms only when the
|
|
55
|
-
adapter can declare limits, auth scope, media requirements,
|
|
56
|
-
delete/republish behavior.
|
|
90
|
+
adapter can declare limits, one canonical auth scope set, media requirements,
|
|
91
|
+
idempotency, and delete/republish behavior.
|
|
92
|
+
|
|
93
|
+
## Connections
|
|
94
|
+
|
|
95
|
+
- Every connect path (dashboard, mobile, CLI) requests the adapter's canonical
|
|
96
|
+
scope set. LinkedIn revokes a member's earlier tokens when a sign-in asks
|
|
97
|
+
for a different set; a shared OAuth client used by other products can do
|
|
98
|
+
the same. `adapters` fails on scope drift and warns on shared clients.
|
|
99
|
+
- A connection whose token the provider revoked, or that a serving host cannot
|
|
100
|
+
decrypt, shows **Reconnect** before anything is scheduled on it. Run the
|
|
101
|
+
decrypt check on every host that serves social routes.
|
|
102
|
+
- Provider avatar URLs are signed and expire; cache the bytes or refresh on
|
|
103
|
+
readback.
|
|
104
|
+
- Keep model structured-output enums small and validate large vocabularies
|
|
105
|
+
server-side; see [provider adapter contract](../../references/provider-adapter-contract.md#structured-model-output).
|
|
57
106
|
|
|
58
107
|
## Safety and commercial boundary
|
|
59
108
|
|