Signet

An autonomous fire intelligence agent that continuously monitors the continental United States for wildfire activity using satellite imagery and geospatial data.

Watch an AI reason about wildfires in real-time →

Live Reasoning Feed Prediction Tracking Autonomous Decision
Reasoning Feed Predictions Cycle Decision
Update Alert Criteria
Real-time stream of Gemini's thought process, tool calls, and decisions during an autonomous cycle Time-bound predictions with confidence levels and verification status decide_live_cycle output showing Gemini choosing what to run next and why
update_alert_criteria tool call showing Gemini adjusting its own detection thresholds and monitoring priorities based on evolving conditions

Overview

Signet picks up a VIIRS thermal detection in Northern California - 12.4 MW of radiative power at 39.2°N, 121.8°W. It pulls the GOES-19 fire temperature image for the Pacific Southwest sector and confirms active hot pixels. It checks NWS: 14% humidity, 35 km/h northeast winds, Haines Index 6. Fuel model: SH7, very high load dry climate shrub. 2,400 people within 10 km. 847 structures.

It creates an incident, rates it critical, and predicts southwest spread within 6 hours based on terrain channeling and wind direction. Next cycle, it verifies that prediction against new satellite data.

Nobody asked it to do any of this. It decided on its own.

VIIRS (Visible Infrared Imaging Radiometer Suite) instruments alone registered over 21 million fire detections globally in 2023 (Dhage, 2025). The bottleneck has never been detection - it's interpretation. A thermal hotspot is meaningless without knowing the wind, the fuel, the terrain, and what's downhill. Today that synthesis happens manually, during business hours, one fire at a time.

Signet replaces that workflow with a single autonomous loop. Gemini 3 fuses satellite imagery with geospatial data, makes predictions, verifies them against subsequent observations, and adjusts its own monitoring strategy - continuously, for hours and days, without human intervention.

Satellites tell you where the heat is. Signet tells you what it means.


Architecture

Signet Architecture

The Autonomous Loop

Each cycle, Gemini 3 executes the following without human intervention:

  1. Restore state - load_cycle_state retrieves priorities, hypotheses, and learnings from the previous cycle
  2. Check predictions - get_due_predictions finds predictions that have reached their verification window
  3. Process intelligence - Analyzes new FIRMS detections or GOES imagery with geospatial enrichment
  4. Act - Creates/updates incidents, generates risk zones, produces threat assessments
  5. Predict - Makes new time-bound predictions about fire behavior
  6. Learn - Resolves predictions against outcomes, adjusts thresholds if accuracy drops
  7. Decide next - decide_live_cycle chooses what to run next and when, closing the autonomous loop

Cycle Types

The system runs four cycle types, all triggered and scheduled by Gemini itself via decide_live_cycle:

  1. FIRMS Cycle - New NASA FIRMS thermal detections arrive. Gemini filters by adaptive thresholds it has tuned itself, deduplicates, correlates against GOES observations, then enriches each detection with weather, fuel, terrain, population, and structures before deciding whether to create an incident, escalate an existing one, or dismiss it.
  2. GOES Cycle - GOES-19 Fire Temperature RGB imagery is sent directly to Gemini as image content. The model interprets thermal patterns in the imagery - distinguishing active fire pixels from surface heating artifacts - and cross-references against FIRMS detections and tracked incidents.
  3. Investigation Cycle - Self-initiated by the agent. When Gemini identifies an area of emerging risk based on weather patterns, prediction outcomes, or GOES anomalies, it autonomously requests a deep investigation of specific coordinates - pulling every available data source to build a comprehensive risk assessment for a location nobody told it to look at.
  4. Risk Outlook - Periodic risk outlook synthesizing all active incidents, risk zones, detections, and geospatial conditions into a forward-looking assessment with a 12–24 hour horizon.

Gemini 3 Integration

Signet is built on Gemini 3. These are the capabilities that make continuous autonomous monitoring possible:

Thought Signatures - Reasoning Continuity Across Tool Chains

// In the streaming loop, thought signatures are explicitly preserved
// across every multi-turn tool call exchange
var validParts []*genai.Part
for _, p := range allParts {
    if p.FunctionCall != nil || p.Text != "" || p.FunctionResponse != nil ||
       p.InlineData != nil || len(p.ThoughtSignature) > 0 {
        validParts = append(validParts, p)
    }
}
contents = append(contents, &genai.Content{
    Role:  "model",
    Parts: validParts,
})

A single FIRMS cycle can involve 15+ sequential tool calls. Between each call, the model needs to remember what it was reasoning about - why it was suspicious of a detection, what the weather implied, what it planned to check next. Thought signatures are opaque tokens returned by Gemini that encode the model's reasoning state. By filtering and preserving them in every model turn during the streaming loop, Signet maintains cognitive continuity across the full multi-step tool chain without re-summarizing context.

This is the critical difference between an agent that makes sequential independent calls and one that thinks through a chain of evidence. When Signet checks weather after seeing a GOES thermal anomaly, the model's assessment of the imagery is still live in its reasoning state - it doesn't re-derive its suspicion from the text history.

Thinking Levels - Variable Reasoning Depth

// Full analysis cycles: medium thinking for complex multi-source reasoning
gc.RunWithOptions(ctx, prompt, images, gemini.Execute, observer, &gemini.RunOptions{
    Stream:        true,
    ThinkingLevel: genai.ThinkingLevelMedium,
})

// Scheduling decisions: low thinking for fast operational choices
gc.RunWithOptions(ctx, prompt, nil, gemini.Execute, observer, &gemini.RunOptions{
    ToolNames:     []string{"decide_live_cycle", "get_alert_criteria",
                            "list_risk_zones", "get_due_predictions"},
    ThinkingLevel: genai.ThinkingLevelLow,
})

Not every decision requires the same depth. FIRMS enrichment, GOES imagery analysis, and proactive investigations use medium thinking - the model needs to weigh conflicting signals across weather, terrain, fuel load, and satellite imagery to distinguish a real wildfire from agricultural burning or industrial heat. Scheduling decisions via decide_live_cycle and grounding queries use low thinking - speed matters more than nuance for operational routing. The system dynamically selects thinking level per operation type.

Real-Time Cognitive Streaming

if event.Type == "thought_delta" || event.Type == "text_delta" {
    apiServer.PublishEvent("stream_delta", map[string]any{
        "type":     event.Type,
        "content":  event.Content,
        "cycle_id": cycleID,
    })
}

IncludeThoughts: true combined with Gemini's streaming API means the model's internal reasoning is visible as it happens. Every thought delta and text delta is pushed through server-sent events to the browser, where the frontend renders a live indicator showing whether the model is "Thinking..." or "Responding..." and which cycle type is running. This isn't a post-hoc log - it's a real-time window into the agent's cognition during a FIRMS analysis, GOES scan, or self-initiated investigation.

Context Caching - Amortized System Context

cache, err := c.client.Caches.Create(ctx, "gemini-3-flash-preview", &genai.CreateCachedContentConfig{
    DisplayName: "signet-system",
    SystemInstruction: &genai.Content{
        Parts: []*genai.Part{{Text: systemPrompt}},
    },
    Tools: Declarations(), // 28 tool declarations
    TTL:   1 * time.Hour,
})

An agent running hundreds of cycles per day can't re-send a system prompt and 28 tool declarations every time. The system prompt and full tool schema are cached server-side with a 1-hour TTL, auto-refreshed 5 minutes before expiry. Every cycle references the cache by name. When a cycle needs a restricted tool set, it bypasses the cache and sends inline - the system dynamically chooses the optimal path per operation.

Multimodal Satellite Analysis

parts = append(parts, genai.NewPartFromText(prompt))
for sector, imgData := range images {
    parts = append(parts, genai.NewPartFromBytes(imgData, "image/jpeg"))
}

GOES-19 Fire Temperature RGB images (1200×1200 JPG per sector, up to 10 sectors) are sent as native image parts alongside the structured text prompt. The model interprets thermal patterns directly - distinguishing bright clustered hot pixels (active fire) from diffuse warm regions (surface heating, arid land emissivity) - and correlates what it sees with FIRMS point detections and geospatial tool results in the same reasoning pass. This is spatial-temporal multimodal fusion: the model synthesizes visual satellite evidence with structured geospatial data to produce an assessment no single source could support.

Google Search Grounding

config := &genai.GenerateContentConfig{
    Tools: []*genai.Tool{
        {GoogleSearch: &genai.GoogleSearch{}},
    },
}

Satellite data tells you there's heat. It doesn't tell you the fire's name, whether evacuations are underway, or that the road to the nearest town is closed. Before FIRMS and investigation cycles, Gemini queries Google Search via built-in grounding for real-time fire context - official names, containment percentages, evacuation orders, road closures. Sources are logged with full attribution in the reasoning feed.

Autonomous Tool Orchestration

Gemini 3's 1M token context window and advanced function calling make it possible to manage 28 tool declarations in a single session while accumulating multi-turn conversation history across 15+ sequential tool calls per cycle. A typical cycle sequences these calls entirely on its own, with thought signatures maintaining reasoning continuity across every step:

load_cycle_stateget_due_predictionsresolve_predictionlist_incidentsget_fire_imagerycreate_goes_observationget_weatherget_fire_weather_analysisget_fuel_modelget_elevationget_populationget_structurescreate_incidentmake_predictionsave_cycle_statedecide_live_cycle

This isn't a fixed sequence. The model skips tools that aren't relevant, calls some multiple times for different coordinates, and decides when to escalate versus dismiss. No routing logic in application code tells the model what to call next - orchestration is entirely within Gemini's reasoning, maintained by thought signatures across the full chain.


Data Sources

Source Provider Data Update Frequency
Thermal detections NASA FIRMS VIIRS/MODIS hotspots with FRP, confidence, coordinates ~30 min
Satellite imagery NOAA GOES-19 ABI Fire Temperature RGB, 10 CONUS sectors ~10 min
Weather National Weather Service Temp, humidity, wind, Haines Index, fire weather indices Real-time
Elevation USGS EPQS Terrain altitude for fire behavior modeling Static
Fuel models LANDFIRE FBFM40 40 Scott & Burgan fuel categories Static
Population US Census Block-level population counts Static
Structures OpenStreetMap Overpass Building counts within configurable radius Near real-time
Web context Google Search Active fire news, containment, evacuations Real-time

Tools (28)

Category Tools
Orchestration decide_live_cycle, save_cycle_state, load_cycle_state
Incidents create_incident, update_incident, list_incidents
Predictions make_prediction, get_due_predictions, resolve_prediction
Satellite get_fire_imagery, create_goes_observation, update_goes_observation, list_goes_observations, correlate_detection
Weather get_weather, get_fire_weather_analysis, analyze_wind_fire_correlation
Terrain get_elevation, get_fuel_model
Exposure get_population, get_structures
Risk create_risk_zone, update_risk_zone, list_risk_zones, validate_risk_zone
Calibration get_alert_criteria, update_alert_criteria
Assessment set_assessment_validity

Usage

Production

The live system is running at signet.zachary.systems.

Development

git clone https://github.com/mapldx/signet
cd signet

# Set environment variables (either system-level, or create a .env)
export GEMINI_API_KEY=your_key
export FIRMS_MAP_KEY=your_firms_key
# Optional: if not set, will create a local SQLite database
export DATABASE_URL=your_postgres_url
# Optional: if not set, will default to 30-minute FIRMS/10-minute GOES cycles
export SIGNET_AUTONOMOUS=1

go run .
# Alternatively: append -dev for development mode, skipping AI calls

This project is built using:

Category Technologies
Backend Go
AI Gemini 3 (google.golang.org/genai)
Database PostgreSQL (production), SQLite (development)
Frontend HTMX, server-sent events

Why This Matters

Fire detection is solved. NASA processes tens of millions of thermal detections annually. GOES images the continental US every 5 minutes. The data is abundant. What's missing is the step between "there's heat at these coordinates" and "here's what that means for the 2,400 people downwind."

That interpretation step - correlating a hotspot with wind, humidity, terrain slope, fuel type, population density, and existing incident history - currently requires a human analyst during business hours. Signet runs that workflow autonomously, 24/7, for every detection that crosses a threshold the model itself is tuning.

Three things make this more than a demo:

  1. It persists. State carries across cycles. The model remembers what it hypothesized last cycle, what it predicted, and what it learned. Thought signatures maintain reasoning continuity within cycles; save_cycle_state / load_cycle_state maintain it across them. This is a Marathon Agent - not a single inference call but a system that accumulates context over hours and days of continuous operation.
  2. It self-corrects. Predictions are testable. "This fire will spread southwest within 6 hours" has a due date. When the due date arrives, the model checks new satellite data, scores itself, and adjusts thresholds if it's been wrong too often. Prediction accuracy below 50% triggers explicit recalibration via update_alert_criteria.
  3. It initiates. The most interesting cycles are the ones nobody requested. The model notices deteriorating weather in an area with high fuel loads and no active incidents, decides to investigate, and either confirms the risk or files it away as a learning. This is autonomous intelligence - not a pipeline waiting for input.

Disclaimer

Signet is not a substitute for official emergency information. Do not use this system to make evacuation, safety, or emergency response decisions.

For official wildfire information, refer to NIFC, InciWeb, and your local emergency management agency.

AI-generated assessments may contain errors. Satellite data may be delayed or incomplete. All analysis is provided as-is with no warranty.

Built With

Share this project:

Updates

posted an update

We launched Signet on Product Hunt today: https://www.producthunt.com/products/signet.

Our latest version is also now live at its new home, https://signet.watch.

Since this hackathon, Signet has evolved from a single-process autonomous wildfire monitoring prototype into a more complete product and research system. Architecturally, the app now separates the live web experience from the autonomous monitoring runtime, which makes the system more reliable and easier to scale. We also improved the deployment and development workflow with a modern frontend build pipeline, containerized deploys, CI, and better observability.

On the product and modeling side, Signet now does much more than surface a live feed of incidents. We added location-based alerting, improved the live intelligence view, and reworked the prediction system so forecasts are more structured and can be adjudicated more cleanly instead of relying on the model to grade itself. We also tightened incident identity and data handling so the system is more consistent and trustworthy in production. Overall, the work since v1 has been about turning an early autonomous demo into something that is both more usable as a product and more defensible as a live research system.

Dashboard screenshot

Incident view screenshot

Reasoning feed screenshot

Signet icon

Log in or sign up for Devpost to join the conversation.

posted an update

Signet is currently running autonomously during the Feb 2026 Texas and Oklahoma Panhandle wildfires.

On Feb 17, at 04:53 UTC, Signet scored the region as a high-risk threat zone based on 13% humidity and gusts exceeding 60 km/h over dry grass fuels. At 05:13 UTC, it confirmed a GOES-19 thermal signature, ran 8 analysis tools across weather, fuel, elevation, structures, and population, and created Incident 420.

So far it has made 9 time-bound predictions about fire behavior and verified them against subsequent satellite passes over 20 hours, with 78% accuracy.

It has escalated to 4 linked critical incidents as fires spread into a regional complex.

This is what persistent, autonomous satellite monitoring looks like when operating against a real-world event. Every tool call, prediction, and reasoning step is in the live feed.

signet.zachary.systems

Incident Report

Log in or sign up for Devpost to join the conversation.