Skip to content

Commit 480fd98

Browse files
authored
Merge pull request #102 from AgentWorkforce/posts/aeon-cron-agent-framework
Add essay: Aeon and the ceiling of cron
2 parents 12361be + c8af087 commit 480fd98

5 files changed

Lines changed: 393 additions & 0 deletions

File tree

components/card-illustrations.tsx

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,54 @@ const C = {
1010
lavender: "#dccaee",
1111
};
1212

13+
function AeonCronArt() {
14+
return (
15+
<svg
16+
viewBox="0 0 500 300"
17+
className="pointer-events-none absolute inset-0 h-full w-full"
18+
aria-hidden
19+
>
20+
<g
21+
opacity="0.14"
22+
stroke={C.ink}
23+
fill="none"
24+
strokeLinecap="round"
25+
strokeLinejoin="round"
26+
>
27+
<g transform="translate(250, 112)">
28+
{/* Clock with cron ticks */}
29+
<circle r="28" strokeWidth="1.8" />
30+
<circle r="2" fill={C.ink} stroke="none" />
31+
<line x1="0" y1="0" x2="0" y2="-18" strokeWidth="1.8" />
32+
<line x1="0" y1="0" x2="12" y2="6" strokeWidth="1.3" />
33+
{/* Gear teeth around the clock */}
34+
{[0, 45, 90, 135, 180, 225, 270, 315].map((angle, i) => {
35+
const rad = (angle * Math.PI) / 180;
36+
const x1 = Math.cos(rad) * 28;
37+
const y1 = Math.sin(rad) * 28;
38+
const x2 = Math.cos(rad) * 36;
39+
const y2 = Math.sin(rad) * 36;
40+
return (
41+
<line key={i} x1={x1} y1={y1} x2={x2} y2={y2} strokeWidth="1.4" />
42+
);
43+
})}
44+
{/* Outer dashed orbit — self-healing loop */}
45+
<circle r="48" strokeWidth="0.9" strokeDasharray="4 4" />
46+
{/* Arrow on the orbit */}
47+
<path d="M44 -18 L48 -10 L40 -12" strokeWidth="1.3" />
48+
{/* Small skill boxes radiating */}
49+
{[-50, -20, 10, 40].map((y, i) => (
50+
<g key={i}>
51+
<rect x={-80} y={y - 6} width="18" height="12" rx="2" strokeWidth="1.2" />
52+
<line x1={-62} y1={y} x2={-48} y2={y > 0 ? 10 : y < -10 ? -10 : 0} strokeWidth="0.8" strokeDasharray="2 3" />
53+
</g>
54+
))}
55+
</g>
56+
</g>
57+
</svg>
58+
);
59+
}
60+
1361
const SLUGS: Record<string, React.ComponentType> = {
1462
"three-primitives": PrimitivesArt,
1563
"reactive-vs-proactive": ReactivePushArt,
@@ -37,6 +85,7 @@ const SLUGS: Record<string, React.ComponentType> = {
3785
"junior-so-ai-employee": JuniorEmployeeArt,
3886
"google-spark-io-2026": SparkIOArt,
3987
"mcp-notifications": MCPNotifArt,
88+
"aeon-cron-agent-framework": AeonCronArt,
4089
};
4190

4291
export function CardArt({ slug }: { slug: string }) {

components/mdx/figures.tsx

Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3871,3 +3871,170 @@ export function SparkSurfacesFigure() {
38713871
</svg>
38723872
);
38733873
}
3874+
3875+
/** Aeon architecture — GitHub Actions cron → skill dispatch → output → commit. */
3876+
export function AeonArchFigure() {
3877+
return (
3878+
<svg viewBox="0 0 320 320" className="w-full" role="img" aria-labelledby="aeon-arch-title">
3879+
<title id="aeon-arch-title">Aeon architecture: GitHub Actions cron dispatches skills, scores output, commits results back to the repo</title>
3880+
<defs>
3881+
<radialGradient id="aeongrad" cx="50%" cy="35%" r="60%">
3882+
<stop offset="0%" stopColor={C.sage} stopOpacity="0.6" />
3883+
<stop offset="100%" stopColor={C.butter} stopOpacity="0.2" />
3884+
</radialGradient>
3885+
</defs>
3886+
<rect x="20" y="10" width="280" height="300" rx="16" fill="url(#aeongrad)" />
3887+
{/* Layer 1: GitHub Actions cron */}
3888+
<rect x="55" y="30" width="210" height="42" rx="8" fill={C.paper} stroke={C.ink} strokeWidth="1.6" />
3889+
<text x="160" y="48" textAnchor="middle" fontFamily="var(--font-display)" fontSize="10" fill={C.ink}>GitHub Actions</text>
3890+
<text x="160" y="62" textAnchor="middle" fontFamily="var(--font-mono)" fontSize="7.5" fill={C.faint}>cron every 5 min</text>
3891+
{/* Connector */}
3892+
<line x1="160" y1="72" x2="160" y2="90" stroke={C.inkSoft} strokeWidth="1.2" strokeDasharray="3 3" />
3893+
<path d="M155 85 L160 92 L165 85" fill="none" stroke={C.inkSoft} strokeWidth="1.2" />
3894+
{/* Layer 2: aeon.yml dispatcher */}
3895+
<rect x="55" y="94" width="210" height="42" rx="8" fill={C.paper} stroke={C.ink} strokeWidth="1.6" />
3896+
<text x="160" y="112" textAnchor="middle" fontFamily="var(--font-display)" fontSize="10" fill={C.ink}>aeon.yml dispatcher</text>
3897+
<text x="160" y="126" textAnchor="middle" fontFamily="var(--font-mono)" fontSize="7.5" fill={C.faint}>match cron → dispatch skill</text>
3898+
{/* Fan-out to skills */}
3899+
{[80, 130, 180, 230].map((x, i) => (
3900+
<line key={i} x1={x} y1="136" x2={x} y2="162" stroke={C.terracotta} strokeWidth="1" strokeDasharray="2 2" />
3901+
))}
3902+
{/* Skill boxes */}
3903+
{[
3904+
{ label: "brief", x: 80 },
3905+
{ label: "review", x: 130 },
3906+
{ label: "digest", x: 180 },
3907+
{ label: "monitor", x: 230 },
3908+
].map(({ label, x }, i) => (
3909+
<g key={i}>
3910+
<rect x={x - 22} y={164} width="44" height="28" rx="5" fill={C.paper} stroke={C.ink} strokeWidth="1.2" />
3911+
<text x={x} y={181} textAnchor="middle" fontFamily="var(--font-mono)" fontSize="7" fill={C.ink}>{label}</text>
3912+
</g>
3913+
))}
3914+
{/* Converge to scoring */}
3915+
{[80, 130, 180, 230].map((x, i) => (
3916+
<line key={i} x1={x} y1="192" x2="160" y2="216" stroke={C.rule} strokeWidth="0.8" />
3917+
))}
3918+
{/* Score + commit */}
3919+
<rect x="100" y="218" width="120" height="32" rx="6" fill={C.paper} stroke={C.terracotta} strokeWidth="1.4" />
3920+
<text x="160" y="233" textAnchor="middle" fontFamily="var(--font-mono)" fontSize="8" fill={C.ink}>score → commit</text>
3921+
<text x="160" y="244" textAnchor="middle" fontFamily="var(--font-mono)" fontSize="6.5" fill={C.faint}>Haiku 1–5 · git push</text>
3922+
{/* Loop back arrow */}
3923+
<path d="M220 234 Q260 234 260 180 Q260 50 220 50" fill="none" stroke={C.moss} strokeWidth="1.2" strokeDasharray="4 3" />
3924+
<path d="M224 46 L218 50 L224 54" fill="none" stroke={C.moss} strokeWidth="1.2" />
3925+
<text x="272" y="140" textAnchor="middle" fontFamily="var(--font-mono)" fontSize="6" fill={C.moss} transform="rotate(90, 272, 140)">state persists</text>
3926+
<text x="160" y="278" textAnchor="middle" fontFamily="var(--font-mono)" fontSize="8.5" fill={C.faint}>zero infrastructure, git is the database</text>
3927+
</svg>
3928+
);
3929+
}
3930+
3931+
/** Aeon self-healing loop — quality scoring drives repair. */
3932+
export function AeonHealFigure() {
3933+
return (
3934+
<svg viewBox="0 0 320 320" className="w-full" role="img" aria-labelledby="aeon-heal-title">
3935+
<title id="aeon-heal-title">Aeon self-healing: skill runs are scored, health tracked over 30 runs, and repair dispatched on degradation</title>
3936+
<defs>
3937+
<radialGradient id="healgrad" cx="50%" cy="40%" r="55%">
3938+
<stop offset="0%" stopColor={C.butter} stopOpacity="0.6" />
3939+
<stop offset="100%" stopColor={C.sage} stopOpacity="0.2" />
3940+
</radialGradient>
3941+
</defs>
3942+
<circle cx="160" cy="155" r="145" fill="url(#healgrad)" />
3943+
{/* Central skill execution */}
3944+
<circle cx="160" cy="100" r="30" fill={C.paper} stroke={C.ink} strokeWidth="1.8" />
3945+
<text x="160" y="96" textAnchor="middle" fontFamily="var(--font-display)" fontSize="10" fill={C.ink}>skill</text>
3946+
<text x="160" y="108" textAnchor="middle" fontFamily="var(--font-mono)" fontSize="7" fill={C.faint}>runs</text>
3947+
{/* Arrow down to scoring */}
3948+
<line x1="160" y1="130" x2="160" y2="155" stroke={C.ink} strokeWidth="1.2" />
3949+
<path d="M155 150 L160 158 L165 150" fill="none" stroke={C.ink} strokeWidth="1.2" />
3950+
{/* Quality score box */}
3951+
<rect x="115" y="160" width="90" height="36" rx="6" fill={C.paper} stroke={C.terracotta} strokeWidth="1.6" />
3952+
<text x="160" y="176" textAnchor="middle" fontFamily="var(--font-mono)" fontSize="9" fill={C.ink}>score: 1–5</text>
3953+
<text x="160" y="190" textAnchor="middle" fontFamily="var(--font-mono)" fontSize="7" fill={C.faint}>Haiku evaluates</text>
3954+
{/* Arrow down to health history */}
3955+
<line x1="160" y1="196" x2="160" y2="218" stroke={C.ink} strokeWidth="1.0" />
3956+
<path d="M155 213 L160 220 L165 213" fill="none" stroke={C.ink} strokeWidth="1.0" />
3957+
{/* Health history bar */}
3958+
<rect x="80" y="222" width="160" height="30" rx="5" fill={C.paper} stroke={C.ink} strokeWidth="1.2" />
3959+
<text x="160" y="237" textAnchor="middle" fontFamily="var(--font-mono)" fontSize="8" fill={C.ink}>30-run health history</text>
3960+
<text x="160" y="248" textAnchor="middle" fontFamily="var(--font-mono)" fontSize="6.5" fill={C.faint}>trend detection · API flags</text>
3961+
{/* Repair branch — left side */}
3962+
<line x1="80" y1="237" x2="40" y2="237" stroke={C.terracotta} strokeWidth="1.2" />
3963+
<line x1="40" y1="237" x2="40" y2="130" stroke={C.terracotta} strokeWidth="1.2" />
3964+
<line x1="40" y1="130" x2="128" y2="100" stroke={C.terracotta} strokeWidth="1.2" />
3965+
<path d="M122 96 L130 100 L124 106" fill="none" stroke={C.terracotta} strokeWidth="1.2" />
3966+
{/* Repair label */}
3967+
<rect x="12" y="165" width="56" height="24" rx="4" fill={C.paper} stroke={C.terracotta} strokeWidth="1" />
3968+
<text x="40" y="178" textAnchor="middle" fontFamily="var(--font-mono)" fontSize="7" fill={C.terracotta}>repair</text>
3969+
<text x="40" y="186" textAnchor="middle" fontFamily="var(--font-mono)" fontSize="5.5" fill={C.faint}>≥3 failures</text>
3970+
{/* Score indicators — mini bars on right */}
3971+
{[
3972+
{ score: 5, w: 24 },
3973+
{ score: 4, w: 20 },
3974+
{ score: 3, w: 14 },
3975+
{ score: 2, w: 8 },
3976+
{ score: 1, w: 4 },
3977+
].map((s, i) => (
3978+
<g key={i}>
3979+
<rect x={258} y={80 + i * 16} width={s.w} height="10" rx="2" fill={C.sage} opacity="0.7" stroke={C.ink} strokeWidth="0.6" />
3980+
<text x={252} y={88 + i * 16} textAnchor="end" fontFamily="var(--font-mono)" fontSize="6.5" fill={C.faint}>{s.score}</text>
3981+
</g>
3982+
))}
3983+
<text x="270" y="165" textAnchor="middle" fontFamily="var(--font-mono)" fontSize="6.5" fill={C.faint}>quality</text>
3984+
<text x="270" y="174" textAnchor="middle" fontFamily="var(--font-mono)" fontSize="6.5" fill={C.faint}>gradient</text>
3985+
<text x="160" y="285" textAnchor="middle" fontFamily="var(--font-mono)" fontSize="8.5" fill={C.faint}>failure is the steady state</text>
3986+
</svg>
3987+
);
3988+
}
3989+
3990+
/** Aeon primitive gap map — clock solid, listener missing, inbox partial. */
3991+
export function AeonGapFigure() {
3992+
return (
3993+
<svg viewBox="0 0 320 320" className="w-full" role="img" aria-labelledby="aeon-gap-title">
3994+
<title id="aeon-gap-title">Aeon primitive coverage: strong clock, absent listener, partial inbox, strong memory</title>
3995+
{/* Clock — strong */}
3996+
<g transform="translate(70, 100)">
3997+
<circle r="38" fill={C.sage} opacity="0.35" />
3998+
<circle r="38" fill="none" stroke={C.ink} strokeWidth="1.5" />
3999+
<path d="M-8 2 L-2 8 L10 -6" fill="none" stroke={C.moss} strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round" />
4000+
</g>
4001+
<text x="70" y="154" textAnchor="middle" fontFamily="var(--font-mono)" fontSize="9" fill={C.ink}>clock</text>
4002+
<text x="70" y="168" textAnchor="middle" fontFamily="var(--font-mono)" fontSize="7.5" fill={C.moss}>strong</text>
4003+
{/* Listener — absent */}
4004+
<g transform="translate(160, 100)">
4005+
<circle r="38" fill="none" stroke={C.rule} strokeWidth="1.5" strokeDasharray="5 4" />
4006+
<g stroke={C.rule} strokeWidth="2" strokeLinecap="round">
4007+
<line x1="-7" y1="-7" x2="7" y2="7" />
4008+
<line x1="7" y1="-7" x2="-7" y2="7" />
4009+
</g>
4010+
</g>
4011+
<text x="160" y="154" textAnchor="middle" fontFamily="var(--font-mono)" fontSize="9" fill={C.faint}>listener</text>
4012+
<text x="160" y="168" textAnchor="middle" fontFamily="var(--font-mono)" fontSize="7.5" fill={C.faint}>absent</text>
4013+
{/* Inbox — partial */}
4014+
<g transform="translate(250, 100)">
4015+
<circle r="38" fill={C.sage} opacity="0.12" />
4016+
<circle r="38" fill="none" stroke={C.ink} strokeWidth="1.5" strokeDasharray="6 3" />
4017+
<path d="M-8 0 Q-3 -6 0 0 Q3 6 8 0" fill="none" stroke={C.faint} strokeWidth="2" strokeLinecap="round" />
4018+
</g>
4019+
<text x="250" y="154" textAnchor="middle" fontFamily="var(--font-mono)" fontSize="9" fill={C.ink}>inbox</text>
4020+
<text x="250" y="168" textAnchor="middle" fontFamily="var(--font-mono)" fontSize="7.5" fill={C.faint}>partial</text>
4021+
{/* Memory — strong */}
4022+
<rect x="40" y="195" width="110" height="36" rx="5" fill={C.sage} opacity="0.2" />
4023+
<rect x="40" y="195" width="110" height="36" rx="5" fill="none" stroke={C.ink} strokeWidth="1.5" />
4024+
<path d="M78 207 L84 213 L96 201" fill="none" stroke={C.moss} strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" />
4025+
<text x="95" y="225" textAnchor="middle" fontFamily="var(--font-mono)" fontSize="9" fill={C.ink}>memory</text>
4026+
{/* Durability — strong */}
4027+
<rect x="170" y="195" width="110" height="36" rx="5" fill={C.sage} opacity="0.2" />
4028+
<rect x="170" y="195" width="110" height="36" rx="5" fill="none" stroke={C.ink} strokeWidth="1.5" />
4029+
<path d="M208 207 L214 213 L226 201" fill="none" stroke={C.moss} strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" />
4030+
<text x="225" y="225" textAnchor="middle" fontFamily="var(--font-mono)" fontSize="9" fill={C.ink}>durability</text>
4031+
{/* Dashed lines connecting rows */}
4032+
<line x1="70" y1="140" x2="70" y2="195" stroke={C.rule} strokeWidth="0.8" strokeDasharray="3 3" />
4033+
<line x1="160" y1="140" x2="160" y2="195" stroke={C.rule} strokeWidth="0.8" strokeDasharray="3 3" />
4034+
<line x1="250" y1="140" x2="250" y2="195" stroke={C.rule} strokeWidth="0.8" strokeDasharray="3 3" />
4035+
<text x="160" y="270" textAnchor="middle" fontFamily="var(--font-mono)" fontSize="9" fill={C.terracotta}>
4036+
strong foundation, missing the listener
4037+
</text>
4038+
</svg>
4039+
);
4040+
}

components/mdx/mdx-components.tsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,9 @@ import {
7878
JuniorIdentityFigure,
7979
JuniorSurveillanceFigure,
8080
JuniorMemoryFigure,
81+
AeonArchFigure,
82+
AeonHealFigure,
83+
AeonGapFigure,
8184
} from "./figures";
8285

8386
export const mdxComponents = {
@@ -161,6 +164,9 @@ export const mdxComponents = {
161164
JuniorIdentityFigure,
162165
JuniorSurveillanceFigure,
163166
JuniorMemoryFigure,
167+
AeonArchFigure,
168+
AeonHealFigure,
169+
AeonGapFigure,
164170
LinkedInEmbed: () => (
165171
<iframe
166172
src="https://www.linkedin.com/embed/feed/update/urn:li:share:7429634994467414016?collapsed=1"

0 commit comments

Comments
 (0)