diff --git a/.github/workflows/trace-ace-v138-joint-effect-field.yml b/.github/workflows/trace-ace-v138-joint-effect-field.yml new file mode 100644 index 00000000..3e68cd59 --- /dev/null +++ b/.github/workflows/trace-ace-v138-joint-effect-field.yml @@ -0,0 +1,61 @@ +name: Trace Ace V138 Joint Effect Field +# Frozen science. Direct branch trigger avoids PR event registration ambiguity. +on: + push: + branches: [agent/v138-joint-effect-field] + paths: + - '.github/workflows/trace-ace-v138-joint-effect-field.yml' + - 'competitions/trace_the_ace/v138_joint_effect_field.py' + - 'competitions/trace_the_ace/V138_PRECOMMIT.md' + pull_request: + branches: [agent/v137-effect-field-minimal-regime] + paths: + - 'competitions/trace_the_ace/v138_joint_effect_field.py' + - '.github/workflows/trace-ace-v138-joint-effect-field.yml' + - 'competitions/trace_the_ace/V138_PRECOMMIT.md' + workflow_dispatch: + +jobs: + evaluate: + runs-on: ubuntu-24.04 + timeout-minutes: 20 + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + with: + python-version: '3.12' + cache: pip + - name: Install dependencies + run: python -m pip install --disable-pip-version-check numpy scikit-learn + - name: Download frozen V137 OOF artifact + uses: actions/download-artifact@v4 + with: + name: trace-ace-v137-effect-field + path: v137_artifact + github-token: ${{ github.token }} + repository: heathsanchez/mathgraph + run-id: 32445760436 + - name: Verify frozen field + run: | + set -euo pipefail + test -f v137_artifact/v137_oof_field.npz + python - <<'PY' + import numpy as np + z=np.load('v137_artifact/v137_oof_field.npz',allow_pickle=True) + req=['y','sessions','objectives','support','p_v97','p_v135','field_support_log','field_prior_disp','field_expert_disagree','field_prior_conf','field_v75_conf','field_prior_shift'] + print('KEYS',sorted(z.files)) + for k in req: assert k in z.files,(k,z.files) + assert len(z['y'])==35072 + print('ROWS',len(z['y']),'SESSIONS',len(set(map(str,z['sessions']))),'OBJECTIVES',len(set(map(str,z['objectives'])))) + PY + - name: Run frozen V138 controller + run: python competitions/trace_the_ace/v138_joint_effect_field.py --field v137_artifact/v137_oof_field.npz --out v138_joint_effect_field.json + - name: Show decision + if: always() + run: cat v138_joint_effect_field.json || true + - uses: actions/upload-artifact@v4 + if: always() + with: + name: trace-ace-v138-joint-effect-field + path: v138_joint_effect_field.json + retention-days: 14 diff --git a/.github/workflows/trace-ace-v139-component-applicability.yml b/.github/workflows/trace-ace-v139-component-applicability.yml new file mode 100644 index 00000000..5eed12c2 --- /dev/null +++ b/.github/workflows/trace-ace-v139-component-applicability.yml @@ -0,0 +1,63 @@ +name: Trace Ace V139 Component Applicability +on: + pull_request: + branches: [agent/v138-joint-effect-field] + paths: + - 'competitions/trace_the_ace/v139_component_applicability.py' + - 'competitions/trace_the_ace/V139_PRECOMMIT.md' + - '.github/workflows/trace-ace-v139-component-applicability.yml' + workflow_dispatch: + +jobs: + evaluate: + runs-on: ubuntu-24.04 + timeout-minutes: 120 + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + with: + python-version: '3.12' + cache: pip + - name: Install dependencies + run: python -m pip install --disable-pip-version-check numpy pandas scipy scikit-learn gdown + - name: Restore exact transcript cache + id: transcript-cache + uses: actions/cache@v4 + with: + path: transcripts.zip + key: trace-ace-transcripts-v1-603547640 + - name: Require cache + run: | + set -euo pipefail + test '${{ steps.transcript-cache.outputs.cache-hit }}' = 'true' + test "$(stat -c%s transcripts.zip)" = '603547640' + echo 'e685b85b04694e130c25b17d09cdd1892fbda5e9fa685e98b2300114b915aa2d transcripts.zip' | sha256sum -c - + - name: Restore metadata + run: | + set -euo pipefail + gdown 1EpqoamY0vFI2qE57R6wdqU5HwuoVk3Zz -O metadata.zip + mkdir -p data/transcripts data/meta + unzip -q transcripts.zip -d data/transcripts + unzip -q metadata.zip -d data/meta + FEATURES=$(find data/meta -type f -name 'train_features*.csv' -print -quit) + LABELS=$(find data/meta -type f -name 'train_labels*.csv' -print -quit) + FIRST=$(find data/transcripts -type f -name '*.csv' -print -quit) + TRANSCRIPTS=$(dirname "$FIRST") + echo "FEATURES=$FEATURES" >> "$GITHUB_ENV" + echo "LABELS=$LABELS" >> "$GITHUB_ENV" + echo "TRANSCRIPTS=$TRANSCRIPTS" >> "$GITHUB_ENV" + - name: Run frozen V139 + run: | + cd competitions/trace_the_ace + python v139_component_applicability.py --features "../../$FEATURES" --labels "../../$LABELS" --transcripts "../../$TRANSCRIPTS" --out ../../v139_component_applicability.json --oof ../../v139_component_oof.npz + - name: Show decision + if: always() + run: cat v139_component_applicability.json || true + - uses: actions/upload-artifact@v4 + if: always() + with: + name: trace-ace-v139-component-applicability + path: | + v139_component_applicability.json + v139_component_oof.npz + retention-days: 14 diff --git a/competitions/trace_the_ace/V138_PRECOMMIT.md b/competitions/trace_the_ace/V138_PRECOMMIT.md new file mode 100644 index 00000000..1777b584 --- /dev/null +++ b/competitions/trace_the_ace/V138_PRECOMMIT.md @@ -0,0 +1,48 @@ +# V138 precommit — Joint effect field + +## Current state +Full V135 is the strongest retained composition law. V136 verified +0.001771 full-data session-grouped gain, positive in every fold, with exact V97 fallback on objective-cold. V137 closed the one-scalar applicability version space: the scalar gate lost 0.000121 versus full V135 and beat its shuffled selector by only 0.000179. + +## Residual +The gain is real but distributed; the missing applicability distinction is not one-dimensionally separable in the current runtime-visible field. + +## Diagnosis +Primary: applicability/composition. Secondary: representation of applicability. Closed: single-threshold scalar gating. + +## Strongest old-world rival +There is no stable deployable applicability structure in the current observables; inner-fold structure is selection noise. + +## JOIN / imported structure +V137's selected scalar varied by fold, but repeatedly involved support, prior displacement, and expert disagreement. This motivates only the hypothesis that applicability may be relational. It is not evidence. + +## K(rho) +Any admitted continuation must: +1. use no labels/benefits at inference; +2. choose its rule only from meta-training OOF effects; +3. transfer to unseen sessions; +4. improve over full V135, not merely V97; +5. beat an equal-capacity shuffled-effect rule search; +6. use exact V97 outside the selected region. + +## Version space +The smallest language strictly beyond V137: an AND of exactly two threshold literals on distinct members of: +`support_log, prior_disp, expert_disagree, prior_conf, v75_conf, prior_shift`. +Thresholds are training-fold quantiles {0.2,0.4,0.6,0.8}; directions are <= and >; coverage must be 0.08..0.80. No OR, trees, generic router, learned embeddings, or post-result tuning. + +## Separator / action table +Primary evaluation is 4-fold session-grouped meta-OOF over the frozen V137 field. +- PROMOTE if total gain vs V97 >=0.003, incremental gain vs full V135 >=0.001, advantage vs shuffled selector >=0.001, no fold regresses vs V97, and >=3 folds beat V135. +- RETAIN JOINT SIGNAL if incremental vs V135 >0, shuffle advantage >=0.0005, and >=3 folds beat V135. +- Otherwise CLOSE TWO-LITERAL APPLICABILITY SPACE and zoom out rather than increasing router capacity automatically. + +## Causal attack +Identical pair-rule search on deterministically shuffled meta-training benefits. + +## Descaffolding +The deployed rule sees only six runtime-visible coordinates. Effect labels exist only in meta-training selection. + +## Transfer +Every selected rule is evaluated on an unseen-session fold. + +## Retention +Negative result is retained as `NOT_SUPPORTED_UNDER(two_literal_current_observable_applicability,V137_OOF,shuffle_control)`. diff --git a/competitions/trace_the_ace/V138_RESULT.md b/competitions/trace_the_ace/V138_RESULT.md new file mode 100644 index 00000000..f6d39f88 --- /dev/null +++ b/competitions/trace_the_ace/V138_RESULT.md @@ -0,0 +1,49 @@ +# V138 result — Joint effect field + +## Frozen verdict + +`CLOSE_TWO_LITERAL_APPLICABILITY_SPACE` + +The precommitted two-literal applicability language is not admitted. + +## Verified metrics + +- V97 LL: `0.5392345448672131` +- Full V135 LL: `0.5374633492487556` +- Full V135 gain: `+0.0017711956184575106` +- V138 pair-gated LL: `0.5373080052672911` +- V138 pair gain vs V97: `+0.0019265395999220614` +- Incremental vs full V135: `+0.00015534398146455075` +- Equal-capacity shuffled-selector LL: `0.5382827410326881` +- Advantage vs shuffled selector: `+0.0009747357653970834` +- Pair coverage: `0.6436473540145985` +- Folds beating V135: `2 / 4` +- All folds non-regressive vs V97: `true` + +## Residual structure + +Despite failing admission, all four untouched meta-folds independently selected effectively the same rule family: + +`support_log <= ~6.08 AND prior_disp > ~0.116` + +with outer coverage about 64.3–64.5% in every fold. + +This is stronger structural recurrence than V137's unstable one-scalar rules, and the real selector substantially outperformed equal-capacity shuffled selectors. However, the effect was not large or fold-consistent enough to satisfy the frozen admission rule. + +## Retained law + +`NOT_SUPPORTED_UNDER(two_literal_current_observable_applicability,V137_OOF,shuffle_control)` + +with a secondary retained observation: + +`STABLE_BUT_UNADMITTED_INTERACTION(support_log_low_or_mid, prior_displacement_nontrivial)` + +The observation is hypothesis-generating only. It must not be promoted or threshold-tuned post hoc. + +## Next controller state + +- PUSH: full V135 remains the admitted candidate law. +- READ: V138 found stable joint geometry but insufficient causal/fold-level gain. +- DIAGNOSE: current observable applicability is structured but not sufficient for robust selective deployment. +- ZOOM: stop increasing router capacity over the same six fields. +- NEXT QUESTION: what mechanism makes objective-prior displacement useful specifically under non-saturated support, and can that mechanism be represented directly rather than routed indirectly? diff --git a/competitions/trace_the_ace/v138_joint_effect_field.py b/competitions/trace_the_ace/v138_joint_effect_field.py new file mode 100644 index 00000000..c3f37a7f --- /dev/null +++ b/competitions/trace_the_ace/v138_joint_effect_field.py @@ -0,0 +1,130 @@ +#!/usr/bin/env python3 +"""V138: full developmental-controller test on the saved V137 OOF effect field. + +Controller state (frozen before result): +PUSH: full V135, the strongest retained supported-objective composition. +READ: V136/V137 establish +0.001771 full-data gain, all folds positive, but V137 one-scalar gating loses 0.000121 vs full V135. +DIAGNOSE: primary=applicability/composition; secondary=representation of applicability. One-dimensional routing is closed. +ZOOM: ask whether V135 benefit has stable JOINT structure in current runtime-visible observables. +IMPORT/JOIN: V137 fold rules repeatedly implicated support_log, prior_disp, expert_disagree; treat this only as hypothesis generation. +RIVAL: no stable deployable applicability structure exists in the current observable field; apparent inner structure is selection noise. +K(rho): any admitted refinement must be label-free at inference, learned only from meta-training OOF effects, improve untouched meta-folds over full V135, beat an equal-capacity shuffled-effect selector, and preserve V97 outside its selected region. +VERSION SPACE: the smallest language beyond V137: conjunction of exactly two threshold literals on distinct frozen fields. No trees, learned router, OR clauses, or parameter sweep outside the frozen grid. +DECIDE: 4-fold session-grouped meta-OOF separator. +ATTACK: identical rule search on deterministically shuffled training benefits. +DESCAFFOLD: inference receives only the six runtime fields, never labels/benefits. +TRANSFER: each selected rule is applied to an unseen session fold. +COMPRESS/RETAIN: output a scoped verdict and next-action law. +""" +from __future__ import annotations +import argparse, json +from pathlib import Path +import numpy as np +from sklearn.model_selection import GroupKFold + +EPS=1e-6 +SEED=20260823 +FIELDS=['support_log','prior_disp','expert_disagree','prior_conf','v75_conf','prior_shift'] +QS=(.2,.4,.6,.8) +MIN_COVER=.08 +MAX_COVER=.80 + +def sample_loss(y,p): + p=np.clip(np.asarray(p,float),EPS,1-EPS); y=np.asarray(y,float) + return -(y*np.log(p)+(1-y)*np.log(1-p)) + +def ll(y,p): return float(np.mean(sample_loss(y,p))) + +def literal(x,th,direction): return x<=th if direction=='le' else x>th + +def thresholds(x): return [(q,float(np.quantile(x,q))) for q in QS] + +def choose_pair(field,benefit): + """Choose one two-literal conjunction maximizing mean all-row benefit.""" + best=None + for ia,a in enumerate(FIELDS): + xa=np.asarray(field[a],float) + for b in FIELDS[ia+1:]: + xb=np.asarray(field[b],float) + for qa,tha in thresholds(xa): + for da in ('le','gt'): + ma=literal(xa,tha,da) + for qb,thb in thresholds(xb): + for db in ('le','gt'): + m=ma & literal(xb,thb,db) + cov=float(m.mean()) + if covMAX_COVER: continue + gain=float(np.mean(np.where(m,benefit,0.0))) + rec={'a':a,'qa':qa,'tha':tha,'da':da,'b':b,'qb':qb,'thb':thb,'db':db, + 'coverage':cov,'train_gain':gain} + if best is None or gain>best['train_gain']+1e-15: + best=rec + if best is None: raise RuntimeError('no admissible pair rule') + return best + +def apply_pair(field,r): + return literal(np.asarray(field[r['a']],float),r['tha'],r['da']) & literal(np.asarray(field[r['b']],float),r['thb'],r['db']) + +def main(a): + z=np.load(a.field,allow_pickle=True) + y=z['y'].astype(int); sessions=z['sessions'].astype(str); objectives=z['objectives'].astype(str) + p0=z['p_v97'].astype(float); p2=z['p_v135'].astype(float) + field={k:z[f'field_{k}'].astype(float) for k in FIELDS} + n=len(y) + assert n==35072 and all(len(v)==n for v in field.values()) + base_gain=ll(y,p0)-ll(y,p2) + benefit=sample_loss(y,p0)-sample_loss(y,p2) + pg=np.zeros(n); pc=np.zeros(n); mask_all=np.zeros(n,bool); control_all=np.zeros(n,bool) + folds=[]; rng=np.random.default_rng(SEED) + splitter=GroupKFold(4) + for k,(tr,va) in enumerate(splitter.split(np.zeros(n),y,sessions),1): + ftr={x:v[tr] for x,v in field.items()}; fva={x:v[va] for x,v in field.items()} + rule=choose_pair(ftr,benefit[tr]) + shuffled=benefit[tr].copy(); rng.shuffle(shuffled) + crule=choose_pair(ftr,shuffled) + m=apply_pair(fva,rule); cm=apply_pair(fva,crule) + q=p0[va].copy(); q[m]=p2[va][m] + qc=p0[va].copy(); qc[cm]=p2[va][cm] + pg[va]=q;pc[va]=qc;mask_all[va]=m;control_all[va]=cm + fr={'fold':k,'rows':int(len(va)),'v97_ll':ll(y[va],p0[va]),'v135_ll':ll(y[va],p2[va]), + 'pair_ll':ll(y[va],q),'control_ll':ll(y[va],qc),'coverage':float(m.mean()), + 'control_coverage':float(cm.mean()),'rule':rule,'control_rule':crule} + folds.append(fr); print('FOLD',json.dumps(fr),flush=True) + l0=ll(y,p0); l2=ll(y,p2); lg=ll(y,pg); lc=ll(y,pc) + gain=l0-lg; inc=l2-lg; causal=lc-lg + all_nonreg=all(r['pair_ll']<=r['v97_ll']+1e-12 for r in folds) + beats_v135_folds=sum(r['pair_ll']=.003 and inc>=.001 and causal>=.001 and all_nonreg and beats_v135_folds>=3: + verdict='PROMOTE_TWO_LITERAL_REGIME_REFINEMENT'; next_action='attack_boundary_then_runtime_parity' + elif inc>0 and causal>=.0005 and beats_v135_folds>=3: + verdict='RETAIN_JOINT_APPLICABILITY_SIGNAL'; next_action='attack_and_descaffold_joint_structure' + else: + verdict='CLOSE_TWO_LITERAL_APPLICABILITY_SPACE'; next_action='zoom_out_current_observable_applicability_exhausted' + out={ + 'protocol':'V138_JOINT_EFFECT_FIELD_CONTROLLER', + 'controller':{ + 'push':'full_v135', + 'residual':{'v135_full_gain':base_gain,'v137_incremental_vs_v135':-0.00012105436555076565, + 'statement':'real distributed V135 gain; one-scalar applicability refinement closed'}, + 'diagnosis':{'primary':'applicability_composition','secondary':['applicability_representation'],'closed':['one_scalar_gate']}, + 'zoom':'test stable joint structure before increasing router capacity', + 'import_join':'recurring V137 coordinates support/prior displacement/expert disagreement motivate relational view only', + 'rival':'no stable deployable applicability exists in current runtime-visible field', + 'K_effect':['label_free_inference','meta_train_only_selection','untouched_session_transfer','beat_full_v135','beat_equal_capacity_shuffle','v97_outside_gate'], + 'version_space':{'operator':'AND of exactly two threshold literals','fields':FIELDS,'quantiles':list(QS),'directions':['le','gt'],'min_coverage':MIN_COVER,'max_coverage':MAX_COVER}, + 'attack':'equal-capacity shuffled-benefit selector','descaffold':'six runtime fields only','transfer':'4 unseen-session meta folds' + }, + 'rows':n,'v97_ll':l0,'v135_ll':l2,'v135_gain':l0-l2,'pair_ll':lg,'pair_gain':gain, + 'incremental_vs_v135':inc,'control_ll':lc,'gain_vs_control':causal, + 'pair_coverage':float(mask_all.mean()),'control_coverage':float(control_all.mean()), + 'all_fold_nonregression':bool(all_nonreg),'folds_beating_v135':int(beats_v135_folds),'folds':folds, + 'decision':{'verdict':verdict,'next_action':next_action}, + 'retained_law':('two_literal_joint_structure_admitted' if verdict.startswith('PROMOTE') else + 'joint_signal_provisional' if verdict.startswith('RETAIN') else + 'NOT_SUPPORTED_UNDER(two_literal_current_observable_applicability,V137_OOF,shuffle_control)') + } + Path(a.out).write_text(json.dumps(out,indent=2)); print('FINAL',json.dumps(out,indent=2),flush=True) + +if __name__=='__main__': + p=argparse.ArgumentParser(); p.add_argument('--field',type=Path,required=True); p.add_argument('--out',type=Path,default=Path('v138_joint_effect_field.json')); main(p.parse_args())