p='crates/spt-daemon/src/relcache.rs'
b=open(p,'rb').read(); crlf=b'\r\n' in b; s=b.decode().replace('\r\n','\n')
a='''    // restoration D6-1) round-trips all three phases through disk; an absent'''
i=s.index(a); i=s.rindex('\n    //',0,i)  # start of that comment block
# insert before the comment block start line
blk_start=s.rindex('\n\n',0,s.index(a))+1
new='''
    fn pending_from(prior_product: Option<&str>) -> AppliedRecord {
        AppliedRecord::AppliedPending {
            version: 9,
            rollback_binary: "spt.exe.old-9".into(),
            candidate_started_ms: 1,
            prior_version: Some(8),
            prior_product_version: prior_product.map(str::to_string),
        }
    }

    fn stage_product(cache: &ReleaseCache, product: &str) {
        cache
            .stage(
                &SignedRelease {
                    metadata_json: format!("{{\\"version\\":9,\\"product_version\\":\\"{product}\\"}}"),
                    signature_hex: "ab".repeat(64),
                },
                b"new-bin",
            )
            .unwrap();
    }

    // [unit->REQ-NOW-SIGNAL-UPDATE-DIVULGE] the DAEMON writer: a promotion
    // records the core move — old from the pending record the swap wrote, new
    // from the staged set's signed product version, at the promotion instant,
    // with the node-served changelog — and it reads the pending record, so it
    // must run before the promotion overwrites it (order pinned below).
    #[test]
    fn core_promotion_records_the_move_from_the_pending_record() {
        let dir = tempfile::tempdir().unwrap();
        let cache = ReleaseCache::open(dir.path());
        stage_product(&cache, "0.73.0");
        cache.record_applied_state(&pending_from(Some("0.72.0"))).unwrap();
        let wrote = cache
            .record_core_promotion(5_000, Some("http://localhost:5474/node/docs/"))
            .expect("both halves known -> recorded");
        let want = SubjectApply {
            old: "0.72.0".into(),
            new: "0.73.0".into(),
            at_ms: 5_000,
            changelog: Some("http://localhost:5474/node/docs/changelog.html".into()),
            notice: None,
        };
        assert_eq!(wrote, want);
        assert_eq!(cache.subject_applies().get(SUBJECT_CORE), Some(&want), "durable, keyed spt-core");

        // Once promotion has overwritten the record, there is no old version to read.
        cache.record_applied_state(&AppliedRecord::Applied { version: 9 }).unwrap();
        assert_eq!(cache.record_core_promotion(6_000, None), None);
        assert_eq!(cache.subject_applies().get(SUBJECT_CORE).unwrap().at_ms, 5_000);
    }

    // [unit->REQ-NOW-SIGNAL-UPDATE-DIVULGE] degrade, never half-fill: a pending
    // record from before the field (no prior product version), a staged set
    // with no product version, or a non-move writes NOTHING.
    #[test]
    fn core_promotion_writes_nothing_when_a_half_is_unknown() {
        let dir = tempfile::tempdir().unwrap();
        let cache = ReleaseCache::open(dir.path());
        stage_product(&cache, "0.73.0");
        cache.record_applied_state(&pending_from(None)).unwrap();
        assert_eq!(cache.record_core_promotion(1, None), None);
        cache.record_applied_state(&pending_from(Some("0.73.0"))).unwrap();
        assert_eq!(cache.record_core_promotion(1, None), None, "same version is not a move");
        cache.stage(&signed(9), b"bin").unwrap();
        cache.record_applied_state(&pending_from(Some("0.72.0"))).unwrap();
        assert_eq!(cache.record_core_promotion(1, None), None, "no signed product version");
        assert!(cache.subject_applies().is_empty());
        // An unreadable record file reads as empty and is started over, not failed.
        std::fs::write(dir.path().join(SUBJECT_APPLIES_FILE), "{not json").unwrap();
        assert!(cache.subject_applies().is_empty());
        let a = core_subject_apply("1.0.0", "1.1.0", 2, None).unwrap();
        assert_eq!(a.changelog.as_deref(), Some(CORE_RELEASES_URL), "offline fallback link");
        cache.record_subject_apply(&subject_adapter("x"), &a).unwrap();
        assert_eq!(cache.subject_applies().len(), 1);
    }

'''
s=s[:blk_start]+new+s[blk_start:]
if crlf: s=s.replace('\n','\r\n')
open(p,'wb').write(s.encode())
