- 4001
assert_eq!(intent.reading.horizon, Horizon::Immediate); - 4002
assert_eq!(intent.reading.stakes, Stakes::Inert); - 4003
assert_eq!(intent.reading.attendance, Attendance::Interactive); - 4004
assert!(intent.engagement.limits.is_at_most(&Limits::unrestricted())); - 4005
assert_eq!(intent.engagement.posture.context, ContextProfile::Minimal); - 4006
} - 4007
- 4008
#[test] - 4009
fn pipeline_irreversible_reaches_human() { - 4010
let intent = resolve_text("deploy the service to production"); - 4011
assert_eq!(intent.reading.stakes, Stakes::Irreversible); - 4012
assert_eq!(intent.reading.act, Act::Operate); - 4013
assert_eq!(intent.engagement.posture.hil, HilMode::Interrupt); - 4014
assert!( - 4015
intent - 4016
.engagement - 4017
.posture - 4018
.note - 4019
.as_deref() - 4020
.is_some_and(|n| n.contains("cannot be undone")) - 4021
); - 4022
} - 4023
- 4024
#[test] - 4025
fn pipeline_verification_requires_observed_satisfaction() { - 4026
let intent = resolve_text("make sure the tests pass before merging"); - 4027
assert_eq!(intent.reading.evidence, Evidence::Verified); - 4028
assert_eq!( - 4029
intent.engagement.limits.min_satisfaction, - 4030
Satisfaction::Observed - 4031
); - 4032
} - 4033
- 4034
#[test] - 4035
fn pipeline_audited_work_requires_attested() { - 4036
let intent = resolve_text("review the code and get sign off from compliance"); - 4037
assert_eq!(intent.reading.evidence, Evidence::Audited); - 4038
assert_eq!( - 4039
intent.engagement.limits.min_satisfaction, - 4040
Satisfaction::Attested - 4041
); - 4042
} - 4043
- 4044
#[test] - 4045
fn pipeline_cited_work_adds_live_data_domain() { - 4046
let intent = resolve_text("research the history with cited sources"); - 4047
assert_eq!(intent.reading.evidence, Evidence::Cited); - 4048
assert!( - 4049
intent - 4050
.engagement - 4051
.limits - 4052
.required_domains - 4053
.contains("live-data") - 4054
); - 4055
assert_eq!( - 4056
intent.engagement.limits.min_satisfaction, - 4057
Satisfaction::Cited - 4058
); - 4059
} - 4060
- 4061
#[test] - 4062
fn pipeline_long_horizon_opens_commitment() { - 4063
let intent = resolve_text("check the cloud bill every day and alert me"); - 4064
assert_eq!(intent.reading.horizon, Horizon::Durable); - 4065
assert!(intent.engagement.posture.open_commitment); - 4066
assert!(intent.engagement.posture.managed); - 4067
assert_eq!(intent.engagement.posture.context, ContextProfile::Full); - 4068
} - 4069
- 4070
#[test] - 4071
fn pipeline_surface_changes_attendance() { - 4072
let mut request = req("do something"); - 4073
request.surface = Surface::Cron; - 4074
let resolution = resolve( - 4075
&request, - 4076
&Declared::default(), - 4077
&Authority::default(), - 4078
&ResolverConfig::default(), - 4079
); - 4080
let intent = resolution.intent(); - 4081
assert_eq!(intent.reading.attendance, Attendance::Unattended); - 4082
} - 4083
- 4084
#[test] - 4085
fn pipeline_attachment_adds_modality_and_act_signal() { - 4086
let attachments = vec![Attachment { - 4087
modality: Modality::Image, - 4088
name: "diagram.png".into(), - 4089
}]; - 4090
let mut request = req("what is wrong with this"); - 4091
request.attachments = &attachments; - 4092
let extraction = extract(&request); - 4093
assert!(extraction.input_modalities.contains(&Modality::Image)); - 4094
assert!( - 4095
extraction - 4096
.act - 4097
.ranked() - 4098
.iter() - 4099
.any(|(a, _)| *a == Act::Analyze) - 4100
); - 4101
} - 4102
- 4103
#[test] - 4104
fn pipeline_workspace_repo_adds_domain() { - 4105
let intent = resolve( - 4106
&req_full("refactor the parser", Surface::Cli, true, false, None, 0), - 4107
&Declared::default(), - 4108
&Authority::default(), - 4109
&ResolverConfig::default(), - 4110
) - 4111
.intent(); - 4112
assert!(intent.reading.domains.contains("engineering")); - 4113
} - 4114
- 4115
#[test] - 4116
fn pipeline_worker_surface_inherits_unattended() { - 4117
let mut request = req("check the status"); - 4118
request.surface = Surface::Worker; - 4119
let extraction = extract(&request); - 4120
assert_eq!(extraction.attendance, Attendance::Unattended); - 4121
} - 4122
- 4123
// ================================================================ - 4124
// Part 26: Authority × Stakes × Autonomy interaction matrix - 4125
// ================================================================ - 4126
- 4127
#[test] - 4128
fn authority_stakes_autonomy_hil_matrix() { - 4129
let mut checked = 0u64; - 4130
for &stakes in &Stakes::ALL { - 4131
for &autonomy in &Autonomy::ALL { - 4132
for &attendance in &Attendance::ALL { - 4133
for &horizon in &[Horizon::Turn, Horizon::Durable] { - 4134
let r = reading_simple(Act::Modify, horizon, stakes, Evidence::None); - 4135
let auth = authority_of(autonomy, attendance); - 4136
let engagement = derive(&r, &auth, true); - 4137
- 4138
if stakes == Stakes::Irreversible { - 4139
// Someone present: interrupt. Nobody present and the - 4140
// work durable enough to park the question: defer to - 4141
// the inbox rather than raise a gate that can only - 4142
// time out. - 4143
let expected = if !attendance.can_answer_now() && horizon.opens_commitment() - 4144
{ - 4145
HilMode::Defer - 4146
} else { - 4147
HilMode::Interrupt - 4148
}; - 4149
assert_eq!( - 4150
engagement.posture.hil, expected, - 4151
"stakes={stakes:?} autonomy={autonomy:?} attendance={attendance:?} horizon={horizon:?}" - 4152
); - 4153
} - 4154
- 4155
if !attendance.can_answer_now() - 4156
&& horizon.opens_commitment() - 4157
&& stakes.rank() >= Stakes::Costly.rank() - 4158
{ - 4159
assert_eq!(engagement.posture.hil, HilMode::Defer); - 4160
} - 4161
- 4162
if attendance == Attendance::Interactive - 4163
&& autonomy == Autonomy::Autonomous - 4164
&& stakes.rank() <= Stakes::Reversible.rank() - 4165
{ - 4166
assert_eq!(engagement.posture.hil, HilMode::Review); - 4167
} - 4168
checked += 1; - 4169
} - 4170
} - 4171
} - 4172
} - 4173
assert!(checked >= 4 * 4 * 3 * 2, "checked {checked} combinations"); - 4174
} - 4175
- 4176
#[test] - 4177
fn regression_polite_preamble_preserves_imperative_verb() { - 4178
let intent_polite = resolve_text("please refactor the parser"); - 4179
let intent_direct = resolve_text("refactor the parser"); - 4180
assert_eq!(intent_polite.reading.act, Act::Modify); - 4181
assert_eq!(intent_direct.reading.act, Act::Modify); - 4182
assert!(intent_polite.reading.axis_confidence.act >= 0.7); - 4183
} - 4184
- 4185
#[test] - 4186
fn regression_inflected_evidence_words_match() { - 4187
let intent = resolve_text("please fix the bug, ensuring all tests pass"); - 4188
assert_eq!(intent.reading.evidence, Evidence::Verified); - 4189
assert_eq!( - 4190
intent.engagement.limits.min_satisfaction, - 4191
Satisfaction::Observed - 4192
); - 4193
} - 4194
- 4195
#[test] - 4196
fn regression_disjoint_domain_meet_collapses_to_empty() { - 4197
let a = Limits { - 4198
required_domains: DomainSet::only(["vcs"]), - 4199
..Limits::unrestricted() - 4200
}; - 4201
let b = Limits { - 4202
required_domains: DomainSet::only(["live-data"]), - 4203
..Limits::unrestricted() - 4204
}; - 4205
let met = a.meet(&b); - 4206
assert_eq!(met.required_domains, DomainSet::Empty); - 4207
assert!(met.is_at_most(&a)); - 4208
assert!(met.is_at_most(&b)); - 4209
assert!(met.is_at_most(&Limits::unrestricted())); - 4210
} - 4211
- 4212
#[test] - 4213
fn regression_compound_clause_heads_receive_imperative_bonus() { - 4214
let extraction = extract(&req( - 4215
"search for the bug and refactor the parser then verify the tests", - 4216
)); - 4217
let contenders = extraction.act.contenders(0.5); - 4218
assert!( - 4219
contenders.contains(&Act::Locate), - 4220
"Locate must be in contenders" - 4221
); - 4222
assert!( - 4223
contenders.contains(&Act::Modify), - 4224
"Modify must be in contenders" - 4225
); - 4226
assert!( - 4227
contenders.contains(&Act::Verify), - 4228
"Verify must be in contenders" - 4229
); - 4230
- 4231
// Test with commas and newlines - 4232
let comma_extraction = extract(&req("locate the issue, patch the code, test everything")); - 4233
let comma_contenders = comma_extraction.act.contenders(0.5); - 4234
assert!(comma_contenders.contains(&Act::Locate)); - 4235
assert!(comma_contenders.contains(&Act::Modify)); - 4236
assert!(comma_contenders.contains(&Act::Verify)); - 4237
} - 4238
- 4239
#[test] - 4240
fn regression_contenders_absolute_floor_and_strong_bypass() { - 4241
let mut votes: vak_intent::signals::Votes<Act> = vak_intent::signals::Votes::default(); - 4242
votes.add(Act::Modify, 0.4); - 4243
votes.add(Act::Answer, 0.2); // 0.2 >= 0.4 * 0.5, but < 0.5 absolute floor! - 4244
let contenders = votes.contenders(0.5); - 4245
assert_eq!( - 4246
contenders, - 4247
vec![Act::Modify], - 4248
"0.2 noise must not join contenders below absolute floor" - 4249
); - 4250
- 4251
// Test strong signal bypass (>= 1.0) when winner is inflated - 4252
let mut inflated: vak_intent::signals::Votes<Act> = vak_intent::signals::Votes::default(); - 4253
inflated.add(Act::Modify, 3.5); - 4254
inflated.add(Act::Verify, 1.2); // 1.2 < 3.5 * 0.5 = 1.75, but 1.2 >= 1.0 strong signal! - 4255
let inflated_contenders = inflated.contenders(0.5); - 4256
assert!(inflated_contenders.contains(&Act::Modify)); - 4257
assert!( - 4258
inflated_contenders.contains(&Act::Verify), - 4259
"Strong act (>= 1.0) must bypass inflated winner gap" - 4260
); - 4261
} - 4262
Indexing the workspace…
Vakyartha documentation is discovering safe artifacts, anchors, and source references.