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
3 changes: 3 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,9 @@ jobs:
- name: Reject high and critical dependency advisories
run: pnpm audit:security

- name: Enforce the service operations contract
run: pnpm ops:check

- name: Check cross-package version references
# Non-blocking. Multi-package patch PRs (one bump touches several packages whose
# downstream deps can't reference the new versions until publish) will always
Expand Down
1 change: 1 addition & 0 deletions docs/reference/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ Quick reference material for API details and protocol indices.
- **[Licensing policy](./licensing.md)** — Uniform Open BSV License Version 6 declarations, package files, and drift controls
- **[npm package supply chain](./npm-package-supply-chain.md)** — Pack-once candidates, SBOMs, attestations, OIDC publication, and registry verification
- **[Release and operations guide](./release-operations.md)** — Scope, preflight, publication, deployment, failure handling, and rollback
- **[Service operations contract](./service-operations.md)** — Generated health, readiness, state, migration, backup, and workload-hardening contracts
- **[Repository health controls](./repository-health.md)** — Machine-readable project, package, documentation, test, and exception governance
- **[Test quality governance](./test-quality-governance.md)** — Required, manual, live, property, mutation, and conformance test ownership
- **[July 2026 modernization release](./release-2026-07-25.md)** — Package versions, compatibility notes, and verification scope
Expand Down
96 changes: 96 additions & 0 deletions docs/reference/service-operations.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
---
id: service-operations
title: 'Service Operations Contract'
kind: reference
version: '1.0.0'
last_updated: '2026-07-28'
last_verified: '2026-07-28'
review_cadence_days: 30
status: stable
tags: [reference, infrastructure, operations, health, recovery]
---

# Service Operations Contract

This page is generated from `governance/service-operations.json`. CI verifies
that all seven released services have a non-root, digest-pinned container with a
real health check and that checked-in application workloads retain startup,
readiness, liveness, resources, seccomp, dropped capabilities, a read-only root
filesystem, and secret indirection.

## Runtime endpoints

| Service | Port contract | Liveness | Readiness | Operations |
|---|---|---|---|---|
| `chaintracks-server` | PORT (default 3011; CDN is port + 1) | `/getInfo` | `/getInfo` | [guide](../infrastructure/chaintracks-server.md) |
| `message-box-server` | PORT, then HTTP_PORT (default 8080) | `/health` | `/ready` | [guide](https://github.com/bsv-blockchain/ts-stack/blob/main/infra/message-box-server/DEPLOYING.md) |
| `overlay-server` | 8080 | `/health/live` | `/health/ready` | [guide](https://github.com/bsv-blockchain/ts-stack/blob/main/infra/overlay-server/deploy/README.md) |
| `uhrp-server-basic` | HTTP_PORT (default 8080) | `/health` | `/ready` | [guide](../infrastructure/uhrp-server-basic.md) |
| `uhrp-server-cloud-bucket` | HTTP_PORT (default 8080) | `/health` | `/ready` | [guide](../infrastructure/uhrp-server-cloud-bucket.md) |
| `wab` | PORT (default 8080) | `/info` | `/info` | [guide](https://github.com/bsv-blockchain/ts-stack/blob/main/infra/wab/deploy/README.md) |
| `wallet-infra` | HTTP_PORT (default 8081; samples set 8080 without nginx) | `/` | `/` | [guide](https://github.com/bsv-blockchain/ts-stack/blob/main/infra/wallet-infra/guides/kube_samples/README.md) |

Health endpoints are public and non-sensitive. They do not replace protocol
authentication or rate limits. Public services retain wildcard,
credential-free CORS by default; CSP remains a separate document/UI policy.

## State, migration, and recovery

### chaintracks-server

- State: Bulk-header files under BULK_HEADERS_PATH; upstream headers are reproducible.
- Migration/startup: No schema migration. Validate the retained header corpus before rollout.
- Backup/restore: Snapshot BULK_HEADERS_PATH or repopulate it from a verified source CDN.
- Operator guide: [docs/infrastructure/chaintracks-server.md](../infrastructure/chaintracks-server.md)

### message-box-server

- State: Knex database plus optional Firebase device registrations.
- Migration/startup: Migrations complete before listen; back up and verify the target schema first.
- Backup/restore: Use the selected database engine's consistent snapshot and restore procedure.
- Operator guide: [infra/message-box-server/DEPLOYING.md](https://github.com/bsv-blockchain/ts-stack/blob/main/infra/message-box-server/DEPLOYING.md)

### overlay-server

- State: Knex transaction state and MongoDB lookup-service state.
- Migration/startup: Overlay migrations complete before listen; preserve both stores as one release boundary.
- Backup/restore: Take coordinated MySQL and MongoDB backups before schema or image changes.
- Operator guide: [infra/overlay-server/deploy/README.md](https://github.com/bsv-blockchain/ts-stack/blob/main/infra/overlay-server/deploy/README.md)

### uhrp-server-basic

- State: Local files and metadata under the configured public storage directory.
- Migration/startup: No schema migration; preserve file and metadata consistency.
- Backup/restore: Snapshot the complete storage directory and verify hashes before restore.
- Operator guide: [docs/infrastructure/uhrp-server-basic.md](../infrastructure/uhrp-server-basic.md)

### uhrp-server-cloud-bucket

- State: Cloud bucket objects and provider metadata.
- Migration/startup: No local schema migration; validate provider configuration before listen.
- Backup/restore: Use provider versioning/replication and verify object hashes and retention policy.
- Operator guide: [docs/infrastructure/uhrp-server-cloud-bucket.md](../infrastructure/uhrp-server-cloud-bucket.md)

### wab

- State: Authentication, identity-link, share, deletion-intent, and faucet database tables.
- Migration/startup: Migrations complete before listen; verify rollback compatibility before rollout.
- Backup/restore: Take an encrypted database snapshot and test identity/share recovery without logging secrets.
- Operator guide: [infra/wab/deploy/README.md](https://github.com/bsv-blockchain/ts-stack/blob/main/infra/wab/deploy/README.md)

### wallet-infra

- State: Wallet Storage database, monitor state, transactions, outputs, baskets, and certificates.
- Migration/startup: Storage migration and availability checks complete before the server starts.
- Backup/restore: Take and verify a consistent database backup before every schema or image change.
- Operator guide: [infra/wallet-infra/guides/kube_samples/README.md](https://github.com/bsv-blockchain/ts-stack/blob/main/infra/wallet-infra/guides/kube_samples/README.md)

## Change procedure

1. Change a service, Dockerfile, manifest, or operator guide.
2. Update `governance/service-operations.json` when the operational contract changes.
3. Run `pnpm ops:docs`, then `pnpm ops:check`.
4. Run the affected service tests and the full repository health, container,
documentation, security, and merge gates.
5. Deploy only through a separately authorized release and record the exact image
digest, probe evidence, migration result, backup, and rollback outcome.
14 changes: 7 additions & 7 deletions docs/reference/stack-facts.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,13 +75,13 @@ the separately released and verified image digest.

| Service | Package | Manifest version | Node engine | Runtime targets | Release | Source |
| --- | --- | --- | --- | --- | --- | --- |
| BSV Chaintracks Server | `chaintracks-server` | `1.0.10` | `>=24 <25` | node, linux/amd64 | ghcr-keyless | [infra/chaintracks-server](https://github.com/bsv-blockchain/ts-stack/tree/main/infra/chaintracks-server) |
| BSV Message Box Server | `@bsv/messagebox-server` | `1.1.14` | `>=24 <25` | node, linux/amd64 | ghcr-keyless | [infra/message-box-server](https://github.com/bsv-blockchain/ts-stack/tree/main/infra/message-box-server) |
| BSV Overlay Server | `@bsv/overlay-express-examples` | `2.1.18` | `>=24 <25` | node, linux/amd64 | ghcr-keyless | [infra/overlay-server](https://github.com/bsv-blockchain/ts-stack/tree/main/infra/overlay-server) |
| BSV UHRP Basic Server | `@bsv/uhrp-lite` | `0.1.8` | `>=24 <25` | node, linux/amd64 | ghcr-keyless | [infra/uhrp-server-basic](https://github.com/bsv-blockchain/ts-stack/tree/main/infra/uhrp-server-basic) |
| BSV UHRP Cloud Bucket Server | `@bsv/uhrp-storage-server` | `0.2.10` | `>=24 <25` | node, linux/amd64 | ghcr-keyless | [infra/uhrp-server-cloud-bucket](https://github.com/bsv-blockchain/ts-stack/tree/main/infra/uhrp-server-cloud-bucket) |
| Wallet Authentication Backend | `@bsv/wab-server` | `1.4.11` | `>=24 <25` | node, linux/amd64 | ghcr-and-aws-marketplace-keyless | [infra/wab](https://github.com/bsv-blockchain/ts-stack/tree/main/infra/wab) |
| BSV Wallet Infrastructure | `@bsv/wallet-infra` | `2.0.13` | `>=24 <25` | node, linux/amd64 | ghcr-keyless | [infra/wallet-infra](https://github.com/bsv-blockchain/ts-stack/tree/main/infra/wallet-infra) |
| BSV Chaintracks Server | `chaintracks-server` | `1.0.11` | `>=24 <25` | node, linux/amd64 | ghcr-keyless | [infra/chaintracks-server](https://github.com/bsv-blockchain/ts-stack/tree/main/infra/chaintracks-server) |
| BSV Message Box Server | `@bsv/messagebox-server` | `1.1.15` | `>=24 <25` | node, linux/amd64 | ghcr-keyless | [infra/message-box-server](https://github.com/bsv-blockchain/ts-stack/tree/main/infra/message-box-server) |
| BSV Overlay Server | `@bsv/overlay-express-examples` | `2.1.19` | `>=24 <25` | node, linux/amd64 | ghcr-keyless | [infra/overlay-server](https://github.com/bsv-blockchain/ts-stack/tree/main/infra/overlay-server) |
| BSV UHRP Basic Server | `@bsv/uhrp-lite` | `0.1.9` | `>=24 <25` | node, linux/amd64 | ghcr-keyless | [infra/uhrp-server-basic](https://github.com/bsv-blockchain/ts-stack/tree/main/infra/uhrp-server-basic) |
| BSV UHRP Cloud Bucket Server | `@bsv/uhrp-storage-server` | `0.2.11` | `>=24 <25` | node, linux/amd64 | ghcr-keyless | [infra/uhrp-server-cloud-bucket](https://github.com/bsv-blockchain/ts-stack/tree/main/infra/uhrp-server-cloud-bucket) |
| Wallet Authentication Backend | `@bsv/wab-server` | `1.4.12` | `>=24 <25` | node, linux/amd64 | ghcr-and-aws-marketplace-keyless | [infra/wab](https://github.com/bsv-blockchain/ts-stack/tree/main/infra/wab) |
| BSV Wallet Infrastructure | `@bsv/wallet-infra` | `2.0.14` | `>=24 <25` | node, linux/amd64 | ghcr-keyless | [infra/wallet-infra](https://github.com/bsv-blockchain/ts-stack/tree/main/infra/wallet-infra) |

## Governed project and release inventory

Expand Down
113 changes: 113 additions & 0 deletions governance/service-operations.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
{
"schemaVersion": 1,
"lastReviewed": "2026-07-28",
"owner": "ts-stack-maintainers",
"manifestRoots": [
"infra/overlay-server/deploy",
"infra/wab/deploy",
"infra/wallet-infra/guides/kube_samples"
],
"services": [
{
"name": "chaintracks-server",
"path": "infra/chaintracks-server",
"port": "PORT (default 3011; CDN is port + 1)",
"livenessPath": "/getInfo",
"readinessPath": "/getInfo",
"state": "Bulk-header files under BULK_HEADERS_PATH; upstream headers are reproducible.",
"migration": "No schema migration. Validate the retained header corpus before rollout.",
"backup": "Snapshot BULK_HEADERS_PATH or repopulate it from a verified source CDN.",
"operatorGuide": "docs/infrastructure/chaintracks-server.md",
"publicProtocol": true
},
{
"name": "message-box-server",
"path": "infra/message-box-server",
"port": "PORT, then HTTP_PORT (default 8080)",
"livenessPath": "/health",
"readinessPath": "/ready",
"state": "Knex database plus optional Firebase device registrations.",
"migration": "Migrations complete before listen; back up and verify the target schema first.",
"backup": "Use the selected database engine's consistent snapshot and restore procedure.",
"operatorGuide": "infra/message-box-server/DEPLOYING.md",
"publicProtocol": true
},
{
"name": "overlay-server",
"path": "infra/overlay-server",
"port": "8080",
"livenessPath": "/health/live",
"readinessPath": "/health/ready",
"state": "Knex transaction state and MongoDB lookup-service state.",
"migration": "Overlay migrations complete before listen; preserve both stores as one release boundary.",
"backup": "Take coordinated MySQL and MongoDB backups before schema or image changes.",
"operatorGuide": "infra/overlay-server/deploy/README.md",
"publicProtocol": true
},
{
"name": "uhrp-server-basic",
"path": "infra/uhrp-server-basic",
"port": "HTTP_PORT (default 8080)",
"livenessPath": "/health",
"readinessPath": "/ready",
"state": "Local files and metadata under the configured public storage directory.",
"migration": "No schema migration; preserve file and metadata consistency.",
"backup": "Snapshot the complete storage directory and verify hashes before restore.",
"operatorGuide": "docs/infrastructure/uhrp-server-basic.md",
"publicProtocol": true
},
{
"name": "uhrp-server-cloud-bucket",
"path": "infra/uhrp-server-cloud-bucket",
"port": "HTTP_PORT (default 8080)",
"livenessPath": "/health",
"readinessPath": "/ready",
"state": "Cloud bucket objects and provider metadata.",
"migration": "No local schema migration; validate provider configuration before listen.",
"backup": "Use provider versioning/replication and verify object hashes and retention policy.",
"operatorGuide": "docs/infrastructure/uhrp-server-cloud-bucket.md",
"publicProtocol": true
},
{
"name": "wab",
"path": "infra/wab",
"port": "PORT (default 8080)",
"livenessPath": "/info",
"readinessPath": "/info",
"state": "Authentication, identity-link, share, deletion-intent, and faucet database tables.",
"migration": "Migrations complete before listen; verify rollback compatibility before rollout.",
"backup": "Take an encrypted database snapshot and test identity/share recovery without logging secrets.",
"operatorGuide": "infra/wab/deploy/README.md",
"publicProtocol": true
},
{
"name": "wallet-infra",
"path": "infra/wallet-infra",
"port": "HTTP_PORT (default 8081; samples set 8080 without nginx)",
"livenessPath": "/",
"readinessPath": "/",
"state": "Wallet Storage database, monitor state, transactions, outputs, baskets, and certificates.",
"migration": "Storage migration and availability checks complete before the server starts.",
"backup": "Take and verify a consistent database backup before every schema or image change.",
"operatorGuide": "infra/wallet-infra/guides/kube_samples/README.md",
"publicProtocol": true
}
],
"applicationWorkloads": [
{
"service": "overlay-server",
"manifest": "infra/overlay-server/deploy/app-deployment.yaml",
"container": "overlay"
},
{
"service": "wab",
"manifest": "infra/wab/deploy/web-deployment.yaml",
"container": "web"
},
{
"service": "wallet-infra",
"manifest": "infra/wallet-infra/guides/kube_samples/wallet.yaml",
"container": "wallet-infra"
}
]
}
3 changes: 3 additions & 0 deletions infra/chaintracks-server/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,9 @@ USER node
# 3012 - CDN Server (bulk headers)
EXPOSE 3011 3012

HEALTHCHECK --interval=30s --timeout=5s --start-period=60s --retries=3 \
CMD ["node", "-e", "const port=process.env.PORT||'3011';fetch('http://127.0.0.1:'+port+'/getInfo').then(r=>{if(!r.ok)process.exit(1)}).catch(()=>process.exit(1))"]

# Run the application with the OpenTelemetry bootstrap preloaded so
# auto-instrumentation patches modules before app code is imported.
CMD ["node", "--require", "./dist/telemetry.js", "dist/server.js"]
4 changes: 2 additions & 2 deletions infra/chaintracks-server/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion infra/chaintracks-server/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "chaintracks-server",
"version": "1.0.10",
"version": "1.0.11",
"engines": {
"node": ">=24 <25",
"npm": ">=11"
Expand Down
3 changes: 3 additions & 0 deletions infra/message-box-server/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@ EXPOSE 8080

USER node

HEALTHCHECK --interval=30s --timeout=5s --start-period=60s --retries=3 \
CMD ["node", "-e", "const port=process.env.PORT||process.env.HTTP_PORT||'8080';fetch('http://127.0.0.1:'+port+'/ready').then(r=>{if(!r.ok)process.exit(1)}).catch(()=>process.exit(1))"]

# Start the app with the OpenTelemetry bootstrap preloaded (ESM --import) so
# auto-instrumentation patches modules before they are imported.
CMD [ "node", "--import", "./out/src/telemetry.js", "out/src/index.js" ]
4 changes: 2 additions & 2 deletions infra/message-box-server/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion infra/message-box-server/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@bsv/messagebox-server",
"private": true,
"version": "1.1.14",
"version": "1.1.15",
"engines": {
"node": ">=24 <25",
"npm": ">=11"
Expand Down
Loading