Show dated historical social shadow results in admin CLI - #215
Merged
Conversation
Greptile SummaryThis PR extends the administrative social-connections command with an optional, explicitly historical SHADOW evaluation while preserving existing machine-output contracts.
Confidence Score: 5/5The PR appears safe to merge with no outstanding correctness, security, or repository-rule violations. The added fields preserve nullability, human output escapes API-provided values, structured responses remain intact, and plain output retains its existing schema. The earlier terminal-walkthrough thread was manually resolved without explanation; the PR now includes the required before/after terminal recording.
|
| Filename | Overview |
|---|---|
| internal/cmd/admin/users/social_connections.go | Adds nullable historical SHADOW evaluation decoding and escaped human rendering without changing plain or structured output contracts. |
| internal/cmd/admin/users/social_shadow_test.go | Covers all output modes and distinguishes missing, null, zero, false, hostile, and absent field values. |
| skills/gumroad/SKILL.md | Documents the optional historical snapshot and clearly separates it from current payout eligibility or authorization. |
Flowchart
%%{init: {'theme': 'neutral'}}%%
flowchart LR
A[Admin social-connections command] --> B[Authenticated read request]
B --> C[Social-connections API response]
C --> D{Output mode}
D -->|Human| E[Connection rows]
E --> F[Historical SHADOW evaluation]
D -->|Plain| G[Connection-only rows]
D -->|JSON or JQ| H[Complete raw response]
Reviews (3): Last reviewed commit: "Treat null shadow signals as unknown" | Re-trigger Greptile
gumclaw
marked this pull request as ready for review
September 8, 2026 03:28
gianfrancopiana
added a commit
to antiwork/gumroad
that referenced
this pull request
Sep 8, 2026
## What Add `latest_shadow_evaluation` to the read-only internal admin social-connections endpoint: null without a stored row; otherwise evaluation date, recording timestamp, stored score/outcome, hold source and signals. Explicitly historical SHADOW evidence—not current eligibility or payout authorization. ## Why Reviewers can read connection evidence but not the stored shadow result. A user-scoped ordered LIMIT 1 read reuses existing data without running scoring or changing holds. Existing connections and authorization remain unchanged. No migration, admin UI, flags, credentials or money movement. CLI consumer: antiwork/gumroad-cli#215. ## Before/After The attached walkthrough runs the before/after CLI against locally replayed responses captured from real Rails controller requests with synthetic test fixtures. It shows absent/dated snapshots and the observed scoped SQL. Not a production or provider test; no browser surface changed. https://github.com/user-attachments/assets/9b37f732-ab26-4944-b1bd-e940994206fd | Probe | Result | | --- | --- | | No stored evaluation | `latest_shadow_evaluation: null` | | Multiple dates, tied recording timestamps, older row with higher ID | Evaluation day `2026-09-02`, not `2026-09-01` | | Another seller has a newer evaluation | Excluded | | Existing connection payload | Identical before/after | | Seller attributes and all evaluation rows | Unchanged after GET | | Shadow query | One user-scoped SELECT, `ORDER BY evaluated_on DESC, id DESC LIMIT 1` | Same-seller same-day duplicates are prohibited by the existing unique user/date index. The new read performs no scoring, hold or evaluation writes; pre-existing admin-token last-used bookkeeping is unchanged. QA: run `bundle exec rspec spec/controllers/api/internal/admin/users_controller_spec.rb -e 'GET social_connections'`; inspect the null and dated snapshots above. Use `gumroad admin users social-connections --email "$TEST_SELLER_EMAIL" --json` only against a configured test environment with synthetic fixtures. The snapshot describes its evaluation date, not current eligibility. ## Test Results - Focused controller group: 11 examples, 0 failures, including existing authorization and connection cases. - Mutation proof: removing user scope produces 2 failing assertions; reversing date order produces 1; restoring the committed source returns 11 examples, 0 failures. - Real endpoint capture: 1 example, 0 failures; one bounded shadow SELECT and unchanged seller/evaluation rows asserted. - RuboCop: 2 files inspected, no offenses after formatting. Ruby syntax and `git diff --check` pass. - Local Astra dev review clean; current-head Astra+Fable panel clean. Final code/spec/comment and recorded-evidence audit complete, including visual inspection of the dated SHADOW warning and SQL proof frames. - `bin/test-confidence --strict`: 99% target reached; all four selected spec files passed (admin users controller, social scoring service, admin base controller and internal admin routing). All GitHub Actions checks pass; Buildkite preview build remains pending. Draft remains actively owned until it settles; human risk-review handoff required, no auto-merge. Premerge review: clean @ 4207a38 --- AI disclosure: OpenAI GPT-6 Astra (`openai/gpt-6-astra`). Prompt: expose latest stored social shadow evaluation through the existing read-only API and backward-compatible CLI; prove absence, ordering, isolation, preserved connections and no writes. Do not alter scoring, holds, flags, credentials or move money. ### Bounded CI owner All current-head checks settled green; ready for Gianfranco risk-evidence review. No auto-merge. --------- Co-authored-by: Gianfranco Piana <52470719+gianfrancopiana@users.noreply.github.com>
JSON null RawMessage was printing the literal null token. Also document unpaid_balance_cents and Stored score, and accept float-form score fields.
Member
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.
September 8 CI repair
The new unpaid-balance field left the Go struct out of
gofmtalignment, failing the quality job ate204895582ec2aaed7fabac8f5594ae2ca3ea697. Commit7c7d49bda8e153f8d20b5d428d4eca414d85dee1changes whitespace only and preserves Gianfranco's field and rendering behavior.make test-coverpassed, including coverage gates. The first local attempt inherited a token that overrode the integration-test credential and failed authentication; removing the inherited token restored the test environment without changing tests.golangci-lint v1.64.8, focusedTestSocialtests,gofmt, andgit diff --checkpass. The installed newer linter does not accept this repository's configuration, so the CI-pinned version was used.Premerge review: clean @ 7c7d49b
What
Show the latest historical SHADOW evaluation in
gumroad admin users social-connections, with evaluation/recording dates, stored score/outcome, hold source and signals. Explicitly not current eligibility or payout authorization.Why
Consume the optional field from antiwork/gumroad#7534 without rescoring or mutations. Older servers remain supported: missing/null snapshots are not negative scores, and absent score/outcome fields remain unknown rather than becoming zero/false.
--plainpreserves its connection-only schema; JSON/JQ retain the complete response.Before/After
Before: connections only. After: connections plus dated historical evidence, including when no current connection remains. This local terminal recording replays actual Rails controller responses captured with synthetic fixtures, not production data. It shows old-server compatibility, null snapshots, dated results, JSON/JQ and the underlying read-only query proof. CLI binary built from the current head; no UI, provider or money action.
shadow-final.mp4
QA:
go test ./internal/cmd/admin/users/ -run TestSocial -count=1; against a configured test API rungumroad admin users social-connections --email "$TEST_SELLER_EMAIL", then--jq .latest_shadow_evaluation. Verify the historical date/warning and unchanged connection rows.--plaindeliberately excludes the snapshot to preserve its existing ten-column contract.Test Results
make test-cover GOFLAGS=-p=1: full suite and coverage gates pass at the current head.go run github.com/golangci/golangci-lint/cmd/golangci-lint@v1.64.8 run ./internal/...: passes.gofmtandgit diff --checkpass; before/after binaries built successfully.Historical premerge review: clean @ 4175e47
AI disclosure: OpenAI GPT-6 Astra (
openai/gpt-6-astra). Prompt: expose latest stored social shadow evidence in the existing read-only API and CLI; date/label historical results, preserve older-server behavior and connection output, verify all modes, and do not alter scoring, holds, flags, credentials or move money. Follow-up: preserve unknown scalar fields instead of displaying zero/false.