Skip to content

Latest commit

 

History

History
159 lines (134 loc) · 4.4 KB

File metadata and controls

159 lines (134 loc) · 4.4 KB

Figures

All Mermaid figures referenced by ../DEFENSIVE-PUBLICATION.md, collected here with captions. They render natively on GitHub.


Figure 1 — Component Architecture

Both gates resolve before any model/tool call; the engine only enqueues.

flowchart TB
    subgraph CFG[Configuration Bridge]
      I[scan_interval_ms]
      K[per-type cooldowns]
      AV[per-type role availability]
    end

    T[Scan Timer] -->|every interval| L{"For each registered,<br/>non-cold agent"}
    L --> SRC

    subgraph SRC[Single-pass Signal Scan]
      D[Deadline Source]
      S[Stale-item Source]
      PT[Pattern / Remediation Source]
      PC[Peer-coordination Source]
    end

    D --> CAND[("Candidate Action Set<br/>typed: tau")]
    S --> CAND
    PT --> CAND
    PC --> CAND

    CAND --> GA{"Availability Gate<br/>A of role and tau?"}
    AV -.-> GA
    GA -- no --> X1[drop]
    GA -- yes --> GC{"Cooldown Gate<br/>now minus last &gt;= cooldown of tau?"}
    K -.-> GC
    GC -- no --> X2[drop]
    GC -- yes --> EQ["Enqueue item +<br/>set last of agent,tau = now"]
    EQ --> EV[emit observability event]
    EQ --> Q[(Agent Work Queue)]
    Q --> CL["Existing Cognitive Loop<br/>executes / acts"]

    I -.-> T
Loading

Figure 2 — Candidate Lifecycle State Machine

Lifecycle of a single candidate action through the two gates.

stateDiagram-v2
    [*] --> Emitted: source produces candidate (type=tau)
    Emitted --> AvailabilityCheck
    AvailabilityCheck --> Dropped_Role: A(role,tau)=0
    AvailabilityCheck --> CooldownCheck: A(role,tau)=1
    CooldownCheck --> Dropped_Cooldown: now-last < cooldown(tau)
    CooldownCheck --> Enqueued: now-last >= cooldown(tau)
    Enqueued --> LedgerUpdated: set last(agent,tau)=now
    LedgerUpdated --> EventEmitted: emit proactive:action
    EventEmitted --> [*]
    Dropped_Role --> [*]
    Dropped_Cooldown --> [*]
Loading

Figure 3 — Logical Data Model

COOLDOWN_LEDGER is keyed on (agent_id, type) — the per-action-type cooldown made concrete. There is no per-item key in the primary cooldown table.

erDiagram
    AGENT ||--o{ REGISTRATION : "registered in"
    AGENT ||--o{ COOLDOWN_LEDGER : "has cooldowns"
    AGENT ||--o{ QUEUE_ITEM : "owns"
    ACTION_TYPE ||--o{ COOLDOWN_LEDGER : "keyed by"
    ACTION_TYPE ||--o{ AVAILABILITY_RULE : "governed by"
    ACTION_TYPE ||--o{ QUEUE_ITEM : "classifies"

    AGENT {
        string agent_id PK
        string role
        string activity_tier
    }
    REGISTRATION {
        string agent_id PK
        timestamp registered_at
    }
    ACTION_TYPE {
        string type PK
        int    cooldown_ms
    }
    COOLDOWN_LEDGER {
        string agent_id PK
        string type PK
        timestamp last_executed_at
    }
    AVAILABILITY_RULE {
        string type PK
        string allowed_roles
    }
    QUEUE_ITEM {
        string item_id PK
        string agent_id FK
        string type
        string channel
        string priority
        string subject
        string body
        string metadata
        string source_app
        timestamp created_at
    }
Loading

Figure 4 — Worked-Example Sequence

Sequence for the worked example, showing class-cooldown suppression on the second tick.

sequenceDiagram
    participant Timer
    participant Engine
    participant Sources
    participant AvailGate as Availability Gate
    participant CDGate as Cooldown Gate
    participant Ledger
    participant Queue

    Timer->>Engine: tick t0
    Engine->>Sources: scan(agent-bob)
    Sources-->>Engine: [deadline-reminder, stale-review]
    Engine->>AvailGate: (member, deadline-reminder)?
    AvailGate-->>Engine: allow
    Engine->>CDGate: now - last(bob,deadline-reminder) >= 1h?
    CDGate->>Ledger: get(bob, deadline-reminder)
    Ledger-->>CDGate: null
    CDGate-->>Engine: pass
    Engine->>Queue: enqueue(deadline-reminder)
    Engine->>Ledger: set(bob, deadline-reminder)=t0
    Note over Engine,Queue: stale-review also enqueued (first time)

    Timer->>Engine: tick t1 (t0+2min)
    Engine->>Sources: scan(agent-bob)
    Sources-->>Engine: [stale-review]
    Engine->>AvailGate: (member, stale-review)?
    AvailGate-->>Engine: allow
    Engine->>CDGate: now - last(bob,stale-review) >= 4h?
    CDGate->>Ledger: get(bob, stale-review)
    Ledger-->>CDGate: t0
    CDGate-->>Engine: FAIL (2min < 4h)
    Note over Engine,Queue: dropped — no duplicate stale spam
Loading