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
25 changes: 23 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,10 @@ jobs:

build-test:
name: Manual Package & Binary for ${{ matrix.platform }}
if: ${{ github.event_name == 'workflow_dispatch' }}
# This owner-triggered job intentionally uses the canonical public capture
# token so a pre-release artifact can be tested end-to-end. Fork and PR
# packaging behavior is covered by the tokenless and synthetic unit tests.
if: ${{ github.event_name == 'workflow_dispatch' && github.actor == github.repository_owner }}
runs-on: ${{ matrix.runner }}
needs: [lint, test]
strategy:
Expand All @@ -234,7 +237,7 @@ jobs:
# schedules on arm64 hardware in this org, so PyInstaller fails with
# IncompatibleBinaryArchError. This matches the release matrix, which
# dropped macos-x64 in v0.4.1 (PR #66); x64 macOS installs from
# source or the release wheel (docs/install-binaries.md).
# source or the release wheel (docs/operations/install-binaries.md).
- runner: macos-15
platform: macos-arm64

Expand All @@ -248,18 +251,36 @@ jobs:
python-version: ${{ env.PYTHON_VERSION }}
poetry-version: ${{ env.POETRY_VERSION }}

- name: Stage public telemetry build configuration
env:
POSTHOG_PUBLIC_CUSTOMER_API_TOKEN: ${{ secrets.POSTHOG_PUBLIC_CUSTOMER_API_TOKEN }}
run: python3 scripts/embed_posthog_token.py --write

- name: Build package
run: make package

- name: Verify package telemetry configuration
env:
POSTHOG_PUBLIC_CUSTOMER_API_TOKEN: ${{ secrets.POSTHOG_PUBLIC_CUSTOMER_API_TOKEN }}
run: >-
poetry run python scripts/verify_embedded_telemetry_artifact.py
--expected-token-env POSTHOG_PUBLIC_CUSTOMER_API_TOKEN
dist/*.whl dist/*.tar.gz

- name: Build kickstart binary
run: make binary

- name: Name, smoke-test, and archive binary
env:
EXPECT_EMBEDDED_TELEMETRY: "1"
PLATFORM: ${{ matrix.platform }}
PYTHON_MINOR: ${{ env.PYTHON_VERSION }}
run: scripts/ci/name-and-smoke-binary.sh "${PLATFORM}" "${PYTHON_MINOR}"

- name: Clear staged public telemetry build configuration
if: ${{ always() }}
run: python3 scripts/embed_posthog_token.py --clear

- name: Upload build artifacts
uses: actions/upload-artifact@v4
with:
Expand Down
36 changes: 36 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,11 @@ jobs:
- name: Verify release version
run: make release-check TAG="$GITHUB_REF_NAME"

- name: Verify public telemetry build token
env:
POSTHOG_PUBLIC_CUSTOMER_API_TOKEN: ${{ secrets.POSTHOG_PUBLIC_CUSTOMER_API_TOKEN }}
run: python3 scripts/embed_posthog_token.py --check

- name: Set up Python + Poetry
uses: ./.github/actions/setup-python-poetry
with:
Expand Down Expand Up @@ -82,9 +87,26 @@ jobs:
python-version: ${{ env.PYTHON_VERSION }}
poetry-version: ${{ env.POETRY_VERSION }}

- name: Stage public telemetry build configuration
env:
POSTHOG_PUBLIC_CUSTOMER_API_TOKEN: ${{ secrets.POSTHOG_PUBLIC_CUSTOMER_API_TOKEN }}
run: python3 scripts/embed_posthog_token.py --write

- name: Build package
run: make package

- name: Verify package telemetry configuration
env:
POSTHOG_PUBLIC_CUSTOMER_API_TOKEN: ${{ secrets.POSTHOG_PUBLIC_CUSTOMER_API_TOKEN }}
run: >-
poetry run python scripts/verify_embedded_telemetry_artifact.py
--expected-token-env POSTHOG_PUBLIC_CUSTOMER_API_TOKEN
dist/*.whl dist/*.tar.gz

- name: Clear staged public telemetry build configuration
if: ${{ always() }}
run: python3 scripts/embed_posthog_token.py --clear

- name: Upload package artifact
uses: actions/upload-artifact@v4
with:
Expand Down Expand Up @@ -122,15 +144,25 @@ jobs:
python-version: ${{ matrix.python-version }}
poetry-version: ${{ env.POETRY_VERSION }}

- name: Stage public telemetry build configuration
env:
POSTHOG_PUBLIC_CUSTOMER_API_TOKEN: ${{ secrets.POSTHOG_PUBLIC_CUSTOMER_API_TOKEN }}
run: python3 scripts/embed_posthog_token.py --write

- name: Build kickstart binary
run: make binary

- name: Name, smoke-test, and archive binary
env:
EXPECT_EMBEDDED_TELEMETRY: "1"
PLATFORM: ${{ matrix.platform }}
PYTHON_MINOR: ${{ matrix.python-version }}
run: scripts/ci/name-and-smoke-binary.sh "${PLATFORM}" "${PYTHON_MINOR}"

- name: Clear staged public telemetry build configuration
if: ${{ always() }}
run: python3 scripts/embed_posthog_token.py --clear

- name: Upload binary artifact
uses: actions/upload-artifact@v4
with:
Expand Down Expand Up @@ -206,6 +238,10 @@ jobs:
pip install ./kickstart-*-py3-none-any.whl
```

Release wheels and binary archives enable pseudonymous telemetry by default for eligible CLI commands. The first eligible event creates a random UUIDv4 that remains stable across upgrades. Events use closed, data-minimized property sets. Run `kickstart telemetry disable` to persist an opt-out; `kickstart telemetry status` is read-only and does not create an ID or send an event.

To prevent an installer-invoked event before a persisted preference exists, set `KICKSTART_TELEMETRY_DISABLED=1` or `DO_NOT_TRACK=1` for that process. A direct Git source install has no embedded capture configuration; delivery from one requires `POSTHOG_PUBLIC_CUSTOMER_API_TOKEN` in the process environment, and a token never overrides an opt-out.

### Manual binary install

Binary archives are attached for `linux-x64`, `linux-arm64`, and `macos-arm64` (Python 3.14). Pick the asset for your platform, extract it, and run `kickstart install` to place the binary payload in a user-writable directory and configure `PATH`:
Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ __pycache__/
*.pyc
*.log
.venv/
/.env
/.env.*
!/.env.example
.mypy_cache/
.claude/settings.local.json
/kickstart
Expand Down
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,14 @@ pipx install git+https://github.com/woud420/kickstart # from source
pip install ./kickstart-<version>-py3-none-any.whl # wheel from the Releases page
```

### Telemetry

Release wheels and binary archives enable pseudonymous telemetry by default for eligible CLI commands. The first eligible event creates a random UUIDv4 in the user configuration directory; it remains stable across CLI upgrades. Events use closed, data-minimized property sets and never include project names, paths, command arguments, generated content, or arbitrary error text.

Run `kickstart telemetry disable` to persist an opt-out. `kickstart telemetry status` is read-only and does not create an ID or send an event. To prevent an installer-invoked event before that preference exists, set `KICKSTART_TELEMETRY_DISABLED=1` or `DO_NOT_TRACK=1` for the install process; the binary installation runbook includes exact examples.

A direct Git source install has no embedded capture configuration; delivery from one requires `POSTHOG_PUBLIC_CUSTOMER_API_TOKEN` in the process environment. A token never overrides an opt-out. See the [telemetry contract](docs/contracts/telemetry.md) and [binary installation runbook](docs/operations/install-binaries.md) for the exact event allowlist and controls.

## Get Started

```bash
Expand Down
3 changes: 2 additions & 1 deletion docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
- [Agent Map](../AGENTS.md): repo-local map for agents modifying kickstart itself.
- [Architecture](architecture/README.md): canonical architecture entrypoint for kickstart itself.
- [Contracts](contracts/README.md): public and generated-output contracts.
- [Pseudonymous CLI Telemetry](contracts/telemetry.md): default-on policy, persistent opt-out, identity, lifecycle events, and data-minimization contract.
- [Scaffold Contract](scaffold-contract.md): generated docs, metadata, and option vocabulary.
- [Decisions](decisions/README.md): durable project decisions.
- [CLI Framework Research](decisions/cli-framework-research.md): sourced recommendation for Rust, Python, and TypeScript CLI framework defaults.
Expand All @@ -13,6 +14,6 @@
- [Contributing](contributing.md): human contribution workflow.
- [Agent Contributing](agent-contributing.md): agent-safe development workflow.
- [Release Policy](release-policy.md): version tags, release assets, and same-version updates.
- [Install Binaries](install-binaries.md): release asset names and install commands.
- [Install Binaries](operations/install-binaries.md): release asset names, install commands, and first-run telemetry controls.

Supported Python range: `>=3.12,<3.15`.
3 changes: 2 additions & 1 deletion docs/contracts/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ Current contract references:
- [Plan Command Drift Scope](plan-drift-scope.md): what `kickstart plan` covers, defers, and emits.
- [Adoption Tiers](adoption-tiers.md): Level 1 conformant vs Level 2 managed, exit codes, and JSON shape.
- [Backstage Export](backstage-export.md): derived/declared/passthrough field classes and re-export semantics.
- [Install Binaries](../install-binaries.md): release asset names and install commands.
- [Pseudonymous CLI Telemetry](telemetry.md): default-on policy, persistent opt-out, identity, closed event allowlists, privacy, and provider boundaries.
- [Install Binaries](../operations/install-binaries.md): release asset names, install commands, and first-run telemetry controls.
- [Human Guide](../human-guide.md): supported project kinds, languages, runtimes, and CLI options.

Add command, file format, and generated-output compatibility contracts here when they need standalone treatment.
Loading
Loading