Skip to content

release-k-01-02: chat trim, canvas beta gate, docs deploy, support-request forwarder#876

Merged
spashii merged 8 commits into
mainfrom
release-k-01-02
Jul 24, 2026
Merged

release-k-01-02: chat trim, canvas beta gate, docs deploy, support-request forwarder#876
spashii merged 8 commits into
mainfrom
release-k-01-02

Conversation

@spashii

@spashii spashii commented Jul 24, 2026

Copy link
Copy Markdown
Member

Release branch for k-01-02, merging to main to deploy echo-next (dev image build triggers on main push). Production ships later via a release tag, per usual.

What's in it (8 commits, squashed here — see branch release-k-01-02 for the individual history)

Agentic chat trim (release scope):

  • Tag edits become a host-approved proposal card instead of direct writes.
  • Canvas (Project Library) gated per-project behind an experimental-settings beta toggle; Overview mode retired; docs updated.

Support loop (ISSUE-034 — closes the honesty gap):

  • task_forward_support_requests: outbox forwarder (*/2 reconciler) POSTing new support_request rows to sam's webhook with the shared token (X-Echo-Support-Token); forwarded_at stamped only on 2xx, at-least-once, sam dedupes by id. No-ops unless SUPPORT_WEBHOOK_URL + ECHO_SUPPORT_WEBHOOK_TOKEN are set — so this is inert everywhere until the env config exists (echo-next's is already live in echo-gitops; prod's deliberately isn't).
  • forwarded_at migration (idempotent; already run on echo-next Directus, snapshot committed). Prod runs it before its config goes live.
  • Receiving side is merged and deployed on sam (Dembrane/sam ECHO-258 switch to custom runpod deployment for whisper #168): deterministic #gen-engineering post + in-thread triage with read-only DB context.
  • Docs: user-facing "Asking the assistant for help" (first-aid, en+nl) + internal docs/support_request_pipeline.md runbook.

CI:

  • docs.dembrane.com deploys on release tags.

Verification

  • Server suite in the devcontainer: no new failures vs the clean-tree baseline (45 pre-existing, billing/invite areas); +11 forwarder tests, all passing. Ruff/mypy clean on changed files.
  • Helm renders verified in echo-gitops: URL+token wired for echo-next across api/worker/scheduler; prod gets the optional token ref only.

After merge

  • Watch the dev image build + tag bump land, then trigger reachOutToDembraneSupport on echo-next — the request should appear in #gen-engineering within ~2 minutes with sam picking up the thread.
  • Prod enablement (with the release): run the forwarded_at migration on prod Directus, then set SUPPORT_WEBHOOK_URL in values-prod.yaml.

🤖 Generated with Claude Code

spashii and others added 8 commits July 24, 2026 12:17
Canvas becomes opt-in per project via project.is_canvas_enabled (default
off), on top of the global ENABLE_CANVAS kill switch:

- Directus migration script for the new boolean (snapshot pull to follow)
- BFF canvas routes and the 8 agentic canvas routes 404 unless the project
  opted in; the gate fires before policy checks so existence stays hidden
- canvas ticks no-op for non-opted-in projects; reconciler exits early
  when the global flag is off
- the agentic worker resolves the verdict per turn and forwards it as
  X-Dembrane-Canvas-Enabled; the agent registers its 9 canvas tools and
  the Canvases prompt section only when enabled, so a canvas-off chat
  never learns canvas exists (prompt is byte-identical when enabled)
- is_canvas_enabled whitelisted on the project PATCH so the settings
  toggle can actually write it

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
New Experimental card in project settings (visible only where the
ENABLE_CANVAS env flag allows) with a per-project Living canvas switch
writing is_canvas_enabled. The Library nav entry now also requires the
project's toggle, so canvas surfaces disappear for non-opted-in projects.
Locale catalogs recompiled.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The smart-loop and building pages now describe the living canvas as an
opt-in beta on dembrane next (off by default, per-project experimental
toggle, not in production). The chat-and-ask pages are rewritten around
the new Ask experience: one question bar, Specific Details as the classic
fallback, Overview retired. Referring anchors and FACTS.md updated.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Extends the gitops rhythm to documentation: push to main keeps deploying
docs.echo-next.dembrane.com; a v*.*.* tag now builds the same docs/
corpus with the production base URL and deploys the static output to the
Vercel project owning docs.dembrane.com (Build Output API, --prebuilt).
Needs the VERCEL_PROJECT_ID_DOCS secret before the first release.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The agent's editProjectTags direct write is replaced by proposeTagsUpdate:
the agent proposes add/remove changes with a one-line reason, a card
renders in the chat (same wiring and persistence as project-update
proposals), and the host applies it through the existing dashboard tag
endpoints. The agent never mutates the tag vocabulary itself. Part of the
production chat trim (founder call 2026-07-24): the last direct-write tool
is gone; remaining writes are memory (host-visible and deletable) and the
support/insight outboxes.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
reachOutToDembraneSupport writes support_request rows and tells the host
"logged for the team" — until now nothing forwarded them. This is the
outbox forwarder that makes the claim true:

- task_forward_support_requests: reconciler catch-up (*/2 cron), rows
  with status=new and forwarded_at NULL are POSTed to sam's webhook and
  stamped forwarded_at only on 2xx — at-least-once, sam dedupes by id.
  4xx (payload bug) logs loudly and leaves the row unstamped; 5xx or a
  network error stops the batch for the next run.
- Auth: shared static token in the X-Echo-Support-Token header (NOT
  Authorization — sam's ingress uses that for its GCP IAM layer).
- SupportSettings (SUPPORT_WEBHOOK_URL + ECHO_SUPPORT_WEBHOOK_TOKEN);
  both unset (the local default) disables the forwarder entirely.
- environment / origin_link derived from admin_base_url host, no new
  env var (analytics-token pattern).
- Idempotent migration adds support_request.forwarded_at; run per env
  before enabling the config, then pull the snapshot.

Receiving side is live (Dembrane/sam PR #168): deterministic
#gen-engineering post + in-thread triage. Payload contract lives in
sam's product-support recipe; keep both ends in sync.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Migration ran against echo-next (idempotent, verified on re-run); this is
the snapshot pull of the new column, plus a --token auth option on the
migration script so deployed envs (which expose DIRECTUS_ADMIN_TOKEN, not
a login) can run it. Production still needs the same migration before its
forwarder config goes live.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- first-aid (en + nl): what happens when the assistant logs a support
  request — goes straight to the engineering team, what's shared (message,
  page context, project reference; never recordings or transcripts), and
  that 'Report an issue' stays the always-available direct route. No
  response-time promises, per the assistant's honesty rules.
- docs/support_request_pipeline.md: the end-to-end internals (outbox →
  forwarder → sam → #gen-engineering), delivery semantics, payload
  contract, code map, and the per-environment enablement order (echo-next
  done; prod = migration, then SUPPORT_WEBHOOK_URL).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@spashii
spashii enabled auto-merge July 24, 2026 14:25
Comment on lines +29 to +58
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
# folder2website reads git history for page metadata
fetch-depth: 0

- name: Setup Bun
uses: oven-sh/setup-bun@v2

- name: Build docs site
run: bunx github:spashii/folder2website#main docs --out _docs-site --base-url https://docs.dembrane.com

- name: Install Node.js
uses: actions/setup-node@v4
with:
node-version: 22

- name: Install Vercel CLI
run: npm install --global vercel@latest

- name: Stage prebuilt static output
run: |
mkdir -p .vercel/output/static
cp -R _docs-site/. .vercel/output/static/
echo '{"version": 3}' > .vercel/output/config.json

- name: Deploy to Vercel (docs.dembrane.com)
run: vercel deploy --prebuilt --prod --token=${{ secrets.VERCEL_TOKEN }}

@dembrane-sam-bot dembrane-sam-bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approving on Sameer's explicit go ('pls merge it', 2026-07-24) — release-k-01-02 → main deploys echo-next only; prod follows via a release tag. Verification in the PR body: zero new test failures vs baseline, helm renders checked, echo-next migration already applied.

@spashii
spashii added this pull request to the merge queue Jul 24, 2026
Merged via the queue into main with commit 9c75d6d Jul 24, 2026
11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants