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
14 changes: 14 additions & 0 deletions src/lib/programs/__tests__/self-driving-detect.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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', () => {
Expand Down
18 changes: 14 additions & 4 deletions src/lib/programs/self-driving/ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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. |
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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]
Expand Down
27 changes: 16 additions & 11 deletions src/lib/programs/self-driving/detect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -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
Expand Down
9 changes: 7 additions & 2 deletions src/lib/programs/self-driving/prompt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Expand Down
Loading