<feed xmlns='http://www.w3.org/2005/Atom'>
<title>npub1tkq8unhsd5jqx6ueex5lcpsgknrpquxuk44ftpjlpm3ulaake7xs76txrw/ngit-grasp-mirror/tests, branch v1.0.2</title>
<subtitle>Unnamed repository; edit this file 'description' to name the repository.
</subtitle>
<id>https://upleb.uk/npub1tkq8unhsd5jqx6ueex5lcpsgknrpquxuk44ftpjlpm3ulaake7xs76txrw/ngit-grasp-mirror/atom?h=v1.0.2</id>
<link rel='self' href='https://upleb.uk/npub1tkq8unhsd5jqx6ueex5lcpsgknrpquxuk44ftpjlpm3ulaake7xs76txrw/ngit-grasp-mirror/atom?h=v1.0.2'/>
<link rel='alternate' type='text/html' href='https://upleb.uk/npub1tkq8unhsd5jqx6ueex5lcpsgknrpquxuk44ftpjlpm3ulaake7xs76txrw/ngit-grasp-mirror/'/>
<updated>2026-02-26T15:42:09+00:00</updated>
<entry>
<title>chore: apply cargo fmt and fix clippy warnings</title>
<updated>2026-02-26T15:42:09+00:00</updated>
<author>
<name>DanConwayDev</name>
<email>DanConwayDev@protonmail.com</email>
</author>
<published>2026-02-26T15:42:09+00:00</published>
<link rel='alternate' type='text/html' href='https://upleb.uk/npub1tkq8unhsd5jqx6ueex5lcpsgknrpquxuk44ftpjlpm3ulaake7xs76txrw/ngit-grasp-mirror/commit/?id=9d86cf15f0275ffeee4519bd054e3b61dc8992ac'/>
<id>urn:sha1:9d86cf15f0275ffeee4519bd054e3b61dc8992ac</id>
<content type='text'>
Fix pre-existing clippy lints:
- &amp;PathBuf -&gt; &amp;Path in audit_cleanup.rs
- too_many_arguments on process_newly_available_git_data,
  process_purgatory_announcements, and HttpService::new
- clone_on_copy for PublicKey (Copy type) in purgatory cleanup loop
</content>
</entry>
<entry>
<title>Merge master into 3ca0-announcements-purgatory</title>
<updated>2026-02-23T15:20:59+00:00</updated>
<author>
<name>DanConwayDev</name>
<email>DanConwayDev@protonmail.com</email>
</author>
<published>2026-02-23T15:20:59+00:00</published>
<link rel='alternate' type='text/html' href='https://upleb.uk/npub1tkq8unhsd5jqx6ueex5lcpsgknrpquxuk44ftpjlpm3ulaake7xs76txrw/ngit-grasp-mirror/commit/?id=113928aa84894ea8f65c247d9987527e792b32a9'/>
<id>urn:sha1:113928aa84894ea8f65c247d9987527e792b32a9</id>
<content type='text'>
</content>
</entry>
<entry>
<title>persist and restore announcement events across graceful restarts</title>
<updated>2026-02-23T15:08:37+00:00</updated>
<author>
<name>DanConwayDev</name>
<email>DanConwayDev@protonmail.com</email>
</author>
<published>2026-02-23T15:08:37+00:00</published>
<link rel='alternate' type='text/html' href='https://upleb.uk/npub1tkq8unhsd5jqx6ueex5lcpsgknrpquxuk44ftpjlpm3ulaake7xs76txrw/ngit-grasp-mirror/commit/?id=26f608e5011b9d1ad6036da75b89272835e69695'/>
<id>urn:sha1:26f608e5011b9d1ad6036da75b89272835e69695</id>
<content type='text'>
Extends purgatory persistence to include announcement purgatory entries.
On graceful shutdown, non-soft-expired announcements are serialised to
purgatory-state.json alongside state/PR/expired events; on startup they
are restored, skipping any entry whose bare repo path no longer exists.

Updates purgatory-design.md to reflect that purgatory persists through
graceful shutdown and documents the new PurgatoryState disk format.

Adds create_announcement_event helper to purgatory_helpers and three new
integration tests in purgatory_persistence covering the full save/restore
cycle, missing-repo skip, and the combined roundtrip with all entry types.
</content>
</entry>
<entry>
<title>fix: rewrite deletion integration tests to avoid shared-state side effects</title>
<updated>2026-02-23T13:42:57+00:00</updated>
<author>
<name>DanConwayDev</name>
<email>DanConwayDev@protonmail.com</email>
</author>
<published>2026-02-23T13:42:57+00:00</published>
<link rel='alternate' type='text/html' href='https://upleb.uk/npub1tkq8unhsd5jqx6ueex5lcpsgknrpquxuk44ftpjlpm3ulaake7xs76txrw/ngit-grasp-mirror/commit/?id=0c71e191963bec729c3ca13c212b231af7582f06'/>
<id>urn:sha1:0c71e191963bec729c3ca13c212b231af7582f06</id>
<content type='text'>
The previous tests deleted purgatory announcements (kind 30617) and checked
for bare-repo absence via git ls-remote, which would corrupt shared-mode
test state by destroying repos other tests depend on.

New approach tests deletion of purgatory state events (kind 30618) instead:

- e-tag test: promotes a repo, creates a unique commit locally, submits a
  state event pointing to it (enters purgatory), deletes the state event by
  event ID, then verifies git push of that commit is rejected.

- a-tag coordinate test: promotes a repo, generates a fresh maintainer
  keypair, sends a replacement announcement adding that maintainer, submits
  a state event signed by the new maintainer (enters purgatory), deletes by
  coordinate 30618:&lt;new_maintainer_pubkey&gt;:&lt;identifier&gt;, then verifies git
  push is rejected.

Also extends DeletionPolicy to handle kind 30618 state events in purgatory
for both e-tag (event ID) and a-tag (coordinate) deletion paths.
</content>
</entry>
<entry>
<title>feat: remove purgatory announcements on NIP-09 deletion events</title>
<updated>2026-02-23T13:29:47+00:00</updated>
<author>
<name>DanConwayDev</name>
<email>DanConwayDev@protonmail.com</email>
</author>
<published>2026-02-23T13:29:47+00:00</published>
<link rel='alternate' type='text/html' href='https://upleb.uk/npub1tkq8unhsd5jqx6ueex5lcpsgknrpquxuk44ftpjlpm3ulaake7xs76txrw/ngit-grasp-mirror/commit/?id=65ac6ef83205c41653e6ffe2acd664f968926fb2'/>
<id>urn:sha1:65ac6ef83205c41653e6ffe2acd664f968926fb2</id>
<content type='text'>
Kind 5 deletion events signed by the announcement author now evict the
corresponding purgatory entry and delete the bare repository from disk.

Both NIP-09 reference styles are supported:
- e tag (event ID): matches the purgatory entry whose event ID equals the tag value
- a tag (coordinate 30617:&lt;pubkey&gt;:&lt;identifier&gt;): matches by coordinate, only
  removes entries with created_at &lt;= deletion event created_at per NIP-09 spec

Author-only enforcement: coordinate pubkey and e-tag owner must match the
deletion event pubkey; third-party deletion attempts are silently ignored.

Includes 6 unit tests and 2 integration tests (event ID and coordinate paths).
</content>
</entry>
<entry>
<title>refactor: replace inline purgatory sync registration with timer-only approach</title>
<updated>2026-02-23T12:48:26+00:00</updated>
<author>
<name>DanConwayDev</name>
<email>DanConwayDev@protonmail.com</email>
</author>
<published>2026-02-23T12:48:26+00:00</published>
<link rel='alternate' type='text/html' href='https://upleb.uk/npub1tkq8unhsd5jqx6ueex5lcpsgknrpquxuk44ftpjlpm3ulaake7xs76txrw/ngit-grasp-mirror/commit/?id=f62ef12fb84e2210f9a0a67a5e1e574a8ee66c16'/>
<id>urn:sha1:f62ef12fb84e2210f9a0a67a5e1e574a8ee66c16</id>
<content type='text'>
Remove the redundant inline kind-30617 registration block from the sync
event loop and the three is_generic/recompute_new_sync_filters_for_relay
calls from confirm_batch error paths. The purgatory announcement sync
timer (run_purgatory_announcement_sync) is now the sole registration path.

Consolidate NGIT_SYNC_BATCH_WINDOW_MS and NGIT_PURGATORY_SYNC_INTERVAL_MS
into a single NGIT_TEST=1 flag that sets both timers to 200ms, replacing
two ad-hoc env vars with one reusable test-mode flag.
</content>
</entry>
<entry>
<title>fix: re-process hot-cache maintainer announcements after git push promotion</title>
<updated>2026-02-23T12:05:29+00:00</updated>
<author>
<name>DanConwayDev</name>
<email>DanConwayDev@protonmail.com</email>
</author>
<published>2026-02-23T11:17:10+00:00</published>
<link rel='alternate' type='text/html' href='https://upleb.uk/npub1tkq8unhsd5jqx6ueex5lcpsgknrpquxuk44ftpjlpm3ulaake7xs76txrw/ngit-grasp-mirror/commit/?id=70749ea9df1f6061c332112c617b615f91d79d48'/>
<id>urn:sha1:70749ea9df1f6061c332112c617b615f91d79d48</id>
<content type='text'>
When an owner announcement is promoted from purgatory via a git push,
any maintainer announcements sitting in the rejected_events_index hot
cache were never re-processed. The invalidate_and_get call only existed
in SyncManager::process_event_static (the nostr sync path); the git push
promotion path (http -&gt; handlers -&gt; git::sync) had no access to the
rejected_events_index at all.

Thread rejected_events_index and write_policy through the git push path:
- process_purgatory_announcements: after saving the promoted announcement,
  parse its maintainers tag and call invalidate_and_get() for each, then
  re-process any returned hot-cache events via admit_event + save
- process_newly_available_git_data: accept optional write_policy and
  rejected_events_index, pass them through to process_purgatory_announcements
- handle_receive_pack: accept Arc&lt;Nip34WritePolicy&gt; and
  Arc&lt;RejectedEventsIndex&gt;, pass them to process_newly_available_git_data
- HttpService / run_server: carry the two new fields, clone into each
  handle_receive_pack call
- main.rs: obtain rejected_events_index from sync_manager before moving
  it into its task; wrap write_policy in Arc for the HTTP server
- RealSyncContext::process_newly_available_git_data: pass None for both
  new params (purgatory sync path already handles this via
  SyncManager::process_event_static)

Also rewrite the maintainer_reprocessing integration tests to correctly
exercise the hot-cache path now that announcements require git data
before being released from purgatory:
- Start relay_b with relay_a as bootstrap so its SyncManager syncs
  maintainer announcements via negentropy before the owner git push
- Use push_unique_git_data_to_relay (new helper) to give each maintainer
  a distinct commit hash, preventing git from skipping pack transfer
- Make wait_for_event_on_relay poll in a retry loop so transient timing
  gaps between DB write and query do not cause false negatives
</content>
</entry>
<entry>
<title>remove recursive relay discovery test</title>
<updated>2026-02-23T12:05:07+00:00</updated>
<author>
<name>DanConwayDev</name>
<email>DanConwayDev@protonmail.com</email>
</author>
<published>2026-02-23T09:22:41+00:00</published>
<link rel='alternate' type='text/html' href='https://upleb.uk/npub1tkq8unhsd5jqx6ueex5lcpsgknrpquxuk44ftpjlpm3ulaake7xs76txrw/ngit-grasp-mirror/commit/?id=9f15929b10825c2f55434a98794fc551794cad2b'/>
<id>urn:sha1:9f15929b10825c2f55434a98794fc551794cad2b</id>
<content type='text'>
Recursive discovery relied on announcement events being gossiped across
relays regardless of whether they listed the service. Now that
announcements enter purgatory until state event and git data arrive,
cross-relay discovery cannot be triggered by a synced announcement alone,
making the three-relay recursive discovery scenario impossible.
</content>
</entry>
<entry>
<title>test: update sync tests to set up git data for purgatory flow</title>
<updated>2026-02-23T12:05:05+00:00</updated>
<author>
<name>DanConwayDev</name>
<email>DanConwayDev@protonmail.com</email>
</author>
<published>2026-02-18T23:17:08+00:00</published>
<link rel='alternate' type='text/html' href='https://upleb.uk/npub1tkq8unhsd5jqx6ueex5lcpsgknrpquxuk44ftpjlpm3ulaake7xs76txrw/ngit-grasp-mirror/commit/?id=49b9405dfcbb872686acdd7abc12dc9c94adc2ab'/>
<id>urn:sha1:49b9405dfcbb872686acdd7abc12dc9c94adc2ab</id>
<content type='text'>
All sync tests now create a local git repo, send announcement + state
event to the source relay, and push git data to release both from
purgatory before the syncing relay starts bootstrap sync.
</content>
</entry>
<entry>
<title>test: update run_sync_test to use push_to_relay for purgatory flow</title>
<updated>2026-02-18T22:56:13+00:00</updated>
<author>
<name>DanConwayDev</name>
<email>DanConwayDev@protonmail.com</email>
</author>
<published>2026-02-18T22:56:13+00:00</published>
<link rel='alternate' type='text/html' href='https://upleb.uk/npub1tkq8unhsd5jqx6ueex5lcpsgknrpquxuk44ftpjlpm3ulaake7xs76txrw/ngit-grasp-mirror/commit/?id=63865548b07e44d69321af3b03ca2c29aa60d74d'/>
<id>urn:sha1:63865548b07e44d69321af3b03ca2c29aa60d74d</id>
<content type='text'>
Previously run_sync_test used a SmartGitServer external to the relay,
but never pushed to the source relay itself. With the announcement
purgatory feature, announcements stay in purgatory until git data
arrives. By using push_to_relay to the source relay, both the
announcement and state event are released from purgatory before
the syncing relay starts, allowing the announcement to be synced.
</content>
</entry>
</feed>
