stacktree-client-deliverable
Publish a client-facing deliverable to stacktr.ee and return a private link the
client can open in a browser, no account needed. This is the publish path for the
client-deliverable job: work that leaves the building and should look finished,
stay reachable, and only open for the intended recipient.
When to invoke
- User is handing a finished artifact to a named client or customer ("send this to
Acme", "this goes to the client tomorrow").
- The page is a deliverable, not a scratch draft: a proposal, audit, report, or
pitch.
- The recipient is outside the user's own org and will not have a Stacktree account.
For an agent-generated report meant for "anyone with the link", use
stacktree-agent-run-report. For a dated digest refreshed in place, use
stacktree-daily-brief. For a public status page, use stacktree-status-dashboard.
The page shape
Produce a single self-contained HTML document in the Client deliverable shape: a
centered white .sheet with a .topbar (the studio/sender name on the left, a
.pill reading "Private deliverable" on the right), then a .pad body with an
.eyebrow "Prepared for ", an <h1> title, a .lede, and a .meta row
(prepared by, date, version). Use .section blocks for Overview, the one
recommendation (in a .callout), an at-a-glance <dl>, and next steps
(<ol class="steps">). Close with a .foot. The published page is what the client
sees, so the craft is the point: keep it editorial, content-first, no broken
assets. The canonical reference is the client-deliverable template in the
Stacktree app (apps/web/src/templates.ts); match its structure and restraint.
Required env
STACKTREE_API_KEY=stk_live_... # generate at https://app.stacktr.ee/api-keys
A client deliverable should publish under the user's own account so they keep
ownership and can revoke it later. If no key is set, ask for one rather than
falling back to an anonymous upload (anonymous uploads expire in 24h, which is
wrong for a deliverable). See the root stacktree-publish skill for the
pay-to-provision path when there is genuinely no human and no key.
The judgment this skill encodes
It must not auto-delete. Publish with --expires-never (or set_expiry to
never). A link that 404s a week after you send it is worse than not sending it.
Only set an expiry if the user wants access to lapse on purpose (e.g. "this quote
is valid 30 days"), then set it to that date, not the 7-day default.
It must be gated to the recipient, not the whole internet. The unlisted token
alone is "anyone with the link", and links get forwarded. Pick the gate from what
the user has:
- Recipient email or company domain known: use the email gate
(
set_email_gate). The client enters their email, gets a one-time code, and is
in. This ties access to a person and gives the user a record of who opened it.
- Only a side channel (the user will pass a secret over Slack/SMS): use a
password (
--password or set_password). Generate a strong one, never reuse
the user's own secrets, and surface it on its own line so it travels separately
from the link.
The template's footer line ("This link is unguessable. Add a password if it
should be.") is the prompt: act on it, do not ship a bare link for a real
deliverable unless the user says "anyone with the link is fine".
It must not leak PII. Keep the PII scan in block mode (the default). Client
deliverables are exactly where an embedded API key, internal thread, or customer
record does real damage. If the scan trips, stop and show the user what it caught
before relaxing anything. Only drop to --pii-check warn when the user confirms
the flagged content is intentional and safe (e.g. the client's own contact
details on the proposal).
The URL can read as professional. A raw stacktr.ee/p/<token>/ link is fine
and private, but for an external deliverable a custom domain (e.g.
proposals.theiragency.com) reads better. Custom domains are a paid Pro unlock,
not a publish flag, and there is no MCP tool for the mapping, so point the user to
https://stacktr.ee/x402 or the dashboard to enable it. Do not block the hand-off
on it; ship the private link now and offer the domain as a follow-up.
Steps
- Build the deliverable as a complete HTML document in the page shape above. If you
only have Markdown or a fragment, wrap and style it so it renders standalone.
- Decide the gate from what the user has. If unclear, ask one short question: "Do
you have the client's email, or will you send them a password separately?"
- Publish with no expiry and the PII scan on, via the publish helper:
echo "$DELIVERABLE_HTML" | bash scripts/publish.sh --expires-never
Equivalent MCP path: publish_html with expiry set to never. Capture the id
and url.
- Apply the gate:
- Email gate:
set_email_gate on the returned id with the client's email or
@their-domain.com.
- Password: pass
--password <generated> in step 3, or call set_password
after. Prefer generating the password over asking the user to invent one.
- Optionally
set_agentation (or --agentation) if the client should be able to
leave inline feedback (useful for a draft-for-review; skip it for a final, signed
deliverable). If you enable it, own the loop: once the client has annotated, pull
their notes with list_feedback, apply the changes with update_site so the
revision lands at the link they already have, then resolve_feedback each item
with a short note so the client can see what changed and why.
- Reply with: the link, the gate type and how the client gets in (the allowed
email/domain, or the password on its own line), the fact that it will not expire,
and any PII warning that was surfaced.
What to tell the user
State plainly who can open it (the gate), that the link will stay live, and what the
PII scan caught if anything. If they wanted a custom domain, note it is a one-time
Pro unlock and offer to walk them through it rather than holding up the hand-off.
1---2name: stacktree-client-deliverable3description: Hand a finished report or proposal to a client at a private link. Use when the user says "send this to the client", "share this with <company>", "this is for a customer", or is handing a polished deliverable to someone outside their team. Produces a page in the Client deliverable shape (a clean editorial "sheet" prepared-for-a-named-recipient), gates it to the recipient, removes the auto-expiry so the link stays live, and refuses to ship if the page leaks PII.4---56# stacktree-client-deliverable78Publish a client-facing deliverable to **stacktr.ee** and return a private link the9client can open in a browser, no account needed. This is the publish path for the10`client-deliverable` job: work that leaves the building and should look finished,11stay reachable, and only open for the intended recipient.1213## When to invoke1415- User is handing a finished artifact to a named client or customer ("send this to16 Acme", "this goes to the client tomorrow").17- The page is a deliverable, not a scratch draft: a proposal, audit, report, or18 pitch.19- The recipient is outside the user's own org and will not have a Stacktree account.2021For an agent-generated report meant for "anyone with the link", use22`stacktree-agent-run-report`. For a dated digest refreshed in place, use23`stacktree-daily-brief`. For a public status page, use `stacktree-status-dashboard`.2425## The page shape2627Produce a single self-contained HTML document in the Client deliverable shape: a28centered white `.sheet` with a `.topbar` (the studio/sender name on the left, a29`.pill` reading "Private deliverable" on the right), then a `.pad` body with an30`.eyebrow` "Prepared for <Client>", an `<h1>` title, a `.lede`, and a `.meta` row31(prepared by, date, version). Use `.section` blocks for Overview, the one32recommendation (in a `.callout`), an at-a-glance `<dl>`, and next steps33(`<ol class="steps">`). Close with a `.foot`. The published page is what the client34sees, so the craft is the point: keep it editorial, content-first, no broken35assets. The canonical reference is the `client-deliverable` template in the36Stacktree app (`apps/web/src/templates.ts`); match its structure and restraint.3738## Required env3940```41STACKTREE_API_KEY=stk_live_... # generate at https://app.stacktr.ee/api-keys42```4344A client deliverable should publish under the user's own account so they keep45ownership and can revoke it later. If no key is set, ask for one rather than46falling back to an anonymous upload (anonymous uploads expire in 24h, which is47wrong for a deliverable). See the root `stacktree-publish` skill for the48pay-to-provision path when there is genuinely no human and no key.4950## The judgment this skill encodes51521. **It must not auto-delete.** Publish with `--expires-never` (or `set_expiry` to53 never). A link that 404s a week after you send it is worse than not sending it.54 Only set an expiry if the user wants access to lapse on purpose (e.g. "this quote55 is valid 30 days"), then set it to that date, not the 7-day default.56572. **It must be gated to the recipient, not the whole internet.** The unlisted token58 alone is "anyone with the link", and links get forwarded. Pick the gate from what59 the user has:60 - **Recipient email or company domain known:** use the email gate61 (`set_email_gate`). The client enters their email, gets a one-time code, and is62 in. This ties access to a person and gives the user a record of who opened it.63 - **Only a side channel (the user will pass a secret over Slack/SMS):** use a64 password (`--password` or `set_password`). Generate a strong one, never reuse65 the user's own secrets, and surface it on its own line so it travels separately66 from the link.67 The template's footer line ("This link is unguessable. Add a password if it68 should be.") is the prompt: act on it, do not ship a bare link for a real69 deliverable unless the user says "anyone with the link is fine".70713. **It must not leak PII.** Keep the PII scan in `block` mode (the default). Client72 deliverables are exactly where an embedded API key, internal thread, or customer73 record does real damage. If the scan trips, stop and show the user what it caught74 before relaxing anything. Only drop to `--pii-check warn` when the user confirms75 the flagged content is intentional and safe (e.g. the client's own contact76 details on the proposal).77784. **The URL can read as professional.** A raw `stacktr.ee/p/<token>/` link is fine79 and private, but for an external deliverable a custom domain (e.g.80 `proposals.theiragency.com`) reads better. Custom domains are a paid Pro unlock,81 not a publish flag, and there is no MCP tool for the mapping, so point the user to82 <https://stacktr.ee/x402> or the dashboard to enable it. Do not block the hand-off83 on it; ship the private link now and offer the domain as a follow-up.8485## Steps86871. Build the deliverable as a complete HTML document in the page shape above. If you88 only have Markdown or a fragment, wrap and style it so it renders standalone.892. Decide the gate from what the user has. If unclear, ask one short question: "Do90 you have the client's email, or will you send them a password separately?"913. Publish with no expiry and the PII scan on, via the publish helper:92 ```bash93 echo "$DELIVERABLE_HTML" | bash scripts/publish.sh --expires-never94 ```95 Equivalent MCP path: `publish_html` with expiry set to never. Capture the `id`96 and `url`.974. Apply the gate:98 - Email gate: `set_email_gate` on the returned id with the client's email or99 `@their-domain.com`.100 - Password: pass `--password <generated>` in step 3, or call `set_password`101 after. Prefer generating the password over asking the user to invent one.1025. Optionally `set_agentation` (or `--agentation`) if the client should be able to103 leave inline feedback (useful for a draft-for-review; skip it for a final, signed104 deliverable). If you enable it, own the loop: once the client has annotated, pull105 their notes with `list_feedback`, apply the changes with `update_site` so the106 revision lands at the link they already have, then `resolve_feedback` each item107 with a short note so the client can see what changed and why.1086. Reply with: the link, the gate type and how the client gets in (the allowed109 email/domain, or the password on its own line), the fact that it will not expire,110 and any PII warning that was surfaced.111112## What to tell the user113114State plainly who can open it (the gate), that the link will stay live, and what the115PII scan caught if anything. If they wanted a custom domain, note it is a one-time116Pro unlock and offer to walk them through it rather than holding up the hand-off.