diff --git a/src/lib/programs/__tests__/self-driving-detect.test.ts b/src/lib/programs/__tests__/self-driving-detect.test.ts index b749cdba..10bd3280 100644 --- a/src/lib/programs/__tests__/self-driving-detect.test.ts +++ b/src/lib/programs/__tests__/self-driving-detect.test.ts @@ -67,6 +67,20 @@ describe('SELF_DRIVING_ABORT_CASES', () => { expect(matched[0].message).toBeTruthy(); expect(matched[0].body).toBeTruthy(); }); + + it('frames the unavailable-access abort as open beta, not a closed per-team beta', () => { + // STEP 1 no longer gates on access — Self-driving is open beta — but the + // abort is kept as a safety net. Its copy must say the product is still + // in beta while dropping the old closed/per-team "join the beta" framing. + const [accessCase] = SELF_DRIVING_ABORT_CASES.filter((c) => + c.match.test('self-driving is not available for this project'), + ); + expect(accessCase).toBeDefined(); + const copy = `${accessCase.message} ${accessCase.body}`.toLowerCase(); + expect(copy).toContain('open beta'); + expect(copy).not.toContain('per team'); + expect(copy).not.toContain('join the beta'); + }); }); describe('selfDrivingConfig', () => { diff --git a/src/lib/programs/self-driving/ARCHITECTURE.md b/src/lib/programs/self-driving/ARCHITECTURE.md index ab1f334b..018cd9b1 100644 --- a/src/lib/programs/self-driving/ARCHITECTURE.md +++ b/src/lib/programs/self-driving/ARCHITECTURE.md @@ -59,7 +59,7 @@ matching context-mill file carries the HOW. **Step backbone (expected action, one line each):** -1. **Check access** — probe the Signals API; if it's not available for the team, abort cleanly (`[ABORT] self-driving is not available for this project`). +1. **Check access** — **instant, no probe.** Self-driving is in **open beta** (available to every team), so there is no access gate to check; the step just marks itself in_progress→completed (no MCP call) so the step-tracking funnel still fires and the user gets an immediate first checkmark. `[ABORT] self-driving is not available for this project` is kept only as a safety net for a genuine Signals-API outage during the run. 2. **Read context** — build an evidence picture of which products are in use (setup report + `signals-scout-project-profile-get` + cheap usage probes + a light repo scan); read-only. 3. **Connect GitHub** — required; if no `github` integration, send the user through the GitHub App install (one-click authorize deep-link) and re-verify; abort if declined. 4. **Enable sources** — always enable the scout gate; enable native sources (error tracking, replay, support) only where step-2 evidence shows the product is in use. @@ -72,7 +72,7 @@ The table below adds the skill reference and the tool/MCP surface for each. | # | Step | Skill ref / file | Tools · surface | |---|---|---|---| -| 1 | Check access | `1-check-access.md` | Probe `inbox-source-configs-list` (no readable beta flag — the API *is* the probe). Fail → `[ABORT] self-driving is not available for this project`. | +| 1 | Check access | `1-check-access.md` | **No probe — instant** (open beta: available to every team). Marks the task in_progress→completed immediately, calls no MCP tool. The `[ABORT] self-driving is not available for this project` string remains a safety net for a genuine Signals-API outage during the run, not a beta gate. | | 2 | Read project & Signals state | `2-read-context.md` | `./posthog-setup-report.md` + `signals-scout-project-profile-get` + cheap usage probes. Prompt opt-ins are authoritative ("repo evidence rules a product IN, never OUT"). | | 3 | Connect GitHub (REQUIRED) | `3-github.md` | `integrations-list` for `kind:"github"`; else `wizard_ask` with the one-click `integrations/authorize?kind=github` deep-link (the single link covers fresh install / link-existing / re-auth — no separate settings "re-link" path), re-verify after a manual "done". Can't → `[ABORT] github connection declined`. | | 4 | Enable signal sources | `4-sources.md` | Create/enable `SignalSourceConfig` rows for products in use (`inbox-source-configs-*`). Always enables the scout gate `signals_scout`/`cross_source_issue`. Never enables an unconfirmed tool. | @@ -232,6 +232,14 @@ scoped to `created_via=MCP`. ## 6. Gating & prerequisites — "will it actually work?" +> [!NOTE] +> **Open beta — the wizard no longer probes access.** Self-driving is in open +> beta (available to every team), so STEP 1 dropped its `inbox-source-configs-list` +> access probe and runs instantly; the wizard surfaces no beta gate of its own. +> The PostHog-side gates below still apply **server-side** (a flag not yet at 100% +> just means findings won't surface), and the `[ABORT] self-driving is not available +> for this project` path is now only a safety net for a genuine Signals-API outage. + 1. **UI flag `product-autonomy`** (`posthog/frontend/src/lib/constants.tsx`, `FEATURE_FLAGS.PRODUCT_AUTONOMY`). Frontend-only — gates the Inbox scene, nav item, and source-config loading. Off → the user can't *see* the inbox; the pipeline is unaffected. @@ -281,8 +289,10 @@ Plus the **Temporal coordinator schedule** (`signals-scout-coordinator-schedule` 3. **posthog backend deploy** of the `feat/signals-scout-config-sync` work: the `sync` endpoint, companion seeding (`lazy_seed.py`), and the 10 canonical scout skills. 4. **Temporal coordinator schedule** running in prod. -5. **Flag rollout:** `signals-scout` 100%-on with target teams in `guaranteed_team_ids`; `product-autonomy` - on for target users. +5. **Flag rollout (open beta = everyone):** `signals-scout` 100%-on for all teams (still the real + server gate for dispatch); `product-autonomy` on for all users. The wizard no longer probes access + in STEP 1, so an un-flagged team isn't turned away at setup — it just won't see findings until the + server-side flags are on. 6. **Per-team runtime** (user's responsibility): org AI consent on, GitHub connected. > [!NOTE] diff --git a/src/lib/programs/self-driving/detect.ts b/src/lib/programs/self-driving/detect.ts index f3595437..6926b2be 100644 --- a/src/lib/programs/self-driving/detect.ts +++ b/src/lib/programs/self-driving/detect.ts @@ -5,13 +5,18 @@ * `session.installDir` is a real, readable directory. We deliberately do * NOT require the base posthog-integration report to be present — it is a * report many users never commit, and `requires: ['posthog-integration']` - * is metadata, not a hard runtime gate. Real readiness (integration state - * + beta access) is established by the agent's STEP 1 Signals API probe at - * the start of the run. The beta gates (the `product-autonomy` access flag - * and `signals-scout` enrollment — PostHog-side flag names, unchanged by - * the wizard-side "self-driving" rename) are PostHog-internal flags with no - * customer-facing read API, which is why that probe lives in the run and - * emits a structured `[ABORT]` when the product is not available. + * is metadata, not a hard runtime gate. + * + * Self-driving is now in OPEN beta — available to every team — so STEP 1 + * no longer probes the Signals API as an access gate; it completes + * instantly so the run opens with a fast first checkmark. The + * `self-driving is not available for this project` abort below is kept + * only as a safety net: if the Signals API genuinely can't be reached + * during the run (a hard error that is unexpected in open beta), the skill + * emits it and the wizard renders a friendly "try again" screen — now with + * open-beta wording, not the old closed, per-team "join the beta" copy. The + * PostHog-side flags (`product-autonomy`, `signals-scout`) are unchanged by + * the wizard-side "self-driving" rename. */ import { existsSync, statSync } from 'fs'; @@ -39,10 +44,10 @@ export const SELF_DRIVING_ABORT_CASES: AbortCase[] = [ match: /^self-driving is not available for this project$/i, message: 'PostHog Self-driving is not available for this project', body: - 'Self-driving is in beta and is enabled per ' + - 'team by PostHog. This project does not appear to have access yet. ' + - 'Reach out to your PostHog contact (or wizard@posthog.com) to join ' + - 'the beta, then run the wizard again.', + 'Self-driving is in open beta and available to every team, so this ' + + 'is unexpected — the PostHog Signals API could not be reached for ' + + 'this project. Nothing was changed. Try again in a moment, and if it ' + + 'keeps happening reach out to wizard@posthog.com.', }, { // Skill emits: [ABORT] github connection declined diff --git a/src/lib/programs/self-driving/prompt.ts b/src/lib/programs/self-driving/prompt.ts index 7d5df20d..afb25533 100644 --- a/src/lib/programs/self-driving/prompt.ts +++ b/src/lib/programs/self-driving/prompt.ts @@ -72,8 +72,13 @@ Wizard mechanics: Follow these steps IN ORDER. Do not skip or reorder. STEP 1 — Check Self-driving access. (skill: "Check access") - Probe the Signals API as the skill describes. If the API is not - available for this project (permission or not-found errors), emit + Self-driving is in open beta and available to every team, so there is + no access gate to probe. Do NOT call any MCP tool here — mark this task + in_progress and then completed right away and emit the + ${AgentSignals.STATUS} line, so the user sees an immediate first step. + Only if the Signals API later turns out to be genuinely unreachable for + this project (a hard error on every Signals call, unexpected in open + beta) should you emit ${AgentSignals.ABORT} self-driving is not available for this project and halt.