Last reviewed: 2026-08-26

Direct answer

Put a moderation gate after your service receives and normalizes an issue, but before any issue text, attachment, or screenshot reaches a generative model. The gate should send the intended input through the CometAPI moderation endpoint, validate the returned contract, apply your own documented policy, and produce one of three outcomes: pass to the coding agent, hold for human review, or reject from automated processing with a neutral explanation.

The CometAPI moderation endpoint documentation describes an OpenAI-compatible POST /v1/moderations request. It accepts one text value, a batch of text values, or supported multimodal parts. Its response includes a model identifier, results, usage data, a top-level flag for each result, category booleans, category scores, and the input types applied to each category.

A concrete happy path looks like this:

  1. Receive the issue and assign a local intake record.
  2. Preserve the original in access-controlled storage, then create a bounded copy containing only the title, relevant body text, and approved attachments.
  3. Send that copy to moderation using the selected model and expected input shape.
  4. Require a successful response, the expected number of results, recognized fields, and evidence that each intended modality was evaluated.
  5. Apply a versioned local policy. If the result is unflagged and no category-specific rule triggers, release only the minimized copy to the coding agent.
  6. Record a sanitized decision event without saving raw issue text or screenshot data in ordinary application logs.

The error path must be just as explicit. Treat an invalid request as a configuration defect, an authentication failure as a stopped route, and temporary model unavailability as a bounded-retry condition. If the retry budget is exhausted, hold the issue for review; do not bypass moderation and send it directly to the coding agent. A successful HTTP response with missing, mismatched, or unrecognized result fields should also enter the hold path.

Moderation is one intake control, not a complete trust decision. A benign classification does not make repository instructions trustworthy, authorize tools, remove sensitive data, or prove that later tool results are safe. Pair this gate with repository prompt-injection defenses and independent tool-permission checks.

Who this is for

This design is for teams that let coding agents read bug reports, support tickets, public issues, copied logs, or screenshots. It is especially useful when the intake channel is open to people outside the engineering team or when an automated triage service can start model work without an operator reading the issue first.

It also applies to internal systems. An internal issue can contain copied third-party text, hostile instructions, graphic screenshots, or accidental sensitive material. The moderation decision should therefore depend on the input and policy, not merely on whether the reporter has an employee account.

This guide does not prescribe one universal threshold. Product context, legal obligations, user population, and review capacity differ. Its aim is to make the contract and routing behavior testable so an operator can tell what was checked, what was not checked, and why automation continued or stopped.

Key takeaways

  • Moderate the exact minimized input that the coding agent would otherwise receive.
  • Keep pass, hold, and reject as separate outcomes; a flagged issue does not have to be deleted.
  • Validate result count, response shape, selected model, and applied input types before trusting the decision.
  • Do not interpret a category score as a universal severity scale.
  • Fail closed to automated model ingestion when moderation is unavailable or its response cannot be validated.
  • Keep raw issue text, attachment bytes, download locations, and request headers out of routine decision logs.
  • Re-run the gate if later enrichment materially changes the agent input.
  • Test moderation and prompt-injection controls separately because they address different risks.

Sources checked

  • The CometAPI create-moderation reference defines the endpoint, accepted text and multimodal shapes, response fields, batch-result behavior, and documented error statuses.
  • The Google Gemini safety-settings guide distinguishes harm probability from severity, describes category-specific request thresholds, and notes that some core protections cannot be adjusted.
  • The Microsoft harm-category guide shows that classifications can carry multiple labels and that another safety system represents severity separately from category membership.
  • The Amazon Bedrock content-filter guide gives a concrete example of coverage boundaries in tool-using systems: its documented filters inspect some text surfaces but not tool results, tool definitions, or generated tool arguments. That boundary is not evidence of CometAPI behavior; it is a reason to document and test the surfaces in your own pipeline.

Contract details to verify

Write the moderation contract down before connecting it to issue intake. At minimum, verify these items in staging and again whenever you change the model or payload builder:

Contract itemOperator check
EndpointThe client invokes POST /v1/moderations, not the generative-model route.
ModelThe configured moderation model supports every modality you intend to send.
InputSingle text, batched text, and multimodal payloads are built intentionally rather than inferred from attachment presence.
Image handlingThe image is actually available to the moderation service, or a permitted self-contained representation is used.
Responseresults exists, has the expected cardinality, and contains the fields required by local policy.
CoverageApplied input types match the text and image surfaces the intake service expected to check.
PolicyCategory actions and any score thresholds have an owner, rationale, test set, and version.
Failure behaviorInvalid requests, stopped authentication, temporary unavailability, timeouts, and malformed success responses all have defined routes.
Audit eventThe event proves which contract and policy ran without copying the untrusted payload into logs.

CometAPI documents one result per input string for batch text requests. Preserve an internal positional mapping while processing the response, but do not place user text into that mapping. If the batch contains five items and the response contains four results, hold the whole batch or split it into individually traceable checks. Never guess which item was omitted.

For screenshots, request construction is only half the test. CometAPI says a public image location must be downloadable by its servers, and its response exposes category-applied input types. Verify both delivery and returned modality evidence. A text result produced after an image fetch failure must not silently count as complete multimodal moderation.

Keep policy interpretation local. Google documents probability-based blocking and warns that probability is not the same as harm severity. Microsoft documents a separate severity scale and multi-label classification. Those examples demonstrate why a numeric value from one contract should not be relabeled with another system’s meaning. Calibrate your own action table against representative, access-controlled fixtures and retain the category names and model identity used by each decision.

The routing skeleton can remain small. This is pseudocode, so adapt method names to the client you use:

def route_issue(issue):
    moderation_input = build_minimized_input(issue)
    response = moderation_client.check(
        model='omni-moderation-latest',
        input=moderation_input,
    )

    if not valid_contract(response, moderation_input):
        return hold_for_review('invalid_moderation_contract')

    action = evaluate_versioned_policy(response.results)
    if action != 'pass':
        return hold_for_review(action)

    return send_minimized_input_to_agent(issue)

Add an error wrapper around that core. A documented 400 response should open a configuration alert and hold the item rather than trigger identical retries. A 401 should stop the route and alert the service owner without recording authentication material. A documented 503 can use a small bounded retry budget; exhaustion moves the item to a visible hold queue. The same hold behavior should cover timeouts and schema-validation failures unless your written policy defines a stricter outcome.

A useful sanitized decision event contains operational metadata, not content:

moderation_event_id: evt-42
intake_record_id_hash: hash-7
received_at: 2026-08-26T00:00:00Z
moderation_model: omni-moderation-latest
input_modalities:
  - text
  - image
input_size_bucket: small
provider_response_id_hash: hash-9
results_count: 1
flagged: false
matched_categories: []
max_score_bucket: none
applied_input_types:
  - text
  - image
policy_action: pass
policy_version: v3
http_status: 200
latency_bucket: under-1s
retry_count: 0
error_class: null

Do not add the issue title, body, screenshot bytes, attachment location, raw provider response, request headers, or free-form exception text to that event. Store diagnostic evidence separately with restricted access and an appropriate retention rule. If you need more operational guidance, use the CometAPI request-fixture preflight guide and the CometAPI error-response review to exercise both successful and failed contracts.

Failure modes

Fail-open routing. The moderation call times out or returns 503, and the intake service forwards the issue to avoid a queue. This turns an outage into a safety-control bypass. Use a visible hold state, bounded retry, and an operator alert instead.

Treating flagged: false as authorization. An unflagged issue may still contain irrelevant instructions, misleading repository guidance, sensitive values, or requests beyond the agent’s permission boundary. Moderation should never grant tool access or expand task scope.

Partial modality coverage. The title and body are checked, but an inaccessible screenshot is later delivered to a vision-capable coding agent. Verify expected input types and prevent downstream enrichment from adding unchecked material.

Batch correlation errors. A service assumes result order after filtering empty fields or rebuilding arrays. Preserve a deterministic internal mapping and require exact cardinality before applying decisions.

Borrowed score semantics. An operator labels a CometAPI category score as low, medium, or high severity without a tested mapping. Keep the original field meaning, define local buckets as policy artifacts, and do not claim that another provider’s scale applies.

Overblocking legitimate engineering context. Security tests, crash reports, abuse-prevention code, and quoted user reports can contain terms that resemble harmful content. Route uncertain or context-dependent cases to trained review rather than deleting evidence or repeatedly rewriting the reporter’s text.

Unlogged policy drift. The payload builder, model, or action table changes, but the event contains only pass. Log the model and local policy version so reviewers can reconstruct which decision contract applied.

Raw-content logging. Debugging middleware records issue bodies, screenshot locations, or complete moderation responses. Use an allowlist of sanitized fields and ensure error handling cannot append the original payload to free-form messages.

Assuming every tool surface is covered. The AWS documentation illustrates that guardrail products can omit tool definitions, arguments, and results from content filtering. Inventory your own agent’s issue input, retrieved files, tool arguments, tool results, and generated output. Test each surface independently instead of assuming the intake gate follows content introduced later.

Retrying an invalid request unchanged. Repeating a 400 consumes time and keeps the issue in an ambiguous state. Hold it, record a sanitized error class, and repair the request builder before replaying the item.

FAQ

Should a flagged issue be deleted?

Usually, no automatic deletion is needed for the gate itself. Keep hold distinct from reject. A hold preserves evidence for an authorized reviewer, while a rejection can return a neutral message without starting the coding agent. Your retention and reporting obligations should be defined outside the model response.

Can I route solely on the top-level flag?

The flag is a useful first signal, but a robust contract also checks result count, model identity, category fields, applied input types, and local category policy. This matters when one category requires a different review path or when a multimodal request was only partially evaluated.

Should text and screenshots be moderated together?

Use a moderation model and input shape that support the intended modalities. Sending them together can preserve context, but the operator must still verify that the image was deliverable and that the returned contract reflects both input types. If either part cannot be checked, hold the combined issue rather than forwarding the unchecked portion.

How should I choose score thresholds?

Do not copy severity labels from a different safety system. Start with the documented flag and category booleans, then evaluate any category-score rules against representative fixtures and human-reviewed outcomes. Record threshold changes as policy versions.

What happens during a moderation outage?

Use bounded retries for temporary failures, then move the item to a visible queue. Do not start a generative or tool-capable agent with the unchecked issue. Operators should be able to replay the same minimized intake after service recovery.

Does moderation stop prompt injection?

No. Harm classification and instruction-trust analysis are different controls. Keep repository and issue text untrusted, maintain task scope, restrict tools, and require approval for sensitive actions even after moderation passes.

Do I need to moderate model output too?

That depends on where the output goes and what your policy requires. At minimum, recognize that the intake gate covers only the material submitted to it. If the agent later retrieves files, receives tool results, or produces user-visible content, define separate checks for those surfaces.

Reader next step

Create a one-page intake contract with the accepted modalities, selected moderation model, required response fields, action table, retry budget, and sanitized log allowlist. Then build fixtures for an ordinary text issue, a context-dependent issue, a text-plus-image issue, a result-count mismatch, an unavailable image, a malformed success response, and each documented error class. Confirm that only the complete pass case can reach the coding agent.

Once those tests and the human hold queue are in place, Start with CometAPI and connect the moderation decision to your issue-intake router.