Make strategic target projection deterministic
This commit is contained in:
parent
67421ada42
commit
b81a9779f1
6 changed files with 134 additions and 210 deletions
|
|
@ -241,10 +241,6 @@ struct CellAppraisalProposal {
|
|||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||
#[serde(tag = "kind", rename_all = "snake_case", deny_unknown_fields)]
|
||||
enum CellInterpreterAgentCommand {
|
||||
InspectActivityTargets {
|
||||
subject_id: String,
|
||||
query: String,
|
||||
},
|
||||
Submit {
|
||||
decisions: BTreeMap<String, serde_json::Value>,
|
||||
},
|
||||
|
|
@ -269,12 +265,6 @@ enum CellInterpreterAgentOutput {
|
|||
#[derive(Clone, Debug, Serialize)]
|
||||
#[serde(tag = "kind", rename_all = "snake_case")]
|
||||
enum CellInterpreterFinding {
|
||||
ActivityTargets {
|
||||
subject_id: String,
|
||||
query: String,
|
||||
matches: BTreeMap<String, CellActivityTargetSlice>,
|
||||
total_matches: usize,
|
||||
},
|
||||
DraftProgress {
|
||||
decision_subject_ids: Vec<String>,
|
||||
missing_subject_ids: Vec<String>,
|
||||
|
|
@ -862,7 +852,7 @@ fn append_actor_correction(
|
|||
}
|
||||
|
||||
const INITIAL_ACTIVITY_TARGET_LIMIT: usize = 24;
|
||||
const ACTIVITY_TARGET_QUERY_LIMIT: usize = 12;
|
||||
const NARRATIVE_ACTIVITY_TARGET_LIMIT: usize = 24;
|
||||
|
||||
fn initial_activity_targets(
|
||||
targets: &BTreeMap<String, CellActivityTargetSlice>,
|
||||
|
|
@ -933,7 +923,29 @@ fn initial_member_activity_targets(
|
|||
)
|
||||
}
|
||||
|
||||
fn bounded_interpreter_slice(slice: &PermittedCellSlice) -> PermittedCellSlice {
|
||||
fn narrative_activity_targets(
|
||||
targets: &BTreeMap<String, CellActivityTargetSlice>,
|
||||
narrative: &str,
|
||||
) -> BTreeMap<String, CellActivityTargetSlice> {
|
||||
let narrative = narrative.to_lowercase();
|
||||
targets
|
||||
.iter()
|
||||
.filter(|(_, target)| {
|
||||
let name = target.name.trim().to_lowercase();
|
||||
name.chars().count() >= 3
|
||||
&& narrative.match_indices(&name).any(|(start, matched)| {
|
||||
let before = narrative[..start].chars().next_back();
|
||||
let after = narrative[start + matched.len()..].chars().next();
|
||||
!before.is_some_and(char::is_alphanumeric)
|
||||
&& !after.is_some_and(char::is_alphanumeric)
|
||||
})
|
||||
})
|
||||
.take(NARRATIVE_ACTIVITY_TARGET_LIMIT)
|
||||
.map(|(target_id, target)| (target_id.clone(), target.clone()))
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn bounded_interpreter_slice(slice: &PermittedCellSlice, narrative: &str) -> PermittedCellSlice {
|
||||
let mut bounded = slice.clone();
|
||||
let decision_owner_ids = bounded.decision_owner_ids.clone();
|
||||
bounded
|
||||
|
|
@ -943,10 +955,20 @@ fn bounded_interpreter_slice(slice: &PermittedCellSlice) -> PermittedCellSlice {
|
|||
.member_exceptions
|
||||
.retain(|member| decision_owner_ids.contains(&member.subject_id));
|
||||
for subject in &mut bounded.constituents {
|
||||
subject.activity_targets = initial_constituent_activity_targets(subject);
|
||||
let mut targets = initial_constituent_activity_targets(subject);
|
||||
targets.extend(narrative_activity_targets(
|
||||
&subject.activity_targets,
|
||||
narrative,
|
||||
));
|
||||
subject.activity_targets = targets;
|
||||
}
|
||||
for member in &mut bounded.member_exceptions {
|
||||
member.activity_targets = initial_member_activity_targets(member);
|
||||
let mut targets = initial_member_activity_targets(member);
|
||||
targets.extend(narrative_activity_targets(
|
||||
&member.activity_targets,
|
||||
narrative,
|
||||
));
|
||||
member.activity_targets = targets;
|
||||
}
|
||||
bounded
|
||||
}
|
||||
|
|
@ -1445,54 +1467,13 @@ struct CellInterpreterWorkbench {
|
|||
lived_stream: String,
|
||||
persona_turn: String,
|
||||
campaign_policy: String,
|
||||
visible_slice: PermittedCellSlice,
|
||||
appraisal_schema: serde_json::Value,
|
||||
draft: BTreeMap<String, serde_json::Value>,
|
||||
repair_subject_ids: BTreeSet<String>,
|
||||
accepted_verifier_bindings: BTreeSet<String>,
|
||||
}
|
||||
|
||||
impl CellInterpreterWorkbench {
|
||||
fn inspect_activity_targets(
|
||||
&mut self,
|
||||
subject_id: &str,
|
||||
query: &str,
|
||||
) -> Result<CellInterpreterFinding> {
|
||||
if !self.active_subject_ids.contains(subject_id) {
|
||||
return Err(anyhow!(
|
||||
"activity-target inspection subject {subject_id} is not an active decision owner"
|
||||
));
|
||||
}
|
||||
let query = query.trim();
|
||||
if query.is_empty() || query.chars().count() > 160 {
|
||||
return Err(anyhow!(
|
||||
"activity-target inspection query must contain 1 to 160 characters"
|
||||
));
|
||||
}
|
||||
let full_targets = activity_targets_for_subject(&self.slice, subject_id)?;
|
||||
let needle = query.to_lowercase();
|
||||
let matching = full_targets
|
||||
.iter()
|
||||
.filter(|(target_id, target)| {
|
||||
target_id.to_lowercase().contains(&needle)
|
||||
|| target.name.to_lowercase().contains(&needle)
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
let total_matches = matching.len();
|
||||
let matches = matching
|
||||
.into_iter()
|
||||
.take(ACTIVITY_TARGET_QUERY_LIMIT)
|
||||
.map(|(target_id, target)| (target_id.clone(), target.clone()))
|
||||
.collect::<BTreeMap<_, _>>();
|
||||
activity_targets_for_subject_mut(&mut self.visible_slice, subject_id)?
|
||||
.extend(matches.clone());
|
||||
Ok(CellInterpreterFinding::ActivityTargets {
|
||||
subject_id: subject_id.to_owned(),
|
||||
query: query.to_owned(),
|
||||
matches,
|
||||
total_matches,
|
||||
})
|
||||
}
|
||||
|
||||
fn progress(&self) -> CellInterpreterFinding {
|
||||
let decision_subject_ids = self.draft.keys().cloned().collect::<Vec<_>>();
|
||||
let decided = decision_subject_ids
|
||||
|
|
@ -1702,15 +1683,7 @@ impl ModelAgentTool for CellInterpreterWorkbench {
|
|||
} else {
|
||||
CellInterpreterSchemaState::Repair(&self.repair_subject_ids)
|
||||
};
|
||||
let mut appraisal_schema = serde_json::to_value(schema_for!(CellAppraisalProposal))
|
||||
.map_err(|error| error.to_string())?;
|
||||
constrain_cell_proposal_schema(
|
||||
&mut appraisal_schema,
|
||||
&self.visible_slice,
|
||||
&self.active_subject_ids,
|
||||
)
|
||||
.map_err(|error| error.to_string())?;
|
||||
cell_interpreter_agent_schema(&appraisal_schema, state, &self.active_subject_ids)
|
||||
cell_interpreter_agent_schema(&self.appraisal_schema, state)
|
||||
.map_err(|error| error.to_string())
|
||||
}
|
||||
|
||||
|
|
@ -1720,21 +1693,6 @@ impl ModelAgentTool for CellInterpreterWorkbench {
|
|||
context: &ModelAgentToolContext,
|
||||
) -> ModelAgentToolOutcome<Self::Output, Self::Finding> {
|
||||
match action.command {
|
||||
CellInterpreterAgentCommand::InspectActivityTargets { subject_id, query } => {
|
||||
match self.inspect_activity_targets(&subject_id, &query) {
|
||||
Ok(observation) => ModelAgentToolOutcome::Continue {
|
||||
observation,
|
||||
receipts: Vec::new(),
|
||||
},
|
||||
Err(error) => ModelAgentToolOutcome::Rejected {
|
||||
finding: CellInterpreterFinding::LocalValidation {
|
||||
diagnostic: error.to_string(),
|
||||
decision_subject_ids: self.repair_subject_ids.iter().cloned().collect(),
|
||||
},
|
||||
receipts: Vec::new(),
|
||||
},
|
||||
}
|
||||
}
|
||||
CellInterpreterAgentCommand::Submit { decisions } => {
|
||||
if !self.draft.is_empty() {
|
||||
return ModelAgentToolOutcome::Rejected {
|
||||
|
|
@ -1783,48 +1741,6 @@ fn required_projection_subject_ids(slice: &PermittedCellSlice) -> BTreeSet<Strin
|
|||
slice.decision_owner_ids.clone()
|
||||
}
|
||||
|
||||
fn activity_targets_for_subject<'a>(
|
||||
slice: &'a PermittedCellSlice,
|
||||
subject_id: &str,
|
||||
) -> Result<&'a BTreeMap<String, CellActivityTargetSlice>> {
|
||||
if let Some(subject) = slice
|
||||
.constituents
|
||||
.iter()
|
||||
.find(|subject| subject.subject_id == subject_id)
|
||||
{
|
||||
return Ok(&subject.activity_targets);
|
||||
}
|
||||
slice
|
||||
.member_exceptions
|
||||
.iter()
|
||||
.find(|member| member.subject_id == subject_id)
|
||||
.map(|member| &member.activity_targets)
|
||||
.ok_or_else(|| anyhow!("cell has no activity-target permissions for {subject_id}"))
|
||||
}
|
||||
|
||||
fn activity_targets_for_subject_mut<'a>(
|
||||
slice: &'a mut PermittedCellSlice,
|
||||
subject_id: &str,
|
||||
) -> Result<&'a mut BTreeMap<String, CellActivityTargetSlice>> {
|
||||
if let Some(index) = slice
|
||||
.constituents
|
||||
.iter()
|
||||
.position(|subject| subject.subject_id == subject_id)
|
||||
{
|
||||
return Ok(&mut slice.constituents[index].activity_targets);
|
||||
}
|
||||
if let Some(index) = slice
|
||||
.member_exceptions
|
||||
.iter()
|
||||
.position(|member| member.subject_id == subject_id)
|
||||
{
|
||||
return Ok(&mut slice.member_exceptions[index].activity_targets);
|
||||
}
|
||||
Err(anyhow!(
|
||||
"cell has no mutable activity-target viewport for {subject_id}"
|
||||
))
|
||||
}
|
||||
|
||||
fn allowed_constituent_effect_types(subject: &CellConstituentSlice) -> Vec<&'static str> {
|
||||
match subject.subject_kind {
|
||||
crate::domain::AgencySubjectKind::Actor => {
|
||||
|
|
@ -2085,7 +2001,12 @@ impl CellProjectionEngine {
|
|||
.require(&slice.cell_id, &slice.snapshot_binding, "cell_interpreter")
|
||||
.await
|
||||
.map_err(|error| cell_pipeline_failure(error, stage_receipts.clone()))?;
|
||||
let visible_slice = bounded_interpreter_slice(&slice);
|
||||
let interpreter_narrative = format!("{}\n{}", lived.text, persona.narrative);
|
||||
let visible_slice = bounded_interpreter_slice(&slice, &interpreter_narrative);
|
||||
let mut appraisal_schema = serde_json::to_value(schema_for!(CellAppraisalProposal))
|
||||
.map_err(|error| cell_pipeline_failure(error.into(), stage_receipts.clone()))?;
|
||||
constrain_cell_proposal_schema(&mut appraisal_schema, &visible_slice, &active_subject_ids)
|
||||
.map_err(|error| cell_pipeline_failure(error, stage_receipts.clone()))?;
|
||||
let interpreter_context = serde_json::to_string(&cell_interpreter_context(
|
||||
&visible_slice,
|
||||
&active_subject_ids,
|
||||
|
|
@ -2097,7 +2018,7 @@ impl CellProjectionEngine {
|
|||
"Every subject in exact_permissions owns one schema-keyed decision slot. Fill that exact slot with one action or one inaction. Use undecided only when the Persona turn supplied no explicit choice or hold; runtime will retry the Persona rather than let the Interpreter invent one. Do not let a voiced constituent vanish during interpretation. ",
|
||||
"Each action carries an effects object whose exact subject-specific lane keys are supplied by the schema. Across scalar effects and every expanded activity scope, an action has one to four exact effects total. Scalar lanes contain one typed effect. An activities lane is one object keyed by chosen activity kinds; each non-null kind contains an array of one to four separate exact target-and-location scopes. Preserve repeated uses of one activity kind as separate scopes when their targets or locations differ; never union scopes across distinct locations or audiences. Top-level lane names are stable across subjects: use null for a null-only unavailable lane and for any schema-required optional lane or activity key the subject does not use. A non-null lane or activity key absent from its exact schema is structurally unavailable: do not emit it and do not invent a destination. Pressure and migration lanes each have one slot. Preserve every means of one chosen course in one action. With relocation, activities at the exact snapshot location occur before departure and activities at the exact admitted destination occur after arrival; activity effects inside each location phase are an atomic set. Field and array order is not chronology. Never split one subject's single choice into multiple actions. ",
|
||||
"Use gestalt_activities or member_activities for concrete attempts that do not themselves change pressure. A cohesive Gestalt coordinating its own unnamed internal members uses coordinate with an empty target_subject_ids list; do not invent its containing population, a distant population, or another canonical subject as the target of internal coordination. Cite the smallest exact set of state_references that materially supports each attempt; the permission list is an upper bound, not a checklist to echo. ",
|
||||
"target_subject_ids and location_ids must come from that exact subject's permissions. activity_targets is a bounded exact viewport: each key is an authoritative ID and each value supplies the target's name and current canonical locations. When the Persona addresses a canonical subject absent from that viewport, call inspect_activity_targets for that decision owner and a distinctive fragment of the target's supplied name before drafting or repairing the decision. Inspection exposes existing permission; it cannot create it. Use an ID only when the Persona addresses that named target, never merely because the ID is permitted. If inspection returns no matching target, the addressed person or role is not a canonical target in this slice. reachable_destinations maps exact actor-movement destination IDs to names. migration_destinations maps exact population destination IDs to names and locations. When the Persona chooses to go to a canonical target, compare the target's current locations with the acting subject's current location and exact reachable destinations; never guess a destination from an opaque ID. Every activity has at most four unique target_subject_ids; choose the four most causally relevant when more permitted subjects are involved. A member activity uses exactly the member's source_location_id. Internal work is prepare with no targets. A local investigate may have no target and use the exact current location to seek information from the environment or an unnamed ordinary role; asking an unnamed clerk or dock master for facts maps here and records only the inquiry, never a reply or discovery. A local communicate may likewise have no target at the exact current location when the Persona speaks, sends, offers, asks permission, or notifies an unnamed ordinary role; it records only the source's outgoing attempt, never a listener, reply, acceptance, or outcome. Communication with a canonical subject requires that exact target ID. When one utterance addresses canonical subjects and an unnamed public audience, emit one communicate activity with those exact target IDs and place its admitted public reach in public_channels; do not invent a second communicate lane. Never substitute a containing population, related institution, or merely permitted ID for an unnamed role. ",
|
||||
"target_subject_ids and location_ids must come from that exact subject's permissions. activity_targets is the bounded exact set deterministically selected from current relevance plus canonical targets named exactly in the lived stream or Persona turn: each key is an authoritative ID and each value supplies the target's name and current canonical locations. Use an ID only when the Persona addresses that named target, never merely because the ID is permitted. If an addressed name has no supplied canonical target, treat it as an unnamed role and use a targetless local activity when that lane is supported. reachable_destinations maps exact actor-movement destination IDs to names. migration_destinations maps exact population destination IDs to names and locations. When the Persona chooses to go to a canonical target, compare the target's current locations with the acting subject's current location and exact reachable destinations; never guess a destination from an opaque ID. Every activity has at most four unique target_subject_ids; choose the four most causally relevant when more permitted subjects are involved. A member activity uses exactly the member's source_location_id. Internal work is prepare with no targets. A local investigate may have no target and use the exact current location to seek information from the environment or an unnamed ordinary role; asking an unnamed clerk or dock master for facts maps here and records only the inquiry, never a reply or discovery. A local communicate may likewise have no target at the exact current location when the Persona speaks, sends, offers, asks permission, or notifies an unnamed ordinary role; it records only the source's outgoing attempt, never a listener, reply, acceptance, or outcome. Communication with a canonical subject requires that exact target ID. When one utterance addresses canonical subjects and an unnamed public audience, emit one communicate activity with those exact target IDs and place its admitted public reach in public_channels; do not invent a second communicate lane. Never substitute a containing population, related institution, or merely permitted ID for an unnamed role. ",
|
||||
"Write intended_effect as the affirmative attempted acts, never the purpose, restraint, condition to preserve, hoped-for outcome, or target response. Keep purpose and restraint in intent. Respecting choice, declining coercion, leaving state unchanged, or waiting for another subject does not add a typed effect unless the Persona separately chooses an observable act. Merely waiting, watching, staying, holding position, or remaining ready is attributed inaction, not prepare. prepare requires concrete work on a bounded arrangement, repair, resource, or capability-backed readiness change. Institution posture must be a specific materially new commitment or withholding of at most {} characters. already_committed_posture is state already in force: maintaining, continuing, or restating it is inaction and must not emit an institution action. Gestalt pressure_resolutions copy exact current_pressures; additions are new unresolved constraints, never completed actions. Use only permitted state references. public_channels means durable publication of this attempt through exact allowed_persistent_publication_channels; it is not a perception method or ordinary local speech. Use [] when that exact list is empty. ",
|
||||
"A population that chooses to board, depart, or relocate together to one supplied migration_destinations key emits gestalt_migration; do not reduce it to prepare. It relocates only that exact population leaf and never implies a named member traveled. A named member who chooses to board, depart, travel, or join a supplied destination emits member_migration; use prepare only while departure remains unchosen. ",
|
||||
"A population or arena cannot migrate a person. Runtime binds identity and effect owner IDs from subject_id. Do not emit institution_id, gestalt_id, actor_id, or member_id inside effect. An inaction means that exact subject takes no strategic action in this horizon. Record only a subject that explicitly holds, waits without making another attempt, or merely continues already_committed_posture in the Persona turn as an inaction, using its exact subject_id and a concrete reason of at most 160 characters. Waiting for the result of an action, withholding a different possible action, or declining one option after choosing another does not make the chosen action an inaction. Never invent an inaction for an unvoiced subject or use absence of a Persona decision as a reason. Inactions share the same count limit stated for actions. A subject cannot appear in both actions and inactions. When nobody acts, actions is empty and inactions must still contain at least one exact attributed decision from the Persona turn."
|
||||
|
|
@ -2123,7 +2044,7 @@ impl CellProjectionEngine {
|
|||
persona_output: &persona.narrative,
|
||||
output_schema: None,
|
||||
domain_guidance: &format!(
|
||||
"{permission_guidance} Operate the private Interpreter workbench. Its current typed action schema is authoritative and exposes only the transition legal now: inspect_activity_targets may expand one decision owner's bounded target viewport, one complete submit creates the draft, and exact named upsert_decision repairs follow rejection. A rejected submit preserves its draft. Only the deterministic workbench can accept the appraisal."
|
||||
"{permission_guidance} Operate the private Interpreter workbench. Its current typed action schema is authoritative and exposes only the transition legal now: one complete submit creates the draft, and exact named upsert_decision repairs follow rejection. A rejected submit preserves its draft. Only the deterministic workbench can accept the appraisal."
|
||||
),
|
||||
});
|
||||
let mut interpreter_causal_receipts = causal_receipts;
|
||||
|
|
@ -2138,7 +2059,7 @@ impl CellProjectionEngine {
|
|||
source_receipt_ids,
|
||||
temperature: Some(0.0),
|
||||
max_output_tokens: Some(1_600),
|
||||
max_steps: active_subject_ids.len().saturating_add(6).clamp(6, 10),
|
||||
max_steps: active_subject_ids.len().saturating_add(4).clamp(4, 8),
|
||||
};
|
||||
let mut workbench = CellInterpreterWorkbench {
|
||||
model: self.model.clone(),
|
||||
|
|
@ -2149,7 +2070,7 @@ impl CellProjectionEngine {
|
|||
lived_stream: lived.text.clone(),
|
||||
persona_turn: persona.narrative.clone(),
|
||||
campaign_policy: campaign_policy.clone(),
|
||||
visible_slice,
|
||||
appraisal_schema,
|
||||
draft: BTreeMap::new(),
|
||||
repair_subject_ids: BTreeSet::new(),
|
||||
accepted_verifier_bindings: BTreeSet::new(),
|
||||
|
|
@ -3336,7 +3257,6 @@ enum CellInterpreterSchemaState<'a> {
|
|||
fn cell_interpreter_agent_schema(
|
||||
appraisal_schema: &serde_json::Value,
|
||||
state: CellInterpreterSchemaState<'_>,
|
||||
active_subject_ids: &BTreeSet<String>,
|
||||
) -> Result<serde_json::Value> {
|
||||
let decisions_schema = appraisal_schema
|
||||
.pointer("/properties/decisions")
|
||||
|
|
@ -3346,7 +3266,7 @@ fn cell_interpreter_agent_schema(
|
|||
.get("properties")
|
||||
.and_then(serde_json::Value::as_object)
|
||||
.ok_or_else(|| anyhow!("cell appraisal schema has no exact decision owners"))?;
|
||||
let mut commands = match state {
|
||||
let commands = match state {
|
||||
CellInterpreterSchemaState::Initial => vec![serde_json::json!({
|
||||
"type":"object",
|
||||
"additionalProperties":false,
|
||||
|
|
@ -3380,16 +3300,6 @@ fn cell_interpreter_agent_schema(
|
|||
.collect::<Result<Vec<_>>>()?
|
||||
}
|
||||
};
|
||||
commands.push(serde_json::json!({
|
||||
"type":"object",
|
||||
"additionalProperties":false,
|
||||
"required":["kind","subject_id","query"],
|
||||
"properties":{
|
||||
"kind":{"const":"inspect_activity_targets"},
|
||||
"subject_id":{"type":"string","enum":active_subject_ids},
|
||||
"query":{"type":"string","minLength":1,"maxLength":160}
|
||||
}
|
||||
}));
|
||||
Ok(serde_json::json!({
|
||||
"$schema":"https://json-schema.org/draft/2020-12/schema",
|
||||
"type":"object",
|
||||
|
|
@ -4438,6 +4348,17 @@ mod tests {
|
|||
}})
|
||||
}
|
||||
|
||||
fn test_appraisal_schema(
|
||||
slice: &PermittedCellSlice,
|
||||
active_subject_ids: &BTreeSet<String>,
|
||||
narrative: &str,
|
||||
) -> serde_json::Value {
|
||||
let visible_slice = bounded_interpreter_slice(slice, narrative);
|
||||
let mut schema = serde_json::to_value(schema_for!(CellAppraisalProposal)).unwrap();
|
||||
constrain_cell_proposal_schema(&mut schema, &visible_slice, active_subject_ids).unwrap();
|
||||
schema
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn interpreter_workbench_reuses_unchanged_valid_effect_verification() {
|
||||
let mut slice = fixture_cell_slice();
|
||||
|
|
@ -4454,7 +4375,11 @@ mod tests {
|
|||
calls: AtomicUsize::new(0),
|
||||
faction_seven_calls: AtomicUsize::new(0),
|
||||
});
|
||||
let visible_slice = bounded_interpreter_slice(&slice);
|
||||
let appraisal_schema = test_appraisal_schema(
|
||||
&slice,
|
||||
&active_subject_ids,
|
||||
"Faction Six withholds; Faction Seven publishes.",
|
||||
);
|
||||
let mut workbench = CellInterpreterWorkbench {
|
||||
model: model.clone(),
|
||||
permit: Arc::new(AllowAllPermit),
|
||||
|
|
@ -4464,7 +4389,7 @@ mod tests {
|
|||
lived_stream: "At location forum: Faction Six and Faction Seven.".into(),
|
||||
persona_turn: "Faction Six withholds; Faction Seven publishes.".into(),
|
||||
campaign_policy: "{}".into(),
|
||||
visible_slice,
|
||||
appraisal_schema,
|
||||
draft: BTreeMap::new(),
|
||||
repair_subject_ids: BTreeSet::new(),
|
||||
accepted_verifier_bindings: BTreeSet::new(),
|
||||
|
|
@ -4520,7 +4445,7 @@ mod tests {
|
|||
assert!(!repair_schema_text.contains("submit"));
|
||||
assert!(repair_schema_text.contains("upsert_decision"));
|
||||
assert!(repair_schema_text.contains("faction-06"));
|
||||
assert!(repair_schema_text.contains("inspect_activity_targets"));
|
||||
assert!(!repair_schema_text.contains("inspect_activity_targets"));
|
||||
assert!(
|
||||
!jsonschema::validator_for(&repair_schema)
|
||||
.unwrap()
|
||||
|
|
@ -4622,7 +4547,11 @@ mod tests {
|
|||
slice.decision_owner_ids.insert("faction-07".into());
|
||||
slice.max_actions = 2;
|
||||
let active_subject_ids = slice.decision_owner_ids.clone();
|
||||
let visible_slice = bounded_interpreter_slice(&slice);
|
||||
let appraisal_schema = test_appraisal_schema(
|
||||
&slice,
|
||||
&active_subject_ids,
|
||||
"Both factions hold for the count.",
|
||||
);
|
||||
let mut workbench = CellInterpreterWorkbench {
|
||||
model: Arc::new(CachingVerifierModel {
|
||||
calls: AtomicUsize::new(0),
|
||||
|
|
@ -4635,7 +4564,7 @@ mod tests {
|
|||
lived_stream: "At location forum: Faction Six and Faction Seven.".into(),
|
||||
persona_turn: "Both factions hold for the count.".into(),
|
||||
campaign_policy: "{}".into(),
|
||||
visible_slice,
|
||||
appraisal_schema,
|
||||
draft: BTreeMap::from([
|
||||
(
|
||||
"faction-06".into(),
|
||||
|
|
@ -4792,13 +4721,8 @@ mod tests {
|
|||
assert!(schema.pointer("/properties/decisions").is_some());
|
||||
assert!(schema.pointer("/properties/actions").is_none());
|
||||
assert!(schema.pointer("/properties/inactions").is_none());
|
||||
let active_subject_ids = BTreeSet::from(["faction-06".to_owned()]);
|
||||
let initial_schema = cell_interpreter_agent_schema(
|
||||
&schema,
|
||||
CellInterpreterSchemaState::Initial,
|
||||
&active_subject_ids,
|
||||
)
|
||||
.unwrap();
|
||||
let initial_schema =
|
||||
cell_interpreter_agent_schema(&schema, CellInterpreterSchemaState::Initial).unwrap();
|
||||
let initial_schema_text = serde_json::to_string(&initial_schema).unwrap();
|
||||
assert_eq!(initial_schema["type"], "object");
|
||||
assert!(initial_schema.get("oneOf").is_none());
|
||||
|
|
@ -4809,7 +4733,7 @@ mod tests {
|
|||
);
|
||||
assert!(initial_schema_text.contains("submit"));
|
||||
assert!(!initial_schema_text.contains("upsert_decision"));
|
||||
assert!(initial_schema_text.contains("inspect_activity_targets"));
|
||||
assert!(!initial_schema_text.contains("inspect_activity_targets"));
|
||||
assert!(!initial_schema_text.contains("inspect_draft"));
|
||||
assert!(!initial_schema_text.contains("remove_decision"));
|
||||
assert!(initial_schema_text.contains("\"maxLength\":240"));
|
||||
|
|
@ -4870,7 +4794,6 @@ mod tests {
|
|||
let repair_schema = cell_interpreter_agent_schema(
|
||||
&schema,
|
||||
CellInterpreterSchemaState::Repair(&repair_subject_ids),
|
||||
&active_subject_ids,
|
||||
)
|
||||
.unwrap();
|
||||
let repair_schema_text = serde_json::to_string(&repair_schema).unwrap();
|
||||
|
|
@ -4975,50 +4898,38 @@ mod tests {
|
|||
}
|
||||
|
||||
#[test]
|
||||
fn interpreter_inspection_expands_context_without_expanding_authority() {
|
||||
fn interpreter_projects_exact_narrative_targets_without_expanding_authority() {
|
||||
let mut slice = fixture_cell_slice();
|
||||
add_many_activity_targets(&mut slice, 1_000);
|
||||
let visible_slice = bounded_interpreter_slice(&slice);
|
||||
let active_subject_ids = slice.decision_owner_ids.clone();
|
||||
let model = Arc::new(CachingVerifierModel {
|
||||
calls: AtomicUsize::new(0),
|
||||
faction_seven_calls: AtomicUsize::new(0),
|
||||
});
|
||||
let mut workbench = CellInterpreterWorkbench {
|
||||
model,
|
||||
permit: Arc::new(AllowAllPermit),
|
||||
interpreter_model: "flash".into(),
|
||||
slice,
|
||||
active_subject_ids,
|
||||
lived_stream: "Faction Six addresses Target 0999.".into(),
|
||||
persona_turn: "Tell Target 0999 to attend.".into(),
|
||||
campaign_policy: "{}".into(),
|
||||
visible_slice,
|
||||
draft: BTreeMap::new(),
|
||||
repair_subject_ids: BTreeSet::new(),
|
||||
accepted_verifier_bindings: BTreeSet::new(),
|
||||
};
|
||||
|
||||
let initial_schema = serde_json::to_string(&workbench.action_schema().unwrap()).unwrap();
|
||||
let initial_schema = test_appraisal_schema(&slice, &active_subject_ids, "ordinary work");
|
||||
let initial_schema = serde_json::to_string(&initial_schema).unwrap();
|
||||
assert!(!initial_schema.contains("target:0999"));
|
||||
let finding = workbench
|
||||
.inspect_activity_targets("faction-06", "Target 0999")
|
||||
.unwrap();
|
||||
assert!(matches!(
|
||||
finding,
|
||||
CellInterpreterFinding::ActivityTargets {
|
||||
total_matches: 1,
|
||||
..
|
||||
}
|
||||
));
|
||||
let expanded_schema = serde_json::to_string(&workbench.action_schema().unwrap()).unwrap();
|
||||
assert!(expanded_schema.contains("target:0999"));
|
||||
let false_prefix = bounded_interpreter_slice(&slice, "Target 09990 remains absent.");
|
||||
assert!(
|
||||
!false_prefix.constituents[0]
|
||||
.activity_targets
|
||||
.contains_key("target:0999")
|
||||
);
|
||||
let visible_slice = bounded_interpreter_slice(
|
||||
&slice,
|
||||
"Faction Six addresses Target 0999. Tell Target 0999 to attend.",
|
||||
);
|
||||
let projected_targets = &visible_slice.constituents[0].activity_targets;
|
||||
assert!(projected_targets.contains_key("target:0999"));
|
||||
assert!(projected_targets.len() <= INITIAL_ACTIVITY_TARGET_LIMIT + 1);
|
||||
let projected_schema = test_appraisal_schema(
|
||||
&slice,
|
||||
&active_subject_ids,
|
||||
"Faction Six addresses Target 0999. Tell Target 0999 to attend.",
|
||||
);
|
||||
let projected_schema = serde_json::to_string(&projected_schema).unwrap();
|
||||
assert!(projected_schema.contains("target:0999"));
|
||||
assert!(projected_schema.len() < 64_000);
|
||||
assert_eq!(
|
||||
activity_targets_for_subject(&workbench.slice, "faction-06")
|
||||
.unwrap()
|
||||
.len(),
|
||||
slice.constituents[0].activity_targets.len(),
|
||||
1_000,
|
||||
"inspection must not truncate or rewrite canonical permission"
|
||||
"narrative projection must not truncate or rewrite canonical permission"
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -75,21 +75,31 @@ smallest failed Interpreter cells contain only two subjects, so repartitioning
|
|||
alone cannot fix the defect. No fictional wave committed and time did not
|
||||
advance.
|
||||
|
||||
The active cut makes context a bounded query projection. Projector receives
|
||||
only exact decision-owner dossiers and at most 24 deterministically relevant
|
||||
activity targets. The existing Interpreter agent workbench starts from the
|
||||
same bounded target viewport and may inspect up to 12 exact name/ID matches;
|
||||
its dynamic schema expands only with inspected targets. Full cell membership
|
||||
and full permissions remain private deterministic state. Effect verification
|
||||
receives only targets cited by the candidate action. Resolution remains cover
|
||||
owner and WorldKernel remains commit owner. Do not raise the connector bound,
|
||||
truncate canonical authority, or split cells merely to paper over projection.
|
||||
Pushed source `67421ad` bounded Projector and Interpreter frames. Immutable Run
|
||||
110 cloned Run 109's exact checkpoint and retried only its 14 failed cells. It
|
||||
proved the frame cut: no connector-frame failure recurred, and one additional
|
||||
cell completed. The durable pulse-two checkpoint contains 227 completed and 13
|
||||
failed cells with SHA-256
|
||||
`88a4f193e9f4d136841ede8d9c6b23e88788002a5f2e6b0c93bea9bb51b388de`.
|
||||
The remaining 13 Interpreters exhausted their agent steps by repeatedly asking
|
||||
the target-inspection command to resolve ordinary noun phrases. Root stopped
|
||||
the transient unit before more calls; no fictional wave committed and time did
|
||||
not advance.
|
||||
|
||||
After focused gates, commit and push, then clone Run 109 and resume only the 14
|
||||
failed cells from its exact checkpoint. Do not replay complexity, clock binding,
|
||||
Nemesis, or the 226 completed cell membranes. The acceptance launcher retains
|
||||
one content-addressed runner per exact source commit and deletes disposable
|
||||
remote compiler output.
|
||||
The current correction removes target lookup from the Interpreter. Projector
|
||||
receives only exact decision-owner dossiers and at most 24 deterministically
|
||||
relevant activity targets. Before Interpreter inference, one deterministic
|
||||
projection adds bounded canonical targets whose exact supplied names occur in
|
||||
the lived stream or Persona turn. Unmatched roles remain targetless local
|
||||
actions when supported. Full cell membership and permissions remain private;
|
||||
effect verification receives only targets cited by the candidate action.
|
||||
Resolution remains cover owner and WorldKernel remains commit owner.
|
||||
|
||||
After commit and push, clone Run 110's exact pulse-two checkpoint and resume
|
||||
only its 13 failed cells. Do not replay complexity, clock binding, Nemesis, or
|
||||
the 227 completed cell membranes. The acceptance launcher retains one
|
||||
content-addressed runner per exact source commit and deletes disposable remote
|
||||
compiler output.
|
||||
|
||||
## Mission and current product shape
|
||||
|
||||
|
|
|
|||
|
|
@ -179,7 +179,8 @@ exact campaign revision
|
|||
-> deterministic agenda admission checks anchor visibility, simulation authority, player exclusion, and per-cell decision quota
|
||||
-> one private Projector/Persona/Interpreter membrane per cell
|
||||
-> Projector receives exact decision-owner dossiers plus a bounded relevant-target viewport, never every inactive constituent dossier
|
||||
-> Interpreter agent inspects bounded exact target matches, then submits or incrementally edits one private exact-decision draft
|
||||
-> deterministic projection adds bounded relevant targets and exact canonical names mentioned by the lived stream or Persona turn
|
||||
-> Interpreter agent submits or incrementally edits one private exact-decision draft without performing target lookup
|
||||
-> deterministic draft compiler checks exact ownership, permissions, topology, and bounds
|
||||
-> independent per-action effect verifier checks the typed action against the Persona choice
|
||||
-> accepted unchanged actions retain their exact verifier binding across local draft repair
|
||||
|
|
|
|||
|
|
@ -243,4 +243,5 @@
|
|||
{"note": "Run 100 proved the individuation model boundary still exposed deterministic fields it did not own: the sole retried Veil dispatch repeatedly emitted null last/relevance revisions while 80 round-14 proposals remained frozen. WorldComplexityMemberDraft now contains only semantic member content; WorldComplexityTool constructs schema, exact parent/version/location, materialization state, and relevance revisions before the unchanged validator/kernel path. Two focused tests, 499 library tests, 18 strategic-smoke tests, and all-target check pass.", "status": "ok", "ts": "2026-08-31T23:10:08+00:00", "type": "correction"}
|
||||
{"note": "Runs 101 and 103 proved a structural compaction contract mismatch: the checkpoint/tool required each unresolved lead to contain 1..600 characters, but the generated action schema bounded only the array count, and the tool returned one opaque combined finding. Round17 retains 52 commits and 23 completed local summaries. The existing compaction owner now publishes identical per-item schema bounds and complete indexed findings; focused regression, 500 library tests, 18 strategic-smoke tests, and all-target check pass.", "status": "ok", "ts": "2026-08-31T23:28:51+00:00", "type": "correction"}
|
||||
{"note": "Run 104 round19 exposed a frozen-batch duplicate person: ordinals1272/1289 proposed the exact same canonical local ID and name Tarin Vel from adjacent Avelune carrier populations with near-identical content; serial admission failed after commits through1288. The round owner now canonicalizes exact local IDs, retains the earliest dispatch, publishes an immutable supersession checkpoint for later duplicates, excludes them from commit/session journals, and lets demand remeasure. Existing-world ID rejection remains with the shared validator. 500 library tests, 19 strategic-smoke tests, and all-target check pass.", "status": "ok", "ts": "2026-08-31T23:41:09+00:00", "type": "correction"}
|
||||
{"ts": "2026-09-01T01:29:25+00:00", "type": "verification", "status": "ok", "note": "Immutable Run 109 proved Nemesis paging and the 240-cell dispatch at 2,400 subjects, banked 226 of 240 cell terminals, then isolated 14 connector-frame failures: six Projector frames serialized inactive constituent dossiers and eight Interpreter frames serialized unbounded activity-target permissions. Bounded decision-owner projection plus Interpreter target inspection preserves full private authority while keeping model frames bounded; 505 library tests and 20 strategic-smoke tests pass."}
|
||||
{"note": "Immutable Run 109 proved Nemesis paging and the 240-cell dispatch at 2,400 subjects, banked 226 of 240 cell terminals, then isolated 14 connector-frame failures: six Projector frames serialized inactive constituent dossiers and eight Interpreter frames serialized unbounded activity-target permissions. Bounded decision-owner projection plus Interpreter target inspection preserves full private authority while keeping model frames bounded; 505 library tests and 20 strategic-smoke tests pass.", "status": "ok", "ts": "2026-09-01T01:29:25+00:00", "type": "verification"}
|
||||
{"ts": "2026-09-01T01:52:59+00:00", "type": "verification", "status": "ok", "note": "Run 110 retried only Run 109's 14 failed cells and eliminated connector-frame failures, but 13 Interpreters exhausted agent steps by using target inspection as directory assistance. The corrected owner deterministically projects bounded exact canonical names from lived and Persona text before inference, removes the Interpreter query command, preserves full private permissions, and passes 505 library plus 20 strategic-smoke tests."}
|
||||
|
|
|
|||
|
|
@ -245,3 +245,4 @@
|
|||
{"key": "2026-08-31T232851Z0000-0243-f35fd2b99a9a", "payload": "eyJub3RlIjogIlJ1bnMgMTAxIGFuZCAxMDMgcHJvdmVkIGEgc3RydWN0dXJhbCBjb21wYWN0aW9uIGNvbnRyYWN0IG1pc21hdGNoOiB0aGUgY2hlY2twb2ludC90b29sIHJlcXVpcmVkIGVhY2ggdW5yZXNvbHZlZCBsZWFkIHRvIGNvbnRhaW4gMS4uNjAwIGNoYXJhY3RlcnMsIGJ1dCB0aGUgZ2VuZXJhdGVkIGFjdGlvbiBzY2hlbWEgYm91bmRlZCBvbmx5IHRoZSBhcnJheSBjb3VudCwgYW5kIHRoZSB0b29sIHJldHVybmVkIG9uZSBvcGFxdWUgY29tYmluZWQgZmluZGluZy4gUm91bmQxNyByZXRhaW5zIDUyIGNvbW1pdHMgYW5kIDIzIGNvbXBsZXRlZCBsb2NhbCBzdW1tYXJpZXMuIFRoZSBleGlzdGluZyBjb21wYWN0aW9uIG93bmVyIG5vdyBwdWJsaXNoZXMgaWRlbnRpY2FsIHBlci1pdGVtIHNjaGVtYSBib3VuZHMgYW5kIGNvbXBsZXRlIGluZGV4ZWQgZmluZGluZ3M7IGZvY3VzZWQgcmVncmVzc2lvbiwgNTAwIGxpYnJhcnkgdGVzdHMsIDE4IHN0cmF0ZWdpYy1zbW9rZSB0ZXN0cywgYW5kIGFsbC10YXJnZXQgY2hlY2sgcGFzcy4iLCAic3RhdHVzIjogIm9rIiwgInRzIjogIjIwMjYtMDgtMzFUMjM6Mjg6NTErMDA6MDAiLCAidHlwZSI6ICJjb3JyZWN0aW9uIn0=", "stored_at": "2026-08-31T23:28:51.509927+00:00", "type": "ghostlight.evidence_record.v0"}
|
||||
{"key": "2026-08-31T234109Z0000-0244-ed94fa1db253", "payload": "eyJub3RlIjogIlJ1biAxMDQgcm91bmQxOSBleHBvc2VkIGEgZnJvemVuLWJhdGNoIGR1cGxpY2F0ZSBwZXJzb246IG9yZGluYWxzMTI3Mi8xMjg5IHByb3Bvc2VkIHRoZSBleGFjdCBzYW1lIGNhbm9uaWNhbCBsb2NhbCBJRCBhbmQgbmFtZSBUYXJpbiBWZWwgZnJvbSBhZGphY2VudCBBdmVsdW5lIGNhcnJpZXIgcG9wdWxhdGlvbnMgd2l0aCBuZWFyLWlkZW50aWNhbCBjb250ZW50OyBzZXJpYWwgYWRtaXNzaW9uIGZhaWxlZCBhZnRlciBjb21taXRzIHRocm91Z2gxMjg4LiBUaGUgcm91bmQgb3duZXIgbm93IGNhbm9uaWNhbGl6ZXMgZXhhY3QgbG9jYWwgSURzLCByZXRhaW5zIHRoZSBlYXJsaWVzdCBkaXNwYXRjaCwgcHVibGlzaGVzIGFuIGltbXV0YWJsZSBzdXBlcnNlc3Npb24gY2hlY2twb2ludCBmb3IgbGF0ZXIgZHVwbGljYXRlcywgZXhjbHVkZXMgdGhlbSBmcm9tIGNvbW1pdC9zZXNzaW9uIGpvdXJuYWxzLCBhbmQgbGV0cyBkZW1hbmQgcmVtZWFzdXJlLiBFeGlzdGluZy13b3JsZCBJRCByZWplY3Rpb24gcmVtYWlucyB3aXRoIHRoZSBzaGFyZWQgdmFsaWRhdG9yLiA1MDAgbGlicmFyeSB0ZXN0cywgMTkgc3RyYXRlZ2ljLXNtb2tlIHRlc3RzLCBhbmQgYWxsLXRhcmdldCBjaGVjayBwYXNzLiIsICJzdGF0dXMiOiAib2siLCAidHMiOiAiMjAyNi0wOC0zMVQyMzo0MTowOSswMDowMCIsICJ0eXBlIjogImNvcnJlY3Rpb24ifQ==", "stored_at": "2026-08-31T23:41:09.829172+00:00", "type": "ghostlight.evidence_record.v0"}
|
||||
{"key": "2026-09-01T012925Z0000-0245-cf212b15c07c", "payload": "eyJub3RlIjogIkltbXV0YWJsZSBSdW4gMTA5IHByb3ZlZCBOZW1lc2lzIHBhZ2luZyBhbmQgdGhlIDI0MC1jZWxsIGRpc3BhdGNoIGF0IDIsNDAwIHN1YmplY3RzLCBiYW5rZWQgMjI2IG9mIDI0MCBjZWxsIHRlcm1pbmFscywgdGhlbiBpc29sYXRlZCAxNCBjb25uZWN0b3ItZnJhbWUgZmFpbHVyZXM6IHNpeCBQcm9qZWN0b3IgZnJhbWVzIHNlcmlhbGl6ZWQgaW5hY3RpdmUgY29uc3RpdHVlbnQgZG9zc2llcnMgYW5kIGVpZ2h0IEludGVycHJldGVyIGZyYW1lcyBzZXJpYWxpemVkIHVuYm91bmRlZCBhY3Rpdml0eS10YXJnZXQgcGVybWlzc2lvbnMuIEJvdW5kZWQgZGVjaXNpb24tb3duZXIgcHJvamVjdGlvbiBwbHVzIEludGVycHJldGVyIHRhcmdldCBpbnNwZWN0aW9uIHByZXNlcnZlcyBmdWxsIHByaXZhdGUgYXV0aG9yaXR5IHdoaWxlIGtlZXBpbmcgbW9kZWwgZnJhbWVzIGJvdW5kZWQ7IDUwNSBsaWJyYXJ5IHRlc3RzIGFuZCAyMCBzdHJhdGVnaWMtc21va2UgdGVzdHMgcGFzcy4iLCAic3RhdHVzIjogIm9rIiwgInRzIjogIjIwMjYtMDktMDFUMDE6Mjk6MjUrMDA6MDAiLCAidHlwZSI6ICJ2ZXJpZmljYXRpb24ifQ==", "stored_at": "2026-09-01T01:29:25.894858+00:00", "type": "ghostlight.evidence_record.v0"}
|
||||
{"key": "2026-09-01T015259Z0000-0246-b09ae25755cb", "payload": "eyJub3RlIjogIlJ1biAxMTAgcmV0cmllZCBvbmx5IFJ1biAxMDkncyAxNCBmYWlsZWQgY2VsbHMgYW5kIGVsaW1pbmF0ZWQgY29ubmVjdG9yLWZyYW1lIGZhaWx1cmVzLCBidXQgMTMgSW50ZXJwcmV0ZXJzIGV4aGF1c3RlZCBhZ2VudCBzdGVwcyBieSB1c2luZyB0YXJnZXQgaW5zcGVjdGlvbiBhcyBkaXJlY3RvcnkgYXNzaXN0YW5jZS4gVGhlIGNvcnJlY3RlZCBvd25lciBkZXRlcm1pbmlzdGljYWxseSBwcm9qZWN0cyBib3VuZGVkIGV4YWN0IGNhbm9uaWNhbCBuYW1lcyBmcm9tIGxpdmVkIGFuZCBQZXJzb25hIHRleHQgYmVmb3JlIGluZmVyZW5jZSwgcmVtb3ZlcyB0aGUgSW50ZXJwcmV0ZXIgcXVlcnkgY29tbWFuZCwgcHJlc2VydmVzIGZ1bGwgcHJpdmF0ZSBwZXJtaXNzaW9ucywgYW5kIHBhc3NlcyA1MDUgbGlicmFyeSBwbHVzIDIwIHN0cmF0ZWdpYy1zbW9rZSB0ZXN0cy4iLCAic3RhdHVzIjogIm9rIiwgInRzIjogIjIwMjYtMDktMDFUMDE6NTI6NTkrMDA6MDAiLCAidHlwZSI6ICJ2ZXJpZmljYXRpb24ifQ==", "stored_at": "2026-09-01T01:52:59.326044+00:00", "type": "ghostlight.evidence_record.v0"}
|
||||
|
|
|
|||
|
|
@ -329,8 +329,8 @@ current_status:
|
|||
provider_acceptance_checkpoint: Exact pushed commit `139b8a6` completed Run 60 under `character-newsroom.v10` without world or per-wave replay. Its acceptance witness and terminal status bind the completed page and exact resume lineage. The independently dispatched blind reviewer, shown only the reader-facing fantasy newspaper, read it as a real left-populist civic broadsheet and did not immediately identify procedural generation, so the narrative reverse-Turing criterion passes. The review's substantive criticism is that the three stories feel like three rewrites of one briefing; accepted Run 60 remains immutable. The run used 96,902 prompt tokens and reported zero cache hits. Its delivered typeset artifact is `output/pdf/canopy-ledger-run-60-front-page.pdf`; frozen-source and visual verification remain accepted. Exact pushed `bc2ca39` then produced frozen-fact newsroom-only Run 61 Issues 13, 15, 16, 17, and 18 without world or wave model replay. Provider output proves `special_issue` convergence in Issues 13 and 15, independent `general_issue` beats in Issues 16 through 18, and assignment-selector cache hits. Blind review of Issues 13, 15, 16, and 17 passes both distinct recurring voices and issue-shape diversity, recognizing Ossan, Mera, Corin, and Lysa's biases plus modest cross-issue evolution. Run 62 exercised v12 without world or wave replay and failed only because two lead articles proposed invalid datelines; recurring reporter calls still recorded zero cache hits. Run 63 used exact pushed v13 `a52d57b`; Issues 17 and 18 completed before root stopped the final weekly recomposition, both repeated bylines again recorded zero cache hits, and live services remained unchanged. Preserve Runs 61 through 63 as stopped or completed immutable evidence. Copy defects remain later deadline-correction work rather than a reason to reopen accepted issue artifacts.
|
||||
implementation_checkpoint: Exact pushed v13 `a52d57b` keeps one stable reporter action schema, places a common stable house charter before recurring identity and dynamic assignment, and projects deterministic `allowed_datelines` from cited records while retaining copy-desk factual authority and deterministic cited-place admission; 480 library tests and the all-target check pass. Run 63 falsifies reporter-cache pursuit as a useful acceptance target for sporadic independent filings. The proposed v14 cache-floor prompt growth was removed. Append-only agent contexts remain the natural cache beneficiary; accepted Run 60 remains immutable. The strategic cut extracts one shared `validate_strategic_individuation_proposals` owner used by resolution validation and by the scheduler before it returns an optional proposal. An invalid optional identity emits a semantic-invalid receipt and produces no individuation instead of aborting the recoverable wave. Focused valid and invalid regressions pass, and exact-source Run 68 exercises the corrected provider path through twelve committed waves; no further validator implementation is pending. The newsroom-only cut adds a navigation-only directory of completed public changes grouped by period and exact source timestamps to new v14 audit citations. The directory derives context from canonical records and gains no fact or world authority. Legacy empty source times are omitted from both rendering and serialization, preserving inherited v13 receipt bytes and digests; new v14 nonempty source times remain rendered and serialized. Exact-source Run 73 proves that compatibility path and final recomposition mechanically. Current source gives the assignment editor bounded full-ledger queries and explicitly asks it to search sideways for opposition and countermoves; Run 73 falsifies the stronger assumption that this access and instruction alone guarantee balanced selection. Exact pushed v15 source `b6787d909bd79b68ed3a4d143b7f6dd438e00fa2` binds accountability, opposition, and counter-narrative pitches to two distinct named parties and selected citations through a typed conflict axis, and preserves canonical ledger order. Run 74 falsifies the stronger v15 assumption: its lone accountability pitch used the same transfer citation for cultivators and a passive Tribunal, while four of five pitches avoided the adversarial axis through lead or consequence functions. Two cited names did not prove two moves. Exact pushed v16 `86fe6ed89d51da26b65ab6a031608075840b1527` binds each adversarial axis to two distinct cited public moves or positions and rejects one record presented as both sides; it adds no event writer, judge, process, dependency, or persistent authority. Formatting, 27 focused newspaper tests, 484 full library tests, and 16 strategic-smoke tests pass.
|
||||
full_world_acceptance_checkpoint: Run 68 at exact source `69c811a2669fc38f19f9199bf57088dc250bfc3e` is mechanically complete at world revision 27 with 12/12 strategic waves, 240 events, 514 public news rows, and a final newspaper. Independent editorial and grounding reviews both fail. Earlier per-wave papers prove the immutable record already contains dramatic completed facts, including an organ breaching the rail capital, a dead pump, and families crossing borders; the final paper failed to make that committed change legible. Preserve Run 68 unchanged. Run 69 at source `84b31e57a462710eb939c4559e0437eb5d6a7a28` failed before any model call when immutable recomposition verification encountered an empty rendered `Source time:` line in inherited v13 per-wave issues. Run 70 at source `ec45952b843e102dc2ebddda3a3bbb4058687175` also failed before any model call because v14 serialization changed the legacy recomposition digest. Exact-source Run 73 `b827d897b9579c2091a67c363d35b8695288ba2f` is terminal complete at `/var/lib/gamecult/ghostlight-dungeon/acceptance/full-world-delvehold-b827d89-73`: world revision 27, 12/12 waves, 240 events, 514 news rows, inherited artifacts byte-identical to Run 68, manifest valid, and archive SHA-256 `090d05f304c8f3d33c9dccd728bffbf3e5dc2969a7aeeffc2f9d7bafe701ac8a`. Exact-source Run 74 `b6787d909bd79b68ed3a4d143b7f6dd438e00fa2` is mechanically complete at `/var/lib/gamecult/ghostlight-dungeon/acceptance/full-world-delvehold-b6787d9-74`: revision 27, 12/12 waves, 240 events, 514 news rows, Run 68 inherited artifacts byte-identical, manifest valid, unchanged live services, and archive SHA-256 `957b11a5d584d27d23bf4d50ed1fbc8d067faf67953b03f80705bfb9587c496d`. Independent editorial review fails: the page has a coherent throughline and sharp prose but no sustained adversarial narrative; opposing decision-makers, motives, responses, and countermoves are largely absent, scandal and public reaction are missing, lived costs remain abstract, and the result reads as polished minutes with conclusions. Its post-press correction notice has two items: `The corridor had begun closing hours earlier` overstates a source that says the prolonged oath-route closure was diverting arrivals six hours before the breach; `no relief or assignment of liability has followed` must narrow to `no tribunal remedy is recorded yet`. Run 75 launched at exact source `86fe6ed89d51da26b65ab6a031608075840b1527` under the superseded 240-cell-only acceptance shape and was stopped cleanly at the operator's scale correction. Preserve `/var/lib/gamecult/ghostlight-dungeon/acceptance/full-world-delvehold-86fe6ed-75` as stopped non-acceptance evidence: preflight, world-region and titled-elaboration checkpoints, a wave-one cell terminal checkpoint, partial pulses 01/02, and two rejected pulse receipts exist. `ghostlight-full-world-run75.service` invocation `86bfe6a3ef504a7d99f579b3d67710ab` is inactive/dead after explicit stop; live services remain unchanged. Do not claim terminal success or failure. Preserve Runs 64 through 75. Mechanical completion of the earlier world is proven, but final newspaper acceptance under the corrected scale target is not.
|
||||
scale_checkpoint: The active 240-cell entitlement is an attention budget, not the world-size claim. Multiresolution Gestalts compress unresolved population; repeated admitted elaboration fissions them and promotes causally meaningful individuals and institutions, with `WorldElaborationDemand` deriving bounded mutation pressure and canonical remeasurement owning completion. Pushed source `8dd3147` keeps compaction journals structurally compact. Immutable Run 108 reached exactly 2,400 actionable subjects at complexity round 43; clock binding advanced the campaign to revision 1551 and resolution epoch 1545. Pushed source `b61e762` bounds Nemesis through anchor-summary and responder-dossier paging while retaining complete deterministic eligibility privately. Immutable Run 109 proved Nemesis and the 240-cell dispatch at that scale: wave-1 pulse one completed 214 cells, bounded retries raised the durable partial checkpoint to 226, and the fifth pulse terminated with exactly 14 frame-bound failures. No fictional wave committed and time did not advance. Six failures belonged to Projector frames that serialized hundreds of inactive constituent dossiers; eight belonged to Interpreter frames whose exact schemas serialized one active owner's unbounded activity-target catalog, including cells with only two subjects. The current cut makes model context a bounded query projection: Projector receives only exact decision-owner dossiers plus at most 24 deterministically relevant targets, while the Interpreter's existing agent workbench can inspect up to 12 exact name/ID matches before its dynamic schema expands. Full membership and permissions remain private deterministic state; effect verification receives only targets cited by the candidate action; Resolution remains cover owner and WorldKernel remains commit owner. Run 109 is immutable at `/var/lib/gamecult/ghostlight-dungeon/acceptance/full-world-delvehold-b61e762-109`; its final wave-1 partial checkpoint contains 226 completed and 14 failed cells with SHA-256 `f502ad560e0f23db226c326072e5e8a6d0ed9975f0e63bc67606d7d7cb9b2c27`. Exact resource/member assignment, compact individuation ownership, proposal supersession, civic fission rebinding, evolved-checkpoint proof, bounded lineage lookup, parallel session compaction, deterministic child-ID reconciliation, and materialized-member affiliation transfer remain preserved.
|
||||
scale_checkpoint: The active 240-cell entitlement is an attention budget, not the world-size claim. Multiresolution Gestalts compress unresolved population; repeated admitted elaboration fissions them and promotes causally meaningful individuals and institutions, with `WorldElaborationDemand` deriving bounded mutation pressure and canonical remeasurement owning completion. Pushed source `8dd3147` keeps compaction journals structurally compact. Immutable Run 108 reached exactly 2,400 actionable subjects at complexity round 43; clock binding advanced the campaign to revision 1551 and resolution epoch 1545. Pushed source `b61e762` bounds Nemesis through anchor-summary and responder-dossier paging while retaining complete deterministic eligibility privately. Immutable Run 109 proved Nemesis and the 240-cell dispatch at that scale, ending with 226 completed and 14 frame-bound failures at SHA-256 `f502ad560e0f23db226c326072e5e8a6d0ed9975f0e63bc67606d7d7cb9b2c27`; no fictional wave committed and time did not advance. Pushed source `67421ad` bounded Projector and Interpreter frames. Immutable Run 110 cloned Run 109's exact checkpoint, retried only its 14 failures, eliminated every connector-frame failure, and banked one additional cell. Its pulse-two checkpoint contains 227 completed and 13 failed cells with SHA-256 `88a4f193e9f4d136841ede8d9c6b23e88788002a5f2e6b0c93bea9bb51b388de`. The 13 remaining Interpreters exhausted their agent steps by using target inspection as directory assistance for ordinary noun phrases, so root stopped the transient unit before more calls. The current correction deletes that misplaced query authority: Projector receives only decision-owner dossiers plus at most 24 relevant targets, and one deterministic pre-Interpreter projection adds bounded canonical targets whose exact supplied names occur in the lived stream or Persona turn. Full membership and permissions remain private; unmatched roles remain targetless local actions when supported; effect verification receives only candidate-cited targets; Resolution remains cover owner and WorldKernel remains commit owner. Exact resource/member assignment, compact individuation ownership, proposal supersession, civic fission rebinding, evolved-checkpoint proof, bounded lineage lookup, parallel session compaction, deterministic child-ID reconciliation, and materialized-member affiliation transfer remain preserved.
|
||||
presentation_checkpoint: The historical press-layout and seed-ownership split are complete. `notes/historical-newspaper-layout-grammar.md` remains the durable grammar. Manifest v2 at `output/tex/canopy-ledger-run-61-style-1847-flow-723.manifest.toml` independently binds `style_seed=1847`, `flow_seed=723`, frozen source SHA-256 `8f195140f52a40ba705d6a66987146a1500ae89668e5d82b01d1792eb3afb882`, and the final artifact `output/pdf/canopy-ledger-run-61-style-1847-flow-723.pdf`, SHA-256 `a457f4b1702a7a52480e42fce0039f0dbe677ff32958e98f1c412b346237190c`. An identical seed pair produces byte-identical TeX and PDF; changing only flow preserves the exact style section while materially changing a plausible layout, and changing only style preserves flow topology. Cut-first and cut-midstory templates pass visual inspection; the failed split-card template is deleted. Frozen copy/assets, actual PDF `/BM /Multiply`, and economic-layer advertising authority remain invariant.
|
||||
public_reference_checkpoint: Public architecture reference is complete. Canonical Ghostlight commit `15ea0f0` owns five pages under `docs/public-architecture` covering overview, authority, pipelines, 43 named production stages, and eight titled elaborators. Site commit `ea0b026` publishes exact projections under `F:\Projects\GhostlightDungeon-site\content\Documentation`, adds the sync/check script, explorer and table-of-contents navigation, scoped documentation layout, and homepage Architecture link. Local Quartz build and visual browser QA pass. GitHub Pages workflow `33408004480` succeeded. `https://ghostlight.gamecult.org/Documentation/` and the extensionless `Documentation/Agents-and-model-stages` route are live; the stage page exposes seven tables and 51 rows. Ghostlight remains technical authority; the site repository owns public composition and deployment.
|
||||
next_action: Preserve Runs 75 through 109 and the exact 2,400-subject round-43 world. Finish review and verification of bounded decision-owner projection and Interpreter target inspection, commit and push, then clone Run 109's exact 226-cell wave-1 checkpoint into a new immutable root. Resume only its 14 failed cells; do not replay complexity rounds, clock binding, Nemesis, or completed cell membranes. Continue through ten committed strategic waves, per-wave publications and final digest, exact provenance and archive/hash checks, and unchanged live-service identities. Do not raise the connector bound, truncate canonical membership or permissions, grant query projections authority, or start another persistence optimization without measured evidence. Preserve compact elaborator continuity, canonical-ID identity ownership, deterministic proposal supersession, Resolution cover ownership, WorldKernel commit authority, the completed public reference, the two-seed press checkpoint, and the economic-layer advertising boundary.
|
||||
next_action: Preserve Runs 75 through 110 and the exact 2,400-subject round-43 world. Commit and push the verified deterministic narrative-target projection, then clone Run 110's exact 227-cell wave-1 pulse-two checkpoint into a new immutable root. Resume only its 13 failed cells; do not replay complexity rounds, clock binding, Nemesis, or completed cell membranes. Continue through ten committed strategic waves, per-wave publications and final digest, exact provenance and archive/hash checks, and unchanged live-service identities. Do not raise the connector bound, truncate canonical membership or permissions, restore Interpreter target lookup, or start another persistence optimization without measured evidence. Preserve compact elaborator continuity, canonical-ID identity ownership, deterministic proposal supersession, Resolution cover ownership, WorldKernel commit authority, the completed public reference, the two-seed press checkpoint, and the economic-layer advertising boundary.
|
||||
gestalt_population: Gestalt Personas own shared population baselines; persistent member deltas own named individuality; WorldKernel materialization and approval-gated fission preserve lineage and identity. Materialisation/folding changes only representation and the exact member delta, advances resolution epoch, and retires the old cover; it has no Gestalt-wide effect authority. Selected actionable member exceptions are mandatory Projector perspective owners, so aggregation cannot silently erase their decision. Presence projection is limited to nearby active leaves and exact-location dormant members, includes reciprocal player relationship evidence, and may propose an earned cast without committing it. Simulation cells are derived covers only.
|
||||
|
|
|
|||
Loading…
Reference in a new issue