# unuforge

Shared preset-backed automation core for the unu product family.

## Scope

`unuforge` owns:
- preset schema and normalization
- machine-facing CLI
- profile/action dispatch contracts
- host adapter integration

`unuforge` does not own:
- product-specific manifests
- product-specific test/deploy scripts
- business-domain logic
- host runtime internals

## Local Development

`unuforge` assumes Python 3.11+.

Source-based usage remains the contributor workflow. Run commands from this
checkout or an equivalent local clone:

```bash
PYTHONPATH=src python3 -m unittest discover -s tests
PYTHONPATH=src python3 -m unuforge.cli --help
```

## Build and Verify Local Artifacts

Build standard local distribution artifacts from the repo root:

```bash
python3 scripts/build_distribution.py --out-dir dist --json
```

That command produces both:

- a wheel under `dist/*.whl`
- a source distribution under `dist/*.tar.gz`

You can then install the wheel into a virtual environment and verify the
installed console entrypoint:

```bash
python3 -m pip install dist/unuforge-0.1.0-py3-none-any.whl
unuforge --help
```

## Install a Published Release

Once a tagged release has been published, the intended official external
install contract for `unuforge` is the versioned PyPI package. External
consumers should install a tagged release rather than depending on a source
checkout.

```bash
python3 -m pip install unuforge==0.1.0
unuforge --help
```

## Release Overview

Contributors should continue to use source-based execution from the repository
checkout. The published PyPI version is the supported interface for external
consumers, and GitHub Releases are the tagged source record with the built
artifacts attached for that release.

Maintainer release steps and publishing requirements live in
[docs/releasing.md](docs/releasing.md).

## Verification

These commands are the recommended repo-local verification path:

```bash
PYTHONPATH=src python3 -m unittest discover -s tests
PYTHONPATH=src python3 -m unittest tests.test_distribution -v
python3 scripts/build_distribution.py --out-dir dist --json
PYTHONPATH=src python3 -m unuforge.cli preset inspect --preset fixtures/presets/v2-sample.json --json
PYTHONPATH=src python3 -m unuforge.cli profiles list --preset fixtures/presets/v2-sample.json --json
PYTHONPATH=src:tests python3 -m unuforge.cli profiles run sample.profile --preset fixtures/presets/v2-sample.json --host-adapter stub_host --dry-run --json -- --flag
PYTHONPATH=src:tests python3 -m unuforge.cli actions run promote --preset fixtures/presets/v2-sample.json --host-adapter stub_host --dry-run --json -- --with-web
```

The `stub_host` adapter used above lives in `tests/stub_host.py` and exists only
to validate the dispatch contract locally.

## Host Integration Model

`unuforge` is a machine-facing thin core. It loads a host adapter module named
by `--host-adapter` and delegates execution-specific behavior to that host.

The host module is expected to export `HOST`, and that object is expected to
implement the profile/action build and run hooks consumed by the CLI. This keeps
runtime internals in the host repository while `unuforge` stays focused on
preset loading, normalization, surface lookup, and dispatch plumbing.

## Current Consumption Mode

`unuforge` is now package-ready, and published releases are expected to follow
the PyPI contract described above.

In practice this means:

- downstream repos may continue to use sibling-path or other external-first
  source checkout layouts
- downstream repos can also validate local package installation from artifacts
  built by this repo
- this repository remains the thin-core truth source
- GitHub Releases carry the tagged source snapshot and the release artifacts
