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
20 changes: 10 additions & 10 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,19 @@ Follows [Keep a Changelog](https://keepachangelog.com/); versioning is [SemVer](

### Added

- Versioning policy SSOT + CHANGELOG tagged-section SelfCheck (C11 L119).
- ADR 0005: explicit no Workers/Vercel/edge deploy target (C11 L114) + `edge-deploy-scope` SelfCheck.

- Blocking `sandbox-boundary` SelfCheck job in `security.yml` (C04 L40; hard no-net/rootless still unpaid).

- `GET /readyz` readiness probe + process-compose probe switch; SLO stubs in observability docs.
## [0.2.0] - 2026-07-04

Initial public release tag (`v0.2.0`).

- Security pack (audit-v38 C04/C06 P0): `SECURITY.md`, `CODE_OF_CONDUCT.md`, `deny.toml`, `.github/workflows/security.yml` (cargo-deny + gitleaks), `.github/dependabot.yml`, `.pre-commit-config.yaml`.
- Agent-readiness docs: `docs/functional_requirements.md` (FR catalog), `PLAN.md`, `WORK_DAG.md`, `llms.txt`.
- Ops stubs: `docs/ops/runbook.md` (`make dev` / healthz :8080) and `docs/ops/observability.md` (metrics + OTel soft goal).
- `AGENTS.md` ΓÇö agent entrypoint (build/test/lint/worktree/forbidden-ops); Key files links to FR/PLAN/llms/runbook.
- `rust-toolchain.toml` ΓÇö reproducible toolchain (MSRV 1.85 via Cargo).
- `.github/PULL_REQUEST_TEMPLATE.md` and `user-friction` issue template + `docs/friction-log.md`.
- proc-compose deploy stack with sl-viewer + Makefile + quickstart (#39).
### Added

<!-- Prior history predates this changelog; reconstruct from git tags as versions are cut. -->
- Desktop viewer release workflow + launch instructions.
- Packaging scaffolds for macOS `.app` and Linux portable binaries.
- Session list / search selection in the viewer.
- Domain mutation-targeted state machine and boundary tests.

<!-- Earlier history was Unreleased-aggregated; tag sections start at 0.2.0. -->
3 changes: 2 additions & 1 deletion docs/ops/distribution.md
Original file line number Diff line number Diff line change
Expand Up @@ -535,7 +535,7 @@ SessionLedger release and data-surface versioning follow distinct rules:

| Surface | Policy | Source of truth |
|---------|--------|-----------------|
| **Git tags / desktop binaries** | [SemVer](https://semver.org/) on `v*` tags (`v0.1.0` → version `0.1.0`) | Root `Cargo.toml` `version` must match the tag body before tagging; [`CHANGELOG.md`](../../CHANGELOG.md) follows Keep a Changelog |
| **Git tags / desktop binaries** | [SemVer](https://semver.org/) on `v*` tags (`v0.1.0` → version `0.1.0`) | Root `Cargo.toml` `version` must match the tag body before tagging; [`CHANGELOG.md`](../../CHANGELOG.md) + [`versioning-policy.md`](versioning-policy.md) |
| **Release asset names** | Tag-derived `VER` in CI (`sl-viewer-v<tag>-<target>`, `SessionLedger-<ver>-x64.msi`, `SessionLedger-<ver>-<arch>.pkg`) | [`.github/workflows/release.yml`](../../.github/workflows/release.yml) `derive version` step |
| **OKF export documents** | `[major].[minor]` tuple with major-bump rejection rules | [`docs/reference/OKF-SPEC.md`](../reference/OKF-SPEC.md#13-versioning--compatibility) |
| **SQLite schema** | Forward-only migrations; consumers on older schema revisions upgrade via `sl-daemon` migrate | [`docs/ops/schema-migrations.md`](schema-migrations.md) |
Expand Down Expand Up @@ -612,3 +612,4 @@ the production path (deferred).
- [`observability.md`](observability.md) — `/healthz`, `/readyz`, metrics
- [`SECURITY.md`](../../SECURITY.md) — supply chain / SBOM
- Issue [#66](https://github.com/KooshaPari/SessionLedger/issues/66) — signing + installers

27 changes: 27 additions & 0 deletions docs/ops/versioning-policy.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Versioning & compatibility policy

Status: **C11 L119** — SemVer + Keep a Changelog cadence for desktop releases.

Related: [`CHANGELOG.md`](../../CHANGELOG.md), [`docs/ops/distribution.md`](distribution.md)
(versioning table), [`docs/reference/OKF-SPEC.md`](../reference/OKF-SPEC.md) §13.

## Rules

| Surface | Policy |
|---------|--------|
| Git tags / crates | SemVer `vMAJOR.MINOR.PATCH`; root `Cargo.toml` `version` matches the tag body before tagging |
| CHANGELOG | Keep a Changelog; every tagged release gets a `## [X.Y.Z] - YYYY-MM-DD` section (not only `[Unreleased]`) |
| rust-version | Workspace `rust-version` (MSRV) is declared in root `Cargo.toml`; bump with a CHANGELOG note |
| OKF documents | Separate `[major].[minor]` rules in OKF-SPEC — independent of crate SemVer |

## Cadence

1. Accumulate notes under `[Unreleased]` during the wave.
2. On tag: move Unreleased bullets into a new `## [X.Y.Z] - <date>` section; leave an empty Unreleased stub.
3. Do not invent tagged sections for untagged commits.

## Machine verification

```powershell
pwsh ./scripts/versioning-policy-check.ps1 -SelfCheck
```
59 changes: 59 additions & 0 deletions scripts/versioning-policy-check.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<#
.SYNOPSIS
Machine-check C11 L119 versioning / CHANGELOG tagged-section anchors.

.PARAMETER SelfCheck
Explicit docs/path smoke.

.EXAMPLE
pwsh ./scripts/versioning-policy-check.ps1 -SelfCheck
#>
[CmdletBinding()]
param([switch]$SelfCheck)

Set-StrictMode -Version Latest
$ErrorActionPreference = "Stop"

$repoRoot = Split-Path -Parent $PSScriptRoot
$changelog = Join-Path $repoRoot "CHANGELOG.md"
$policy = Join-Path $repoRoot "docs/ops/versioning-policy.md"
$dist = Join-Path $repoRoot "docs/ops/distribution.md"
$script = Join-Path $repoRoot "scripts/versioning-policy-check.ps1"
$wrapper = Join-Path $repoRoot "tests/versioning_policy.rs"

function Assert-File([string]$Path,[string]$Label) {
if (-not (Test-Path -LiteralPath $Path -PathType Leaf)) { throw "Missing $Label at '$Path'." }
}
function Write-Check([string]$Label,[bool]$Ok) {
$mark = if ($Ok) { "PASS" } else { "FAIL" }; Write-Host " [$mark] $Label"; return $Ok
}
function Assert-Contains([string]$Doc,[string]$Needle,[string]$Label,[string]$Context="document") {
$ok = $Doc.Contains($Needle); [void](Write-Check -Label $Label -Ok $ok)
if (-not $ok) { throw "$Context missing required anchor: '$Needle'" }
}

Write-Host "Versioning policy check (C11 L119)"
if ($SelfCheck) { Write-Host "Mode: SelfCheck (CHANGELOG tagged section + policy doc)" }

Assert-File $changelog "CHANGELOG.md"
Assert-File $policy "versioning-policy.md"
Assert-File $dist "distribution.md"
Assert-File $script "versioning-policy-check.ps1"
Assert-File $wrapper "versioning_policy.rs"

$cl = Get-Content -LiteralPath $changelog -Raw
$pol = Get-Content -LiteralPath $policy -Raw
$d = Get-Content -LiteralPath $dist -Raw

Assert-Contains $cl "## [Unreleased]" "Unreleased section" "CHANGELOG.md"
Assert-Contains $cl "## [0.2.0]" "tagged 0.2.0 section" "CHANGELOG.md"
Assert-Contains $cl "Keep a Changelog" "Keep a Changelog mention" "CHANGELOG.md"
Assert-Contains $pol "C11 L119" "policy L119 marker" "versioning-policy.md"
Assert-Contains $pol "SemVer" "SemVer" "versioning-policy.md"
Assert-Contains $pol "Keep a Changelog" "Keep a Changelog" "versioning-policy.md"
Assert-Contains $pol "rust-version" "rust-version" "versioning-policy.md"
Assert-Contains $pol "scripts/versioning-policy-check.ps1" "SelfCheck script ref" "versioning-policy.md"
Assert-Contains $d "CHANGELOG.md" "distribution links CHANGELOG" "distribution.md"
Assert-Contains $d "versioning-policy.md" "distribution links versioning policy" "distribution.md"

Write-Host "Versioning policy SelfCheck passed (C11 L119 tagged CHANGELOG + policy SSOT)."
29 changes: 29 additions & 0 deletions tests/versioning_policy.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
//! Hermetic `SelfCheck` for C11 L119 versioning policy / tagged CHANGELOG.
//! Local: `pwsh ./scripts/versioning-policy-check.ps1 -SelfCheck`

use std::path::PathBuf;
use std::process::Command;

fn repo_root() -> PathBuf {
PathBuf::from(env!("CARGO_MANIFEST_DIR"))
}

#[test]
fn versioning_policy_self_check_validates_anchors() {
let script = repo_root().join("scripts/versioning-policy-check.ps1");
assert!(script.is_file(), "expected versioning policy check at {}", script.display());
let output = Command::new("pwsh")
.args(["-NoProfile", "-File", script.to_str().expect("utf-8"), "-SelfCheck"])
.output()
.unwrap_or_else(|e| panic!("spawn pwsh: {e}"));
let stdout = String::from_utf8_lossy(&output.stdout);
let stderr = String::from_utf8_lossy(&output.stderr);
assert!(
output.status.success(),
"versioning-policy-check.ps1 failed\nstdout:\n{stdout}\nstderr:\n{stderr}"
);
assert!(
stdout.contains("Versioning policy SelfCheck passed"),
"expected success line, got:\n{stdout}"
);
}
Loading