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
46 changes: 46 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
name: CI

on:
push:
branches: [main]
pull_request:
workflow_dispatch:

permissions:
contents: read

jobs:
validate:
name: Validate (${{ matrix.os }})
runs-on: ${{ matrix.os }}
timeout-minutes: 20
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-dotnet@v4
with:
dotnet-version: 10.0.x
- run: dotnet restore SharedMemoryStore.slnx
- run: dotnet build SharedMemoryStore.slnx -c Release --no-restore
- run: dotnet format SharedMemoryStore.slnx --verify-no-changes --no-restore
- run: dotnet test SharedMemoryStore.slnx -c Release --no-build
- shell: pwsh
run: ./scripts/validate-docs.ps1
- shell: pwsh
run: ./scripts/validate-package-consumption.ps1 -Configuration Release
- run: dotnet pack src/SharedMemoryStore/SharedMemoryStore.csproj -c Release --no-build -o artifacts/package

docker:
name: Docker sharing
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- uses: actions/checkout@v4
- uses: actions/setup-dotnet@v4
with:
dotnet-version: 10.0.x
- shell: pwsh
run: ./scripts/validate-docker-shared-memory.ps1 -Configuration Release
31 changes: 31 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,37 @@
All notable package and documentation changes are recorded in reverse
chronological order.

## 1.0.1 - 2026-07-09

### Fixed

- Enforced one caller-selected wait budget across same-handle synchronization,
Linux lifecycle locking, and shared store locking.
- Replaced destructive key-index rebuilds with crash-safe backward-shift
compaction and duplicate-tolerant cleanup.
- Made Linux owner metadata replacement atomic and resistant to PID reuse, and
prevented failed opens from leaving live-looking owner records.
- Rejected layout dimensions whose index, alignment, or section calculations
cannot be represented safely.
- Moved stores that detect usage-count underflow into shared safe error mode.
- Prevented Windows mapping-handle leaks when view creation fails and removed
process-local Linux lock registry growth after handles are disposed.
- Matched Windows `Global\` mapping names with global synchronization so
cross-session participants cannot mutate one mapping under different mutexes.
- Made segmented publish use one synchronized operation so bounded contention
cannot strand an internal reservation.

### Security

- Linux shared-memory directories now use owner-only `0700` permissions and
region, synchronization, owner, and lifecycle files use owner-only `0600`
permissions.

### Compatibility

- Public API names, status values, and shared-memory layout remain compatible
with the `1.0.0` production contract.

## 1.0.0 - 2026-07-03

### Added
Expand Down
7 changes: 7 additions & 0 deletions Directory.Build.props
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<Project>
<PropertyGroup>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<NuGetAudit>true</NuGetAudit>
<NuGetAuditMode>all</NuGetAuditMode>
</PropertyGroup>
</Project>
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ readers can exchange data without copying payloads through a broker process.
Package identity:

- PackageId: `SharedMemoryStore`
- Version: `1.0.0`
- Version: `1.0.1`
- Target framework: `net10.0`
- License: MIT, see the [license file](LICENSE)
- Runtime dependencies: .NET BCL only
Expand Down Expand Up @@ -47,7 +47,7 @@ Docker into distributed storage.

For package consumers, start with [Getting started](docs/getting-started.md) and
the [Usage guide](docs/usage.md). A local package source workflow is documented
because this prerelease repository may be consumed before a public NuGet publish.
when validating a local build before consuming the published package.

```powershell
dotnet pack src/SharedMemoryStore/SharedMemoryStore.csproj -c Release -o artifacts/package
Expand Down Expand Up @@ -204,4 +204,4 @@ pwsh ./scripts/validate-docker-shared-memory.ps1

Documentation changes must keep package metadata, README content, release notes,
support policy, security policy, and contract links aligned with the current
`1.0.0` package behavior.
`1.0.1` package behavior.
21 changes: 12 additions & 9 deletions SECURITY.md
Original file line number Diff line number Diff line change
@@ -1,26 +1,29 @@
# Security Policy

SharedMemoryStore is currently a prerelease `0.1.0` library. Security support is
best effort until maintainers publish a stable support policy.
SharedMemoryStore `1.0.x` receives best-effort community security fixes. This
policy does not promise response or remediation service levels.

## Supported Versions

| Version | Support |
|---------|---------|
| `0.1.x` | Best-effort prerelease security review |
| `1.0.x` | Supported with best-effort community security fixes |
| `< 1.0` | Unsupported |

Older unpublished or local builds are not independently supported. Users should
reproduce reports against the latest package version available to them.

## Reporting a Vulnerability

Use GitHub private vulnerability reporting or a repository security advisory for
this project. Do not include exploit details, private payloads, credentials, or
reproduction data in public issues or pull requests.
Use GitHub private vulnerability reporting or a repository security advisory
for this project when that channel is enabled. Do not include exploit details,
private payloads, credentials, or reproduction data in public issues or pull
requests.

If private vulnerability reporting is not enabled for the hosted repository
before publication, maintainers must replace this guidance with an
owner-approved private contact path before publishing a public release.
Enabling private vulnerability reporting, or publishing an owner-approved
private contact path, is a mandatory release gate. If neither is available,
open only a minimal public issue requesting a secure contact channel and do not
include vulnerability details.

Include:

Expand Down
4 changes: 2 additions & 2 deletions SUPPORT.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Support

SharedMemoryStore is a prerelease package. Support is best effort and does not
SharedMemoryStore `1.0.x` is a stable community package. Support is best effort and does not
include response-time service levels, production incident response, or paid
support commitments.

Expand Down Expand Up @@ -30,7 +30,7 @@ Useful reports include:

## Unsupported Scenarios

The current prerelease does not claim support for:
The current package does not claim support for:

- C++ or Python bindings.
- macOS runtime support.
Expand Down
2 changes: 1 addition & 1 deletion docs/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ create/open, publish, acquire, release, remove, and dispose workflow.
- Docker Engine or Docker Desktop only when validating same-host container
sharing.

The package version is `1.0.0`. If it has not been published to a package
The package version is `1.0.1`. If it has not been published to a package
feed, build a local package source from the repository.

## Create a Local Package Source
Expand Down
5 changes: 5 additions & 0 deletions docs/lifecycle.md
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,11 @@ the store toward safe error outcomes such as `CorruptStore`.
- Use `TryRecoverLeases` and `TryRecoverReservations` only when owner policy
permits recovery.

Linux removes region, synchronization, and owner metadata after the final live
handle closes. A zero-length per-name lifecycle lock file may remain so a later
opener cannot race a different lock inode; applications should use stable store
names rather than generating an unbounded sequence of one-time names.

## Long-Running Identity

Reusable slots carry generation and reuse-epoch identity. Index entries, lease
Expand Down
5 changes: 3 additions & 2 deletions docs/packaging.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,15 @@ and targets `net10.0`. Runtime dependencies are limited to the .NET BCL.
| Field | Value |
|-------|-------|
| `PackageId` | `SharedMemoryStore` |
| `Version` | `1.0.0` |
| `Version` | `1.0.1` |
| `TargetFramework` | `net10.0` |
| `Description` | `A bounded named shared-memory key-value store for opaque binary values.` |
| `PackageTags` | `shared-memory;memory-mapped-file;zero-copy;linux;windows;docker;library` |
| `PackageLicenseExpression` | `MIT` |
| `PackageReadmeFile` | `README.md` |
| `PackageReleaseNotes` | `Linux, Windows, and same-host Docker support: adds platform resource adapters, Docker validation, portable development workflows, and updated platform documentation while preserving the 1.0.0 public API contract.` |
| `PackageReleaseNotes` | `Linux, Windows, and same-host Docker support hardening: fixes bounded waits, crash-safe ownership and index maintenance, private Linux resource permissions, layout overflow validation, and cleanup reliability while preserving the 1.0.0 public API and layout.` |
| `RepositoryType` | `git` |
| `RepositoryUrl` | `https://github.com/rantri/SharedMemoryStore` |

The package project packs the root [README.md](../README.md) at the package
root so NuGet consumers see the same package purpose, status, first-use
Expand Down
10 changes: 9 additions & 1 deletion docs/portability.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ Detailed sources:

## Current Baseline

- Runtime package: `SharedMemoryStore` `1.0.0`.
- Runtime package: `SharedMemoryStore` `1.0.1`.
- Target framework: `net10.0`.
- Supported host platforms: Linux and Windows.
- Supported container profile: Linux-based same-host Docker containers with
Expand Down Expand Up @@ -70,12 +70,20 @@ API. Future implementations or bindings must document the same trust boundary.
## Platform Resource Model

Windows uses named operating-system memory mappings and named synchronization.
An explicit `Global\` mapping name uses global synchronization as of `1.0.1`;
all participants in such a store must use `1.0.1` or later. Ordinary unqualified
and explicit `Local\` names retain session-local synchronization.
Linux uses deterministic files in a shared runtime memory location such as
`/dev/shm`, with names derived from the public store name and a collision
prevention hash. Docker containers participate in the Linux model only when
their IPC and process-liveness configuration lets all participants see the same
resources and classify owners safely.

The Linux resource directory is owner-only (`0700`), and region,
synchronization, owner, and lifecycle files are owner-only (`0600`). Cooperating
host processes must therefore run as the same Unix identity. Containers must
share a compatible identity as well as IPC and process-liveness namespaces.

## Unsupported Scenarios

- Current public docs do not claim C++ or Python bindings exist.
Expand Down
23 changes: 22 additions & 1 deletion docs/releases.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Release Preparation

This guide is the maintainer checklist for preparing a package release. It is
written for the current `1.0.0` package and should be updated when package
written for the current `1.0.1` package and should be updated when package
metadata, public API behavior, compatibility scope, support policy, security
reporting, documentation scope, or sample behavior changes.

Expand Down Expand Up @@ -183,6 +183,27 @@ dotnet run --project benchmarks/SharedMemoryStore.Benchmarks/SharedMemoryStore.B
dotnet run --project benchmarks/SharedMemoryStore.Benchmarks/SharedMemoryStore.Benchmarks.csproj -c Release -- --filter *SegmentedPublish*
```

## 1.0.1 Production Hardening Notes

The 2026-07-09 review completed the following release evidence:

- Windows Release build completed with zero warnings and 153 tests passed.
- Linux .NET 10 container validation passed 43 contract, 62 unit, and 47
integration tests; the package-consumption path was validated separately in
a clean Linux container.
- The full Docker matrix passed supported sharing, advanced ingest, abrupt-exit
recovery, contention, disposal race, isolated negative behavior, and clean
packed-package consumption.
- Documentation validation, formatting/analyzers, package packing, Windows
clean-consumer validation, and current transitive NuGet vulnerability checks
passed.
- Public API names, status values, runtime dependencies, and the shared-memory
layout remain compatible with `1.0.0`.

External publication gate: the GitHub repository reported private
vulnerability reporting as disabled during this review. Enable it or publish an
owner-approved private reporting channel before publishing `1.0.1`.

## 1.0.0 Documentation and Samples Excellence Notes

The documentation and samples excellence update reorganizes the reader journey,
Expand Down
9 changes: 5 additions & 4 deletions docs/usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -209,10 +209,11 @@ ReadOnlySequence<byte> payload = GetPayloadSequence();
var publish = store.TryPublishSegments(key, payload, descriptor, out var copiedBytes);
```

The helper reserves a contiguous slot, copies each segment in order, advances
reservation progress, and commits only after the copied byte count matches the
sequence length. On copy, advance, or commit failure, it aborts the active
reservation before returning.
The helper acquires shared synchronization once, reserves a contiguous slot,
copies each segment in order, and publishes only after the copied byte count
matches the sequence length. A copy or validation failure reclaims the internal
slot before synchronization is released, so bounded contention cannot strand a
caller-inaccessible reservation.

## Diagnostics

Expand Down
2 changes: 1 addition & 1 deletion scripts/validate-docker-shared-memory.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ function Invoke-DockerCleanConsumerValidation {
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="SharedMemoryStore" Version="1.0.0" />
<PackageReference Include="SharedMemoryStore" Version="1.0.1" />
</ItemGroup>
</Project>
'@
Expand Down
5 changes: 3 additions & 2 deletions scripts/validate-docs.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -264,11 +264,12 @@ function Assert-PackageMetadata {
$expected = @{
TargetFramework = "net10.0"
PackageId = "SharedMemoryStore"
Version = "1.0.0"
Version = "1.0.1"
Description = "A bounded named shared-memory key-value store for opaque binary values."
PackageLicenseExpression = "MIT"
PackageReadmeFile = "README.md"
RepositoryType = "git"
RepositoryUrl = "https://github.com/rantri/SharedMemoryStore"
}

foreach ($name in $expected.Keys) {
Expand Down Expand Up @@ -298,7 +299,7 @@ function Assert-PackageMetadata {
}

Assert-Contains "README.md" "SharedMemoryStore" "package README identity"
Assert-Contains "README.md" "1.0.0" "package version alignment"
Assert-Contains "README.md" "1.0.1" "package version alignment"
Assert-Contains "README.md" "net10.0" "target framework alignment"
Assert-Contains "README.md" "MIT" "license alignment"
Assert-Contains "LICENSE" "MIT License" "license metadata alignment"
Expand Down
12 changes: 6 additions & 6 deletions specs/003-zero-copy-ingest/contracts/reservation-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -115,14 +115,14 @@ and compatibility contract belongs to the span, memory, and sequence APIs above.

## Segmented Publish Rules

- `TryPublishSegments` is a helper over the reservation lifecycle.
- `TryPublishSegments` applies the same pending-to-published safety rules as a
reservation while holding one shared-synchronization acquisition.
- `ReadOnlySequence<byte>.Length` must fit in `int` and not exceed
`MaxValueBytes`.
- The helper copies segments in order into one reserved payload region,
advances the reservation by each segment length, and commits only after the
copied byte count equals the sequence length.
- If segment copy fails or commit fails, the helper aborts any active
reservation before returning.
- The helper copies segments in order into one reserved payload region and
publishes only after the copied byte count equals the sequence length.
- If segment copy or validation fails, the helper reclaims the unpublished slot
before releasing shared synchronization.
- The helper must not allocate a temporary contiguous full-payload array.
- The stored value bytes must equal the logical concatenation of all segments.

Expand Down
Loading
Loading