S-01 — the marked-pub open contract (ADR-047 amendment 4): - ChannelCore::register_pub_openable + PubOpenHandler (the put path's handler returns its result for the merged single response; the wrapper awaits inline, teardown is EOF-driven, handler_task stays None); register_openable* refuses Pub-typed specs; the wrapper entry points refuse unmarked/non-Pub shapes - the reserved input key `channel_id` (the initiator-allocated id): stripped pre-validation by resolve_sink_handler (the single source of truth, P-08), handed to the wrapper via OperationContext.metadata, a missing key rejected INVALID_INPUT; adopt parity enforced (ManagerError::InvalidAdopt) and adopt failures answer channel:open_failed / adopt_failed - zero call.published on marked ops: the first publish chunk on a marked op is rejected loudly (channel:publish_chunks_rejected) in both dispatch loops; the handler is never fed - relay put-translation replaces RelayError::PubTypedOpen: hub allocates odd on the producer leg, opens the spoke op in the background (put-acks-in-result), one-direction pump, response-mirror with the producer's reserved key stripped - ChannelClient::open_pub_channel + PubOpenReply (the initiator- allocates put open capability) S-02 — channel/control implemented (ADR-052): establisher-contributed ChannelControl (Establishment::with_control), manager-owned registry, teardown removals, channel:no_control_handle capability answer. S-03 — channel/resources/subscribe implemented (ADR-053): the ResourceEnumerators registry (shared per peer), snapshot-then-changes enumerators, scan-once aggregation, the empty seed; the always-failing one-shot error stream removed. S-04 — op/register forward-through (ADR-022 amendment): announced unmarked Sub/Pub register the real streaming/sink forwarding shapes; marked announcements refused with MARKED_SPEC_UNSUPPORTED; marked specs refuse the generic registration path and register_imported (Result-returning now). Guard (review 010 action 3): tests/stub_guard.rs greps src/ for not_implemented; the four pinned stub tests are deleted and the marked-spec registration refusals are pinned by tests. Verified: cargo test (696 + guard), clippy --all-targets -D warnings, fmt --check, fuzz corpus replay.
50 lines
1.8 KiB
Rust
50 lines
1.8 KiB
Rust
//! The stub guard (review 010 action 3): no `*:not_implemented` path
|
|
//! may exist in `src/`. A handler that registers successfully and
|
|
//! returns an error of this form on every invocation is a bug, not a
|
|
//! documented limitation — shipping one is a hard failure per the
|
|
//! repo ruling (reviews 010/011; four stubs shipped across nine
|
|
//! published versions before this guard existed).
|
|
|
|
#[test]
|
|
fn source_tree_has_no_not_implemented_path() {
|
|
let manifest = env!("CARGO_MANIFEST_DIR");
|
|
let src = std::path::Path::new(manifest).join("src");
|
|
let mut offenders = Vec::new();
|
|
walk(&src, &mut offenders);
|
|
assert!(
|
|
offenders.is_empty(),
|
|
"no `not_implemented` string may appear in src/ — a registered surface \
|
|
that always fails is the stub class (review 010 S-01..S-04); offended \
|
|
by: {offenders:?}"
|
|
);
|
|
}
|
|
|
|
fn walk(dir: &std::path::Path, offenders: &mut Vec<String>) {
|
|
let entries = match std::fs::read_dir(dir) {
|
|
Ok(entries) => entries,
|
|
Err(_) => return,
|
|
};
|
|
for entry in entries.flatten() {
|
|
let path = entry.path();
|
|
if path.is_dir() {
|
|
walk(&path, offenders);
|
|
} else if path.extension().is_some_and(|e| e == "rs") {
|
|
let contents = match std::fs::read_to_string(&path) {
|
|
Ok(c) => c,
|
|
Err(_) => continue,
|
|
};
|
|
for (line_no, line) in contents.lines().enumerate() {
|
|
if line.contains("not_implemented") {
|
|
offenders.push(format!(
|
|
"{}:{}",
|
|
path.strip_prefix(env!("CARGO_MANIFEST_DIR"))
|
|
.unwrap_or(&path)
|
|
.display(),
|
|
line_no + 1
|
|
));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|