Find which send tools unreviewed text can reach

Agent buildMedium25 min

Your task

Your agent's tools pass text to each other along one-way links, and text from outside is untrusted. The policy says outside text may leave the company only after a redact tool and then a review tool have both handled it, in that order. A fetch tool mixes in fresh outside text, so the text that comes out of it has to go through both again.

Write unsafe_sinks(kinds, links, source) that returns the send tools that can receive text that has not met the policy.

Input and output:

  • kinds: one string per tool, tools numbered from 0: "plain", "redact", "review", "fetch" or "send". There are 1 to 100,000 tools.
  • links: up to 200,000 pairs [a, b], each a one-way link from tool a to tool b. A pair can repeat, a can equal b, and the links can form loops.
  • source: the tool where outside text enters. Its kind is "plain".
  • Return the unsafe send tools in increasing order.

Rules:

  • Text has a status. It starts as raw at source, and each tool it enters can change the status.
  • "redact" turns raw into redacted. Other statuses stay as they are.
  • "review" turns redacted into cleared. Other statuses stay as they are, so a review of raw text does not count.
  • "fetch" turns any status into raw.
  • "plain" and "send" change nothing. Text can go on along the links out of a send tool.
  • Text can travel along any route of links from source, and a route may pass through a tool more than once.
  • A send tool is unsafe if some route brings text into it with any status other than cleared.

Examples

unsafe_sinks(kinds: list[str], links: list[list[int]], source: int) -> list[int]
Example 1
Inputunsafe_sinks(["plain", "redact", "review", "send", "send"], [[0, 1], [1, 2], [2, 3], [1, 4]], 0)
Output[4]
Example 2
Inputunsafe_sinks(["plain", "review", "redact", "send"], [[0, 1], [1, 2], [2, 3]], 0)
Output[3]
Example 3
Inputunsafe_sinks(["plain", "redact", "review", "fetch", "send"], [[0, 1], [1, 2], [2, 3], [3, 4]], 0)
Output[4]