diff --git a/.corviduo-canonicals.toml b/.corviduo-canonicals.toml index 06db492..06ab4d6 100644 --- a/.corviduo-canonicals.toml +++ b/.corviduo-canonicals.toml @@ -192,8 +192,8 @@ id = "soong-lab-export-contract-v1" canonical_source = "soong-lab" canonical_path = "docs/contracts/export.contract.md" consumer_path = "docs/vendor/soong-lab-bundle/export.contract.md" -pinned_sha256_16 = "bbd8fcf0cc7bc535" -pinned_at = "2026-07-14T17:15:44+00:00" +pinned_sha256_16 = "2f5efa72dd469d47" +pinned_at = "2026-07-18T09:14:59+00:00" tolerate_drift = true # soong-lab-dev owns the bundle format + pings ratatoskr-dev on change [[pins]] @@ -201,6 +201,6 @@ id = "soong-lab-importer-contract-v1" canonical_source = "soong-lab" canonical_path = "docs/contracts/importer.contract.md" consumer_path = "docs/vendor/soong-lab-bundle/importer.contract.md" -pinned_sha256_16 = "777b1764c8eb2cb7" -pinned_at = "2026-07-14T17:15:44+00:00" +pinned_sha256_16 = "edbd306596f26a9e" +pinned_at = "2026-07-18T09:14:59+00:00" tolerate_drift = true # soong-lab-dev owns the bundle format + pings ratatoskr-dev on change diff --git a/docs/vendor/soong-lab-bundle/export.contract.md b/docs/vendor/soong-lab-bundle/export.contract.md index edab8b2..8fdadd1 100644 --- a/docs/vendor/soong-lab-bundle/export.contract.md +++ b/docs/vendor/soong-lab-bundle/export.contract.md @@ -16,7 +16,7 @@ assumptions: - "The DesignObject handed to export is already mutated to its final state by E3 (the Soong convo loop). Export READS it; it never mutates the design (INV-E5-4)." - "design_id is CALLER-SUPPLIED (a param), not generated here. Its generation + lifecycle (the durable library key, ≠ Worldtree session_id) is the per-design-sessions epic; export only needs the value to stamp the bundle. This keeps E5-export self-contained + forward-compatible with per-design-sessions landing before OR after it (agent-discretion, see open_question C)." - "exported_at is CALLER-SUPPLIED (a param, default None). Pure builders can't read the clock; the caller (tool handler / endpoint) stamps the timestamp so build_export_bundle stays deterministic + testable (byte-identical output for identical inputs)." - - "role is a FIRST-CLASS design field (operator ruling 2026-07-13), set by the E3a set_role tool from a CURATED 4-value enum ROLE_CHOICES = {assistant, thoughtful-assistant, character, thoughtful-character} — mirroring the D2 curated-style-modes pattern (a fixed semantic set, NOT the target deployment's arbitrary model-role registry). Export EMITS design.role into ship.native.role, so the native payload is directly valid (Frame Invariant 1 now holds literally — no 'modulo role' caveat; only tools still bind separately at session-create). The 4 enum values are canonical soong-lab labels that MUST be registered/granted model-roles on the target Worldtree at deploy (same grant requirement as Soong's own 'agent_architect' role, ADR-0012) — a deploy-time grounding item, not a contract blocker (open_question B)." + - "role is a FIRST-CLASS design field (operator ruling 2026-07-13), set by the E3a set_role tool from a CURATED 4-value enum ROLE_CHOICES = {assistant, thoughtful-assistant, character, thoughtful-character} — mirroring the D2 curated-style-modes pattern (a fixed semantic set, NOT the target deployment's arbitrary model-role registry). Export EMITS design.role into ship.native.role, so the native payload is directly valid (Frame Invariant 1 now holds literally — no 'modulo role' caveat; only tools still bind separately at session-create). The 4 enum values are canonical soong-lab labels that map to WT model-role slugs. open_question B RESOLVED (2026-07-14, worldtree-dev via ratatoskr-dev): the 4 labels ARE WT slugs by EXACT name (1:1, no remap) — assistant/thoughtful-assistant under the `foundational` grant (gen / gen-reasoning seats), character/thoughtful-character under the `character` grant (char-rp / char-rp-reasoning seats). So ship.native.role is directly define-valid; the only deploy concern is that the CONSUMER's key must hold the matching grant (define 403s otherwise — same model.use requirement as Soong's own 'agent_architect', ADR-0012). Not a contract blocker." - "psych_profile exports to the NATIVE persona layer at persona.psychological_profile. RESOLVED: the vendored canonical spec (docs/psych-profile-authoring-spec.md §4) states the wire shape is LOCKED (b53) — a single prose str field, Tier-3 ValidatedPersona.psychological_profile, nesting under the existing Any-typed persona field (no schema change). Corroborated by worldtree-codex (vor-cross) + brokkr-smithy-dev (althing 01KXD34ZTF…). The open worldtree-dev thread (01KXD1PZR7…) closes as a formality." open_questions: - "[B — deploy grounding, not a blocker] The 4 ROLE_CHOICES values (assistant / thoughtful-assistant / character / thoughtful-character) must be registered + grantable model-role slugs on the TARGET Worldtree (like Soong's own agent_architect role). Confirm with worldtree-dev/infra that these exact slugs exist on the deploy target before shipping; a missing slug fails the designed agent's session-create, not export. Export emits whatever role the design holds; validity of the slug on a given deployment is a deploy concern." @@ -103,7 +103,10 @@ not this module.) "ocean": {O,C,E,A,N}, # each a real number in [-1,1] (validate_ocean parity) "psychological_profile": # persona.psychological_profile (LOCKED b53); included iff non-blank }, - "motivational": {"goals": [...], "fears": [...]} # included iff goals_fears present + non-empty + "motivational": { # WT #187 OBJECTS, not strings (ratatoskr-dev bug 2026-07-16); iff goals_fears present + non-empty + "goals": [{"id": "goal-N", "type": , "salience": <0..1>, "description": =20 chars>}], + "fears": [{"id": "fear-N", "salience": <0..1>, "description": =20 chars>}] + } # `id` synthesized at export (goal-N/fear-N, unique across both); validate_exportable gates description>=20 / type∈GOAL_TYPES / salience∈[0,1] }, "sidecar": { "portrait": , # only when portrait.status == "ready"; E4 owns generation diff --git a/docs/vendor/soong-lab-bundle/importer.contract.md b/docs/vendor/soong-lab-bundle/importer.contract.md index 52d7ac5..2cfbf56 100644 --- a/docs/vendor/soong-lab-bundle/importer.contract.md +++ b/docs/vendor/soong-lab-bundle/importer.contract.md @@ -128,7 +128,12 @@ Gróa#1/#2: a malformed portrait/goalsFears would otherwise coerce to a default non-export-critical — the same loss the `tools` gate was added to close). Import does NOT validate their VALUE contents — portrait `status`/`styleMode` enums or goals/fears item contents are not export-critical (E4 / the UI own portrait validity); those -round-trip as-is (heid-review Gróa#6). +round-trip as-is (heid-review Gróa#6). A goalsFears item is COERCED into a Goal/Fear by +`_coerce_goal`/`_coerce_fear` (totality, INV-I-6): a dict → its {description, type?, +salience?} fields (missing/mistyped → the model default), a LEGACY bare string (a +pre-2026-07-16 design, when goals were strings) → its `description`, anything else → a +blank Goal/Fear (which `validate_exportable`'s ≥20-char/type/salience gate then rejects on +the strict re-validate — no silent loss). ## Invariants