-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathABSTRACTIONS.html
More file actions
230 lines (230 loc) · 23.6 KB
/
Copy pathABSTRACTIONS.html
File metadata and controls
230 lines (230 loc) · 23.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
<!doctype html>
<html lang="en">
<!-- GENERATED by catalog.py build — DO NOT EDIT. Edit the sibling .md and re-run `catalog.py build`. -->
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Abstractions</title>
<link rel="preconnect" href="https://fonts.googleapis.com"><link rel="preconnect" href="https://fonts.gstatic.com" crossorigin><link href="https://fonts.googleapis.com/css2?family=Source+Serif+4:ital,opsz,wght@0,8..60,400;0,8..60,600;0,8..60,700;1,8..60,400&family=Source+Sans+3:ital,wght@0,400;0,600;0,700;1,400&family=IBM+Plex+Mono:wght@400;500&display=swap" rel="stylesheet">
<style>
/* Legacy var aliases → design tokens: --line/--link predate the token model and are referenced across
the landing + views CSS; alias them so every site rule resolves to the Umber-Monograph tokens without
touching hundreds of call sites. The token :root (inlined via FONT_CSS) defines --ink/--muted/--accent. */
:root { --line: var(--rule); --link: var(--accent); }
* { box-sizing: border-box; }
body { margin:0; font-family:var(--font-body);
color:var(--ink); background:var(--paper); line-height:var(--lh-body); font-size:var(--fs-body); }
main { width: 94vw; max-width: 1320px; margin: 0 auto; padding: 32px 26px 80px; }
/* The landing is a figure-prose BOARD — a controlled ceiling so wide-screen scan-lines stay comfortable
(was 2100); entry/prose pages keep the 1320 reading width. */
body.landing main { max-width: 1600px; }
body.landing .site-foot { max-width: 1600px; }
nav.crumb { font-size: var(--fs-meta); color: var(--muted); margin: 0 0 18px; letter-spacing:.01em; }
nav.crumb a { color: var(--link); text-decoration: underline; text-underline-offset: 2px; }
nav.crumb a:hover { text-decoration: underline; }
/* "Calm authority": the page title (h1) is the one BOLD level; h2/h3 stay semibold (--display-weight)
via the shared binding, with more air above each so headings organise rather than compete. */
h1 { font-size: var(--fs-thesis-title); font-weight:700; margin: 6px 0 4px; letter-spacing:var(--display-tracking); line-height:1.12; }
h2 { font-size: var(--fs-section); margin: 38px 0 8px; padding-top: 6px; border-top:var(--border-hairline) solid var(--line); }
h3 { font-size: var(--fs-card-title); margin: 26px 0 6px; }
h4 { font-size: var(--fs-card-body); margin: 16px 0 4px; color:var(--ink); }
p, li { font-size: var(--fs-body); }
a { color: var(--link); }
code { background:var(--code-bg); padding:1px 5px; border-radius:var(--radius-chip); font-size:.9em;
font-family:var(--font-mono); }
pre { background:var(--code-bg); padding:12px 14px; border-radius:var(--radius-code); overflow:auto; }
pre code { background:none; padding:0; }
table { border-collapse: collapse; margin: 12px 0; font-size: var(--fs-meta); width:100%; }
th, td { border:var(--border-hairline) solid var(--line); padding:6px 10px; text-align:left; vertical-align:top; }
th { background:var(--panel); font-weight:700; }
hr { border:none; border-top:var(--border-hairline) solid var(--line); margin: 22px 0; }
.subtitle { font-size: var(--fs-meta); color:var(--muted); font-style: italic; margin: 0 0 6px; }
a.abbr { color:var(--ink); text-decoration:none; border-bottom:var(--border-hairline) dotted var(--accent);
cursor:help; }
a.abbr:hover { color:var(--accent); border-bottom-style:solid; }
section.abbr-entry { scroll-margin-top:14px; }
section.abbr-entry h2 code.slug { font-size:var(--fs-micro); font-weight:400; color:var(--accent);
background:var(--accent-tint); vertical-align:middle; margin-left:8px; }
p.abbr-grounds { font-size:var(--fs-meta); color:var(--muted); margin:4px 0 2px; }
/* Derived "Governed by" block — appended to is-a-model entry pages (reverse of the Governs join). */
.govby { margin-top:28px; border-top:var(--border-accent-bar) solid var(--accent); padding-top:6px; }
.govby h2 { border-top:none; padding-top:0; margin-top:8px; }
.gb-note { font-size:var(--fs-meta); color:var(--muted); font-style:italic; margin:2px 0 8px; }
.gb-list { margin:0; padding-left:20px; }
.gb-list li { font-size:var(--fs-meta); margin:4px 0; }
.gb-list li a { font-weight:600; text-decoration:none; }
.gb-list li a:hover { text-decoration:underline; color:var(--accent); }
.gb-all { font-size:var(--fs-micro); color:var(--muted); background:var(--panel); border:var(--border-hairline) solid var(--rule);
border-radius:var(--radius-chip); padding:0 6px; margin-left:5px; white-space:nowrap; }
.tag { color: var(--accent); font-weight: 700; font-size: var(--fs-micro); letter-spacing:.08em; text-transform:uppercase; }
.census h3.role-h { color:var(--accent); border-top:var(--border-accent-bar) solid var(--line); padding-top:14px; margin-top:26px; }
.census .role-note { font-size:var(--fs-micro); color:var(--muted); background:var(--accent-tint); border-left:var(--border-accent-bar) solid var(--accent);
padding:7px 12px; border-radius:0 var(--radius-code) var(--radius-code) 0; margin:2px 0 10px; }
/* Census tables read as the card language: no full cell-grid — row hairlines only, header a stronger
bottom rule, warm-panel header fill. */
table.census-t th, table.census-t td { border:none; border-bottom:var(--border-hairline) solid var(--line); }
table.census-t thead th { border-bottom:2px solid var(--rule); background:var(--panel); }
table.census-t td.c-name a { font-weight:600; text-decoration:none; }
table.census-t td.c-name a:hover { text-decoration:underline; }
table.census-t td.c-sum { font-size:var(--fs-meta); color:var(--muted); }
table.census-t td.c-enf { white-space:nowrap; color:var(--ink); }
table.census-t th, table.census-t td { vertical-align:top; }
table.census-t tr:hover { background:var(--panel); }
.fam-lede { font-size:var(--fs-meta); color:var(--muted); font-style:italic; margin:2px 0 6px; }
.foot { font-size: var(--fs-micro); color: var(--muted); border-top:var(--border-hairline) solid var(--line); padding-top:14px; margin-top: 34px; }
/* Concept Card (the Concepts section's per-idea page). Single umber accent throughout — the section's
identity is the warm accent-tint band + the "Concept" chip + its idea glyph, never a new hue. */
.concept-band { display:flex; align-items:center; gap:12px; background:var(--accent-tint);
border-left:var(--border-accent-bar) solid var(--accent);
border-radius:0 var(--radius-code) var(--radius-code) 0; padding:8px 14px; margin:2px 0 20px; }
.concept-chip { display:inline-flex; align-items:center; gap:6px; color:var(--accent); font-weight:700;
font-size:var(--fs-micro); letter-spacing:.08em; text-transform:uppercase; white-space:nowrap; }
.concept-chip .cc-ico { width:1.1em; height:1.1em; flex:0 0 auto; }
.concept-kicker { font-size:var(--fs-meta); color:var(--muted); }
figure.cc-fig { margin:20px 0; max-width:660px; }
figure.cc-fig svg { width:100%; height:auto; }
section.cc-rel, section.cc-mech, section.cc-intuition, section.cc-read { margin-top:8px; }
ul.cc-links { list-style:none; margin:8px 0; padding:0; }
ul.cc-links li { margin:5px 0; }
ul.cc-links li a { font-weight:600; text-decoration:none; }
ul.cc-links li a:hover { text-decoration:underline; color:var(--accent); }
.cc-mech-empty { font-size:var(--fs-meta); color:var(--muted); font-style:italic; margin:8px 0; }
a.cc-read-link { font-weight:600; text-decoration:none; }
a.cc-read-link:hover { text-decoration:underline; }
/* The brick's single "→ read the concept" link into each rich Concept ENTRY (two-tier split). */
a.s-concept { display:inline-block; font-size:var(--fs-meta); font-weight:600;
color:var(--accent); text-decoration:none; }
a.s-concept:hover { text-decoration:underline; }
/* GENERATED by book-models/design_tokens.py from design-tokens.json — do not hand-edit. */
:root {
--ink: #1c1917;
--paper: #fdfcf9;
--panel: #f6f4ef;
--rule: #e4e0d8;
--muted: #57534e;
--accent: #9a3f12;
--accent-tint: #faf1e6;
--link: #9a3f12;
--code-bg: #f3efe7;
--box-thesis-rule: #15803d;
--box-thesis-fill: #eef7ee;
--box-def-rule: #1f6fae;
--box-def-fill: #eef4fb;
--box-inset-rule: #7c6bb0;
--box-inset-fill: #f2effb;
--diagram-churn: #b23b3b;
--diagram-churn-fill: #fbeaea;
--diagram-fleet: #2f5169;
--diagram-fleet-fill: #e7edf3;
--diagram-governed: #1f7a4d;
--diagram-governed-fill: #e3f0e7;
--diagram-trust: #155c38;
--diagram-trust-fill: #eef7f0;
--font-display: "Source Serif 4", Charter, "IBM Plex Serif", Georgia, serif;
--font-body: "Source Sans 3", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
--font-mono: "IBM Plex Mono", "SF Mono", Menlo, Consolas, monospace;
--display-weight: 600;
--display-tracking: -0.01em;
--fs-micro: 12px;
--fs-meta: 14px;
--fs-card-body: 16px;
--fs-body: 18px;
--fs-card-title: 22px;
--fs-section: 28px;
--fs-thesis-title: 36px;
--fs-display: 52px;
--lh-body: 1.62;
--lh-display: 1.08;
--lh-card: 1.5;
--space-0: 4px;
--space-1: 8px;
--space-2: 16px;
--space-3: 24px;
--space-4: 32px;
--space-5: 48px;
--space-6: 64px;
--radius-card: 10px;
--radius-chip: 4px;
--radius-code: 6px;
--border-hairline: 1px;
--border-accent-bar: 3px;
--border-box-rule: 4px;
}
body { font-family:var(--font-body); }
h1,h2,h3,h4,.walk-h,.section-h { font-family:var(--font-display); font-weight:var(--display-weight); }
.site-foot { max-width:1320px; margin:var(--space-5) auto 0; padding:var(--space-2) 26px var(--space-4); border-top:var(--border-hairline) solid var(--rule); font-size:var(--fs-micro); color:var(--muted); text-align:center; }
.site-foot a { color:var(--accent); text-decoration:underline; } .site-foot a:hover { text-decoration:none; }
.site-foot .gh { white-space:nowrap; }
.site-foot .foot-line { display:block; }
.site-foot .foot-line + .foot-line { margin-top:var(--space-1); }
.site-foot .foot-nsf { color:var(--muted); }
.topnav { position:absolute; top:14px; right:20px; font-size:var(--fs-micro); display:flex; gap:var(--space-2); }
.topnav a { color:var(--muted); text-decoration:none; white-space:nowrap; } .topnav a:hover { color:var(--accent); }
@media (max-width:640px){ .topnav { position:static; justify-content:flex-end; margin:0 0 var(--space-1); } }
</style>
</head>
<body>
<main>
<nav class="crumb"><a href="index.html">Home</a> / Abstractions</nav>
<h1>Abstractions</h1>
<p><strong>Intent</strong> — A glossary of the concrete artifacts the catalogue's mechanisms are built from, each named by its <strong>role and shape</strong>. Each implementation is custom to a distinct engineering context. I hope these descriptions give you ideas for yours.</p>
<p>Every abstraction below carries a <strong>slug</strong> (the citation key, shown in brackets), a definition, the artifact it <strong>grounds</strong> in the reference system (named once, for concreteness), and a <strong>see</strong> link to the mechanism that governs it. To cite one from an entry, write <code>[[slug]]</code> (renders the headword) or <code>[[slug|custom text]]</code> (renders your own words) — hovering shows the definition.</p>
<hr />
<section class="abbr-entry" id="repo-query"><h2>Model query tool <code class="slug">[[repo-query]]</code></h2>
<p>The canonical, self-describing read/query API over the system models — a tool with deterministic subcommands that emit structured JSON — so an agent reads the system's compressed truth through one interface instead of re-parsing raw model files and getting the dialect subtly wrong.</p>
<p><strong>Grounds</strong> — a repo-query CLI (<code>repo-query.py</code>). <strong>See</strong> — <a href="models-bridge/system-models/query-surface.html">model query surface</a>.</p></section>
<section class="abbr-entry" id="component-registry"><h2>Component registry <code class="slug">[[component-registry]]</code></h2>
<p>A typed registry mapping every component to its code zone — focus-dirs, tags, boundary kind, and sanctioned seams — so "which component owns this file, and what may touch it" is a queried fact rather than a hardcoded path list that drifts the moment a directory moves.</p>
<p><strong>Grounds</strong> — a typed component registry (<code>components.py</code>, a <code>Component</code> dataclass set). <strong>See</strong> — <a href="models-bridge/system-models/component-zone-model.html">component & zone model</a>.</p></section>
<section class="abbr-entry" id="boundary-seam-classifiers"><h2>Boundary & seam classifiers <code class="slug">[[boundary-seam-classifiers]]</code></h2>
<p>Typed helpers that classify each component's boundary kind, its outside-touching seams, and its sanctioned read surfaces — the zone <em>meaning</em> the directory layout does not carry, named once so lints and dispatch read it instead of re-inferring it per tool.</p>
<p><strong>Grounds</strong> — boundary-kind / external-seam / read-surface classifiers (<code>boundary_kinds.py</code>, <code>external_seams.py</code>, <code>canonical_read_surfaces.py</code>). <strong>See</strong> — <a href="models-bridge/system-models/component-zone-model.html">component & zone model</a>.</p></section>
<section class="abbr-entry" id="reverse-mapping-test"><h2>Reverse-mapping parity test <code class="slug">[[reverse-mapping-test]]</code></h2>
<p>A characterization test that asserts a model matches the real tree in <strong>both</strong> directions — every model row ↔ a real thing on disk, and every real thing ↔ a model row — so the model cannot silently diverge from the code it describes.</p>
<p><strong>Grounds</strong> — the model↔tree reverse-mapping tests (the <code>test_*_reverse_mapping</code> family). <strong>See</strong> — <a href="models-bridge/system-models/drift-parity-gates.html">drift & parity gates</a>.</p></section>
<section class="abbr-entry" id="mediator-registry"><h2>Mediator registry <code class="slug">[[mediator-registry]]</code></h2>
<p>A typed registry of the dev-time subprocess serializers — what each one mediates (the test runner, the build compiler, and so on), its concurrency cap, and its bypass switch — read by the enforcers that refuse an un-mediated call, so a newly added subprocess can be checked for coverage.</p>
<p><strong>Grounds</strong> — a dev-mediator registry (<code>mediators.py</code>). <strong>See</strong> — <a href="models-bridge/system-models/concurrency-contracts.html">mediator & single-writer contracts</a>.</p></section>
<section class="abbr-entry" id="single-writer-registry"><h2>Single-writer registry <code class="slug">[[single-writer-registry]]</code></h2>
<p>A typed registry declaring which state-mutation functions are single-writer / monopoly — exactly one writer, no concurrent mutation — so a coverage lint can flag a mutator that should be contracted but isn't.</p>
<p><strong>Grounds</strong> — a single-writer / monopoly-contract registry (<code>state_mutator_registry.py</code>). <strong>See</strong> — <a href="models-bridge/system-models/concurrency-contracts.html">mediator & single-writer contracts</a>.</p></section>
<section class="abbr-entry" id="synchronization-registry"><h2>Synchronization registry <code class="slug">[[synchronization-registry]]</code></h2>
<p>A typed model of every OS-level lock — the primitive it guards, its declared acquisition sites, and the required acquisition <em>ordering</em> — so an undeclared lock and a deadlock-inducing inverted ordering become detectable by a lint rather than discoverable only by deadlock. Composes three record kinds: a lock, an acquirer, and an ordering constraint.</p>
<p><strong>Grounds</strong> — a synchronization (meta-sync) registry (<code>synchronization.py</code>). <strong>See</strong> — <a href="models-bridge/system-models/synchronization-model.html">synchronization model</a>.</p></section>
<section class="abbr-entry" id="deployment-topology-loader"><h2>Deployment-topology loader <code class="slug">[[deployment-topology-loader]]</code></h2>
<p>A typed loader for the managed-deployment topology — which service runs where, and how the deployment layers may depend on one another — that deploy scripts and layering lints read instead of hardcoding the topology as scattered constants.</p>
<p><strong>Grounds</strong> — a typed deployment-topology loader (<code>deployment_topology.py</code>). <strong>See</strong> — <a href="models-bridge/system-models/deployment-topology-model.html">deployment & tier topology</a>.</p></section>
<section class="abbr-entry" id="service-tier-registry"><h2>Service-tier registry <code class="slug">[[service-tier-registry]]</code></h2>
<p>A typed classification of each service's tier, read by deploy and parity checks rather than restated as scattered per-script constants that drift when a service moves tier.</p>
<p><strong>Grounds</strong> — a service-tier classifier (<code>service_tiers.py</code>). <strong>See</strong> — <a href="models-bridge/system-models/deployment-topology-model.html">deployment & tier topology</a>.</p></section>
<section class="abbr-entry" id="layer-boundary-contracts"><h2>Layer-boundary contracts <code class="slug">[[layer-boundary-contracts]]</code></h2>
<p>A typed declaration of the agent-substrate's layer boundaries — which layer may import which — so a cross-layer import is blocked by a boundary lint at build time rather than crossed quietly and discovered in review.</p>
<p><strong>Grounds</strong> — an agent-substrate layering model (<code>agent_substrate_layering.py</code>). <strong>See</strong> — <a href="models-bridge/system-models/deployment-topology-model.html">deployment & tier topology</a>.</p></section>
<section class="abbr-entry" id="aggregate-lint-runner"><h2>Aggregate lint runner <code class="slug">[[aggregate-lint-runner]]</code></h2>
<p>The whole-repo lint aggregator, singleton-locked so only one instance runs per host — a compute-protection mutex that keeps concurrent agent worktrees from stampeding the shared machine by all running the full lint sweep at once.</p>
<p><strong>Grounds</strong> — a repo-wide lint runner behind a host mutex (a <code>lint-all</code> command). <strong>See</strong> — <a href="agent/mediators-and-resource-locks/aggregate-compute-protection.html">aggregate compute protection</a>.</p></section>
<section class="abbr-entry" id="dispatch-tool"><h2>Dispatch tool <code class="slug">[[dispatch-tool]]</code></h2>
<p>The canonical entry point for launching a coding agent — it composes the brief, runs the pre-launch checks, records the agent in the lifecycle registry, and launches it into an isolated worktree, so every agent enters the fleet the same audited way rather than by an ad-hoc hand-rolled invocation.</p>
<p><strong>Grounds</strong> — an agent-dispatch CLI (<code>dispatch.py</code>). <strong>See</strong> — <a href="agent/context-and-dispatch/role-typed-dispatch.html">role-typed dispatch</a>.</p></section>
<section class="abbr-entry" id="brief-lint"><h2>Brief lint <code class="slug">[[brief-lint]]</code></h2>
<p>A lint run over an agent's brief <em>before</em> the agent launches — it verifies every mandatory marker and snippet (worktree isolation, self-check, commit cadence, …) is present, and refuses the launch if not, so a malformed brief never reaches an agent.</p>
<p><strong>Grounds</strong> — a pre-launch brief linter (<code>agent_prompt_lint.py</code>). <strong>See</strong> — <a href="agent/context-and-dispatch/brief-linting.html">brief linting</a>.</p></section>
<section class="abbr-entry" id="dispatch-self-check"><h2>Dispatch self-check <code class="slug">[[dispatch-self-check]]</code></h2>
<p>A self-check an agent runs at boot asserting it is operating inside its sanctioned worktree and on its own branch (not the shared trunk) — if the assertion fails the agent bails out, so a mis-placed agent cannot mutate the wrong tree.</p>
<p><strong>Grounds</strong> — an agent-boot canonical-dispatch assertion (<code>assert-agent-canonical-dispatch.py</code>). <strong>See</strong> — <a href="agent/context-and-dispatch/brief-linting.html">brief linting</a>.</p></section>
<section class="abbr-entry" id="test-serializer"><h2>Test-runner serializer <code class="slug">[[test-serializer]]</code></h2>
<p>A host-level <code>flock</code> wrapper that serializes the test runner so exactly one test process runs per machine at a time — concurrent agent worktrees route their runs through it instead of invoking the runner raw and saturating the host.</p>
<p><strong>Grounds</strong> — a test-runner flock mediator (<code>test-serializer.py</code>). <strong>See</strong> — <a href="agent/mediators-and-resource-locks/test-serializer.html">test-runner serializer</a>.</p></section>
<section class="abbr-entry" id="build-serializer"><h2>Build serializer <code class="slug">[[build-serializer]]</code></h2>
<p>A host-level semaphore wrapper that caps how many heavy build/compile invocations run at once per machine — the sibling of the test serializer for the adjacent (build/typecheck) compute class.</p>
<p><strong>Grounds</strong> — a build/compile semaphore mediator (<code>build-serializer.py</code>). <strong>See</strong> — <a href="agent/mediators-and-resource-locks/build-serializer.html">build serializer</a>.</p></section>
<section class="abbr-entry" id="event-bus"><h2>Event bus <code class="slug">[[event-bus]]</code></h2>
<p>An append-only, typed event log that lifecycle tools emit to (dispatch, sentinel, merge-train, tombstone, cron) and the orchestrator reacts over — one observable stream of what the fleet is doing, rather than state scattered across tools.</p>
<p><strong>Grounds</strong> — a typed append-only event log (<code>event-bus.py</code>). <strong>See</strong> — <a href="agent/lifecycle-and-observability/typed-event-bus.html">orchestrator-as-reactor over an event bus</a>.</p></section>
<section class="abbr-entry" id="agent-registry"><h2>Agent registry <code class="slug">[[agent-registry]]</code></h2>
<p>An append-only log that is the authoritative record of which agents are currently in flight — every lifecycle tool dual-writes it, and cleanup/tombstone gates query it first, so "who is live" is a fact rather than a guess from directory listings.</p>
<p><strong>Grounds</strong> — an append-only agent registry (<code>agent-registry.jsonl</code>). <strong>See</strong> — <a href="agent/lifecycle-and-observability/agent-registry.html">agent registry</a>.</p></section>
<footer class="site-foot"><span class="foot-line foot-copy">© <a href="https://davisjam.github.io">James C. Davis</a>, 2026–present · Assistant Professor, ECE @ Purdue</span><span class="foot-line foot-links"><a class="gh" href="https://github.com/davisjam/model-based-agentic-software-engineering"><svg viewBox="0 0 16 16" width="15" height="15" aria-hidden="true" style="vertical-align:-2px;fill:currentColor"><path d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.01 8.01 0 0016 8c0-4.42-3.58-8-8-8z"></path></svg> model-based-agentic-software-engineering</a> · <a class="book-foot" href="book/index.html">Read the book →</a></span><span class="foot-line foot-nsf">This work was supported by the U.S. National Science Foundation under grants #2541917 and #2452533.</span></footer>
</main>
</body>
</html>