Receber por email
← Voltar para o catálogo

nudge-sync

Synchronous immediate signaling channel for inter-agent communication. Implements latest-wins single-file nudge pattern for health checks, stall detection, and urgent pings.

65estrelas
Atualizado há 4 meses

Ver no GitHub ↗ Licença: NOASSERTION

Como adicionar

/plugin marketplace add Tibsfox/gsd-skill-creator

O comando exato pode variar conforme o repositório. Confira o README no GitHub.

Para o autor da skill

Cole no README do seu repo

Mostra que sua skill está catalogada na Skillteca, gera backlink e tráfego rastreável.

[![Skillteca](https://www.skillteca.com.br/api/badge/nudge-sync/svg)](https://www.skillteca.com.br/skills/nudge-sync)

Alerta por categoria

Receba novas skills de Design e Frontend toda segunda

1 email curto, só com as skills novas de Design e Frontend. 4 minutos de leitura, sem spam, cancela com 1 clique.

Você confirma o email no primeiro envio. Sem spam. Cancela com 1 clique.

Ler descrição completa

Nudge Sync

Lightweight synchronous signaling for multi-agent orchestration. Each agent has a single nudge file that is overwritten on every new nudge -- latest wins, no accumulation. Agents check their nudge file on every state poll, making this the fastest communication channel in the chipset.

Purpose

Nudge is the low-bandwidth, urgent signal channel in the Gastown chipset -- the SMI (System Management Interrupt) equivalent. It carries health checks from the witness, stall recovery prompts, and urgent coordination signals. Unlike mail (which accumulates), nudge is intentionally ephemeral: only the latest nudge matters.

The witness uses nudge to implement Gastown's Deacon heartbeat pattern. When an agent has hooked work but hasn't reported activity, the witness sends a nudge asking "are you working?" If the agent doesn't respond within the nudge interval, the witness escalates to the mayor via mail.

Filesystem Contract

.chipset/state/nudge/{agent-id}/latest.json

Each agent has a dedicated nudge directory containing exactly one file: latest.json. This file is overwritten on every new nudge. Reading the file always returns the most recent nudge (or null if no nudge has been sent).

Example paths:

.chipset/state/nudge/polecat-alpha/latest.json
.chipset/state/nudge/mayor-a1b2c/latest.json
.chipset/state/nudge/refinery-f5g6h/latest.json

Message Format

{
  "from": "witness-d3e4f",
  "type": "health_check",
  "message": "You have hooked work (gt-abc12). Are you working on it?",
  "timestamp": "2026-03-05T10:35:00Z",
  "requires_response": true
}

Field Reference

| Field | Type | Required | Description | |-------|------|----------|-------------| | from | string | yes | Sender agent ID | | type | string | yes | Nudge type (see Nudge Types below) | | message | string | yes | Human-readable nudge content | | timestamp | string | yes | ISO 8601 creation timestamp | | requires_response | boolean | yes | Whether the recipient must respond |

Nudge Types

| Type | Sender | Purpose | |------|--------|---------| | health_check | witness | Verify agent is alive and working | | stall_warning | witness | Agent has not reported activity | | priority_change | mayor | Work item priority has changed | | abort | mayor | Stop current work immediately | | sync_request | any | Request state synchronization |

Sending a Nudge

The send protocol overwrites the recipient's latest.json atomically.

Protocol

  1. Construct the nudge JSON with all required fields
  2. Serialize with sorted keys for deterministic output
  3. Write to a temporary file: .chipset/state/nudge/{agent-id}/.nudge.tmp
  4. Fsync the temporary file
  5. Rename to latest.json (atomic overwrite)

Pseudocode

async function sendNudge(nudge: NudgeMessage): Promise<void> {
  const nudgeDir = join(stateDir, 'nudge', nudge.to);
  await mkdir(nudgeDir, { recursive: true });

  const filePath = join(nudgeDir, 'latest.json');
  const content = serializeSorted(nudge);
  const tmpPath = join(nudgeDir, '.nudge.tmp');

  const fd = await open(tmpPath, 'w');
  try {
    await fd.writeFile(content, 'utf-8');
    await fd.sync();
  } finally {
    await fd.close();
  }
  await rename(tmpPath, filePath);
}

Note: The nudge message includes a to field implicitly via the directory path. The JSON itself does not store to -- the recipient is identified by the directory.

Receiving a Nudge

Polling

Agents read their latest.json on every state poll cycle. If the file exists and has a newer timestamp than the last processed nudge, the agent processes it.

async function checkNudge(agentId: string): Promise<NudgeMessage | null> {
  const filePath = join(stateDir, 'nudge', agentId, 'latest.json');
  return readJson<NudgeMessage>(filePath);
}

Processing Decision

When an agent reads a nudge, it decides how to respond based on type and requires_response:

async function processNudge(agentId: string, lastSeen: string): Promise<void> {
  const nudge = await checkNudge(agentId);
  if (!nudge) return;
  if (nudge.timestamp <= lastSeen) return; // Already processed

  switch (nudge.type) {
    case 'health_check':
      if (nudge.requires_response) {
        await respondToNudge(agentId, nudge);
      }
      break;
    case 'stall_warning':
      // Log warning, update activity timestamp
      await updateActivity(agentId);
      if (nudge.requires_response) {
        await respondToNudge(agentId, nudge);
      }
      break;
    case 'abort':
      // Stop current work, clear hook
      await abortWork(agentId);
      break;
    case 'priority_change':
      // Re-read hook for updated priority
      await refreshHook(agentId);
      break;
    case 'sync_request':
      // Synchronize state
      await syncState(agentId);
      break;
  }
}

Responding to a Nudge

When requires_response is true, the agent must write a response within the nudge interval. Responses are written to the sender's nudge directory (the sender becomes the recipient).

Response Protocol

  1. Read the incoming nudge
  2. Construct a response nudge with type: "nudge_response"
  3. Write to the sender's nudge directory as latest.json
async function respondToNudge(
  agentId: string,
  incoming: NudgeMessage
): Promise<void> {
  const response: NudgeMessage = {
    from: agentId,
    type: 'nudge_response',
    message: `Acknowledged. Working on hooked bead. Last activity: ${new Date().toISOString()}`,
    timestamp: new Date().toISOString(),
    requires_response: false,
  };
  // Write to the sender's nudge directory
  await sendNudge({ ...response, to: incoming.from });
}

Nudge Interval

The nudge interval defines how long a sender waits for a response before escalating. Default: 60 seconds. Configurable per-agent in the chipset configuration.

If no response arrives within the interval:

  1. Witness logs the agent as unresponsive
  2. Witness sends a health_escalation mail to the mayor
  3. Mayor decides whether to reassign the hooked work

Deacon Heartbeat Pattern

The witness implements Gastown's Deacon pattern using nudge:

[Witness] --health_check--> [Polecat]
                                |
                          (working? yes)
                                |
[Witness] <--nudge_response-- [Polecat]

If the polecat doesn't respond:

[Witness] --health_check--> [Polecat]
                                |
                          (no response)
                                |
[Witness] --health_escalation (mail)--> [Mayor]
                                            |
                                      (reassign work)

The witness runs the Deacon loop on a configurable interval, checking all agents with active hooks.

Latest-Wins Semantics

Nudge intentionally discards history. If two nudges arrive in rapid succession, only the second one is visible to the recipient. This is by design:

  • Health checks only need the latest status
  • Stall warnings escalate through mail if unresolved
  • Abort signals are terminal -- only the most recent matters
  • No message queue to overflow or drain

This contrasts with mail-async, which accumulates all messages.

Cross-Channel Integration

Nudge works with the other channels in the escalation flow:

  1. Hook set (hook-persistence): Agent gets work
  2. Nudge sent (nudge-sync): Witness checks if agent is active
  3. No response within interval
  4. Mail sent (mail-async): Witness escalates to mayor
  5. Hook reassigned (hook-persistence): Mayor moves work to another agent

Nudge is the detection layer. Mail is the escalation layer. Hook is the assignment layer.

Error Handling

| Condition | Behavior | |-----------|----------| | Nudge directory doesn't exist | Created automatically on first send | | Corrupt latest.json | Returns null, treated as no nudge pending | | Co

Compartilhar X LinkedIn