Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 28 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,11 @@ acknowledged. It is not a diagnosis product and makes **no accuracy claim**.
analytics chart.
- **Responsible student data:** the roster, activity, names, and evaluation corpus are visibly
synthetic; real student data is rejected and remains out of scope.
- **Trustworthy AI boundary:** rules classify and rank without a model. Only a manual synthetic
refresh may draft the explanation, first question, and teaching move from a bounded packet; a
complete deterministic card always keeps the board usable.
- **Trustworthy AI boundary:** rules classify and rank without a model. Only an authenticated,
manual refresh of synthetic data may call Claude with a bounded packet to draft the likely
explanation, first question, and suggested teaching move. The confident/struggling follow-ups
and listen-for remain deterministic; nightly refreshes and missing or rejected provider responses
persist a complete deterministic fallback card.

## Architecture and trust boundaries

Expand Down Expand Up @@ -101,6 +103,9 @@ the evaluation contract remains deferred before any pilot or accuracy-backed cla
- server-only `DATABASE_URL`
- server-only `SUPABASE_DB_CA_BASE64` (the public Supabase Server root CA, base64 encoded)
- server-only `HUDDLE_ACKNOWLEDGMENT_KEY_CURRENT`
- server-only `ANTHROPIC_API_KEY` for the authenticated manual synthetic-refresh draft only; never
use a `NEXT_PUBLIC_` name or expose it in source, logs, screenshots, or chat. Adding or changing
any Vercel variable requires a new deployment before the runtime receives it.
- `HUDDLE_DEMO_BOARD_DATE=2026-07-27`
- `INTERNAL_REFRESH_SECRET` only if the protected nightly dispatcher will be used

Expand All @@ -109,10 +114,11 @@ credential in browser-visible variables. Run migrations and `demo:seed` from a t
terminal before deployment. The reviewer-facing `/board` and `/import` operations require the
Supabase account; unauthenticated requests expose no roster, evidence, or freshness.

Private hosting is required for this demo. In Vercel **Project Settings → Deployment Protection**,
select **All Deployments** with **Vercel Authentication** before release, and add the reviewer to the
Vercel project or team. Do not ship from a plan or project configuration that leaves the production
domain public. Send the reviewer the separate Supabase guide credentials through a private channel.
The stable production alias, https://huddle-tsa-portfolio-demo.vercel.app, is intentionally reachable
at the Vercel layer so reviewers can reach Huddle's sign-in page. Supabase application Auth protects
`/board`, `/import`, roster, evidence, and freshness. Generated immutable deployment URLs may remain
behind Vercel Authentication; do not change protection settings merely to make them public. Send the
reviewer the separate Supabase guide credentials through a private channel.

Deploy from the repository root with the pinned CLI version so the committed `vercel.json` and
workspace build are used consistently:
Expand All @@ -128,21 +134,25 @@ Create a Vercel Protection Bypass for Automation secret for the hosted smoke onl
npm run smoke:hosted -- --base-url https://YOUR-PRIVATE-DEMO.vercel.app
```

That command checks health/policy output, the sign-in page, the fixed synthetic CSV, and fail-closed
anonymous board access through the required protection wall. Never add the bypass value to Vercel's
application environment or share it with the reviewer. The captain still performs the authenticated
walkthrough below; the smoke command does not pretend to replace it.
Use that smoke only with a protected generated deployment URL, not the stable production alias. It
checks health/policy output, the sign-in page, the fixed synthetic CSV, and fail-closed anonymous
board access through the protection wall. Never add the bypass value to Vercel's application
environment or share it with the reviewer. The captain still performs the authenticated walkthrough
below; the smoke command does not pretend to replace it.

## Two-minute reviewer walkthrough

1. **0:00–0:15 — Sign in.** Note the private Supabase Auth boundary and synthetic-only label.
2. **0:15–0:40 — Import.** Open **Import synthetic CSV**, download/select the fixed file, then
validate. Call out the separate received/accepted/duplicate/unmapped/rejected counts and that
validation stores no activity.
3. **0:40–0:55 — Commit and refresh.** Commit the same bytes, then choose **Refresh board now**. The
deterministic engine publishes one immutable ranked run. With `ANTHROPIC_API_KEY`, this manual
synthetic refresh may draft only the explanation, first question, and teaching move; without it,
the complete deterministic card publishes instead. Nightly refresh never invokes AI.
2. **0:15–0:40 — Import.** Open **Import synthetic CSV**, download/select the reviewed file, then
validate and commit it. **Refresh board now** appears only after that select/validate/commit flow
in the same browser session; there is no standalone refresh control. Repeating the reviewed sample
is idempotent: existing rows are reported as duplicates, not duplicated. Call out the separate
received/accepted/duplicate/unmapped/rejected counts and that validation stores no activity.
3. **0:40–0:55 — Refresh.** Choose **Refresh board now**. The deterministic engine publishes one
immutable ranked run and its board refresh timestamp advances. An accepted Claude draft is shown
as **Validated wording**; **Deterministic fallback** means the complete safe fallback was persisted.
Claude drafts only the likely explanation, first question, and suggested teaching move; nightly
refresh and unavailable or rejected provider responses use the deterministic fallback.
4. **0:55–1:30 — Use the Evidence Desk.** Open the top report. The visible teacher-decision map
presents a hypothesis, first question, confident/struggling fork, listen-for, and teaching move.
Only the three draftable fields are labeled AI-drafted wording; the fork and listen-for are
Expand Down
8 changes: 5 additions & 3 deletions scripts/verify-quickstart.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,10 @@ async function main(): Promise<void> {
}
for (const deploymentRequirement of [
'npx --yes vercel@48.8.0 deploy --prod',
'All Deployments',
'Vercel Authentication',
'https://huddle-tsa-portfolio-demo.vercel.app',
'Generated immutable deployment URLs may remain',
'behind Vercel Authentication; do not change protection settings merely to make them public.',
'protected generated deployment URL, not the stable production alias',
]) {
if (!readme.includes(deploymentRequirement)) {
throw new Error(`README is missing deployment requirement: ${deploymentRequirement}`);
Expand Down Expand Up @@ -80,7 +82,7 @@ async function main(): Promise<void> {
]);
console.log('Quickstart contract passed without credentials or model calls.');
console.log(
'Operator steps remaining: migrate, seed, protect, deploy, smoke, then manual walkthrough.'
'Operator steps remaining: migrate, seed, deploy, run protected-URL smoke when applicable, then manual walkthrough.'
);
}

Expand Down
Loading