Skip to content

refactor(agent): WIP make runAgent a function with progress and interaction contracts - #1292

Closed
gewenyu99 wants to merge 1 commit into
mainfrom
posthog/functional-a1-agent
Closed

gewenyu99 wants to merge 1 commit into
mainfrom
posthog/functional-a1-agent

Conversation

@gewenyu99

Copy link
Copy Markdown
Collaborator

Intent

Make the agent callable as a function. runAgent(config, input, {onProgress?, interaction?, signal?}) returns a RunResult, and nothing under src/lib/agent touches a screen, a session, the program registry or process.exit. Release A, A1′ of the functional stack plan, on top of #1288.

Impact

People using the wizard. Nothing changes. Every runner still calls a session-taking runAgent, now at src/lib/programs/run-agent-legacy.ts. It maps each progress event back to the same WizardUI call in the same order, so frames, flow traces, exit codes and error copy are byte-identical. Zero goldens regenerated.

People maintaining it. The agent is sealed. The import-boundaries test refuses any src/ui import from it, and every ending is a result rather than an exit or a throw. Anyone writing a harness or sequence takes BackendRunInputs or SequenceContext and an emit, never a session. Anyone importing runAgent, ProgramRun, PROGRAM_BINDINGS, bootstrapProgram, sessionToOptions or abortOnInstallFailure from the agent has to re-point, and all in-tree callers already did.

The map

flowchart LR
  classDef new fill:#dbeafe,stroke:#1d4ed8,color:#1e3a8a
  rw["run-wizard.ts / run-non-interactive.ts / posthog-integration composed step"]
  legacy["run-agent-legacy.ts runAgent(programConfig, session)"]:::new
  gates["gates · authenticate · flags · refreshAccessTokenIfNeeded · bindingFor"]:::new
  fn["runner/index.ts runAgent(config, input, options)"]:::new
  prep["prepareRun: mint, triage"]
  seq["runLinearProgram | runOrchestrator"]
  harness["anthropic | pi harness"]
  collector["createProgressCollector → RunSnapshot"]:::new
  reducer["createUiReducer → WizardUI"]:::new
  answer["uiInteraction → requestQuestion / showTaskNotice"]:::new
  apply["result: success → nothing · aborted/failed → wizardAbort · crashed → rethrow"]:::new
  rw --> legacy --> gates --> fn --> prep --> seq --> harness
  harness -. emit .-> collector -. onProgress .-> reducer
  harness -. ask .-> answer
  fn --> apply
Loading

Shaded nodes are new. Before, the gates, the UI calls and the exit all lived inside the agent's bootstrap and sequences. Now the adapter owns the left and right edges, the agent owns the middle, and the two only meet through data.

The contract

runAgent(config: RunConfig, input: RunInput, options?: {
  onProgress?: (event: AgentProgress) => void;   // one-way, never awaited
  interaction?: AgentInteraction;                  // ask, taskNotice, cancels
  signal?: AbortSignal;                            // cooperative cancel
}): Promise<RunResult>                            // never rejects
Piece What it is
RunConfig What to run and how it's routed. Program id, run definition, resolved binding, flags, run tags, tool lists, caller-bound hooks.
RunInput The invocation snapshot. Directory, credentials, project, user, skill, eight flags, host hints.
AgentProgress 13 event kinds, one per former getUI() call, same order, copied payloads. A throwing observer is logged, the run continues.
AgentInteraction ask, cancelAsk, taskNotice, cancelTaskNotice, all optional. No answerer means no bridge, the tool says unavailable, notices decline. Same as today's CI path.
RunResult outcome, outro, failure, snapshot (tasks, status lines, stage, handoff text, URLs, token totals, cost).

The five endings

outcome Set at Adapter does
success end of runLinearProgram / runOrchestrator nothing, the reducer already rendered the outro
aborted linear on [ABORT] wizardAbort(failure)
failed every former wizardAbort site, plus installFailure and the 401 wizardAbort(failure)
cancelled signal checks before install and before the harness wizardAbort(failure), unreachable from the adapter
crashed the catch in runner/index.ts wrapping any throw rethrow failure.error, so run-wizard's mint-failure screen and headless classifyRunFailure see what they saw

failure has the fields wizardAbort takes (code, message, outroData, error, exitCode, detail), so the exit path receives what it always received.

What moved

Left the agent Now in
Health gate, settings gate, agent started capture, authenticate, AI opt-in gate, post-auth gates, flag fetch, run tags, token refresh, binding resolution, switchboard telemetry, registerCleanup, outro settings-restore hook, wizardAbort src/lib/programs/run-agent-legacy.ts
authenticate, refreshAccessTokenIfNeeded src/lib/programs/authenticate.ts, body unchanged
PROGRAM_BINDINGS src/lib/programs/bindings.ts
ProgramRun with its session-taking hooks src/lib/programs/program-run.ts, extends agent AgentRunDefinition
WizardError src/lib/errors/wizard-error.ts, re-exported from wizard-abort
TokenUsageDelta, SpinnerHandle, AuthErrorDetail src/lib/agent/progress.ts, re-exported from wizard-ui.ts

Four honest differences

  • Scan flush order. The agent's finally flushes the YARA report before the exit sequence instead of inside runCleanups. Idempotent, and the printed order is unchanged.
  • Mint vs switchboard event. A refused gateway mint now follows the switchboard resolved capture instead of preceding it.
  • Anthropic Write/Edit guard. getPendingQuestion used to read a forked session snapshot and was always null. It now reads bridge-side state, the guard pi already keeps.
  • Orchestrator cleanup on a mid-drain 401. The run ends when the failing task returns (RunTaskFatal through drainQueue) and the orchestrator's finally runs where process.exit used to skip it. In-flight sibling tasks keep running until exit, as before.

Verification

Check Result
pnpm typecheck pass
pnpm lint 0 errors, 482 pre-existing warnings
pnpm build + vitest run 184 files, 3115 tests pass (+1 file, +14 tests vs base)
Goldens none regenerated
Architecture known violations 72 → 60, none from the agent, new agent-imports-ui rule at 0
run-agent-standalone.test.ts 11 cases, @ui mocked to throw on any use, fake harness, no store, no registry
Headless CI run, express-todo copy, project 228144 exit 0, PostHog set up: 7/7 steps completed (1 skipped as not required), same line as P0

Full parity table and run log: workbench/wizard-functional-evidence/a1-prime-evidence.md (local).


Created with PostHog Desktop

…on contracts

runAgent(config, input, {onProgress?, interaction?, signal?}) returns a
RunResult and never rejects. RunConfig and RunInput replace the session and
program config reads, AgentProgress replaces the 58 getUI() calls, an optional
AgentInteraction replaces the getUI() answerer, and every former wizardAbort
returns as a failure with the same fields. Unexpected throws return as
outcome 'crashed' with the original error.

Gates, authenticate, token refresh, flag fetch, binding resolution and the
exit move to src/lib/programs/run-agent-legacy.ts, which maps each progress
event to one WizardUI call so every existing caller keeps its output.
PROGRAM_BINDINGS, ProgramRun and authenticate leave the agent for programs.
The architecture test forbids agent -> src/ui imports; known violations go
from 72 to 60. A standalone test runs the agent with @ui mocked to throw.

Generated-By: PostHog Desktop
Task-Id: d14e92bb-6ee1-49b5-8502-39cb80079589
@github-actions

Copy link
Copy Markdown

🧙 Wizard CI

Run the Wizard CI and test your changes against wizard-workbench example apps by replying with a GitHub comment using one of the following commands:

Test all apps:

  • /wizard-ci all

Test all apps in a directory:

  • /wizard-ci ai-observability
  • /wizard-ci basic-integration
  • /wizard-ci mcp-analytics
  • /wizard-ci replay-vision
  • /wizard-ci revenue
  • /wizard-ci self-driving
  • /wizard-ci warehouse
  • /wizard-ci warehouse-seeded

Test an individual app:

  • /wizard-ci ai-observability/anthropic
  • /wizard-ci ai-observability/google-adk
  • /wizard-ci ai-observability/groq
Show more apps
  • /wizard-ci ai-observability/manual-capture
  • /wizard-ci ai-observability/openai
  • /wizard-ci ai-observability/openai-agents
  • /wizard-ci ai-observability/opentelemetry
  • /wizard-ci ai-observability/vercel-ai
  • /wizard-ci basic-integration/android
  • /wizard-ci basic-integration/angular
  • /wizard-ci basic-integration/astro
  • /wizard-ci basic-integration/django
  • /wizard-ci basic-integration/fastapi
  • /wizard-ci basic-integration/flask
  • /wizard-ci basic-integration/flutter
  • /wizard-ci basic-integration/javascript-node
  • /wizard-ci basic-integration/javascript-web
  • /wizard-ci basic-integration/laravel
  • /wizard-ci basic-integration/next-js
  • /wizard-ci basic-integration/nuxt
  • /wizard-ci basic-integration/python
  • /wizard-ci basic-integration/rails
  • /wizard-ci basic-integration/react-native
  • /wizard-ci basic-integration/react-router
  • /wizard-ci basic-integration/sveltekit
  • /wizard-ci basic-integration/swift
  • /wizard-ci basic-integration/tanstack-router
  • /wizard-ci basic-integration/tanstack-start
  • /wizard-ci basic-integration/vue
  • /wizard-ci mcp-analytics/custom-dispatcher
  • /wizard-ci mcp-analytics/typescript-sdk
  • /wizard-ci replay-vision/javascript-node
  • /wizard-ci replay-vision/next-js
  • /wizard-ci replay-vision/react-vite
  • /wizard-ci revenue/stripe
  • /wizard-ci self-driving/astro
  • /wizard-ci self-driving/fastapi
  • /wizard-ci self-driving/nuxt
  • /wizard-ci self-driving/react-router
  • /wizard-ci self-driving/sveltekit
  • /wizard-ci warehouse/monorepo-env
  • /wizard-ci warehouse/multi-source-next
  • /wizard-ci warehouse/stripe-node
  • /wizard-ci warehouse/zero-source
  • /wizard-ci warehouse-seeded/next-stripe
  • /wizard-ci warehouse-seeded/next-stripe-declined

Test against a Context Mill branch:

  • /wizard-ci all context-mill:my-branch

Add context-mill:<branch> to any command above to pin the Context Mill branch. It defaults to main.

Results will be posted here when complete.

@gewenyu99

Copy link
Copy Markdown
Collaborator Author

Verified locally on the rebased commit a18d15f. Not waiting on CI.

Check Result
pnpm typecheck pass
pnpm lint 0 errors, 482 pre-existing warnings
pnpm build:ci + vitest run 184 files, 3116 tests pass
architecture 60 known violations, agent-imports-ui at 0
headless --ci run, fresh express-todo copy, project 228144 exit 0, PostHog set up: 7/7 steps completed (1 skipped as not required)

Run log and parity table live in workbench/wizard-functional-evidence/ (local).

@gewenyu99

Copy link
Copy Markdown
Collaborator Author

Logs and outputs from the local verification of a18d15f.

Headless --ci run on express-todo, 126 lines, exit 0
┌  Welcome to the PostHog setup wizard
│  Running posthog-integration in CI mode
│  Using provided API key (CI mode - OAuth bypassed)
│  Scanning the repo for projects...
│  Continuing with . (Express).
│  Task-queue orchestrator enabled.
◌  Planning the integration...
◇  Seeding the independent setup tasks.
◌  Seeding the independent setup tasks.
◇  Queueing identity and error coverage after setup.
◌  Queueing identity and error coverage after setup.
◇  Scheduling event instrumentation after identity.
◌  Scheduling event instrumentation after identity.
◇  Adding parallel review and analytics tasks.
◌  Adding parallel review and analytics tasks.
◇  Queueing the final report after review and insights.
◌  Queueing the final report after review and insights.
◇  Publishing the queued-work handoff.
◌  Publishing the queued-work handoff.
●  Planned the integration
◌  [0/8] Add the PostHog SDK
◌  [0/8] Add the PostHog SDK · Initialize PostHog
◇  I’m reading the integration rules and installation workflow before inspecting the project.
◌  I’m reading the integration rules and installation workflow before inspecting the project.
◇  I’m identifying the project manifest and its configured package manager.
◌  I’m identifying the project manifest and its configured package manager.
◇  Reviewing the integration workflow and project structure before making the initialization change.
◌  Reviewing the integration workflow and project structure before making the initialization change.
◇  I’m checking the manifest and application entry point to select the required SDK package.
◌  I’m checking the manifest and application entry point to select the required SDK package.
◇  Inspecting the Node application entry point, manifest, and any CSP configuration to choose the singleton initialization pattern.
◌  Inspecting the Node application entry point, manifest, and any CSP configuration to choose the singleton initialization pattern.
◇  I’m installing the server-side Node.js SDK with npm for this Express API.
◌  I’m installing the server-side Node.js SDK with npm for this Express API.
│  Allowing bash command: npm install posthog-node
◇  I’m verifying the resolved dependency declaration and generated lockfile.
◌  I’m verifying the resolved dependency declaration and generated lockfile.
◇  I’m recording the completed SDK installation for the next workflow step.
◌  I’m recording the completed SDK installation for the next workflow step.
◌  [1/8] Initialize PostHog
◇  Adding the server SDK singleton and environment configuration; no CSP is present because this is an API-only Express service.
◌  Adding the server SDK singleton and environment configuration; no CSP is present because this is an API-only Express service.
◇  Resolving the Node-specific environment variable convention after the configuration tool rejected a nonstandard token key.
◌  Resolving the Node-specific environment variable convention after the configuration tool rejected a nonstandard token key.
◇  Configuring the documented Node environment keys and creating the singleton module that the Express entry loads once.
◌  Configuring the documented Node environment keys and creating the singleton module that the Express entry loads once.
◇  Wiring the process-wide PostHog singleton into the Express startup path and documenting its configuration keys.
◌  Wiring the process-wide PostHog singleton into the Express startup path and documenting its configuration keys.
◇  Verifying the initialization wiring and environment-key presence without running build or test commands.
◌  Verifying the initialization wiring and environment-key presence without running build or test commands.
◇  Publishing the initialization handoff with the singleton access pattern and configuration details for subsequent instrumentation work.
◌  Publishing the initialization handoff with the singleton access pattern and configuration details for subsequent instrumentation work.
◌  [2/8] Add user identification
◌  [2/8] Add user identification · Capture unhandled errors
◇  I’m reviewing the identification workflow and the Express app’s auth boundaries before making a targeted change.
◌  I’m reviewing the identification workflow and the Express app’s auth boundaries before making a targeted change.
◇  Reviewing the prescribed SDK error-tracking guidance and current server entry point.
◌  Reviewing the prescribed SDK error-tracking guidance and current server entry point.
◇  Checking the Node and Error Tracking reference patterns before adding the centralized Express handler.
◌  Checking the Node and Error Tracking reference patterns before adding the centralized Express handler.
◇  I confirmed this is a backend-only Express API; I’m checking the identification reference before concluding whether an auth boundary exists.
◌  I confirmed this is a backend-only Express API; I’m checking the identification reference before concluding whether an auth boundary exists.
◇  Adding PostHog’s official Express error-handler integration at application setup.
◌  Adding PostHog’s official Express error-handler integration at application setup.
◇  I found no authentication, account, session, or user identifier in this API, so no safe identification boundary exists to instrument.
◌  I found no authentication, account, session, or user identifier in this API, so no safe identification boundary exists to instrument.
◌  [2/8] Capture unhandled errors
◌  [2/8] Capture unhandled errors · Instrument key events
◇  Recording the completed error-tracking handoff.
◌  Recording the completed error-tracking handoff.
◌  [3/8] Instrument key events
◇  I’m reviewing the capture workflow and the existing API routes to instrument meaningful todo actions.
◌  I’m reviewing the capture workflow and the existing API routes to instrument meaningful todo actions.
◇  I found three meaningful, unauthenticated todo mutations; I’m checking existing event conventions and the server SDK’s personless capture form before recording the plan.
◌  I found three meaningful, unauthenticated todo mutations; I’m checking existing event conventions and the server SDK’s personless capture form before recording the plan.
◇  I’m verifying the installed SDK method signature so the unauthenticated route events remain personless without fabricating an identity.
◌  I’m verifying the installed SDK method signature so the unauthenticated route events remain personless without fabricating an identity.
◇  I’m recording the three core mutation events, then I’ll add guarded, personless captures immediately after each successful mutation.
◌  I’m recording the three core mutation events, then I’ll add guarded, personless captures immediately after each successful mutation.
◇  I’m updating the Express mutation handlers with minimal guarded captures and non-PII outcome properties.
◌  I’m updating the Express mutation handlers with minimal guarded captures and non-PII outcome properties.
◇  I’ve added the event captures; I’m verifying the final handlers and the recorded event contract without running tests.
◌  I’ve added the event captures; I’m verifying the final handlers and the recorded event contract without running tests.
◌  [4/8] Review and verify integration
◌  [4/8] Review and verify integration · Build product insights
◇  Loading the verification rules and upstream changeset handoffs before reviewing or installing.
◌  Loading the verification rules and upstream changeset handoffs before reviewing or installing.
◇  Reading the dashboard, insight, and MCP workflows before creating analytics assets.
◌  Reading the dashboard, insight, and MCP workflows before creating analytics assets.
◇  Inspecting the PostHog creation schemas, then I’ll create the dashboard and attached todo insights.
◌  Inspecting the PostHog creation schemas, then I’ll create the dashboard and attached todo insights.
◇  Creating the starter dashboard before attaching event-based operational insights.
◌  Creating the starter dashboard before attaching event-based operational insights.
◇  Reading each review file once, checking configured environment keys safely, and detecting the package manager before installation.
◌  Reading each review file once, checking configured environment keys safely, and detecting the package manager before installation.
◇  Installing the declared dependency set with the detected npm package manager; the manifest defines no build, typecheck, or lint scripts.
◌  Installing the declared dependency set with the detected npm package manager; the manifest defines no build, typecheck, or lint scripts.
│  Allowing bash command: npm install
◇  Adding three 30-day trend views for todo creation, update, and deletion activity.
◌  Adding three 30-day trend views for todo creation, update, and deletion activity.
◇  Dashboard creation is complete with four attached event-based insights.
◌  Dashboard creation is complete with four attached event-based insights.
◌  [5/8] Review and verify integration
◇  Checking the repository’s existing environment-file convention before fixing the two runtime wiring issues found in review.
◌  Checking the repository’s existing environment-file convention before fixing the two runtime wiring issues found in review.
◇  Adding the minimal dotenv loader dependency so the configured `.env` values actually initialize PostHog during normal local startup.
◌  Adding the minimal dotenv loader dependency so the configured `.env` values actually initialize PostHog during normal local startup.
◇  Installing dotenv with npm after confirming the manifest and lockfile state.
◌  Installing dotenv with npm after confirming the manifest and lockfile state.
│  Allowing bash command: npm add dotenv
◇  Re-reading the two source files immediately before targeted runtime-wiring edits.
◌  Re-reading the two source files immediately before targeted runtime-wiring edits.
◇  Applying two focused fixes: load configured env values before SDK construction, and register Express error tracking after routes so thrown route errors reach it.
◌  Applying two focused fixes: load configured env values before SDK construction, and register Express error tracking after routes so thrown route errors reach it.
◇  Re-reading the Express entrypoint immediately before relocating its error middleware.
◌  Re-reading the Express entrypoint immediately before relocating its error middleware.
◇  Relocating the official Express error handler without changing any event contract.
◌  Relocating the official Express error handler without changing any event contract.
◇  Publishing the verification handoff: installation succeeded, two review defects were fixed, and the project defines no build, typecheck, or lint command to run.
◌  Publishing the verification handoff: installation succeeded, two review defects were fixed, and the project defines no build, typecheck, or lint command to run.
◇  Completing the task with the reviewed changeset and verification evidence.
◌  Completing the task with the reviewed changeset and verification evidence.
◌  [6/8] Report the integration
◇  Reviewing the reporting workflow records and notebook instructions before composing the final integration handoff.
◌  Reviewing the reporting workflow records and notebook instructions before composing the final integration handoff.
◇  Preparing the recorded integration report and loading the notebook-creation guidance required for the shareable in-app copy.
◌  Preparing the recorded integration report and loading the notebook-creation guidance required for the shareable in-app copy.
◇  Publishing the complete recorded setup summary, with unconfirmed runtime delivery explicitly separated from completed code and configuration work.
◌  Publishing the complete recorded setup summary, with unconfirmed runtime delivery explicitly separated from completed code and configuration work.
◇  Mirroring the published report into a shareable PostHog notebook using the same recorded findings and caveats.
◌  Mirroring the published report into a shareable PostHog notebook using the same recorded findings and caveats.
└  PostHog set up: 7/7 steps completed (1 skipped as not required).
EXIT=0
Standalone agent test, 11 cases, @ui mocked to throw
✓  runs to success with an observer and an answerer 3ms
✓  runs to a complete result with no options at all 0ms
✓  installs no bridge in CI even with an answerer, as before 0ms
✓  returns an agent abort as a decided failure with the matched case 1ms
✓  returns a coded failure for a harness error 0ms
✓  passes a harness-decided failure through untouched 0ms
✓  skips the terminal outro and the shutdown for a composed sub-run 0ms
✓  finishes when the observer throws on every event 0ms
✓  calls the bound hooks with the run credentials 1ms
✓  returns a crash as a result instead of rejecting 1ms
✓  is cancelled by a signal that is already aborted 0ms
Tests  11 passed (11)
known-violations.json, 72 → 60

Removed edges are the program files that imported ProgramRun and friends from the agent, plus the agent's one src/ui import. Added edges are the adapter and the two moved tables reaching back into the agent.

-    "src/lib/agent/mcp-prompt-streaming.ts -> src/ui/tui/services/mcp-suggested-prompts-services.ts",
-    "src/lib/detection/project-scope.ts -> src/lib/agent/runner/shared/authenticate.ts",
-    "src/lib/programs/agent-skill/index.ts -> src/lib/agent/agent-runner.ts",
-    "src/lib/programs/audit/detect.ts -> src/lib/agent/agent-runner.ts",
-    "src/lib/programs/audit/index.ts -> src/lib/agent/agent-runner.ts",
+    "src/lib/programs/bindings.ts -> src/lib/agent/runner/switchboard/index.ts",
-    "src/lib/programs/error-tracking-upload-source-maps/detect.ts -> src/lib/agent/agent-runner.ts",
-    "src/lib/programs/error-tracking-upload-source-maps/index.ts -> src/lib/agent/agent-runner.ts",
-    "src/lib/programs/error-tracking/index.ts -> src/lib/agent/runner/shared/types.ts",
-    "src/lib/programs/events-audit/index.ts -> src/lib/agent/agent-runner.ts",
-    "src/lib/programs/mcp-analytics/index.ts -> src/lib/agent/agent-runner.ts",
-    "src/lib/programs/migration/index.ts -> src/lib/agent/agent-runner.ts",
-    "src/lib/programs/posthog-integration/index.ts -> src/lib/agent/runner/shared/bootstrap.ts",
-    "src/lib/programs/program-step.ts -> src/lib/agent/agent-runner.ts",
+    "src/lib/programs/program-run.ts -> src/lib/agent/runner/shared/types.ts",
-    "src/lib/programs/replay-vision/index.ts -> src/lib/agent/agent-runner.ts",
-    "src/lib/programs/revenue-analytics/detect.ts -> src/lib/agent/agent-runner.ts",
-    "src/lib/programs/self-driving/detect.ts -> src/lib/agent/agent-runner.ts",
-    "src/lib/programs/self-driving/index.ts -> src/lib/agent/agent-runner.ts",
+    "src/lib/programs/run-agent-legacy.ts -> src/lib/agent/agent-interface.ts",
+    "src/lib/programs/run-agent-legacy.ts -> src/lib/agent/claude-settings.ts",
+    "src/lib/programs/run-agent-legacy.ts -> src/lib/agent/progress.ts",
+    "src/lib/programs/run-agent-legacy.ts -> src/lib/agent/runner/index.ts",
+    "src/lib/programs/run-agent-legacy.ts -> src/lib/agent/runner/switchboard/index.ts",
+    "src/lib/programs/run-agent-legacy.ts -> src/lib/yara-hooks.ts",
-    "src/lib/programs/self-driving/prompt.ts -> src/lib/agent/agent-runner.ts",
-    "src/lib/programs/warehouse-source/detect.ts -> src/lib/agent/agent-runner.ts",
-    "src/lib/programs/warehouse-source/index.ts -> src/lib/agent/agent-runner.ts",
-    "src/lib/programs/web-analytics-doctor/detect.ts -> src/lib/agent/agent-runner.ts",
+    "src/ui/wizard-ui.ts -> src/lib/agent/progress.ts",
Full suite tail
Test Files  184 passed (184)
     Tests  3116 passed (3116)

No snapshot or fixture file changed: frames, keyboard pairs, flow traces, post-auth gates, commandments, credential isolation all byte-identical.

@gewenyu99

Copy link
Copy Markdown
Collaborator Author

Superseded by a trimmed cut of the same change on posthog/functional-a1-min: 39 files instead of 88, moves and enforcement deferred to A2′.

@gewenyu99 gewenyu99 closed this Sep 21, 2026
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.

1 participant