Match a subscription as written, and require a bridge for a relation
See an unreviewed preprint fail a declared 'peer-reviewed' condition, and a similar-looking paper stay UNRESOLVED because no bridge names both scopes.
A channel delivers things; a semantic channel delivers things that match what you actually asked for. The chapter’s claim is that the two are different machinery, and the run shows the two rules that make the difference: a subscription is matched as written and never rewritten, and a relation to the tracked claim is established by a bridge or not at all.
Run it
git clone https://github.com/ernanhughes/project-language.git
cd project-language
git checkout 329660f679a5a87831f91fe1430c20ac9360dda8
npm ci
npm run example:radarOne invented afternoon, five invented candidates. The model is a scripted stand-in and no real model is called.
Expected outcome
Five candidates arrive; each stops at a different gate, and the run says which:
...
candidate obs ret elig sel asm qual res time pres noticed
preprint yes yes yes n/a n/a NO . . ? ?
mechanism yes yes yes yes yes ? yes yes ? ?
contradiction yes yes yes yes yes yes yes yes ? ?
lossy yes yes yes yes yes yes yes yes ? ?
decoy yes yes NO . . . . . ? ?A preprint does not satisfy a declared peer-review condition, and the subscription is not quietly rewritten to include preprints:
...
preprint A eligible, and its standing does not satisfy 'peer-reviewed': not qualified. The subscription is as the person wrote it.A different mechanism, with high closeness and no bridge, is not a relation:
...
mechanism B closeness is high; no bridge; the relation to the tracked claim is UNRESOLVED, so it is kept available (not pushed) and says so.And a keyword-stuffed decoy is retrieved and then goes no further:
...
decoy E keyword-stuffed. Retrieved. No grant and the wrong domain: not eligible. It goes no further.A subscription is matched as written
The subscription’s conditions are checked against the candidate and the result records what was unmet. Nothing rewrites the condition to make it fit.
export function matchSubscription(sub: Subscription, c: CandidateItem): SubscriptionMatch {
const unmet: Unmet[] = []; const reasons: Reason[] = [];
for (const cond of sub.conditions) {
if (cond.kind === "standing") {
const ok = cond.requires.includes(c.standing);
reasons.push(R("evidence_standing", "computed_rule", `${sub.id}@${sub.version}`, `requires ${cond.requires.join("|")}; candidate is ${c.standing}`));
if (!ok) unmet.push({ condition: `standing in [${cond.requires.join(", ")}]`, stated: cond.stated, observed: c.standing });
} else {
const ok = parseTime(c.validFrom, "validFrom") >= parseTime(cond.requires[0]!, "condition.after");
if (!ok) unmet.push({ condition: `after ${cond.requires[0]}`, stated: cond.stated, observed: c.validFrom });
}
}
const excluded_by = sub.exclusions.filter(x => c.text.toLowerCase().includes(x.toLowerCase()));
return { matched: unmet.length === 0 && excluded_by.length === 0, unmet, excluded_by, subscription_version: sub.version, reasons };
}A relation is established by a bridge or not at all
Similarity, an embedding, or a model’s assertion cannot establish that another item bears on the tracked claim. A bridge must come from a person or a domain rule, must name both scopes, and must claim the relation the subscription asks for.
export function establishRelation(sub: Subscription, c: CandidateItem, bridge?: Bridge): RelationResult {
const unresolved = (why: string): RelationResult => ({
status: "UNRESOLVED", why,
reasons: [R("relation", "computed_rule", "no-bridge", why)],
});
if (!bridge) return unresolved(`no bridge connects "${c.scope}" to the tracked claim's scope "${sub.anchor.scope}"; closeness is not a relationship`);
if (bridge.supplied_by === "model") return unresolved("a model's assertion is a proposal, not a bridge");
if (!bridge.argument_ref.trim()) return unresolved("a bridge must cite its argument");
if (!bridge.preserves_scope) return unresolved("the bridge does not claim to preserve scope");
if (bridge.relation !== sub.relation) return {
status: "NOT_RELATED", why: `the bridge asserts "${bridge.relation}"; the subscription asks about "${sub.relation}"`,
reasons: [R("relation", "supplied_judgement", bridge.id, `${bridge.supplied_by} bridge asserts "${bridge.relation}", not the subscribed "${sub.relation}"`)],
};
if (bridge.anchor_scope !== sub.anchor.scope) return unresolved(`bridge is for scope "${bridge.anchor_scope}", not the tracked "${sub.anchor.scope}"`);
if (bridge.candidate_scope !== c.scope) return unresolved(`bridge is for candidate scope "${bridge.candidate_scope}", not "${c.scope}"`);
return {
status: "ESTABLISHED", why: bridge.asserts,
reasons: [R("relation", "supplied_judgement", bridge.id, `${bridge.supplied_by} bridge ${bridge.argument_ref}: ${bridge.asserts}`)],
};
}Mechanism and limitations
Documented: the two rules above, and the four independent eligibility
booleans — permission, currentness, scope and standing — are in
core/radar/src/attention/qualify.ts. The Part II contract at the root of the
repository states the wider design.
Observed: the run above. The preprint was eligible and observed but did not qualify, with the unmet condition recorded; the mechanism item was retrieved and selected but its relation was UNRESOLVED, and it was kept AVAILABLE rather than pushed; the decoy was retrieved and then refused at eligibility for want of a grant and a scope mismatch.
Not shown. The bridge is supplied: nothing here finds a relation, and cross-domain discovery is not established. In the tests, a model’s assertion alone cannot serve as the missing bridge, but a person can supply one. There is no open-world coverage or recall, and no claim is made about how often these situations occur.
Understand this example
Copy this prompt into your AI tool. No code runs here.
Apply this example
Copy this prompt into your AI tool. No code runs here.