Working with the source alpha
A small guide to
real experiments.
Start with the bundled replay, then bring a reviewed local Git product. These commands describe implemented behavior and expose the current limits.
Quick start
The reproducible entry point is the source build. Use Git, stable Rust/Cargo, Node.js 22+ and pnpm 10. Build the dashboard before installing so release-mode RustEmbed includes the current assets.
git clone https://github.com/OthmaneBlial/GrowthLab.git
cd GrowthLab
pnpm -C ui install --frozen-lockfile
pnpm -C ui build
cargo install --path . --bin growthlab --locked
growthlab demoOn macOS, configured validation requires /usr/bin/sandbox-exec. Its runtime policy has passed local checks on the development host. Linux requires /usr/bin/bwrap and permitted unprivileged namespaces; native Linux runtime behavior is still unverified. Windows validation isolation is not implemented.
This is a source alpha. A passing macOS build does not establish Linux or Windows runtime support, provider authorization, signing, notarization or production readiness. Check any published prerelease notes for its exact platform and limits.
For an uninstalled source checkout, replace growthlab with cargo run --locked --bin growthlab --. The retained orx binary is a compatibility entry point; public workflows use growthlab.
growthlab demo --no-browserThe demo prints a loopback URL and keeps its server running until Ctrl-C. No Docker, agent API key or provider request is required by this declared replay.
Download and verify
GrowthLab ships source first. The current v0.1.0-alpha.20 source prerelease includes a manually validated macOS arm64 CLI archive plus macOS x86_64, Linux x86_64 musl, Linux arm64 musl and Windows x86_64 GNU archives. The public release now also carries cargo-dist-compatible names, checksums, and shell/PowerShell installers; the read-only verifier checks all ten archive/checksum pairs and the local macOS shell-install smoke passed. All are unsigned and not notarized; Linux and Windows runtime and installer proof remain pending.
scripts/package-cli-archive.sh
scripts/verify-release-archive.sh dist/archives/growthlab-v0.1.0-alpha.20-macos-arm64.tar.gzThe archive verifier is offline. It checks the checksum, rejects traversal and unexpected links, requires the MIT, OpenResearch and dependency notices, and executes the binary only when the target matches the current machine. See the distribution guide ↗ for the target matrix and release limits.
The bundled demo
growthlab demo creates an original fictional PatchKit homepage, a private local Git baseline and three competitor worktrees. Its proposals are declared replay input. The edits, commits, command execution and sealed evidence are real.
| Competing approach | Structure / links / claims | Review status |
|---|---|---|
| Outcome-first positioning | Exit 0 / 0 / 0 | Eligible |
| Proof beside the promise | Exit 2 / 0 / 0 | Ineligible: primary heading removed |
| Faster first success | Exit 0 / 0 / 0 | Eligible |
The intended heading failure makes the overall battle status failed. It does not discard the two eligible alternatives. Missing prerequisites or interrupted execution can produce different results; those actual outcomes stay visible.
Open individual check fractions, inspect logs and change records, and review the candidate source and archive digests. No candidate is automatically selected or applied. The demo retains only its newly owned fictional repositories and evidence under the active data root for inspection.
How to read it: replay proposals are SIMULATED, deterministic checks are OBSERVED, and growth outcomes are UNTESTED. These fixture commands are not accessibility certification, performance scores or conversion evidence. The same experiment loop applies to onboarding, pricing and launch work.
Audit one page
Review one local HTML page or one public HTTPS page without preparing a battle. Both paths use the same explainable SEO page-hygiene rubric shown in the dashboard.
growthlab seo-audit --html ./website/index.html
growthlab seo-audit --html ./website/index.html --format markdown
growthlab seo-audit --url https://example.com/pricing --format markdownThe result exposes eight structural dimensions: title, description, headings, language, useful copy, canonical URL, useful links and image descriptions. Every score is ESTIMATED and tied to direct observations. Partial or missing signals include concrete next steps for the page review. Battle comparisons also show a separate 30-point Page quality hints record for mobile viewport, named controls, form labels, loading sources and claim guardrails. It is source-level guidance, not a Lighthouse score, timing trace, screen-reader audit or accessibility certification.
URL analysis is read-only: it checks same-origin robots.txt, makes one bounded HTTPS request, follows no redirects and sends no credentials. Local files are regular UTF-8 inputs up to 4 MiB. Neither path claims rankings, traffic, conversions, accessibility certification or performance results.
Review a public repository
Inspect one canonical GitHub URL before you bring product context locally. The review reports public description, default branch, license and archive/fork flags as OBSERVED metadata. After reviewing it, you can explicitly clone into a new local folder and register a workspace; an existing growthlab.yaml is preserved, and a missing contract can be supplied locally.
growthlab repo-audit --url https://github.com/owner/product --format markdownThe request is unauthenticated, bounded, read-only and redirect-free. Credentials, query strings, fragments, non-GitHub hosts and .git URLs are refused. No source files are cloned, executed or registered by the review. For an explicit checkout, use growthlab workspace import-url --url https://github.com/owner/product --path ./product; the destination must be new, no push occurs, and any generated contract is committed only locally. For a starting context without a checkout, use growthlab workspace brief --name … --audience … --goal …; the generated workspace remains local and analysis-only.
Repository metadata is not product, market or growth evidence. GrowthLab does not infer stars, traffic, adoption, rankings, conversion or revenue.
Measure locally
Summarize a user-supplied CSV export without contacting an analytics provider. Each row is one numeric observation; variant and value are required, while metric, distribution and timestamp are optional.
growthlab measure --csv ./telemetry.csv --format markdown
growthlab measure --csv ./telemetry.csv --baseline control --metric qualified_signupThe report exposes means, sample sizes, totals, arithmetic differences from the supplied baseline, an optional date range and exploratory 95% intervals when samples allow. A distribution or channel column keeps each source baseline separate; without it, rows use the all distribution. Use the same summary in the dashboard's Measure locally panel or from the CLI. It is labelled MEASURED because the values come from your file; it does not establish attribution, causality, statistical significance, rankings, traffic, revenue or conversion lift.
The importer is local and bounded: regular UTF-8 files up to 8 MiB, quoted CSV fields, limited rows and columns, no network request. A missing timestamp or baseline is reported as a limitation rather than filled with invented data.
Choose a growth angle
GrowthLab includes ten reusable role contracts for focused growth work: strategist, researcher, positioning, conversion, ethical SEO, onboarding, pricing, launch, evaluator and skeptic.
| Role | Focus | Output |
|---|---|---|
| Strategist | Choose a tractable growth question | Brief, hypothesis tree and decision rule |
| Researcher | Collect permitted facts | Evidence records and claim map |
| Positioning | Make value easy to understand | Messages and claim checklist |
| Conversion | Remove uncertainty before action | Page hierarchy and CTA alternatives |
| SEO | Match useful pages to search intent | Intent brief and local audit steps |
| Onboarding | Shorten the path to first value | First-value map and quick start |
| Pricing | Explore packaging safely | Value hypotheses and guardrails |
| Launch | Prepare a truthful channel narrative | Drafts, proof links and checklist |
| Evaluator | Apply a stable rubric | Inspectable scores and rationale |
| Skeptic | Try to falsify the claim | Counter-hypotheses and evidence gaps |
Read the catalog without side effects, or run a role contract inside a registered workspace. growthlab playbook run <project-id> seo --answer "Qualified developer visitors" and POST /api/growth/workspaces/{id}/playbooks/{role} save an inspectable local run with ordered answers, outputs and guardrails. Missing answers stay Unknown; every run is UNTESTED with low confidence. No provider, analytics, product file or publication is touched.
Bring your product
Import supports a local Git repository root with a checked-out branch and committed context, or a local folder with the explicit --init-git option. Public repository review and manual briefs are available from Home. repo-audit reads one unauthenticated GitHub metadata response without cloning or executing source; workspace brief creates a private local analysis snapshot with no remote or provider request.
Create an implementation contract with explicitly allowed paths and real validation commands. init atomically creates a new file and refuses to overwrite one.
growthlab init --path /path/to/product \
--name Acme --audience 'Open-source maintainers' \
--goal 'Increase qualified signups' \
--mode implementation --allow website/ \
--deny infra/production/ \
--validate 'pnpm test' --validate 'pnpm build'
growthlab config check --path /path/to/productReview growthlab.yaml before importing. Secrets never belong in this file. Existing Git repositories require the on-disk configuration to agree with the committed one. For a non-Git folder, opt into a local snapshot explicitly:
growthlab workspace import --path /path/to/product
# only for a folder without Git
growthlab workspace import --path /path/to/product --init-git
growthlab workspace list
growthlab workspace view <project-id>
growthlab hypotheses <project-id>The explicit option creates one local main commit after rejecting protected paths such as credentials and .env; it configures no remote and never auto-commits an existing repository. Initial hypothesis templates are UNTESTED and low confidence; they are not proof that a native agent or external researcher ran.
The experiment map groups hypotheses by role and keeps each persisted hypothesisId visible through battle comparisons and exported reports, so a reviewer can follow the same branch from idea to archived evidence.
Permission modes
| Mode | What it permits |
|---|---|
analyze_only | No product file changes. |
draft | Lab artifacts; no product file changes. |
implementation | Only allowed paths, in isolated competitor worktrees. Requires an allowed path and a validation command. |
| Selected apply | A separate explicit delivery action. Configuration never grants automatic product push or deployment. |
Allowed and denied paths are relative prefixes, not globs. Denials win. Traversal, absolute paths, symlinks, .git, credential files and protected namespaces are refused.
Run and compare
Battle preparation freezes one imported commit, configuration and validation contract. Three lab-owned branches and worktrees start from that same source. Continuing to work on your product does not move an existing battle’s baseline.
growthlab battle 'Improve qualified activation' \
--project <project-id> --prepare-only
growthlab experiments --project <project-id>
growthlab battle-status <battle-id>Use the bundled demo first. For your own deterministic replay, the plan is a versioned JSON file containing exactly three ordered implementations with summaries, allowed file edits and stated risks. The full battle guide documents its schema and conservative size limits.
growthlab run <battle-id> --replay /path/to/plan.json
growthlab battle-status <battle-id>
growthlab compare <battle-id>Configured commands execute against content-addressed immutable candidate source archives, with bounded logs and enforced timeouts. They do not run against a mutable agent checkout. The command pass fraction is individually inspectable; eligibility requires every exact command to pass on one successful sealed attempt.
Terminal battles are not silently rerun or overwritten. Make a new battle for a new attempt. Inspect battle status even when orchestration exits zero: a failed configured command is part of the recorded outcome.
Native-agent status: the inherited registry preserves Claude Code, Codex, OpenCode and Cursor adapters. Current strict tools-disabled proposal capability is declared only by Claude Code. Native battle execution is unverified in this environment; adapter detection does not prove provider support.
Static previews
Opt in for a static landing page before preparing a battle. root is relative to the product repository; entry is relative to that root and ends in .html.
static_preview:
root: website
entry: index.htmlThe CLI also accepts --preview-root website --preview-entry index.html on init. Review and commit the contract before import. The bundled demo already opts in.
After implementation is committed, Rust archives permitted candidate Git objects, a self-contained document and source metadata. The dashboard’s Static preview tab displays that verified document at desktop 1280 × 900 or phone 390 × 844 CSS dimensions, scaled to fit the inspector. When a local Chromium-compatible browser is available, the engine also archives verified desktop and phone PNGs at preview/screenshot-desktop.png and preview/screenshot-phone.png with their dimensions, sizes and SHA-256 values in the metadata. It records optional renderChecks for viewport coverage, visible text length, horizontal overflow and local navigation/paint timings; these are OBSERVED inspection traces of the sanitized document, not Lighthouse, Core Web Vitals, accessibility, visual-regression, real-user or growth evidence. Sealed comparison rows summarize them with the decomposable static-render-hints-v1 rubric when both viewports are available, plus the browser-timing-hints-v1 rubric when timing entries are present. The timing rubric is a local heuristic; when file:// exposes no paint entry, first paint uses a first-rendered-frame proxy.
- Supported sources: HTML, CSS, PNG, JPEG, GIF, WebP, WOFF and WOFF2.
- Limits: 128 source files, 4 MiB per file, 8 MiB total source and a 4 MiB packaged document.
- Scripts, frames, forms, event handlers and navigation are removed. External, unsupported and cyclic resources are omitted.
- A restrictive archived CSP and an opaque, inert frame with an empty sandbox prevent interaction and script execution.
- Missing, denied, oversized or unsafe input records an unavailable preview. No render is fabricated.
This is a live browser view of archived static source. A captured PNG is a render artifact, not a visual quality result or measured growth outcome. It shows one viewport; content below the fold can be clipped. Dynamic apps, SVG assets and CSS image-set() string sources are not reproduced. Preview availability does not change candidate eligibility.
Selected delivery
Delivery uses a verified, eligible sealed candidate. A failed candidate cannot be selected, exported or applied. An explicit selection records your decision; it does not change product files.
growthlab compare <battle-id>
growthlab select <variant-id>
growthlab apply <variant-id> --checkApply preview lists changed paths and the patch digest without modifying the product. Actual apply requires the frozen source HEAD, unchanged configuration and a clean ordinary checkout/index. Dirty, staged, untracked, sparse, symlink, changed-policy and changed-baseline states are refused.
growthlab apply <variant-id>
# Review the resulting product diff before committing it yourself.GrowthLab does not automatically commit, merge, push or deploy. Apply copies only the selected patch to the product working tree. You review it and use your normal Git workflow.
growthlab export <variant-id> \
--output /path/outside/product/selected.patchExport uses exact committed objects verified against sealed artifacts. Mutable variant branches cannot supply its contents. The parent directory must exist, the destination must be new and outside product/variant checkouts. Existing files and dangling symlinks are refused; Unix output files are owner-private.
Private reports
HTML and Markdown reports are self-contained offline summaries. They include actual command failures, eligibility, selected candidate, diffs, provenance and reproducibility digests. Default reports withhold private names, goals, paths, model identifiers, prompt text, command text and raw logs.
growthlab report <battle-id> \
--output /path/outside/product/battle.html
growthlab report <battle-id> --format markdown \
--output /path/outside/product/battle.mdA report never changes selection. It works offline without external fonts, JavaScript or network requests. Tampered evidence refuses generation. Create-only owner-private file output follows the same rules as patch export.
Disclose context intentionally
--public-goal discloses only a goal you explicitly provide. --include-context approves disclosure of configured goals, variant titles, implementation summaries and command text; review that exported file before sharing. Full prompts and raw logs are never copied. --without-attribution removes the optional footer.
growthlab report <battle-id> --output battle.html \
--public-goal 'Compare three activation approaches'Visual privacy: reports do not include candidate source documents or renderings by default. The local candidate inspector exposes verified desktop and phone PNGs when browser capture succeeds; pass --include-visuals to the CLI or includeVisuals=true to the report API when you explicitly want those archived captures embedded. Documentation screenshots are separate from run archives.
Read the evidence
A useful experiment explains how it knows what it knows. These provenance categories remain distinct in domain records and exported results.
- MEASURED
- Computed from connected real telemetry. The current demo has no such outcome data.
- OBSERVED
- Produced by a deterministic check or direct inspection, such as an actual exit code or verified page view.
- ESTIMATED
- A model or rubric estimate with stated assumptions. It is not an objective measurement.
- SIMULATED
- A declared simulation, such as the demo’s ordered replay proposals.
- UNTESTED
- No outcome evidence yet. This remains the growth-outcome status of current replay candidates.
Passing all configured commands makes a candidate eligible for review. A command pass fraction does not establish copy clarity, accessibility, performance or conversion lift. Multiple eligible candidates require your judgment; there is no unexplained aggregate score or measured Winner.
Sealed archives bind the frozen contract, proposal context, candidate changes, command logs and policy metadata with SHA-256 digests. Readers verify archived evidence rather than trusting mutable checkout content. Raw CLI JSON and local archives can contain private product context; sanitized report exports are the sharing boundary.
Cancel and recover
Cancellation persists intent for the active battle. Failed and cancelled attempts remain inspectable.
growthlab battle-status <battle-id> --cancelExplicit recovery acquires the controller lease and verifies retained checkpoints and seals. It never reruns a provider or validation command, resets a worktree or applies a patch.
growthlab battle-status <battle-id>
growthlab recover <battle-id>
growthlab compare <battle-id>When a registered command is still alive, recovery records waiting. Repeat after that same job ends. An interrupted attempt cannot become eligible just because a recovered command exited zero. Complete terminal checkpoints may recover their exact original seals; previously sealed siblings remain unchanged.
Unknown or incompletely registered launchers keep termination unverified. Stronger registration and interrupted selected-delivery recovery remain gates. Recovery does not guess or kill unrelated processes.
Safety and limits
Default implementation never authorizes production deployment, advertising purchases, email or social messages, live pricing/billing changes, production analytics mutations, repository pushes or customer-data access.
Local data
Default product data is under $XDG_DATA_HOME/growthlab or ~/.local/share/growthlab. Settings use the corresponding GrowthLab configuration namespace. GROWTHLAB_DATA_DIR can explicitly choose another data root. Existing OpenResearch defaults are not silently moved or reused.
Upstream telemetry is disabled in source builds. The upstream updater is refused. The inherited openresearch.sh companion is not a GrowthLab service; local product data is not redirected to it.
Validation isolation
Commands require a supported OS driver, can write their candidate snapshot and private scratch, and receive only approved read-only runtimes. Host network access and unrelated product data are blocked. Exact confinement policy digests accompany observed checks.
| Platform | Current evidence |
|---|---|
| macOS | Local runtime checks passed using /usr/bin/sandbox-exec. Future OS compatibility is not promised. |
| Linux | Bubblewrap implementation exists; native runtime verification is pending. User/network namespaces must be permitted. |
| Windows | Validation isolation is not implemented; validation is refused. |
Configured validation dependencies must already be available offline in permitted paths. There is no CPU, memory or disk quota and no unrestricted execution fallback. A missing driver is refused; driver presence alone does not prove kernel permission or successful isolation.
Build with us
Use the repository’s dev-slot helper for isolated local development data, ports and owned processes. Its status prints the actual backend and dashboard URLs.
node scripts/dev-slot.mjs start --db empty
node scripts/dev-slot.mjs status
node scripts/dev-slot.mjs stopAll six GrowthLab GitHub Actions workflows are manually disabled at the user’s request. Run relevant formatting, Rust, UI and real CLI checks locally. Keep the committed ui/dist current after UI changes.
cargo fmt --all -- --check
cargo test --locked
cargo clippy --all-targets -- -D warnings
pnpm -C ui build
cargo build --locked
python3 scripts/test-growth-demo.py target/debug/growthlabThe overall project estimate is about 95%, subjectively assessed against the full specification. Progress changes when behavior or verification changes; a source scaffold or passing test suite is not a complete-product claim.
Next work includes provider adapters, full visual regression/accessibility evaluation, native-agent verification, dynamic rubric evidence mapping, and broader target-platform release proof.