Here's an idea.

When a citizen gets robbed, have the citizen store a `report`:

    public class report{
    Thief offender;
    Time timeOfOccurrence;
    Citizen victim;
    Vector3 location;
    Item[] stolenItems;
    }

After the citizen gets robbed, have the citizen run around looking for a `guard`. It could be random running until the citizen finds a `guard` via `Physics.OverlapSphere` or any other similar method if you're not using Unity (to simulate the effect of not knowing where the `guard` is) or they could run to the nearest Guard Post where a `guard` is usually standing.

When the `citizen` finds a `guard`, it tags them and the `guard` and `citizen` move toward each other. Once within range, the `citizen` gives it's `report` to the `guard`. The `guard` then paths to `report.location` and looks around until it finds `report.offender`.

If the `guard` doesn't find `report.offender` within x amount of time after `report.timeOfOccurrence`, the `guard` gives up and goes back to his post. The report remains, but the guard no longer actively searches for `report.offender`.

When the `guard` finds `report.offender`, they chase him down and get back `report.stolenItems`, incarcerate `report.offender` based on the value of `report.stolenItems`, and go back to `report.victim` and give them back `report.stolenItems`. The `report` is then disposed of.

This of course is a very old-fashioned representation of law enforcement. In a more modern setting, a `citizen` could call in a `report` to a dispatch center who would then relay the `report` to a nearby `guard`.

In summary, I like to create classes that store information and exchange those class instances between scripts. Think of how packets of data are sent through the internet. The machines that send them might be different, but they can understand the data inside the packets, so communication is possible.