speckit-eye Home

DATA MODEL · data-model.md

Data Model: First npm Release, Safe Release Automation, and Documentation Site

Raw markdown
# Data Model: First npm Release, Safe Release Automation, and Documentation Site

**Feature**: [spec.md](./spec.md) | **Plan**: [plan.md](./plan.md)

No runtime data is stored. The entities below are files and workflow values; the rules are
enforced by `scripts/release/release.js` (see [contracts/release-cli.md](./contracts/release-cli.md)).

## Version

| Field | Rule |
|---|---|
| `value` | SemVer 2.0 `MAJOR.MINOR.PATCH` with optional pre-release `-<id>.<n>` (id: `rc` by default). No build metadata. Defined only in `package.json` `version` (§III). |
| `tag` | `v` + `value`, e.g. `v1.0.0`. Annotated, points at the release commit. |
| `prerelease` | `true` when `value` contains `-`. |
| `distTag` | `next` when `prerelease`, otherwise `latest` (FR-016). |

**Next version** (`bump`):

| Kind | From `1.2.3` | From `1.3.0-rc.1` |
|---|---|---|
| `patch` | `1.2.4` | `1.3.0` (finishes the pre-release) |
| `minor` | `1.3.0` | `1.3.0` |
| `major` | `2.0.0` | `2.0.0` |
| `prepatch` | `1.2.4-rc.0` | `1.3.1-rc.0` |
| `preminor` | `1.3.0-rc.0` | `1.4.0-rc.0` |
| `premajor` | `2.0.0-rc.0` | `2.0.0-rc.0` |
| `prerelease` | `1.2.4-rc.0` | `1.3.0-rc.2` |
| `--version X` | `X` (must be valid; may equal the current version only if there is no `## [X]` section — the first-release case, `1.0.0`; an existing tag `vX` is caught by the Release run's checks, not by the script) | same |

Uniqueness: a value is released at most once — no existing git tag, no changelog section, not on
npm (npm refuses reuse even after unpublish).

## Changelog section

`CHANGELOG.md` keeps the Keep a Changelog 1.1.0 shape:

```text
# Changelog
<intro>
## [Unreleased]
### Added | Changed | Deprecated | Removed | Fixed | Security
- entries…
## [X.Y.Z] - YYYY-MM-DD
…
[Unreleased]: https://github.com/SerafAC/speckit-eye/compare/vX.Y.Z...HEAD
[X.Y.Z]: https://github.com/SerafAC/speckit-eye/compare/vW...vX.Y.Z   (first release: /releases/tag/vX.Y.Z)
```

| Rule | Where enforced |
|---|---|
| Unreleased must have at least one `- ` entry to bump | `bump` (FR-008) |
| After bump: Unreleased is empty (heading only); the entries sit under `## [X.Y.Z] - <UTC date>` directly below it, sub-headings kept | `bump` (FR-006) |
| The newest released section's version equals `package.json` version and the tag, and is non-empty | `verify` (FR-010) |
| Link definitions: exactly one `[Unreleased]` line comparing the newest tag to `HEAD`, one line per released version | `bump` rewrites them; repository URL from `package.json` `repository` (§III) |
| Release notes = body of the version's section (without its heading) | `notes` (FR-015) |

## Release run

One run of `release.yml` for one version.

```text
            ┌── not a release commit ──► done (nothing happens)
prepare ────┤
            └── release ──► ci ─┐
                           verify ─┴─► awaiting approval ──rejected──► stopped (no tag, nothing published)
                                            │ approved
                                            ▼
                                   tag created (if missing) ──► published to npm ──► GitHub release created
any failing check ─────────────────────────────────────────► failed (names the check; nothing published)
```

| Field | Source |
|---|---|
| `trigger` | `push-main` / `push-tag` / `dispatch` (on a tag, to re-run a release) |
| `commit` | head commit (push) or tag target |
| `version`, `tag`, `distTag` | `package.json` (push-main) or the tag name |
| `tarball` | artifact `speckit-eye-<version>.tgz` from `verify`, the only file published |
| `notes` | artifact `notes.md` from `verify` |
| `provenance` | attached by npm from the OIDC identity of the `publish` job |

## Documentation site

| Path on the site | Content | Source |
|---|---|---|
| `/` (e.g. `https://serafac.github.io/speckit-eye/`) | docmd home page | `docs/index.md` |
| `/usage/`, `/hosting/`, `/architecture/`, `/releasing/` | guides | `docs/<name>.md` |
| `/assets/…` | docmd assets + screenshots | docmd + `docs/assets/` |
| `/status/…` | speckit-eye static build of this repository | `specs/`, `.specify/` via `bin/speckit-eye.js --build` |

The site URL has one definition: `package.json` `homepage`. The docmd `url`, the dashboard
`--base` (`<path of homepage>status/`) and `--home` (`homepage`) are derived from it.

Feature: spec.md | Plan: plan.md

No runtime data is stored. The entities below are files and workflow values; the rules are enforced by scripts/release/release.js (see contracts/release-cli.md).

01 Version

Field Rule
value SemVer 2.0 MAJOR.MINOR.PATCH with optional pre-release -<id>.<n> (id: rc by default). No build metadata. Defined only in package.json version (§III).
tag v + value, e.g. v1.0.0. Annotated, points at the release commit.
prerelease true when value contains -.
distTag next when prerelease, otherwise latest (FR-016).

Next version (bump):

Kind From 1.2.3 From 1.3.0-rc.1
patch 1.2.4 1.3.0 (finishes the pre-release)
minor 1.3.0 1.3.0
major 2.0.0 2.0.0
prepatch 1.2.4-rc.0 1.3.1-rc.0
preminor 1.3.0-rc.0 1.4.0-rc.0
premajor 2.0.0-rc.0 2.0.0-rc.0
prerelease 1.2.4-rc.0 1.3.0-rc.2
--version X X (must be valid; may equal the current version only if there is no ## [X] section — the first-release case, 1.0.0; an existing tag vX is caught by the Release run's checks, not by the script) same

Uniqueness: a value is released at most once — no existing git tag, no changelog section, not on npm (npm refuses reuse even after unpublish).

02 Changelog section

CHANGELOG.md keeps the Keep a Changelog 1.1.0 shape:

# Changelog
<intro>
## [Unreleased]
### Added | Changed | Deprecated | Removed | Fixed | Security
- entries…
## [X.Y.Z] - YYYY-MM-DD
…
[Unreleased]: https://github.com/SerafAC/speckit-eye/compare/vX.Y.Z...HEAD
[X.Y.Z]: https://github.com/SerafAC/speckit-eye/compare/vW...vX.Y.Z   (first release: /releases/tag/vX.Y.Z)
Rule Where enforced
Unreleased must have at least one - entry to bump bump (FR-008)
After bump: Unreleased is empty (heading only); the entries sit under ## [X.Y.Z] - <UTC date> directly below it, sub-headings kept bump (FR-006)
The newest released section's version equals package.json version and the tag, and is non-empty verify (FR-010)
Link definitions: exactly one [Unreleased] line comparing the newest tag to HEAD, one line per released version bump rewrites them; repository URL from package.json repository (§III)
Release notes = body of the version's section (without its heading) notes (FR-015)

03 Release run

One run of release.yml for one version.

            ┌── not a release commit ──► done (nothing happens)
prepare ────┤
            └── release ──► ci ─┐
                           verify ─┴─► awaiting approval ──rejected──► stopped (no tag, nothing published)
                                            │ approved
                                            ▼
                                   tag created (if missing) ──► published to npm ──► GitHub release created
any failing check ─────────────────────────────────────────► failed (names the check; nothing published)
Field Source
trigger push-main / push-tag / dispatch (on a tag, to re-run a release)
commit head commit (push) or tag target
version, tag, distTag package.json (push-main) or the tag name
tarball artifact speckit-eye-<version>.tgz from verify, the only file published
notes artifact notes.md from verify
provenance attached by npm from the OIDC identity of the publish job

04 Documentation site

Path on the site Content Source
/ (e.g. https://serafac.github.io/speckit-eye/) docmd home page docs/index.md
/usage/, /hosting/, /architecture/, /releasing/ guides docs/<name>.md
/assets/… docmd assets + screenshots docmd + docs/assets/
/status/… speckit-eye static build of this repository specs/, .specify/ via bin/speckit-eye.js --build

The site URL has one definition: package.json homepage. The docmd url, the dashboard --base (<path of homepage>status/) and --home (homepage) are derived from it.