Skip to content

CORE-141 stage 1: Aboga/Cifria staging score corpus protocol

Status: preparation only, 2026-10-03. No source-specific operator sign-off, staging connection, export, corpus, or threshold calibration has occurred. This protocol and its validator use synthetic data only. It does not authorize a Kubernetes or database connection.

Evidence and current blocker

The CORE-134 decision dossier (docs/concepts/agent-transition-decision-dossiers-v11.md, hydration_min_relevance) shows that the legacy floor reads the pre-floor MemoryEntry.score produced by RetrievalEngine / RetrievalScorer (a weighted composite, not raw cosine), while native RetrievalCoordinator._gate can compute a different composite. The synthetic differential is not representative of Aboga or Cifria. Numerically copying legacy 0.2 into native policy is therefore not a calibration method.

Read-only GitOps inspection found Aboga/Cifria staging overlays naming aboga-staging and cifria-staging. Both include the application's persistent postgres StatefulSet and postgres-data-postgres-0 PVC; these are not disposable corpus sources. Manifests do not prove the currently deployed cluster/context, database contents, source owner, or export boundary. No cluster or database connection has been made for CORE-141.

The GitOps evidence is each application's apps/<app>/base/postgres.yaml and apps/<app>/overlays/staging/kustomization.yaml (where <app> is aboga-api or cifria-api).

Before any data operation, the Aboga and Cifria operators must supply, for each application:

  1. The named staging owner and written approval for a bounded, read-only export; the cluster/context and namespace, plus proof the target is staging.
  2. A disposable staging database or operator-controlled export path, its schema/version and field map for query, candidate, score, layer, scope, timestamps, and relevance labels. No credentials belong in this repo.
  3. A reviewed local transform that strips text and source identifiers, uses fresh random UUIDv4 case IDs, and demonstrates that the output contains only the schema below. A human privacy/domain review must sign off the transform and a sample before transfer.
  4. A storage location outside git with access controls, encryption, and a named deletion owner. Capture an aggregate manifest and deletion date.

No live Kubernetes database, production record, or raw adopter text is needed for stage 1. A future staging run needs separate operational authorization specific to the named target.

Minimal transfer schema

One JSONL row is one paired candidate: the same staging query/candidate observed under both score semantics. The allowlist is enforced by scripts/core141_corpus/validate.py; unknown fields fail. There are no query strings, memory contents, tenant IDs, original record IDs, timestamps, paths, URLs, credentials, or arbitrary metadata in the transfer format.

Field Meaning
schema_version Integer 1
application aboga or cifria
query_id, candidate_id Fresh random canonical UUIDv4, generated for this export; never derived from source IDs
query_class fact_recall, workflow, ambiguous, or negative_control
memory_layer semantic, episodic, or procedural
source graph, vector, keyword, or legacy_port
scope_class tip, ancestor, or unknown
legacy_raw_score Historical field name: null for unscored, else finite pre-floor legacy MemoryEntry.score in [0, 1], normally the RetrievalScorer weighted composite; not raw cosine
native_gate_score Null for unscored, else finite score in [0, 1] used for native admission before scope blend/rank attenuation
native_score_is_final Whether the native source marked cue as final, so admission used that cue instead of recomputing a composite
legacy_selected, native_selected Whether each route actually admitted this candidate to the provider-visible context under the recorded policy
relevance Blindly adjudicated relevant, irrelevant, or uncertain

The paired candidate universe must include the union offered to either route, including filtered candidates. The export transform must record the actual native policy and legacy configuration in an aggregate, non-sensitive manifest outside git. Scores alone cannot reconstruct top-K truncation, unscored admission, prompt budget, or post-retrieval effects. If candidate identity cannot be matched safely without transferring source identifiers, the operator must pair locally and export only fresh case IDs.

Sampling and privacy checks

Pre-register a bounded sampling window and query count per app before looking at results. Sample across each query class, semantic/episodic/ procedural layers in use, graph/vector/keyword sources in use, sparse and dense memories, tip/ancestor scope, scored/unscored candidates, and records near and far from the legacy boundary. Record per-stratum eligible and sampled counts in an aggregate manifest. Do not claim representativeness for a stratum with no staging examples; report it as missing.

Operators perform extraction and deidentification inside their staging boundary. The core validator is only a second structural gate; it cannot detect reidentification encoded in a score pattern, identify a real person, or prove a UUID was generated independently of a source ID. Before transfer, review the transform, inspect a local sample, run the validator, and review aggregate counts for unusually small cells. Do not publish row-level output or aggregates for cells smaller than five.

Run the offline structural gate on the already deidentified JSONL:

python scripts/core141_corpus/validate.py /secure/off-git/core141-paired.jsonl

The CLI prints only {"schema_version": 1, "structurally_valid": true}. This means the JSONL shape passed; it does not certify deidentification, privacy, provenance, or permission to transfer. It emits no app counts or cell breakdowns because complements and missing keys can reveal small cells. Validation failures can disclose a row number and the failing field on stderr; run the CLI only inside the same restricted staging boundary as the corpus and do not publish error output. validate_file returns raw counts only to restricted in-process operator code; those counts are not publishable without a separate disclosure review. Keep the corpus and manifest in the approved encrypted, access-restricted off-git location for at most seven days after sign-off or abandonment, then delete both and log a deletion receipt. Never commit even scrubbed staging rows. Only synthetic fixtures, aggregate decisions, and reviewed protocol changes belong in this repository.

Synthetic-only conditional projection

scripts/core141_corpus/project.py accepts a local corpus only with the operator-supplied --synthetic-only declaration. It does not verify synthetic provenance. Its output is for restricted synthetic experiments, not staging calibration or a stage-gate decision. The JSON output leaves small cells unsuppressed, including counts and missing-strata lists; do not publish it or run it on real adopter data.

The projection's public deterministic query split is a synthetic test split, not a real holdout. It excludes those split rows from output, but does not perform holdout evaluation. Per-app tuning observed counts and missing_strata pool rows across both values of native_score_is_final, as their aggregation_scope labels state. Only the conditional floor-pass sweeps are separated into recomputed and source_final; unscored rows remain in the pooled observations but cannot enter either score sweep. A floor pass is not proof of native gate admission or provider visibility.

Calibration and decision inputs

Freeze a holdout split by query ID before tuning. For each app separately, compare actual legacy and native provider-visible candidate sets, relevant recall, relevant exclusions, irrelevant admissions, unscored behavior, and the score distributions by source/layer/scope. Treat uncertain labels separately. Inspect every relevant legacy-only exclusion inside the staging boundary; aggregate the cause as floor, source availability, top-K, scope blend, or prompt budget. Report both the raw legacy score and actual native admission score for each local paired case, but transfer only the schema above.

On the tuning split, sweep native composite floors using the application's observed scores and policy; do not use legacy 0.2 as a native default. Evaluate the selected candidate once on the untouched holdout. An app owner must set acceptable recall, exclusion, and irrelevant-admission bounds before viewing the holdout and approve a per-app rollout or an explicit restore proposal. The existing synthetic CORE-134 test remains mechanism evidence; it cannot supply staging calibration or sign the decision row.

Owner-approved target namespace names: aboga-staging and cifria-staging. GitOps overlays use those names, but cluster identity and deployment state remain unverified. Their postgres StatefulSets/PVCs are persistent app resources, not approved disposable sources. No scratch source or export boundary has been identified, and no cluster/database connection is authorized by this protocol.