Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 1e06f00336 | |||
| e7775541fe |
5 changed files with 132 additions and 9 deletions
|
|
@ -4,7 +4,7 @@
|
|||
//! lowerer sees, comes from `PacketStore::admit` alone, which builds it from
|
||||
//! the admitted packet and its corpus item through the crate-private
|
||||
//! `LoweringInput::of`. The stance is checked like every feature
|
||||
//! list, in slot `Stance`. The rules are V1..V8, V10..V12 and V14..V17: the
|
||||
//! list, in slot `Stance`. The rules are V1..V8, V10..V12 and V14..V18: the
|
||||
//! shape of an id or a grade is its type's parse, not a rule, so V9 is retired
|
||||
//! and not renumbered; V13 is retired too. [`LoweringInput::with_scene`] reads the
|
||||
//! scene of the view's own item group from the speaker-state store, and
|
||||
|
|
@ -120,6 +120,12 @@ pub enum Refusal {
|
|||
V17AddresseeNotAReferent {
|
||||
id: NodeId,
|
||||
},
|
||||
/// V18: a predication whose frame is the inventory's `request_intervention`,
|
||||
/// with no `addressee_consent` naming it. It says what the addressee did, so
|
||||
/// only the packet's own record may license it.
|
||||
V18RequestWithoutConsent {
|
||||
predication: NodeId,
|
||||
},
|
||||
}
|
||||
|
||||
impl Refusal {
|
||||
|
|
@ -144,6 +150,7 @@ impl Refusal {
|
|||
Refusal::V15ConsentSource { .. } => "V15",
|
||||
Refusal::V16SpeakerNotInScene => "V16",
|
||||
Refusal::V17AddresseeNotAReferent { .. } => "V17",
|
||||
Refusal::V18RequestWithoutConsent { .. } => "V18",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -173,6 +180,9 @@ impl fmt::Display for Refusal {
|
|||
"the scene does not cover the speaker of every live item of its group"
|
||||
}
|
||||
Refusal::V17AddresseeNotAReferent { .. } => "the addressee names no referent",
|
||||
Refusal::V18RequestWithoutConsent { .. } => {
|
||||
"a request frame needs the addressee's consent naming it"
|
||||
}
|
||||
};
|
||||
write!(f, "{}: {what}", self.rule())
|
||||
}
|
||||
|
|
@ -221,6 +231,7 @@ pub fn validate(packet: &Packet, inventory: &Inventory) -> Result<(), Vec<Refusa
|
|||
out: &mut out,
|
||||
}
|
||||
.check(packet);
|
||||
check_requests(packet, inventory, &mut out);
|
||||
} else {
|
||||
out.push(Refusal::V10UnknownRevision {
|
||||
rev: packet.inventory_rev,
|
||||
|
|
@ -303,6 +314,25 @@ fn check_consent(packet: &Packet, nodes: &BTreeSet<NodeId>, out: &mut Vec<Refusa
|
|||
}
|
||||
}
|
||||
|
||||
/// The gloss of the inventory frame that reports an addressee's request.
|
||||
const REQUEST_FRAME_GLOSS: &str = "request_intervention";
|
||||
|
||||
/// V18: a predication whose frame, resolved at the packet's revision, is the
|
||||
/// request frame is named by `addressee_consent`. An unresolved frame is V5's.
|
||||
fn check_requests(packet: &Packet, inventory: &Inventory, out: &mut Vec<Refusal>) {
|
||||
for p in &packet.predications {
|
||||
if inventory
|
||||
.resolve(&p.frame, packet.inventory_rev)
|
||||
.is_some_and(|e| e.gloss == REQUEST_FRAME_GLOSS)
|
||||
&& packet.discourse.addressee_consent.as_ref() != Some(&p.id)
|
||||
{
|
||||
out.push(Refusal::V18RequestWithoutConsent {
|
||||
predication: p.id.clone(),
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn node_lists(packet: &Packet) -> [(&Vec<NodeId>, &'static str); 3] {
|
||||
[
|
||||
(&packet.context.participants, "participant"),
|
||||
|
|
|
|||
|
|
@ -593,6 +593,41 @@ mod lowering {
|
|||
assert!(Prompt::lower(&read, &item, &away(), "en-US", &inv, &held, &empty).is_ok());
|
||||
}
|
||||
|
||||
/// The packet the encoder emits for a request: frame:3, no consent, source
|
||||
/// ModelDecomposition. Admission refuses it, so no lowering view exists.
|
||||
#[test]
|
||||
fn an_encoder_request_never_reaches_a_lowerer() {
|
||||
let cast = InventoryStore::open(&data("interlingua/inventory.cc")).unwrap();
|
||||
let entities = EntityStore::open(&data("entity/entity.cc")).unwrap();
|
||||
let corpus = CorpusStore::open(&data("corpus/corpus.cc")).unwrap();
|
||||
let dir = tempfile::tempdir().unwrap();
|
||||
let mut store = PacketStore::open(&dir.path().join("p.cc")).unwrap();
|
||||
let mut packet = proof_packet();
|
||||
packet.provenance.source = weksa::packet::ProvenanceSource::ModelDecomposition;
|
||||
packet.predications[0].frame = weksa::InvId::parse("frame:3").unwrap();
|
||||
match store.admit(packet.clone(), &cast, &corpus, &entities) {
|
||||
Err(weksa::StoreError::Invalid(r)) => assert_eq!(
|
||||
r,
|
||||
vec![weksa::Refusal::V18RequestWithoutConsent {
|
||||
predication: weksa::packet::NodeId::parse("n4").unwrap()
|
||||
}]
|
||||
),
|
||||
other => panic!("expected V18, got {:?}", other.map(|_| ())),
|
||||
}
|
||||
// Not blanket: telemetry that records the consent admits and lowers.
|
||||
packet.provenance.source = weksa::packet::ProvenanceSource::GameTelemetry;
|
||||
packet.discourse.addressee_consent = Some(weksa::packet::NodeId::parse("n4").unwrap());
|
||||
drop(store);
|
||||
let view = admitted(packet, &cast, "corpus/corpus.cc", &entities);
|
||||
let item = CorpusItemId::parse("item:nibu:1").unwrap();
|
||||
let held = Held(vec![nibu(&[("en-US", &["Nibu"])])]);
|
||||
let empty = weksa::Ontology::empty();
|
||||
assert!(
|
||||
Prompt::lower(&view, &item, &away(), "en-US", &cast.inventory().unwrap(), &held, &empty)
|
||||
.is_ok()
|
||||
);
|
||||
}
|
||||
|
||||
fn dao(index: usize) -> (LoweringInput, Inventory, EntityStore, CorpusItemId) {
|
||||
let inv = InventoryStore::open(&data("daodejing/inventory.cc")).unwrap();
|
||||
let entities = EntityStore::open(&data("daodejing/entity.cc")).unwrap();
|
||||
|
|
|
|||
|
|
@ -104,6 +104,7 @@ fn refusal_display_names_the_rule_and_no_identifier() {
|
|||
},
|
||||
Refusal::V16SpeakerNotInScene,
|
||||
Refusal::V17AddresseeNotAReferent { id: node() },
|
||||
Refusal::V18RequestWithoutConsent { predication: node() },
|
||||
];
|
||||
assert_eq!(
|
||||
Refusal::V16SpeakerNotInScene.to_string(),
|
||||
|
|
|
|||
|
|
@ -740,6 +740,53 @@ fn a_source_that_only_read_wording_cannot_set_consent() {
|
|||
}
|
||||
}
|
||||
|
||||
// V18: a request frame is licensed by the packet's own consent record.
|
||||
|
||||
/// The committed inventory, where `frame:3` is `request_intervention`.
|
||||
fn cast_refusals(p: &Packet) -> Vec<Refusal> {
|
||||
let path = std::path::Path::new(env!("CARGO_MANIFEST_DIR")).join("../../data/interlingua/inventory.cc");
|
||||
let inv = weksa::InventoryStore::open(&path).unwrap().inventory().unwrap();
|
||||
validate(p, &inv).err().unwrap_or_default()
|
||||
}
|
||||
|
||||
fn requesting() -> Packet {
|
||||
let mut p = proof_packet();
|
||||
p.predications[0].frame = iv("frame:3");
|
||||
p.discourse.addressee_consent = Some(nd("n4"));
|
||||
p
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn a_request_frame_needs_consent_naming_its_predication() {
|
||||
assert_eq!(cast_refusals(&requesting()), vec![]);
|
||||
let mut p = requesting();
|
||||
p.discourse.addressee_consent = None;
|
||||
assert_eq!(
|
||||
cast_refusals(&p),
|
||||
vec![Refusal::V18RequestWithoutConsent { predication: nd("n4") }]
|
||||
);
|
||||
p.discourse.addressee_consent = Some(nd("n5"));
|
||||
assert_eq!(
|
||||
cast_refusals(&p),
|
||||
vec![Refusal::V18RequestWithoutConsent { predication: nd("n4") }]
|
||||
);
|
||||
let mut p = requesting();
|
||||
p.provenance.source = ProvenanceSource::GameTelemetry;
|
||||
assert_eq!(cast_refusals(&p), vec![]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn model_source_consent_is_v15_alone() {
|
||||
let mut p = requesting();
|
||||
p.provenance.source = ProvenanceSource::ModelDecomposition;
|
||||
assert_eq!(
|
||||
cast_refusals(&p),
|
||||
vec![Refusal::V15ConsentSource {
|
||||
source: ProvenanceSource::ModelDecomposition
|
||||
}]
|
||||
);
|
||||
}
|
||||
|
||||
// V17: the addressee is someone spoken to, a referent.
|
||||
|
||||
#[test]
|
||||
|
|
|
|||
|
|
@ -164,6 +164,7 @@ names the rule.
|
|||
`GameTelemetry`; a decomposition of text or imported corpus text cannot mint
|
||||
it.
|
||||
- V17: an `addressee` names a referent, not a predication.
|
||||
- V18: a predication whose frame is the inventory's `request_intervention` is named by `addressee_consent`.
|
||||
|
||||
V9 is retired and not renumbered: the form of a key or a grade is its type, and
|
||||
an extension key's family is V6. `PacketStore::admit` returns the lowering view of a
|
||||
|
|
@ -197,14 +198,23 @@ whatever the inventory grows). This is source-side communicative pressure, not
|
|||
target-language register. `addressee_consent` is no feature: it names the
|
||||
predication the addressee asked for or agreed to, a fact about what the
|
||||
addressee did. `V14` and `V15` check the field: it may be set only by authoring or game
|
||||
telemetry, and it must name a predication of the packet. Open gap: `frame:3`
|
||||
(`request_intervention`) is in the committed inventories (`data/interlingua`,
|
||||
`data/original`, `data/daodejing`) and seeded at `inventory.rs:518`. No
|
||||
committed packet uses it, but the encoder sees it, and `V14` and `V15` check only
|
||||
the consent field, so a model-encoded `frame:3` predication with a null
|
||||
`addressee_consent` reaches `Prompt::lower` and nothing refuses it. The retired
|
||||
gate covered only the deleted `lower()`. Follow-up
|
||||
`table-retirement-consent-gap` owns the gap.
|
||||
telemetry, and it must name a predication of the packet. `V18` refuses a predication whose frame resolves, at the packet's revision, to
|
||||
the gloss `request_intervention` (`frame:3` in the committed inventories)
|
||||
unless `addressee_consent` names that predication. The encoder can never set
|
||||
consent (`V15`), so an encoder-produced `request_intervention` predication (`frame:3`) is always refused.
|
||||
Limits, tracked by `weksa-lowering:follow_up:request-frame-consent-residual`:
|
||||
`V18` keys on the gloss `request_intervention` and sees no other frame or
|
||||
concept, so a request-shaped meaning built from another frame or concept (a
|
||||
`frame:12` communication with `concept:6` request validates) or from a renamed
|
||||
or newly minted frame is not seen by `validate`, which does not read meaning.
|
||||
The inventory carries no marker for request shape, so classifying it would be
|
||||
an inventory-shape decision for Imagination and language-ontology. `addressee_consent`
|
||||
is one field, so a packet carries one request predication, and a compound
|
||||
request is two packets until a packet schema revision makes consent a set. The
|
||||
asker is not checked to be the addressee: a consented `frame:3` whose agent is
|
||||
not the addressee validates, and no code outside `validate` and the encoder
|
||||
prompt text reads `addressee_consent`. That check is an owed obligation with no
|
||||
owner yet.
|
||||
|
||||
### `stance`
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue