Skip to content

Prepare release 0.1.0: versioning policy, changelog, security notes, Swift Package Index settings, code owners, issue templates, adopters and release notes (#65) - #145

Merged
alaineid merged 5 commits into
mainfrom
release-0.1.0-prep
Oct 6, 2026
Merged

alaineid merged 5 commits into
mainfrom
release-0.1.0-prep

Conversation

@alaineid

@alaineid alaineid commented Oct 6, 2026

Copy link
Copy Markdown
Contributor

Refs #65.

Prepares release 0.1.0 without publishing anything: no tag, GitHub release or Swift Package Index submission is made here. The commands for those, run after the merge, are at the end. Docs and config only; Package.swift did not need a change (item 8).

Dependencies: #64, #31 and #39 are closed (2026-10-02, 2026-10-02 and 2026-10-01), and so are milestones 0 to 5, which the issue's "once milestones 2 and 3 are complete" asks for.

What this adds

Item Files
1. Versioning policy: Semantic Versioning, a minor release may break before 1.0, a patch never does; what the public interface is; bare tags such as 0.1.0; -dev version strings between releases; dependencies only by version CHANGELOG.md header, docs/development.md "Versioning and releases"
2. The 0.1.0 entry: backends, endpoints, request options, the openjev tool, apps on iOS and macOS, compatibility, documentation, and the known gaps (CLM #59; #100, #101, #102). Every line links the doc that backs it; no timing figures CHANGELOG.md
3. Security notes from the code: the reporting channel (private vulnerability reporting, already enabled: the API answers {"enabled":true}), supported versions, the listener and its routes, every outgoing connection, no telemetry, the variables that hold keys and that none is logged SECURITY.md
4. Swift Package Index: the five DocC modules in the docs site's order, with the site's --exclude-extended-types, and the scheme iOS builds .spi.yml
5. Code owners and issue forms: a bug report, a compatibility report (the request, upstream's response, this server's response), and a contact link that sends vulnerabilities to private reporting .github/CODEOWNERS, .github/ISSUE_TEMPLATE/
6. Adopters: the table header and how to add a row, linked from the README ADOPTERS.md, README.md
7. Release notes for the GitHub release: summary, compatibility matrix, the models with their credits, installing with SwiftPM from: "0.1.0" and building openjev docs/release-notes/0.1.0.md
Also, because the release makes them wrong README.md (status: milestones 0 to 5, 0.1.0 released, "Not there yet" without #65; a SwiftPM line; links to the new files), Sources/OpenJevCore/Documentation.docc/GettingStarted.md (its "no release yet, depend on branch: "main"" section and the stale mlx-swift-lm paragraph become from: "0.1.0"; the backend table gains JevK5), docs/README.md (points at the release notes and the changelog)

Checks on the new config: .spi.yml loads with SPIManifest 1.13.0, the Swift Package Index's own parser (836 of its 1,500-byte limit; the five documentation targets, the parameter, and scheme OpenJevCore-iOS for iOS). The two issue forms and config.yml validate against SchemaStore's github-issue-forms and github-issue-config schemas with no errors. Every relative link and heading anchor in the changed Markdown resolves, and none of the files has an em dash.

Network call sites

Searched in Sources/ for URLSession, URLRequest, URL(string:, URLComponents, HTTPClient, HubApi, snapshot(, AutoTokenizer, from(pretrained, ModelFactory, loadModel, ClientBootstrap, ServerBootstrap, NWConnection, NWListener, import Network, socket(, connect(, bind(, Process(, curl, huggingface.co, github.com, https?://, MetricsSystem, InstrumentationSystem, LoggingSystem, .bootstrap, telemetry and analytics, and read every match.

Call site What it does When
OpenJevServer/OpenJevApplication.swift:96-105 The listener, address: .hostname(settings.host, port: settings.port), HTTP/1.1 without TLS; routes at :58-69 (/health, /v1/models, /v1/systemone, /v1/chat/completions when the model generates text) openjev serve, on OPENJEV_HOST:OPENJEV_PORT, 127.0.0.1:8080 by default
OpenJevEncoders/Store/EncoderPackageStore.swift:312 URLSession.shared (:90, :105) download(from:) of each manifest file: package files from https://github.com/Algorythm-Canada/openjev-models/releases/download/<tag>/<asset> and tokenizer and calibrator files from https://huggingface.co/<repo>/resolve/<pinned commit>/<file> (EncoderPackageManifest+Verdict.swift:57-69, EncoderPackageManifest+Laya.swift:245-257); no token; size and SHA-256 checked before use Loading verdict or laya, and LayaBackend.prefetch(lengths:) on an iPhone, for files that are missing or unchecked; never with OPENJEV_ENCODER_MODELS
OpenJevDiffusionGemma/Download/ModelResolver.swift:251 Ephemeral URLSession (:133-141) to https://huggingface.co: GET /api/models/<repo>/revision/<rev> (:575-588, branch or tag only) and GET /api/models/<repo>/tree/<commit>?recursive=true (:591-636, every load of a Hub source; a next page on another origin is refused at :624-629) mlx (DiffusionGemmaRuntime.swift:237) and jevk5 (JevK5Checkpoint.swift:199) with a Hub source; never with a folder
OpenJevDiffusionGemma/Download/ModelResolver.swift:314 dataTask per missing file, GET /<repo>/resolve/<commit>/<path>, resumed with Range, checked by SHA-256 or git blob SHA-1 (:735-841); Authorization dropped when a redirect changes host (:337-349) The same, for files the Hugging Face cache lacks
OpenJevServer/ModelRouter.swift:96-103 AsyncHTTPClient POST to <route url>/v1/systemone with the client's authorization, x-origin-secret and content-type, and Basic authorization from credentials in the URL (:84-94); no redirects, HTTP/1.1, one client per request (:124-139); the answer read whole (:104) OPENJEV_MODEL_ROUTES, for a routed model this server does not serve
openjev-bench/Targets.swift:55,69 URLSession POSTs to the server --url names Not shipped (no product)
openjev-stub-server/StubServer.swift A listener for the SDK suite Not shipped

Checked and not a connection: AutoTokenizer.from(modelFolder:) (OpenJevEncoders/TokenizerFolder.swift:22, OpenJevLetterReadout/MLX/JevK5Tokenizer.swift:30) and LanguageModelConfigurationFromHub(modelFolder:) (OpenJevDiffusionGemma/Tokenization/SwiftTransformersTokenizer.swift:293) read local files only (swift-transformers 1.3.4, Hub.swift:247); creating the shared HubApi they default to starts an NWPathMonitor (HubApi.swift:1159-1186), which sends nothing. openjev-bench/BenchCommand.swift:134 runs /usr/bin/pmset. Images are base64 or data: URLs (OpenJevCore/Images/ImageValidation.swift), never fetched. PillowJPEGHeader.swift:186 and SystemOneService.swift:127-154 hold URLs as text (an XMP namespace and model descriptions).

Telemetry: no MetricsSystem.bootstrap, InstrumentationSystem.bootstrap, analytics or telemetry code in Sources/; no metrics or tracing middleware is installed; the tool logs through StreamLogHandler.standardError (openjev/CommandContext.swift:51), and mlx-swift's own logger writes to the unified log by default (mlx-swift/Source/MLX/Logging.swift:43-44). So SECURITY.md says "no telemetry", and it lists the model routes and the listener beside the downloads rather than the issue's "no network calls except model download".

Keys: OPENJEV_API_KEY and OPENJEV_ORIGIN_SECRET (ServerSettings.swift:226-227), compared in constant time (AuthenticationMiddleware.swift:64-85) and logged only as set or unset (ServeCommand.swift:187-193); route URLs are logged without credentials (ServeCommand.swift:95-97, ServerSettings.swift:297-334); HF_TOKEN (ModelSource.swift:86, :124-129, passed at BackendRegistry.swift:152 and :218) goes only to the Hub's requests, and its errors name the variable. One case quotes a secret: a malformed OPENJEV_MODEL_ROUTES entry is echoed whole in upstream's startup error (ServerSettings.swift:279-286, :408-411), credentials included; SECURITY.md says so.

Dependency check (item 8)

Every requirement in Package.swift is a version, so nothing changed:

Package Requirement Declared on
hummingbird from: "2.23.0" all hosts
swift-argument-parser from: "1.8.0" all hosts
swift-http-types from: "1.8.0" all hosts
swift-log from: "1.15.1" all hosts
swift-nio from: "2.103.0" all hosts
swift-service-lifecycle from: "2.12.0" all hosts
async-http-client from: "1.36.2" all hosts
swift-docc-plugin from: "1.5.0" all hosts
mlx-swift exact: "0.32.3" macOS hosts
mlx-swift-lm exact: "3.32.3" macOS hosts
swift-transformers .upToNextMinor(from: "1.3.0") macOS hosts
swift-jinja from: "2.4.2" macOS hosts

All 35 pins in Package.resolved are versions; none is a branch. The fresh packages below prove the transitive side: SwiftPM resolved this package by version and every package under it.

Fresh packages: the acceptance criteria, with nothing published

In a scratch folder outside the repository, S=/private/tmp/claude-501/<session>/scratchpad/release-proof, with Swift 6.4 (Xcode 27.0, Swift Build) on macOS 27.0, Apple silicon. $WORKTREE is this branch's worktree. The tag exists only in the scratch clone, whose only remote is the local worktree; nothing was pushed. The clone is commit 62c20ef.

The commits after the tested one change Markdown only:

$ git diff --stat 62c20ef HEAD
 CHANGELOG.md                |  7 +++---
 SECURITY.md                 |  2 +-
 docs/release-notes/0.1.0.md | 58 ++++++++++-----------------------------------
 3 files changed, 17 insertions(+), 50 deletions(-)

The clone and its tag

$ git clone --branch release-0.1.0-prep --single-branch $WORKTREE $S/OpenJevSwift
Cloning into '$S/OpenJevSwift'...
done.
$ git tag -a 0.1.0 -m "OpenJevSwift 0.1.0"
$ git log --oneline -1
62c20ef Prepare release 0.1.0: versioning policy, changelog, security notes, Swift Package Index settings, code owners, issue templates, adopters and release notes (#65)
$ git tag --list
0.1.0
$ git ls-remote --tags .
30cdb5c425ebaeab1cd281a633444fb880d98646	refs/tags/0.1.0
62c20ef6ee7139127fa3c0a075a905a8098a386c	refs/tags/0.1.0^{}
$ git remote -v
origin	$WORKTREE (fetch)
origin	$WORKTREE (push)

A package that uses OpenJevCore

$ cat Package.swift
// swift-tools-version: 6.2
import PackageDescription

let package = Package(
    name: "CoreConsumer",
    platforms: [.macOS(.v14), .iOS(.v17)],
    dependencies: [
        .package(url: "file://$S/OpenJevSwift", from: "0.1.0")
    ],
    targets: [
        .executableTarget(
            name: "CoreConsumer",
            dependencies: [.product(name: "OpenJevCore", package: "OpenJevSwift")])
    ]
)
$ cat Sources/CoreConsumer/main.swift
import OpenJevCore

let request = try SystemOneRequest(
    json: JSONParser().parse(
        #"{"model":"jev-latest","state":"The site is down.","questions":{"urgent":{"type":"noul","instructions":"Is this urgent?"}}}"#
    ))
print("OpenJevCore \(openJevCoreVersion): \(request.questions.count) question for \(request.model)")
$ swift package resolve
Computed $S/OpenJevSwift at 0.1.0 (0.87s)
Computed https://github.com/ml-explore/mlx-swift-lm at 3.32.3 (1.82s)
Computed https://github.com/ml-explore/mlx-swift at 0.32.3 (1.00s)
Working copy of $S/OpenJevSwift resolved at 0.1.0
(the other dependencies all at versions; the full list is below)
$ swift package show-dependencies --format text
.
└── openjevswift<$S/OpenJevSwift@0.1.0>(traits: default)
    ├── hummingbird<https://github.com/hummingbird-project/hummingbird.git@2.27.0>(traits: FullFoundation, ConfigurationSupport)
    ...
$ swift build
Build complete! (8.56 secs.)
$ swift run CoreConsumer
OpenJevCore 0.1.0-dev: 1 question for jev-latest

The same package without platforms does not build, which is why the install docs name them:

$ grep -n platforms Package.swift
(no match)
$ swift build
error: The package product 'OpenJevCore-product' requires minimum platform version 14.0 for the macOS platform, but this target supports 12.0
error: Build failed

A package that uses OpenJevDiffusionGemma

$ cat Package.swift
// swift-tools-version: 6.2
import PackageDescription

let package = Package(
    name: "GemmaConsumer",
    platforms: [.macOS(.v14), .iOS(.v17)],
    dependencies: [
        .package(url: "file://$S/OpenJevSwift", from: "0.1.0")
    ],
    targets: [
        .executableTarget(
            name: "GemmaConsumer",
            dependencies: [.product(name: "OpenJevDiffusionGemma", package: "OpenJevSwift")])
    ]
)
$ cat Sources/GemmaConsumer/main.swift
import OpenJevDiffusionGemma

print("OpenJevDiffusionGemma \(openJevDiffusionGemmaVersion): default checkpoint \(ModelSource.fourBit)")
$ swift package resolve
Computed $S/OpenJevSwift at 0.1.0 (1.26s)
Working copy of $S/OpenJevSwift resolved at 0.1.0
$ swift build
(compiles MLX's C++ and Metal sources: 78 warnings, the C++17-extension notices of mlx-swift's Metal headers and Swift Build's "missing creator for mutated node"; no error)
Build complete! (33.76 secs.)
$ swift run GemmaConsumer
OpenJevDiffusionGemma 0.1.0-dev: default checkpoint mlx-community/diffusiongemma-26B-A4B-it-4bit@a7a81407613811e8ba63af92ac0d852b809e191f
$ ls -l .build/out/Products/Debug/mlx-swift_Cmlx.bundle/Contents/Resources/default.metallib
-rw-r--r-- 1 aeid wheel 2401016 Oct  6 14:29 .build/out/Products/Debug/mlx-swift_Cmlx.bundle/Contents/Resources/default.metallib

Both packages resolved the same 36 pins, every one a version (Package.resolved of each):

async-http-client              1.36.2
eventsource                    1.5.1
hummingbird                    2.27.0
mlx-swift                      0.32.3
mlx-swift-lm                   3.32.3
openjevswift                   0.1.0
swift-algorithms               1.2.1
swift-argument-parser          1.8.2
swift-asn1                     1.7.3
swift-async-algorithms         1.1.7
swift-atomics                  1.3.1
swift-certificates             1.21.0
swift-collections              1.7.1
swift-configuration            1.2.2
swift-crypto                   4.5.2
swift-distributed-tracing      1.5.0
swift-http-structured-headers  1.7.0
swift-http-types               1.8.0
swift-huggingface              0.13.0
swift-jinja                    2.5.1
swift-log                      1.15.1
swift-metrics                  2.11.0
swift-nio                      2.104.0
swift-nio-extras               1.35.1
swift-nio-http2                1.46.0
swift-nio-ssl                  2.37.5
swift-nio-transport-services   1.28.0
swift-numerics                 1.1.1
swift-service-context          1.3.0
swift-service-lifecycle        2.12.1
swift-syntax                   603.0.2
swift-system                   1.8.1
swift-transformers             1.3.4
yyjson                         0.12.0

swift package dump-package in the tagged clone prints valid JSON (5 products, 12 dependencies, macOS 14 and iOS 17, tools 6.2), which the Swift Package Index requires.

In the worktree, swift build (Build complete), make lint (no findings) and make docs (the five modules, every DocC warning an error) pass. Package.swift did not change, so the full swift test was not run.

Contradictions and open points

  1. The version strings say 0.1.0-dev, so a tag of this merge reports 0.1.0-dev. All five Version.swift constants hold "0.1.0-dev", their doc comment says the suffix "marks unreleased work toward 0.1.0", openjev --version prints it, and six tests expect it (Tests/OpenJevCoreTests/VersionTests.swift:6, Tests/OpenJevServerTests/VersionTests.swift:6, Tests/OpenJevDiffusionGemmaTests/VersionTests.swift:6, Tests/OpenJevEncodersTests/EncoderPackageSpecTests.swift:220, Tests/OpenJevCLITests/ArgumentParsingTests.swift:170, Tests/OpenJevCLITests/BinaryTests.swift:20). The fresh package above printed OpenJevCore 0.1.0-dev from the local 0.1.0 tag. Changing them is a Swift change, which this PR's scope (docs and config) leaves out. Either a small PR sets the five constants and six tests to 0.1.0 before the tag and another moves them to the next -dev after it, as the new "Version strings" rule in development.md says, or the tag goes ahead with 0.1.0-dev.
  2. No local Linux build. Docker 29.6.2 is installed, but it holds no Swift image, so, as the prompt allows, the Linux side rests on CI: the Linux job builds and tests OpenJevCore, the server and the tool in swift:6.2-noble, and it runs on this PR because .spi.yml and the issue forms are not Markdown (ci.yml's paths are ** without !**.md); the Documentation workflow runs too, for the DocC article. That job builds the package as the root, not through a version requirement; on Linux the manifest declares only the eight from: dependencies, a subset of the graph that resolved by version here, and OpenJevCore depends on none of them.
  3. The issue's "no network calls except model download" is not the whole picture. The server also listens, and it forwards requests for routed models (OPENJEV_MODEL_ROUTES). SECURITY.md lists all three and says "no telemetry", which the search supports.
  4. Private vulnerability reporting is already on: ghp api repos/Algorythm-Canada/OpenJevSwift/private-vulnerability-reporting answers {"enabled":true}, so SECURITY.md's link works now.
  5. Choices made here that are yours to change: security fixes go to the newest minor release only before 1.0 (SECURITY.md); the CHANGELOG entry is dated 2026-10-06, so change the date if the tag lands on another day; blank issues stay enabled beside the two forms and the contact link, and the compatibility form has no label because the repository has no compatibility label (the bug form uses bug).
  6. Fresh resolutions take newer patches than Package.resolved: swift-nio 2.104.0, swift-service-lifecycle 2.12.1, swift-async-algorithms 1.1.7, swift-configuration 1.2.2 and swift-huggingface 0.13.0, against 2.103.0, 2.12.0, 1.1.6, 1.2.1 and 0.11.0 in this repository's file. The two fresh packages built with them, so a consumer gets a working set today.
  7. Stale lines found and left alone, outside this PR's items: docs/development.md:317 says the upstream live file's think, chat and stream tests fail "until The think option: thought generation before a read, prefix continuation, billing #52 and /v1/chat/completions: OpenAI-compatible generation with streaming, JSON mode and cancellation #53 land" (both landed in Generate text, think and chat on the MLX backend: the diffusion sampler, the block loop, think and the chat model (#50, #51, #52, #53, D-059) #137); docs/development.md:100-101 lists mlx-swift-lm's products as MLXLMCommon, MLXVLM and swift-transformers' as Tokenizers, while Package.swift also uses MLXLLM, MLXHuggingFace and Hub; CONTRIBUTING.md:3 says the project is "in its research and planning phase"; docs/development.md:90 says autogenerated schemes are never written to disk, while eight are committed (known, and your call).

After the merge

Run from the main checkout once this PR has merged (and, if you take point 1 above, once the version PR has merged too, tagging its commit instead).

Check that origin/main is the commit to release:

git fetch origin
git log -1 --format='%h %s' origin/main

Tag it and push the tag:

git tag -a 0.1.0 -m "OpenJevSwift 0.1.0" origin/main
git push origin 0.1.0

Create the GitHub release from the notes file on main (--verify-tag refuses to run if the tag is not on GitHub yet):

git show origin/main:docs/release-notes/0.1.0.md > "$TMPDIR/openjevswift-0.1.0.md"
GH_PROMPT_DISABLED=1 timeout 120 /Users/aeid/.local/bin/ghp release create 0.1.0 --repo Algorythm-Canada/OpenJevSwift --verify-tag --title "OpenJevSwift 0.1.0" --notes-file "$TMPDIR/openjevswift-0.1.0.md" < /dev/null

Submit the package to the Swift Package Index: https://swiftpackageindex.com/add-a-package, then Add Package(s), which opens an issue on SwiftPackageIndex/PackageList; give it https://github.com/Algorythm-Canada/OpenJevSwift.git. The index needs the https URL with .git and at least one semantic version tag, which 0.1.0 is.

Then close the issue:

GH_PROMPT_DISABLED=1 timeout 120 /Users/aeid/.local/bin/ghp issue close 65 --repo Algorythm-Canada/OpenJevSwift --comment "Released as 0.1.0: https://github.com/Algorythm-Canada/OpenJevSwift/releases/tag/0.1.0" < /dev/null

Copilot AI balanced review requested due to automatic review settings October 6, 2026 18:33

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟡 Changes recommended

The release still reports 0.1.0-dev, and the compatibility form needs a private-data redaction warning.

Review effort: Balanced
Findings: 1 Medium severity · 1 Low severity

Open (2)
What changed in this PR

Prepares OpenJevSwift 0.1.0 with release documentation, security guidance, and repository configuration.

Changes:

  • Adds versioning policy, changelog, release notes, and adopter documentation.
  • Documents security, installation, supported backends, and release status.
  • Adds Swift Package Index, CODEOWNERS, and issue-template configuration.
File Description
Sources/​OpenJevCore/​Documentation.docc/​GettingStarted.md Updates backend and SwiftPM guidance.
SECURITY.md Documents reporting, networking, secrets, and downloads.
README.md Adds release installation and status information.
docs/​release-notes/​0.1.0.md Adds 0.1.0 release notes.
docs/​README.md Links release documentation.
docs/​development.md Defines versioning and release policy.
CHANGELOG.md Adds version policy and 0.1.0 changes.
ADOPTERS.md Adds the adopter-list process.
.spi.yml Configures Package Index documentation and iOS builds.
.github/​ISSUE_TEMPLATE/​config.yml Adds security reporting guidance.
.github/​ISSUE_TEMPLATE/​compatibility_report.yml Adds compatibility-report fields.
.github/​ISSUE_TEMPLATE/​bug_report.yml Adds structured bug reporting.
.github/​CODEOWNERS Assigns repository ownership.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread docs/development.md
Comment on lines +159 to +161
- **Version strings.** Every module's `Version.swift` holds the same version, which
`openjev --version` prints: the next release with `-dev` between releases, and the release itself
at its tag.
Comment thread .github/ISSUE_TEMPLATE/compatibility_report.yml Outdated
alaineid and others added 2 commits October 6, 2026 14:59
…rning before requesting request/response logs'

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
@alaineid
alaineid merged commit faf33c0 into main Oct 6, 2026
1 of 2 checks passed
@alaineid
alaineid deleted the release-0.1.0-prep branch October 6, 2026 18:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants