Skip to content

feat(ci): v0.9 enterprise-ready β€” GHCR auto-build, SBOM, air-gapped doc, compliance one-pager#129

Merged
dfrostar merged 5 commits into
mainfrom
claude/v0.9-enterprise-ready
May 18, 2026
Merged

feat(ci): v0.9 enterprise-ready β€” GHCR auto-build, SBOM, air-gapped doc, compliance one-pager#129
dfrostar merged 5 commits into
mainfrom
claude/v0.9-enterprise-ready

Conversation

@dfrostar
Copy link
Copy Markdown
Owner

Summary

Phase 3 of the release arc β€” turn the v0.6.0 β†’ v0.7.0 β†’ v0.8.0 foundation into something a CTO, security team, or regulated-industry operator can actually adopt. Addresses #120.

Four logical commits (CI infrastructure + docs, no production code changes):

Commit Lands
feat(ci): GHCR multi-platform image auto-build on tag push .github/workflows/docker-publish.yml β€” every v* tag publishes ghcr.io/dfrostar/neuralmind:vX.Y.Z and :latest, multi-platform (linux/amd64+linux/arm64), with a verify-pull smoke test
feat(ci): CycloneDX SBOM generation + release-asset attachment .github/workflows/sbom.yml β€” every v* tag generates a CycloneDX JSON SBOM via Anchore syft and attaches it to the GitHub Release as neuralmind-vX.Y.Z.sbom.json
docs(use-cases): air-gapped install walkthrough docs/use-cases/air-gapped.md β€” bundle-and-sneakernet pattern for PyPI wheels + ChromaDB embedding model, plus the Docker variant via docker save
docs(compliance): NIST + SOC 2 + GDPR one-pager + v0.9.0 release notes docs/COMPLIANCE-SUMMARY.md β€” single reviewable surface consolidating claims from SECURITY-GUIDE.md + ENTERPRISE.md, plus RELEASE_NOTES_v0.9.0.md

Deferred (per "ship code + minimum docs" cadence)

  • README hero callout, wiki Home "What's New" entry, GitHub Pages updates
  • LinkedIn drafts, NotebookLM v0.9 pack, screencast script, Hacker News submission
  • v0.9 marketing arc lands as v0.9.1 once the infrastructure has proven out (first GHCR pull, first external SBOM ingestion, first compliance review)

Test plan

  • Both new workflow YAML files parse via python3 -c "import yaml; yaml.safe_load(...)"
  • No code changes; no test changes
  • All claims in the compliance summary either link to existing evidence (audit log, source files, workflow definitions) or have a "how to verify yourself" command
  • Air-gapped walkthrough uses the v0.7.0 multi-stage Dockerfile (pre-wheels all transitive deps in builder); the airgap docs and the Dockerfile design are consistent
  • Maintainer to verify on first release:
    • GHCR image pulls cleanly + multi-platform manifest visible (docker manifest inspect)
    • SBOM attaches to the Release page as a downloadable asset
  • Maintainer to optionally end-to-end test: the air-gapped walkthrough on a network-isolated machine

Versioning

Two feat(ci): commits + two docs(...) commits β†’ release-please should propose v0.9.0 with the matching changelog scope. Lessons learned from v0.7β†’v0.7.1β†’v0.8.0 dance: the merge commit title for this PR should use conventional-commit format so release-please picks up the feat scope correctly. Title chosen accordingly.

Order vs PR #128

This PR doesn't depend on #128 (Release-As v0.8.0 override) merging first. They sit on separate branches and address separate releases. Natural sequence:

  1. Merge chore: Release-As 0.8.0 overrideΒ #128 β†’ release-please proposes v0.8.0 β†’ merge it β†’ publish v0.8.0
  2. Merge this PR β†’ release-please proposes v0.9.0 β†’ merge it β†’ publish v0.9.0
  3. Once RELEASE_PLEASE_TOKEN secret is added (from PR fix(ci): use PAT for release-please so tag pushes trigger release.ymlΒ #126), both publishes are zero-touch on the tag push

Issues

Closes #120 (Phase 3 Enterprise-Ready) once the maintainer verifies the GHCR + SBOM workflows succeed on the v0.9.0 tag.

https://claude.ai/code/session_01SH6iHNAqeMJHXdq7ubVcuJ


Generated by Claude Code

claude added 4 commits May 18, 2026 01:13
Phase 3 enterprise-ready: every `v*` tag push builds the repo-root
Dockerfile and publishes to GHCR. No more "the README documents the
ghcr.io URL but you have to build the image yourself for now."

- Tags: ghcr.io/dfrostar/neuralmind:vX.Y.Z and :latest
- Platforms: linux/amd64 + linux/arm64 via buildx + QEMU
- Auth: GITHUB_TOKEN with packages:write (no separate registry creds)
- OCI labels: source, version, licenses=MIT, title/description
- Cache: type=gha, mode=max so subsequent releases reuse the
  transitive-wheel pre-download layer in the builder stage
- verify-pull job pulls the published image and runs `neuralmind --help`
  before declaring success

Also supports workflow_dispatch with a tag input for backfilling an
already-tagged release that didn't fire the on-push trigger (same
escape hatch as release.yml's dispatch path).

https://claude.ai/code/session_01SH6iHNAqeMJHXdq7ubVcuJ
Phase 3 enterprise-ready: every `v*` tag push generates a CycloneDX
JSON SBOM and attaches it to the GitHub Release as
neuralmind-vX.Y.Z.sbom.json.

- Generator: Anchore syft via the official anchore/sbom-action
- Format: CycloneDX 1.x JSON (ingested by Grype, Trivy,
  Dependency-Track, FOSSology, most enterprise SCA scanners)
- Scope: scans the active Python env after `pip install .`, so every
  transitive runtime dep is captured with version + license info
- Asset name: neuralmind-vX.Y.Z.sbom.json on the release page,
  downloadable via stable URL
  https://github.com/dfrostar/neuralmind/releases/download/vX.Y.Z/neuralmind-vX.Y.Z.sbom.json
- Fallback: if the release upload fails (immutable Release), the SBOM
  is preserved as a 90-day workflow artifact
- workflow_dispatch with tag input for backfilling

https://claude.ai/code/session_01SH6iHNAqeMJHXdq7ubVcuJ
Phase 3 enterprise-ready: new docs/use-cases/air-gapped.md covering
the strictest deployment posture β€” no outbound network at install,
build, runtime, or query phase.

Addresses the two install-time network deps that have always been the
"but does it work behind a firewall" question:

1. PyPI bundle β€” `pip download` on a connected machine with explicit
   --platform tags matching the target, transfer the wheel set, install
   with --no-index --find-links on the air-gapped machine.
2. ChromaDB embedding model β€” pre-cache the all-MiniLM-L6-v2 ONNX
   model (~85 MB) on the connected machine and transfer alongside the
   wheel bundle. Sets the standard ~/.cache/chroma path; supports
   CHROMA_CACHE_DIR override for containerised / NFS-home setups.

Includes the Docker variant β€” `docker save` + sneakernet works the
same way because the v0.7.0 multi-stage Dockerfile pre-wheels all
transitive deps in the builder stage (no PyPI calls at image runtime).

Includes a compliance-posture summary block + troubleshooting for the
two failure modes (platform-tag mismatch, ChromaDB cache miss).

Cross-links to the v0.9 COMPLIANCE-SUMMARY.md.

https://claude.ai/code/session_01SH6iHNAqeMJHXdq7ubVcuJ
#120)

Phase 3 enterprise-ready: new docs/COMPLIANCE-SUMMARY.md β€” single
reviewable surface for procurement, security review, and compliance
teams. Consolidates claims previously scattered across SECURITY-GUIDE.md
and ENTERPRISE.md.

Sections:
- At-a-glance posture table
- NIST AI RMF β€” full GOVERN / MAP / MEASURE / MANAGE coverage with
  line-item evidence
- SOC 2 Type II β€” CC6.1, CC7.1, CC7.2, A1.1, C1.2, P3.1/4.1 with
  evidence pointers
- GDPR β€” data minimisation, storage limitation, right to erasure,
  no controller/processor split (operator is sole controller)
- SBOM + container image provenance β€” what v0.9 ships, where to get it
- Deployment postures (strict β†’ permissive)
- Verification table β€” every claim has a "how to verify yourself"
  command so the doc isn't asking the reader to take our word

Also includes RELEASE_NOTES_v0.9.0.md with the minimum-doc scope
(marketing rollout deferred per the project's "ship code + minimum
docs, marketing arc later" cadence).

Honest scope note up front: "NeuralMind itself is not certified to
any compliance framework. The architecture supports certification of
your deployment β€” every required control is either built in or
available to switch on."

https://claude.ai/code/session_01SH6iHNAqeMJHXdq7ubVcuJ
Copilot AI review requested due to automatic review settings May 18, 2026 01:13
@github-actions github-actions Bot added documentation Improvements or additions to documentation enhancement New feature or request priority: high Critical issues question Further information is requested security Security related labels May 18, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 18, 2026

NeuralMind self-benchmark

Status: PASS β€” floor 4Γ—, measured 5.9Γ—.

Phase 1 β€” Reduction on committed fixture

  • Average reduction: 5.9Γ—
  • Top-k retrieval hit rate: 71.7%
  • Naive baseline: 47,360 tokens (all fixture files concatenated)
  • NeuralMind total: 8,149 tokens across 10 queries
  • Estimated monthly savings @ 100 queries/day on Claude 3.5 Sonnet: ~$35.30
# Query Shape Naive NeuralMind Ratio Hit
1 auth-flow cross-file 4,736 815 5.8Γ— 33.3%
2 api-endpoints focused 4,736 809 5.9Γ— 100.0%
3 billing-flow cross-file 4,736 846 5.6Γ— 33.3%
4 user-storage cross-file 4,736 672 7.0Γ— 50.0%
5 jwt-verify focused 4,736 681 7.0Γ— 100.0%
6 stripe-webhook focused 4,736 838 5.7Γ— 100.0%
7 create-user cross-file 4,736 794 6.0Γ— 50.0%
8 refund focused 4,736 827 5.7Γ— 100.0%
9 db-choice identity 4,736 899 5.3Γ— 100.0%
10 invoice-send cross-file 4,736 968 4.9Γ— 50.0%

Phase 2 β€” Learning uplift

  • Memory events logged: 20
  • Learned patterns: 20
  • Reduction ratio after neuralmind learn: 5.9Γ— (Ξ” +0.00Γ— vs. cold)
  • Top-k hit rate after learning: 71.7% (Ξ” +0.0 points vs. cold)

Note: uplift numbers on a 500-line fixture are intentionally modest β€” the point is to
verify the learning mechanism persists and applies. On real production repos the lift
is larger; this test only catches regressions in persistence.

Assumptions

  • Baseline: every .py file in tests/fixtures/sample_project/ concatenated.
  • Tokenizer: tiktoken GPT-4o encoding (per-model breakdown in multi_model.json if generated).
  • Pricing: Claude 3.5 Sonnet input @ $3.0/MTok.
  • Regression floor: 4Γ— β€” well below NeuralMind's typical 40–70Γ— on real repos.

Per-model token reduction

Model Tokenizer Naive NeuralMind Ratio Source
GPT-4o / GPT-4o-mini tiktoken o200k_base 4,739 927 5.1Γ— measured
GPT-4 / GPT-3.5-turbo tiktoken cl100k_base 4,710 918 5.1Γ— measured
Claude 3.5 Sonnet estimated: GPT-4o Γ— 1.08 β€” install anthropic for an exact count 5,118 1,001 5.1Γ— estimated
Llama 3 (70B) estimated: GPT-4o Γ— 1.22 β€” Llama tokenizer requires model weights; estimate based on published vocab ratios 5,781 1,130 5.1Γ— estimated

Rows marked measured use the provider's real tokenizer. Rows marked
estimated apply a published vocab-size correction to the GPT-4o count β€”
honest approximations, not hardcoded claims.


Automated by .github/workflows/ci-benchmark.yml β€” regenerate locally with python -m tests.benchmark.run.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Phase 3 of the v0.6β†’v0.7β†’v0.8 release arc, packaging NeuralMind for enterprise consumption: CI-driven GHCR container publishing, a CycloneDX SBOM attached to each release, and two new compliance-oriented docs. No runtime code changes.

Changes:

  • New docker-publish.yml workflow that builds multi-platform (amd64+arm64) images on v* tag push, pushes to GHCR with version + :latest + OCI labels, and runs a smoke-test pull job.
  • New sbom.yml workflow that generates a CycloneDX JSON SBOM via anchore/sbom-action, attaches it to the GitHub Release (falling back to a workflow artifact), and supports manual workflow_dispatch.
  • New docs: air-gapped.md walkthrough (wheel bundle + ChromaDB ONNX cache, Docker variant), COMPLIANCE-SUMMARY.md consolidating NIST AI RMF / SOC 2 / GDPR claims, and RELEASE_NOTES_v0.9.0.md.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
.github/workflows/docker-publish.yml New tag-triggered workflow to build/push multi-arch GHCR images and verify the pull.
.github/workflows/sbom.yml New tag-triggered workflow producing a CycloneDX SBOM and attaching it to the Release.
docs/use-cases/air-gapped.md New walkthrough for installing NeuralMind without outbound network at install or runtime.
docs/COMPLIANCE-SUMMARY.md New one-pager consolidating NIST AI RMF, SOC 2 and GDPR posture for procurement reviewers.
RELEASE_NOTES_v0.9.0.md Release notes describing the GHCR build, SBOM, air-gapped doc and compliance one-pager.
Comments suppressed due to low confidence (1)

docs/use-cases/air-gapped.md:32

  • The TL;DR tar command bundles ~/.cache/chroma/onnx_models using its (absolute) path, so after tar xzf the model directory will land at home/<user>/.cache/chroma/onnx_models/ (with leading slash stripped), not at ./onnx_models/. The follow-up cp -r onnx_models ~/.cache/chroma/ therefore won't find the directory. Either use the -C form shown in Step 3 (tar czf ... offline-bundle/ -C ~/.cache/chroma onnx_models/) so onnx_models/ extracts at the working directory, or update the cp step to point at the actual extracted path.
tar czf neuralmind-offline.tgz ./offline-bundle \
  ~/.cache/chroma/onnx_models
# Move the tarball to the air-gapped machine, then:
tar xzf neuralmind-offline.tgz
pip install --no-index --find-links offline-bundle neuralmind graphifyy
mkdir -p ~/.cache/chroma && cp -r onnx_models ~/.cache/chroma/

πŸ’‘ Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread docs/use-cases/air-gapped.md Outdated
# On a connected machine, with the same Python version as the target:
pip download neuralmind graphifyy --dest ./offline-bundle
python -c "from chromadb.utils import embedding_functions as ef; \
ef.DefaultEmbeddingFunction()()" # warm the model cache
Comment thread .github/workflows/docker-publish.yml Outdated
Comment on lines +64 to +66
tags: |
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ env.RELEASE_TAG }}
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest
Comment on lines +26 to +29
env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
RELEASE_TAG: ${{ inputs.tag || github.ref_name }}
Comment thread .github/workflows/sbom.yml Outdated
Comment on lines +67 to +74
if ! gh release view "${TAG}" --repo "${GITHUB_REPOSITORY}" >/dev/null 2>&1; then
echo "::warning title=Release not found yet::${TAG} doesn't exist; release.yml usually creates it. Skipping upload β€” re-run this workflow once the release exists."
exit 0
fi
if gh release upload "${TAG}" "${ASSET}" --repo "${GITHUB_REPOSITORY}" --clobber; then
echo "SBOM attached as ${ASSET}"
else
echo "::warning title=SBOM upload failed::Release ${TAG} may be immutable. SBOM is in the workflow artifacts."
… SBOM race + air-gapped TL;DR

Bundle of 5 fixes from Copilot review on PR #129:

scripts/docker-publish.yml:
- Switched to docker/metadata-action for tag generation. This handles
  two Copilot findings at once:
  - **case sensitivity**: GHCR rejects uppercase in image references;
    metadata-action lowercases ${{ github.repository }} when building
    tags, so a future repo rename or mixed-case fork doesn't break the
    push.
  - **:latest on pre-release tags**: previously tagged every v* push
    as :latest. Now :latest is only set when the tag has no `-`
    suffix (via type=raw,...,enable=${{ !contains(...) }}), so
    v0.10.0-rc1 / v1.0.0-beta1 won't override stable :latest.
- The verify-pull job reads the version-tagged ref from the
  metadata-action outputs (first line of `tags`) instead of
  reconstructing it from env.

scripts/sbom.yml:
- Added a polling loop (~6 min, 20s intervals) around `gh release
  view` so the SBOM lands on the GitHub Release on first publish even
  when release.yml is still in flight when this workflow starts. The
  existing workflow_artifact fallback is preserved for genuine failure
  cases. Avoids the "first release has no SBOM attached" UX gap
  Copilot flagged.

docs/use-cases/air-gapped.md TL;DR snippet:
- Fixed the tar invocation: previously used absolute path
  ~/.cache/chroma/onnx_models which tar strips to home/<user>/.cache/...
  on extract, so the later `cp -r onnx_models ...` couldn't find it.
  Switched to the `-C ~/.cache/chroma onnx_models` form that Step 3
  already uses correctly.
- Fixed the embedding-function call: ef.DefaultEmbeddingFunction()()
  with no args raises TypeError. ChromaDB embedding functions expect
  a list of documents. Changed to (['warm']) to match the detailed
  Step 2 below.

Verified locally:
- Both workflow YAML files parse via `python3 -c 'import yaml; ...'`
- No production-code changes
- The metadata-action tag pattern logic verified in the YAML expression:
  type=raw,value=latest,enable=${{ !contains('v0.9.0', '-') }} β†’ true,
  so v0.9.0 will get both :v0.9.0 and :latest; v0.10.0-rc1 β†’ false,
  only :v0.10.0-rc1.

Review URLs:
- #129 (comment)
- #129 (comment)
- #129 (comment)
- #129 (comment)

https://claude.ai/code/session_01SH6iHNAqeMJHXdq7ubVcuJ
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

πŸ’‘ Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 5ac1c2d738

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with πŸ‘.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +67 to +69
if ! gh release view "${TAG}" --repo "${GITHUB_REPOSITORY}" >/dev/null 2>&1; then
echo "::warning title=Release not found yet::${TAG} doesn't exist; release.yml usually creates it. Skipping upload β€” re-run this workflow once the release exists."
exit 0
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Retry release lookup instead of skipping SBOM upload

On push to a release tag, this workflow runs in parallel with release.yml, but this step exits successfully as soon as gh release view cannot find the release yet. Because there is no wait/retry path, the normal first run on a new tag can permanently skip attaching neuralmind-vX.Y.Z.sbom.json unless someone manually reruns the workflow, which breaks the β€œattached to every tagged release” behavior advertised by this change.

Useful? React with πŸ‘Β / πŸ‘Ž.

@dfrostar dfrostar merged commit eb5969f into main May 18, 2026
14 checks passed
dfrostar pushed a commit that referenced this pull request May 18, 2026
v0.9.0 "Enterprise-Ready" β€” Phase 3 of the release arc. Pure CI
infrastructure + docs; no production code changes.

- feat(ci): GHCR multi-platform image auto-build on tag push (#129).
  ghcr.io/dfrostar/neuralmind:vX.Y.Z + :latest (stable tags only),
  linux/amd64 + linux/arm64, non-root runtime. docker/metadata-action
  for lowercase-safe naming + smart :latest gating.
- feat(ci): CycloneDX SBOM generation + release-asset attachment.
  Anchore syft via anchore/sbom-action; 6-min poll loop around
  `gh release view` so it lands on first publish.
- docs(use-cases): air-gapped install walkthrough (wheel bundle +
  ChromaDB ONNX cache, with Docker variant via `docker save`).
- docs(compliance): NIST AI RMF + SOC 2 + GDPR one-pager with a
  "how to verify yourself" command for every claim.

5 Copilot + 1 Codex review items addressed in commit fdf8b4e.

Full release notes: RELEASE_NOTES_v0.9.0.md.

Closes #120 once the maintainer verifies the GHCR + SBOM workflows
succeed on the v0.9.0 tag.

https://claude.ai/code/session_01SH6iHNAqeMJHXdq7ubVcuJ
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation enhancement New feature or request priority: high Critical issues question Further information is requested security Security related

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[v0.7.x Phase 3] Enterprise-Ready β€” Docker Hub auto-build, air-gapped, SBOM

3 participants