<feed xmlns='http://www.w3.org/2005/Atom'>
<title>npub1tkq8unhsd5jqx6ueex5lcpsgknrpquxuk44ftpjlpm3ulaake7xs76txrw/ngit-grasp-mirror/src/git/handlers.rs, branch master</title>
<subtitle>Unnamed repository; edit this file 'description' to name the repository.
</subtitle>
<id>https://upleb.uk/npub1tkq8unhsd5jqx6ueex5lcpsgknrpquxuk44ftpjlpm3ulaake7xs76txrw/ngit-grasp-mirror/atom?h=master</id>
<link rel='self' href='https://upleb.uk/npub1tkq8unhsd5jqx6ueex5lcpsgknrpquxuk44ftpjlpm3ulaake7xs76txrw/ngit-grasp-mirror/atom?h=master'/>
<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>send auth rejection reason to git client via ERR pkt-line</title>
<updated>2026-02-26T12:19:31+00:00</updated>
<author>
<name>DanConwayDev</name>
<email>DanConwayDev@protonmail.com</email>
</author>
<published>2026-02-26T12:19:06+00:00</published>
<link rel='alternate' type='text/html' href='https://upleb.uk/npub1tkq8unhsd5jqx6ueex5lcpsgknrpquxuk44ftpjlpm3ulaake7xs76txrw/ngit-grasp-mirror/commit/?id=b13c6d924f7de5ff34405254b8bb21adf33c78c0'/>
<id>urn:sha1:b13c6d924f7de5ff34405254b8bb21adf33c78c0</id>
<content type='text'>
Previously push auth failures returned HTTP 403 which git clients
display as a generic transport error. Now they return HTTP 200 with
an ERR pkt-line containing the rejection reason (e.g. 'authorisation
failed: No state events in purgatory'), which git displays directly.

Remove GitError::Unauthorized as it is no longer used. GitError
variants now represent only transport/infrastructure failures; app-level
rejections use ERR pkt-line responses.
</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>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>Revert "feat: upgrade repo to Full sync and trigger PR event subscription after announcement promotion"</title>
<updated>2026-02-18T19:28:28+00:00</updated>
<author>
<name>DanConwayDev</name>
<email>DanConwayDev@protonmail.com</email>
</author>
<published>2026-02-18T19:28:28+00:00</published>
<link rel='alternate' type='text/html' href='https://upleb.uk/npub1tkq8unhsd5jqx6ueex5lcpsgknrpquxuk44ftpjlpm3ulaake7xs76txrw/ngit-grasp-mirror/commit/?id=3d9359d5ac0045fb93fd8732160e0de8413d6881'/>
<id>urn:sha1:3d9359d5ac0045fb93fd8732160e0de8413d6881</id>
<content type='text'>
This reverts commit d76003b629a4a03dba23a8a1c41da6e4ac4c30cf.
</content>
</entry>
<entry>
<title>feat: upgrade repo to Full sync and trigger PR event subscription after announcement promotion</title>
<updated>2026-02-18T17:12:17+00:00</updated>
<author>
<name>DanConwayDev</name>
<email>DanConwayDev@protonmail.com</email>
</author>
<published>2026-02-18T17:12:17+00:00</published>
<link rel='alternate' type='text/html' href='https://upleb.uk/npub1tkq8unhsd5jqx6ueex5lcpsgknrpquxuk44ftpjlpm3ulaake7xs76txrw/ngit-grasp-mirror/commit/?id=d76003b629a4a03dba23a8a1c41da6e4ac4c30cf'/>
<id>urn:sha1:d76003b629a4a03dba23a8a1c41da6e4ac4c30cf</id>
<content type='text'>
When git data arrives for a purgatory announcement and promotes it to the
database, the relay now:

1. Upgrades the announcement's sync level in RepoSyncIndex from StateOnly
   to Full (git/sync.rs: process_purgatory_announcements)
2. Sends AddFilters actions to SyncManager for all connected relays, using
   Full sync filters (Layer 2 #a/#A/#q) to subscribe to PR events
   (purgatory/sync/context.rs: RealSyncContext.process_newly_available_git_data)
3. For user-submitted purgatory announcements, registers the repo in
   RepoSyncIndex with StateOnly level and sends AddFilters to SyncManager
   so it discovers and connects to relays listed in the announcement tags
   (nostr/builder.rs: handle_announcement AcceptPurgatory path)

The RealSyncContext now accepts optional repo_sync_index and sync_action_tx
parameters. main.rs wires these up from SyncManager. PolicyContext gains
repo_sync_index and sync_action_tx fields for the write policy path.
</content>
</entry>
<entry>
<title>Add error logging to all git handler IO operations</title>
<updated>2026-02-03T22:00:31+00:00</updated>
<author>
<name>DanConwayDev</name>
<email>DanConwayDev@protonmail.com</email>
</author>
<published>2026-02-03T22:00:31+00:00</published>
<link rel='alternate' type='text/html' href='https://upleb.uk/npub1tkq8unhsd5jqx6ueex5lcpsgknrpquxuk44ftpjlpm3ulaake7xs76txrw/ngit-grasp-mirror/commit/?id=22d93ea5e707e99d67ab367d60c7a9d867b7665c'/>
<id>urn:sha1:22d93ea5e707e99d67ab367d60c7a9d867b7665c</id>
<content type='text'>
Previously, some IO errors in git handlers were logged while others were
not, leading to inconsistent observability. Additionally, the HTTP layer
logged all git errors redundantly, adding no useful context beyond what
was already logged at the source.

Changes:
- Add error logging to all previously unlogged IO operations in
  handle_upload_pack and handle_receive_pack (stdin writes, stdout/stderr
  reads, process waits)
- Remove redundant error logging at HTTP layer since all errors are now
  logged at their source with full context
- Ensures consistent error-level logging for all git subprocess failures

This provides complete observability of git operations while eliminating
duplicate log entries that don't add value.
</content>
</entry>
<entry>
<title>feat: add diagnostic logging for partial state event matches</title>
<updated>2026-02-03T21:41:19+00:00</updated>
<author>
<name>DanConwayDev</name>
<email>DanConwayDev@protonmail.com</email>
</author>
<published>2026-02-03T21:21:33+00:00</published>
<link rel='alternate' type='text/html' href='https://upleb.uk/npub1tkq8unhsd5jqx6ueex5lcpsgknrpquxuk44ftpjlpm3ulaake7xs76txrw/ngit-grasp-mirror/commit/?id=d392f0bc14bcd687e918d4653ae016226496b4c4'/>
<id>urn:sha1:d392f0bc14bcd687e918d4653ae016226496b4c4</id>
<content type='text'>
Improves observability when pushes are rejected due to state events that
only partially match the pushed refs. Previously, logs only showed 'No
state event found' even when state events existed but didn't match.

Changes:
- Add diagnose_state_mismatch() to explain why state events don't match
- Log specific reasons: missing refs, wrong SHAs, or extra refs
- Update rejection message to 'No matching state event found' (more accurate)
- Add 4 unit tests for diagnostic function

Example diagnostic output:
  WARN State event abc123 from authorized author doesn't match push:
       refs/heads/main missing (state declares 9cc3d93b)

This addresses the issue where a push with only refs/heads/test was
rejected because the state event also declared refs/heads/main, but
logs didn't explain why the match failed.
</content>
</entry>
<entry>
<title>fix: return HTTP 200 with ERR pkt-line for git protocol errors</title>
<updated>2026-01-27T20:38:25+00:00</updated>
<author>
<name>DanConwayDev</name>
<email>DanConwayDev@protonmail.com</email>
</author>
<published>2026-01-27T19:43:41+00:00</published>
<link rel='alternate' type='text/html' href='https://upleb.uk/npub1tkq8unhsd5jqx6ueex5lcpsgknrpquxuk44ftpjlpm3ulaake7xs76txrw/ngit-grasp-mirror/commit/?id=3a7fa1d1288c28eae0ee58b4c448c672ec3b69c2'/>
<id>urn:sha1:3a7fa1d1288c28eae0ee58b4c448c672ec3b69c2</id>
<content type='text'>
Previously, all git upload-pack/receive-pack failures returned HTTP 500,
but the git smart HTTP protocol requires protocol-level errors (like
"not our ref") to be returned as HTTP 200 OK with an ERR pkt-line in
the response body.

Changes:
- Add build_git_protocol_error_response() to create HTTP 200 responses
  with properly formatted ERR pkt-line ("ERR &lt;message&gt;\n")
- Add is_git_protocol_error() to detect protocol errors (exit code 128
  with stderr content) vs transport errors
- Update handle_upload_pack() and handle_receive_pack() to return
  protocol errors as HTTP 200 with ERR pkt-line
- Keep HTTP 500 for actual transport errors (spawn failures, I/O errors,
  signals)

This allows git clients to properly parse and display protocol error
messages instead of seeing generic HTTP 500 errors.
</content>
</entry>
<entry>
<title>Add Git protocol v2 support to fix modern git client compatibility</title>
<updated>2026-01-07T21:35:56+00:00</updated>
<author>
<name>DanConwayDev</name>
<email>DanConwayDev@protonmail.com</email>
</author>
<published>2026-01-07T21:35:56+00:00</published>
<link rel='alternate' type='text/html' href='https://upleb.uk/npub1tkq8unhsd5jqx6ueex5lcpsgknrpquxuk44ftpjlpm3ulaake7xs76txrw/ngit-grasp-mirror/commit/?id=457e296d90e2f7c2808e216f2ef0608b70f76553'/>
<id>urn:sha1:457e296d90e2f7c2808e216f2ef0608b70f76553</id>
<content type='text'>
Modern git clients (2.51.0+) default to protocol v2 and send the
Git-Protocol header. The server must pass this to git processes via
the GIT_PROTOCOL environment variable for proper negotiation.

Changes:
- Extract Git-Protocol header in HTTP layer (src/http/mod.rs)
- Pass git_protocol parameter through all handler functions
- Set GIT_PROTOCOL env var when spawning git subprocesses
- Update all tests to pass None for backward compatibility

This fixes hangs/timeouts when modern git clients connect to the server.

Fixes issue discovered in work/2025-01-07-pr-clone-tag-sync-investigation.md
</content>
</entry>
</feed>
