<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Yousef Ali</title>
    <description>The latest articles on DEV Community by Yousef Ali (@jservodotcom).</description>
    <link>https://dev.to/jservodotcom</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4100698%2F3d6a9136-fe13-406b-be44-6efb11d18471.jpg</url>
      <title>DEV Community: Yousef Ali</title>
      <link>https://dev.to/jservodotcom</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/jservodotcom"/>
    <language>en</language>
    <item>
      <title>Giving AI Agents a Deterministic Clock (Zero LLM in the Loop)</title>
      <dc:creator>Yousef Ali</dc:creator>
      <pubDate>Sat, 29 Aug 2026 19:50:18 +0000</pubDate>
      <link>https://dev.to/jservodotcom/giving-ai-agents-a-deterministic-clock-zero-llm-in-the-loop-3fk5</link>
      <guid>https://dev.to/jservodotcom/giving-ai-agents-a-deterministic-clock-zero-llm-in-the-loop-3fk5</guid>
      <description>&lt;p&gt;When building autonomous AI systems, developers eventually hit a fundamental architectural wall. Your coding agent asks you a question, and you step away from the keyboard. Today, nothing happens. The session hangs, the question rots, and the work stalls.&lt;/p&gt;

&lt;p&gt;At &lt;a href="https://jservo.com" rel="noopener noreferrer"&gt;J. Servo LLC&lt;/a&gt;, we architect enterprise AI systems to operate predictably. We built &lt;a href="https://github.com/bigjoe-oti/sundial" rel="noopener noreferrer"&gt;Sundial&lt;/a&gt; to act as the missing half of the human-in-the-loop framework[cite: 1]. It operates on a single defining principle: Sundial measures absence, not time[cite: 1]. &lt;/p&gt;

&lt;p&gt;When the human becomes the blocker, the agent's clock keeps running[cite: 1]. It nudges you on your desktop, escalates politely through your absence, and greets you with continuity upon your return[cite: 1]. If you never answer, the agent proceeds on its stated judgment or stands down[cite: 1]. It does this deterministically, with zero model calls, and runs 100% locally[cite: 1].&lt;/p&gt;

&lt;h2&gt;
  
  
  The Flawed Status Quo: LLMs as Cron Jobs
&lt;/h2&gt;

&lt;p&gt;Relying on a Large Language Model to determine if a user has abandoned a session violates lean architecture principles. Time tracking belongs at the system level. The separation of actors is the design[cite: 2]. &lt;/p&gt;

&lt;p&gt;Sundial enforces a strict architectural boundary across three main components:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Sensors:&lt;/strong&gt; These perform zero-permission OS reads[cite: 2]. They utilize &lt;code&gt;HIDIdleTime&lt;/code&gt;, &lt;code&gt;lsappinfo&lt;/code&gt;, and &lt;code&gt;pmset&lt;/code&gt; on macOS, and &lt;code&gt;xprintidle&lt;/code&gt; or &lt;code&gt;loginctl&lt;/code&gt; on Linux[cite: 1]. Any missing sensor returns &lt;code&gt;None&lt;/code&gt; and softens to wall time rather than blocking the system[cite: 1].&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;The Watcher Daemon:&lt;/strong&gt; A pure Python loop running via &lt;code&gt;launchd&lt;/code&gt; that handles presence classification and escalation[cite: 1, 2]. It uses zero LLMs[cite: 2].&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;The Ledgers:&lt;/strong&gt; Plain JSON files stored in a git-ignored &lt;code&gt;data/&lt;/code&gt; directory[cite: 2]. State is written atomically using &lt;code&gt;NamedTemporaryFile&lt;/code&gt;, &lt;code&gt;fsync()&lt;/code&gt;, and &lt;code&gt;os.replace()&lt;/code&gt;, serialized by inter-process locking via &lt;code&gt;fcntl.flock&lt;/code&gt;[cite: 1]. &lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Core Architecture 1: The Presence-Scaled Absence Ladder
&lt;/h2&gt;

&lt;p&gt;Escalation advances only while you genuinely have not seen the chat[cite: 1]. Sundial categorizes your presence into three strict states:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;HERE:&lt;/strong&gt; The chat is visible[cite: 1]. The clock is paused because silence in this state means "not now"[cite: 1].&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;ELSEWHERE:&lt;/strong&gt; You are in another application[cite: 1]. The clock runs at half speed[cite: 1].&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;AWAY:&lt;/strong&gt; The workstation is idle[cite: 1]. The clock runs at full speed[cite: 1].&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The system enforces urgency tiers[cite: 1]. A high-urgency task utilizes a retimed ladder of 5, 10, and 20 minutes, backed by a hard 40-minute wall ceiling that forces a final resolution regardless of sensor data[cite: 1].&lt;/p&gt;

&lt;h2&gt;
  
  
  Core Architecture 2: Bounded Breakpoint Delivery
&lt;/h2&gt;

&lt;p&gt;A ripe nudge never fires mid-keystroke[cite: 1]. Drawing from Interruption Science, the daemon holds ripe notifications for up to three minutes waiting for a natural typing gap or application switch before delivering[cite: 1].&lt;/p&gt;

&lt;p&gt;Sound courtesy is strictly enforced. Chimes escalate with urgency, but they mute unconditionally if your screen is locked or if you have been away for more than 30 minutes[cite: 1]. &lt;/p&gt;

&lt;h2&gt;
  
  
  Core Architecture 3: Self-Calibrated Task Estimation
&lt;/h2&gt;

&lt;p&gt;Agents must stop guessing execution durations using fabricated calendar weeks[cite: 1]. Sundial tracks the empirical ratio distribution of actual versus estimated time across completed tasks[cite: 1]. &lt;/p&gt;

&lt;p&gt;The estimation engine (&lt;code&gt;lib/estimator.py&lt;/code&gt;) operates purely mathematically to compute empirical P50 and P90 execution durations[cite: 1]. It applies a small-n honesty floor, utilizing a 2.0x multiplier when sample sizes are below five, ensuring the system never provides confident numbers from thin data[cite: 1, 2].&lt;/p&gt;

&lt;h2&gt;
  
  
  Core Architecture 4: The Autonomy Gate
&lt;/h2&gt;

&lt;p&gt;The trigger path never thinks[cite: 2]. When an agent blocks on an &lt;code&gt;awaiting-reply&lt;/code&gt; question, the ladder climbs until expiry, triggering the Autonomy Gate in &lt;code&gt;lib/policy.py&lt;/code&gt;[cite: 1]. &lt;/p&gt;

&lt;p&gt;The agent is forced into a deterministic verdict:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;REQUIRE_EXPLICIT_YES:&lt;/strong&gt; The action is flagged as irreversible[cite: 1]. Silence never authorizes it[cite: 1].&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;PROCEED:&lt;/strong&gt; The action is reversible and confidence is equal to or greater than 0.95[cite: 1].&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;PROCEED (Present-Silence Proven):&lt;/strong&gt; The action is reversible, confidence is 0.80 to 0.95, and the user sat in front of the chat for at least 30 minutes without objecting[cite: 1].&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;STAND_DOWN:&lt;/strong&gt; Confidence is below 0.80 or there is insufficient presence proof[cite: 1].&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The absolute autonomy rule: Silence-while-present is an answer, whereas silence-while-absent is a void[cite: 1]. They receive distinct, deterministic responses[cite: 1].&lt;/p&gt;

&lt;h2&gt;
  
  
  Deploy Sundial Today
&lt;/h2&gt;

&lt;p&gt;Sundial integrates via a generic hook protocol passing JSON on &lt;code&gt;stdin&lt;/code&gt; and outputting text blocks to &lt;code&gt;stdout&lt;/code&gt;[cite: 1]. It supports ready-made adapters for &lt;code&gt;claude-code&lt;/code&gt;, &lt;code&gt;hermes&lt;/code&gt;, and generic environments[cite: 1].&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
bash
# Clone the repository
git clone [https://github.com/bigjoe-oti/sundial.git](https://github.com/bigjoe-oti/sundial.git) ~/sundial
cd ~/sundial

# Run the installer for your target platform
./setup.sh --name "YourName" --fresh

Built with obsession by Yousef Ali and the engineering team at J. Servo LLC.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

</description>
      <category>agents</category>
      <category>ai</category>
      <category>architecture</category>
      <category>automation</category>
    </item>
  </channel>
</rss>
