Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 57 additions & 4 deletions .github/workflows/client-v1-conformance.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,65 @@ on:
validator_revision:
required: true
type: string
producer_revision:
description: >-
Exact merged Chat commit to validate. Defaults to the dispatch ref
tip. It must already be an ancestor of that tip: an unmerged or
unrelated revision is refused, so this decouples a protected run from
whatever happens to be at the tip without widening what may be
validated.
required: false
type: string
permissions:
contents: read
jobs:
producer-revision:
name: resolve-producer-revision
if: github.ref == 'refs/heads/main'
runs-on: ubuntu-24.04
timeout-minutes: 5
permissions:
contents: read
outputs:
revision: ${{ steps['resolve'].outputs.revision }}
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1
with:
fetch-depth: 0
persist-credentials: false
ref: ${{ github.sha }}
- id: resolve
name: Resolve and verify the producer revision
env:
OPENCOVEN_PRODUCER_REVISION_INPUT: ${{ inputs.producer_revision }}
OPENCOVEN_DISPATCH_SHA: ${{ github.sha }}
run: |
set -euo pipefail
requested="${OPENCOVEN_PRODUCER_REVISION_INPUT:-}"
if [ -z "$requested" ]; then
requested="$OPENCOVEN_DISPATCH_SHA"
fi
case "$requested" in
*[!0-9a-f]* | "" ) echo 'Producer revision must be an exact lowercase 40-hex commit.' >&2; exit 1 ;;
esac
if [ "${#requested}" -ne 40 ]; then
echo 'Producer revision must be an exact lowercase 40-hex commit.' >&2
exit 1
fi
if ! git cat-file -e "$requested^{commit}" 2>/dev/null; then
echo 'Producer revision is not a commit in this repository.' >&2
exit 1
fi
if ! git merge-base --is-ancestor "$requested" "$OPENCOVEN_DISPATCH_SHA"; then
echo 'Producer revision is not an ancestor of the dispatch ref; only merged revisions may be validated.' >&2
exit 1
fi
Comment thread
BunsDev marked this conversation as resolved.
printf 'revision=%s\n' "$requested" >> "$GITHUB_OUTPUT"
echo "Validating producer revision $requested"
windows-supervisor:
name: build-windows-supervisor
if: github.ref == 'refs/heads/main'
needs: producer-revision
runs-on: macos-latest
timeout-minutes: 30
permissions:
Expand All @@ -22,7 +75,7 @@ jobs:
with:
fetch-depth: 0
persist-credentials: false
ref: ${{ github.sha }}
ref: ${{ needs['producer-revision'].outputs.revision }}
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020
with:
node-version: 24.18.1
Expand All @@ -42,7 +95,7 @@ jobs:
platform-conformance:
name: platform-conformance (${{ matrix.platform }})
if: github.ref == 'refs/heads/main'
needs: windows-supervisor
needs: [producer-revision, windows-supervisor]
timeout-minutes: 60
strategy:
fail-fast: false
Expand Down Expand Up @@ -71,7 +124,7 @@ jobs:
OPENCOVEN_VALIDATOR_REVISION_INPUT: ${{ inputs.validator_revision }}
OPENCOVEN_PROTECTED_VALIDATOR_REVISION: ${{ vars.CLIENT_V1_CONFORMANCE_VALIDATOR_REVISION }}
OPENCOVEN_CHAT_REPOSITORY: ${{ github.repository }}
OPENCOVEN_CHAT_SHA: ${{ github.sha }}
OPENCOVEN_CHAT_SHA: ${{ needs['producer-revision'].outputs.revision }}
Comment thread
BunsDev marked this conversation as resolved.
OPENCOVEN_WINDOWS_IMAGE_OS: 'win25-vs2026'
OPENCOVEN_WINDOWS_IMAGE_VERSION: '20260907.229.1'
OPENCOVEN_WINDOWS_PREVIOUS_IMAGE_VERSION: '20260824.214.3'
Expand Down Expand Up @@ -1819,7 +1872,7 @@ jobs:
with:
fetch-depth: 0
persist-credentials: false
ref: ${{ github.sha }}
ref: ${{ needs['producer-revision'].outputs.revision }}
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020
if: matrix.platform != 'win32-x64'
with:
Expand Down
86 changes: 24 additions & 62 deletions docs/phase1-conformance.md
Original file line number Diff line number Diff line change
@@ -1,38 +1,5 @@
# Phase 1 real-authority conformance

## Bounded quota retry categories

Protected [run 35146928092](https://github.com/OpenCoven/chat/actions/runs/35146928092)
used Chat #311 at `157fb3206b9b90f24049aa2043bae534d2b9a709` and SDK #293 at
`3459dcaad0877bbef2a25da24fbd521879ef020e`. Windows failed with `access-denied`,
root `harness-execution-aggregate`, scope `checkouts`, operation
`directory-enumeration-depth-3-plus`, and repeat `persistent`. Linux and macOS
records passed identity, timing, privacy, schema, and all 197 ordered assertions.
Windows emitted no record, and no accepted aggregate exists. This earlier quota
failure does not establish that the Cave build home repair passed isolation.

The legacy `persistent` label means the repeat threw a non-missing exception.
It does not prove a second access denial. The bounded diagnostic now preserves
the initial category and reports the repeat as `persistent-<category>`, using
only the existing fixed exception categories. For example, first-attempt access
denial followed by an I/O failure reports `access-denied` with `persistent-io`;
two access denials report `access-denied` with `persistent-access-denied`.
Legacy `persistent` remains accepted by the context normalizer.

Run the portable classification and non-recovery checks with:

```sh
pwsh -NoLogo -NoProfile -NonInteractive -File scripts/windows-quota-diagnostics.test.ps1
```

The regression matrix covers every fixed repeat category, rejects private text,
preserves the first failure, and requires one whole-pass attempt for each
non-recoverable result. The change adds no retries and changes no quotas,
permissions, or recovery predicates. Native Windows fixtures require the refined
labels; their execution remains a delivery gate. Reviewed producer binding,
actual-merge SDK rebinding, both scope rotations, and fresh protected validation
remain required before claiming acceptance or identifying the failing checkout.

## Cave build home isolation checkpoint

Protected run `35138402347` failed on Windows with
Expand Down Expand Up @@ -247,8 +214,8 @@ assignment, RPC decoder and primary/secondary exception pipeline. This fixture
correction does not establish the protected installation failure's cause or
relax the round-trip assertions.

The lock now selects reviewed source `0a35e571de69c3f17b2f490974caec36b34205a5`,
tree `4f98b5cff7ac65d7229c136490265ea60d2cd764`, including all 25 governed files
The lock now selects reviewed source `28821d4d035d7815df396b756c2e30ecb0d54f5e`,
tree `f893c71be4fd0eec23c8739716441bd2f533d764`, including all 25 governed files
and ten production deltas. The checkout regression exercises all five labels
from that immutable revision. SDK rebinding, both scope rotations and fresh
protected validation remain required; this binding alone is not acceptance.
Expand Down Expand Up @@ -2053,7 +2020,7 @@ revision authorities can therefore have different workflow hashes:

| File | Bytes | SHA-256 |
| --- | ---: | --- |
| `.github/workflows/client-v1-conformance.yml` | 178,086 | `3c2f0d5423533b7b2c6d601e9f91a250064704bceeb4e53090ebecc935cacb09` |
| `.github/workflows/client-v1-conformance.yml` | 180,386 | `be7f36a7ce1b3dd6834b565e33825c5af410c49ed0e193ffaffda91ef79125b3` |
| `scripts/contract-canary.mjs` | 40,618 | `a4c2fe0a5eb6a5ff4653de5374c34c0fb46907c6806a5d23b86d8b37206ef958` |
| `scripts/executable-resolution.mjs` | 9,154 | `31e3c412ff8c835f14522f36a59e91f4a4ba82913210ae8e3b4455217503f430` |
| `scripts/owned-temp-directory.mjs` | 7,762 | `95f546ef9ed614f2a0f55d356ddfc54c943fc53b595b4eebebfcbd4db68e5c0b` |
Expand Down Expand Up @@ -2821,31 +2788,26 @@ Fresh reviewed source binding, SDK rebinding, and protected validation are
required before attributing the Windows failure or claiming a repaired run.


### Unsupported custody installation

`secure_store_unavailable` covered two unrelated causes on the installation
preflight. `KeyringError::Unavailable` is returned both by a secure store that
is genuinely unavailable and by `CredentialCustody::installation_id`'s default
trait body, which a custody implementation reaches only by never overriding it.
`InstallationStage::classify` already rewrites `Unavailable` into
`installation_lock_unavailable`, `installation_entry_unavailable`,
`installation_read_unavailable`, `installation_write_unavailable` and
`installation_persistence_unavailable`, so those five stages were already
distinguishable; the default trait body was the remaining unclassified path.

It now returns the fixed code `installation_custody_unsupported`, published as
`phase1.native-scenarios.native-preflight-installation-custody-unsupported`.
The outer launcher derives its native-stage allowlist from the producer
registry, so the identifier survives extraction without a second edit. Only the
fixed identifier is published: no message, stack, path, credential or
subprocess output is added.

Protected run
[35100084575](https://github.com/OpenCoven/chat/actions/runs/35100084575)
reported `native-preflight-installation-secure-store-unavailable` on Windows
while Linux and macOS passed. This change does not repair that failure and does
not establish its cause; it separates the two causes so the next protected run
attributes it.
### Dispatching a protected run against a specific merged revision

`workflow_dispatch` previously validated whatever `main` pointed at when the
run started. The cross-repository contract requires the evidence producer to be
a merge whose tree equals its reviewed second parent's tree, so a binding names
one exact merge; any later commit to `main` — conformance-related or not —
leaves that binding unable to describe the tip. Protected runs were therefore
only usable inside the window between a binding landing and the next merge.

The optional `producer_revision` input names the commit to validate. The
`resolve-producer-revision` job requires an exact lowercase 40-hex commit that
exists in this repository and is an **ancestor of the dispatch ref**, then
publishes it for the supervisor build, the Windows bootstrap and the Unix
workspace checkout. Omitting it keeps the previous behaviour of validating the
dispatch ref tip.

The ancestry requirement is what keeps this from widening the trust boundary:
an unmerged branch, an unrelated commit, or a revision from a fork is refused,
so a protected run still only ever validates reviewed history that reached
`main`. What changes is that it no longer has to be the newest such history.

### Unexpected installation RPC failures

Expand Down Expand Up @@ -2947,7 +2909,7 @@ validation, attestation, and aggregation were skipped.
`ReadBoundedDirectorySnapshot` materializes a bounded snapshot. On access denial,
`ReadDirectorySnapshotOperation` performs one fresh, complete snapshot read under the
existing quota-reader identity. A successful repeat supplies the measurement; a missing
directory is classified separately. In that historical producer, any other repeat exception produced `persistent`,
directory is classified separately. Any other repeat exception produces `persistent`,
while the initial access-denied category is preserved. An injected access denial followed
by an I/O exception now exercises that distinction through the production snapshot seam.
Thus the log does not prove two identical ACL failures, a particular checkout, a denied
Expand Down
10 changes: 5 additions & 5 deletions phase1-conformance.lock.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@
},
"harness": {
"repository": "OpenCoven/chat",
"revision": "0a35e571de69c3f17b2f490974caec36b34205a5"
"revision": "28821d4d035d7815df396b756c2e30ecb0d54f5e"
},
"harnessAuthority": {
"revision": "0a35e571de69c3f17b2f490974caec36b34205a5",
"tree": "4f98b5cff7ac65d7229c136490265ea60d2cd764",
"revision": "28821d4d035d7815df396b756c2e30ecb0d54f5e",
"tree": "f893c71be4fd0eec23c8739716441bd2f533d764",
"files": [
{
"path": "scripts/phase1-conformance.mjs",
Expand Down Expand Up @@ -146,8 +146,8 @@
},
{
"path": ".github/workflows/client-v1-conformance.yml",
"blob": "1bfcccfe5bbbc864182bcc8d8a5e3aa2ba7189ee",
"sha256": "3c2f0d5423533b7b2c6d601e9f91a250064704bceeb4e53090ebecc935cacb09"
"blob": "2204f8f5f4e9bc9b787e23e624038c376d518f7f",
"sha256": "be7f36a7ce1b3dd6834b565e33825c5af410c49ed0e193ffaffda91ef79125b3"
}
],
"productionDeltas": [
Expand Down
Loading
Loading