Bind the decision to one change
Record the repository reference, full revision, the supplied textual diff, and its SHA-256 digest. The local gate recomputes that digest from the declared synthetic diff; if the diff changes, it rejects the record until the review is restarted. Then declare the Kubernetes version and the smallest policy question the reviewer must answer.
| Declaration | It does not prove |
|---|---|
| Concurrency policy | That an overlapping effect cannot happen elsewhere |
| Missed-run deadline or hold rule | That every old occurrence was classified correctly |
| Unresolved idempotency boundary | That retry or catch-up is safe |
| Hold for a named non-production fixture test | That the target cluster or production effect was exercised |
| Local rollback route | That a cluster rollback has been performed |
Keeping uncertainty explicit is stronger than assuming a policy name supplies business semantics.
Run the local admission gate
The synthetic declaration below makes the local gate inspectable. Its revision and digest are fixture values, not a real repository change or cluster result:
import { createHash } from "node:crypto";
const diffText = "--- fixture-cronjob.yaml\n+++ fixture-cronjob.yaml\n@@\n-concurrencyPolicy: Allow\n+concurrencyPolicy: Forbid\n";
const policyDeclaration = {
repositoryReference: "repo:example/scheduler",
revision: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
diffText,
diffDigest: createHash("sha256").update(diffText).digest("hex"),
boundary: "synthetic-local-cronjob-policy",
kubernetesVersion: "kubernetes-v1.33",
concurrencyPolicy: "forbid",
missedRunPolicy: "declared-deadline-or-hold",
effectBoundary: "idempotency-unproven",
outcomeRoute: "hold-for-non-production-cluster-test",
clusterTestPlan: "named-non-production-cronjob-fixture",
clusterTestFixture: "fixture:cronjob-catch-up-non-production",
reviewer: "reviewer:platform-maintainer",
rollbackRoute: "local-revert-and-hold"
};
// With the local gate, this fixture produces: { admitted: true }
This page includes the declaration for inspection; the repository test remains a local editorial fixture. Run it if you have the accompanying source:
node --test sites/odexing.com/evidence/P217/cronjob-catch-up-gate.test.mjs
The gate accepts a synthetic local declaration only when the immutable change identity is bound to its declared diff, a named Kubernetes version, allowed concurrency policy, declared missed-run policy, unresolved effect boundary, a hold for a named non-production fixture, reviewer identifier, and local rollback route are present. It labels a test hold without reading a manifest, connecting to a cluster, running a Job, or approving a merge. It binds the declared diff as an identity record; it does not prove that the separately declared policy fields match that diff.
Require the cluster-specific questions
Before merge, a human maintainer still needs to compare the declaration against the actual manifest and target environment. Ask whether a long-running job can overlap, what happens after suspend and resume, how an old occurrence is classified, what records make a duplicate effect detectable, and which revision returns the fixture to its prior state. Keep these questions bounded to one CronJob and a named non-production test environment.
Reject the proposal when the version is merely “current,” the effect is called safe without evidence, or a rollback is only a remembered command. The local gate is an admission record, not a substitute for a manifest review or a cluster exercise. For a neighbouring recovery boundary, see Gate an Agent-Generated Retry-Policy Change Before Merge.