Lacuna/Labs
polish-listing-for-google
light purple
#289 / 601

NAME

polish-listing-for-google — cloud reasoning rewrites the description for Google Shopping's search-results audience (vs the maker-storefront audience of Etsy / eBay). Opt-in. Operator approves the draft before sync. Atlas-grounded — preserves the operator's voice. Lives under scheme/carts/google/manifest.js.

SYNOPSIS

id polish-listing-for-google tier light-purple section §9. Light purple — cloud reasoning (51 baseline, 86 post-matrix) trigger operator-commanded tools sakura/relay (cloud-reason), merchant_center/sync source new

DESCRIPTION

cloud reasoning writes or reasons over your real data. The 'sound like you, but cleaner' tier. Atlas-pair-trained on the operator's own voice.

cloud reasoning rewrites the description for Google Shopping's search-results audience (vs the maker-storefront audience of Etsy / eBay). Opt-in. Operator approves the draft before sync. Atlas-grounded — preserves the operator's voice. Lives under scheme/carts/google/manifest.js.

MECHANISM

PREfetchGUARDtier: light-purpleACTperformRESULTrenderON-ERRretry / esc
;;~ title    "Polish · listing for Google Shopping (Sonnet)"
;;~ author   "lacuna"
;;~ version  1
;;~ mode     automation
;;~ flavor   purple
;;~ id       polish-listing-for-google
;;~ touches  (google-merchant)
;;~ summary  "Operator-commanded. Sonnet rewrites the listing's description specifically for Google Shopping's audience — search-results-page reading rather than maker's-storefront. OPT-IN, not default. Preserves the operator's voice (Atlas-grounded). Light-purple tier — Magic+."

;; Light-purple polish cart. The other five Google-tier carts are pink
;; (Sakura local) for the field mapping + sequencing; THIS one calls
;; Sonnet for the rewrite because the audience is fundamentally
;; different from Etsy / eBay (search-results-page reader, not a
;; storefront browser) and the rewrite quality matters.
;;
;; Opt-in: never fires on event. The operator picks it from the
;; analysis surface or asks Sakura ("polish this for Google").
;; The rewrite is shown to the operator for approval before any push.

(cart 'polish-listing-for-google
  '((author    . "lacuna")
    (version   . 1)
    (touches   . (google-merchant))
    (read-only . #f)))

;; ── start ──────────────────────────────────────────────────────
;; ctx carries 'listing-id. Fetch the listing first; we need the
;; current title + description as the seed for the rewrite.
(define (start ctx)
  (let ((id (ctx-get 'listing-id ctx)))
    (if (null? id)
        (escalate 'missing-listing-id null)
        (next 'fetch ctx))))

(define (fetch ctx)
  (let ((id (ctx-get 'listing-id ctx)))
    ;; Platform-agnostic listing fetch — the dispatcher routes to the
    ;; right origin platform based on the listing's id prefix.
    (act 'listing/fetch (list id) 'check-listing)))

(define (check-listing ctx)
  (let ((listing (ctx-result ctx)))
    (cond
      ((null? listing)             (escalate 'listing-not-found null))
      ((listing-is-draft? listing) (escalate 'drafts-do-not-sync null))
      (else (next 'rewrite (ctx-set 'listing listing ctx))))))

;; ── rewrite — the Sonnet hop ──────────────────────────────────
;; sakura/relay routes to Sonnet (per the orchestration grammar in
;; AUTOMATIONS-CANONICAL.md §9). The audience prompt is "Google
;; Shopping search results"; the operator's Atlas-grounded voice is
;; pulled in as a system note so the rewrite preserves the voice.
(define (rewrite ctx)
  (let ((listing (ctx-get 'listing ctx)))
    (sakura/relay 'sonnet 'polish-google
                  (list (listing-title       listing)
                        (listing-description listing)
                        (listing-category    listing))
                  'check-rewrite)))

(define (check-rewrite ctx)
  (let ((draft (ctx-result ctx)))
    (cond
      ((null? draft) (escalate 'rewrite-failed null))
      (else
       ;; Show the operator the proposed rewrite before pushing. The
       ;; surface owns the approval UI; the cart waits for the operator
       ;; to commit or cancel.
       (next 'await-approval (ctx-set 'draft draft ctx))))))

;; ── await-approval — surface waits for operator ───────────────
;; The driver pauses here; the surface emits an "approve / edit /
;; cancel" pill. On approve, ctx is updated with 'approved=#t and the
;; driver re-runs us — we move to push. On cancel the cart ends without
;; touching Google.
(define (await-approval ctx)
  (cond
    ((eq? (ctx-get 'approved ctx) #t) (next 'push ctx))
    ((eq? (ctx-get 'cancelled ctx) #t) (done))
    (else (sakura/say "Tap approve to push the polished version to Google.")
          (done))))

;; ── push — the only side-effecting state ──────────────────────
;; Build the polished listing dict (the original + the rewritten
;; description) and call merchant_center/sync.
(define (push ctx)
  (let ((listing (listing-with-description
                   (ctx-get 'listing ctx)
                   (ctx-get 'draft   ctx))))
    (act 'merchant_center/sync (list listing) 'check-push-result)))

(define (check-push-result ctx)
  (let ((r (ctx-result ctx)))
    (cond
      ((push-ok? r)
       (sakura/say (string-append
                     "Polished + pushed to Google · "
                     (push-product-id r)))
       (done))
      ((eq? r 'rate-limited) (after 30 'push ctx))
      (else                  (escalate 'push-failed r)))))

source: curator-web/src/scheme/carts/google/polish-listing-for-google.sks · 101 lines

EXAMPLES

Example forthcoming — docs/automations/examples.json entry editable in place.

TIER

light purple
cloud reasoning · cents per call

FITNESS

Almost there

Works on smaller shops too; the answer sharpens as you collect more sales.

SEE ALSO

HISTORY

canonical source: curator/docs/AUTOMATIONS-CANONICAL.md · §9-light-purple-cloud-reasoning-51-baseline-86-post-matrix
last regenerated: 2026-06-05 20:31 UTC (mechanical — edits land in the MD or sidecars, not here)

KNOWN BUGS

(none recorded — flag in AUTOMATIONS-CANONICAL.md or open an issue against the cart file)