channel.vexa.ai — the live registry. Source:
Vexa-ai/vexa-delivery main @ 4a82369, clean detached checkout.
Container work ran on bbb, never on the laptop.
Two sentences. The entry-5 station install
recorded five findings and fixed none of them; they are fixed here, published as
kit v0.1.7, and the channel’s latest tag now resolves to it. Three of the
five are one shape — a write that reached a surface it does not own, and a
check that then reported the result as green — which is the same invariant
this repository states about ledger surfaces, one level down.
The subscriber is not named. Their registry hostnames, project names and estate
details are not in this document. The channel is written as
<pilot-channel>.The five, and what each one now does
1 · A namespace the installer did not create is not written to
install.sh’s ensure_namespace ran
kubectl create namespace <ns> --dry-run=client -o yaml | kubectl apply -f -
unconditionally. Applying a bare Namespace is a three-way merge, so against
a project the platform team pre-created it pruned
kubernetes.io/metadata.name label. Silently, on a namespace
the installer does not own — and a pre-created project carrying exactly those
labels and annotations is the documented shape for a shared cluster.
It is now create-only: the installer writes a Namespace object only when it
is the thing creating it, says so once per namespace when it is not, and touches
no label, annotation or rolebinding of a namespace that already exists.
And the check that reported the result as green no longer can. Preflight P4
returned PASS with “no SCC and no PSA enforce label on the namespace —
admission here is permissive; nothing to trip, nothing verified about hardened
namespaces”. A green obtained from the enforcement being absent, in the one
check whose subject is the enforcement. P4 now prints the effective
admission it read — PSA enforce level, whether the cluster serves SCC, which
openshift.io/sa.scc.* annotations the namespace carries — and a namespace that
enforces neither is NOT EVALUATED, never a pass.
2 · Preflight P2 compares what admission compares
The delivered postgres asks a 4Gi memory limit; the documented project shape caps a container at 2560Mi, the figure sized for the meeting bot’s 2Gi memory-backed/dev/shm. Admission refused the database, the admin tier
crash-looped behind it, and the estate came up partly down — after a green
preflight.
The receipt’s diagnosis of why P2 passed was wrong, and the correction is
the more useful finding. It read “P2 checks that limits are declared, not
that they are under the LimitRange’s max”. It did compare, and a test pinned
that comparison. P2 passed because the live max.memory was 8Gi when the
preflight ran — the session’s own admin snapshot records max.memory: 8Gi
beside a last-applied-configuration reading 2560Mi, a hand-widened value
that a later re-apply of the project’s grant reset. The refusal arrived when
every pod was deleted and re-admitted under the restored ceiling.
So the check was true when it was taken and false an hour later, and nothing
in its output could distinguish those two worlds: it printed
namespace has 1 LimitRange(s) and no number. It now prints the numbers it
compared against, which is the same discipline this repository applies to
verdicts — positive evidence, not the absence of a complaint.
Three real holes were beside it, and all three are closed. The LimitRanger
checks max and min against the request and the limit, for every resource
the LimitRange names; P2 compared exactly one of those four pairs, in one
dimension. It now compares all four, in memory and cpu, and names the object
and the number:
limits.cpu is no longer a bound
nothing is compared against.
And the delivered set now fits the documented project shape by default.
postgres is the only container in the chart above 2560Mi; every other component
asks 1Gi or less. The shipped customer-values.example.yaml — the file the
installer renders with unless you hand it your own — caps it. The other road is
unchanged and still documented: if your platform team can size the project to
the chart’s own largest ask, do that and delete the cap. Both are now checked by
P2 before the first sync rather than at admission.
3 · A path typo no longer wears the attack message
vexa-verify.sh chdirs into its workdir and only then resolves --pubkey and
--policy, so a relative path silently missed and the miss surfaced as
Verified OK by hand one command later. The
script’s own comment says a signature failure “says someone may be attacking
you” — which makes it the worst available message a mistyped path can produce,
because the subscriber’s next move is to call their security team.
Both paths are resolved before the chdir and before anything is pulled, and a
file that is not there is named as what it is: pubkey file not found: <path>,
exit 2, with no signature language anywhere near it. A --policy that cannot be
read refuses too — it used to degrade to no contract, which turns every
contract check into a check that did not run.
4 · The bytes the gate hashes are the bytes the ledger holds
install.sh wrote the contract ConfigMap through
json.dumps(yaml.safe_load(file)), re-serializing a 757-byte record into 617
bytes of compact JSON. The in-cluster gate hashes the copy it is mounted, so the
recorded verdict named one hash while the ledger record — and the station
report’s own contract_document section — hashed to another. An audit asking
which promise was this admitted under could not answer from either side.
A JSON contract is now mounted verbatim. YAML is still converted, because
the gate reads the document with jq, and then both shas are recorded in
the ConfigMap so the converted document traces back to the bytes a human signed
off. The installer prints the sha it wrote, which is the number the verdict will
carry.
This is the same defect the chart template fixed with a double-quoted scalar
after the 2026-08-29 station lost a verdict to a single 0a. It was the other
write path, and it still had it.
5 · The ledger records the position the report carries
The ingest reducer readtargetRevision out of a values file and then a
position key that appears in no schema. It never read the station report’s own
release block — which carried the entry sequence, the entry digest, the chart
version and the chart digest — so a report saying exactly where a station stands
reduced to subscribed_position: unknown and entry_seq: null, and the
staleness flag could not fire for it.
It now reads that block, most specific source first, and cross-checks the
entry identity against the ingest receipt rather than silently ranking two
sources for one fact. A disagreement is recorded as a flag, because it is a
finding about the submission.
What was published
kit/release.sh --dry-run ran first. It packaged 270382 bytes against the
real run’s 270381; the difference is the built= timestamp inside VERSION,
written per run. The tree packaged was the same tree — worth saying rather than
claiming a byte-identical dry run that did not happen.
Proof 1 — the version tag and latest name one digest
latest is moved with oras tag against the same descriptor bytes, so the
signature made over the digest carries without a second signing operation. The
predecessor still resolves to its own digest, unmoved.
Proof 2 — it verifies against the channel’s pinned key
cosign tree on that digest shows exactly one signature, one layer — not a
second stacked beside it.
The control: kit v0.1.6 still verifies against the same key. One key
verifies both, which is what makes “one key for this channel’s whole life” a
check rather than a claim. --insecure-ignore-tlog=true is correct here rather
than a weakening: the channel signs offline against a pinned key and uploads
nothing to a transparency log, which is what makes it air-gappable, and it is
the same form kit/bootstrap.sh runs on the subscriber’s side.
Proof 3 — a subscriber-shaped pull gets a verified v0.1.7, with the fixes in it
Run from a clean directory withHOME and TMPDIR pointed at it, so the
publisher credential this same host had just pushed with was not reachable — the
isolated HOME has no .docker directory at all, checked after the run — and
with a pull-only credential supplied on stdin of a script already resident
on the host, so it never reached argv, a file or a transcript.
And the fixes are in the artifact, not only in the branch — grepped in the
unpacked tree, which is bytes that came off the registry:
python3 preflight/vexa_preflight.py --help runs from the unpacked tree.
What this pass does NOT claim
- Nothing was installed from this kit. Pull, verify, unpack, shape and
content are proven.
install.shwas not run against a cluster here, so the five fixes rest on their own tests — a fake pre-created namespace, the contract bytes, path resolution, the LimitRange cases and the reducer cases — and on their presence in the published artifact. The next station install is what closes that, and it is the one that will exercise finding 1’s fix against a real pre-created project. - No cluster was read or written in this pass, and no meeting was captured, so nothing here says anything about the release’s quality.
- The pull-only credential was an existing account of ours, not a freshly minted throwaway; the credential tool still cannot mint one against the live channel. Reads are not scoped per account at the edge — only writes are — so the path exercised is the one a subscriber takes, but this pass did not exercise credential issue and revoke.
- No entry, pin or contract moved. No credential was minted or rotated, and the signing key stayed in tmpfs on the build host for the length of the run.