Add GitHub noreply email alias to coilyco-ops bot #482

Open
opened 2026-07-08 19:22:31 +00:00 by coilyco-ops · 5 comments
Member

Goal

Add the GitHub noreply identity as an email alias for the coilyco-ops bot:

301460342+coilyco-ops[bot]@users.noreply.github.com

Context

This came up while cutting ward release/build plumbing across Forgejo + GitHub. The bot needs the GitHub noreply address associated with its account so commits, releases, or mirrored activity attributed with GitHub's bot noreply address can still resolve to the coilyco-ops bot identity where the forge supports email alias matching.

The durable home appears to be scripts/provision-coilyco-ops-bot.sh in infrastructure. It currently owns bot user creation/update, password reset, token minting, and SSM storage. It sets the primary email via BOT_EMAIL=coilyco-ops@coilysiren.me, but it does not manage secondary email aliases.

Do

  • Teach scripts/provision-coilyco-ops-bot.sh to add the GitHub noreply address above as an email alias for coilyco-ops, idempotently.
  • Keep coilyco-ops@coilysiren.me as the primary bot email unless the Forgejo API requires a different representation.
  • Use the least-privilege API path that works. If the bot can add its own email through the user email endpoint, prefer that. If only an admin endpoint works, use the same admin-token source this script already uses.
  • Verify the script handles reruns without failing when the alias already exists.
  • Update nearby docs or token-minting notes if the script's bot-account responsibilities change.
  • If the live account cannot be reconciled from a headless run because Forgejo requires interactive email verification or a human-admin-only action, leave the script change landed and file/record the exact manual step.

Validate

  • Run the script in dry-run/testable mode if one exists, or add focused tests/helpers for the alias API payload construction.
  • Confirm the live Forgejo account has 301460342+coilyco-ops[bot]@users.noreply.github.com listed as an email alias, or document the blocker precisely.

Filed from the read-only director surface.

## Goal Add the GitHub noreply identity as an email alias for the `coilyco-ops` bot: ```text 301460342+coilyco-ops[bot]@users.noreply.github.com ``` ## Context This came up while cutting ward release/build plumbing across Forgejo + GitHub. The bot needs the GitHub noreply address associated with its account so commits, releases, or mirrored activity attributed with GitHub's bot noreply address can still resolve to the coilyco-ops bot identity where the forge supports email alias matching. The durable home appears to be `scripts/provision-coilyco-ops-bot.sh` in infrastructure. It currently owns bot user creation/update, password reset, token minting, and SSM storage. It sets the primary email via `BOT_EMAIL=coilyco-ops@coilysiren.me`, but it does not manage secondary email aliases. ## Do * Teach `scripts/provision-coilyco-ops-bot.sh` to add the GitHub noreply address above as an email alias for `coilyco-ops`, idempotently. * Keep `coilyco-ops@coilysiren.me` as the primary bot email unless the Forgejo API requires a different representation. * Use the least-privilege API path that works. If the bot can add its own email through the user email endpoint, prefer that. If only an admin endpoint works, use the same admin-token source this script already uses. * Verify the script handles reruns without failing when the alias already exists. * Update nearby docs or token-minting notes if the script's bot-account responsibilities change. * If the live account cannot be reconciled from a headless run because Forgejo requires interactive email verification or a human-admin-only action, leave the script change landed and file/record the exact manual step. ## Validate * Run the script in dry-run/testable mode if one exists, or add focused tests/helpers for the alias API payload construction. * Confirm the live Forgejo account has `301460342+coilyco-ops[bot]@users.noreply.github.com` listed as an email alias, or document the blocker precisely. Filed from the read-only director surface.
Author
Member

🔒 Reserved by ward agent --harness claude — container engineer-claude-infrastructure-482 on host kais-macbook-pro-2.local is carrying this issue (reserved 2026-07-08T19:22:39Z). Concurrent ward agent runs are blocked until it finishes or the reservation goes stale (1h TTL); --force overrides.

Do not comment on or edit this issue to steer the run while it is reserved. The engineer seeded the body once at launch and never re-reads it, so a comment or edit reaches only human readers, never the running engineer. A correction goes to a new issue, dispatched fresh — that is the only channel that reaches a run in flight. Where the forge supports it, ward locks this conversation to make that a road-block rather than a convention (ward#494).

run seed context — what this run is carrying (ward#609)
  • Resolved: coilyco-flight-deck/infrastructure#482 · branch issue-482 · harness claude · workflow direct-main
  • Run: engineer-claude-infrastructure-482 · ward v0.463.0 · dispatched 2026-07-08T19:22:39Z
  • Comment thread: 0 included in the pre-flight read, 0 stripped (ward's own automated comments).

Static container doctrine and seed boilerplate are identical every run and omitted here (they ride ward v0.463.0).

— Claude (she/her), via ward agent

<!-- ward-agent-reservation --> 🔒 Reserved by `ward agent --harness claude` — container `engineer-claude-infrastructure-482` on host `kais-macbook-pro-2.local` is carrying this issue (reserved 2026-07-08T19:22:39Z). Concurrent `ward agent` runs are blocked until it finishes or the reservation goes stale (1h TTL); `--force` overrides. **Do not comment on or edit this issue to steer the run while it is reserved.** The engineer seeded the body once at launch and never re-reads it, so a comment or edit reaches only human readers, never the running engineer. A correction goes to a **new issue, dispatched fresh** — that is the only channel that reaches a run in flight. Where the forge supports it, ward locks this conversation to make that a road-block rather than a convention (ward#494). <details><summary>run seed context — what this run is carrying (ward#609)</summary> - **Resolved:** `coilyco-flight-deck/infrastructure#482` · branch `issue-482` · harness `claude` · workflow `direct-main` - **Run:** `engineer-claude-infrastructure-482` · ward `v0.463.0` · dispatched `2026-07-08T19:22:39Z` - **Comment thread:** 0 included in the pre-flight read, 0 stripped (ward's own automated comments). Static container doctrine and seed boilerplate are identical every run and omitted here (they ride ward v0.463.0). </details> <!-- ward-agent-signature --> — Claude (she/her), via `ward agent`
Author
Member

Correction from Kai after filing: this should not hardcode the full GitHub noreply alias. The GitHub bot identity is now represented by SSM config under /github/, including /github/coilyco-ops-user-id; consumers should derive <user-id>+coilyco-ops[bot]@users.noreply.github.com where needed.

The SSM inventory update is now tracked separately as coilyco-bridge/agentic-os-kai#720. This comment is for human readers only because this issue is already reserved and the running engineer does not re-read comments.

Correction from Kai after filing: this should not hardcode the full GitHub noreply alias. The GitHub bot identity is now represented by SSM config under `/github/`, including `/github/coilyco-ops-user-id`; consumers should derive `<user-id>+coilyco-ops[bot]@users.noreply.github.com` where needed. The SSM inventory update is now tracked separately as coilyco-bridge/agentic-os-kai#720. This comment is for human readers only because this issue is already reserved and the running engineer does not re-read comments.
Author
Member

WARD-RESERVATION: held 🔒

reservation details

Holder: container engineer-codex-infrastructure-482 on host kais-macbook-pro-2.local.

Reserved by ward agent --harness codex (reserved 2026-07-10T12:12:48Z). Concurrent ward agent runs are blocked until it finishes or the reservation goes stale (1h TTL). --force overrides.

Do not comment on or edit this issue to steer the run while it is reserved. The engineer seeded the body once at launch and never re-reads it, so a comment or edit reaches only human readers, never the running engineer. A correction goes to a new issue, dispatched fresh. That is the only channel that reaches a run in flight. Where the forge supports it, ward locks this conversation to make that a road-block rather than a convention (ward#494).

run seed context — what this run is carrying (ward#609)
  • Resolved: coilyco-flight-deck/infrastructure#482 · branch issue-482 · harness codex · workflow direct-main
  • Run: engineer-codex-infrastructure-482 · ward v0.580.0 · dispatched 2026-07-10T12:12:48Z
  • Comment thread: 1 included in the pre-flight read, 1 stripped (ward's own automated comments).

Static container doctrine and seed boilerplate are identical every run and omitted here (they ride ward v0.580.0).

— Codex, via ward agent

<!-- ward-agent-reservation --> WARD-RESERVATION: held 🔒 <details><summary>reservation details</summary> Holder: container `engineer-codex-infrastructure-482` on host `kais-macbook-pro-2.local`. Reserved by `ward agent --harness codex` (reserved 2026-07-10T12:12:48Z). Concurrent `ward agent` runs are blocked until it finishes or the reservation goes stale (1h TTL). `--force` overrides. **Do not comment on or edit this issue to steer the run while it is reserved.** The engineer seeded the body once at launch and never re-reads it, so a comment or edit reaches only human readers, never the running engineer. A correction goes to a **new issue, dispatched fresh**. That is the only channel that reaches a run in flight. Where the forge supports it, ward locks this conversation to make that a road-block rather than a convention (ward#494). <details><summary>run seed context — what this run is carrying (ward#609)</summary> - **Resolved:** `coilyco-flight-deck/infrastructure#482` · branch `issue-482` · harness `codex` · workflow `direct-main` - **Run:** `engineer-codex-infrastructure-482` · ward `v0.580.0` · dispatched `2026-07-10T12:12:48Z` - **Comment thread:** 1 included in the pre-flight read, 1 stripped (ward's own automated comments). - included: @coilyco-ops (2026-07-08T19:25:22Z) - stripped: @coilyco-ops (2026-07-08T19:22:41Z) Static container doctrine and seed boilerplate are identical every run and omitted here (they ride ward v0.580.0). </details> </details> <!-- ward-agent-signature --> — Codex, via `ward agent`
Author
Member

WARD-OUTCOME: done

details workflow: direct-main; review summary: review gate skipped by ~/.ward/config.yaml default felt: straightforward. the merge only needed one upstream token-family conflict. confidence: medium-high surprises: the live Forgejo token in this container can read `coilyco-ops` but lacks `write:user`, so the alias add itself is still blocked here. follow-ups: run the alias add once a `write:user` credential or the bot password is available, then rerun `scripts/provision-coilyco-ops-bot.sh` to confirm `/api/v1/user/emails`.
WARD-OUTCOME: done <details><summary>details</summary> workflow: direct-main; review summary: review gate skipped by ~/.ward/config.yaml default felt: straightforward. the merge only needed one upstream token-family conflict. confidence: medium-high surprises: the live Forgejo token in this container can read `coilyco-ops` but lacks `write:user`, so the alias add itself is still blocked here. follow-ups: run the alias add once a `write:user` credential or the bot password is available, then rerun `scripts/provision-coilyco-ops-bot.sh` to confirm `/api/v1/user/emails`. </details>
Author
Member

Live reconciliation was retried on 2026-07-15 from the infrastructure repo without using the site-admin token path. The existing bot password from SSM can read /api/v1/user/emails, so auth is not the current blocker.\n\nThe add call fails with HTTP 422 because Forgejo rejects the derived GitHub App noreply address as an invalid email. The rejected address was the SSM-derived coilyco-ops GitHub App bot noreply form, redacted in local output as .\n\nThat means the remaining blocker is Forgejo email validation for the GitHub App bot local part containing [bot], not just missing write:user scope. The script still has the right derivation logic, but the live alias cannot be reconciled through /api/v1/user/emails as written.

Live reconciliation was retried on 2026-07-15 from the infrastructure repo without using the site-admin token path. The existing bot password from SSM can read /api/v1/user/emails, so auth is not the current blocker.\n\nThe add call fails with HTTP 422 because Forgejo rejects the derived GitHub App noreply address as an invalid email. The rejected address was the SSM-derived coilyco-ops GitHub App bot noreply form, redacted in local output as <github-bot-noreply-alias>.\n\nThat means the remaining blocker is Forgejo email validation for the GitHub App bot local part containing [bot], not just missing write:user scope. The script still has the right derivation logic, but the live alias cannot be reconciled through /api/v1/user/emails as written.
Sign in to join this conversation.
No description provided.