4 Commits

Author SHA1 Message Date
0d0ab1f23f Harden runtime tuple recertification policy 2026-07-18 16:46:56 -07:00
Ajay Krishnan
84c0d80b76 Merge pull request #2 from ajaynomics/certify/alpha7-runtime-tuples
Some checks failed
Candidate compatibility / prepare (push) Successful in 8s
Candidate compatibility / repository (push) Successful in 12s
Candidate compatibility / image ${{ matrix.id }} (push) Failing after 9m44s
Candidate compatibility / fixture-contract (push) Successful in 10m7s
Watch upstream OpenCode / open-compatibility-pr (push) Failing after 42s
Certify alpha7 compatibility candidates
2026-07-18 15:26:08 -07:00
4bd552f389 Certify alpha7 compatibility candidates 2026-07-18 15:10:59 -07:00
Ajay Krishnan
49604f18bd Merge pull request #1 from ajaynomics/feature/runtime-tuple-promotion
Some checks failed
Candidate compatibility / prepare (push) Successful in 7s
Candidate compatibility / repository (push) Successful in 8s
Candidate compatibility / image ${{ matrix.id }} (push) Failing after 9m39s
Candidate compatibility / fixture-contract (push) Successful in 9m41s
Add atomic runtime tuple promotion gate
2026-07-18 14:18:40 -07:00
28 changed files with 2253 additions and 142 deletions

View File

@@ -20,7 +20,7 @@ jobs:
- uses: ruby/setup-ruby@v1
with:
ruby-version: "3.4"
- run: ruby test/repository_test.rb && ruby test/runtime_tuple_promoter_test.rb
- run: ruby test/repository_test.rb && ruby test/runtime_tuple_promoter_test.rb && ruby test/exact_live_contract_test.rb
prepare:
runs-on: ubuntu-latest

View File

@@ -16,8 +16,29 @@ prompts, credentials, sessions, or user data belong here.
can pull them. Public CI certifies their upstream base plus the same profile.
- Promotion is explicit. CI may certify a tuple and the watcher may open a PR;
neither workflow deploys or changes a consumer.
- Each consumer retains both `current` and `previous` certified tuples so a
rollback restores the gem and server together.
- A passing pull-request head is candidate evidence only. Promotion and
deployed certification use the actual main/merge commit, or an explicit
equal-tree attestation paired with a passing post-merge canary.
- Git-sourced gems use the full peeled commit as the Bundler `ref` and lockfile
revision. A consumer test must also prove the running process loaded that
exact `Bundler::Source::Git`; a release tag or lockfile alone is provenance,
not loaded-source proof.
- Ajent records AIGL, Blackline, and Raven selections together. Every selected
product needs a content digest or local image ID before promotion; a full
commit tag selects a candidate build but does not prove its content.
- In steady state, each consumer retains both `current` and `previous`
certified tuples so a rollback restores the gem and server together. The
explicitly labeled bootstrap state is the temporary degraded exception.
- A failing bootstrap baseline is never relabeled as a certified `previous`
tuple. After a real main/deploy canary, an explicitly acknowledged degraded
bootstrap may certify only `current`; it leaves `previous` null and keeps the
failed baseline as emergency provenance. The next meaningful passing release
becomes the first genuine certified rollback tuple.
The runtime ledger is schema version 2; its machine-readable shape lives at
[`schemas/runtime-tuples.schema.json`](schemas/runtime-tuples.schema.json).
The current candidates remain deliberately unpromotable PR-head records, and
all `previous` slots remain `null` because no passing rollback tuple exists.
## What is covered
@@ -42,9 +63,10 @@ Prerequisites are Ruby 3.2+, Python 3, `jq`, and Docker.
```sh
ruby test/repository_test.rb
ruby test/runtime_tuple_promoter_test.rb
OPENCODE_RUBY_PATH=/data/projects/opencode-ruby-alpha6 \
ruby test/exact_live_contract_test.rb
OPENCODE_RUBY_PATH=/path/to/opencode-ruby-at-78b6f9c9e9c7d58b699af1c3c17764acd33de798 \
ruby ruby/opencode_ruby_fixture_contract.rb
OPENCODE_RUBY_PATH=/data/projects/opencode-ruby-alpha6 \
OPENCODE_RUBY_PATH=/path/to/opencode-ruby-at-78b6f9c9e9c7d58b699af1c3c17764acd33de798 \
OPENCODE_IMAGE='ghcr.io/anomalyco/opencode@sha256:e975a0647576016dfdf77d54b979ca30d32b4750472c10263e9894aad6628c2a' \
scripts/run_image_contract.sh
```
@@ -52,7 +74,9 @@ OPENCODE_IMAGE='ghcr.io/anomalyco/opencode@sha256:e975a0647576016dfdf77d54b979ca
The live contract starts a deterministic local OpenAI-compatible model stub and
an isolated OpenCode container. It creates a session, subscribes, submits an
async prompt, observes terminal SSE, fetches the authoritative exchange, and
deletes the session. It never calls an external model provider.
deletes the session. Passing requires the authoritative final text to equal the
expected text byte-for-byte and the deterministic model stub to observe exactly
one request. It never calls an external model provider.
## Adding an upstream release

View File

@@ -6,6 +6,16 @@ A candidate tuple is the complete set of client version or commit, Rails gem
version or commit where applicable, exact OpenCode image, profile, and consumer
commit. Changing any member invalidates the certification.
There are two distinct scopes:
- `pre-merge-pr-head-candidate-only` proves that one reviewed PR head is
compatible. It is never a deployment or promotion authorization.
- `promotion-deployed` is recorded only after a passing post-merge canary and
the consumer coordinate is the actual main/merge commit. If policy
deliberately retains the PR-head commit, the evidence must additionally
record both Git trees as identical and name the actual main/merge commit.
Comparing diffs is not an identical-tree attestation.
The gate requires:
1. repository validation and the shared fixture corpus;
@@ -16,14 +26,41 @@ The gate requires:
6. captured evidence including image ID/digest, server version, source commit,
gem commits, timestamps, and probe outcome.
For a Git-sourced gem, “gem commit” means the peeled 40-character commit in
both the Gemfile `ref` and lockfile `revision`, plus runtime loaded-source proof:
the loaded version, `Bundler::Source::Git`, observed revision (and observed ref
when the consumer test exposes it), and the consumer test that made those
assertions. Annotated tag objects remain useful release provenance, but they
are not an execution coordinate.
Ajent's runtime is a three-product selection. The ledger records AIGL,
Blackline, and Raven under one source commit. Candidate evidence may say that a
product artifact has not been built; promotion may not. At promotion time the
set of content-addressed product artifacts must exactly equal the selected
product set.
Health-only probes do not certify a tuple.
The shared live probe is intentionally strict: `full_text` must equal the
expected text byte-for-byte and the deterministic model must receive exactly
one request. A response that merely contains the expected text, including a
duplicated `compat-ok\n\ncompat-ok`, fails.
## Promotion
Promotion is a reviewed manifest change that moves the old `current` tuple to
`previous` and the passing candidate to `current`. The consumer change is then
merged and deployed separately. Workflows in this repository have no deploy
credentials or deploy steps.
`previous` and the passing candidate to `current`. The consumer change must
already have a main/merge identity (or the equal-tree exception below) before
that manifest change. Production rollout remains a separate consumer-owned
operation; workflows in this repository have no deploy credentials or deploy
steps.
Before invoking the promoter, replace PR-head-only metadata with either the
actual main/merge consumer ref and `main-commit` promotion provenance, or an
explicit identical-tree attestation containing the main commit/tree. Both
forms require a post-merge canary evidence path. Set `promotion_eligible` only
after that evidence exists. The promoter rejects the current PR-head candidates
even when their compatibility probes pass.
Use the repository promotion command; do not hand-edit the three tuple slots.
It binds evidence to a canonical SHA-256 of the complete tuple, requires full
@@ -78,10 +115,65 @@ only in a `tag_provenance` field; `image`, `registry_ref`, and base image fields
must use `image@sha256:...`, while a private local artifact may use an exact
`docker_image_id`.
An application canary and the shared deterministic contract prove different
layers. For example, a consumer may instrument one application prompt without
being able to observe the underlying model request. Record that distinction
explicitly; do not infer a model request count from an application prompt
count. The exact-image shared contract supplies the model-request proof.
Likewise, the public image job executes only `ruby-rest-sse`; it does not
silently certify Rails persistence, plugin hooks, voice streaming, strict route
gates, or provider hooks. Every other profile is labeled
`executable-consumer-attestation` with `shared_ruby_probe_sufficient: false`.
Those profiles appear as `required_consumer_profiles` in the image matrix and
need executable evidence from their owning consumer before a full tuple can
pass. A prose review or a successful shared Ruby probe is not that evidence.
The command clears `candidate` after promotion. It sets the repository-wide
`migration_state` to `certified` only after every consumer has certified
`current` and `previous` tuples and no pending candidate.
## Bootstrap with a failing baseline
If the observed production baseline fails the current contract, keep its full
coordinates for emergency recovery but mark it failed. Do not create passing
evidence for it and do not promote it into `previous`. The promoter rejects
known-failed baselines even if a document claims `pass`.
Do not manufacture a no-op second commit merely to fill `previous`. Once the
candidate has been merged, deployed, and canaried under promotion-grade
provenance, a reviewer may use `bootstrap-current` with this exact
acknowledgement:
```text
accept-degraded-rollback-with-failed-emergency-provenance
```
That operation certifies only `current`, moves the failed baseline to
`emergency_provenance` without relabeling it, leaves `previous` null, and sets
`migration_state` to `bootstrap-current-only`. This is an intentionally
degraded rollback state, not full certification. The next meaningful passing
release uses normal promotion; the already-certified current tuple then becomes
the first honest certified `previous` tuple.
Until main/deploy evidence exists, `promotion_readiness` remains blocked and a
candidate PR must not be treated as deploy authorization.
After reviewing the degraded rollback consequence, preview the explicit
bootstrap before writing it:
```sh
ruby scripts/promote_runtime_tuple.rb bootstrap-current \
--consumer travelwolf \
--consumer-commit FULL_MAIN_OR_ATTESTED_PR_COMMIT \
--status pass \
--certified-at 2026-07-18T12:00:00Z \
--evidence evidence/travelwolf-post-merge.json \
--acknowledge-degraded-rollback \
accept-degraded-rollback-with-failed-emergency-provenance \
--dry-run
```
## Rollback
Rollback restores the whole `previous` tuple. Do not roll back only the gem or

View File

@@ -0,0 +1,88 @@
{
"schema_version": 1,
"consumer": "ajent-rails",
"profile": "rails-persisted-turn",
"consumer_commit": "01cdf9da8e1b3f9a205d681e448aefefd9704db2",
"consumer_tree": "9e93834ad16b60fa5edfe1cb3baaba193402be74",
"consumer_ref_kind": "pull-request-head",
"review_url": "https://gitea.ajay.to/ajaynomics/ajent-rails/pulls/946",
"certification_scope": "pre-merge-pr-head-candidate-only",
"promotion_eligible": false,
"status": "pass",
"certified_at": "2026-07-18T23:28:16.435369Z",
"tuple_sha256": "sha256:e7026c294d0b2981f6ec785a45afb69969f4dc2b4d0ed6533f9bda5153304663",
"shared_evidence": "evidence/2026-07-18-opencode-ruby-alpha7.json",
"loaded_sources": {
"opencode-ruby": {
"version": "0.0.1.alpha7",
"requested_ref": "78b6f9c9e9c7d58b699af1c3c17764acd33de798",
"locked_revision": "78b6f9c9e9c7d58b699af1c3c17764acd33de798",
"observed_revision": "78b6f9c9e9c7d58b699af1c3c17764acd33de798"
},
"opencode-rails": {
"version": "0.0.1.alpha7",
"requested_ref": "2a391ccad1d098e4bb51eb19b6ca52adaa79e5cb",
"locked_revision": "2a391ccad1d098e4bb51eb19b6ca52adaa79e5cb",
"observed_revision": "2a391ccad1d098e4bb51eb19b6ca52adaa79e5cb"
},
"source_class": "Bundler::Source::Git",
"proof_test": "test/lib/opencode/runtime_image_provenance_test.rb",
"status": "pass"
},
"deterministic_contract": {
"checked_at": "2026-07-18T23:16:13Z",
"docker_image_id": "sha256:075cb49ac7fcb1f8972e051dff96d655fa0d0d911d83a523a6abf03a5e2e2935",
"expected_text": "compat-ok",
"full_text": "compat-ok",
"authoritative_assistant_count": 1,
"model_request_count": 1,
"status": "pass"
},
"application_canary": {
"checked_at": "2026-07-18T23:28:16.435369Z",
"docker_image_id": "sha256:075cb49ac7fcb1f8972e051dff96d655fa0d0d911d83a523a6abf03a5e2e2935",
"persisted_final_text": "compat-ok",
"authoritative_final_text": "compat-ok",
"authoritative_assistant_count": 1,
"model_request_count": 1,
"cleanup_status": "pass",
"status": "pass"
},
"consumer_verification": {
"tests": {
"runs": 4077,
"assertions": 14495,
"failures": 0,
"errors": 0,
"existing_skips": 4
},
"rubocop": {
"files": 1365,
"offenses": 0
},
"gitea_actions": {
"run_id": 2545,
"status": "success",
"commit": "01cdf9da8e1b3f9a205d681e448aefefd9704db2"
},
"remotes_exact": [
"origin",
"github",
"backup"
]
},
"product_artifact_coverage": {
"selected_products": [
"aigl",
"blackline",
"raven"
],
"content_addressed_artifacts": [
"blackline"
],
"missing_before_promotion": [
"aigl",
"raven"
]
}
}

View File

@@ -0,0 +1,89 @@
{
"schema_version": 1,
"consumer": "mushu",
"profile": "ruby-rest-sse",
"consumer_commit": "7cff22788b36ae703f6b1b8fa39b52d6dbafe7e0",
"consumer_tree": "762eb8dcc7042a52cd240ca69acdb9cb45150a84",
"consumer_ref_kind": "pull-request-head",
"review_url": "https://gitea.ajay.to/ajaynomics/mushu/pulls/1",
"certification_scope": "pre-merge-pr-head-candidate-only",
"promotion_eligible": false,
"status": "pass",
"certified_at": "2026-07-18T23:26:06.865190Z",
"tuple_sha256": "sha256:648d53b1d800c065e8ecdb95974049ee179617569170cfc169c31c3bfc1e8865",
"shared_evidence": "evidence/2026-07-18-opencode-ruby-alpha7.json",
"loaded_source": {
"gem": "opencode-ruby",
"version": "0.0.1.alpha7",
"source_class": "Bundler::Source::Git",
"requested_ref": "78b6f9c9e9c7d58b699af1c3c17764acd33de798",
"locked_revision": "78b6f9c9e9c7d58b699af1c3c17764acd33de798",
"observed_ref": "78b6f9c9e9c7d58b699af1c3c17764acd33de798",
"observed_revision": "78b6f9c9e9c7d58b699af1c3c17764acd33de798",
"loaded_file_within_spec": true,
"proof_test": "test/services/mushu/runtime/opencode_dependency_provenance_test.rb",
"status": "pass"
},
"deterministic_contract": {
"checked_at": "2026-07-18T23:23:41Z",
"image": "docker-registry:5000/mushu-opencode@sha256:ed6293ca87e6db1dc07870d3ed6da21960743e6e2e904533b3c566d334b58d6a",
"expected_text": "compat-ok",
"full_text": "compat-ok",
"authoritative_assistant_count": 1,
"model_request_count": 1,
"status": "pass"
},
"application_canary": {
"checked_at": "2026-07-18T23:26:06.865190Z",
"response_text": "compat-ok",
"authoritative_final_text": "compat-ok",
"message_roles": [
"user",
"assistant"
],
"authoritative_assistant_count": 1,
"provider_request_count": 1,
"mapping_and_last_turn_persisted": true,
"active_claim_cleared": true,
"opencode_session_deleted": true,
"synthetic_database_rows_after_cleanup": 0,
"status": "pass"
},
"consumer_verification": {
"focused_tests": {
"runs": 126,
"assertions": 1413,
"failures": 0,
"errors": 0
},
"full_tests": {
"runs": 632,
"assertions": 9013,
"failures": 0,
"errors": 0
},
"rubocop": {
"files": 216,
"offenses": 0
},
"gitea_actions": {
"run_id": 2544,
"url": "https://gitea.ajay.to/ajaynomics/mushu/actions/runs/2544",
"overall_status": "failure",
"commit": "7cff22788b36ae703f6b1b8fa39b52d6dbafe7e0",
"classification": "inherited-unrelated-baseline-failures",
"jobs": {
"lint": "success",
"scan_js": "success",
"scan_ruby": "inherited-vendor-bundle-source-scan-failure",
"test": "inherited-evidence-report-single-failure",
"system-test": "inherited-missing-test-system-directory"
},
"baseline_run_id": 2508
},
"remotes_exact": [
"origin",
"backup"
]
}
}

View File

@@ -0,0 +1,86 @@
{
"schema_version": 1,
"client": {
"repository": "ajaynomics/opencode-ruby",
"version": "0.0.1.alpha2",
"commit": "889d38332f98f5f7b76d16952b7204d8a5b9a662"
},
"rails_client": {
"repository": "ajaynomics/opencode-rails",
"version": "0.0.1.alpha2",
"commit": "9b0c4cd3cd31bdfebbb89567daca012d68a356ea"
},
"recorded_at": "2026-07-18T22:04:14Z",
"status": "fail",
"failure": {
"expected_text": "compat-ok",
"full_text": "compat-ok\n\ncompat-ok",
"llm_request_count": 1,
"reason": "The client concatenates the streamed and authoritative text, duplicating the final response."
},
"exact_image_contracts": [
{
"image": "ghcr.io/anomalyco/opencode@sha256:e975a0647576016dfdf77d54b979ca30d32b4750472c10263e9894aad6628c2a",
"server_version": "1.16.1",
"status": "fail"
},
{
"image": "ghcr.io/anomalyco/opencode@sha256:bf9d0e84b7cedef436a8f57db4d48767cd5d8fc6604f666335c1cc916b199a97",
"server_version": "1.17.18",
"status": "fail"
},
{
"image": "ghcr.io/anomalyco/opencode@sha256:c2d5d6398df72aac85cb1bdc8f900c71a9b75a33fb7c0a76dc1484e4b126e41e",
"server_version": "1.18.3",
"status": "fail"
},
{
"target": "ajent-production-artifact",
"consumer_commit": "8d8550265dca0ac06a41d5427c585ede56bbb808",
"product": "blackline",
"docker_image_id": "sha256:af479243e6ccf1206f57dffd13b8e9d2c028de401cccc954bcc2f00940274c60",
"server_version": "1.18.3",
"status": "fail"
},
{
"target": "mushu-production-artifact",
"docker_image_id": "sha256:ed6293ca87e6db1dc07870d3ed6da21960743e6e2e904533b3c566d334b58d6a",
"server_version": "0.0.0-permission-shortcuts-202606300721",
"status": "fail"
}
],
"observed_ajent_production_runtime": {
"consumer_commit": "8d8550265dca0ac06a41d5427c585ede56bbb808",
"upstream_base_layer_match": "ghcr.io/anomalyco/opencode@sha256:c2d5d6398df72aac85cb1bdc8f900c71a9b75a33fb7c0a76dc1484e4b126e41e",
"shared_accessory": {
"product": "blackline",
"tag_provenance": "docker-registry:5000/opencode-blackline:8d8550265dca0ac06a41d5427c585ede56bbb808",
"docker_image_id": "sha256:af479243e6ccf1206f57dffd13b8e9d2c028de401cccc954bcc2f00940274c60"
},
"deployed_per_user_product_configuration": {
"strategy": "mutable-latest",
"status": "observed-configuration-drift-failure",
"references": {
"aigl": "docker-registry:5000/opencode-aigl:latest",
"blackline": "docker-registry:5000/opencode-blackline:latest",
"raven": "docker-registry:5000/opencode-raven:latest"
}
},
"ci_built_sha_artifacts": {
"aigl": {
"tag_provenance": "docker-registry:5000/opencode-aigl:8d8550265dca0ac06a41d5427c585ede56bbb808",
"docker_image_id": "sha256:72c454f39d423618b75439122c9073dbba7c9071421e5f3abd12cf288dc1f898"
},
"blackline": {
"tag_provenance": "docker-registry:5000/opencode-blackline:8d8550265dca0ac06a41d5427c585ede56bbb808",
"docker_image_id": "sha256:af479243e6ccf1206f57dffd13b8e9d2c028de401cccc954bcc2f00940274c60"
},
"raven": {
"tag_provenance": "docker-registry:5000/opencode-raven:8d8550265dca0ac06a41d5427c585ede56bbb808",
"docker_image_id": "sha256:6c4da94a8dec6160f0b1b4d0e2cd9ff38a3faa18dbd2a8d6023a71f6416a544c"
}
},
"scope_note": "The hardened alpha2 contract was rerun against the exact shared Blackline accessory. The three SHA-tagged image IDs are CI artifact provenance, not evidence that the deployed per-user ProductConfig selected them; it selected mutable latest references."
},
"promotion_effect": "The observed alpha2 consumer baselines are not eligible for certified previous tuples. After a real main/deploy/post-merge canary, an explicitly acknowledged bootstrap may certify current while leaving previous null and retaining alpha2 only as failed emergency provenance; the next meaningful passing release creates the first certified previous tuple."
}

View File

@@ -1,69 +0,0 @@
{
"schema_version": 1,
"candidate": {
"repository": "ajaynomics/opencode-ruby",
"version": "0.0.1.alpha6",
"commit": "a116b2708cc148f61b1e1fae0405553c099f4202",
"certified_payload_commit": "8adc95985a79b16e6e4bc0c0f827d638f244d509",
"payload_equivalence": "release differs only in .github/workflows/test.yml, which is outside the gem payload",
"transport_implementation_commit": "5113a953db8026697262bd4f97197a3d13077762"
},
"fixture_contract": {
"status": "pass",
"fixture_count": 7
},
"unit_contract": {
"status": "pass",
"runs": 24,
"assertions": 56
},
"image_contracts": [
{
"target": "travelwolf-1.16.1",
"image": "ghcr.io/anomalyco/opencode@sha256:e975a0647576016dfdf77d54b979ca30d32b4750472c10263e9894aad6628c2a",
"server_version": "1.16.1",
"checked_at": "2026-07-18T20:34:05Z",
"status": "pass"
},
{
"target": "opencode-ajent-1.17.18",
"image": "ghcr.io/anomalyco/opencode@sha256:bf9d0e84b7cedef436a8f57db4d48767cd5d8fc6604f666335c1cc916b199a97",
"server_version": "1.17.18",
"checked_at": "2026-07-18T20:34:08Z",
"status": "pass"
},
{
"target": "ajent-base-1.18.3",
"image": "ghcr.io/anomalyco/opencode@sha256:c2d5d6398df72aac85cb1bdc8f900c71a9b75a33fb7c0a76dc1484e4b126e41e",
"server_version": "1.18.3",
"checked_at": "2026-07-18T20:34:08Z",
"status": "pass"
},
{
"target": "ajent-blackline-live-artifact",
"image_id": "sha256:6fb2b3bf8e4cdf48e16bf6c3475e953df2f8304e77f5efe816ceb46f905eead8",
"registry_ref": "docker-registry:5000/opencode-blackline:83eed3c247a352842b08fc5cf339c4d0acdaacba",
"server_version": "1.18.3",
"checked_at": "2026-07-18T20:34:10Z",
"status": "pass"
},
{
"target": "mushu-permission-shortcuts-live-artifact",
"image_id": "sha256:ed6293ca87e6db1dc07870d3ed6da21960743e6e2e904533b3c566d334b58d6a",
"registry_ref": "docker-registry:5000/mushu-opencode:sha-99d6328b1",
"source_commit": "99d6328b18ff8a340a928449a2aa8bc184a063f9",
"server_version": "0.0.0-permission-shortcuts-202606300721",
"checked_at": "2026-07-18T20:34:08Z",
"status": "pass"
}
],
"contract": [
"health",
"create-session",
"subscribe-ready-before-async-prompt",
"deterministic-model-request",
"sse-terminal",
"authoritative-final-exchange",
"delete-session"
]
}

View File

@@ -0,0 +1,136 @@
{
"schema_version": 1,
"candidate": {
"opencode_ruby": {
"repository": "ajaynomics/opencode-ruby",
"version": "0.0.1.alpha7",
"commit": "78b6f9c9e9c7d58b699af1c3c17764acd33de798",
"tag_provenance": {
"tag": "v0.0.1.alpha7",
"annotated_tag_object": "abfce3ec8cb1ee468107d0845521769502251645",
"peeled_commit": "78b6f9c9e9c7d58b699af1c3c17764acd33de798"
}
},
"opencode_rails": {
"repository": "ajaynomics/opencode-rails",
"version": "0.0.1.alpha7",
"commit": "2a391ccad1d098e4bb51eb19b6ca52adaa79e5cb",
"tag_provenance": {
"tag": "v0.0.1.alpha7",
"annotated_tag_object": "61e128084b2b665c0ba20b332987e41794948d7c",
"peeled_commit": "2a391ccad1d098e4bb51eb19b6ca52adaa79e5cb"
}
}
},
"fixture_contract": {
"status": "pass",
"fixture_count": 7
},
"opencode_ruby_unit_contract": {
"status": "pass",
"runs": 26,
"assertions": 63
},
"opencode_rails_unit_contract": {
"status": "pass",
"runs": 55,
"assertions": 145
},
"exact_image_contracts": [
{
"target": "travelwolf-1.16.1",
"image": "ghcr.io/anomalyco/opencode@sha256:e975a0647576016dfdf77d54b979ca30d32b4750472c10263e9894aad6628c2a",
"server_version": "1.16.1",
"checked_at": "2026-07-18T23:35:57Z",
"expected_text": "compat-ok",
"full_text": "compat-ok",
"llm_request_count": 1,
"status": "pass"
},
{
"target": "opencode-ajent-1.17.18",
"image": "ghcr.io/anomalyco/opencode@sha256:bf9d0e84b7cedef436a8f57db4d48767cd5d8fc6604f666335c1cc916b199a97",
"server_version": "1.17.18",
"checked_at": "2026-07-18T23:35:58Z",
"expected_text": "compat-ok",
"full_text": "compat-ok",
"llm_request_count": 1,
"status": "pass"
},
{
"target": "ajent-base-1.18.3",
"image": "ghcr.io/anomalyco/opencode@sha256:c2d5d6398df72aac85cb1bdc8f900c71a9b75a33fb7c0a76dc1484e4b126e41e",
"server_version": "1.18.3",
"checked_at": "2026-07-18T23:35:58Z",
"expected_text": "compat-ok",
"full_text": "compat-ok",
"llm_request_count": 1,
"status": "pass"
}
],
"consumer_canaries": [
{
"consumer": "ajent-rails",
"consumer_commit": "01cdf9da8e1b3f9a205d681e448aefefd9704db2",
"consumer_ref_kind": "pull-request-head",
"certification_scope": "pre-merge-pr-head-candidate-only",
"tag_provenance": "ajent-opencode-blackline-canary:01cdf9da8e1b3f9a205d681e448aefefd9704db2",
"docker_image_id": "sha256:075cb49ac7fcb1f8972e051dff96d655fa0d0d911d83a523a6abf03a5e2e2935",
"source_commit": "01cdf9da8e1b3f9a205d681e448aefefd9704db2",
"upstream_base": "ghcr.io/anomalyco/opencode@sha256:c2d5d6398df72aac85cb1bdc8f900c71a9b75a33fb7c0a76dc1484e4b126e41e",
"server_version": "1.18.3",
"checked_at": "2026-07-18T23:28:16.435369Z",
"application_path": "Blackline::GenerateResponseJob",
"persisted_final_text": "compat-ok",
"authoritative_final_text": "compat-ok",
"authoritative_assistant_count": 1,
"model_request_count": 1,
"cleanup_status": "pass",
"status": "pass"
},
{
"consumer": "mushu",
"consumer_commit": "7cff22788b36ae703f6b1b8fa39b52d6dbafe7e0",
"consumer_ref_kind": "pull-request-head",
"certification_scope": "pre-merge-pr-head-candidate-only",
"tag_provenance": "docker-registry:5000/mushu-opencode:sha-99d6328b1",
"image": "docker-registry:5000/mushu-opencode@sha256:ed6293ca87e6db1dc07870d3ed6da21960743e6e2e904533b3c566d334b58d6a",
"docker_image_id": "sha256:ed6293ca87e6db1dc07870d3ed6da21960743e6e2e904533b3c566d334b58d6a",
"source_commit": "99d6328b18ff8a340a928449a2aa8bc184a063f9",
"server_version": "0.0.0-permission-shortcuts-202606300721",
"checked_at": "2026-07-18T23:26:06.865190Z",
"response_text": "compat-ok",
"authoritative_final_text": "compat-ok",
"authoritative_assistant_count": 1,
"provider_request_count": 1,
"cleanup_status": "pass",
"status": "pass"
},
{
"consumer": "travelwolf",
"consumer_commit": "b9a2c2dd361a6b2ea547cc67ee817b8eb4ce31e8",
"consumer_ref_kind": "pull-request-head",
"certification_scope": "pre-merge-pr-head-candidate-only",
"run_id": "travelwolf-alpha7-ref-20260718T232211Z-48eadf",
"image": "ghcr.io/anomalyco/opencode@sha256:e975a0647576016dfdf77d54b979ca30d32b4750472c10263e9894aad6628c2a",
"server_version": "1.16.1",
"checked_at": "2026-07-18T23:22:26.216140Z",
"final_text": "TRAVELWOLF_ALPHA7_REF_PIN_READY",
"subscription_ready_before_prompt": true,
"opencode_api_prompt_count": 1,
"provider_request_count_observed": false,
"message_roles": ["user", "assistant"],
"cleanup_status": "pass",
"status": "pass"
}
],
"contract": [
"health",
"create-session",
"subscribe-ready-before-async-prompt",
"exactly-one-deterministic-model-request",
"sse-terminal",
"exact-authoritative-final-exchange",
"delete-session"
]
}

View File

@@ -0,0 +1,87 @@
{
"schema_version": 1,
"consumer": "travelwolf",
"profile": "rails-persisted-turn",
"consumer_commit": "b9a2c2dd361a6b2ea547cc67ee817b8eb4ce31e8",
"consumer_tree": "8b3f8a97dc1f1d8b558a49523bf312d2810422df",
"consumer_ref_kind": "pull-request-head",
"review_url": "https://gitea.ajay.to/ajaynomics/travelwolf/pulls/29",
"certification_scope": "pre-merge-pr-head-candidate-only",
"promotion_eligible": false,
"status": "pass",
"certified_at": "2026-07-18T23:35:57Z",
"tuple_sha256": "sha256:bed7d6f6a5e6dd9138c3b960b8bf13ac6f5bf402d0aa7e5c01a52a8e8ea1083d",
"shared_evidence": "evidence/2026-07-18-opencode-ruby-alpha7.json",
"loaded_sources": {
"opencode-ruby": {
"version": "0.0.1.alpha7",
"requested_ref": "78b6f9c9e9c7d58b699af1c3c17764acd33de798",
"locked_revision": "78b6f9c9e9c7d58b699af1c3c17764acd33de798",
"observed_ref": "78b6f9c9e9c7d58b699af1c3c17764acd33de798",
"observed_revision": "78b6f9c9e9c7d58b699af1c3c17764acd33de798"
},
"opencode-rails": {
"version": "0.0.1.alpha7",
"requested_ref": "2a391ccad1d098e4bb51eb19b6ca52adaa79e5cb",
"locked_revision": "2a391ccad1d098e4bb51eb19b6ca52adaa79e5cb",
"observed_ref": "2a391ccad1d098e4bb51eb19b6ca52adaa79e5cb",
"observed_revision": "2a391ccad1d098e4bb51eb19b6ca52adaa79e5cb"
},
"source_class": "Bundler::Source::Git",
"proof_test": "test/services/travelwolf/opencode_env_wiring_test.rb",
"status": "pass"
},
"deterministic_contract": {
"checked_at": "2026-07-18T23:23:03Z",
"image": "ghcr.io/anomalyco/opencode@sha256:e975a0647576016dfdf77d54b979ca30d32b4750472c10263e9894aad6628c2a",
"opencode_ruby_commit": "78b6f9c9e9c7d58b699af1c3c17764acd33de798",
"expected_text": "compat-ok",
"full_text": "compat-ok",
"authoritative_assistant_count": 1,
"model_request_count": 1,
"status": "pass"
},
"application_canary": {
"run_id": "travelwolf-alpha7-ref-20260718T232211Z-48eadf",
"checked_at": "2026-07-18T23:22:26.216140Z",
"final_text": "TRAVELWOLF_ALPHA7_REF_PIN_READY",
"subscription_ready_before_prompt": true,
"opencode_api_prompt_count": 1,
"provider_request_count_observed": false,
"message_roles": [
"user",
"assistant"
],
"cleanup_status": "pass",
"status": "pass"
},
"consumer_verification": {
"source_guard": {
"runs": 4,
"assertions": 110,
"failures": 0,
"errors": 0
},
"focused_tests": {
"runs": 31,
"assertions": 248,
"failures": 0,
"errors": 0
},
"bounded_full_tests": {
"runs": 2300,
"assertions": 21679,
"failures": 0,
"errors": 0
},
"rubocop": {
"changed_ruby_files": 6,
"offenses": 0
},
"remotes_exact": [
"origin",
"github",
"backup"
]
}
}

View File

@@ -10,11 +10,15 @@ module OpenCodeCompat
class PromotionError < StandardError; end
class RuntimeTuplePromoter
SCHEMA_VERSION = 2
FULL_COMMIT = /\A[0-9a-f]{40}\z/
DIGEST = /\Asha256:[0-9a-f]{64}\z/
IMMUTABLE_IMAGE = /\A[^@\s]+@sha256:[0-9a-f]{64}\z/
UTC_TIMESTAMP = /\A\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?Z\z/
CERTIFICATION_STATUS = "pass"
DEGRADED_BOOTSTRAP_ACKNOWLEDGEMENT =
"accept-degraded-rollback-with-failed-emergency-provenance"
NON_CERTIFIABLE_TUPLE_STATUSES = %w[observed-production-contract-failed].freeze
TUPLE_METADATA_KEYS = %w[
certification
certified_at
@@ -40,7 +44,7 @@ module OpenCodeCompat
manifest = read_manifest
consumer_entry = fetch_consumer!(manifest, consumer)
profile = fetch_profile!(consumer_entry, consumer)
candidate = prepare_candidate!(consumer_entry, consumer_commit)
candidate = prepare_candidate!(consumer_entry, consumer_commit, for_promotion: false)
current = consumer_entry.fetch("current") do
raise PromotionError, "#{consumer} has no current tuple to preserve as previous"
end
@@ -81,6 +85,37 @@ module OpenCodeCompat
end
end
def bootstrap_current(consumer:, consumer_commit:, certification:, acknowledgement:, dry_run: false)
validate_full_commit!(consumer_commit, "consumer commit")
unless acknowledgement == DEGRADED_BOOTSTRAP_ACKNOWLEDGEMENT
raise PromotionError,
"bootstrap requires explicit acknowledgement #{DEGRADED_BOOTSTRAP_ACKNOWLEDGEMENT.inspect}"
end
if dry_run
manifest = read_manifest
return bootstrap_current_manifest(
manifest,
consumer: consumer,
consumer_commit: consumer_commit,
certification: certification,
acknowledgement: acknowledgement
)
end
with_current_manifest_lock do |manifest|
bootstrapped = bootstrap_current_manifest(
manifest,
consumer: consumer,
consumer_commit: consumer_commit,
certification: certification,
acknowledgement: acknowledgement
)
atomic_write(bootstrapped)
bootstrapped
end
end
private
def read_manifest
@@ -92,7 +127,7 @@ module OpenCodeCompat
def promote_manifest(manifest, consumer:, consumer_commit:, certification:, previous_certification:)
consumer_entry = fetch_consumer!(manifest, consumer)
profile = fetch_profile!(consumer_entry, consumer)
candidate = prepare_candidate!(consumer_entry, consumer_commit)
candidate = prepare_candidate!(consumer_entry, consumer_commit, for_promotion: true)
current = consumer_entry.fetch("current") do
raise PromotionError, "#{consumer} has no current tuple to preserve as previous"
end
@@ -123,13 +158,60 @@ module OpenCodeCompat
consumer_entry["previous"] = certified_previous
consumer_entry["current"] = certified_candidate
consumer_entry["candidate"] = nil
manifest["migration_state"] = all_consumers_certified?(manifest) ? "certified" : "candidate"
consumer_entry.delete("rollback_state")
manifest["migration_state"] = migration_state_for(manifest)
manifest
end
def bootstrap_current_manifest(manifest, consumer:, consumer_commit:, certification:, acknowledgement:)
consumer_entry = fetch_consumer!(manifest, consumer)
profile = fetch_profile!(consumer_entry, consumer)
candidate = prepare_candidate!(consumer_entry, consumer_commit, for_promotion: true)
current = consumer_entry.fetch("current") do
raise PromotionError, "#{consumer} has no current tuple to retain as emergency provenance"
end
validate_tuple!(current, "#{consumer} current")
unless NON_CERTIFIABLE_TUPLE_STATUSES.include?(current["status"])
raise PromotionError, "degraded bootstrap is only for a current tuple known to fail the contract"
end
candidate_fingerprint = tuple_fingerprint(candidate, consumer: consumer, profile: profile)
current_fingerprint = tuple_fingerprint(current, consumer: consumer, profile: profile)
if candidate_fingerprint == current_fingerprint
raise PromotionError, "#{consumer} candidate is identical to its failed current tuple"
end
certified_candidate = certify_tuple!(
candidate,
consumer: consumer,
profile: profile,
supplied: certification,
expected_fingerprint: candidate_fingerprint,
label: "bootstrap candidate"
)
consumer_entry["emergency_provenance"] = deep_copy(current)
consumer_entry["current"] = certified_candidate
consumer_entry["candidate"] = nil
consumer_entry["previous"] = nil
consumer_entry["rollback_state"] = {
"status" => "degraded-no-certified-previous",
"acknowledgement" => acknowledgement,
"recorded_at" => certification.fetch("certified_at"),
"emergency_provenance_status" => current.fetch("status")
}
manifest["migration_state"] = migration_state_for(manifest)
manifest["promotion_readiness"] = {
"status" => "bootstrap-current-only",
"reason" => "The current tuple is certified, but no independently passing previous tuple exists.",
"required_action" => "Certify the next meaningful release; normal promotion will then retain this current tuple as the first certified previous rollback."
}
manifest
end
def fetch_consumer!(manifest, consumer)
unless manifest.is_a?(Hash) && manifest["schema_version"] == 1 && manifest["consumers"].is_a?(Hash)
raise PromotionError, "runtime tuple manifest must use schema_version 1 and contain consumers"
unless manifest.is_a?(Hash) && manifest["schema_version"] == SCHEMA_VERSION && manifest["consumers"].is_a?(Hash)
raise PromotionError, "runtime tuple manifest must use schema_version #{SCHEMA_VERSION} and contain consumers"
end
manifest.fetch("consumers").fetch(consumer) do
@@ -137,7 +219,7 @@ module OpenCodeCompat
end
end
def prepare_candidate!(consumer_entry, consumer_commit)
def prepare_candidate!(consumer_entry, consumer_commit, for_promotion:)
candidate = consumer_entry["candidate"]
unless candidate.is_a?(Hash)
raise PromotionError, "consumer has no candidate tuple to promote"
@@ -154,9 +236,151 @@ module OpenCodeCompat
prepared = deep_copy(candidate)
prepared["consumer_commit"] = consumer_commit
validate_tuple!(prepared, "candidate")
validate_candidate_consumer_ref!(prepared, consumer_commit)
validate_candidate_client_sources!(prepared)
if for_promotion
validate_promotion_provenance!(prepared, consumer_commit)
validate_promotion_product_artifacts!(prepared.fetch("runtime"))
end
prepared
end
def validate_candidate_consumer_ref!(candidate, consumer_commit)
reference = candidate["consumer_ref"]
unless reference.is_a?(Hash)
raise PromotionError, "candidate must record its exact consumer ref"
end
kind = reference["kind"]
unless %w[pull-request-head main-commit].include?(kind)
raise PromotionError, "candidate consumer ref must be a pull-request-head or main-commit"
end
validate_full_commit!(reference["commit"], "candidate consumer ref commit")
validate_full_commit!(reference["tree"], "candidate consumer ref tree")
unless reference["commit"] == consumer_commit
raise PromotionError, "candidate consumer ref does not match the tuple consumer commit"
end
unless reference["repository"].is_a?(String) && !reference["repository"].empty?
raise PromotionError, "candidate consumer ref must name its repository"
end
return unless kind == "pull-request-head"
validate_full_commit!(reference["base_commit"], "candidate pull request base commit")
unless reference["review_url"].is_a?(String) && reference["review_url"].start_with?("https://")
raise PromotionError, "candidate pull request ref must include its HTTPS review URL"
end
end
def validate_candidate_client_sources!(candidate)
%w[opencode_ruby opencode_rails].each do |client_name|
client = candidate[client_name]
next unless client
validate_client_source!(client, "candidate #{client_name}", required: true)
end
end
def validate_promotion_provenance!(candidate, consumer_commit)
unless candidate["certification_scope"] == "promotion-deployed" && candidate["promotion_eligible"] == true
raise PromotionError,
"pre-merge pull-request evidence is candidate-only; promotion requires deployed certification scope"
end
provenance = candidate["promotion_provenance"]
unless provenance.is_a?(Hash)
raise PromotionError, "promotion requires main-commit provenance or an identical-tree attestation"
end
case provenance["kind"]
when "main-commit"
unless candidate.dig("consumer_ref", "kind") == "main-commit" &&
provenance["main_commit"] == consumer_commit
raise PromotionError, "main-commit promotion provenance must match the tuple consumer commit"
end
validate_post_merge_canary!(
provenance["post_merge_canary"],
consumer_commit: provenance["main_commit"]
)
when "identical-tree-attestation"
validate_identical_tree_attestation!(candidate, provenance, consumer_commit)
else
raise PromotionError, "unknown promotion provenance kind #{provenance['kind'].inspect}"
end
end
def validate_identical_tree_attestation!(candidate, provenance, consumer_commit)
validate_full_commit!(provenance["pull_request_commit"], "attested pull request commit")
validate_full_commit!(provenance["pull_request_tree"], "attested pull request tree")
validate_full_commit!(provenance["main_commit"], "attested main commit")
validate_full_commit!(provenance["main_tree"], "attested main tree")
validate_timestamp!(provenance["attested_at"], "identical-tree attestation timestamp")
unless provenance["pull_request_commit"] == consumer_commit &&
provenance["pull_request_tree"] == candidate.dig("consumer_ref", "tree") &&
provenance["main_tree"] == provenance["pull_request_tree"]
raise PromotionError, "identical-tree attestation does not match the candidate and main trees"
end
validate_post_merge_canary!(
provenance["post_merge_canary"],
consumer_commit: provenance["main_commit"]
)
end
def validate_post_merge_canary!(canary, consumer_commit:)
unless canary.is_a?(Hash) && canary["status"] == "pass"
raise PromotionError, "promotion requires a passing post-merge canary"
end
validate_timestamp!(canary["checked_at"], "post-merge canary timestamp")
evidence = Array(canary["evidence"])
if evidence.empty? || evidence.any? { |path| !path.is_a?(String) || !path.start_with?("evidence/") }
raise PromotionError, "post-merge canary must reference evidence under evidence/"
end
evidence.each do |reference|
validate_post_merge_canary_evidence!(
reference,
checked_at: canary.fetch("checked_at"),
consumer_commit: consumer_commit
)
end
end
def validate_post_merge_canary_evidence!(reference, checked_at:, consumer_commit:)
relative = Pathname.new(reference).cleanpath
if relative.absolute? || relative.each_filename.first != "evidence"
raise PromotionError, "post-merge canary evidence must stay under evidence/"
end
evidence_root = File.realpath(File.join(@root, "evidence"))
real_path = File.realpath(File.join(@root, relative.to_s))
unless real_path.start_with?("#{evidence_root}#{File::SEPARATOR}")
raise PromotionError, "post-merge canary evidence resolves outside evidence/"
end
document = parse_json(File.read(real_path), relative.to_s)
unless document.is_a?(Hash) && document["schema_version"] == 1 &&
document["status"] == "pass" && document["checked_at"] == checked_at &&
document["consumer_commit"] == consumer_commit
raise PromotionError,
"post-merge canary evidence must match its passing timestamp and main consumer commit"
end
rescue Errno::ENOENT
raise PromotionError, "post-merge canary evidence does not exist: #{reference}"
end
def validate_promotion_product_artifacts!(runtime)
selection = runtime["product_selection"]
return unless selection
selected_products = selection.fetch("references").keys.sort
artifact_products = runtime.fetch("product_images", {}).keys.sort
return if selected_products == artifact_products
raise PromotionError,
"promotion requires exact content IDs or digests for every selected product image"
end
def fetch_profile!(consumer_entry, consumer)
profile = consumer_entry["profile"]
unless profile.is_a?(String) && profile.match?(/\A[a-z0-9][a-z0-9-]*\z/)
@@ -172,6 +396,11 @@ module OpenCodeCompat
end
def certify_previous!(tuple, consumer:, profile:, supplied:, expected_fingerprint:)
if NON_CERTIFIABLE_TUPLE_STATUSES.include?(tuple["status"])
raise PromotionError,
"current tuple is known to fail the compatibility contract and cannot become a certified rollback"
end
if tuple["status"] == "certified"
validate_recorded_certification!(
tuple,
@@ -340,6 +569,46 @@ module OpenCodeCompat
end
validate_full_commit!(client["git_commit"], "#{label} git commit")
validate_client_source!(client, label, required: false)
end
def validate_client_source!(client, label, required:)
source = client["source"]
if source.nil?
raise PromotionError, "#{label} must include loaded exact-ref source proof" if required
return
end
unless source.is_a?(Hash) && source["type"] == "git" && source["uri"].is_a?(String) && !source["uri"].empty?
raise PromotionError, "#{label} source must identify its Git URI"
end
commit = client.fetch("git_commit")
%w[requested_ref locked_revision].each do |key|
unless source[key] == commit
raise PromotionError, "#{label} source #{key} must equal the peeled client commit"
end
end
proof = source["loaded_source_proof"]
unless proof.is_a?(Hash) && proof["status"] == "pass" && proof["source_class"] == "Bundler::Source::Git"
raise PromotionError, "#{label} must include passing Bundler Git loaded-source proof"
end
expected = {
"loaded_version" => client.fetch("version"),
"observed_revision" => commit
}
expected.each do |key, value|
unless proof[key] == value
raise PromotionError, "#{label} loaded-source proof #{key} must equal #{value.inspect}"
end
end
if proof.key?("observed_ref") && proof["observed_ref"] != commit
raise PromotionError, "#{label} loaded-source proof observed_ref must equal #{commit.inspect}"
end
unless proof["test"].is_a?(String) && !proof["test"].empty?
raise PromotionError, "#{label} loaded-source proof must name the consumer test"
end
end
def validate_runtime!(runtime, label)
@@ -349,6 +618,47 @@ module OpenCodeCompat
end
exact_execution_coordinate = false
product_selection = runtime["product_selection"]
if product_selection
unless product_selection.is_a?(Hash) && product_selection["strategy"] == "full-consumer-commit-tag"
raise PromotionError, "#{label} product_selection must use the full-consumer-commit-tag strategy"
end
validate_full_commit!(product_selection["source_commit"], "#{label} product selection source commit")
references = product_selection["references"]
unless references.is_a?(Hash) && !references.empty?
raise PromotionError, "#{label} product selection references must be a non-empty object"
end
references.each do |product, reference|
unless product.match?(/\A[a-z0-9][a-z0-9-]*\z/) &&
reference.is_a?(String) && reference.end_with?(":#{product_selection['source_commit']}")
raise PromotionError,
"#{label} #{product} selection must end in the full consumer commit tag"
end
end
exact_execution_coordinate = true
end
product_images = runtime["product_images"]
if product_images
unless product_images.is_a?(Hash) && !product_images.empty?
raise PromotionError, "#{label} product_images must be a non-empty object"
end
product_images.each do |product, coordinate|
unless product.match?(/\A[a-z0-9][a-z0-9-]*\z/) && coordinate.is_a?(Hash)
raise PromotionError, "#{label} product image entries must use named coordinate objects"
end
image_id = coordinate["docker_image_id"]
image = coordinate["image"]
unless (image_id.is_a?(String) && image_id.match?(DIGEST)) ||
(image.is_a?(String) && image.match?(IMMUTABLE_IMAGE))
raise PromotionError,
"#{label} #{product} product image must include an exact sha256 image ID or OCI digest"
end
validate_full_commit!(coordinate["source_commit"], "#{label} #{product} source commit")
exact_execution_coordinate = true
end
end
runtime.each do |key, value|
if key == "docker_image_id" || key.end_with?("_image_id")
unless value.is_a?(String) && value.match?(DIGEST)
@@ -449,6 +759,15 @@ module OpenCodeCompat
end
end
def migration_state_for(manifest)
return "certified" if all_consumers_certified?(manifest)
degraded = manifest.fetch("consumers").any? do |_consumer, entry|
entry.dig("rollback_state", "status") == "degraded-no-certified-previous"
end
degraded ? "bootstrap-current-only" : "candidate"
end
def with_current_manifest_lock
loop do
retry_with_new_inode = false

View File

@@ -1,6 +1,11 @@
{
"repository": "ajaynomics/opencode-ruby",
"ref": "a116b2708cc148f61b1e1fae0405553c099f4202",
"version": "0.0.1.alpha6",
"ref": "78b6f9c9e9c7d58b699af1c3c17764acd33de798",
"version": "0.0.1.alpha7",
"tag_provenance": {
"tag": "v0.0.1.alpha7",
"annotated_tag_object": "abfce3ec8cb1ee468107d0845521769502251645",
"peeled_commit": "78b6f9c9e9c7d58b699af1c3c17764acd33de798"
},
"status": "candidate"
}

View File

@@ -7,8 +7,14 @@
"image": "ghcr.io/anomalyco/opencode@sha256:e975a0647576016dfdf77d54b979ca30d32b4750472c10263e9894aad6628c2a",
"tag_provenance": "ghcr.io/anomalyco/opencode:1.16.1",
"consumers": ["travelwolf"],
"profiles": ["ruby-rest-sse", "rails-persisted-turn"],
"certification_status": "certified"
"profiles": ["ruby-rest-sse"],
"required_consumer_profiles": ["rails-persisted-turn"],
"certification_status": "certified",
"certified_client_commit": "78b6f9c9e9c7d58b699af1c3c17764acd33de798",
"certified_at": "2026-07-18T23:35:57Z",
"expected_text": "compat-ok",
"full_text": "compat-ok",
"llm_request_count": 1
},
{
"id": "upstream-1.17.18",
@@ -16,8 +22,14 @@
"image": "ghcr.io/anomalyco/opencode@sha256:bf9d0e84b7cedef436a8f57db4d48767cd5d8fc6604f666335c1cc916b199a97",
"tag_provenance": "ghcr.io/anomalyco/opencode:1.17.18",
"consumers": ["opencode-ajent"],
"profiles": ["plugin-ledger", "ruby-rest-sse"],
"certification_status": "certified"
"profiles": ["ruby-rest-sse"],
"required_consumer_profiles": ["plugin-ledger"],
"certification_status": "certified",
"certified_client_commit": "78b6f9c9e9c7d58b699af1c3c17764acd33de798",
"certified_at": "2026-07-18T23:35:58Z",
"expected_text": "compat-ok",
"full_text": "compat-ok",
"llm_request_count": 1
},
{
"id": "upstream-1.18.3",
@@ -25,34 +37,57 @@
"image": "ghcr.io/anomalyco/opencode@sha256:c2d5d6398df72aac85cb1bdc8f900c71a9b75a33fb7c0a76dc1484e4b126e41e",
"tag_provenance": "ghcr.io/anomalyco/opencode:1.18.3",
"consumers": ["ajent-rails"],
"profiles": ["ruby-rest-sse", "rails-persisted-turn", "plugin-ledger"],
"certification_status": "certified"
"profiles": ["ruby-rest-sse"],
"required_consumer_profiles": ["rails-persisted-turn", "plugin-ledger"],
"certification_status": "certified",
"certified_client_commit": "78b6f9c9e9c7d58b699af1c3c17764acd33de798",
"certified_at": "2026-07-18T23:35:58Z",
"expected_text": "compat-ok",
"full_text": "compat-ok",
"llm_request_count": 1
}
],
"host_canary": [
{
"id": "ajent-blackline-live",
"id": "ajent-blackline-alpha7-canary",
"consumer": "ajent-rails",
"registry_ref": "docker-registry:5000/opencode-blackline:83eed3c247a352842b08fc5cf339c4d0acdaacba",
"docker_image_id": "sha256:6fb2b3bf8e4cdf48e16bf6c3475e953df2f8304e77f5efe816ceb46f905eead8",
"consumer_commit": "01cdf9da8e1b3f9a205d681e448aefefd9704db2",
"consumer_ref_kind": "pull-request-head",
"certification_scope": "pre-merge-pr-head-candidate-only",
"promotion_eligible": false,
"tag_provenance": "ajent-opencode-blackline-canary:01cdf9da8e1b3f9a205d681e448aefefd9704db2",
"docker_image_id": "sha256:075cb49ac7fcb1f8972e051dff96d655fa0d0d911d83a523a6abf03a5e2e2935",
"source_commit": "01cdf9da8e1b3f9a205d681e448aefefd9704db2",
"reported_version": "1.18.3",
"upstream_base": "ghcr.io/anomalyco/opencode@sha256:c2d5d6398df72aac85cb1bdc8f900c71a9b75a33fb7c0a76dc1484e4b126e41e",
"profiles": ["ruby-rest-sse", "rails-persisted-turn", "plugin-ledger"],
"profiles": ["rails-persisted-turn"],
"certification_status": "candidate-certified",
"certified_candidate": "a116b2708cc148f61b1e1fae0405553c099f4202",
"certified_at": "2026-07-18T20:34:10Z"
"certified_client_commit": "78b6f9c9e9c7d58b699af1c3c17764acd33de798",
"certified_rails_commit": "2a391ccad1d098e4bb51eb19b6ca52adaa79e5cb",
"certified_at": "2026-07-18T23:28:16.435369Z",
"persisted_final_text": "compat-ok",
"authoritative_final_text": "compat-ok",
"model_request_count": 1,
"product_artifacts_missing_before_promotion": ["aigl", "raven"]
},
{
"id": "mushu-permission-shortcuts-live",
"id": "mushu-permission-shortcuts-alpha7-canary",
"consumer": "mushu",
"registry_ref": "docker-registry:5000/mushu-opencode:sha-99d6328b1",
"consumer_commit": "7cff22788b36ae703f6b1b8fa39b52d6dbafe7e0",
"consumer_ref_kind": "pull-request-head",
"certification_scope": "pre-merge-pr-head-candidate-only",
"promotion_eligible": false,
"tag_provenance": "docker-registry:5000/mushu-opencode:sha-99d6328b1",
"image": "docker-registry:5000/mushu-opencode@sha256:ed6293ca87e6db1dc07870d3ed6da21960743e6e2e904533b3c566d334b58d6a",
"docker_image_id": "sha256:ed6293ca87e6db1dc07870d3ed6da21960743e6e2e904533b3c566d334b58d6a",
"reported_version": "0.0.0-permission-shortcuts-202606300721",
"source_commit": "99d6328b18ff8a340a928449a2aa8bc184a063f9",
"reported_version": "0.0.0-permission-shortcuts-202606300721",
"profiles": ["ruby-rest-sse"],
"certification_status": "candidate-certified",
"certified_candidate": "a116b2708cc148f61b1e1fae0405553c099f4202",
"certified_at": "2026-07-18T20:34:08Z"
"certified_client_commit": "78b6f9c9e9c7d58b699af1c3c17764acd33de798",
"certified_at": "2026-07-18T23:26:06.865190Z",
"authoritative_final_text": "compat-ok",
"provider_request_count": 1
}
]
}

View File

@@ -1,41 +1,184 @@
{
"schema_version": 1,
"$schema": "../schemas/runtime-tuples.schema.json",
"schema_version": 2,
"migration_state": "candidate",
"promotion_readiness": {
"status": "blocked",
"reason": "Every observed alpha2 baseline fails the hardened exact-final-text contract, so none can be certified as the previous rollback tuple; the passing evidence is also bound to unmerged pull-request heads.",
"evidence": "evidence/2026-07-18-opencode-ruby-alpha2-regression.json",
"required_action": "Merge, deploy, and canary the exact main/merge tuple (or record an identical-tree attestation plus post-merge canary), then explicitly acknowledge bootstrap-current-only; previous remains null until the next meaningful independently passing release."
},
"consumers": {
"ajent-rails": {
"profile": "rails-persisted-turn",
"current": {
"status": "observed-production",
"consumer_commit": "83eed3c247a352842b08fc5cf339c4d0acdaacba",
"opencode_ruby": {"version": "0.0.1.alpha2", "git_commit": "889d383"},
"opencode_rails": {"version": "0.0.1.alpha2", "git_commit": "9b0c4cd"},
"status": "observed-production-contract-failed",
"consumer_commit": "8d8550265dca0ac06a41d5427c585ede56bbb808",
"opencode_ruby": {
"version": "0.0.1.alpha2",
"git_commit": "889d38332f98f5f7b76d16952b7204d8a5b9a662"
},
"opencode_rails": {
"version": "0.0.1.alpha2",
"git_commit": "9b0c4cd3cd31bdfebbb89567daca012d68a356ea"
},
"runtime": {
"registry_ref": "docker-registry:5000/opencode-blackline:83eed3c247a352842b08fc5cf339c4d0acdaacba",
"docker_image_id": "sha256:6fb2b3bf8e4cdf48e16bf6c3475e953df2f8304e77f5efe816ceb46f905eead8",
"tag_provenance": "docker-registry:5000/opencode-blackline:8d8550265dca0ac06a41d5427c585ede56bbb808",
"docker_image_id": "sha256:af479243e6ccf1206f57dffd13b8e9d2c028de401cccc954bcc2f00940274c60",
"source_commit": "8d8550265dca0ac06a41d5427c585ede56bbb808",
"reported_version": "1.18.3",
"upstream_base": "ghcr.io/anomalyco/opencode@sha256:c2d5d6398df72aac85cb1bdc8f900c71a9b75a33fb7c0a76dc1484e4b126e41e"
"upstream_base": "ghcr.io/anomalyco/opencode@sha256:c2d5d6398df72aac85cb1bdc8f900c71a9b75a33fb7c0a76dc1484e4b126e41e",
"upstream_base_proof": {
"method": "rootfs-prefix-layer-match",
"matched_layer_count": 4,
"status": "pass",
"note": "The deployed images match the exact 1.18.3 base layers even though this main commit selected the mutable upstream tag at build time."
},
"deployed_product_selection": {
"strategy": "mutable-latest",
"status": "observed-configuration-drift-failure",
"references": {
"aigl": "docker-registry:5000/opencode-aigl:latest",
"blackline": "docker-registry:5000/opencode-blackline:latest",
"raven": "docker-registry:5000/opencode-raven:latest"
},
"note": "The shared Blackline accessory used the SHA tag above, but Rails ProductConfig resolved per-user AIGL, Blackline, and Raven containers through mutable latest references."
},
"ci_built_product_images": {
"aigl": {
"tag_provenance": "docker-registry:5000/opencode-aigl:8d8550265dca0ac06a41d5427c585ede56bbb808",
"docker_image_id": "sha256:72c454f39d423618b75439122c9073dbba7c9071421e5f3abd12cf288dc1f898",
"source_commit": "8d8550265dca0ac06a41d5427c585ede56bbb808"
},
"blackline": {
"tag_provenance": "docker-registry:5000/opencode-blackline:8d8550265dca0ac06a41d5427c585ede56bbb808",
"docker_image_id": "sha256:af479243e6ccf1206f57dffd13b8e9d2c028de401cccc954bcc2f00940274c60",
"source_commit": "8d8550265dca0ac06a41d5427c585ede56bbb808"
},
"raven": {
"tag_provenance": "docker-registry:5000/opencode-raven:8d8550265dca0ac06a41d5427c585ede56bbb808",
"docker_image_id": "sha256:6c4da94a8dec6160f0b1b4d0e2cd9ff38a3faa18dbd2a8d6023a71f6416a544c",
"source_commit": "8d8550265dca0ac06a41d5427c585ede56bbb808"
}
}
}
},
"candidate": {
"status": "compatibility-certified",
"opencode_ruby": {"version": "0.0.1.alpha6", "git_commit": "a116b2708cc148f61b1e1fae0405553c099f4202"},
"opencode_rails": {"version": "0.0.1.alpha6", "git_commit": "17025f0ed955899c57830eaea34da49f07250fcc"},
"runtime": {
"docker_image_id": "sha256:6fb2b3bf8e4cdf48e16bf6c3475e953df2f8304e77f5efe816ceb46f905eead8",
"reported_version": "1.18.3",
"upstream_base": "ghcr.io/anomalyco/opencode@sha256:c2d5d6398df72aac85cb1bdc8f900c71a9b75a33fb7c0a76dc1484e4b126e41e"
"certification_scope": "pre-merge-pr-head-candidate-only",
"promotion_eligible": false,
"promotion_blockers": [
"consumer-ref-is-an-unmerged-pull-request-head",
"aigl-and-raven-candidate-content-artifacts-have-not-been-built-and-canaried",
"no-certified-previous-tuple"
],
"consumer_commit": "01cdf9da8e1b3f9a205d681e448aefefd9704db2",
"consumer_ref": {
"kind": "pull-request-head",
"repository": "ajaynomics/ajent-rails",
"commit": "01cdf9da8e1b3f9a205d681e448aefefd9704db2",
"tree": "9e93834ad16b60fa5edfe1cb3baaba193402be74",
"base_commit": "8d8550265dca0ac06a41d5427c585ede56bbb808",
"review_url": "https://gitea.ajay.to/ajaynomics/ajent-rails/pulls/946"
},
"certified_at": "2026-07-18T20:34:10Z"
"opencode_ruby": {
"version": "0.0.1.alpha7",
"git_commit": "78b6f9c9e9c7d58b699af1c3c17764acd33de798",
"tag_provenance": {
"tag": "v0.0.1.alpha7",
"annotated_tag_object": "abfce3ec8cb1ee468107d0845521769502251645"
},
"source": {
"type": "git",
"uri": "https://gitea.krishnan.ca/ajaynomics/opencode-ruby.git",
"requested_ref": "78b6f9c9e9c7d58b699af1c3c17764acd33de798",
"locked_revision": "78b6f9c9e9c7d58b699af1c3c17764acd33de798",
"loaded_source_proof": {
"status": "pass",
"source_class": "Bundler::Source::Git",
"loaded_version": "0.0.1.alpha7",
"observed_revision": "78b6f9c9e9c7d58b699af1c3c17764acd33de798",
"test": "test/lib/opencode/runtime_image_provenance_test.rb"
}
}
},
"opencode_rails": {
"version": "0.0.1.alpha7",
"git_commit": "2a391ccad1d098e4bb51eb19b6ca52adaa79e5cb",
"tag_provenance": {
"tag": "v0.0.1.alpha7",
"annotated_tag_object": "61e128084b2b665c0ba20b332987e41794948d7c"
},
"source": {
"type": "git",
"uri": "https://gitea.krishnan.ca/ajaynomics/opencode-rails.git",
"requested_ref": "2a391ccad1d098e4bb51eb19b6ca52adaa79e5cb",
"locked_revision": "2a391ccad1d098e4bb51eb19b6ca52adaa79e5cb",
"loaded_source_proof": {
"status": "pass",
"source_class": "Bundler::Source::Git",
"loaded_version": "0.0.1.alpha7",
"observed_revision": "2a391ccad1d098e4bb51eb19b6ca52adaa79e5cb",
"test": "test/lib/opencode/runtime_image_provenance_test.rb"
}
}
},
"runtime": {
"reported_version": "1.18.3",
"upstream_base": "ghcr.io/anomalyco/opencode@sha256:c2d5d6398df72aac85cb1bdc8f900c71a9b75a33fb7c0a76dc1484e4b126e41e",
"product_selection": {
"strategy": "full-consumer-commit-tag",
"source_commit": "01cdf9da8e1b3f9a205d681e448aefefd9704db2",
"references": {
"aigl": "docker-registry:5000/opencode-aigl:01cdf9da8e1b3f9a205d681e448aefefd9704db2",
"blackline": "docker-registry:5000/opencode-blackline:01cdf9da8e1b3f9a205d681e448aefefd9704db2",
"raven": "docker-registry:5000/opencode-raven:01cdf9da8e1b3f9a205d681e448aefefd9704db2"
}
},
"product_images": {
"blackline": {
"tag_provenance": "ajent-opencode-blackline-canary:01cdf9da8e1b3f9a205d681e448aefefd9704db2",
"docker_image_id": "sha256:075cb49ac7fcb1f8972e051dff96d655fa0d0d911d83a523a6abf03a5e2e2935",
"source_commit": "01cdf9da8e1b3f9a205d681e448aefefd9704db2"
}
}
},
"deterministic_contract": {
"checked_at": "2026-07-18T23:16:13Z",
"docker_image_id": "sha256:075cb49ac7fcb1f8972e051dff96d655fa0d0d911d83a523a6abf03a5e2e2935",
"expected_text": "compat-ok",
"full_text": "compat-ok",
"authoritative_assistant_count": 1,
"model_request_count": 1,
"status": "pass"
},
"application_canary": {
"checked_at": "2026-07-18T23:28:16.435369Z",
"path": "Blackline::GenerateResponseJob",
"persisted_final_text": "compat-ok",
"authoritative_final_text": "compat-ok",
"authoritative_assistant_count": 1,
"model_request_count": 1,
"cleanup_status": "pass",
"status": "pass"
},
"certified_at": "2026-07-18T23:28:16.435369Z"
},
"previous": null
},
"travelwolf": {
"profile": "rails-persisted-turn",
"current": {
"status": "repository-configured",
"status": "observed-production-contract-failed",
"consumer_commit": "1ca756d64f058c9e0379f69fc4a3d53330cfcd15",
"opencode_ruby": {"version": "0.0.1.alpha2", "git_commit": "889d383"},
"opencode_rails": {"version": "0.0.1.alpha2", "git_commit": "9b0c4cd"},
"opencode_ruby": {
"version": "0.0.1.alpha2",
"git_commit": "889d38332f98f5f7b76d16952b7204d8a5b9a662"
},
"opencode_rails": {
"version": "0.0.1.alpha2",
"git_commit": "9b0c4cd3cd31bdfebbb89567daca012d68a356ea"
},
"runtime": {
"image": "ghcr.io/anomalyco/opencode@sha256:e975a0647576016dfdf77d54b979ca30d32b4750472c10263e9894aad6628c2a",
"reported_version": "1.16.1"
@@ -43,38 +186,190 @@
},
"candidate": {
"status": "compatibility-certified",
"opencode_ruby": {"version": "0.0.1.alpha6", "git_commit": "a116b2708cc148f61b1e1fae0405553c099f4202"},
"opencode_rails": {"version": "0.0.1.alpha6", "git_commit": "17025f0ed955899c57830eaea34da49f07250fcc"},
"certification_scope": "pre-merge-pr-head-candidate-only",
"promotion_eligible": false,
"promotion_blockers": [
"consumer-ref-is-an-unmerged-pull-request-head",
"no-certified-previous-tuple"
],
"consumer_commit": "b9a2c2dd361a6b2ea547cc67ee817b8eb4ce31e8",
"consumer_ref": {
"kind": "pull-request-head",
"repository": "ajaynomics/travelwolf",
"commit": "b9a2c2dd361a6b2ea547cc67ee817b8eb4ce31e8",
"tree": "8b3f8a97dc1f1d8b558a49523bf312d2810422df",
"base_commit": "75c92ed5248996e5278ac9a3351cc4eaf03df820",
"review_url": "https://gitea.ajay.to/ajaynomics/travelwolf/pulls/29"
},
"opencode_ruby": {
"version": "0.0.1.alpha7",
"git_commit": "78b6f9c9e9c7d58b699af1c3c17764acd33de798",
"tag_provenance": {
"tag": "v0.0.1.alpha7",
"annotated_tag_object": "abfce3ec8cb1ee468107d0845521769502251645"
},
"source": {
"type": "git",
"uri": "https://gitea.krishnan.ca/ajaynomics/opencode-ruby.git",
"requested_ref": "78b6f9c9e9c7d58b699af1c3c17764acd33de798",
"locked_revision": "78b6f9c9e9c7d58b699af1c3c17764acd33de798",
"loaded_source_proof": {
"status": "pass",
"source_class": "Bundler::Source::Git",
"loaded_version": "0.0.1.alpha7",
"observed_ref": "78b6f9c9e9c7d58b699af1c3c17764acd33de798",
"observed_revision": "78b6f9c9e9c7d58b699af1c3c17764acd33de798",
"test": "test/services/travelwolf/opencode_env_wiring_test.rb"
}
}
},
"opencode_rails": {
"version": "0.0.1.alpha7",
"git_commit": "2a391ccad1d098e4bb51eb19b6ca52adaa79e5cb",
"tag_provenance": {
"tag": "v0.0.1.alpha7",
"annotated_tag_object": "61e128084b2b665c0ba20b332987e41794948d7c"
},
"source": {
"type": "git",
"uri": "https://gitea.krishnan.ca/ajaynomics/opencode-rails.git",
"requested_ref": "2a391ccad1d098e4bb51eb19b6ca52adaa79e5cb",
"locked_revision": "2a391ccad1d098e4bb51eb19b6ca52adaa79e5cb",
"loaded_source_proof": {
"status": "pass",
"source_class": "Bundler::Source::Git",
"loaded_version": "0.0.1.alpha7",
"observed_ref": "2a391ccad1d098e4bb51eb19b6ca52adaa79e5cb",
"observed_revision": "2a391ccad1d098e4bb51eb19b6ca52adaa79e5cb",
"test": "test/services/travelwolf/opencode_env_wiring_test.rb"
}
}
},
"runtime": {
"image": "ghcr.io/anomalyco/opencode@sha256:e975a0647576016dfdf77d54b979ca30d32b4750472c10263e9894aad6628c2a",
"reported_version": "1.16.1"
},
"certified_at": "2026-07-18T20:34:05Z"
"deterministic_contract": {
"evidence": "evidence/2026-07-18-opencode-ruby-alpha7.json",
"checked_at": "2026-07-18T23:23:03Z",
"image": "ghcr.io/anomalyco/opencode@sha256:e975a0647576016dfdf77d54b979ca30d32b4750472c10263e9894aad6628c2a",
"opencode_ruby_commit": "78b6f9c9e9c7d58b699af1c3c17764acd33de798",
"expected_text": "compat-ok",
"full_text": "compat-ok",
"authoritative_assistant_count": 1,
"model_request_count": 1,
"status": "pass"
},
"application_canary": {
"run_id": "travelwolf-alpha7-ref-20260718T232211Z-48eadf",
"checked_at": "2026-07-18T23:22:26.216140Z",
"final_text": "TRAVELWOLF_ALPHA7_REF_PIN_READY",
"subscription_ready_before_prompt": true,
"opencode_api_prompt_count": 1,
"provider_request_count_observed": false,
"message_roles": [
"user",
"assistant"
],
"cleanup_status": "pass",
"status": "pass"
},
"certified_at": "2026-07-18T23:35:57Z"
},
"previous": null
},
"mushu": {
"profile": "ruby-rest-sse",
"current": {
"status": "observed-production",
"status": "observed-production-contract-failed",
"consumer_commit": "fe16e5bab028e3c92cd5508ef2cebd9bfa23386f",
"opencode_ruby": {"version": "0.0.1.alpha2", "git_commit": "889d383"},
"opencode_ruby": {
"version": "0.0.1.alpha2",
"git_commit": "889d38332f98f5f7b76d16952b7204d8a5b9a662"
},
"runtime": {
"registry_ref": "docker-registry:5000/mushu-opencode:sha-99d6328b1",
"tag_provenance": "docker-registry:5000/mushu-opencode:sha-99d6328b1",
"image": "docker-registry:5000/mushu-opencode@sha256:ed6293ca87e6db1dc07870d3ed6da21960743e6e2e904533b3c566d334b58d6a",
"docker_image_id": "sha256:ed6293ca87e6db1dc07870d3ed6da21960743e6e2e904533b3c566d334b58d6a",
"source_commit": "99d6328b18ff8a340a928449a2aa8bc184a063f9",
"base_image": "docker-registry:5000/mushu-opencode-base@sha256:de8a6adeefb30ce1c474cde23fe173dfe059434a13df0a54d14c7473edb33e16",
"reported_version": "0.0.0-permission-shortcuts-202606300721"
}
},
"candidate": {
"status": "compatibility-certified",
"opencode_ruby": {"version": "0.0.1.alpha6", "git_commit": "a116b2708cc148f61b1e1fae0405553c099f4202"},
"certification_scope": "pre-merge-pr-head-candidate-only",
"promotion_eligible": false,
"promotion_blockers": [
"consumer-ref-is-an-unmerged-pull-request-head",
"no-certified-previous-tuple"
],
"consumer_commit": "7cff22788b36ae703f6b1b8fa39b52d6dbafe7e0",
"consumer_ref": {
"kind": "pull-request-head",
"repository": "ajaynomics/mushu",
"commit": "7cff22788b36ae703f6b1b8fa39b52d6dbafe7e0",
"tree": "762eb8dcc7042a52cd240ca69acdb9cb45150a84",
"base_commit": "fe16e5bab028e3c92cd5508ef2cebd9bfa23386f",
"review_url": "https://gitea.ajay.to/ajaynomics/mushu/pulls/1"
},
"opencode_ruby": {
"version": "0.0.1.alpha7",
"git_commit": "78b6f9c9e9c7d58b699af1c3c17764acd33de798",
"tag_provenance": {
"tag": "v0.0.1.alpha7",
"annotated_tag_object": "abfce3ec8cb1ee468107d0845521769502251645"
},
"source": {
"type": "git",
"uri": "https://gitea.krishnan.ca/ajaynomics/opencode-ruby.git",
"requested_ref": "78b6f9c9e9c7d58b699af1c3c17764acd33de798",
"locked_revision": "78b6f9c9e9c7d58b699af1c3c17764acd33de798",
"loaded_source_proof": {
"status": "pass",
"source_class": "Bundler::Source::Git",
"loaded_version": "0.0.1.alpha7",
"observed_ref": "78b6f9c9e9c7d58b699af1c3c17764acd33de798",
"observed_revision": "78b6f9c9e9c7d58b699af1c3c17764acd33de798",
"loaded_file_within_spec": true,
"test": "test/services/mushu/runtime/opencode_dependency_provenance_test.rb"
}
}
},
"runtime": {
"tag_provenance": "docker-registry:5000/mushu-opencode:sha-99d6328b1",
"image": "docker-registry:5000/mushu-opencode@sha256:ed6293ca87e6db1dc07870d3ed6da21960743e6e2e904533b3c566d334b58d6a",
"docker_image_id": "sha256:ed6293ca87e6db1dc07870d3ed6da21960743e6e2e904533b3c566d334b58d6a",
"source_commit": "99d6328b18ff8a340a928449a2aa8bc184a063f9",
"base_image": "docker-registry:5000/mushu-opencode-base@sha256:de8a6adeefb30ce1c474cde23fe173dfe059434a13df0a54d14c7473edb33e16",
"reported_version": "0.0.0-permission-shortcuts-202606300721"
},
"certified_at": "2026-07-18T20:34:08Z"
"deterministic_contract": {
"checked_at": "2026-07-18T23:23:41Z",
"image": "docker-registry:5000/mushu-opencode@sha256:ed6293ca87e6db1dc07870d3ed6da21960743e6e2e904533b3c566d334b58d6a",
"expected_text": "compat-ok",
"full_text": "compat-ok",
"authoritative_assistant_count": 1,
"model_request_count": 1,
"status": "pass"
},
"application_canary": {
"checked_at": "2026-07-18T23:26:06.865190Z",
"response_text": "compat-ok",
"authoritative_final_text": "compat-ok",
"message_roles": [
"user",
"assistant"
],
"authoritative_assistant_count": 1,
"provider_request_count": 1,
"mapping_and_last_turn_persisted": true,
"active_claim_cleared": true,
"opencode_session_deleted": true,
"synthetic_database_rows_after_cleanup": 0,
"status": "pass"
},
"certified_at": "2026-07-18T23:26:06.865190Z"
},
"previous": null
}

View File

@@ -1,6 +1,8 @@
{
"id": "plugin-ledger",
"owner": "opencode-ajent",
"certification_mode": "executable-consumer-attestation",
"shared_ruby_probe_sufficient": false,
"required_behaviors": [
"exact-upstream-image",
"exact-plugin-version",

View File

@@ -1,6 +1,8 @@
{
"id": "provider-hooks",
"owner": "inference",
"certification_mode": "executable-consumer-attestation",
"shared_ruby_probe_sufficient": false,
"required_behaviors": [
"provider-schema",
"model-routing",

View File

@@ -1,6 +1,8 @@
{
"id": "rails-persisted-turn",
"owner": "opencode-rails",
"certification_mode": "executable-consumer-attestation",
"shared_ruby_probe_sufficient": false,
"extends": ["ruby-rest-sse"],
"required_behaviors": [
"session-recovery",

View File

@@ -1,6 +1,8 @@
{
"id": "ruby-rest-sse",
"owner": "opencode-ruby",
"certification_mode": "shared-ruby-fixture-and-live-probe",
"shared_ruby_probe_sufficient": true,
"required_fixtures": [
"legacy-idle",
"current-status-idle",

View File

@@ -1,6 +1,8 @@
{
"id": "strict-v2",
"owner": "leela",
"certification_mode": "executable-consumer-attestation",
"shared_ruby_probe_sufficient": false,
"required_behaviors": [
"exact-upstream-version-and-commit",
"bun-toolchain-provenance",

View File

@@ -1,6 +1,8 @@
{
"id": "voice-stream",
"owner": "greenroom",
"certification_mode": "executable-consumer-attestation",
"shared_ruby_probe_sufficient": false,
"extends": ["ruby-rest-sse"],
"required_behaviors": [
"legacy-and-current-terminal-events",

View File

@@ -0,0 +1,33 @@
# frozen_string_literal: true
module OpenCodeCompat
module ExactLiveContract
class ContractError < StandardError; end
module_function
def assert_final_text!(actual, expected)
return if actual == expected
raise ContractError, "Expected final text to equal #{expected.inspect}, got #{actual.inspect}"
end
def assert_model_request_count!(value)
count = Integer(value, 10)
return if count == 1
raise ContractError, "Expected exactly one deterministic model request, got #{count}"
rescue ArgumentError, TypeError
raise ContractError, "Deterministic model request count is not an integer: #{value.inspect}"
end
end
end
if $PROGRAM_NAME == __FILE__
begin
OpenCodeCompat::ExactLiveContract.assert_model_request_count!(ARGV.fetch(0))
rescue IndexError, OpenCodeCompat::ExactLiveContract::ContractError => error
warn error.message
exit 1
end
end

View File

@@ -2,6 +2,7 @@
require "json"
require "time"
require_relative "exact_live_contract"
gem_path = File.expand_path(ENV.fetch("OPENCODE_RUBY_PATH"))
$LOAD_PATH.unshift(File.join(gem_path, "lib"))
@@ -32,9 +33,7 @@ begin
observed_parts << JSON.parse(JSON.generate(part))
end
unless result.full_text.include?(expected_text)
raise "Expected final text to include #{expected_text.inspect}, got #{result.full_text.inspect}"
end
OpenCodeCompat::ExactLiveContract.assert_final_text!(result.full_text, expected_text)
messages = client.get_messages(session_id)
assistant_messages = Array(messages).select { |message| message.dig(:info, :role) == "assistant" }

View File

@@ -0,0 +1,401 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://github.com/ajaynomics/opencode-compat/schemas/runtime-tuples.schema.json",
"title": "OpenCode runtime tuple ledger",
"type": "object",
"required": [
"schema_version",
"migration_state",
"promotion_readiness",
"consumers"
],
"properties": {
"schema_version": {
"const": 2
},
"migration_state": {
"enum": [
"candidate",
"bootstrap-current-only",
"certified"
]
},
"consumers": {
"type": "object",
"additionalProperties": {
"type": "object",
"required": [
"profile",
"current",
"candidate",
"previous"
],
"properties": {
"rollback_state": {
"type": "object",
"required": [
"status",
"acknowledgement",
"recorded_at",
"emergency_provenance_status"
],
"properties": {
"status": {
"const": "degraded-no-certified-previous"
},
"acknowledgement": {
"const": "accept-degraded-rollback-with-failed-emergency-provenance"
},
"emergency_provenance_status": {
"const": "observed-production-contract-failed"
}
}
},
"candidate": {
"oneOf": [
{
"type": "null"
},
{
"$ref": "#/$defs/candidate"
}
]
}
}
}
}
},
"$defs": {
"fullCommit": {
"type": "string",
"pattern": "^[0-9a-f]{40}$"
},
"loadedGitSource": {
"type": "object",
"required": [
"type",
"uri",
"requested_ref",
"locked_revision",
"loaded_source_proof"
],
"properties": {
"type": {
"const": "git"
},
"requested_ref": {
"$ref": "#/$defs/fullCommit"
},
"locked_revision": {
"$ref": "#/$defs/fullCommit"
},
"loaded_source_proof": {
"type": "object",
"required": [
"status",
"source_class",
"loaded_version",
"observed_revision",
"test"
],
"properties": {
"status": {
"const": "pass"
},
"source_class": {
"const": "Bundler::Source::Git"
},
"observed_ref": {
"$ref": "#/$defs/fullCommit"
},
"observed_revision": {
"$ref": "#/$defs/fullCommit"
}
}
}
}
},
"client": {
"type": "object",
"required": [
"version",
"git_commit",
"source"
],
"properties": {
"git_commit": {
"$ref": "#/$defs/fullCommit"
},
"source": {
"$ref": "#/$defs/loadedGitSource"
}
}
},
"consumerRef": {
"type": "object",
"required": [
"kind",
"repository",
"commit",
"tree"
],
"properties": {
"kind": {
"enum": [
"pull-request-head",
"main-commit"
]
},
"commit": {
"$ref": "#/$defs/fullCommit"
},
"tree": {
"$ref": "#/$defs/fullCommit"
},
"base_commit": {
"$ref": "#/$defs/fullCommit"
}
},
"allOf": [
{
"if": {
"properties": {
"kind": {
"const": "pull-request-head"
}
}
},
"then": {
"required": [
"base_commit",
"review_url"
]
}
}
]
},
"promotionProvenance": {
"oneOf": [
{
"type": "object",
"required": [
"kind",
"main_commit",
"post_merge_canary"
],
"properties": {
"kind": {
"const": "main-commit"
},
"main_commit": {
"$ref": "#/$defs/fullCommit"
},
"post_merge_canary": {
"type": "object",
"required": [
"status",
"checked_at",
"evidence"
],
"properties": {
"status": {
"const": "pass"
},
"evidence": {
"type": "array",
"minItems": 1,
"items": {
"type": "string",
"pattern": "^evidence/"
}
}
}
}
}
},
{
"type": "object",
"required": [
"kind",
"pull_request_commit",
"pull_request_tree",
"main_commit",
"main_tree",
"attested_at",
"post_merge_canary"
],
"properties": {
"kind": {
"const": "identical-tree-attestation"
},
"pull_request_commit": {
"$ref": "#/$defs/fullCommit"
},
"pull_request_tree": {
"$ref": "#/$defs/fullCommit"
},
"main_commit": {
"$ref": "#/$defs/fullCommit"
},
"main_tree": {
"$ref": "#/$defs/fullCommit"
},
"post_merge_canary": {
"type": "object",
"required": [
"status",
"checked_at",
"evidence"
],
"properties": {
"status": {
"const": "pass"
},
"evidence": {
"type": "array",
"minItems": 1,
"items": {
"type": "string",
"pattern": "^evidence/"
}
}
}
}
}
}
]
},
"runtime": {
"type": "object",
"required": [
"reported_version"
],
"properties": {
"product_selection": {
"type": "object",
"required": [
"strategy",
"source_commit",
"references"
],
"properties": {
"strategy": {
"const": "full-consumer-commit-tag"
},
"source_commit": {
"$ref": "#/$defs/fullCommit"
},
"references": {
"type": "object",
"minProperties": 1,
"additionalProperties": {
"type": "string",
"pattern": ":[0-9a-f]{40}$"
}
}
}
},
"product_images": {
"type": "object",
"minProperties": 1,
"additionalProperties": {
"type": "object",
"required": [
"source_commit"
],
"properties": {
"source_commit": {
"$ref": "#/$defs/fullCommit"
},
"docker_image_id": {
"type": "string",
"pattern": "^sha256:[0-9a-f]{64}$"
},
"image": {
"type": "string",
"pattern": "@sha256:[0-9a-f]{64}$"
}
},
"anyOf": [
{
"required": [
"docker_image_id"
]
},
{
"required": [
"image"
]
}
]
}
}
}
},
"candidate": {
"type": "object",
"required": [
"status",
"certification_scope",
"promotion_eligible",
"consumer_commit",
"consumer_ref",
"opencode_ruby",
"runtime"
],
"properties": {
"status": {
"const": "compatibility-certified"
},
"certification_scope": {
"enum": [
"pre-merge-pr-head-candidate-only",
"promotion-deployed"
]
},
"promotion_eligible": {
"type": "boolean"
},
"consumer_commit": {
"$ref": "#/$defs/fullCommit"
},
"consumer_ref": {
"$ref": "#/$defs/consumerRef"
},
"promotion_provenance": {
"$ref": "#/$defs/promotionProvenance"
},
"opencode_ruby": {
"$ref": "#/$defs/client"
},
"opencode_rails": {
"$ref": "#/$defs/client"
},
"runtime": {
"$ref": "#/$defs/runtime"
}
},
"allOf": [
{
"if": {
"properties": {
"promotion_eligible": {
"const": true
}
}
},
"then": {
"required": [
"promotion_provenance"
],
"properties": {
"certification_scope": {
"const": "promotion-deployed"
}
}
}
}
]
}
}
}

View File

@@ -20,6 +20,10 @@ parser = OptionParser.new do |opts|
--status pass --certified-at TIMESTAMP --evidence evidence/FILE.json \\
[--previous-status pass --previous-certified-at TIMESTAMP \\
--previous-evidence evidence/FILE.json] [--dry-run]
ruby scripts/promote_runtime_tuple.rb bootstrap-current --consumer NAME --consumer-commit SHA \\
--status pass --certified-at TIMESTAMP --evidence evidence/FILE.json \\
--acknowledge-degraded-rollback \\
accept-degraded-rollback-with-failed-emergency-provenance [--dry-run]
USAGE
opts.on("--consumer NAME") { |value| options["consumer"] = value }
@@ -30,6 +34,9 @@ parser = OptionParser.new do |opts|
opts.on("--previous-status STATUS") { |value| options["previous_status"] = value }
opts.on("--previous-certified-at TIMESTAMP") { |value| options["previous_certified_at"] = value }
opts.on("--previous-evidence PATH") { |value| options["previous_evidence"] << value }
opts.on("--acknowledge-degraded-rollback VALUE") do |value|
options["degraded_rollback_acknowledgement"] = value
end
opts.on("--dry-run") { options["dry_run"] = true }
end
@@ -94,8 +101,42 @@ begin
"migration_state" => promoted.fetch("migration_state")
)
end
when "bootstrap-current"
required!(
options,
"consumer",
"consumer_commit",
"status",
"certified_at",
"evidence",
"degraded_rollback_acknowledgement"
)
bootstrapped = promoter.bootstrap_current(
consumer: options.fetch("consumer"),
consumer_commit: options.fetch("consumer_commit"),
certification: {
"status" => options.fetch("status"),
"certified_at" => options.fetch("certified_at"),
"evidence" => options.fetch("evidence")
},
acknowledgement: options.fetch("degraded_rollback_acknowledgement"),
dry_run: options.fetch("dry_run", false)
)
if options.fetch("dry_run", false)
puts JSON.pretty_generate(bootstrapped)
else
raise OptionParser::InvalidArgument, "command must be fingerprint or promote"
consumer = bootstrapped.fetch("consumers").fetch(options.fetch("consumer"))
puts JSON.pretty_generate(
"consumer" => options.fetch("consumer"),
"current_consumer_commit" => consumer.dig("current", "consumer_commit"),
"current_tuple_sha256" => consumer.dig("current", "certification", "tuple_sha256"),
"previous" => consumer.fetch("previous"),
"rollback_state" => consumer.fetch("rollback_state"),
"migration_state" => bootstrapped.fetch("migration_state")
)
end
else
raise OptionParser::InvalidArgument, "command must be fingerprint, promote, or bootstrap-current"
end
rescue OpenCodeCompat::PromotionError, OptionParser::ParseError => e
warn "error: #{e.message}"

View File

@@ -34,7 +34,8 @@ unless matrix.fetch("public_ci").any? { |target| target.fetch("image") == image
"image" => image,
"tag_provenance" => "ghcr.io/anomalyco/opencode:#{version}",
"consumers" => ["upstream-candidate"],
"profiles" => ["ruby-rest-sse", "rails-persisted-turn", "voice-stream", "strict-v2", "plugin-ledger", "provider-hooks"],
"profiles" => ["ruby-rest-sse"],
"required_consumer_profiles" => ["rails-persisted-turn", "voice-stream", "strict-v2", "plugin-ledger", "provider-hooks"],
"certification_status" => "pending"
}
end

View File

@@ -127,10 +127,7 @@ OPENCODE_RUBY_COMMIT="$gem_commit" \
llm_stats="$(docker exec "$llm_container_name" wget -qO- http://127.0.0.1:8080/stats)"
request_count="$(jq -r '.request_count' <<<"$llm_stats")"
if [[ "$request_count" -lt 1 ]]; then
echo "OpenCode never called the deterministic model" >&2
exit 1
fi
ruby "$repo_root/ruby/exact_live_contract.rb" "$request_count"
jq -cn \
--arg status pass \

View File

@@ -0,0 +1,29 @@
# frozen_string_literal: true
require "minitest/autorun"
require_relative "../ruby/exact_live_contract"
class ExactLiveContractTest < Minitest::Test
def test_accepts_only_exact_final_text
assert_nil OpenCodeCompat::ExactLiveContract.assert_final_text!("compat-ok", "compat-ok")
error = assert_raises(OpenCodeCompat::ExactLiveContract::ContractError) do
OpenCodeCompat::ExactLiveContract.assert_final_text!("compat-ok\n\ncompat-ok", "compat-ok")
end
assert_match(/equal/, error.message)
assert_raises(OpenCodeCompat::ExactLiveContract::ContractError) do
OpenCodeCompat::ExactLiveContract.assert_final_text!("prefix compat-ok", "compat-ok")
end
end
def test_accepts_only_one_model_request
assert_nil OpenCodeCompat::ExactLiveContract.assert_model_request_count!("1")
%w[0 2 not-a-number].each do |count|
assert_raises(OpenCodeCompat::ExactLiveContract::ContractError) do
OpenCodeCompat::ExactLiveContract.assert_model_request_count!(count)
end
end
end
end

View File

@@ -2,6 +2,7 @@
require "json"
require "minitest/autorun"
require_relative "../lib/opencode_compat/runtime_tuple_promoter"
class RepositoryTest < Minitest::Test
ROOT = File.expand_path("..", __dir__)
@@ -11,7 +12,7 @@ class RepositoryTest < Minitest::Test
end
def test_every_json_document_parses
paths = Dir.glob(File.join(ROOT, "{evidence,fixtures,manifests,profiles}/**/*.json"))
paths = Dir.glob(File.join(ROOT, "{evidence,fixtures,manifests,profiles,schemas}/**/*.json"))
refute_empty paths
paths.each { |path| JSON.parse(File.read(path)) }
end
@@ -35,6 +36,19 @@ class RepositoryTest < Minitest::Test
end
end
def test_only_ruby_rest_sse_can_be_certified_by_the_shared_ruby_probe
Dir.glob(File.join(ROOT, "profiles/*.json")).each do |path|
profile = JSON.parse(File.read(path))
if profile.fetch("id") == "ruby-rest-sse"
assert_equal "shared-ruby-fixture-and-live-probe", profile.fetch("certification_mode")
assert_equal true, profile.fetch("shared_ruby_probe_sufficient")
else
assert_equal "executable-consumer-attestation", profile.fetch("certification_mode")
assert_equal false, profile.fetch("shared_ruby_probe_sufficient")
end
end
end
def test_public_matrix_uses_only_immutable_oci_digests
targets = json("manifests/image-matrix.json").fetch("public_ci")
refute_empty targets
@@ -42,9 +56,24 @@ class RepositoryTest < Minitest::Test
assert_match %r{\Aghcr\.io/anomalyco/opencode@sha256:[0-9a-f]{64}\z}, target.fetch("image")
refute_includes target.fetch("image"), ":latest"
refute_empty target.fetch("profiles")
next unless target.fetch("certification_status") == "certified"
assert_match(/\A[0-9a-f]{40}\z/, target.fetch("certified_client_commit"))
assert_equal target.fetch("expected_text"), target.fetch("full_text")
assert_equal 1, target.fetch("llm_request_count")
end
end
def test_candidate_is_bound_to_an_annotated_tag
candidate = json("manifests/client-candidate.json")
provenance = candidate.fetch("tag_provenance")
assert_match(/\A[0-9a-f]{40}\z/, candidate.fetch("ref"))
assert_match(/\Av\d+\.\d+\.\d+\.alpha\d+\z/, provenance.fetch("tag"))
assert_match(/\A[0-9a-f]{40}\z/, provenance.fetch("annotated_tag_object"))
assert_equal candidate.fetch("ref"), provenance.fetch("peeled_commit")
end
def test_certified_migration_keeps_previous_tuple
tuples = json("manifests/runtime-tuples.json")
return unless tuples.fetch("migration_state") == "certified"
@@ -62,12 +91,166 @@ class RepositoryTest < Minitest::Test
def test_runtime_tuple_profiles_exist
tuples = json("manifests/runtime-tuples.json")
schema = json("schemas/runtime-tuples.schema.json")
assert_equal 2, tuples.fetch("schema_version")
assert_equal 2, schema.dig("properties", "schema_version", "const")
tuples.fetch("consumers").each_value do |consumer|
profile = consumer.fetch("profile")
assert_path_exists File.join(ROOT, "profiles", "#{profile}.json")
end
end
def test_runtime_tuples_use_full_commits_and_no_mutable_registry_coordinate
tuples = json("manifests/runtime-tuples.json")
tuples.fetch("consumers").each_value do |consumer|
%w[current candidate previous].each do |slot|
tuple = consumer[slot]
next unless tuple
assert_match(/\A[0-9a-f]{40}\z/, tuple.fetch("consumer_commit"))
%w[opencode_ruby opencode_rails].each do |client_name|
client = tuple[client_name]
assert_match(/\A[0-9a-f]{40}\z/, client.fetch("git_commit")) if client
end
runtime = tuple.fetch("runtime")
if runtime.key?("registry_ref")
assert_match(/\A[^@\s]+@sha256:[0-9a-f]{64}\z/, runtime.fetch("registry_ref"))
end
if runtime.key?("tag_provenance")
refute_empty runtime.fetch("tag_provenance")
end
end
end
end
def test_failed_alpha2_baselines_block_promotion_instead_of_becoming_previous
tuples = json("manifests/runtime-tuples.json")
readiness = tuples.fetch("promotion_readiness")
assert_equal "blocked", readiness.fetch("status")
assert_path_exists File.join(ROOT, readiness.fetch("evidence"))
tuples.fetch("consumers").each_value do |consumer|
assert_equal "observed-production-contract-failed", consumer.dig("current", "status")
assert_nil consumer.fetch("previous")
end
end
def test_pull_request_heads_are_explicitly_candidate_only
tuples = json("manifests/runtime-tuples.json")
tuples.fetch("consumers").each do |name, consumer|
candidate = consumer.fetch("candidate")
reference = candidate.fetch("consumer_ref")
assert_equal "pre-merge-pr-head-candidate-only", candidate.fetch("certification_scope"), name
assert_equal false, candidate.fetch("promotion_eligible"), name
assert_equal "pull-request-head", reference.fetch("kind"), name
assert_equal candidate.fetch("consumer_commit"), reference.fetch("commit"), name
assert_match(/\A[0-9a-f]{40}\z/, reference.fetch("tree"), name)
assert_match(%r{\Ahttps://.+/pulls/\d+\z}, reference.fetch("review_url"), name)
end
end
def test_candidate_gems_use_peeled_refs_and_loaded_source_proof
tuples = json("manifests/runtime-tuples.json")
tuples.fetch("consumers").each do |consumer_name, consumer|
candidate = consumer.fetch("candidate")
%w[opencode_ruby opencode_rails].each do |client_name|
client = candidate[client_name]
next unless client
commit = client.fetch("git_commit")
source = client.fetch("source")
proof = source.fetch("loaded_source_proof")
assert_equal "git", source.fetch("type"), "#{consumer_name} #{client_name}"
assert_equal commit, source.fetch("requested_ref"), "#{consumer_name} #{client_name}"
assert_equal commit, source.fetch("locked_revision"), "#{consumer_name} #{client_name}"
assert_equal "pass", proof.fetch("status"), "#{consumer_name} #{client_name}"
assert_equal "Bundler::Source::Git", proof.fetch("source_class"), "#{consumer_name} #{client_name}"
assert_equal client.fetch("version"), proof.fetch("loaded_version"), "#{consumer_name} #{client_name}"
assert_equal commit, proof.fetch("observed_ref"), "#{consumer_name} #{client_name}" if proof.key?("observed_ref")
assert_equal commit, proof.fetch("observed_revision"), "#{consumer_name} #{client_name}"
refute_empty proof.fetch("test"), "#{consumer_name} #{client_name}"
end
end
end
def test_ajent_records_current_selection_drift_and_exact_candidate_selection
ajent = json("manifests/runtime-tuples.json").fetch("consumers").fetch("ajent-rails")
expected_products = %w[aigl blackline raven]
current_runtime = ajent.fetch("current").fetch("runtime")
assert_match(/\Asha256:[0-9a-f]{64}\z/, current_runtime.fetch("docker_image_id"))
deployed = current_runtime.fetch("deployed_product_selection")
assert_equal "mutable-latest", deployed.fetch("strategy")
assert_equal "observed-configuration-drift-failure", deployed.fetch("status")
assert_equal expected_products, deployed.fetch("references").keys.sort
deployed.fetch("references").each_value { |reference| assert reference.end_with?(":latest") }
built = current_runtime.fetch("ci_built_product_images")
assert_equal expected_products, built.keys.sort
built.each_value do |coordinate|
assert_match(/\Asha256:[0-9a-f]{64}\z/, coordinate.fetch("docker_image_id"))
assert_equal ajent.dig("current", "consumer_commit"), coordinate.fetch("source_commit")
end
candidate_runtime = ajent.fetch("candidate").fetch("runtime")
selected = candidate_runtime.fetch("product_selection")
assert_equal expected_products, selected.fetch("references").keys.sort
selected.fetch("references").each_value do |reference|
assert reference.end_with?(":#{ajent.dig('candidate', 'consumer_commit')}")
refute reference.end_with?(":latest")
end
assert_equal ["blackline"], candidate_runtime.fetch("product_images").keys
assert_includes ajent.dig("candidate", "promotion_blockers"),
"aigl-and-raven-candidate-content-artifacts-have-not-been-built-and-canaried"
end
def test_manifest_candidates_cannot_be_promoted_from_pre_merge_evidence
promoter = OpenCodeCompat::RuntimeTuplePromoter.new(root: ROOT)
tuples = json("manifests/runtime-tuples.json")
tuples.fetch("consumers").each do |name, consumer|
error = assert_raises(OpenCodeCompat::PromotionError) do
promoter.promote(
consumer: name,
consumer_commit: consumer.dig("candidate", "consumer_commit"),
certification: {},
dry_run: true
)
end
assert_match(/pre-merge pull-request evidence is candidate-only/, error.message)
end
end
def test_candidate_evidence_is_bound_to_complete_tuple_fingerprints
promoter = OpenCodeCompat::RuntimeTuplePromoter.new(root: ROOT)
evidence_paths = {
"ajent-rails" => "evidence/2026-07-18-ajent-rails-alpha7-candidate.json",
"travelwolf" => "evidence/2026-07-18-travelwolf-alpha7-candidate.json",
"mushu" => "evidence/2026-07-18-mushu-alpha7-candidate.json"
}
evidence_paths.each do |consumer, path|
evidence = json(path)
fingerprints = promoter.fingerprints(
consumer: consumer,
consumer_commit: evidence.fetch("consumer_commit")
)
assert_equal consumer, evidence.fetch("consumer")
assert_equal fingerprints.fetch("profile"), evidence.fetch("profile")
assert_equal fingerprints.fetch("candidate_tuple_sha256"), evidence.fetch("tuple_sha256")
assert_equal "pre-merge-pr-head-candidate-only", evidence.fetch("certification_scope")
assert_equal false, evidence.fetch("promotion_eligible")
assert_equal "pass", evidence.fetch("status")
end
end
def test_watcher_has_no_deployment_commands
workflow = File.read(File.join(ROOT, ".github/workflows/watch-upstream.yml"))
refute_match(/\b(kamal|kubectl|helm|nomad|docker\s+service)\b/i, workflow)
@@ -84,4 +267,14 @@ class RepositoryTest < Minitest::Test
refute_match(/`[^`]+`/, implementation)
refute_match(/\b(kamal|kubectl|helm|nomad|docker\s+service)\b/i, implementation)
end
def test_live_contract_requires_exact_text_and_one_model_request
probe = File.read(File.join(ROOT, "ruby/live_probe.rb"))
runner = File.read(File.join(ROOT, "scripts/run_image_contract.sh"))
assert_includes probe, "ExactLiveContract.assert_final_text!"
refute_includes probe, "full_text.include?"
assert_includes runner, "exact_live_contract.rb"
refute_match(/request_count.*-lt\s+1/, runner)
end
end

View File

@@ -18,6 +18,7 @@ class RuntimeTuplePromoterTest < Minitest::Test
CANDIDATE_IMAGE = "ghcr.io/anomalyco/opencode@sha256:#{'b' * 64}"
CURRENT_TIME = "2026-07-17T12:00:00Z"
CANDIDATE_TIME = "2026-07-18T12:00:00Z"
CANDIDATE_TREE = "7" * 40
def setup
@root = Dir.mktmpdir("opencode-compat-promotion")
@@ -25,6 +26,7 @@ class RuntimeTuplePromoterTest < Minitest::Test
FileUtils.mkdir_p(File.join(@root, "evidence"))
FileUtils.mkdir_p(File.join(@root, "profiles"))
File.write(File.join(@root, "profiles", "rails-persisted-turn.json"), "{}\n")
write_post_merge_canary_evidence("post-merge-canary.json", CANDIDATE_COMMIT)
write_manifest(valid_manifest)
@promoter = OpenCodeCompat::RuntimeTuplePromoter.new(root: @root)
end
@@ -155,6 +157,174 @@ class RuntimeTuplePromoterTest < Minitest::Test
assert_equal before, File.binread(manifest_path)
end
def test_rejects_known_failed_baseline_even_with_passing_evidence
manifest = valid_manifest
manifest.dig("consumers", CONSUMER, "current")["status"] = "observed-production-contract-failed"
write_manifest(manifest)
candidate, previous = write_matching_evidence
before = File.binread(manifest_path)
error = assert_raises(OpenCodeCompat::PromotionError) do
@promoter.promote(
consumer: CONSUMER,
consumer_commit: CANDIDATE_COMMIT,
certification: certification(CANDIDATE_TIME, candidate),
previous_certification: certification(CURRENT_TIME, previous)
)
end
assert_match(/known to fail/, error.message)
assert_equal before, File.binread(manifest_path)
end
def test_rejects_pre_merge_pull_request_evidence_as_candidate_only
manifest = valid_manifest
candidate = manifest.dig("consumers", CONSUMER, "candidate")
candidate["certification_scope"] = "pre-merge-pr-head-candidate-only"
candidate["promotion_eligible"] = false
candidate["consumer_ref"] = {
"kind" => "pull-request-head",
"repository" => "example/consumer",
"commit" => CANDIDATE_COMMIT,
"tree" => CANDIDATE_TREE,
"base_commit" => CURRENT_COMMIT,
"review_url" => "https://example.test/pulls/1"
}
candidate.delete("promotion_provenance")
write_manifest(manifest)
candidate_evidence, previous_evidence = write_matching_evidence
error = assert_raises(OpenCodeCompat::PromotionError) do
@promoter.promote(
consumer: CONSUMER,
consumer_commit: CANDIDATE_COMMIT,
certification: certification(CANDIDATE_TIME, candidate_evidence),
previous_certification: certification(CURRENT_TIME, previous_evidence),
dry_run: true
)
end
assert_match(/pre-merge pull-request evidence is candidate-only/, error.message)
end
def test_accepts_explicit_identical_tree_attestation_with_post_merge_canary
manifest = valid_manifest
candidate = manifest.dig("consumers", CONSUMER, "candidate")
candidate["consumer_ref"] = {
"kind" => "pull-request-head",
"repository" => "example/consumer",
"commit" => CANDIDATE_COMMIT,
"tree" => CANDIDATE_TREE,
"base_commit" => CURRENT_COMMIT,
"review_url" => "https://example.test/pulls/1"
}
main_commit = "8" * 40
write_post_merge_canary_evidence("post-merge-attested-canary.json", main_commit)
candidate["promotion_provenance"] = {
"kind" => "identical-tree-attestation",
"pull_request_commit" => CANDIDATE_COMMIT,
"pull_request_tree" => CANDIDATE_TREE,
"main_commit" => main_commit,
"main_tree" => CANDIDATE_TREE,
"attested_at" => CANDIDATE_TIME,
"post_merge_canary" => {
"status" => "pass",
"checked_at" => CANDIDATE_TIME,
"evidence" => ["evidence/post-merge-attested-canary.json"]
}
}
write_manifest(manifest)
candidate_evidence, previous_evidence = write_matching_evidence
promoted = @promoter.promote(
consumer: CONSUMER,
consumer_commit: CANDIDATE_COMMIT,
certification: certification(CANDIDATE_TIME, candidate_evidence),
previous_certification: certification(CURRENT_TIME, previous_evidence),
dry_run: true
)
assert_equal "certified", promoted.dig("consumers", CONSUMER, "current", "status")
end
def test_main_commit_promotion_still_requires_a_post_merge_canary
manifest = valid_manifest
manifest.dig("consumers", CONSUMER, "candidate", "promotion_provenance").delete("post_merge_canary")
write_manifest(manifest)
error = assert_raises(OpenCodeCompat::PromotionError) do
@promoter.promote(
consumer: CONSUMER,
consumer_commit: CANDIDATE_COMMIT,
certification: {},
dry_run: true
)
end
assert_match(/passing post-merge canary/, error.message)
end
def test_rejects_candidate_without_loaded_exact_ref_source_proof
manifest = valid_manifest
manifest.dig("consumers", CONSUMER, "candidate", "opencode_ruby").delete("source")
write_manifest(manifest)
error = assert_raises(OpenCodeCompat::PromotionError) do
@promoter.fingerprints(consumer: CONSUMER, consumer_commit: CANDIDATE_COMMIT)
end
assert_match(/loaded exact-ref source proof/, error.message)
end
def test_explicit_degraded_bootstrap_certifies_current_without_faking_previous
manifest = valid_manifest
failed = manifest.dig("consumers", CONSUMER, "current")
failed["status"] = "observed-production-contract-failed"
write_manifest(manifest)
fingerprint = @promoter.fingerprints(
consumer: CONSUMER,
consumer_commit: CANDIDATE_COMMIT
).fetch("candidate_tuple_sha256")
evidence = write_evidence(
"bootstrap-candidate.json",
commit: CANDIDATE_COMMIT,
timestamp: CANDIDATE_TIME,
fingerprint: fingerprint
)
bootstrapped = @promoter.bootstrap_current(
consumer: CONSUMER,
consumer_commit: CANDIDATE_COMMIT,
certification: certification(CANDIDATE_TIME, evidence),
acknowledgement: OpenCodeCompat::RuntimeTuplePromoter::DEGRADED_BOOTSTRAP_ACKNOWLEDGEMENT,
dry_run: true
)
consumer = bootstrapped.dig("consumers", CONSUMER)
assert_equal "certified", consumer.dig("current", "status")
assert_equal CANDIDATE_COMMIT, consumer.dig("current", "consumer_commit")
assert_nil consumer["candidate"]
assert_nil consumer["previous"]
assert_equal "observed-production-contract-failed", consumer.dig("emergency_provenance", "status")
assert_nil consumer.dig("emergency_provenance", "certification")
assert_equal "degraded-no-certified-previous", consumer.dig("rollback_state", "status")
assert_equal "bootstrap-current-only", bootstrapped.fetch("migration_state")
end
def test_degraded_bootstrap_requires_exact_explicit_acknowledgement
error = assert_raises(OpenCodeCompat::PromotionError) do
@promoter.bootstrap_current(
consumer: CONSUMER,
consumer_commit: CANDIDATE_COMMIT,
certification: {},
acknowledgement: "yes",
dry_run: true
)
end
assert_match(/explicit acknowledgement/, error.message)
end
def test_rejects_evidence_that_does_not_match_the_complete_tuple
candidate, previous = write_matching_evidence
manifest = JSON.parse(File.read(manifest_path))
@@ -234,7 +404,7 @@ class RuntimeTuplePromoterTest < Minitest::Test
def valid_manifest
{
"schema_version" => 1,
"schema_version" => 2,
"migration_state" => "candidate",
"consumers" => {
CONSUMER => {
@@ -249,8 +419,25 @@ class RuntimeTuplePromoterTest < Minitest::Test
"candidate" => {
"status" => "compatibility-certified",
"certified_at" => "2026-07-18T10:00:00Z",
"opencode_ruby" => {"version" => "0.0.1.alpha6", "git_commit" => RUBY_CANDIDATE},
"opencode_rails" => {"version" => "0.0.1.alpha6", "git_commit" => RAILS_CANDIDATE},
"certification_scope" => "promotion-deployed",
"promotion_eligible" => true,
"consumer_ref" => {
"kind" => "main-commit",
"repository" => "example/consumer",
"commit" => CANDIDATE_COMMIT,
"tree" => CANDIDATE_TREE
},
"promotion_provenance" => {
"kind" => "main-commit",
"main_commit" => CANDIDATE_COMMIT,
"post_merge_canary" => {
"status" => "pass",
"checked_at" => CANDIDATE_TIME,
"evidence" => ["evidence/post-merge-canary.json"]
}
},
"opencode_ruby" => client("0.0.1.alpha7", RUBY_CANDIDATE),
"opencode_rails" => client("0.0.1.alpha7", RAILS_CANDIDATE),
"runtime" => {"image" => CANDIDATE_IMAGE, "reported_version" => "1.18.3"}
},
"previous" => nil
@@ -259,6 +446,27 @@ class RuntimeTuplePromoterTest < Minitest::Test
}
end
def client(version, commit)
{
"version" => version,
"git_commit" => commit,
"source" => {
"type" => "git",
"uri" => "https://example.test/client.git",
"requested_ref" => commit,
"locked_revision" => commit,
"loaded_source_proof" => {
"status" => "pass",
"source_class" => "Bundler::Source::Git",
"loaded_version" => version,
"observed_ref" => commit,
"observed_revision" => commit,
"test" => "test/dependency_provenance_test.rb"
}
}
}
end
def write_matching_evidence
fingerprints = @promoter.fingerprints(consumer: CONSUMER, consumer_commit: CANDIDATE_COMMIT)
candidate = write_evidence(
@@ -291,6 +499,16 @@ class RuntimeTuplePromoterTest < Minitest::Test
{"path" => path, "tuple_sha256" => fingerprint}
end
def write_post_merge_canary_evidence(name, commit)
document = {
"schema_version" => 1,
"status" => "pass",
"checked_at" => CANDIDATE_TIME,
"consumer_commit" => commit
}
File.write(File.join(@root, "evidence", name), JSON.pretty_generate(document) + "\n")
end
def certification(timestamp, evidence)
{
"status" => "pass",