Skip to content
Open
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
15 changes: 15 additions & 0 deletions PSScriptAnalyzerSettings.psd1
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
@{
Severity = @('Error', 'Warning')

# The bootstrap intentionally owns a terminal wizard experience. Write-Host
# is used only for presentation; operational data and diagnostics are logged
# separately and CLI commands use structured output where available.
ExcludeRules = @('PSAvoidUsingWriteHost')

Rules = @{
PSUseCompatibleSyntax = @{
Enable = $true
TargetVersions = @('5.1', '7.0')
}
}
}
74 changes: 37 additions & 37 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
# AI Flywheel CLI for Python

A cross-platform command-line application for inspecting, installing, validating, upgrading, and safely operating AI Flywheel artifacts in a repository.
A cross-platform command-line application for inspecting, validating, and safely operating AI Flywheel artifacts in a repository.

## Requirements

- Python 3.11 or newer
- A local repository directory
- A verified AI Flywheel framework ZIP archive and its published SHA-256 checksum for installation or upgrade
- A compatible AI Flywheel framework installed by the official framework installer

Hosted execution is not enabled. All validation is performed locally.

Expand Down Expand Up @@ -127,42 +127,40 @@ flywheel complete-execution \

These commands enforce schema validation, active-stage boundaries, reference integrity, and atomic state updates.

### Install
### Framework installation

Installation is plan-first. Omitting `--apply` makes no repository changes:
The Python CLI does not install or upgrade `.flywheel`. Framework installation is
owned by the published AI Flywheel Framework installer. On Windows, use the
repository bootstrap to ensure framework `2026.08.08` is present and choose either
repository-owned editable source or a managed Python CLI:

```text
flywheel install . \
--archive ai-flywheel-framework.zip \
--checksum <sha256> \
--framework-version 0.1.0
```powershell
.\scripts\install-ai-flywheel.ps1
```

After inspecting the plan, apply it explicitly:
The bootstrap invokes the official framework installer when `.flywheel` is absent,
leaves a compatible installation intact, and stops without overwriting older,
newer, malformed, legacy, or untracked installations. Interactive setup prompts:

```text
flywheel install . \
--archive ai-flywheel-framework.zip \
--checksum <sha256> \
--framework-version 0.1.0 \
--source-identity github-release-v0.1.0 \
--apply
```

Installation refuses to overwrite an existing `.flywheel` directory. The archive checksum is verified before extraction, archive paths are inspected, a repository mutation lock is acquired, changes are staged, and installation metadata is written only after the operation succeeds.
1. Repository-owned source (recommended)
Seeds editable source, tests, and project tasks under .flywheel/tools.

### Upgrade
2. Managed CLI
Installs the current versioned CLI outside the repository.
```

Upgrade is also plan-first:
For automation, select the mode explicitly:

```text
flywheel upgrade . \
--archive ai-flywheel-framework.zip \
--checksum <sha256> \
--framework-version 0.2.0
```powershell
.\scripts\install-ai-flywheel.ps1 -NonInteractive -Apply -CliInstallMode Source
.\scripts\install-ai-flywheel.ps1 -NonInteractive -Apply -CliInstallMode Managed
```

Use `--apply` after reviewing the requested target. Upgrade refuses to overwrite locally modified framework-owned files and blocks unsupported major-version transitions. Mutable operating content such as state, missions, goals, executions, evidence, approvals, and knowledge is not treated as framework-owned upgrade content.
Source mode creates an editable runtime under `.flywheel/.runtime/python-cli` and
preserves `.flywheel/tools` on later runs so repository-governed adaptations are
never overwritten. Managed mode retains the existing isolated environment under
`%LOCALAPPDATA%\AI-Flywheel`. A hybrid extension system is not part of this change.

## Exit code contract

Expand All @@ -177,29 +175,30 @@ Flywheel-defined failures are sequential and single-purpose:
- `5`: operation lock contention (`category=lock-contention`, `reason=repository-lock-active`)
- `6`: governed AI fallback required (`category=ai-fallback-required`, `reason=governed-ai-step-required`)
- `7`: other expected operation failure (`category=operation-failed`, `reason=mutation-rejected` or `operation-error`)
- `8`: framework absent or incompatible during `doctor`

For automation, rely on the numeric exit code for coarse control flow and use structured JSON `category` and `reason` fields for stable, finer-grained branching.

Runtime and shell statuses observed outside explicit Flywheel exits (for example signal termination or shell-specific interruption codes) are platform-dependent and should not be treated as part of the Flywheel-defined contract.

## Installation metadata
## Framework installation metadata

Successful installation and upgrade write:
Successful official framework installation writes:

```text
.flywheel/installation.yaml
```

The metadata records the framework version, archive checksum, source identity, installation time, and SHA-256 checksum for each framework-owned file.
The framework installer owns this metadata. The CLI reads `framework_version` only
to determine compatibility; it does not regenerate or independently prove the
installer's checksum and provenance contract.

## Safety model

- No silent overwrite of an existing installation
- No silent overwrite of locally modified framework-owned files
- SHA-256 verification before extraction
- Rejection of path traversal, absolute paths, symbolic links, duplicate destinations, and content outside `.flywheel`
- Framework installation and archive safety remain owned by the official framework installer
- No Python-side extraction, checksum verification, provenance generation, or `.flywheel` publication
- No automatic framework upgrade until the framework publishes an upgrade contract
- Atomic lock-file acquisition under `.flywheel/.runtime`
- Staged writes with rollback for write failures
- No automatic deletion of ambiguous stale locks
- No GitHub Actions or other hosted execution without separate approval

Expand All @@ -209,8 +208,9 @@ The metadata records the framework version, archive checksum, source identity, i

## Current limitations

- Release discovery and download are not performed implicitly; the first implementation accepts an already downloaded immutable archive and expected checksum.
- Offline release bundles and standalone executable distribution remain deferred.
- The CLI currently supports framework `2026.08.08` exactly.
- Automatic framework upgrade remains deferred until an official framework upgrade contract is published.
- Mission and goal creation, editing, listing, and broader administrative management remain deferred; execution lifecycle transitions are supported.
- A dedicated stale-lock recovery command remains deferred.
- Release-candidate proof has been completed on Windows with Python 3.13.14; other supported platforms require their own execution evidence.
Expand All @@ -227,7 +227,7 @@ python -m venv .release-proof
.release-proof\Scripts\python -m pip install dist\ai_flywheel_cli-0.1.0-py3-none-any.whl
.release-proof\Scripts\flywheel --version
.release-proof\Scripts\python -m ai_flywheel_cli --version
.release-proof\Scripts\flywheel doctor .
.release-proof\Scripts\flywheel --help
.release-proof\Scripts\flywheel status .
.release-proof\Scripts\flywheel validate .
```
Expand Down
213 changes: 213 additions & 0 deletions docs/windows-bootstrap.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,213 @@
# Windows Python Bootstrap Contract

## Purpose

The Windows bootstrap ensures a compatible published AI Flywheel framework is
present, asks the user to choose a Python CLI installation model, and verifies the
selected runtime. It never starts onboarding or lifecycle work.

Dependency direction is:

```text
AI Flywheel Specification
AI Flywheel Framework
Python runtime implementation
```

## Responsibility boundary

- **AI Flywheel framework installer** owns release acquisition, checksum
verification, archive safety, provenance, staging, atomic `.flywheel`
publication, rollback, and refusal to overwrite.
- **Windows Python bootstrap** detects framework compatibility, invokes the official
installer only when the framework is absent, asks whether the CLI should be
repository-owned source or managed, prepares the selected runtime, and runs
health checks.
- **Python CLI** validates and operates an installed framework. It does not install,
extract, checksum, publish, or upgrade framework artifacts.

The supported framework identity for this milestone is:

```text
Framework version: 2026.08.08
Release tag: v2026.08.08
Package: ai-flywheel-framework-2026.08.08.zip
Checksum asset: ai-flywheel-framework-2026.08.08.zip.sha256
Installer commit: fe11b801b5dfeef812377a978558fd563b67fa9e
Default CLI source commit: 2d84294cbe9922ec907fe718e9dd06e9944e0ebc
Public launcher bootstrap commit: 4f787819df1617d0a6b8435196e9c978cfbf1457
```

## Invocation

```powershell
.\scripts\install-ai-flywheel.ps1
```

Supported inputs:

- `-Repository <path>`: target Git repository or a path inside it.
- `-CliRef <branch|tag|commit>`: CLI source ref; the normal default is immutable.
- `-CliPath <path>`: local CLI source/package for development testing.
- `-CliInstallMode Source|Managed`: makes the installation choice explicitly.
Interactive runs prompt when this parameter is omitted. Non-interactive runs
require it.
- `-NonInteractive`: disables prompts.
- `-Apply`: required with `-NonInteractive` when framework installation or initial
repository-owned source installation is needed.
- `-ValidateOnly`: checks an existing installation without installing one.
- Common `-WhatIf` and `-Confirm` semantics are passed to the official installer.

Framework source parameters are intentionally absent. The Python bootstrap cannot
select a local framework, development ref, archive, checksum, or source identity.

## Setup sequence

1. Resolve the Git root and report repository/Git-operation conditions.
2. Classify the existing framework without mutation.
3. If absent, download and invoke the official installer pinned to
`fe11b801b5dfeef812377a978558fd563b67fa9e`.
4. Re-detect the framework. Cancellation or unsuccessful installation stops before
Python setup.
5. Reject older, newer, malformed, inconsistent, legacy, or untracked frameworks
without overwriting them.
6. Ask the user to choose repository-owned source or a managed CLI.
7. Detect Python 3.11+ and offer explicit `winget` remediation when appropriate.
8. Install or reuse the selected CLI model.
9. Run `flywheel doctor`, which verifies CLI version, framework identity,
compatibility, and repository validation.
10. Stop without invoking onboarding or lifecycle commands.

## CLI installation modes

### Repository-owned source (recommended)

This mode seeds an editable Python project into `.flywheel/tools`:

```text
.flywheel/
├── tools/
│ ├── cli-source.yaml
│ ├── pyproject.toml
│ ├── README.md
│ ├── src/
│ ├── tests/
│ └── tools/
└── .runtime/
└── python-cli/
```

The seed includes the CLI package source, tests, project quality-gate tasks,
project metadata, and README. It intentionally excludes the CLI repository's own
`.flywheel` records, Git metadata, release-proof files, installer scripts, and
distribution-only documentation.

The runtime under `.flywheel/.runtime/python-cli` installs `.flywheel/tools` in
editable mode with development dependencies. AI may therefore adapt the source
and tests through the repository's governed lifecycle without rebuilding or
activating the virtual environment. Re-running setup preserves existing source;
the installer never replaces an existing `.flywheel/tools` directory.

This milestone does not make the managed CLI discover repository extensions and
does not implement a hybrid CLI.

### Managed CLI

This mode retains the existing PR #9 behavior. It creates or reuses a versioned
environment under `%LOCALAPPDATA%\AI-Flywheel\environments`. The CLI source is not
copied into the application repository. This milestone does not add a stable PATH
launcher; the completion output reports the exact CLI executable path.

## Framework compatibility

The classifier reports one of:

- `not-installed`
- `compatible`
- `older-unsupported`
- `newer-unsupported`
- `untracked-or-legacy`
- `malformed`
- `invalid`

It reads `.flywheel/installation.yaml` `framework_version` and
`.flywheel/manifest.yaml` `framework.version`. These values must agree and equal
`2026.08.08`.

Compatibility detection does not recompute installer-owned checksums or regenerate
provenance. A compatible framework is left intact. Existing incompatible content is
never routed through the initial installer because that installer correctly refuses
to overwrite `.flywheel`.

No automatic upgrade path is offered until the framework publishes an official
upgrade contract.

## CLI health contract

`flywheel doctor <repository> --json` reports:

- CLI version;
- supported framework version;
- installed framework version;
- compatibility status and reason;
- repository validation status and issues;
- overall status.

It exits successfully only when the framework is compatible and repository
validation passes. Framework incompatibility and validation failure have distinct
exit codes.

The CLI no longer exposes `flywheel install` or `flywheel upgrade`. Repository
locking remains available to lifecycle and persistence operations.

## Diagnostics

Expected operational conditions use concise messages and remediation, including:

- installation cancellation;
- missing framework in validation-only mode;
- older or newer unsupported framework;
- missing provenance;
- malformed or inconsistent framework identity;
- missing non-interactive `-Apply` authority.

Unexpected exceptions retain exception type, message, source location, failing
statement, stack trace, inner exceptions, native-command output, and diagnostic-log
locations.

## Storage and safety

Managed-mode Python assets remain outside the target repository:

```text
%LOCALAPPDATA%\AI-Flywheel\
├── cache\cli\
├── environments\
└── logs\
```

Temporary CLI-source extraction occurs under `%TEMP%\AIFW\<run-id>` and is
removed after the run. The bootstrap never commits, pushes, merges, changes
application source, enables application missions, or begins lifecycle execution.

Source mode additionally writes the governed seed to `.flywheel/tools` and keeps
its generated virtual environment under `.flywheel/.runtime`.

## Validation

The full gate includes:

```powershell
.\tools\validate-powershell.ps1
.\tools\test-install-launcher.ps1
.\tools\test-windows-bootstrap.ps1
```

Regression coverage verifies compatibility classifications, explicit CLI mode
selection, immutable official installer identity, framework-before-Python ordering,
preservation of compatible framework files, repository-owned source seeding and
repeat-run preservation, absence of Python-owned framework installation logic, CLI
source archive safety, and removal of lifecycle invocation from bootstrap. Python
tests cover the same compatibility policy and deterministic `doctor` output.
Loading