test: wip validate scope replacement and target compatibility

This commit is contained in:
2026-10-09 01:13:15 +09:00
parent 23cf6c4f88
commit c1b3b95c5d
2 changed files with 105 additions and 2 deletions
+81
View File
@@ -457,3 +457,84 @@ async fn ancestor_replacement_during_in_flight_call_keeps_the_original_descripto
assert_eq!(new.content.as_deref(), Some("2"));
assert_eq!(provider.calls.load(Ordering::SeqCst), 2);
}
#[tokio::test]
async fn same_name_scope_replacement_or_loss_of_ref_rejects_old_metadata_without_replay() {
for identity in [Some("replacement"), None] {
let (runtime, provider) = fixture("/github/team", true, false);
let selected = reference("/github/team", "read");
runtime
.inspect(provider.target_path.clone(), false)
.await
.unwrap();
{
let mut state = provider.state.lock().unwrap();
state.identity = identity.map(Into::into);
if identity.is_some() {
state.generation = 1;
}
}
assert_eq!(
rejected_code(
&runtime,
metadata_request(
&provider.target_path,
json!({"scope":"/github/team","name":"read"}),
None,
Some("live-scope")
)
)
.await,
"interface_mismatch"
);
let failed = runtime
.invoke(
provider.target_path.clone(),
selected.clone(),
"read".into(),
json!({}),
ToolExecutionContext::direct(),
)
.await
.unwrap_err();
assert!(failed.to_string().contains("InterfaceMismatch"), "{failed}");
assert_eq!(provider.calls.load(Ordering::SeqCst), 0);
let fetched = runtime.host.fetch_interface_live(&selected).await.unwrap();
assert_eq!(fetched.scope_ref.as_deref(), identity);
assert_eq!(
fetched.descriptor.documentation.unwrap().summary,
if identity.is_some() {
"Published generation 1"
} else {
"Published generation 0"
}
);
runtime
.inspect(provider.target_path.clone(), true)
.await
.unwrap();
runtime
.invoke(
provider.target_path.clone(),
selected,
"read".into(),
json!({}),
ToolExecutionContext::direct(),
)
.await
.unwrap();
assert_eq!(provider.calls.load(Ordering::SeqCst), 1);
let state = runtime.state.lock().unwrap();
let call = state
.client
.call_history(&state.session)
.unwrap()
.back()
.unwrap();
// Omitted scope_ref is never filled from the placeholder or other observations.
assert_eq!(
call.context.request().interface.scope_ref.as_deref(),
identity
);
}
}
+24 -2
View File
@@ -17,10 +17,10 @@ Cargo resolves the release, not that checkout or an unreleased Rust revision.
## Executed checks on registry 0.2.0
- `cargo test -p worker --locked --offline`: **893 unit + 110 integration tests
- `cargo test -p worker --locked --offline`: **894 unit + 110 integration tests
passed**, no ignored/failed tests. This includes ordinary Tools mode, Feature
permission/revocation, restore, session/history and controller integration.
- Narrow development checks: `wip::binding` (25), `wip::provider_tests` (11), existing
- Narrow development checks: `wip::binding` (25), `wip::provider_tests` (12), existing
`wip::tests` and workdir projection tests (43), checkout transports/providers
(20), workspace-config production/authority tests (19). These are included
in the complete worker run.
@@ -36,6 +36,26 @@ Cargo resolves the release, not that checkout or an unreleased Rust revision.
hash. This validates credential-free dependency acquisition, not a full Nix
binary/image build or deployment update.
## Current target compatibility (preview, not integration)
Source runtime at `23cf6c4f882ce78985ba4bd673751cebe64e2d87` and current develop
`b5ea162f838fc36e364edec9ab6689292b59cffd` produce the conflict-free `git merge-tree`
preview tree `7ef3545b635cbdfc5e24658f6d1532e0f8b0947c`. An archive of this tree,
without a branch/ref change, passed root locked/offline Cargo check, all **91**
Server API TypeScript tests (including OpenAPI/checked-in generator freshness),
registry WIP resolution checks, and Nix dependency acquisition with the same hash.
T-722's API macros, Server API/Drive/Server source, OpenAPI and generated TS blobs
are unchanged from develop in the combined tree; no artifact overwrite or
regeneration is necessary for this source change. The later added same-name scope
regression changes tests only, not the validated runtime or shared contracts.
The initial archive check reused a Cargo target directory; returning to the older
main checkout exposed stale preview Server API artifacts. All local workspace
artifacts were invalidated, and a fresh main root check and complete **894 + 110**
Worker suite passed. Use an isolated target directory for future cross-tree checks.
No target push, integration branch, deployment, or live dogfood update was made.
Orchestrator readiness/integration must still resolve the then-current target.
## Contract evidence
`crates/worker/src/wip/binding.rs` tests exercise fresh/loading/stale/failed and
@@ -60,6 +80,8 @@ valid live ancestor refs that differ from registration placeholders, root `/` an
intermediate provider-owned ancestors, ref-less and ref-bearing scope deletion
without a prior scope Inspect, rejected cached dispatch and orphan observation,
replacement/republication without restoring old Interface registrations,
same-name scope replacement or loss of public ref rejecting copied old metadata
without replay (and later explicit Inspect/Invoke copying only the new optional ref),
shape/target/Object-validator/Interface-mismatch precedence, and frozen in-flight
ancestor Descriptor/handler/result validation after replacement. Valid Invoke
makes one provider publication call for the target, not a separate scope lookup.