Repository navigation
feat: log one invite_outcome event per invite branch - #9
Merged
Merged
Conversation
mroderick
force-pushed
the
log-invite-outcomes
branch
from
November 1, 2026 18:10
4587ea8 to
ddca3a1
Compare
mroderick
force-pushed
the
log-invite-outcomes
branch
from
November 1, 2026 20:56
a164f95 to
da2289b
Compare
Planning artifacts for additive structured logging of every POST /invite branch (see proposal.md). Investigation tails the planner#3069 incident: the unmapped Slack error branch returned a 200 page and logged nothing, hiding inviter_email_not_verified for weeks.
Implements the log-invite-outcomes openspec change. Every terminal branch of
POST /invite now emits `{ event: 'invite_outcome', outcome, detail,
slack_error }` in addition to the existing events:
- success invite: success/invited, no slack_error, no email in the payload
- already_invited / already_in_team: success with the Slack string kept
- invalid_email and any other ok:false reply: failure with the verbatim
slack_error, mapped or not
- missing_email, secrets_missing, verification_error, verification_failed,
slack_unreachable, unexpected_error: failure with a stable detail key
HTTP statuses and page text are unchanged. Log-assertion coverage lives in
test/logs.test.js, which drives the Worker through wrangler's
createTestHarness and asserts server.getLogs() per branch (the Workers
plugin runtime exposes no console capture; see tasks 0.1-0.2).
- The secrets_missing invite_outcome branch was unreachable in the logs suite (harness always seeded secrets) while tasks.md claimed it asserted; a second createTestHarness instance now boots with no secrets and pins exactly one failure/secrets_missing event on the fail-closed response. - The mapped-error fixture covered only already_invited; it.each now asserts already_in_team (success with the exact string) too. - The stay-quiet requirement had no automated check; the logs suite now asserts zero invite_outcome events for favicon and the join page request. - Slack replying ok:false without an error field produced an event with detail 'slack_error' but no slack_error field, contradicting the spec; the generic branch now falls back to a sentinel so the field is always present, with a fixture pinning it. - The PII guard ran only on the success event; expectSingleOutcome now checks every asserted event against the email that produced it. - tasks.md verification wording now names the real assertion paths.
mroderick
force-pushed
the
log-invite-outcomes
branch
from
November 1, 2026 20:59
da2289b to
ed1b07e
Compare
mroderick
marked this pull request as ready for review
November 1, 2026 20:59
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #3069 follow-up work identified during the planner#3069 investigation: the unmapped Slack error branch returned an HTTP 200 page and logged nothing, which hid
inviter_email_not_verified(a silent Slack platform change) while dashboards showed zero errors.Summary
log-invite-outcomesopenspec change: every terminalPOST /invitebranch emits one structured event,{ event: 'invite_outcome', outcome, detail, slack_error }, additive to the existing log events; HTTP statuses and page text unchanged.slack_erroralways carries the verbatim Slack string forok: falsereplies, mapped or not, so future Slack-side changes stay visible without a redeploy.already_invited/already_in_teamcount as success; failures use stabledetailkeys (missing_email,verification_error,verification_failed,secrets_missing,slack_unreachable,unexpected_error).test/logs.test.jsdrives the Worker through wrangler'screateTestHarnessand assertsserver.getLogs()per branch (the plugin runtime exposes no console capture). The node-side suites (createTestHarness + config-pin) run undervitest.harness.config.js/vitest.node.config.js, both wired intonpm test.Review notes
Schema-first reading
src/index.jslogOutcome()and its call sites: look for a terminal branch emitting nothing (would show as a failing logs-suite case), and confirm no branch passes user input into the event (PII check: the logs suite asserts the submitted email never appears in the success event).outcome(success/failure),detail(low-cardinality key),slack_error(verbatim string, present only onok: falsereplies). Changes to these keys would break the future dashboard grouping, prefer additive fields.Stacked on #8 (test-stack migration). Review that one first; this diff builds on it.
Deliberately not done