The Plastic Substrate
In materials science, plastic deformation is the part of a material's response to stress that does not spring back. Push a steel beam past its elastic limit and the bend stays. Push a fluid and it flows away. Plastic deformation sits between the two.
A plastic substrate, in software, is an authored layer that behaves the same way under use. The user edits something. The behavior of the system on the next invocation is different in a way the user intended, in a form the user can read back. The deformation persists and the record is legible.
What follows is the architecture of that layer. While examples are from Claude Code for familiarity, the pattern should translate into any harness.
The Three Layers⚓︎
The substrate sits across three layers. Each holds a different kind of state with a different lifetime.
The Playbook is the authored layer. It holds authored items — rules, recipes, schedules, schemas — written by the user or captured by the agent, that persist across sessions and shape the next invocation. An edit on Tuesday changes the agent's behavior on Wednesday: on the laptop, on the build server, in any subagent that spawns under it. The Playbook is where the substrate deforms.
In Claude Code, the Playbook is everything in CLAUDE.md and under .claude/. CLAUDE.md holds rules the agent reads on every turn. .claude/skills/ holds named procedures invoked by topic match. .claude/commands/ holds slash commands invoked by name. .claude/hooks/ holds events fired on session lifecycle, tool calls, or external triggers. Each lives in a directory tree the user can read, edit, and version.
The Runtime is the active session. The prompt, the agent's tool use, the streamed output. Items from the Playbook fire here — threads execute, subagents spawn, views render, events trigger. Nothing in the Runtime survives the session.
In Claude Code, the Runtime is a single claude invocation. Subagents spawn into nested sessions. Tool calls reach into the working directory and the network. The streamed transcript is the Runtime's only direct output. When the session closes, the Runtime is gone.
The Filesystem is where outputs accrue. Artifacts the agent wrote into the working directory. Transcripts of past sessions, indexed for future ones to read. A provenance ledger that records, for every artifact, which session produced it and which Playbook items were in scope at the time. The Filesystem is the substrate's long memory.
In Claude Code, the Filesystem is ~/.claude/projects/<repo-hash>/ — transcripts, indexed history — plus the working directory the agent edits in. Both are version-controlled by their owners. Both feed back into future Playbook edits.
| Layer | Role | Holds |
|---|---|---|
| Playbook | Deforms | Authored items: rules, invocables, events, views |
| Runtime | Fires | Threads, subagent runs, view renders, event handlers |
| Filesystem | Persists | Artifacts, transcripts, provenance ledger |
A simple test separates a plastic substrate from things that look like one. An edit must do two things: change what the system does next time the way you intended, and leave a record you can read back later. Saved vendor preferences can fail the first — the platform may quietly override or ignore your setting. Trained model weights fail the second — something changed durably, but it's encoded in numbers no human can inspect. A markdown line the agent reads on the next turn passes both.
The Four Shapes⚓︎
Every authored item in the Playbook answers three questions. What's in it. When does it fire. What comes out. The named shapes — Rule, Invocable, Event, View — are common answer patterns.
| Shape | What's in it | When fires | What comes out |
|---|---|---|---|
| Rule | text | always · topic | context |
| Invocable | text [+ script] | name | context · artifact · side-effect |
| Event | script [+ text] | trigger | side-effect · context |
| View | schema | name · trigger | UI · artifact |
As an example of a hybrid shape, a Claude Code slash command for release status reads three columns at once:
| Item | What's in it | When fires | What comes out | Reads as |
|---|---|---|---|---|
/release-status |
text + script | name | context + UI + artifact | Invocable + View |
A short walk through each question grounds the answer-values.
What's in it. Three values:
- Text — what the LLM reads. A persona in
CLAUDE.mdinjected every turn. A reference document on API conventions, pulled in when the topic matches. - Script — deterministic code the runtime executes. A pre-commit hook in
.claude/hooks/. A step inside an Invocable that calls a build API. - Schema — a renderer's input. A
view.jsondeclaring the columns and field-types of a release dashboard, against which the UI is produced.
When does it fire. Four values:
- Always — every turn. A persona injected into every prompt.
- On topic — when the active task matches the item's scope. A Typescript-conventions reference pulled in only when Typescript is in play.
- By name — when the user calls it.
/release-status. A subagent definition the orchestrator addresses by handle. - On trigger — deterministic firing on an observable signal. A pre-commit hook on a commit. A nightly digest on a schedule. A webhook handler on inbound HTTP.
Hooks and crons differ only in which trigger fires them; both are Events.
What comes out. Four values:
- Context — text read back into the LLM. A Rule injected into the prompt. An Invocable's structured brief returned to the orchestrator.
- Artifact — a file pinned to the Filesystem with provenance attached. A markdown report. A generated migration. A test fixture.
- Side-effect — a deterministic external write. A database migration applied. A build triggered. A Slack message sent.
- UI — a rendered surface. The dashboard a
/release-statusinvocation displays. The status-report card a stakeholder-update Invocable hands back.
Cross-Cutting Properties⚓︎
Every shape carries the same metadata. Three properties cover what the substrate must record on each item, in the same way every file has a name, a size, and a modification time.
Provenance is the load-bearing property. Source, version, authorship chain — including whether the author was the user or the agent itself. The author writes a source string in frontmatter — source: pack:typescript-conventions@v3, source: agent-captured, source: regulator:victoria-payroll. A Rule the user typed into CLAUDE.md and a lesson the agent captured from a session transcript both land in the Playbook; their source strings differ, and downstream review treats them differently. Human-led authorship is throttled by how often the user remembers to look; agent-led authorship is throttled only by how often the harness runs, which is how small improvements accumulate during sessions the user is not thinking about. From that single field, three jobs follow. The harness honors precedence when a user edit, a vendor rule, and a Pack-imported lesson coexist. It furnishes the audit trail every regulated context requires, because every rule the agent applied traces back to an authoring source. It gives the user reversibility — strip the Playbook by source when something misbehaves, leave the rest intact.
Scope bounds what any one item can reach. Tools, connections, files, network. A skill in .claude/skills/db-migrate/ with allowedTools: [Bash(psql:*)] and a connection to the production database has a different Scope from one whose declared scope is Read-only on the current repo. A change to Scope is a reviewable event, which is how the substrate avoids blast-radius surprises. The author declares Scope in the item's frontmatter; the harness enforces it at injection.
Telemetry is feedback metadata in two directions. Retrospective: what fired, how often, with what hit-rate — surfaced from the per-session transcripts the harness ledgers under ~/.claude/projects/<repo-hash>/. Prospective: dry-run before activation, replay against past sessions to see where a new Rule would have changed the outcome. The author declares minimal hooks on the item, often through a SessionEnd entry in .claude/hooks/; the harness provides the heavy lifting. The runtime mechanics that turn declared hooks into traces are the harness's concern, not the substrate's; the harness post lays them out.
Packs and Curation⚓︎
A Pack is the composition unit. A versioned, provenance-preserving bundle of Playbook items plus a manifest, distributable as a single object. The manifest is the Pack's top-level descriptor — name, version, inventory of items, declared scope, dependencies on other Packs — analogous to package.json for npm, Cargo.toml for Rust, or Chart.yaml for Helm. A Pack can carry any mix of the four shapes — a handful of Rules, an Invocable that references them, an Event that fires the Invocable on a schedule, a View the Invocable renders against. The composition unit and the distribution format are the same object. A Pack lands in the Playbook; the Runtime fires from it on the next session, and the Filesystem accrues the outputs with the Pack's source recorded against each.
| Tier | Who | Distribution |
|---|---|---|
| Personal | One user, one harness | Copy the folder |
| Firm | Shared inside an organisation | Internal registry, dotfiles repo |
| Public | Marketplace | Versioned, certified, supported like software |
What changes between tiers is governance, liability, and audience. The shapes and the provenance mechanism do not. Personal Packs are where most substrate-shaping happens; most never publish, because the specific shape they take is worth more to the author than to any general audience. Firm Packs encode norms a firm operates on but cannot publish externally without losing the differentiation the norms encode. Public Packs are where network effects accumulate, because every consumer's evidence improves the Pack the next consumer installs — and where abuse surfaces fastest, because a misbehaving Public Pack hits many consumers at once.
Without the substrate, every correction evaporates at session end — the agent fixes the instance and the friction returns next session. The substrate's first job is to make corrections stick: a user edit or an agent-captured lesson lands in the Playbook, traced by Provenance, and every future Runtime fires against the new shape.
The second job is curation — keeping the body of stuck corrections healthy over time. This is where the substrate earns out. Five of twenty Invocables sit unused. Two Events conflict on edge cases. An Invocable built against last year's model misbehaves on this year's. The Filesystem's transcripts and provenance ledger are the evidence base; the work moves from operating the substrate to maintaining it.
Network effects accumulate where agent-led curation meets a Public Pack. A Public Pack whose curation runs without the publisher in the loop gets better between releases on its own schedule: when v3.1 adds a Rule that survived on a subset of tenants, v3.2 ships it to every consumer, and the publisher's job becomes review rather than authorship.
Views as Generative Interfaces⚓︎
A generative interface is a UI produced from a schema rather than shipped as fixed code. The schema declares what is there — columns, fields, sections, actions; the harness's renderer (often the agent itself, generating code each invocation) turns the schema into a surface on the fly. The user authors the schema; the rendered surface gets produced for them. New schemas yield new interfaces; edited schemas reshape existing ones on the next invocation. Views are the substrate's generative-interface mechanism.
Views have more range than any other shape — a spectrum from disposable scratch surfaces to durable mini-apps to thin clients over external systems. Three patterns are worth naming.
Disposable. A View written for one task, then discarded. While debugging an agent run, the user renders a table of the last twenty tool calls from the session log: write the schema, read the output, delete the file when the bug is fixed. The substrate hosts the View for as long as the question lives.
Mini-app. A View that is actually a bundle — multiple Views, Invocables, and Events composed into something durable. Take a scheduling app inside a harness: a calendar View, an appointment-list View, Invocables to create and edit appointments, Events that fire reminders, Rules encoding booking policy. This is a Pack, not a single View. The "mini-app inside a harness" concept and the Pack primitive are the same object viewed from different angles. Personal mini-apps stay on one user's machine; firm-tier mini-apps get shared across a team.
Connected. A View that renders against state held elsewhere. The schema lives in the Playbook; the data comes from a connector — a database, an API, a CRM. Scope declares which connections the View can reach; a Script attached to the View's Invocable does the fetch. The harness owns the surface; the system of record stays where it was. This is how a substrate hosts a Linear panel or a Salesforce dashboard without owning the data.
Treating Views as a spectrum makes the substrate's UI surface area explicit. Most of the visible variation between substrates will accumulate here.
Conclusion⚓︎
A plastic substrate is an authored layer that deforms persistently and legibly under use. Edit it on Tuesday; the agent behaves differently on Wednesday, the way you intended, in a form you can read back later.
The architecture has three layers (Playbook, Runtime, Filesystem), four shapes inside the Playbook (Rule, Invocable, Event, View), three properties on each item (Provenance, Scope, Telemetry), and Packs at three tiers (Personal, Firm, Public). Items enter the Playbook by user edit or agent capture. Over time, the Playbook needs curation.
Polished tools win the first week. Shapeable tools win the sixth month.
See also: Harness Engineering: A Composable Architecture — the architecture for the firing discipline this surface fires from.