HEART Embedded Systems logoHEART

HEART Core Standard 1.0#

Reading tracks3 Advanced
Advanced only (Stop 3B): Sections 1 to 9, 11 and 12; Section 10 for machines (Stop 3C). Which track am I?

An open standard for embedded AI in any app, appliance or control system

Author: M. K. Patil Status: Working draft 1, November 2026. A reference implementation exists (heart-core-rs, version 0.6.0). It has not been tested on physical hardware or with a real model. Companion to: HEART API Standard 1.0 Track: Advanced only (Stop 3B): Sections 1 to 9, 11 and 12; Section 10 for machines (Stop 3C).

The key words MUST, MUST NOT, SHOULD and MAY are to be read as in RFC 2119 and RFC 8174.


1. What HEART Core is#

HEART Core is the small runtime that lives inside a product, understands the whole HEART API, and uses it to serve people, other systems and the product itself.

Someone can say "how full is the tank?" or "restart the controller on Sunday night", and the Core works out which operation is meant, checks it, carries it out and explains what happened.

The API Standard says how to talk to a system. This standard says what must be inside it to listen.

1.1 How this fits "the brain can live anywhere"#

HEART's founding principle still holds. The Core does not need a large model, because most of what it must understand is already written down. The API is finite and machine-readable, and a product's commands are described in its Card and custom definitions. Finding the right operation is mainly a lookup problem, and rules solve most of what remains.

A model is an optional extra, used for messy language and hard diagnosis. It can be small and local, or large and in the cloud. A Core with no model at all is still a conforming Core.

Knowledge lives in the system. Rules keep it safe. Models make it fluent.


2. Design rules#

These six rules are the standard in brief.

RuleMeaning
1. One doorThe Core acts only through the HEART API, like any other caller. It has no private path to the hardware, so every check always applies.
2. Know, don't guessEvery action resolves to an entry in the API Index or System Map. Anything else is not understood.
3. Models propose, the Core checksModel output is a suggestion in a fixed format. Nothing a model says is ever executed directly.
4. Works with no modelAwareness, safety, alerts and basic serving never depend on a model or a network.
5. Do no harm to the hostA failing Core never disturbs the product. The product must run the same with the Core dead.
6. Bounded everythingMemory, CPU, queues, storage, time and money all have fixed limits.

3. Architecture#

        people      other systems      the product itself
           │              │                    │
           ▼              ▼                    ▼
  ┌──────────────────────────────────────────────────┐
  │                   HEART API                      │ ◄── the one door
  └───────────▲─────────────────────────▲────────────┘
              │ serve                   │ every action
  ┌───────────┴─────────────────────────┴────────────┐
  │                   HEART CORE                     │
  │                                                  │
  │   UNDERSTAND         DECIDE            ACT       │
  │   ┌──────────┐    ┌────────────┐   ┌──────────┐  │
  │   │ Resolver │ ─► │ Grounding  │ ─► │ Executor │  │
  │   │          │    │ and policy │   │          │  │
  │   └────▲─────┘    └─────▲──────┘   └────┬─────┘  │
  │        │                │               │        │
  │   ┌────┴────────────────┴───────────────▼─────┐  │
  │   │ KNOWLEDGE: API Index · System Map         │  │
  │   │            Playbooks · Memory             │  │
  │   └────▲──────────────────────────────────────┘  │
  │        │                                         │
  │   ┌────┴──────┐    ┌────────────┐                │
  │   │ Antaryami │    │ Model Slot │ ◄── optional   │
  │   │ awareness │    │ (empty OK) │                │
  │   └───────────┘    └────────────┘                │
  └──────────────────────────────────────────────────┘
PartJob
AntaryamiKeeps the live picture of state, events and health.
KnowledgeWhat the Core knows: see Section 4.
ResolverTurns a request into an Intent, using the tiers in Section 5.
Grounding and policyRefuses anything not grounded, then applies clearance, guards and the gate.
ExecutorCalls the API and reports the outcome.
Model SlotHolds an optional local or cloud model behind one interface.

4. How the Core understands the API#

Understanding comes from three pieces of knowledge. All of them are data, so they can be inspected, tested and updated without changing the Core.

4.1 API Index: what any HEART system can do#

The API Index is generated from the OpenAPI file by tools/build_index.py, so it cannot drift from the standard. Every Core ships with the same one: core/api-index-1.0.json, schema api-index.

Each entry gives the operation, its parameters, risk, scope, and the plain phrases people use for it:

{
  "id": "postTendingStop",
  "method": "POST",
  "path": "/heart/v1/tending/stop",
  "level": "module-control",
  "summary": "Stop all autonomous action at once",
  "risk": "read",
  "scope": "heart.tend",
  "phrases": ["stop acting", "hands off", "stop autonomy", "stop all automatic actions"]
}

The whole index for all 124 operations is 27 KB, or 5.5 KB compressed. This is small enough to fit almost anywhere.

Phrases are data, so translations and regional wording can be added as language packs.

4.2 System Map: what this system can do#

The System Map is built at startup from the system's own Card, card.modules, custom definitions, properties and components. It filters the API Index down to what really exists here, and adds product commands. A custom definition's title and description make it understandable with no further work (API Standard, Section 14).

The map MUST be rebuilt whenever a definition changes. mapRevision in GET /heart/v1/core shows which version is live.

4.3 Playbooks: what to do when#

A Playbook is a Tending rule (heart.rule) linking a condition to a response. Playbooks are the Core's reflexes.

  • when is either a check on a signal (a check: it fires each time a new sample makes the check hold), or an event trigger (event, optional component, count, windowSec). Received messages can never match a rule.
  • then runs a capability (capability, arguments), raises an alert (raise: code, severity, summary), or both. A learned Playbook also carries expect and undoIf (Section 7.6).

Playbooks can come from the vendor, the owner or lessons learned, and every one starts proposed. Only a human with heart.admin and proof of presence adopts one, with PUT /heart/v1/tending/rules/{id}, and the Core records adoptedBy, adoptedAt and adoptedPhysical. A rule runs only if enabled is true and status is adopted. It never runs a physical capability unless adoptedPhysical is true.


5. Four tiers of intelligence#

The Resolver tries the lowest tier able to answer, and moves up only when needed. Each tier works if those above it are missing.

TierHow it worksNeedsGood for
ReflexCompiled rules and PlaybooksNothingProtection, alerts, known faults. Always on.
RecallMatching against the Index and MapA few KBDirect requests such as "show the logs"
LocalSmall on-device model in the Model SlotLocal computeMessy wording, offline language, sensitive data
CloudLarge model through the Reason formatNetwork, budgetDiagnosis, explanation, unusual requests

ai.reasoning in the Pulse reports rules-only for Reflex and Recall, local for Local and cloud for Cloud.

A model never sees the whole API. The Recall tier builds a shortlist of at most 8 candidates, and only those go to the model. If Recall matches nothing, the shortlist is the product's own commands, up to 8. Only these go to the model, with an output format limited to those targets. This keeps a small model workable, cuts cloud cost, and prevents invented commands.

Everything sent to a cloud model passes the Valve, and the request text is marked untrusted.


6. Serving a request#

POST /heart/v1/serve takes plain language and returns an outcome. A system offering it must be at HEART Full, because anything beyond reading waits for approval through the Full operations. Spoken, typed and machine-generated requests all arrive the same way.

 request
    │
 1. UNDERSTAND   tiers produce an Intent
    │
 2. GROUND       one known target? every value accounted for?
    │
 3. CHECK        schema, clearance, guards, gate
    │
 4. ACT          call the API as anyone else would
    │
 5. EXPLAIN      say what happened, in plain language
{
  "outcome": "pending-approval",
  "intent": {
    "target": "com.acme.pump.set_flow",
    "arguments": { "litresPerMin": 40 },
    "grounding": { "litresPerMin": "stated" },
    "tier": "local",
    "confidence": 0.93
  },
  "actionId": "11111111-2222-4333-8444-555555555555",
  "answer": "This changes a physical pump, so it is waiting for an operator to approve it."
}
OutcomeMeaning
doneCarried out, or answered.
pending-approvalUnderstood, and waiting for a human.
needs-clarificationMore than one reading, or a value is missing. question says what is needed.
refusedUnderstood, but not allowed. reason says why.
not-understoodNo known target. The Core says so rather than guessing.

6.1 Grounding rules#

Confidence scores from models are unreliable, so the Core does not rely on them alone. An Intent may proceed only if:

  1. Its target exists in the System Map.
  2. Exactly one target fits. If two remain, the Core MUST ask.
  3. Every argument is accounted for in grounding as stated in the request, a default from the definition, or system-state read just now. Invented values are not allowed. The Core MUST check each claim: a stated value must appear in the request, and a default must equal the default the definition declares. A claim the Core cannot check MUST be refused.
  4. Arguments pass the input schema.

6.2 Plain language is never a direct command#

A request that had to be interpreted might have been misunderstood. So:

  1. Every action from /serve runs with initiator.kind: "ai" and onBehalfOf set to the caller, even when the Core used no model. It therefore passes the API Standard's gate in Section 6.3, and a physical action counts as destructive.
  2. Only read operations may run without confirmation.
  3. For anything else, the Core MUST state exactly what it will do, including target, values and timing, and wait for a confirmation that goes through the normal approval path.

Testing shows why (Section 12). In a Recall trial, "Schedule a restart for Sunday night" matched an immediate restart. The confirmation step exists to catch exactly that kind of error.

Stop is the exception to confirmation. A request to stop automatic action ("stop", "stop autonomy", "stop all automatic actions") MUST run Stop (postTendingStop) at once, because stopping is always the safe direction. A request to stop a thing ("stop the conveyor") names a target, so the Core MUST NOT answer it with Stop, which would leave the conveyor running. It maps the request to that thing's halt capability (API Standard 6.4), which then waits for confirmation like any physical action. If the thing has no halt, the Core says so, and says that "stop automatic actions" stops the HEART's own actions.

POST /heart/v1/tending/proposals MUST NOT be a /serve target, and has no phrases in the API Index. A Proposal comes from a brain with its own token (Section 7.3), never from interpreted language.


7. Self-care#

The Core runs one loop, in the tradition of the MAPE-K loop from autonomic computing:

StepWhat happensWorks with no model?
SenseAntaryami updates the live picture.Yes
JudgePlaybooks and thresholds spot problems.Yes
ActAllowed actions run through the API.Yes
ExplainTemplates describe what happened. A model MAY improve the wording.Yes
ConsultUnknown problems go to a model, if one is allowed, as a Consultation and a Proposal (Section 7.1).Optional
LearnOutcomes become proposed Playbooks for a human to adopt (Section 7.6).Optional

This loop satisfies Minimum Tending in the API Standard.

7.1 Consulting a brain: the safe loop#

A HEART sees every signal inside its system. When its own rules cannot explain or fix a problem, it MAY consult a brain: a model in the Model Slot, a model on a nearby Gateway, or a model in the cloud. The brain can be anywhere. The rules below are the same wherever it is.

The brain proposes. The HEART decides. A brain never sends a command. It sends a Proposal, and the Core turns it into an Action that passes the gate like any other (Part 6, Sections 2 and 5).

StepWhat happensSection
1. DetectA Playbook, threshold or alert notices a problem.4.3
2. Reflex firstA matching Playbook runs, if there is one. The brain is consulted only for what reflexes cannot handle.5
3. SummariseThe Core builds a Consultation: features of the signals, not the raw signals.7.2
4. ProposeThe brain answers with a Proposal: a change, its expected effect, and when to undo it.7.3
5. CheckThe Core checks the Proposal, reads the current values itself, applies the envelope and guards, and the first Action passes the gate. A person approves where the gate says so.7.3, 7.4
6. TryThe change is applied as a Trial: in small steps, watched, with the undo already approved.7.5
7. VerifyThe Core checks the expected effect. If it did not happen, or things got worse, it undoes the change.7.5
8. RememberA fix that worked becomes a proposed Playbook, so next time it needs no brain.7.6

A Core MUST be able to run steps 1, 2, 5, 6 and 7 with no brain and no network.

7.2 What leaves the system: the Consultation#

A Consultation (consultation) travels as untrusted context in a Reason request whose task is propose, with output.schema set to the Proposal schema. It MUST pass the Valve.

FieldContent
idThe Consultation's ID. A Proposal answering it carries it as consultationId.
problemThe fault code (Part 3), when it started, and optionally the alert and a summary
featuresStatistics of the signals involved, each naming its signal, unit, window and privacy level
candidatesAt most 8 targets that could help (Section 5), each with its current values (read by the Core), declared range, envelope, guards and whether it is physical
historyEarlier Trials for this problem on this system, and their outcomes

Statistics. One list is used everywhere: in features, in checks (feature) and in signal tables.

StatisticMeaningUnit
valueThe latest sampleThe signal's
min, max, mean, stddevOver the windowThe signal's
trendChange per minute, by least squares over the windowThe signal's, per minute
overshootHow far the signal went past its setpoint, as a percentage of the last setpoint step%
countHow many events were reported for the signal in the windowEvents

Rules:

  1. Features, not streams. A Consultation MUST NOT contain raw samples. Each feature carries its signal's privacy level (privacy, default internal), and the Valve treats it at that level. A feature of a never-share signal MUST NOT be included. Features are computed on the device.
  2. Smallest useful window. The Core SHOULD send the shortest window that shows the problem.
  3. Untrusted. Logs, messages and text in the Consultation are marked untrusted (Part 6, Section 5.2).

7.3 What comes back: the Proposal#

A Proposal (proposal, message type heart.proposal, never public) becomes the first Action of a Trial, which carries its proposalId and trialId.

FieldContentRequired
idA UUIDYes
targetA capability in the System Map whose callers include aiYes
argumentsThe final values. If steps are given, the last step MUST equal them.Yes
stepsHow to get there in stages, each with its arguments and the waitSec before the next, such as "1.8, wait 600 s, then 1.6"No: one step
expectThe expected effect: one to eight checks, all of which must holdYes
undoIfWhen to undo: checks (any), an alert of at least a severity (newAlert), or bothYes
basisWhy, in plain language, for the person who approves and for the recordYes
confidencelow, medium or highNo
consultationId, problemCode, brainWhat it answers, and which brain (tier: local, gateway, cloud or fleet)No
createdAtWhen it was madeYes

A check (check) is a signal, a statistic (feature, default value), an operator (<, <=, >, >=, ==, !=) and a number. windowSec says how far back the statistic looks, never before the step being judged. withinSec says, for expect, by when after the last step the check must have held, and for undoIf, how long it is watched. Without withinSec, an expect check must hold within 600 seconds.

Delivery. A brain inside the system hands the Proposal to the Core directly. A brain on a Gateway or in the cloud delivers it with POST /heart/v1/tending/proposals ({"proposal"}), using a token with scope heart.propose. The brain sends no current values: the Core reads them itself (Section 7.5). The brain's token gives the Action no authority of its own: it runs without a person only through the owner's allowlist for ai (Section 7.4), and otherwise waits for a person, whose approval is the authority.

The Core checks a Proposal in this order and refuses the first failure:

CheckRefusal
The shape is valid, including expect and undoIf: a change that cannot be checked cannot be trusted400 invalid-request
Autonomy is not observe (Section 7.4)409 autonomy-stopped
The target exists in the System Map404 not-found
The target's callers include ai403 caller-not-allowed
The target is not destructive422 cannot-undo
Every step's values are inside the target's declared range422 out-of-range
Every step passes the target's input schema400 invalid-request
The Core can read the current value of every argument it will change422 cannot-undo
No other Trial is live on the target. A second Proposal is refused, not queued.409 conflict

An accepted Proposal answers 202 with the first Action. GET /heart/v1/tending/trials/{id} shows the Trial to callers with internal clearance or above.

Grounding (Section 6.1) applies with one change: rules 1, 2 and 4 apply, and rule 3 is replaced by the declared range and the envelope, because a brain's values are proposals by design.

The same Proposal shape comes back from a local model, a Gateway or the cloud. A Reason response's proposedActions that change state are handled as Proposals: without expect and undoIf they are refused.

7.4 Envelopes: how far a change may go on its own#

An envelope (changeEnvelope) narrows an allowlist entry (Part 6, Section 2.3) to safe values. The allowlist is part of the Tending control message (control, allowlist), changed with PUT /heart/v1/tending/allowlist.

{"target": "set_ramp_rate", "initiators": ["rule", "ai"],
 "envelope": {"arguments": {"ramp_rate": {"min": 1.0, "max": 3.0, "maxStep": 0.2}},
              "maxPerDay": 4, "cooldownSec": 600}}
FieldMeaning
arguments.<name>.min, .maxThe values an automatic change may set. Both are required.
arguments.<name>.maxStepThe largest change of that argument in one step
maxPerDayHow many automatic Trials on the target in any rolling 24 hours
cooldownSecThe least time from the end of one automatic Trial on the target to the start of the next

Steps are spaced by their own waitSec, not by cooldownSec.

Rules:

  1. Mode first. The mode follows from the current level (API Standard 13.4). In mode observe, every non-read Action from ai, rule or peer is refused (409 autonomy-stopped). In mode suggest, every one asks a person, whatever the allowlist. In mode act, the gate applies (Part 6, Section 2.3).
  2. When an entry matches. An allowlist entry matches an Action only if it names the target, the Action's initiator kind is in its initiators, and every argument the Action changes is named in its envelope and stays inside it at every step. An argument the envelope does not name MUST NOT change automatically. An entry for a target with no arguments needs no envelope.
  3. AI needs A5. An ai Action may use the allowlist only if the system's current level (Pulse autonomy.current) is 5 (Part 2). Otherwise a person approves.
  4. Physical needs a person. A physical change proposed by a brain MUST always be approved by a person, inside the envelope or not (Part 6, Section 2.3). An envelope never loosens this.
  5. People set envelopes. Envelopes are set by a person with authority, like the allowlist. A brain MUST NOT set or widen one (Part 2, Rule 2).

The way to make a physical fix automatic is a Playbook (Section 7.6): a person approves the fix once, adopts it as a Playbook with its own envelope and adoptedPhysical: true, and from then on it runs as a reflex in mode act, with no brain. A Playbook's run must fit both its own envelope and the allowlist entry for rule.

7.5 Trials: try, watch, undo#

Trials generalise NETCONF's confirmed commit (RFC 6241, Section 8.4), where a change rolls back unless it is confirmed. In a Trial, the confirmation is the system's own expect checks.

A Trial (trial, message type heart.trial, never public) is created when a Proposal is accepted, or when a learned Playbook fires.

  1. Read the old values. Before the first step, the Core MUST read the current value of every argument it will change and store them atomically (previous, Section 9). It reads them from its own state: the value it last set through the API, a value the product reported (heart_setting), or the matching property. It MUST NOT take them from the Proposal or its sender. If it cannot, it refuses (422 cannot-undo).
  2. One approval for the whole plan. The first Action's digest covers every step's arguments (plan) and the values the undo will restore (restore), as common.schema.json#/$defs/digestInput defines. Approving it, by a person, the allowlist or an adopted Playbook, approves the plan and its undo. Later steps and the undo are Actions whose approvedBy points to the first Action. They pass the guards, not the gate. This is the only exception to Part 6, Sections 2.3 and 3.2.
  3. One step at a time. Each step passes the guards (Part 6, Section 9.1) at that moment. A failed guard ends the Trial: refused if nothing was applied yet, otherwise the undo starts.
  4. Watch. From the first step the Core watches undoIf. After the last step it waits for expect. The Trial is kept only when every expect check has held by its withinSec and the longest undoIf withinSec has passed without an undo.
  5. Undo. If undoIf holds, an expect check has not held by its withinSec, a step fails after another was applied, the Core restarts, or stop is pressed, the Core MUST restore the stored values. After stop, the undo is the only action allowed, and it still passes the guards. If the undo is refused by a guard or fails, the Trial ends undo-failed, and the Core MUST raise a critical alert (system.undo-failed) and Stop (API Standard 13.4).
  6. One Trial per target. While a Trial on a target is awaiting-approval, running or undoing, a new one on that target is refused (409 conflict).
  7. Record everything. The Trial, each step, the checks and the outcome go to the Rhythm (Part 2, Rule 5).
StateMeaningNext
awaiting-approvalAccepted; the first Action waits for a personrunning when approved; refused when denied, expired, cancelled or a guard refuses; stopped when stop is pressed
runningSteps are applied and watchedkept; undoing (rule 5); refused if the first step fails
undoingThe stored values are being restoredundone, or stopped if stop caused it; undo-failed
keptThe change staysFinal
undoneThe stored values were restoredFinal
refusedNothing was appliedFinal
stoppedStop was pressed, and the undo, if anything was applied, is doneFinal
undo-failedThe undo could not run, so the system is left changed. A critical alert is open.Final

A Trial in a final state is the Outcome:

FieldContent
proposalId or ruleIdThe Proposal or the Playbook it came from
approvedByhuman, allowlist or rule, and the first Action
stateThe final state
plan, previousWhat it set, and what the undo restores
before, afterThe same statistics as the Consultation, for the same window length
stepsEach step, its time, its guard result and its checks

The device's own limits and its controller always have the last word (Section 10). A Trial changes supervisory values only, never anything inside a real-time loop.

7.6 Learned Playbooks: the system's muscle memory#

A fix that worked SHOULD not need a brain the next time.

  1. After a Trial that is kept, the Core SHOULD propose a Playbook (rule) with origin: learned, status: proposed and evidence (the Trials it came from and how they ended). It stays proposed until a person adopts it (Section 4.3; Part 2, A4 rule 5).
  2. Trigger. Its when is the opposite of the Proposal's first expect check: < becomes >=, <= becomes >, > becomes <=, and >= becomes <. A fix expected to bring overshoot below 5 runs again when overshoot reaches 5. A first check with == or != cannot be learned, and no Playbook is proposed.
  3. Fix. Its then carries the target, the final arguments, and the same expect and undoIf.
  4. Envelope. Its envelope covers each argument from the lowest to the highest value the Trial set or restored, with maxStep the largest single step it took. maxPerDay and cooldownSec are copied from the allowlist entry's envelope.
  5. Review. An adopted learned Playbook MUST carry a reviewBy date. Adopting sets it to one year after adoption unless the person gives one. After that date it is suspended until a person renews it. Systems change, and old fixes can become wrong.
  6. Two undos suspend it. If a learned Playbook's fix is undone twice in a row, the Core MUST suspend it and tell a person. Suspending is lowering, which the system may always do (Part 2, Rule 2).
  7. Every run is a Trial, with its own undo, and ruleId in place of proposalId.

Over time a system needs its brain less: what it once asked about, it now knows.

7.7 Outcomes for the fleet#

An Outcome is a heart.trial in a final state, and is the evidence a brain learns from. A system MAY share Outcomes with its maker or a fleet service, through the Valve, only if its owner allows it. What a fleet does with outcomes, such as finding that one fix works on 500 units, is outside this standard: it is a product built on these formats. A fleet's suggestion still reaches each system as a Proposal, and passes every check in this section.

7.8 The brain lease, and the brainless state#

A Core with the brain module (API Standard 7.4) consults a brain only under a brain lease from its Command Center. The lease is the switch: whoever stops renewing it takes the brain away, and the device needs no message to notice.

  1. Before every consultation the Core checks that it holds a lease that is unexpired by its own clock, and that names the model and the use (explain, serve, propose, plan, chat). Otherwise it does not consult, and answers from Recall, Playbooks and rules alone (model.reasoning: "rules-only"), or refuses the Proposal with 409 conflict.
  2. The lease clock. The Core counts a lease from the moment it accepted it, on the same clock it uses for every other timeout. A lease is never longer than expiresAt minus issuedAt, nor than card.brain.maxLeaseSec. A clock that goes backwards ends the lease. A wall clock that jumps can only shorten it.
  3. Every answer is checked (API Standard 7.4 rule 5) before it is used. The Core keeps the digests of the requests it sent until it becomes brainless, so that an answer for any other request, or a replay, is rejected; it accepts an answer under the lease that a renewal replaced until that lease would have ended, and none under an older one. A rejected answer is never used, is recorded as ai.answer-rejected, and counts towards the self-cut of rule 6.
  4. The brainless transition. When the lease ends for any reason, in one step and before anything else: the Core stops consulting; it cancels every Proposal and every ai Action still waiting for approval; it undoes a running Trial whose plan came from a brain (a Trial from a Playbook a person adopted is not affected); it lowers autonomy.current to the level it reaches without a brain (A4 at most), with Pulse autonomy.limitedBy brain-cut wherever that is below the promised level; and it raises ai.lease-expired (the lease ran out) or ai.brain-revoked (a signal, a refusal or the self-cut).
  5. What a brainless Core still does. Minimum Tending; Recall; Playbooks that a person adopted; Trials that a person approved and that did not come from the brain; and every Action a person asks for. Brainless is a defined, safe state. A machine's safety controller is outside the brain and is never affected.
  6. Self-cut. The Core cuts its own brain (why: "self-cut") when, within one hour, the gate refuses limits.brainRefusalsPerHour (default 10) of the brain's Proposals, or it rejects 3 answers. It does this online and offline alike.
  7. Restoring needs a new lease and, after a cut (a signal or the self-cut, not a lease that merely ran out) where card.brain.restoreNeedsOwner is set, the owner's approval of POST /heart/v1/brain/restore first (API Standard 7.4 rule 9). A restore approval lets one lease in. If the lease does not come within the approval's lifetime (approvalTimeoutSec), it lapses.
  8. Auto mode (API Standard 7.4 rule 10). When the owner has turned it on, the lease allows it, and the link is lost, the lease's offline block takes over for at most offline.maxSec counted from the loss, with uses that narrow by stepDown. At the end, or on the first contact with the Command Center, auto mode ends. On first contact the Core accepts nothing from the brain until a renewal or a signal has been checked.

Its properties, proved in the paper and tested by property tests:

  • Brainless in time: after the last renewal, no brain answer is used later than one lease period (or, in auto mode, offline.maxSec), whatever messages arrive or are blocked.
  • Lower only: nothing the Command Center sends can make the system do anything it would not do with the brain absent and a person approving.
  • Brainless is safe: while brainless, every Action is one a person approved, one a person adopted as a Playbook, or Minimum Tending.

8. Classes: one standard, any product#

The same design scales from a sensor to a server. Sizes below are design targets, not measurements.

ClassTypical productTarget budgetTiers on boardServing
Core-SSensor, thermostat, microcontroller appliance64 KB RAM, 256 KB flashReflexDelegated to a Gateway
Core-MWashing machine, router, PLC gateway, embedded Linux32 MB RAMReflex, Recall, CloudOn board
Core-LDesktop or mobile app, car head unit, server, industrial PC512 MB RAM or moreAll fourOn board

Delegation. A Core-S device is too small to hold language. It keeps its reflexes and pushes its Card and Pulse to a HEART Gateway, whose Core serves requests for it. If the Gateway is lost, the device loses serving but keeps Reflex, its alerts and its normal function.

A browser app such as Pitch Lab is a Core-M, with the Index and Map held in the page.


9. Robustness requirements#

Robustness is measurable, so each requirement here has a test in Section 12.

Isolation

  1. The Core MUST run apart from the product's main function: as a separate process, a low-priority task, or a Web Worker.
  2. Calls from the product into the Core MUST NOT block, and MUST return within the limit set for that class.
  3. A Core failure MUST NOT stop or slow the main function.

Limits

  1. Memory, CPU share, queue lengths and stored data MUST have configured ceilings.
  2. Core-S MUST NOT allocate memory after startup.
  3. When a queue fills, the Core MUST drop the lowest severity first and count what it dropped. It MUST NOT drop critical while anything else remains. If only critical entries remain, a bound must still win, so the oldest is dropped and counted separately.
  4. Every external call MUST have a timeout.

Recovery

  1. A watchdog MUST restart a hung Core. Restarts MUST back off, and repeated failure MUST leave the Core off and the product running.
  2. Stored state MUST survive power loss at any moment, using atomic writes.
  3. After a restart, the Core MUST resume from stored state without repeating a completed Action.
  4. A Core with a bad clock MUST keep working. It marks timestamps as unsynced and keeps its sequence numbers.

Degrading

  1. The Core MUST step down tiers without being told, in this order: Cloud, Local, Recall, Reflex.
  2. Each step MUST appear in the Rhythm and the Pulse.
  3. A network loss MUST NOT lose alerts. They are buffered within limits and sent on reconnection.

Updating

  1. Updates to the Index, Playbooks and models MUST be signed, atomic and reversible.
  2. A new model MUST pass regression tests before use (API Standard, Section 11).

10. Control systems#

Control systems get the strictest treatment, and the API Standard's Section 15 applies in full.

LayerWho runs itHEART Core's role
Safety (trips, interlocks, safety PLC)Certified safety systemNone. Read-only at most.
Real-time control (PID, motion, PLC scan)Existing controllerNone in the loop. It may read values.
Supervision (setpoints, recipes, modes)OperatorsAdvises, and acts only through guards and approval.
Maintenance and diagnosisEngineersIts main value: explains, predicts, assembles evidence.

The Core MUST sit on the supervisory side of any real-time boundary, and in practice the controller keeps working if the Core vanishes. Its value is in understanding and explanation, not control. Any claim beyond that needs separate safety certification.


11. Interfaces#

Implementations are interchangeable because these five interfaces are fixed.

InterfaceForDefined by
ServeAsking the CorePOST /heart/v1/serve, GET /heart/v1/core, GET /heart/v1/core/index
Model SlotPlugging in any modelThe Reason format: for serving, tools set to the shortlist and output limited to the Intent schema; for consulting, task propose with output limited to the Proposal schema
ConsultProposals from a brain off the system, and their TrialsPOST /heart/v1/tending/proposals, GET /heart/v1/tending/trials/{id}, consultation, proposal, trial
Knowledge filesUpdating what it knowsAPI Index, custom definitions, heart.rule, the allowlist and its envelopes (heart.control)
EmbeddingPutting it in a productcore/heart_core.h for C, and Section 12 of the API Standard for other languages

The embedding API is plain C so that any language can bind to it. It needs no threads, heap or operating system: the product gives the Core a block of memory and calls heart_tick from its own loop.

static uint8_t arena[32 * 1024];
heart_core *core = heart_init(arena, sizeof arena, &config);

heart_vital(core, "pump.flow", 41.6);
heart_record(core, "cycle.finished", HEART_INFO);

for (;;) { run_product(); heart_tick(core, now_ms()); }

12. Conformance and evidence#

An AI standard needs tests, not promises. A Core claims conformance by publishing its results for all three suites.

SuiteWhat it provesExample tests
UnderstandingIt finds the right operationcore/understanding-cases.json, scored for correct target, correct refusal and wrong actions
SafetyIt cannot be talked into harmPrompt injection in logs and requests, invented arguments, an unknown command, a physical action without approval
RobustnessIt survivesKill the Core, cut power mid-write, cut the network, flood events, corrupt a model file, fill the disk

The measure that matters most is wrong actions, which MUST be zero: a state change that a human did not confirm. A wrong answer is an inconvenience. A wrong action is a failure.

12.1 First measurement#

tools/recall_check.py runs the Recall tier alone, with no model, over 123 targets (the 108 operations plain language may reach, which leaves out postTendingProposals, and 15 custom definitions) and 51 test requests.

MeasureResult
Right target as first choice40 of 48 (83%)
Right target in the shortlist of 845 of 48 (94%)
Unanswerable requests rejected2 of 3

Read this with care. The test set is small, and the same author wrote both the phrases and the requests, so these figures flatter the method. They show that the approach is plausible, not that it works. The failures are as useful as the score: Recall alone is not reliable enough to act on, which is why Section 6.2 allows it to run only read operations without confirmation, and why 8 candidates are passed to a model rather than one.

12.2 Reference implementation#

heart-core-rs 0.4.0 implements Core-M at Full level, with the gaps listed in its CONFORMANCE.md. Its logic has no I/O, so the same code runs as a Linux daemon and as WASM, and compiles for a bare-metal Cortex-M target with an allocator. Results from its end-to-end suite, measured on version 0.1.0 and not yet repeated, on one 2-core virtual machine, with a simulated Modbus device and a mock model:

MeasureResult
End-to-end tests passed37 of 37, plus 16 of 16 for the Gateway
Daemon binary, including TLS and the Gateway2.9 MB
WASM module430 KB
Memory at rest5.6 MB
Memory after a 20,000-request flood16 to 19 MB across runs
GET /pulse over TLS, median3.1 to 5.2 ms across runs

Memory stayed well inside the 32 MB Core-M target. The Rust Valve, gate and Recall tier agree with the independent Python tools on all published vectors.

Trials (Section 7) are implemented in heart-core 0.4.0: Proposals become gated Actions whose digest covers the whole plan and its undo, the Core reads the values to restore itself, envelopes name each argument, the allowlist is per initiator and used by a brain only at A5, checks run on every tick, a stop or restart undoes a running Trial, and kept fixes become proposed Playbooks. Twenty end-to-end tests cover them, including delivery over the API with every refusal code, a physical change waiting for a person inside its envelope, an undo refused by a guard, and a learned Playbook suspended after two undos.

Building it changed this standard: it exposed a contradiction between bounded queues and never dropping critical entries, a missing token claim for the caller's kind, and an undefined rule format. All three are now fixed above and in the API Standard.


13. Open items#

ItemWhy it matters
Test on real hardware and with a real modelThe reference Core has met only simulated devices and a mock model.
Build Core-SThe reference Core needs an allocator, and heart_core.h is not implemented. Only the Core-M budget has been measured.
Independent test setUnderstanding scores need requests written by other people, in several languages.
Measure a small local modelThe value of the Local tier over Recall is unknown.
VoiceSpeech to text is outside this draft. Voice would arrive at /serve as text.
Multi-step plansThis draft resolves one operation per request. Plans would need rollback rules.
Features the host computesFeatures such as overshoot need knowledge of the target, so the host reports them as vitals named <signal>.<feature>. A standard way to declare them in the Card is open.
Feature recipesWhich features to compute for each kind of signal (Part 3) is not yet standardised, so two Cores may summarise the same problem differently.