Extracts sighting profile/message/read-pointer records from captured .har archives and pushes them to platform-privacy-scan-api's ingest route
| Tier | tools |
| Role | tooling |
| Path | crates/tools/sighting-ingest |
| Edition | 2021 |
| Targets | chat-drive, chat-record, har-request, media-session, page-probe, tools-sighting-ingest, ws-probe, ws-tap, tools_sighting_ingest |
| Public items | 19 across 0 modules |
| Tests | 56 |
What it is for
Extraction of sightings records from captured .har archives.
Lifted from infrastructure-har/examples/push_sniffies.rs (sprint 3.129), which was an example invoked by hand — rule 14: the repeatable step is a program, tested, not a remembered cargo run --example line. The parsing shapes are that example's, unchanged where they were right; what changed is stated in the sprint doc.
Site-specific by construction: these are sniffies.com's endpoint shapes. The records this module emits are the normalized shape platform-privacy-scan-api's /api/sightings/ingest accepts, which knows nothing about any site.
Capabilities
crate root
Extraction of sightings records from captured .har archives.
| Item |
|---|
pub const MAX_RESPONSE_BYTES: usize |
pub const BATCH_ITEM_CAP: usize |
pub const ASSUMED_TYPING_CPM: u64 |
fn pace_before(chars : usize, gap_seconds : u64) -> std::time::Duration |
fn send_payload(site : & str, conversation_id : Option <& str>, user_id_to : & str, body : & str, file : Option <& str>,) -> Value |
fn send_verdict(status : u16, body : & str) -> Result <String, String> |
Endpoint
Extraction of sightings records from captured .har archives.
| Item |
|---|
pub enum Endpoint |
fn classify(method : & str, url : & str) -> Option <Endpoint> |
Extractor
Extraction of sightings records from captured .har archives.
| Item |
|---|
Extractor :: fn on_request(& mut self, _meta : EntryMeta <'_>, request : RequestView <'_>,) -> Result <EntryAction <Self::Response>, Self::Error> |
Findings
Extraction of sightings records from captured .har archives.
| Item |
|---|
pub struct Findings |
Findings :: fn absorb(& mut self, endpoint : Endpoint, body : & u8) |
Findings :: fn is_empty(& self) -> bool |
fn read_har(path : & std::path::Path, findings : & Rc <RefCell <Findings>>) -> Result <usize, String> |
fn batches(site : & str, findings : & Findings) -> Vec <Value> |
RawMessage
Extraction of sightings records from captured .har archives.
| Item |
|---|
pub struct RawMessage |
ReadPointer
Extraction of sightings records from captured .har archives.
| Item |
|---|
pub struct ReadPointer |
Sink
Extraction of sightings records from captured .har archives.
| Item |
|---|
Sink :: fn on_head(& mut self, head : ResponseHead <'_>) -> Result <HeadDecision, Self::Error> |
Sink :: fn on_body(& mut self, body : & u8) -> Result <(), Self::Error> |
Sink :: fn on_end(self, _outcome : ResponseOutcome) -> Result <(), Self::Error> |
How to use it
No examples/ target and no doctest in this crate's rustdoc. The tests listed under Verification are the closest executable usage.
Module structure
No public modules: the crate root is its whole surface.
Public surface
`crate root`
| Item | What it is |
|---|---|
pub enum Endpoint | The endpoints that carry profile, message, or read-pointer data |
fn classify(method : & str, url : & str) -> Option <Endpoint> | Which endpoint a request hit, or None to decline it |
pub struct RawMessage | — |
pub struct ReadPointer | One read pointer, in the shape /api/sightings/ingest accepts. |
pub struct Findings | Everything one or more captures yielded, deduplicated by natural key. |
Findings :: fn absorb(& mut self, endpoint : Endpoint, body : & u8) | Fold one response body into the findings |
Findings :: fn is_empty(& self) -> bool | — |
pub const MAX_RESPONSE_BYTES: usize | Gate 1.5.6 input limit |
Sink :: fn on_head(& mut self, head : ResponseHead <'_>) -> Result <HeadDecision, Self::Error> | — |
Sink :: fn on_body(& mut self, body : & u8) -> Result <(), Self::Error> | — |
Sink :: fn on_end(self, _outcome : ResponseOutcome) -> Result <(), Self::Error> | — |
Extractor :: fn on_request(& mut self, _meta : EntryMeta <'_>, request : RequestView <'_>,) -> Result <EntryAction <Self::Response>, Self::Error> | — |
fn read_har(path : & std::path::Path, findings : & Rc <RefCell <Findings>>) -> Result <usize, String> | Fold one .har into findings, returning how many entries the archive held. |
pub const BATCH_ITEM_CAP: usize | Under the ingest route's 500-item cap, with room to spare — the route counts profiles, messages and read pointers together. |
fn batches(site : & str, findings : & Findings) -> Vec <Value> | The ingest batches one findings set produces, each already under the route's cap |
pub const ASSUMED_TYPING_CPM: u64 | Characters a minute, used to price the pause in front of a message |
fn pace_before(chars : usize, gap_seconds : u64) -> std::time::Duration | How long to wait before sending a message of this length |
fn send_payload(site : & str, conversation_id : Option <& str>, user_id_to : & str, body : & str, file : Option <& str>,) -> Value | The POST /api/sightings/send request body |
fn send_verdict(status : u16, body : & str) -> Result <String, String> | What the server's answer means, as an outcome rather than a status code |
No pub use re-exports: every item above is declared in this crate.
Boundary
Reaches into infrastructure.
Shares tier tools with 84 other crates: tools-advisory-reach, tools-archive-guard, tools-artifact-scaffold, tools-ask-ai-core, tools-ask-ais, tools-ask-gemini, tools-book, tools-book-report, … (84 total).
_What this crate deliberately does NOT own is a judgment. No committed registry records one for it, so none is stated here._
Where it sits
| Tier (ontology) | tools |
| Architectural role (taxonomy) | tooling |
| Location | crates/tools/sighting-ingest |
| Vocabulary in force (lexicon) | current |
Tier flow. Which tiers this crate's own edges cross.
flowchart LR n_tools["tools"] --> n_infrastructure["infrastructure"]
Dependencies
Runtime, in this workspace.
| Crate | Tier | Optional | Only on |
|---|---|---|---|
| `infrastructure-browser-cdp` | infrastructure | no | always |
| `infrastructure-har` | infrastructure | no | always |
Runtime, from outside the workspace.
| Crate | Requirement | Features | Optional | Only on |
|---|---|---|---|---|
clap | ^4 | derive, env | no | always |
reqwest | ^0.12 | blocking, json | no | always |
serde | ^1 | derive | no | always |
serde_json | ^1 | — | no | always |
url | ^2 | — | no | always |
Development, in this workspace.
| Crate | Tier | Optional | Only on |
|---|---|---|---|
| `tools-cli-conformance` | tools | no | always |
Build. None.
Depended on by. Nothing in this workspace.
Signal flow — what reaches this crate, and what it reaches.
flowchart LR SELF["tools-sighting-ingest"] SELF -->|development| n_tools_cli_conformance["tools-cli-conformance"] SELF -->|runtime| n_infrastructure_browser_cdp["infrastructure-browser-cdp"] SELF -->|runtime| n_infrastructure_har["infrastructure-har"] classDef self fill:#1f883d,stroke:#1f883d,color:#fff; class SELF self;
Feature flags
No Cargo features are defined: every capability is unconditional, so no consumer can receive a half-wired crate.
Targets
| Kind | Name | Source |
|---|---|---|
| bin | chat-drive | `src/bin/chat-drive.rs` |
| bin | chat-record | `src/bin/chat-record.rs` |
| bin | har-request | `src/bin/har-request.rs` |
| bin | media-session | `src/bin/media-session.rs` |
| bin | page-probe | `src/bin/page-probe.rs` |
| bin | tools-sighting-ingest | `src/main.rs` |
| bin | ws-probe | `src/bin/ws-probe.rs` |
| bin | ws-tap | `src/bin/ws-tap.rs` |
| lib | tools_sighting_ingest | `src/lib.rs` |
Error model
No public error type was detected: no public item declares a type named *Error, and no public signature returns one.
Operational characteristics
| Property | Evidence |
|---|---|
| async public surface | none detected |
| async runtime | none detected |
| database access | none detected |
| network I/O | yes |
| unsafe code | none detected |
| environment variables | yes |
No unsafe block, unsafe fn, unsafe impl or unsafe trait was found by the parser anywhere in this crate's source.
Configuration
| Variable | Read in |
|---|---|
API_KEY | src/bin/media-session.rs |
CARGO_MANIFEST_DIR | src/bin/chat-drive.rs |
Related capabilities
No workspace crate depends on this one.
Verification
| Kind | Count |
|---|---|
| Unit tests | 56 |
| Integration tests | 0 |
| Examples | 0 |
| Doctests | 0 |
Evidence by module. How often each public module is named by something executable.
| Module | Tests | Examples | Consumers |
|---|---|---|---|
crate root | 13 | 0 | 0 |
What the tests establish, by name:
a_partial_second_still_costs_a_second—src/bin/chat-drive.rsa_thumbnail_is_found_by_its_token_and_never_by_its_place—src/bin/chat-drive.rsa_thumbnail_off_the_screen_does_not_count_as_found—src/bin/chat-drive.rsan_empty_message_takes_no_time_and_a_zero_rate_does_not_divide_by_zero—src/bin/chat-drive.rsboth_ways_the_site_draws_a_picture_are_searched—src/bin/chat-drive.rsthe_attribute_this_queries_is_one_the_overlay_actually_writes—src/bin/chat-drive.rsthe_click_reports_a_point_and_the_predicate_reports_a_boolean—src/bin/chat-drive.rsthe_dom_contract_uses_this_systems_own_vocabulary—src/bin/chat-drive.rstyping_time_is_the_messages_length_not_a_fixed_pause—src/bin/chat-drive.rsa_match_cannot_widen_past_the_site—src/bin/chat-record.rsa_match_narrows_to_one_tab_and_excludes_its_sibling—src/bin/chat-record.rsa_third_party_is_not_worth_recording—src/bin/chat-record.rsour_own_extension_and_server_are_never_recorded—src/bin/chat-record.rsthe_sites_own_pages_and_api_hosts_are—src/bin/chat-record.rsa_body_within_the_cap_is_printed_whole—src/bin/har-request.rsan_oversized_body_says_that_it_was_cut—src/bin/har-request.rsa_url_holding_a_quote_stays_a_string—src/bin/media-session.rsonly_the_two_asset_hosts_are_fetched_from—src/bin/media-session.rsa_short_quiet_spell_is_not_a_dead_attachment—src/bin/ws-tap.rssilence_past_the_limit_means_re_attach—src/bin/ws-tap.rsa_bridge_with_nobody_on_it_names_that_rather_than_a_status_code—src/lib.rsa_capture_without_a_login_names_no_account—src/lib.rsa_findings_set_under_the_cap_is_one_batch_per_kind—src/lib.rsa_first_contact_omits_the_conversation_rather_than_sending_an_empty_one—src/lib.rsa_local_id_says_so_and_a_site_id_does_not—src/lib.rsa_long_message_waits_longer_than_a_short_one—src/lib.rsa_lookalike_host_is_declined—src/lib.rsa_malformed_body_is_ignored_rather_than_discarding_the_capture—src/lib.rsa_refusal_inside_a_200_is_a_failure_not_a_send—src/lib.rsa_text_only_message_carries_no_file_key_at_all—src/lib.rs- _… 26 more_
Documentation coverage
| Measure | Documented | Total |
|---|---|---|
| Public items with rustdoc | 13 | 19 |
Public modules with a //! block | 0 | 0 |
pie showData
title Public items with rustdoc
"Documented" : 13
"No rustdoc detected" : 6
Metrics
| Metric | Value |
|---|---|
| Rust source files | 9 |
| Source lines | 4356 |
| Code lines | 3175 |
| Public API items | 19 |
| Public modules | 0 |
| Tests | 56 |
| Examples | 0 |
| Cargo features | 0 |
| Direct runtime dependencies | 7 |
| Workspace reverse dependencies | 0 |
pie showData
title Public API by kind
"constant" : 3
"enum" : 1
"function" : 6
"method" : 6
"struct" : 3
pie showData
title Rust source composition
"Code" : 3175
"Blank or comment" : 1181
Generation
Rendered by tools-corpus corpus readme from repository evidence alone, renderer schema 2, lexicon current. No model, network service or database was consulted. Regenerate with tools-corpus corpus readme --write; verify with --check.