Integrate dockerized sentinel#1
Open
sahilx13 wants to merge 12 commits into
Open
Conversation
3b0d3de to
db664d1
Compare
db664d1 to
9102c53
Compare
* Resolve merge conflicts with main - client/src/graphql/generated.ts, server/graphql/generated.ts: regenerated via `npm run generate` after syncing codegen deps with main's lockfile (adds SENTINEL / SENTINEL_RARE_CLASS_AFFINITY only). - server/graphql/modules/integration.ts: kept main's removal of SIGHT_ENGINE/TWO_HAT, added SENTINEL. - client/src/webpages/dashboard/integrations/integrationConfigs.ts: kept main's string-literal style and updated OpenAI title, added the Sentinel tile. * Fix backend lint errors uncovered in Sentinel service/signal code - sentinelService.ts now uses the injectable fetchHTTP dependency instead of raw fetch, wired through SignalsService -> instantiateBuiltInSignals. - Replaced JSON.parse/JSON.stringify with the repo's jsonParse/jsonStringify helpers. - Rewrote sentinelService.test.ts to mock fetchHTTP directly instead of mutating global.fetch. - Declared @roostorg/types explicitly in server/package.json (it was only present transitively via a peer dependency). - Staged the previously untracked RobloxLogo.png asset. * Fix formatting issues flagged by npm run prettier - Ran `prettier --write` to fix import ordering and line wrapping in leafCondition.ts, submitContent.ts, and the Sentinel service/signal files (formatting only, no logic changes). * Skip local pre-commit hook for this merge - lint-staged fails non-deterministically on this in-progress merge with hundreds of staged files (a stash-based partial-checkout limitation, not a code issue). - Verified the equivalent checks directly instead: `docker compose run --rm codegen-check`, `backend npm run lint`, `backend npm run build`, `client npm run lint`, `client npm run build`, `npm run prettier`.
99f6cd1 to
83cb67a
Compare
* SentinelRareClassAffinitySignal.ts: skip the first thread-context item
that matches the primary text
- submitContent.ts writes the current submission to Scylla before rules
run, so getThreadSubmissionsByTime (time-bounded, not identity-bounded)
returns the triggering submission itself alongside genuine prior
messages, skewing the aggregate score Sentinel computes
* SentinelRareClassAffinitySignal.test.ts: add regression tests
- covers the de-dup path when the triggering submission is echoed back
- covers that only one occurrence is dropped if a genuine duplicate
message exists in the thread
Collaborator
Author
|
Testing doc for manual testing the feature |
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.
Summary
Adds Sentinel as a first-class Coop integration and wires up a new built-in signal,
SENTINEL_RARE_CLASS_AFFINITY, that scores string content for rare harmful text patterns (e.g. grooming) using Sentinel's contrastive example banks.Sentinel is treated as a local HTTP service (no org credentials). The signal is disabled gracefully when Sentinel is unreachable or banks are not loaded. When thread context is available, scoring includes prior messages in the thread so patterns spanning multiple messages can be detected.
Also includes a small GraphQL fix for item type create/update mutations returning
nulldata on success, and updates local dev env docs for HMA port mapping.What changed
Sentinel integration & signal
SENTINELto GraphQLIntegrationenum and client/server generated typesSENTINEL_RARE_CLASS_AFFINITYsignal type across GraphQL, server signal registry, and client signal→integration mappingSentinelServiceHTTP client (/health,/banks/status,/score, etc.) with unit testsSentinelRareClassAffinitySignal:/scoreendpointItemInvestigationServicewhen athreadIdis presentThread-aware rule evaluation
submitContentbefore rule evaluation (best-effort, retried once) so thread history is available when Sentinel runsleafConditionfor Sentinel signals:threadIdentifier— from content schemathreadIdrolecontentTextFieldName— from the condition's evaluated fieldthreadIdvalues in content submissions to{ id, typeId }for validationUI
requiresInfo: false)Config & docs
SENTINEL_API_URLtoserver/.env.exampleandserver/decs.d.ts.env.exampleandDEVELOPMENT.mdtohttp://localhost:5001Bug fix
content,thread,user) to return{ data: ... }inside success responses instead of the raw object, which causednulldata on successArchitecture
sequenceDiagram participant Client participant SubmitContent participant Scylla as ItemInvestigation (Scylla) participant RuleEngine participant SentinelSignal participant SentinelAPI Client->>SubmitContent: POST content SubmitContent->>Scylla: insertItem (best-effort, pre-rules) SubmitContent->>RuleEngine: runEnabledRules RuleEngine->>SentinelSignal: evaluate with thread runtime args SentinelSignal->>Scylla: getThreadSubmissionsByTime SentinelSignal->>SentinelAPI: POST /score (primary + thread texts) SentinelSignal-->>RuleEngine: rare_class_affinity_scoreLocal development
Set
SENTINEL_API_URL=http://localhost:8000inserver/.envRun Sentinel locally (local overlay compose file):
Start Coop as usual (
npm run up, migrations,npm start)Create a rule using Sentinel Rare Class Affinity on a string content field; submit threaded content to exercise context scoring
Test plan
Automated tests
Run Sentinel unit tests:
Confirm all existing server tests still pass:
Signal availability
Scoring behavior
Thread store integration
threadIdand confirm it is coerced to{ id, typeId }without validation errorsGraphQL regression
datadatadataClient build
Confirm the client builds successfully:
Verify
client/src/images/RobloxLogo.pngis present (required by the integrations dashboard import)