Agent-memory index curation — task #2093
Summary (all three units)
| agent | before (bytes / rows) | after (bytes / rows) | merge groups | retires |
|---|---|---|---|---|
| experiment-implementer | 19,697 / 118 | 14,449 / 83 | 3 | 32 |
| experimenter | 19,303 / 96 | 15,578 / 71 | 6 | 19 |
| reconciler | 19,300 / 79 | 17,784 / 62 | 11 | 0 |
Bodies deleted: 0 across all three agents (curation is index-row-level only; every body stays on disk and loads on demand).
Per-agent curation manifests for the three near-ceiling agent-memory indexes
(.claude/agent-memory/<agent>/MEMORY.md). Curation happens at the INDEX-ROW
level only: ZERO feedback bodies were deleted — every retired/merged row's
body stays on disk and loads on demand. Each retire cites the superseding
always-on surface with a one-line quoted covering clause (verified by grep at
curation time, 2026-08-05, worktree issue-2093 at origin/main ==
b8164e9fe0), or records the relocation evidence for a
target-no-longer-exists retire.
experiment-implementer
Before: 19,697 bytes / 118 rows. After: 14,449 bytes / 83 rows.
Classification: 83 KEEP · 3 MERGE groups (3 rows folded into 3 rewritten
rows) · 32 RETIRE. Every surviving pointer resolves on disk (test -f loop:
0 missing over 89 referenced bodies).
Merges (rows in → row out; all original bodies stay reachable)
- "Smoke coverage parity (width, class×regime, branches)" + "prefix-arm
degenerate cloud kills spectral smoke" → one family row keyed on
feedback_smoke_ft_zero3_width_parity.md, withfeedback_prefix_arm_degenerate_cloud_smoke.mdnamed inline as the zero-variance single-context sibling (#1112). Same trap class: a smoke slice whose realized composition cannot exercise what production exercises. - "Long loops: per-unit atomic writes + --resume" + "--resume pins every
output-affecting regime key" → one family row keyed on
feedback_long_running_analysis_needs_resume.md, withfeedback_resume_metadata_pin_every_regime_key.mdnamed inline (#722 #399 #600). Same trap class: long-loop resume discipline. - "Ruff strips unused imports" + "Edit-then-read-modify-write lost
update" → one "Format-hook edit hazards" row keyed on
feedback_ruff_strips_unused_imports.md, withfeedback_edit_then_read_modify_write_lost_update.mdnamed inline (#1345). Same trap class: the PostToolUse format hook racing an edit.
Retires (32) — verbatim row + justification + quoted covering clause
Format: the original index row, then the superseding surface. "gotchas.md" =
.claude/rules/gotchas.md (on-demand rule, trigger indexed always-on in
.claude/rules/LESSONS.md); line numbers from the curation-time worktree
copy. Bodies retained on disk in all cases.
- [MooseFS stale-serves an rsync OVERWRITE](/docs/feedback_moosefs_stale_serve_on_rsync_overwrite) — rsync rc=0 but pod runs old bytes; rm-then-rsync + sha both sides (#1482)→ gotchas.md:86: "rsync/scp INTO a MooseFS-backed pod path can silently serve STALE bytes to a subsequent reader on the same mount (#2051 rider, from archived #2053)."- [#1586 disk-headroom family](/docs/feedback_resume_aware_phase_headroom_gates) — scale need by PENDING cells; reap ckpts on verified upload + smoke roots at phase entry (#1586 fu)→.claude/rules/plan-compute-sizing.md§ Out-root mount binding: "The gate MUST be resume-aware: compute the phase's PENDING set with the same predicates the phase's own resume scan uses" (incident #1586 fu crash 5;_wave_headroom); the reap-on-verified-upload half is the same rule's ladder-retention/fan-out blocks ("delete a cell's local outputs once uploaded to the Hub").- [SAE published FVE/L0 need the reference token pool](/docs/feedback_sae_reference_eval_token_pool) — dictionary_learning remove_bos: BOS-8 strip (#1482)→ gotchas.md:474: "SAE fitness/eval against a published FVE/L0 reference must reproduce the reference eval's TOKEN-POOL semantics — not just its encode/decode math."- [Batch-API judge item ids — charset + 53-char budget](/docs/feedback_batch_custom_id_53_char_budget) — custom_ids must match ^[a-zA-Z0-9_-]{1,64}$ (#1776, #1415)→ gotchas.md:400: "Anthropic Batchcustom_ids must match^[a-zA-Z0-9_-]{1,64}$— BOTH a charset AND a length constraint".- [Pilot timing gates measure at the SWEEP's execution shape](/docs/feedback_pilot_timing_gate_sweep_shape) — batch-1 pilot vs batched sweep false-fires a (#1415)→ plan-compute-sizing.md:399 (§ Per-cell fit phases): "a phase that runs B-wide batched calls is piloted [with one B-wide batched call normalized per-sample, never a serial batch-1 loop … (#1415)]".- [GCV lambda interpolation degeneracy](/docs/feedback_gcv_lambda_interpolation_degeneracy) — n_tr ≲ D: GCV → grid-min λ, R² −2..−46 (#1335, #1345)→ CLAUDE.md § User-chat inline free analysis (always-on): "GCV-specific ban (#1887): pure-GCV λ selection at n_train < d is REFUSED (the shared #825 fit cores enforce this by default — GCV runs only WITH a dof cap, default 0.9, or under an explicit LEGACY_UNGUARDED_GCV opt-in)"; plus.claude/rules/artifact-reuse.mdcheck (l) (documents the #1335 grid-min collapse + registered mitigations). Residual noted: a from-scratch GCV fitter bypassing the shared cores is not code-guarded, but writing one instead of reusing the cores violates the reuse rules independently.- [rule-24 surgical re-judge recipe](/docs/feedback_rule24_surgical_rejudge_recipe) — recover 529 draws from judge_raw via (#1315)→.claude/rules/llm-judging.mdrule 24(ii) (llm-judging.md:163 area): "The re-judge BYPASSES the rubric-keyed judge cache for the affected draws — surgical per-draw merge, a freshcache_dir, or draw-indexed keying … (#1090's own recovery used the surgical per-draw merge for exactly this reason)."- [Hub prefix-mirror staging ≠ consumer layout](/docs/feedback_hub_prefix_mirror_vs_consumer_layout) — pure hub-rel→local-rel map + fail-loud entry check (#928 #1481 #1774)→.claude/rules/artifact-reuse.mdcheck (h)(iv) — the rule inlines the requirements (pure mapping fn, fail-loud entry check, 1-file staging probe per (family × consumer) pair) and cites this very body at artifact-reuse.md:280: "Full 4-point implementation recipe …:.claude/agent-memory/experiment-implementer/feedback_hub_prefix_mirror_vs_consumer_layout.md" — the body stays reachable FROM the rule.- [Artifact pin/provenance family](/docs/feedback_artifact_pair_provenance_coherence) — sha pins ≠ capture-time identity; 4 siblings in entry (#922 #1776 #600 #601)→ CLAUDE.md reuse bullet (always-on) clauses (f) content identity/sha-pinning (#600) + (j) pairwise provenance ("a consumed input regenerated AFTER its dependent capture is inconsistent regardless of sha pins", #922); artifact-reuse.md:417 check (j): "a pin freezes current bytes, not pair coherence" — check (j) also cites the sibling bodyfeedback_pinned_artifact_pair_mutual_inconsistency.mddirectly.- [vLLM generate traps: chunk batches, use_tqdm=False](/docs/feedback_vllm_large_batch_deadlock_chunk_it) — one huge generate() wedges EngineCore (chunk ~500); bank length-validate sibling in entry (#664 #613 #952)→ gotchas.md: "A single largellm.generate(N_prompts, ...)call can DEADLOCK the vLLM v1 EngineCore worker — chunk large batches by default (PREVENTION for the hang the #601 entry recovers from)" (with theVLLM_GREEDY_CHUNK_SIZEcode recipe at gotchas.md:155-161) + gotchas.md:194 (use_tqdm=FalseZeroDivisionError entry).- [vLLM teardown + HF coexistence](/docs/feedback_vllm_orphan_worker_after_destroy) — destroy_* leaves workers (psutil child-kill); gpu_mem_util≤0.5 (#399 #685)→ gotchas.md:132-133: "vLLM in-process teardown does NOT reap worker subprocesses. When the SAME process loads vLLM then a non-vLLM framework (HF Transformers …)" + "Reaping recipe (vLLM v1, 0.11.0)"; the teardown entry is also named always-on in CLAUDE.md § Gotchas ("vLLM worker-subprocess teardown").- [642 v4/v5 villain on-policy matched-LR](/docs/project_642_v4_villain_onpolicymatchedlr) — 4 NEW arms, #612 30-panel, splice #411(actual filename:project_642_v4_villain_onpolicy_matchedlr.md) → Retire (b), target no longer exists: stale in-flight design context for task #642, whose run is COMPLETE — REGISTRY:status: awaiting_promotion,has_clean_result: True(the promoted clean-result body now carries the methodology). Relocation grep recorded:grep -rn "villain_onpolicy\|642 v4\|project_642" scripts/ src/ tests/ .claude/rules/ .claude/skills/ .claude/agents/→ sole hitscripts/issue_642/i642_dispatch.py:1999(the completed run's own dispatch script — a consumer of nothing in this memory).- [snapshot_download full-tree enumeration](/docs/feedback_hf_snapshot_download_full_tree_enumeration) — walks the ~1M-file data repo before allow_patterns; SCOPED list_repo_tree + per-file download (#833)→ artifact-reuse.md:223 ("~1M-file data repo —snapshot_downloadfull-tree-enumerates there") + :346 check (i)(3) ("an unscoped full-treelist_repo_files/snapshot_downloadagainst the data repo FAILS … gotchas.md #833 entry"); also the always-on CLAUDE.md reuse bullet ("data-repo Hub calls prefix-scoped").- [max_model_len tracks max_new_tokens](/docs/feedback_max_model_len_tracks_max_new_tokens) — raising max_new_tokens on an inherited vLLM (#601)→ CLAUDE.md:33max_new_tokensbullet (always-on): "raising a cap on an INHERITED rig ⇒ re-check itsmax_model_len/DEFAULT_MAX_MODEL_LENpins at the call site (.claude/rules/gotchas.md— the #505/#601 slot-read overflow)."- [Lazy imports in smoke-skipped branches](/docs/feedback_lazy_imports_skipped_by_smoke) — hoist to module top + AST --verify-imports (#606, #1332)→ gotchas.md:350: "Lazy imports inside smoke-skipped branches (--dry-run/--skip-upload/ GPU-only paths) are unverified code — the ImportError fires on the pod, AFTER the expensive phases."- [Subagent one turn, no watchers](/docs/feedback_subagent_one_turn_no_watchers) — watchers die at turn end; run minutes-scale→.claude/agents/experiment-implementer.md:1000 (the agent's own always-loaded spec): "### Smoke runs are same-turn, synchronous work — You get ONE turn and are never re-woken by background events — watchers, … NEVER arm watchers/Monitor and end the turn."- [Preflight --json is pretty-printed](/docs/feedback_preflight_json_parse) — parse whole stdout (first-{ slice), never→ gotchas.md:228: "orchestrate.preflight --jsonemits PRETTY-PRINTED multi-line JSON — parse the WHOLE stdout, neversplitlines()[-1]."- [CI bounds vs mpl xerr/yerr offsets](/docs/feedback_constant_bootstrap_negative_yerr) — clamp max(0,v-lo)/max(0,hi-v) element-wise (#547, #1335)→ gotchas.md:128: "matplotlibxerr/yerrtake NON-NEGATIVE per-point OFFSETS from the value — never CI bounds and never signed deltas."- [Memory cap: calibrate from measured real-shape peak](/docs/feedback_memory_cap_calibrate_measured_peak) — explicit-temporary counting under-estimates (#811)→ gotchas.md:82: "Memory caps for torch fit loops: calibrate the live-tensor factor from a MEASURED real-shape peak — counting the code's explicit temporaries under-estimates the true per-chunk peak ~6×" + plan-compute-sizing.md:562 (§ CPU-phase RAM/RSS: "with the live-factor MEASURED, never the explicit-temporary count").- [Upload pipeline-INPUT artifacts before teardown](/docs/feedback_upload_pipeline_input_artifacts_before_teardown) — tiny pod-generated inputs upload before (#779)→ CLAUDE.md:373 § Upload Policy (always-on): "Persist by default — upload every artifact a run produces, even if this task has no use for it (a sibling / follow-up may)" — text/JSON "uploads ALWAYS, unconditionally".- [HF datasets streaming shutdown SIGABRT](/docs/feedback_hf_datasets_streaming_shutdown_sigabrt) — a streaming IterableDataset surviving to (#952)→ gotchas.md:196: "HFdatasets/transformerssubprocesses can exitrc=134(SIGABRT) with aPyGILState_Releasefatal abort DURING interpreter shutdown — AFTER the work already completed and the output file was written."- [splitlines shreds JSONL with Unicode line boundaries](/docs/feedback_splitlines_jsonl_unicode_boundaries) — never read/count JSONL via str.splitlines() (#825)→ gotchas.md:229: "str.splitlines()shreds JSONL whose strings carry raw U+2028/U+2029/NEL — read/count JSONL via text-mode file iteration orsplit(\"\\n\"), NEVERsplitlines()."- [Anthropic system-role lift at dispatcher seams](/docs/feedback_anthropic_system_role_lift) — Messages API 400s on role:system; kwargs-bind sibling in entry (#906)→ gotchas.md:399: "The Anthropic Messages API has NO\"system\"message ROLE — a chat-template-style message list forwarded verbatim 400s (invalid_request_error) the moment a{\"role\": \"system\"}entry appears; lift system content …".- [Reused artifact's realized keys vs builder code](/docs/feedback_reused_artifact_realized_keys_vs_builder_code) — verify a reused artifact's OWN keys, not its (#1073)→ artifact-reuse.md:130 check (c): "for a multi-field tensor bundle, verify the artifact's REALIZED key set … reading the builder code is NOT verification" — mechanized at :137 (scripts/verify_reused_artifact_keys.py) + verify_plan.py gate c30.- [Smoke-slice sizing vs downstream gates](/docs/feedback_smoke_gate_realized_slice_arithmetic) — floors from realized slice arithmetic + min-N asserts; demote production-n under --smoke (#1489 #1345)→ gotchas.md:51: "Smoke/production parity includes SLICE ARITHMETIC — a post-smoke artifact floor (checkpoint/step count) satisfied only under an ASSUMED smoke row cap dies whenever the REALIZED yield comes in smaller; derive the smoke dial (epochs/steps) from realized …".- [Out-root never /tmp (container disk)](/docs/feedback_outroot_tmp_container_disk) — RunPod /tmp = 50 GB overlay; anchor (#1333)→ plan-compute-sizing.md:245 § Out-root mount binding: "/tmp/+ everything outside/workspaceis the container disk, typically ~50 GB" — the block names incident #1333 and mandates the per-phaseassert_out_root_headroompreamble.- [Parent-branch stranded fixes](/docs/feedback_parent_branch_stranded_fixes) — reused modules may lack the parent branch's (#1345)→ CLAUDE.md:29 reuse bullet (always-on): "parent-lineage coherence of reused parent code + realized artifacts — diff the main-resident module against the parent's unmerged issue- branch (git log --oneline origin/main..origin/issue-<M> -- <module>) … (#1345)" + artifact-reuse.md check (k) leg A.- [Subprocess phase registry + full-panel smoke](/docs/feedback_subprocess_phase_registry_and_full_panel_smoke) — subprocess phases inherit no module (#1090)→ gotchas.md:52: "Smoke/production parity includes REGISTRY/PANEL MEMBERSHIP — a subprocess-per-phase dispatcher child inherits NO module-level registry state, 'the registrar runs somewhere' is not enough (the registered set must cover the set the phase RESOLVES)".- [Purge/reap only after the LAST consumer](/docs/feedback_incremental_reap_last_consumer) — enumerate every reader (#1489, #1776)→ CLAUDE.md:176 § Disk hygiene (always-on): "a direct-pathopen()reader does NOT re-download, so 'CONSUMED' means no LATER phase or provision reads it; enumerate every later consumer before placing the reap — #1489,.claude/rules/gotchas.md" (the body itself opens by citing this contract).- [Off-pod phase file-reads vs upload manifest](/docs/feedback_offpod_phase_upload_manifest_seam) — off-pod phase reads must be in the upload (#1482)→ gotchas.md:127: "Every file an OFF-POD phase loads must be in the pod's UPLOAD SET — an all-on-one-filesystem smoke is structurally blind to the cross-machine seam."- [Fenced dispatcher-block extraction probe](/docs/feedback_fenced_dispatcher_block_extraction_probe) — sed-extract SMOKE=0 embedded-python legs; replicate the registry preamble; drive both branches (#1336 unit D)→ gotchas.md:351: "Import + signature checks do NOT catch a runtime-logic bug in a smoke-FENCED branch — code that acfg.smoke/--smokeconditional short-circuits … is unreachable by EVERY smoke, so its first-ever execution is the production run."- [Real-corpus streaming filters need tiny-real probes](/docs/feedback_real_corpus_streaming_filters_tiny_real_probe) — WildChat/LMSYS store FULL language names; dupes + UltraChat siblings in entry (#1092 #1768)→ gotchas.md:404: "Real-corpus streaming filters (WildChat/LMSYS): verify field semantics against REAL rows + run a bounded tiny-real streaming probe with per-filter reject counters BEFORE any production corpus launch."
Bodies intentionally left index-unreferenced
Newly index-unreferenced this round (32): exactly the 32 retired rows'
primary bodies listed above — each retained on disk; superseding surface per
the corresponding retire entry. Two remain directly cited from rule files:
feedback_hub_prefix_mirror_vs_consumer_layout.md (artifact-reuse.md:280)
and feedback_pinned_artifact_pair_mutual_inconsistency.md
(artifact-reuse.md check (j)).
Pre-existing index-unreferenced (67 — unchanged this round): sibling bodies absorbed into merged family rows' consolidated entries in PRIOR compaction rounds; each is reachable via its family primary body's entry text ("siblings in entry"), not via a direct index pointer. This round neither created nor removed any of these: feedback_apply_parity_probe_n_sizing.md, feedback_batched_press_loco_twin_exact.md, feedback_bf16_merge_truncates_small_lora_delta.md, feedback_bf16_single_position_equivalence_gate_calibration.md, feedback_chained_smoke_leg_out_root_residue.md, feedback_chat_template_span_find_misanchor.md, feedback_cross_frame_gate_asserts.md, feedback_cross_machine_input_staging.md, feedback_cudnn_tf32_fp32_parity_gate.md, feedback_cusolver_eigh_nonconvergence_cpu_fallback.md, feedback_deviation_path_sweeps_all_pin_verifiers.md, feedback_dual_gram_per_question_grain_cost.md, feedback_eval_rig_per_phase_checkpoint.md, feedback_exdev_tempdir_hub_staging.md, feedback_exit137_kill_source_verification.md, feedback_fanout_shared_staging_race.md, feedback_fellows_shared_node_gpu_sizing.md, feedback_hf_mirror_divergence_pin_hashes.md, feedback_hf_vllm_coexistence_captured_dict.md, feedback_hidden_states_tail_post_norm.md, feedback_hub_upload_no_path_transport_retry.md, feedback_hub_verify_retry_transient.md, feedback_kwargs_constructor_bind.md, feedback_left_pad_position_ids_required.md, feedback_logits_to_keep_capture_oom.md, feedback_manifest_inputs_staged_eagerly.md, feedback_mask_audit_offset_mapping.md, feedback_midrun_verified_upload_ckpt_reap.md, feedback_numerics_probe_thresholds_dtype.md, feedback_numpy_argsort_tie_order_cross_machine.md, feedback_numpy_svd_nonconvergence_bootstrap.md, feedback_orphan_pid_check_must_be_cvd_aware.md, feedback_output_hidden_states_activation_accumulation_oom.md, feedback_parity_floor_weak_writer_vs_gauge_error.md, feedback_per_arm_class_smoke_and_panel_disjointness.md, feedback_pinned_artifact_pair_mutual_inconsistency.md, feedback_plain_text_span_boundary_bpe_merge.md, feedback_rank_space_bootstrap_tail_gating.md, feedback_real_corpus_exact_dupes_sha_sample.md, feedback_resume_branch_synthesize_result.md, feedback_resume_predicate_recorded_terminal_verdicts.md, feedback_resume_seed_min_n_gates.md, feedback_sha_pin_domain_mismatch.md, feedback_skippable_phase_staging_side_effects.md, feedback_slurm_rsync_lane_committed_eval_results_unshipped.md, feedback_small_cell_bootstrap_ci_degeneracy.md, feedback_smoke_class_regime_coverage.md, feedback_smoke_root_rebind_orphans_parent_inputs.md, feedback_smoke_scale_gates.md, feedback_smoke_slice_min_n_downstream_asserts.md, feedback_smoke_ternary_skips_production_branch.md, feedback_snapshot_download_siblings_truncation.md, feedback_sonnet_refusal_in_seed_prompts.md, feedback_stage_hub_prefix_dest_is_mirror_root.md, feedback_stage_hub_prefix_verbatim_mirror_consumer_rebind.md, feedback_stratified_null_not_centered_at_chance.md, feedback_strict_llm_count_assert_over_generation.md, feedback_teacher_forced_capture_token_id_concat.md, feedback_threshold_gated_telemetry_short_runs.md, feedback_trl_assistant_only_loss_qwen_template.md, feedback_ultrachat_prompt_field_case_variant.md, feedback_upload_loop_retry_plus_skip_set.md, feedback_verbatim_embed_answer_anchored_span_gate.md, feedback_vllm_bank_length_validate_at_load.md, feedback_vllm_use_tqdm_zerodivision.md, feedback_write_tool_lands_in_session_cwd.md, feedback_zero_width_span_bpe_delimiter_merge.md.
Verification
- Bytes: 19,697 → 14,449 (soft target ~15,000 met; hard cap 18,000).
- Rows: 118 → 83; 188 body files on disk, 0 deleted.
- Link-resolution loop over surviving rows: 89/89 referenced bodies exist.
- No residual: legitimate curation reached the soft target; no live lesson was dropped to hit the byte number.
experimenter
Before: 19,303 bytes / 96 index rows (95 distinct bodies; one row was an
exact duplicate). After: 15,578 bytes / 71 rows referencing 77 bodies.
Classification: 65 KEEP (verbatim) · 6 MERGE groups (12 rows → 6
multi-link rows) · 19 RETIRE rows (18 distinct bodies; includes the
duplicate-row pair). Every surviving pointer resolves on disk (test -f
loop: 77/77). Structural fixes riding along: the one row that sat ABOVE the
# Experimenter Memory H1 was resolved by its retire (R1); the trailing
section was renamed ## Project results (durable) + run forensics to match
the forensics rows it hosts.
Merges (rows in → row out; all original bodies stay reachable)
- "Preflight fetch-timeout false-negative" (#664) + "Preflight
wandb-reachability HANG" (#778) → one "Preflight false-negative probes
on fresh pods" row linking
feedback_preflight_fetch_timeout_false_negative.mdfeedback_preflight_wandb_reachability_hang.md. Same trap class: preflight's OWN network probes false-fail/hang on first-touch pods.
- "Load .env explicitly in nohup" (#260, #923) + "RunPod lane .env not
sourced via nohup bash driver" (#657) → one row linking
feedback_load_env_in_nohup.md+feedback_runpod_lane_env_not_sourced_via_nohup.md. Same trap class: detached/non-login launches missing API keys. - **"GCP lane is git-clone-only — local data/ doesn't reach the VM" (#634)
- "Reused parent train-mix is local-only" (#734)** → one row linking
feedback_gcp_lane_git_clone_only_data.md+feedback_reused_train_mix_local_only_gcp_lane.md. Same trap class: git-clone-only lanes cannot stage VM-local inputs.
- "Reused parent train-mix is local-only" (#734)** → one row linking
- "Carry-over data claims lie ~half the time" (#186, #368) + "Carry-over
artifacts local-disk gate" (#504) → one row linking
feedback_carryover_data_assumption.md+feedback_carryover_artifacts_local_disk_gate.md. Same trap class: verify claimed carry-over inputs (HF leg AND local staging) before spend. - "Liger + PEFT/LoRA = 2x regression" (#36) + "TRL rejects Liger DPO +
precompute" (#36) → one row linking
feedback_liger_peft.md+feedback_trl_dpo_liger_precompute.md. Same trap class: Liger fused kernels don't compose with the LoRA/DPO paths. - "Stale procs steal log + GPU + checkpoints" (#399 v8) + "SSH timeout ≠
child dead — pgrep before relaunch" (#383, #399) → one "Relaunch
hygiene" row linking
feedback_stale_eval_proc_steals_log.md+feedback_ssh_bash_lc_backgrounding.md. Same trap class: relaunching without confirming the prior instance's state.
Retires (19 rows / 18 bodies) — verbatim row + quoted covering clause
Format matches the experiment-implementer section: original row, then the
superseding surface (line numbers from the curation-time worktree copy).
13 of the 18 retired bodies remain CITED from .claude/rules/ entries, so
they stay reachable from the covering rule itself. Bodies retained on disk
in all cases.
- [Foreign GPU allocation invisible to compute-apps](/docs/feedback_gpu_foreign_allocation_no_compute_apps) — fresh RunPod GPU held ~72GB by a host-level tenant; gate on memory.used per GPU, never compute-apps alone (#825 r11)→ gotchas.md:145: "A FRESH pod can arrive with a GPU already held by a FOREIGN tenant —--query-compute-appsreads EMPTY … GPU-free gates must read per-GPUmemory.used, never compute-apps alone" (body cited in the entry).- [Pod git HTTPS 403 with VALID token — bundle sideload](/docs/feedback_pod_git_https_403_bundle_sideload) — pod fetch can 403 with a verified-valid token + correct helper (likely egress-IP git-http block) (#1315)→ gotchas.md:465: "Pod git fetch 403 with a VERIFIED-VALID token — after ONE helper-recovery attempt, stop debugging auth and sideload the commit delta viagit bundle" (body cited in the entry).- [Podgit pullsilent on stale.git/index.lock](/docs/feedback_pod_git_pull_silent_index_lock) — A crashed mid-git workload leaves a 0-byte.git/index.lock(#653)plus its exact-duplicate sibling row (same body,(#653, #1336)tail) — the one duplicate-referenced body in the pre-curation index. → gotchas.md:464: "Same-pod relaunch:git pull --ff-onlyexits 0 on a stale.git/index.lockbut HEAD does NOT advance — a SILENT-success sibling of the two pull-ABORT entries above" (body cited in the entry). The run-END half of the trap keeps its own row (feedback_stale_index_lock_pre_launch_probe.md, #1336).- [Fan-out handshake timeout masks a single fast-crashing unit](/docs/feedback_fanout_handshake_timeout_masks_single_unit_crash) — "ALL units hit the vLLM 5-min front-end handshake timeout" is usually the SYMPTOM of one unit crashing instantly (#1112)→ gotchas.md:190: "ALL fan-out units dumping the vLLM 5-minute front-end handshake timeout … is usually the MASK of ONE unit crashing instantly — read the earliest/smallest unit log's traceback BEFORE classifying infra"; entry names the body as "Long-form twin".- [vLLM zombie GPU: pkill -f misses the orphan EngineCore](/docs/feedback_vllm_zombie_gpu_pkill_reaper) — after killing a hung vLLM dispatcher tree (#664)→ gotchas.md:135: "Crashed/killed/HUNG vLLM parents leave orphanedVLLM::EngineCoreworkers that OOM the RELAUNCH — andpgrep -f <script-name>/pkill -f <script-name>cannot see them" (full reap recipe; body cited at gotchas.md:142); the teardown family is also named always-on in CLAUDE.md § Gotchas.- [CUDA OOM on Qwen-7B teacher-forced capture — workload-cmd hot-fix, no code change](/docs/feedback_cuda_oom_expandable_segments) — multi-layer activation capture on Qwen-2.5-7B OOMs at the lm_head after ~6000 forwards on PyTorch CUDA-allocator (#761)→ gotchas.md:224 (expandable-segments entry): "Cross-ref (long-form recipe):.claude/agent-memory/experimenter/feedback_cuda_oom_expandable_segments.md. (Incident #761 r3 relaunch …)".- [HF Hub pinned-revision 404](/docs/feedback_hf_hub_pinned_rev_404) — hf_hub_download(revision, filename) 404s when the pair doesn't coexist (#477)→ artifact-reuse.md:88-89: "run the probe at that revision … existence atmaindoes not imply existence at the pin (#1345 — 2/4 stems returned 0 files at the plan's pin after a default-branch probe read CONFIRMED)"; mechanized plan-side byverify_plan.pyc35 (c35_pinned_revision_reuse, "revision-pinned reuse verified at pin").- [Bank vs R-artifact schema drift](/docs/feedback_bank_r_artifact_schema_drift) — issue_472 bank + R_eval not pinned to one snapshot (#477)→ artifact-reuse.md:382 check (j): "Pairwise provenance coherence (mutually-dependent artifact PAIRS) … a question/prompt bank vs activations / teacher-forced reads captured under it; … checks (e)/(f) pin each member's CURRENT bytes individually but say nothing about whether the members come from the SAME generation"; the same clause rides the always-on CLAUDE.md reuse bullet.- [RunPod overlay HF cache trap](/docs/feedback_runpod_overlay_hf_cache) — /root/.cache/huggingface as REAL dir overflows the 50G overlay on eval (#356)→ mechanized at source:scripts/bootstrap_pod.sh:377export HF_HOME=/workspace/.cache/huggingfaceruns on every provision; CLAUDE.md § Pods "Hard requirements" item 4: "Bootstrap on provision — runsbootstrap_pod.sh(uv, repo clone, .env push, HF cache redirect, preflight)"; preflight additionally checksHF_HOME.- [Preflight feature-branch false positive](/docs/feedback_preflight_feature_branch_false_positive) — FIXED at source by #554 (2026-06-12, branch-aware preflight); tolerance/pre-clear is LEGACY for pre-#554 pods only (#383, #550)→ fixed at source (the row's own text declares it):src/explore_persona_space/orchestrate/preflight.py:308"Check git working tree is clean and up to date — branch-aware (#554)"; pods are ephemeral (7-day TTL), so no pre-#554 pod remains; body also cited frompod-side-reporting.md:659.- [Detached-spawn launchers cannot be &&-chained into waves](/docs/feedback_detached_spawn_launcher_cannot_chain_waves) — a fan-out script that setsid-detaches shards (reparented to init) exits after its spawn loop (#1738)→ gotchas.md:87: "Chained waves on a detached-spawn launcher fan out CONCURRENTLY — a launcher thatsetsid-detaches its shards exits right after its spawn loop, sowave2 && wave3 && wave4is NOT sequential"; entry names the body as "Long-form".- [Divergent .claude/** spec files block ff-only pull](/docs/feedback_pod_git_sync_diverged_spec_files) — same-pod relaunch of a branch carrying a spec-freshness sync commit abortsgit pull --ff-only(#653)→ gotchas.md:441: "Same-pod relaunch: divergent.claude/**spec files blockgit pull --ff-only" (full 4-step recovery recipe; body cited at gotchas.md:463).- [CUDA_VISIBLE_DEVICES clobber family](/docs/feedback_cuda_visible_devices) — set CVD before torch import; module-level writes poison importers (#269); train_lora/merge_lora stomp shell CVD (#192)→ CLAUDE.md § Gotchas (always-on): "the+gpu_id=NCUDA_VISIBLE_DEVICES clobber for parallel launches"; LESSONS.md gotchas trigger binds it at every launch: "launch GPU workers / multi-GPU/vLLM fan-outs, incl. via train_lora/merge_lora (CVD clobber, …)"; gotchas.md carries the full entries (7 CVD hits).- [Sonnet model id -20251001 is invalid](/docs/feedback_anthropic_sonnet_4_5_20251001_invalid_model) — 404 NotFoundError ~40s in; alias is claude-sonnet-4-5; grep all judge sites, code-class, never retry (#489)→ CLAUDE.md LLM-judge bullet (always-on): "Set viaDEFAULT_JUDGE_MODEL/JUDGE_MODEL=claude-sonnet-4-5-20250929; never graft a-20251001suffix (that is Haiku 4.5)"; mechanized byworkflow_lint.py --check-judge-model-pins(bundled into the no-flags default run).- [MooseFS FUSE wedge on .venv imports](/docs/feedback_moosefs_fuse_wedge_venv_import) — silent launch hang (zero stderr, wchan=request_wait_answer, GPU 0 MiB) = wedged /workspace FUSE mount (#779)→ gotchas.md:85: "MooseFS FUSE READ-wedge on the pod/workspace.venv— the silent launch hang (zero stderr)" (full discriminator probe + remediation; entry names the body as "Long-form runbook"); ALSO named always-on in CLAUDE.md § Gotchas: "the MooseFS FUSE read-wedge on the pod.venv(silent launch hang — see the discriminator probe in the rule)".- [vLLM H100 IMA under heavy shared-prefix caching](/docs/feedback_vllm_h100_prefix_cache_ima) — A100-clean + short-probe-clean differential pins the class (#1092)→ gotchas.md:189: "vLLM-on-H100 CUDA illegal-memory-access under heavy shared-prefix caching at long-prompt production shapes — run the A100-clean + short-probe-clean differential BEFORE any code hunt" (body cited in the entry).- [Pod git auth can go stale mid-lifecycle](/docs/feedback_pod_git_auth_stale_midlifecycle) — #1239 credential-helper recovery works on RunPod too; pod sync = single-statement git -C calls (#1315)→ gotchas.md:465 (same entry as retire 2): the entry owns the helper-recovery-then-bundle-sideload ladder for pod git auth failures and cites this body directly.- [hf-xet download wedge — kill + replay with HF_HUB_DISABLE_XET=1](/docs/feedback_hf_xet_download_wedge_kill_replay) — du frozen + ss empty + py-spy xet_get frame = native xet hang; retry wrappers cannot fire (#1345)→ gotchas.md:427: "hf-xet DOWNLOAD wedge — the nativexet_getcall can hang FOREVER with ZERO TCP connections and no exception; per-file retry wrappers structurally cannot fire; recover by kill + replay withHF_HUB_DISABLE_XET=1inline" (body cited in the entry).
Considered and kept (retire candidates rejected)
feedback_vllm_teardown_sigabrt_resume.md— gotchas.md:196 only cites it as a DISCRIMINATOR ("… vs a vLLM engine ()"); the entry itself teaches the HF-datasets shutdown-SIGABRT sibling, not this lesson's verify-outputs/plain-relaunch/resume recipe. KEPT.feedback_shallow_clone_fix_commit_verification.md— no covering entry:grep -n "shallow\|depth-1" .claude/rules/crash-fix-rounds.md→ 0 hits. KEPT.feedback_hf_rate_limit.md— upload-policy.md:343 covers the rate limit + bulk-commit halves, but the "NEVER upload_large_folder (0-file bug)" residual appears in no covering surface (grep upload_large_folder .claude/rules/upload-policy.md→ 0 hits). KEPT.feedback_archive_script_path.md— target still exists (scripts/archive/is populated). KEPT.feedback_vllm0110_transformers5_breakage.md—uv.lockpins vllm>=0.6,<1.0, so the 0.11.x combo remains reachable. KEPT.feedback_uv_sync_moosefs_stale_handle_persistent.md— gotchas.md:85 mentions it only to DISTINGUISH it ("Also distinct from theuv syncerrno-116 stale-handle trap"); the fix recipe lives in the body alone. KEPT.
Intentionally-unreferenced bodies (18 — the retired set; no others)
Post-curation reconcile: every body in
.claude/agent-memory/experimenter/ is referenced by a surviving row
EXCEPT exactly the 18 retired bodies listed above (retires 1-18), each
justified there; 13 of the 18 remain cited from .claude/rules/
(gotchas.md / pod-side-reporting.md), so they stay reachable from the
covering rules.
Verification
- Bytes: 19,303 → 15,578 (hard cap 18,000 met with margin; ~600 B above the ~15,000 soft target — the residual is 65 KEEP rows that are live, unique, and unsuperseded; per the plan §6 kill criterion nothing further was dropped to chase the byte number).
- Rows: 96 → 71; 95 body files on disk, 0 deleted.
- Link-resolution loop over surviving rows: 77/77 referenced bodies exist.
workflow_lint.py --check-agent-memory-index-size(the same check the no-flags bundle runs): PASS — no agent-memory WARN/FAIL for experimenter (or any other agent) at curation time.
reconciler
Before: 19,300 bytes / 79 index rows (77 distinct bodies; two exact
duplicate-row pairs). After: 17,784 bytes / 62 rows, still referencing
all 77 bodies. Classification: 51 KEEP (byte-verbatim) · 11 MERGE groups
(28 rows → 11 rows: 2 exact-duplicate dedupes + 9 multi-link family rows) ·
0 RETIRE. Every surviving pointer resolves on disk (test -f loop: 77/77);
zero previously-referenced bodies lost a direct index pointer (set
difference old-referenced ∖ new-referenced = ∅).
Merges (rows in → row out; all original bodies stay directly linked)
- Exact-duplicate dedupe: the two "Claude misses when the plan's
HEADLINE decision statistic isn't produced" rows (same body;
(#841)vs(#841, #922)tails) → ONE row keeping the richer(#841, #922)text verbatim (feedback_claude_misses_headline_decision_statistic_not_produced.md). - Exact-duplicate dedupe: the two "Claude under-classes silent
failures" rows (same body; one tail carried "incl (#1098)", the other
"11-incident ledger + defenses") → ONE union row
(
feedback_claude_underclasses_silent_failures.md). - "Grep the consumer/writer surface before crediting a plan claim" ←
daemon-interface route filter (#956) + state-rewrite safety claims
(#908, #919) + reroute consumer-pointer trace (#564 r1). Same trap/fix
class: Claude APPROVEs a plan's topology/state claim without grepping
the actual consumer/writer surface. Bodies linked inline:
feedback_claude_approves_daemon_interface_read_missing_route_filter.md,feedback_claude_accepts_plan_state_rewrite_safety_claim.md,feedback_claude_approves_reroute_without_consumer_pointer_trace.md. - "Claude credits claims without the direct probe" ← per-item disk
assumption framed as a code claim (#724) + caller-topology claims
without wrapper trace (#868) + labeled-split over disjoint registries
(#901). Same fix class: run the direct probe (per-folder ls /
live-execute the predicate / intersect the key sets) instead of a code
read. Bodies linked inline:
feedback_claude_trusts_disk_assumption_framed_as_code_claim.md,feedback_claude_trusts_caller_topology_claims_without_wrapper_trace.md,feedback_claude_approves_labeled_split_over_disjoint_registries.md. - "Same name, different quantity → FAIL not Nit" ← predictor formula
mismatch as Nit (#518) + plan-vs-parent semantic refinement (#506 r3) +
estimand divergence via plan pseudocode (#539). Same trap class: the
implementation computes a different quantity than the plan's named
construct, under the construct's name. Bodies linked inline:
feedback_claude_treats_predictor_formula_mismatch_as_nit.md,feedback_claude_inherits_parent_with_plan_semantic_refinement.md,feedback_claude_excuses_estimand_divergence_via_plan_pseudocode.md. - "Claude accepts insufficient smoke evidence (smoke-gate family)" ←
missing tiny-N smoke (#492, #551) + dry-run misses CUDA init (#488) +
synthetic-fixture masks args-grid bug (#517 r2). Same trap class: smoke
evidence that cannot exercise what production exercises. Bodies linked
inline:
feedback_claude_concerns_on_smoke_gate.md,feedback_claude_dry_run_smoke_misses_cuda_init.md,feedback_claude_synthetic_fixture_smoke_masks_args_grid_bug.md. - "Read the named gate's ACTUAL semantics before crediting it" ←
trusts green tests over verifier semantics (#454, #608) + cites
nonexistent backstop semantics (#594). Same fix class: read the gate's
check bodies / fail condition before crediting it. Bodies linked
inline:
feedback_claude_trusts_green_tests_over_verifier_semantics.md,feedback_claude_cites_nonexistent_backstop_semantics.md. - "Claude misses built-but-not-wired production paths" ←
dispatcher-wiring correctness bugs (#504/#517/#520) +
scaffolded-but-not-plumbed pipelines (#397, #508). Same fix class: grep
the production wiring/invocation site. Bodies linked inline:
feedback_claude_misses_dispatcher_wire_bugs.md,feedback_claude_scaffolded_pipeline_not_plumbed.md. - "Codex misreads git/worktree state (git-provenance family)" ←
litigates pre-existing/stale state in round N (#922) + gitignored
worktree artifacts as production state (#543, #570) + raw-branch-diff
misses the Step 10d surgical merge (#511 r1). Same trap class: Codex
FAILs on repo/worktree state the round's diff did not introduce. Bodies
linked inline:
feedback_codex_litigates_pre_existing_in_round_n.md,feedback_codex_gitignored_artifacts_as_production_state.md,feedback_codex_raw_branch_diff_misses_surgical_merge.md. - "Codex re-litigates adjudicated content" ← grandfathered re-gate
prose (#464) + plain-English replacement after a keyword ban (#715).
Same trap class: re-flagging content a prior round already
adjudicated. Bodies linked inline:
feedback_codex_relitigates_grandfathered_regate_prose.md,feedback_codex_relitigates_replacement_register_after_keyword_ban.md. - "Numeric claims: re-derive from the pinned artifacts yourself" ←
recount with silent matcher variant (#833 r2) + fix WORDING vs
artifact TRUTH (#778) + wrong statistic / JSON-only artifact search
(#920). Same fix class: adjudicate numeric disputes by re-deriving
from the pinned artifacts under the plainest rule. Bodies linked
inline:
feedback_codex_recount_with_silent_normalization.md,feedback_codex_verifies_fix_wording_not_artifact_truth.md,feedback_codex_fails_correct_numeric_claim_wrong_statistic_or_artifact.md.
Retires — none (0)
The reconciler index was already curated once by #1891 (commit
28bb5842dc, 2026-07-30, 24,479 → 19,300 B), which stripped it to dense
single-incident calibration rows. Every retire candidate evaluated this
round failed the airtight-supersession bar (§ Considered and kept below);
per the plan's "when in doubt → KEEP; never drop a live lesson for bytes",
zero rows were retired.
Considered and kept (retire candidates rejected)
feedback_claude_approves_unwired_lint_check_plans.md(#842, #891) — candidate covering surfaceverify_plan.pycheck 37 is WARN-only AND claim-verb-anchored (fires only when the plan makes a no-flags bundling CLAIM;scripts/verify_plan.py:6664-6708): a check-addition plan with unpinned wiring that makes no bundling claim escapes it entirely. KEPT.feedback_codex_conflates_marker_format_with_code.md— the CLAUDE.md § Codex ensemble review mechanical-contract strip covers TAGGEDmarker-shapeblockers at the ORCHESTRATOR; untagged cosmetic nits still reach the reconciler, which is this row's audience. KEPT.feedback_claude_misses_comment_tail_spoof_on_rawscan_guards.md(#897) —grep -n 'waiver\|replay\|comment-tail' .claude/rules/trigger-dense-review.md→ 0 hits; no covering clause. KEPT.feedback_cross_lens_defect_refiled_per_lens.md(#546) +feedback_codex_plan_section_in_scope.md(#505 r6) —.claude/agents/reconciler.mdencodes neither the lens-scope nor the round-scope judgment (grep over the spec: no covering span). KEPT.feedback_clean_result_bare_issue_refs_and_reuse_path.md(#722) — reconciler.md rule 10 forces SPEC-quoting on a structure-lens override but does not encode these two grounded finding classes; the row saves the SPEC lookup at exactly the adjudication moment. KEPT.feedback_codex_litigates_pre_existing_in_round_n.md— the evidence-based git-provenance strip (CLAUDE.md § Codex ensemble review) covers TAGGED blockers at the orchestrator, same residual argument as the marker-shape row; MERGED into family row 9 above instead of retired.
Intentionally-unreferenced bodies (47 — all pre-existing; 0 new this round)
This curation created NO newly-unreferenced bodies (all 28 merged-away
rows' bodies stay directly linked from their family rows). The dir
carries 47 bodies that were ALREADY index-unreferenced on origin/main
before this round, in two classes, verified against EVERY historical
revision of the index (git log --all --follow --format=%H -- .claude/agent-memory/reconciler/MEMORY.md, each revision's blob grepped
for each filename; 10 revisions checked):
(a) Never referenced by ANY index revision (40) — bodies written by
reconciler invocations that never added an index row; each remains
readable on demand (self-describing frontmatter/title), and some are
cited directly from rule files (e.g.
.claude/rules/selection-symmetric-nulls.md § Files of record cites
feedback_layer_selection_asymmetry_is_alternatives_finding.md).
Re-indexing dormant bodies is additive work outside this task's
merge/retire scope and would breach the byte cap (~40 rows ≈ +8 KB):
feedback_claude_approves_infra_plan_with_unpinned_required_behaviors.md,
feedback_claude_approves_plan_test_scope_omits_sibling_behavior_tests.md,
feedback_claude_asserts_link_confinement_without_grep.md,
feedback_claude_asserts_resident_loop_on_oneshot_poller.md,
feedback_claude_bounded_argument_covers_only_half_the_predicate.md,
feedback_claude_conflates_adjacent_smoke_carveout_sections.md,
feedback_claude_credits_fix_to_wrong_surface.md,
feedback_claude_credits_test_without_tracing_falsification_path.md,
feedback_claude_downgrades_validation_gate_logic_and_gauge_blindness.md,
feedback_claude_fileexistence_pass_misses_named_deliverable_absence.md,
feedback_claude_generalizes_panel_validity_across_unread_behaviors.md,
feedback_claude_interp_critic_verify_body_fail_out_of_scope.md,
feedback_claude_misses_symmetric_failure_path_after_pivot_fix.md,
feedback_claude_passes_rulea_deferral_and_dropped_headline_deliverable.md,
feedback_claude_round_n_walkdown_misses_registered_operand_mismatch.md,
feedback_claude_self_flags_then_excuses_feature_defeating_bug.md,
feedback_claude_underclasses_idempotency_breach_as_perinvariant_reframe.md,
feedback_claude_underclasses_vacuous_regression_test.md,
feedback_claude_unregistered_null_for_argmax_winmatrix_as_nonblocking.md,
feedback_claude_walkdown_omits_unlisted_grouping_parser.md,
feedback_codex_approves_by_not_engaging_anchored_reproduction_target.md,
feedback_codex_catches_comment_promised_reraise_and_logp_sibling.md,
feedback_codex_catches_mismatched_question_contrastive_negatives.md,
feedback_codex_catches_registered_bar_wired_to_wrong_harness_baseline.md,
feedback_codex_clean_result_cosmetic_nits_and_prior_pass_relitigation.md,
feedback_codex_default_value_assumed_to_be_intended_dose.md,
feedback_codex_flags_step5a_specfreshness_sync_as_scope_violation.md,
feedback_codex_isolation_review_misses_stale_base_merge_collision.md,
feedback_codex_misreads_permutation_null_as_same_sample_optimism.md,
feedback_codex_per_machine_capability_divergence_unsupported.md,
feedback_codex_reads_followup_round_delta_note_as_missing_smoke.md,
feedback_codex_real_defect_off_the_actual_run_path.md,
feedback_codex_real_gap_with_regressing_fix_is_recoverable.md,
feedback_codex_reapplies_v3_check_to_v2_body.md,
feedback_codex_rope_leftpad_position_ids_blocker.md,
feedback_foreign_tasks_union_merge_dup_propagation.md,
feedback_g0_base_recompute_gate_does_not_validate_theta_plus_apply.md,
feedback_layer_selection_asymmetry_is_alternatives_finding.md,
feedback_preregistered_verdict_grid_miscalibrated_vs_own_clean_exemplar.md,
feedback_worked_example_excerpt_rank_vs_ranking_dv.md.
(b) Index row existed only on branch-side revisions (7) — their rows
were appended on issue branches and dropped when stale branch-side index
copies were aligned to main's #1891-curated version (commits
038a42ec6c, 0aaf39acac); the bodies survived (the add/add
resurrection shape). Restoring 7 rows ≈ +1.6 KB against the byte cap and
sits outside the approved merge/retire scope — flagged as a candidate for
a future curation round rather than done here:
feedback_claude_credits_plan_machine_claim_without_intent_map.md,
feedback_claude_downgrades_deliverable_corrupting_deviation_to_minor.md,
feedback_claude_misses_static_default_empty_filter_resample_order.md,
feedback_claude_recoverable_vs_unsatisfiable_registered_analysis_launch.md,
feedback_codex_catches_production_only_crash_claude_smoke_skips.md,
feedback_codex_catches_unwired_cron_and_silent_auth_pass.md,
feedback_codex_interp_roundN_misses_new_prose_regressions.md.
Verification
- Bytes: 19,300 → 17,784 (hard cap 18,000 met; ~2,800 B above the ~15,000 soft target — kill-criterion residual per plan §6: the 51 kept rows are post-#1891 single-incident calibration lessons, each live and unsuperseded; reaching ~15,000 would require dropping live lessons or fusing unrelated trap classes. Reported, not forced).
- Rows: 79 → 62; 124 body files on disk, 0 deleted.
- Link-resolution loop over surviving rows: 77/77 referenced bodies exist; previously-referenced-now-unreferenced set = ∅.
- KEEP rows byte-verbatim: verified by set difference — new rows not byte-identical to an old row = exactly the 10 rewritten merge rows (the 11th merge survivor keeps an old row's text verbatim).
workflow_lint.py(no-flags bundle): 0 agent-memory findings for the three curated agents.