Fix commenter-targeted outreach attribution
This commit is contained in:
1 parent
b5304e24e3
commit
f77157d303
19 files changed
+328
-49
No files matched your search
+2
-2
@@ -36,9 +36,9 @@ A screening worker leases one discovered candidate. `MonitorService.screenCandid
|
||||
3. Seller evidence from the post, profile/about (including structured social links when exposed and narrow NSFW link-funnel language), and recent activity.
|
||||
4. Source-specific preparation in `ProcessorService`.
|
||||
|
||||
For image posts, preparation downloads and validates the image, detects target gender, and performs model analysis. The analysis includes a separate 1–10 visible-physique score only when enough of the body is visible. Its strict anchors place a broadly average visible physique at 5, reserve 8–10 for rare athletic or model-like physiques, and explicitly forbid using 6 as a safe default; nudity, breast size, face, pose, and photographic quality do not affect it. If physique targeting is enabled, an unknown score or a score outside the configured inclusive range becomes an explicit rejection before strategy selection and opener generation. Passing image posts then select an image strategy and generate an opener. Chat posts do not use physique targeting; they select a chat strategy and generate from the post text. Both paths apply outbound safety checks and return either a prepared immutable result or an explicit skip reason.
|
||||
For image posts, preparation downloads and validates the image, detects target gender, and performs model analysis. The analysis includes a separate 1–10 visible-physique score only when enough of the body is visible. Its strict anchors place a broadly average visible physique at 5, reserve 8–10 for rare athletic or model-like physiques, and explicitly forbid using 6 as a safe default; nudity, breast size, face, pose, and photographic quality do not affect it. If physique targeting is enabled, an unknown score or a score outside the configured inclusive range becomes an explicit rejection before strategy selection and opener generation. Passing post-author candidates use the normal image opener. Comment-author candidates use a separate commenter contract: the public comment is primary recipient evidence, while the source title and image analysis only resolve what the comment refers to. A deterministic attribution guard rejects drafts that treat the commenter as pictured, claim they created the post, request another image, or fail to ground the opener in what they expressed; one corrected regeneration is allowed before preparation fails closed. Chat posts do not use physique targeting; they select a chat strategy and generate from the post text. All paths apply outbound safety checks and return either a prepared immutable result or an explicit skip reason.
|
||||
|
||||
Terminal results become rejected candidates. Rate limits and transient failures become retryable candidates. Prepared candidates become ready; the persisted snapshot includes the opener, grounded image analysis, attractiveness and physique scores, the physique range used, source-image URL, and experiment/model/tone metadata. This lets a different account deliver without repeating AI work and lets the authenticated operator inspect the exact preparation context. Saving a physique-range change transactionally re-evaluates prepared image candidates in ready and delivery-retry stages, rejects those outside the new range, and refreshes the displayed range snapshot for retained candidates. A candidate already leased for sending is left unchanged until that send resolves.
|
||||
Terminal results become rejected candidates. Rate limits and transient failures become retryable candidates. Prepared candidates become ready; the persisted snapshot includes the opener contract, opener, grounded image analysis, attractiveness and physique scores, the physique range used, source-image URL, and experiment/model/tone metadata. This lets a different account deliver without repeating AI work and lets the authenticated operator inspect the exact preparation context. On upgrade, unedited ready or retryable commenter candidates prepared without the current commenter contract return to discovery for safe regeneration; in-flight sends and operator-edited messages are untouched. Saving a physique-range change transactionally re-evaluates prepared image candidates in ready and delivery-retry stages, rejects those outside the new range, and refreshes the displayed range snapshot for retained candidates. A candidate already leased for sending is left unchanged until that send resolves.
|
||||
|
||||
### 3. Dispatch
|
||||
|
||||
|
||||
+1
-1
@@ -24,7 +24,7 @@ Shared HTTP/SSE schemas live in `packages/api-contracts`. The server and client
|
||||
|
||||
Navigation is declared in `app/navigation.ts`; route elements are composed in `app/router.tsx`.
|
||||
|
||||
The subreddit editor chooses both a source type and recipient: image sources can target the post author or high-confidence qualifying commenters, while chat/text sources always target the post author. Comment-targeted rows carry a visible `Commenters` badge.
|
||||
The subreddit editor chooses both a source type and recipient: image sources can target the post author or high-confidence qualifying commenters, while chat/text sources always target the post author. Comment-targeted rows carry a visible `Commenters` badge. In the outreach funnel, commenter candidates are labelled separately from image-post authors and show the qualifying comment beside the prepared opener so the operator can verify that the message responds to the comment rather than attributing the source image to its author.
|
||||
|
||||
The account-growth page states plainly that comments are AI-written and posted without review, shows the adaptive allowance and trust level rather than a settable rate, and surfaces every posted comment's exact text alongside its score and removal state. A paused account replaces the pause control with a resume control and explains why it stopped, because resuming is the one action that can compound the damage.
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ Configured subreddits have a source type:
|
||||
- `image`: image-led posts are downloaded and analyzed before an opener is generated.
|
||||
- `chat`: text-led posts require a parseable self-declared gender and adult age, then use the chat-opener prompt.
|
||||
|
||||
Image subreddits may separately target either the post author (the default) or a qualifying commenter. Comment-author targeting scans a bounded set of top-level comments on newly listed image posts and uses a fail-closed AI classification. A comment qualifies only when it personally expresses a desire to experience or take the depicted role and confidence is at least 0.8. The normal image screen then verifies that the depicted role matches `reddit.targetGenders`. This is an interpretation of role alignment in the public comment, not a claim about the author's actual gender or identity. Generic praise, ambiguous reactions, deleted/moderator comments, and the post author's own comments do not qualify. The original image remains the preparation context, but generated openers are explicitly told that the recipient is a commenter and is not necessarily depicted.
|
||||
Image subreddits may separately target either the post author (the default) or a qualifying commenter. Comment-author targeting scans a bounded set of top-level comments on newly listed image posts and uses a fail-closed AI classification. A comment qualifies only when it personally expresses a desire to experience or take the depicted role and confidence is at least 0.8. The normal image screen then verifies that the depicted role matches `reddit.targetGenders`. This is an interpretation of role alignment in the public comment, not a claim about the author's actual gender or identity. Generic praise, ambiguous reactions, deleted/moderator comments, and the post author's own comments do not qualify. The original image remains scene context, but commenter openers use a separate prompt contract and must ground the message in what the commenter expressed. Drafts fail closed when they attribute the pictured body, pose, post, or image to the commenter, request another image, or omit a clear connection to the comment.
|
||||
|
||||
Image analysis may produce a subjective 1–10 visible-physique score. It is not a medical assessment and remains unknown when the image does not show enough of the body for a grounded judgment. The scale is deliberately critical: 5 is broadly average, 6 requires visible above-average leanness or definition, and 8–10 are reserved for rare athletic or model-like physiques. Nudity and photographic presentation do not increase the score. Physique targeting is disabled by default. When an operator enables an inclusive minimum/maximum range, image candidates outside that range—and unscorable image candidates—are rejected before opener generation; chat candidates are unaffected.
|
||||
|
||||
|
||||
+2
-1
@@ -24,11 +24,12 @@ This is an ownership map, not an API dump. Read the owning implementation and te
|
||||
| `reddit/api.ts` | Reddit JSON calls, post/comment parsing, seller/profile evidence, username resolution, error types | All reads must use the coordinator; redact error metadata. |
|
||||
| `reddit/request-coordinator.ts` | Process-wide Reddit request spacing and cooldown | Space failed requests too; 429 cooldown is global. |
|
||||
| `services/processor.ts` | Source-specific AI preparation and outbound safety | Returns prepared or explicit skip; performs no remote chat send. |
|
||||
| `services/comment-targeted-opener.ts` | Deterministic commenter/source attribution validation | Requires comment grounding; rejects source-image ownership/appearance claims and image requests before a commenter opener can be prepared. |
|
||||
| `services/physique-targeting.ts` | Pure optional score-range decision for image candidates | Disabled means pass; enabled ranges reject unknown and out-of-range scores before opener generation. |
|
||||
| `services/strategy-selector.ts` | Weighted explore/exploit selection and experiment metadata | Separate image/chat strategy sections; respect mature response window and sample floor. |
|
||||
| `services/recipient-deduplicator.ts` | Global recipient history plus live reservation | Case-insensitive; release failures, commit successes, recover stale claims. |
|
||||
| `utils/rate-limiter.ts` | Per-account send spacing/hour limits/jitter | Increment only for confirmed sends; reply priority may use the same limiter. |
|
||||
| `database/candidate-queue-repository.ts` | Durable candidate state machine, leases, retries, prepared-message replacement, counts, and manual clearing | Mutations require an eligible state or expected worker lease; recover expired/interrupted work; operator edits clear AI attribution; manual removals preserve sending leases and terminal audit rows. |
|
||||
| `database/candidate-queue-repository.ts` | Durable candidate state machine, leases, retries, prepared-message replacement, counts, and manual clearing | Mutations require an eligible state or expected worker lease; recover expired/interrupted work; requeue unedited legacy commenter preparations after a contract upgrade; operator edits clear AI attribution; manual removals preserve sending leases and terminal audit rows. |
|
||||
|
||||
## Account growth
|
||||
|
||||
|
||||
Reference in new issue
Block a user