Register the Forgejo webhook for Period on the Command Center #9

Closed
opened 2026-08-18 02:14:38 -05:00 by null · 1 comment
Owner

The repository is mapped to the Command Center, so its issue and milestone counts arrive on the periodic reconcile. The webhook is a separate step and it is silent when missing.

Without it:

  • tracker counts arrive a day late instead of within seconds of a push
  • an opened P0 raises no alert at all — it becomes news at the next sweep rather than at the moment it is filed

That second one is the reason this is an issue rather than a footnote. The failure is invisible: everything looks like it is working, just slowly, and nobody notices that the alerting half was never switched on.

What is needed, and why it is filed rather than done: the webhook URL and its secret are held by the Command Center and are not in any credential file on this machine that an agent can read. Registering it is POST /repos/null/Privacy-Period-Tracker/hooks once those two values are in hand, or the repository's Settings → Webhooks page.

Do not treat mapping the repository as having done this. They are different operations and only one of them is visible from the project screen.

Verify: curl -H "$H" "$BASE/repos/null/Privacy-Period-Tracker/hooks" lists a hook, its most recent delivery shows a 2xx response, and opening a test issue labelled P0 produces an alert rather than waiting for the next reconcile.

The repository is mapped to the Command Center, so its issue and milestone counts arrive on the periodic reconcile. **The webhook is a separate step and it is silent when missing.** Without it: - tracker counts arrive a day late instead of within seconds of a push - **an opened `P0` raises no alert at all** — it becomes news at the next sweep rather than at the moment it is filed That second one is the reason this is an issue rather than a footnote. The failure is invisible: everything looks like it is working, just slowly, and nobody notices that the alerting half was never switched on. What is needed, and why it is filed rather than done: the webhook URL and its secret are held by the Command Center and are not in any credential file on this machine that an agent can read. Registering it is `POST /repos/null/Privacy-Period-Tracker/hooks` once those two values are in hand, or the repository's Settings → Webhooks page. Do not treat mapping the repository as having done this. They are different operations and only one of them is visible from the project screen. Verify: `curl -H "$H" "$BASE/repos/null/Privacy-Period-Tracker/hooks"` lists a hook, its most recent delivery shows a 2xx response, and opening a test issue labelled `P0` produces an alert rather than waiting for the next reconcile.
null added this to the Batch 01 — Foundation milestone 2026-08-18 02:14:38 -05:00
Author
Owner

Registered. Hook id 3 on null/Privacy-Period-Tracker.

url:     https://privacyllc.dev/api/webhooks/forgejo
type:    forgejo    content_type: json    active: true
events:  push, issues, issue_assign, issue_label, issue_milestone, issue_comment

Config is byte-for-byte the payload the site's own src/lib/forgejo-write.ts
sends (references/api.md:172-186 of the privacyllc-webhook-listener skill).
The secret came from FORGEJO_WEBHOOK_SECRET in the credentials file; it is not
recorded here or anywhere in this repo.

Evidence it works

A signed replay against the live endpoint — troubleshooting step 8 — returned:

HTTP 200
{"ok":true,"applied":true,"project":"Privacy: Period Tracker","correlationId":"2f9bc82b-bd80-46b6-92e8-b4741383f182"}

That single response proves four things at once: the endpoint is live (not the
503 not_configured it returns with no secret set), the HMAC matches (it returns
401 on a bad signature and never accepts unsigned deliveries), the repo is
mapped to a project — "project":"Privacy: Period Tracker" — so tracker
refreshes are not silently dropped for a null projectId, and the event applied.

The probe used refs/heads/webhook-registration-check with zero commits on
purpose: only non-empty default-branch pushes stamp last_verified_at, so
this could not falsely mark the project as verified.

What it now does

  • issues opened with P0 → immediate alert on every carried transport,
    instead of the P0 sitting unannounced until the next sweep. This was the whole
    reason for the issue.
  • issues any action → tracker report refreshed within seconds.
  • push to main → stamps projects.last_verified_at, so the verified date
    on the project screen is real rather than stale.

Payloads are SHA-256 hashed and discarded — only counts, identifiers and the
action reach the activity log, never issue titles or commit messages. That
matters for this repo in particular.

One deviation from the documented event set, deliberate

The skill says the site registers push, issues, milestone. This Forgejo
has no standalone milestone repo-hook event
— it accepts the POST, drops the
name, and expands issues into its sub-events. Confirmed twice: on create, and
on a PATCH explicitly re-sending milestone, which returned the same list.
null/PrivacyLLC-Web's hook (id 1, 17 events) has no milestone either, so the
site's own registration path hits this too.

Practical effect is small: issue_milestone still fires when an issue moves in
or out of a batch, and every issues event refreshes the tracker regardless. The
only uncovered case is opening or closing a milestone with no issue activity
attached, which the daily reconcile still catches.

Registered. Hook id **3** on `null/Privacy-Period-Tracker`. ``` url: https://privacyllc.dev/api/webhooks/forgejo type: forgejo content_type: json active: true events: push, issues, issue_assign, issue_label, issue_milestone, issue_comment ``` Config is byte-for-byte the payload the site's own `src/lib/forgejo-write.ts` sends (`references/api.md:172-186` of the `privacyllc-webhook-listener` skill). The secret came from `FORGEJO_WEBHOOK_SECRET` in the credentials file; it is not recorded here or anywhere in this repo. ### Evidence it works A signed replay against the live endpoint — troubleshooting step 8 — returned: ``` HTTP 200 {"ok":true,"applied":true,"project":"Privacy: Period Tracker","correlationId":"2f9bc82b-bd80-46b6-92e8-b4741383f182"} ``` That single response proves four things at once: the endpoint is live (not the 503 `not_configured` it returns with no secret set), the HMAC matches (it returns 401 on a bad signature and never accepts unsigned deliveries), the repo **is** mapped to a project — `"project":"Privacy: Period Tracker"` — so tracker refreshes are not silently dropped for a null `projectId`, and the event applied. The probe used `refs/heads/webhook-registration-check` with zero commits on purpose: only non-empty **default-branch** pushes stamp `last_verified_at`, so this could not falsely mark the project as verified. ### What it now does - **`issues` opened with `P0`** → immediate alert on every carried transport, instead of the P0 sitting unannounced until the next sweep. This was the whole reason for the issue. - **`issues` any action** → tracker report refreshed within seconds. - **push to `main`** → stamps `projects.last_verified_at`, so the verified date on the project screen is real rather than stale. Payloads are SHA-256 hashed and discarded — only counts, identifiers and the action reach the activity log, never issue titles or commit messages. That matters for this repo in particular. ### One deviation from the documented event set, deliberate The skill says the site registers `push`, `issues`, `milestone`. **This Forgejo has no standalone `milestone` repo-hook event** — it accepts the POST, drops the name, and expands `issues` into its sub-events. Confirmed twice: on create, and on a `PATCH` explicitly re-sending `milestone`, which returned the same list. `null/PrivacyLLC-Web`'s hook (id 1, 17 events) has no `milestone` either, so the site's own registration path hits this too. Practical effect is small: `issue_milestone` still fires when an issue moves in or out of a batch, and every `issues` event refreshes the tracker regardless. The only uncovered case is opening or closing a milestone with no issue activity attached, which the daily reconcile still catches.
null closed this issue 2026-08-19 01:55:50 -05:00
Sign in to join this conversation.
No Label
P0
P1
P2
release-blocker
No project
No Assignees
1 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: null/Privacy-Period-Tracker#9
No description provided.