ja-inventory-6: rev 6 concepts (try, someday, a little, as one pleases, kite flyer) and the admit-cap test #55
5 changed files with 46 additions and 19 deletions
|
|
@ -26,7 +26,7 @@ measured.
|
|||
- `data/corpus/corpus.cc`, `data/entity/entity.cc` and `data/interlingua/inventory.cc`: the English
|
||||
corpus, its entities and the inventory, read with `weksa corpus dump`,
|
||||
`weksa entity dump` and `weksa inventory dump`. `data/original/inventory.cc`
|
||||
carries its own Validation-informed lexicon revision (rev 5) for lowering
|
||||
carries its own Validation-informed lexicon revisions (5 and 6) for lowering
|
||||
measurements; scored runs use `data/interlingua`.
|
||||
- [Lowering target](./docs/targets/interlingua-lowering.md) and
|
||||
[its map](./docs/targets/interlingua-lowering-map.md): the design, scoring
|
||||
|
|
|
|||
|
|
@ -1903,3 +1903,26 @@ fn inventory_admit_numbers_a_draft_and_refuses_an_empty_one() {
|
|||
let dump = out(&weksa(d.path(), &["inventory", "dump"]));
|
||||
assert!(dump.contains("bath_house") && dump.contains("fly_a_kite"), "{dump}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn inventory_admit_cap_is_256_and_a_refusal_writes_nothing() {
|
||||
let d = tempfile::tempdir().unwrap();
|
||||
assert!(weksa(d.path(), &["inventory", "seed"]).status.success());
|
||||
let draft = |name: &str, n: usize| {
|
||||
let adds: Vec<String> = (0..n)
|
||||
.map(|i| format!(r#"{{"family":"Concept","gloss":"cap_probe_{i}"}}"#))
|
||||
.collect();
|
||||
let p = d.path().join(name);
|
||||
std::fs::write(&p, format!(r#"{{"add":[{}]}}"#, adds.join(","))).unwrap();
|
||||
p.to_str().unwrap().to_owned()
|
||||
};
|
||||
let before = out(&weksa(d.path(), &["inventory", "dump"]));
|
||||
|
||||
let refused = weksa(d.path(), &["inventory", "admit", &draft("over.json", 257)]);
|
||||
assert!(!refused.status.success(), "{}", out(&refused));
|
||||
assert_eq!(before, out(&weksa(d.path(), &["inventory", "dump"])));
|
||||
|
||||
let admitted = weksa(d.path(), &["inventory", "admit", &draft("cap.json", 256)]);
|
||||
assert!(admitted.status.success(), "{}", out(&admitted));
|
||||
assert!(out(&admitted).contains("admitted rev:2 with 256 entries"));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -240,14 +240,15 @@ fn the_first_six_original_items_are_unchanged() {
|
|||
}
|
||||
}
|
||||
|
||||
/// Revision 5 of `data/original/inventory.cc` is the original bed's own
|
||||
/// lexicon: concepts and frames drafted by claude-sonnet-5-5 (Weksa Hands,
|
||||
/// Revisions 5 and 6 of `data/original/inventory.cc` are the original bed's own
|
||||
/// lexicon (rev 5, 233 adds; rev 6, five adds for try, someday, a little, as one
|
||||
/// pleases and the one who flies a kite, same generator): concepts and frames drafted by claude-sonnet-5-5 (Weksa Hands,
|
||||
/// model-drafted original-bed lexicon from Train and Validation passages) so an
|
||||
/// encoder can name baths, kites and persimmons. It is Validation-informed on
|
||||
/// purpose: numbers on this bed measure the lowering half (register, scene,
|
||||
/// ontology), never inventory generalization or convergence; scored runs use
|
||||
/// `data/interlingua`. The Dao De Jing inventory is its revision prefix.
|
||||
const ORIGINAL_REV5_ADDS: usize = 233;
|
||||
const ORIGINAL_OWN_ADDS: [usize; 2] = [233, 5];
|
||||
|
||||
#[test]
|
||||
fn the_dao_inventory_is_a_prefix_of_the_original_inventory() {
|
||||
|
|
@ -261,8 +262,7 @@ fn the_dao_inventory_is_a_prefix_of_the_original_inventory() {
|
|||
};
|
||||
let (dao, own) = (open("daodejing"), open("original"));
|
||||
assert_eq!(dao.latest().unwrap().n, 4);
|
||||
let latest = own.latest().unwrap();
|
||||
assert_eq!((latest.n, latest.parent), (5, Some(4)));
|
||||
assert_eq!(own.latest().unwrap().n, 6);
|
||||
for n in 1..=4 {
|
||||
let revision = |inv: &weksa::Inventory| inv.revisions().find(|r| r.n == n).cloned();
|
||||
assert_eq!(revision(&dao), revision(&own), "rev {n}");
|
||||
|
|
@ -272,17 +272,21 @@ fn the_dao_inventory_is_a_prefix_of_the_original_inventory() {
|
|||
assert_eq!(own.entry(&e.id), Some(e), "{}", e.gloss);
|
||||
glosses.insert(e.gloss.clone());
|
||||
}
|
||||
assert_eq!(latest.changes.len(), ORIGINAL_REV5_ADDS);
|
||||
for change in &latest.changes {
|
||||
let Change::Add(id) = change else {
|
||||
panic!("rev 5 retires {change:?}");
|
||||
};
|
||||
let e = own.entry(id).unwrap();
|
||||
assert!(matches!(id.family(), Family::Concept | Family::Frame), "{id}");
|
||||
assert_eq!(e.introduced_rev, 5, "{id}");
|
||||
assert!(glosses.insert(e.gloss.clone()), "{} repeats a gloss", e.gloss);
|
||||
for (n, expected) in [5u32, 6].into_iter().zip(ORIGINAL_OWN_ADDS) {
|
||||
let rev = own.revisions().find(|r| r.n == n).unwrap();
|
||||
assert_eq!(rev.parent, Some(n - 1), "rev {n}");
|
||||
assert_eq!(rev.changes.len(), expected, "rev {n}");
|
||||
for change in &rev.changes {
|
||||
let Change::Add(id) = change else {
|
||||
panic!("rev {n} retires {change:?}");
|
||||
};
|
||||
let e = own.entry(id).unwrap();
|
||||
assert!(matches!(id.family(), Family::Concept | Family::Frame), "{id}");
|
||||
assert_eq!(e.introduced_rev, n, "{id}");
|
||||
assert!(glosses.insert(e.gloss.clone()), "{} repeats a gloss", e.gloss);
|
||||
}
|
||||
}
|
||||
assert_eq!(own.entries().count(), dao.entries().count() + ORIGINAL_REV5_ADDS);
|
||||
assert_eq!(own.entries().count(), dao.entries().count() + ORIGINAL_OWN_ADDS.iter().sum::<usize>());
|
||||
}
|
||||
|
||||
/// The committed seed ontology: every entry model-drafted, exactly the two
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -31,7 +31,7 @@ means no store holds it and nothing writes it.
|
|||
|---|---|---|---|
|
||||
| Packet | Key `packet:<16 hex>`, an opaque digest of item, inventory revision and encoder (the item key lives in `provenance.corpus_item`, which the lowerer never sees); CultCache type `weksa.interlingua_packet`, carrying `schema_version` and `inventory_rev`. Every id inside is an opaque form type (`n<k>` nodes, `encoder:<16 hex>`, canonical `<family>:<n>`). From cut `speaker-state` (schema v4) it also carries the utterance **stance**: the speaker's felt affect and restraint, as inventory features of slot `Stance` (see Speaker state below) | Minted by an encoder for one corpus item under one spec version; immutable; a new spec version means a new packet, never an edit. Admitted only through `PacketStore::admit`, which validates against the inventory store at the packet's revision | The encoder writes; the form types refuse malformed ids at construction and load, the validator refuses broken references and over-capacity packets: a feature at most once per slot, at most 64 nodes (`typed-packet`); nothing else writes packets |
|
||||
| Schema version | `weksa.interlingua_packet.v<N>` constant in `crates/weksa`; published JSON Schema at `schemas/cultnet/` | Bumped by a commit that changes the Rust types; the published schema is regenerated in the same commit and a test fails on drift | A cut (Hands, under a spec); never the loop |
|
||||
| Inventory entry | Key `<family>:<n>`, `n` canonical decimal >= 1 (families: concept, frame, role, relation, speech_act, feature, referent_kind, extension); type `weksa.inventory_entry`, with a bounded gloss, value kind (option labels bounded), the slots a feature may sit in (`Discourse`, `Referent`, `Predication`, `Relation`; `Stance` from cut `speaker-state`, `Speaker` and `Scene` from cut `speaker-scene`), `introduced_rev` and optional `retired_rev`. Speaker axes, scene relations and affects are features of those slots, so the loop grows them like any closed-class family and convergence covers them | Added or retired by an inventory revision; never edited in place (a changed meaning is a retire plus an add); a retired id still resolves for packets of earlier revisions | The loop's accepted rounds, whose minting call the context builder assembles from Train items only; `weksa inventory admit` for one model-drafted `EditDraft` outside a run (cap 256, reviewed whole in its cut; same numbering and admission check as the loop); Self on merge to main. `data/original` rev 5 (233 concepts and frames) was drafted by claude-sonnet-5-5 (Weksa Hands, model-drafted original-bed lexicon from Train and Validation passages); Validation-informed: numbers on this bed measure lowering, never generalization or convergence. Admission checks form, not text |
|
||||
| Inventory entry | Key `<family>:<n>`, `n` canonical decimal >= 1 (families: concept, frame, role, relation, speech_act, feature, referent_kind, extension); type `weksa.inventory_entry`, with a bounded gloss, value kind (option labels bounded), the slots a feature may sit in (`Discourse`, `Referent`, `Predication`, `Relation`; `Stance` from cut `speaker-state`, `Speaker` and `Scene` from cut `speaker-scene`), `introduced_rev` and optional `retired_rev`. Speaker axes, scene relations and affects are features of those slots, so the loop grows them like any closed-class family and convergence covers them | Added or retired by an inventory revision; never edited in place (a changed meaning is a retire plus an add); a retired id still resolves for packets of earlier revisions | The loop's accepted rounds, whose minting call the context builder assembles from Train items only; `weksa inventory admit` for one model-drafted `EditDraft` outside a run (cap 256, reviewed whole in its cut; same numbering and admission check as the loop); Self on merge to main. `data/original` revs 5 (233 concepts and frames) and 6 (five concepts closing named gaps) were drafted by claude-sonnet-5-5 (Weksa Hands, model-drafted original-bed lexicon from Train and Validation passages); Validation-informed: numbers on this bed measure lowering, never generalization or convergence. Residue after rev 6, not amended (each fresh coverage reader names new gaps; the loop's growth path owns them): simultaneity (ながら), distal deixis (あの), 'first' (まず), counterfactual mood, 'at least', emphatic question; heaven versus sky for the visible 天 stays weak. Admission checks form, not text |
|
||||
| Inventory revision | Key `rev:<n>`, type `weksa.inventory_revision`, with parent, change list and `frozen` | Appended per accepted round; exactly one revision is ever marked frozen, by the convergence test | The loop's accept rule appends; the convergence test freezes; Self records the freeze as a ruling |
|
||||
| Target profile | Locale or language-project id (`en-US`, `ja-JP`, a conlang's slug). Until entries grow in rounds there is no profile revision document: a run names the profile it lowered with by the ontology store's path and digest in its `RunRecord` (cut `language-ontology`); `profile:<language>:<n>` revision documents arrive with follow-up `language-ontology-growth` | The ontology store is revised by commit; a run pins it and refuses drift; it likewise pins the speaker-state store (`RunRecord` keys 17 and 18, `Drift(SpeakerState)`, cut `language-ontology-scene`) | Profile authors and accepted rounds; never the lowerer's defaults (`persona-drives-register`) |
|
||||
| Language ontology entry (cut `language-ontology`) | Key `onto:<language>:<n>`, `n` from 1 per language; type `weksa.ontology_entry` in `data/ontology/ontology.cc`: the language, the revision of the inventory it was admitted through (provenance: beds number revisions independently and a run reads each condition's feature at its own head), a layer (lexicon, grammar, discourse, phonology, orthography), at most four conditions (a feature id of slot `Stance`, `Discourse` or `Scene` with `AtLeast`/`AtMost` a grade or `Is` an option or flag; a `Scene` condition reads the relation of the item's speaker to its addressee that `with_scene` selected; slot `Speaker` and community ids wait on follow-up `language-ontology-communities`), a choice of 1 to 200 bytes, at most three examples of 1 to 120 bytes, and an `Annotator`. Whether an entry's text keeps politeness on the scene is a model reader's judgment, owed per change (a mint owes it under `language-ontology-growth`), not a test | Admitted in all-or-nothing batches through `OntologyStore::admit`, immutable, never edited; retire arrives with `language-ontology-growth`. The run pins the store like the entity store (path and digest, `Drift(Ontology)`), never copies it, because no loop step writes it yet. Cut `language-ontology-seed` converts by drafting, not by parse: a fresh model drafts each language's seed from that language's YAML and the inventory's feature lines with no corpus text, then deletes `data/target-language-ontology/` and `.weksa/cultural-ontology/` in the same cut | Seed: a labelled model (`Annotator::Model`), no operator gate, never Test evidence (`ja-ontology-owner-answer`); attestation (operator, native reader) appends later. Accepted rounds later, through a mint call from Train items only. Selection is `ontology::select(ontology, language, view)`, called only inside `Prompt::lower`, so no caller picks entries; the prompt prints each selected entry's id, layer, choice and examples. Its text is minted text for the leak diagnostic, which today has no runtime caller (follow-up `leak-diagnostic-in-round`) |
|
||||
|
|
@ -321,7 +321,7 @@ line two", "その 制御" against the
|
|||
`TestReadings::at_checkpoint` take minted text as `&[&str]` and have no
|
||||
caller outside tests: no round reads glosses or any minted text against
|
||||
Validation. `data/daodejing/inventory.cc` is a revision prefix of
|
||||
`data/original/inventory.cc` (revisions 1 to 4 equal, a test proves it; rev 5 adds the bed's own lexicon); with `data/interlingua/inventory.cc` they share revision 1,
|
||||
`data/original/inventory.cc` (revisions 1 to 4 equal, a test proves it; revs 5 and 6 add the bed's own lexicon); with `data/interlingua/inventory.cc` they share revision 1,
|
||||
where features 6 to 8 (hedge, certainty grades, irony flag) sit in
|
||||
`Discourse` and `Predication` and features 9 to 18 (anger to restraint,
|
||||
grades) in `Stance`. `PROMPT_SOURCE_DIGEST` covers `context.rs`, `split.rs`,
|
||||
|
|
|
|||
Loading…
Reference in a new issue