{"record":{"id":"256c3226d1e0b5d2","repo":"block/buzz","slug":"project-announcement-timestamp-is-too-far-in-the-f","errorCode":null,"errorMessage":"project announcement timestamp is too far in the future","messagePattern":"project announcement timestamp is too far in the future","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/buzz-acp/src/lib.rs","lineNumber":1734,"sourceCode":"                anyhow::bail!(\"unsupported project announcement kind\");\n            }\n            if !template.tags.iter().any(|tag| {\n                tag.first().is_some_and(|value| value == \"d\")\n                    && tag.get(1).is_some_and(|value| !value.trim().is_empty())\n            }) {\n                anyhow::bail!(\"project announcement is missing its address\");\n            }\n            let tags = template\n                .tags\n                .into_iter()\n                .map(|tag| {\n                    nostr::Tag::parse(tag)\n                        .map_err(|error| anyhow::anyhow!(\"invalid project tag: {error}\"))\n                })\n                .collect::<Result<Vec<_>>>()?;\n            let created_at = template.created_at.unwrap_or(now);\n            if created_at > now.saturating_add(300) {\n                anyhow::bail!(\"project announcement timestamp is too far in the future\");\n            }\n            nostr::EventBuilder::new(nostr::Kind::Custom(template.kind), template.content)\n                .tags(tags)\n                .custom_created_at(nostr::Timestamp::from(created_at))\n                .sign_with_keys(keys)\n                .map_err(|error| anyhow::anyhow!(\"sign project announcement: {error}\"))\n        })\n        .collect()\n}\n\nfn emit_project_owner_control_result(\n    observer: Option<&observer::ObserverHandle>,\n    request_id: &str,\n    status: &str,\n    events: &[nostr::Event],\n    error: Option<String>,\n) {\n    let Some(observer) = observer else {","sourceCodeStart":1716,"sourceCodeEnd":1752,"githubUrl":"https://github.com/block/buzz/blob/dad5a33865fc81a2e55b3b60746632f615ec1e3a/crates/buzz-acp/src/lib.rs#L1716-L1752","documentation":"A project announcement's created_at (taken from the template, defaulting to now) must not be more than 300 seconds in the future. This guard prevents far-future timestamps, which would defeat relay last-write-wins ordering and pin the announcement forever.","triggerScenarios":"A template explicitly sets created_at more than now+300s, or the template's created_at was computed on a machine whose clock runs more than 5 minutes ahead of the harness host's clock.","commonSituations":"NTP drift on the workstation that authored the config; a CI pipeline with a skewed clock stamping generated templates; daylight-saving or timezone math bugs producing future timestamps.","solutions":["Remove created_at from the template so it defaults to the harness's current time","Or set created_at to a value at or before the moment the harness starts","Sync the machine that generates the config and the harness host with NTP"],"exampleFix":"# agent config\n# before\nproject_owner_announcements:\n  - kind: 30621\n    tags: [[\"d\", \"my-project\"]]\n    created_at: 4102444800\n# after\nproject_owner_announcements:\n  - kind: 30621\n    tags: [[\"d\", \"my-project\"]]\n    # created_at omitted -> defaults to now","handlingStrategy":"validation","validationCode":"// Preflight: reject templates whose created_at is more than 5 minutes ahead\nlet now = std::time::SystemTime::now()\n    .duration_since(std::time::UNIX_EPOCH)?.as_secs();\nif let Some(ts) = template.created_at {\n    if ts > now + 300 { anyhow::bail!(\"created_at {ts} is more than 300s ahead of host clock {now}\"); }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Omit created_at in generated templates and let the harness stamp now","Keep NTP enabled on machines that author or run agent configs; clock skew breaks all Nostr timestamp checks, not just this one"],"tags":["config","nostr","timestamp","clock-skew","validation","buzz-acp"],"backgroundTag":"timestamp-clock-skew","analyzedSha":"dad5a33865fc81a2e55b3b60746632f615ec1e3a","analyzedAt":"2026-08-20T04:38:24.874Z","contentChangedAt":"2026-08-20T04:38:24.874Z","schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}