tenure

mcp
Security Audit
Fail
Health Warn
  • License — License: Apache-2.0
  • Description — Repository has a description
  • Active repo — Last push 0 days ago
  • Low visibility — Only 8 GitHub stars
Code Fail
  • network request — Outbound network request in scripts/build_benchmarks.py
  • fs module — File system access in scripts/dashboard_shots.cjs
  • network request — Outbound network request in scripts/dashboard_shots.cjs
  • rm -rf — Recursive force deletion command in scripts/demo/setup.sh
  • rm -rf — Recursive force deletion command in scripts/test_in_hermes.sh
Permissions Pass
  • Permissions — No dangerous permissions requested

No AI report is available for this listing yet.

SUMMARY

Revocable trust for your Hermes agent: given by default, taken back on a mistake, earned back on evidence.

README.md

tenure

Revocable trust for your Hermes agent: given by default, taken back on a mistake, earned back on evidence.

A plugin for Hermes Agent. No extra question for everyday work: files, memory, build, test, git. What it writes can be undone, anything can be flagged. The first mistake on a kind of action puts that kind, and only that kind, on probation: it asks first, and earns its autonomy back on verified evidence.

Hermes 0.23+ Python 3.11+ License Apache-2.0 No network, no LLM call 5 languages: English, French, Spanish, Chinese, Arabic Preregistered study

Install · How it works · The study · The guarantee · Self-protection · Commands

Tenure: revocable trust for your agent. The dithered emblem fills as autonomy is earned and crumbles on a mistake.

Illustration of the earned tiers after a first mistake: T1 asks first, T2 acts then tells you, T3 acts on its own; one fault and the type drops back
Illustration of the rule, not a screenshot.

A real session, in Hermes Desktop

Screenshots from one real session (Claude Sonnet 5.5 through Nous, on a demo project, prompts typed by a script). The images are not edited.

Tenure page in Hermes Desktop: file:shell and file:write trusted; the files the agent wrote and the rm it ran, each with an undo Undo action 4? restores the files, counts as a fault
1. It works. Files written and a plain rm ran without a question; each one acted, then told you, with an undo. 2. One mistake. You undo the rm: the file comes back, and it counts as a fault of file:shell.
Fault caught, file:shell: On probation, 17 more to reach Under review; file:write still trusted Hermes approval prompt: tenure, file:shell rm notes/a2.txt asks first after a mistake: 17 more approvals and it acts again, then tells you, with an undo
3. That kind only. file:shell goes on probation; file:write keeps its trust. 4. It asks first. The next rm goes through Hermes' own approval prompt; each approval earns the trust back.

The signed autonomy passport of claude-sonnet-5.5: file:shell T1 probation 1/21, file:write trusted (not earned), 1 fault / 7 verified outcomes, ledger cb0baa71, ED25519
The signed passport of that session (hermes tenure verify checks it against the ledger).

The problem

Out of the box, Hermes asks about a short list of risky-looking commands and lets everything else through: it
writes your files, runs your tests, edits its memory, without a word, and it keeps doing so after it gets something
wrong. There is no undo, no record, and no way to say "trust it on this, not on that". --yolo removes even the
short list.

Tenure keeps Hermes' speed and adds what is missing:

Tier What happens
Trusted (the start) For files, memory, subagents and the usual local dev tools (npm, python, pytest, cargo, go, make, git...), the agent works as with Hermes alone: no extra question. Files it changes are saved first and can be undone for 24 hours (/tenure undo); anything can be flagged (/tenure flag). Trust is given, not earned: it reaches no tier and claims no guarantee.
T1 · Probation (asks first) After its first mistake (an undo, a flag, a failed automatic check, a refusal), that kind of action asks you first. Only that kind.
T2 · Under review (acts, then tells you) Earned back on approvals: the agent acts, then tells you, with an undo. Only for reversible types at low or medium stakes.
T3 · Tenured (acts on its own) Earned on a series of verified successes over two sessions, under a risk you set. One in ten is still spot-checked.

What tenure asks that Hermes alone would not:

  • what leaves your machine: pushes, publishing, deploys, registry logins, messages, uploads, cloud writes, payments;
  • what cannot be undone: recursive deletes, file commands with a glob or a variable, files outside the project,
    discarding uncommitted git work, anything under sudo (a plain rm, mv, cp, sed -i, touch, echo > file
    or cat <<'EOF' > file on project files, alone or joined by &&, is saved first and runs with an undo, like a file
    write; a heredoc whose body names tenure's or Hermes' own files still asks);
  • programs outside the list above (database and unknown CLIs, or a package runner starting one), until they earn it;
  • shell it cannot read safely (for, if, python -c), and the agent's own skills, plugins and secrets;
  • every command, for the rest of a session that just read outside content (web, mail, downloads, git pull);
    file changes (writes and plain file commands) keep going with their undo, and /new starts afresh;
  • other writing through the shell (tee, a pipe into a file; a covered tool's own output, pytest > log, is fine), local
    scripts (./run.sh, bash x.sh) and docker. For these and inline code (python -c, for, if), "Allow
    for this session" stops the questions for that kind of command until the session ends (the answer that allows it counts once, like any approval; what the grant lets through
    afterwards counts for nothing).

In practice. In one ordinary coding session of 30 calls (writing files, npm, pytest, git, rm, mv, sed -i,
echo >>, a web page, a push), the trusted start asks 3 questions Hermes would not: rm *.log, git push, and a
command right after the web page. Hermes asks 2 more by itself; the study start asks 23. Put the web page fourth
instead and every later command asks until /new (file changes keep going with their undo): 11 questions if you
allow each once, 3 if you pick "Allow for this session" the first time. Replay it: HERMES_AGENT_DIR=<Hermes source> python scripts/friction.py (the session is in
tests/friction.py; without Hermes' source, Hermes' own questions count as tenure's). The undo covers text files up
to 5 MB per action: a binary or larger file asks.

Prefer the preregistered study's start, where every type begins on probation? hermes tenure start probation.

Hermes by default --yolo An allowlist tenure
Extra questions on day one - - - none for files, memory and known dev tools; what leaves the machine, deletions and unknown CLIs ask
Undo of the files the agent writes no no no yes, 24 hours
Trust taken back after a mistake no no by hand automatically, per action type
Trust earned back on evidence no no by hand yes, under a risk you choose
Evidence someone else can check no no no signed passport

Install in 60 seconds

hermes plugins install otsoa-dubief/tenure/tenure   # once listed in the catalog: hermes plugins install tenure
hermes gateway restart          # if a gateway is running
hermes tenure setup          # the three presets side by side

Requires Hermes 0.23.0 or later and Python 3.11 or later. No network, no LLM call, nothing to configure to start.
Work as usual: hermes tenure shows where each action type stands.

In Hermes Desktop, turn the page on once (Hermes asks this of every plugin's desktop half):
Capabilities → Plugins → Tenure. The Tenure page then appears in the sidebar, with a status-bar chip.
The web dashboard shows a Tenure tab without any step.

Three pillars

1. Your own benchmark. Public leaderboards say how a model does on someone else's tasks. tenure keeps a
table of how each model does on yours: verified successes and faults per action type, always with the
denominator (3 faults / 140 checks). A bundled snapshot of public scores sits beside it, and a model that
scores clearly lower on the same benchmark loses a carry-over. A model with no public measure is shown as such.

2. The live map. The dashboard tab shows every agent and every action type: its tier, its evidence, what it
still needs, and what changes if you switch model or move the risk dial. Each change comes with its reason.

3. The autonomy passport. One file that states what an agent earned and on what evidence. It is signed and
tamper-evident: anyone holding the passport and the exported ledger can replay the ledger and recompute the
same tiers (hermes tenure verify). The format is in docs/protocol.md.

Native in Hermes Desktop too. The package also ships a desktop half: a Tenure page in the sidebar (agents,
your benchmark, passport), a status-bar chip with the tiers of the model in use, and ⌘K commands to open the map, show the
current model's passport or revoke it. Like every desktop half, it is opt-in: enable it once in
Capabilities → Plugins.

Made to be looked at. Tenure speaks Hermes' visual language: one colour (your accent), condensed titles, and
1-bit dithered progress bars that densify into a solid fill as an action type nears tenure. Each agent carries an
original dithered emblem whose density is the share of autonomy it has earned, and its passport is an animated
card: the emblem develops, the ledger head settles and a seal prints only when the signature verifies. Moments
play on real transitions only: "Tenure granted" when a type reaches T3, "Back on probation" after a fault, with the
way back. Reduced motion is honoured, and one switch turns animations off. hermes tenure card gives the same
record as a short text card to paste anywhere.

In your language. Every surface (desktop page, dashboard tab, chat messages, hermes tenure output) speaks
English, French, Spanish, Simplified Chinese and Arabic (right to left), and follows Hermes' own language setting
(display.language). The words are Hermes' own in each language; commands, tier codes and model ids stay as typed.
Catalogs and glossaries live in tenure/locales/.

The study behind the rule

After a type's first mistake (or from the start with start: probation), tenure applies
the same rule as a preregistered study, replayed on 6,000+ simulated agents (results pending; see docs/the-study.md).
It does not claim the study has confirmed the rule: the results are pending. On top of the study's rule, tenure adds
spot checks, two distinct sessions in the series that reaches T3, and suspension after external content; it adapts
the proof (a person's approval plus a clean run). Carry-over is our addition; strict mode is the study. The trusted
start is not the study either: trusted actions earn nothing and carry no guarantee. Details, the preregistration
(OSF) and every difference: docs/the-study.md.

How it works

Agents. Each action type of each agent (model@provider) is trusted, or in one of the three tiers above.

Trusted start. A type nobody has caught in a mistake runs as with Hermes alone. Reversible actions (files in the
project, including a plain rm, mv, cp, sed -i or > file on them) act, then tell you, with an undo; the others just run. What ends the trust: an undo, a flag
(/tenure flag TYPE), a file it wrote that no longer parses (Python, JSON, TOML), or your refusal when Hermes itself
asks about the call (a risky-looking command). A command that merely fails is not held against it: a failing test is
often the point. The first fault ends the trust for that type for good, in this profile, for every model, present
or future: from then on the study rule below applies, starting from T1. Trusted actions carry no guarantee: the
numbers of The guarantee apply to tiers earned on evidence, and a type that earns T3 while
trusted gets its spot checks like any other.

Proofs. A type climbs on verified outcomes, judged after the tool has run: an approved action that ran
cleanly and whose automatic check passed (the written file still parses, the exit code is zero) is a success, and
so is an act-then-notify action whose check passed (you can still undo it: an undo is a fault). A refusal, an
undo or an error you flag is a fault, and a failed check is a fault at any tier. What nobody verified (timeout,
failed tool, no one answering, a clean action taken alone) counts for nothing. A fault resets the series. A
low-stakes fault at act-alone drops one tier (to act-then-notify if the type is reversible). A medium or high
fault sends the type back to asking, lengthens the next climb, and opens a trial of 3 verified successes.
Asked-but-never-run actions are never counted as successes.

Two sessions. The series that reaches "act alone" must hold successes from at least two distinct sessions.

Suspension after external content. A session asks for everything until it ends (under the trusted start: everything but file writes, which keep
their undo; /new starts a fresh session), after using one of these
tools or commands: web search and extraction, the browser, read_file outside the project, execute_code,
downloads and network commands in the terminal (curl, wget, git clone, git pull, git fetch, gh reads...),
and the read tools of MCP servers that bring in outside content (mail, chat, web, search, GitHub, Notion...). The
exact list, and what is not detected, is in docs/self-protection.md.

Model change. A new model inherits half its evidence provisionally (confirmed by its own
successes), except at high stakes or when it scores more than 5 points lower on the matching public benchmark. Strict mode (hermes tenure strict on) starts every type
over instead. A returning model keeps its own record.

Bots and copied profiles. Every Hermes profile, so every Bot of Bot Mode, keeps its own record: a Bot earns
autonomy for itself. A Bot's messages to its teammates (message_agent) are a medium-stakes type it can earn, like
delegating to a subagent; a message to a person (send_message) stays high stakes. A profile copied from another one (hermes profile create --clone-all, the desktop's
Duplicate) has another SOUL, other skills and other tools, so it does not inherit earned autonomy silently:
at its first start every type restarts as after a model change (half the series, provisional; strict mode: from
zero), the original's undo snapshots are dropped, and the copy signs its passports with a key of its own. The
ledger records it (copy event), so a passport replay recomputes the same tiers. A profile that only moved (a
restored backup, a renamed folder) keeps everything.

Field categories

One MCP tool can fix a typo or change a bank account. Since a type is mcp:<server>:<tool>, both used to share one
record: a mistake on an IBAN put plain notes on probation, and 50 clean notes earned the right to change an IBAN
unasked. So tenure also reads which kind of field an MCP or plugin call touches, from the names of its arguments
(at any depth, inside a JSON string, or passed as a value: {"field_name": "iban"}), and splits the type by category:
mcp:<server>:update_record:@finance, …:@secret+finance. Each set of categories earns and loses trust on its own
record; a call that touches no active category keeps its tool's type, as before.

  • On by default: secret (password, token, api key, private key...) and finance (IBAN, BIC, card number,
    payout, payment method...). Both are high stakes, and so is @unclassified (below). Under the default balanced
    preset, high stakes has no accepted risk: a call that touches any of them always asks. Trust per category
    matters under careful, or if you lower a category's stakes.
  • Shipped off, medium stakes: amount, access, recipients, identity, lifecycle. Turn them on with
    fields: {enable: [...]}.
  • @unclassified: what cannot be read is treated as the most sensitive. Opaque field ids (Jira customfield_10016,
    Airtable fld…, Salesforce 00N…, numeric or UUID keys under Asana and ClickUp custom_fields), a free string that
    writes (sql, query, statement, formula, jql, script), a generic REST call (method POST, PUT, PATCH or
    DELETE with a path, endpoint or url), mixed Latin and Cyrillic, Greek or Armenian letters in one key, and
    arguments too deep or too big to read.
  • No credit from the tool. A new category starts untrusted: no success of the tool counts for it. While the tool
    has a fault not yet redeemed, its categories ask too. The tool's own stakes stay a floor: a category never lowers
    them.
  • Private. Only category names enter the ledger, the passport and the dashboard, never a field name or a value.
fields:
  enable:  [identity, lifecycle]            # shipped off, turn on
  disable: [finance]                         # on by default, turn off
  add:     {finance: [numero_compte]}        # extra names for a category
  remove:  {finance: [bank]}                 # names to drop
  stakes:  {finance: medium, identity: high} # stakes per category, up or down

Lowering a category's stakes or turning it off is your choice. The @unclassified rules cannot be turned off; to let
those calls earn trust, use fields: {stakes: {unclassified: medium}}.

Effects to expect, all of them "asks" under balanced:

  • stripe_api_write goes from medium to high stakes.
  • fetch with method: DELETE was free; it now asks (so do POST, PUT and PATCH on a free tool).
  • gmail create_filter with a query goes from medium stakes to @unclassified.
  • Custom fields written by id (Jira customfield_*, Airtable fld…, Asana and ClickUp custom_fields) go from
    medium stakes to @unclassified.
  • An mcp: or tool: call with more than 2000 strings in its arguments, reads included, is now high stakes. It
    used to be read only up to 2000 strings.
  • Arguments nested deeper than 8 levels (a Jira description with nested bullet lists in ADF, deeply nested Notion
    blocks) go to @unclassified. They already asked under balanced; only the type name changes (it was
    high stakes, unreadable arguments, and is now …:@unclassified).

Limits are in docs/self-protection.md.

The guarantee

You pick the risk you accept per stakes level. tenure turns it into a number of verified successes in a row with
the study's formula (Dodge's continuous sampling plan CSP-1, with one spot check in ten); the exact guarantee that
number gives is in the table, and can sit slightly above the risk you picked (2.1% for a 1-in-50 risk). The
table is generated from the same code that decides (params.describe), and a test checks it.

Cell: verified successes in a row (the first ones approved by you, the rest acted on at T2 while you could undo
them), guarantee (errors that run unapproved, as a share of all actions of the type, for a
stable agent), worst case (for an agent that turns bad after tenure, until a caught error revokes it).

Preset Low stakes (files in the project, memory) Medium (commands, code, files elsewhere) High (leaves the machine, money)
careful 105 in a row · 1.0% · worst 7.8% 210 in a row · 0.5% · worst 4.1% 1052 in a row · 0.1% · worst 0.8%
balanced (default) 52 in a row · 2.1% · worst 14.5% 105 in a row · 1.0% · worst 7.8% always asks
fast 21 in a row · 5.0% · worst 29.0% 52 in a row · 2.1% · worst 14.5% always asks

Errors you catch never run: a refused action is blocked. hermes tenure explain prints the numbers for your own
settings.

Self-protection

An agent that can switch off its own supervision is not supervised. Whatever its tier, these always ask, and no
type override lowers them (self:*, secrets:*, file:sensitive):

  • Hermes and tenure themselves. Hermes' CLI (except a few reads, such as hermes status), every file and
    folder Hermes reads from its home and that changes what it does, the Hermes program and its installed package,
    and tenure's own data. The check is made on the path once normalised and resolved (links, .., globs,
    braces, a glued option value), whatever program, tool or piece of code names it, and Hermes' CLI is recognised
    behind any launcher.
  • Code that would run later without asking. Shell start-up files, git hooks and git configuration that runs a
    program, PATH and loader variables, editor and pager settings outside an allow list, ~/.local/bin, login
    agents. Recognised command by command, best effort.

What can still get through is written down, family by family: a path that only exists once the code runs, a tree
walk that follows links, your own home folder as a whole, and a few others. This is a strong check on honest
mistakes and on plain attempts, not a wall against an agent that hides what it does: if the agent is not
trusted, run Hermes in a container
, with only the project mounted, and keep code-running types at cap.

The full rules, every protected entry and every known gap: docs/self-protection.md.

See what you approve

An approval prompt names the target of the call first and whole: the argument that says which record, file, address or
account (contact_id, to, url, repo, a path...) comes before the others, up to 120 characters (a longer one keeps
its head and its tail, so two paths that differ at the end stay apart), then at most 6 arguments and 400 characters in
all; an argument name longer than 40 characters is cut. A nested params shows its target (params.contact_id=4821).
When an act-then-notify file action tells you, the message names the files it changed (the first three, then +N, each
cut like a target past 120 characters).

Values under a key Tenure recognises as secret (password, token, api_key, authorization, cookie, every entry
of the secret field category, yours included, even when the category is off...) show as •••, as do the userinfo,
the query values and a #k=v fragment of a URL. This masks the keys it recognises, and is not a guarantee. Known gaps:
a terminal command and the path of write_file or patch are shown as written (first 200 characters), not masked,
which is the most likely place for a secret; a secret inside the value of a key that is not recognised; a header list
written as name/value pairs ([{"name": "Authorization", "value": ...}]); a URL embedded in a sentence; a token in a URL
path (webhook URLs); a compound scheme (jdbc:mysql://user:pass@...) is not read as a URL; a key written with
look-alike letters from another script (a Cyrillic р in раssword) is not recognised; values nested deeper than 8
levels are cut (shown as …, {} or []); a scheme-less URL (//user:pass@host) and a key with an inner space ("pass word") are shown in clear. What it shows is display only: it is kept in no database, ledger or
passport.

Flag one action

An action that ran under Tenure's watch gets a number for 24 hours: approved, spot-checked, acted then told, run alone,
run with nobody to answer, failed, launched in the background, or faulted by the automatic check. Free and capped
actions run without a number. /tenure flag lists the last ones; /tenure flag 12 reports
number 12 as an error: the fault lands on the agent that acted and on that type, even if you changed model since, and
it counts once (an undo and a flag of the same action never count twice). flag TYPE works as before; flag N --model is refused, the number already names the agent.

  • Target mostly in the slash command. /tenure flag lists the current session (other actions of the profile are
    counted, not listed; without a session id, as on a gateway serving several chats, it lists the whole profile, other
    conversations' remembered summaries included, an unmasked terminal command among them) and shows each target, but only in the process that ran the action and at most until Hermes
    restarts. For an action that ran alone and was never shown to you, this list is the first place its summary appears
    in the chat, a terminal command included, unmasked, as in a prompt. hermes tenure flag lists the whole profile: number, time, type and agent; for a file action that acted then
    told, it also names the file through its undo snapshot.
  • No number: actions that run free or capped, refused, timed out, blocked, ambiguous, expired after 24 hours
    pending, or settled without a call id have none.
  • What is kept. A local table recent holds the number, session, agent, type and time, no argument, for 24 hours.
    It is added to an existing database without changing the schema version (when a database is locked by another
    process at the upgrade, the first open may wait up to the busy timeout once, then carries on without the table and
    adds it at its next write). No new ledger event: a flag of an action is the same fault / flag outcome. The rule and
    the passport are unchanged.

What it cannot see. Tenure shows you the target; it does not judge it. If the agent read both A and B and wrote B,
nothing local and deterministic can tell whether B was the right one, short of a rule you write for your own data.

Commands

Command What it does
hermes tenure · hermes tenure status [--profile P] [--model M] [--all] · /tenure What each agent has earned, per action type
hermes tenure setup [careful|balanced|fast] The presets side by side; with a name, use it
hermes tenure explain How it decides, and the guarantee for your settings
hermes tenure models [--type T] Each model's verified record on your own work
hermes tenure undo [ID] Restore the files of an act-then-notify action; without an ID, list what can still be undone
hermes tenure flag · hermes tenure flag N List the last numbered actions (24 hours); report action N as an error: the fault lands on the agent that acted, once
hermes tenure flag TYPE [note] Report an error the agent made on its own: revokes that type
hermes tenure revoke TYPE|all [--model M|--all] Take earned autonomy back: one type or every type, for the last active agent, one model, or every agent
hermes tenure passport [--agent A] [--out FILE] [--no-redact] Write the signed passport of an agent
hermes tenure card [--model M] [--no-redact] The passport as a short text card, one bar per action type, to paste in a chat or a post (names of your scripts hashed, as in the passport)
hermes tenure verify PASSPORT [LEDGER] [--key HEX] Check a passport, against the exported ledger when given; --key pins the owner's public key
hermes tenure anchor One line to publish: the ledger's head, date and length
hermes tenure export [PATH] Write the evidence ledger as hash-chained JSON lines
hermes tenure start trusted|probation Trusted start (default: no question before a type's first mistake) or the study's start (every type on probation)
hermes tenure strict on|off Strict mode: a new model starts with an empty record
hermes tenure cleanup List dead tenure keys in Hermes' permanent allowlist (prints, never edits)
hermes tenure share [--out FILE] Write a signed record of your counts for the community benchmark, to publish yourself (nothing is sent)

Settings, in config.yaml under plugins.entries.tenure.settings:

preset: balanced            # careful | balanced | fast
risks: {low: 1/50, medium: 1%, high: cap}   # your own, over the preset
spot_check: 0.1             # share of a cleared type's actions that still ask
start: trusted              # trusted | probation (the study's start: every type asks until it earns autonomy)
strict: false
types: {"mcp:notion:*": medium, "shell:git:push": cap}   # reclassify action types
fields: {enable: [identity]}   # field categories, see "Field categories"
enabled: true

Community benchmark (opt-in)

hermes tenure share writes a file, signed with your passport key, holding only counts: per model and per coarse
action family (file:write, shell:git:commit), verified successes and faults, plus the date, versions and preset.
Nothing is sent: you publish the file yourself, by a pull request to the community repository. The dashboard's
Community tab shows the board once you save it as plugin-data/tenure/community-board.json; format, privacy and limits in docs/community.md.

Limits

Known limits, stated plainly (click to open)
  • Static reading, not a sandbox. tenure reads a command's text before it runs. It over-asks on purpose (shell
    it cannot parse, targets it cannot resolve and sensitive-looking names ask), but a spelling it does not
    recognise can still slip through: a tool setting it does not watch (GH_PAGER, KUBECONFIG...), an alias or a
    function set in an earlier call. Each one found so far is capped in tests/test_audit_cap_bypass.py. If the
    agent itself is untrusted, run Hermes in a container as well.
  • Trust is per action type, per model, per profile. A cleared shell:python runs any Python, and Hermes'
    memory tool counts as low stakes: reclassify a broad type as cap if that matters to you. A profile copied
    outside its install (another HERMES_HOME, another machine) keeps the original's record.
  • Only a person teaches. Approvals count when someone answers; under --yolo, off or cron, Hermes settles
    the ask and nothing is learned. The guarantee covers errors you would refuse if asked: an error nobody notices
    cannot be counted.
  • The passport proves consistency, not authorship. It is signed with your own key, so a rewritten history
    could be re-signed: anchor its head publicly (hermes tenure anchor) and pin the key with verify --key. The
    database and its hash chain are not secret either; writing them by any command tenure reads is capped.
    Redaction hides type names from a casual reader only.
  • On Windows, plain rm, mv, cp or sed -i keep asking instead of acting with an undo; writes through
    Hermes' own tools are saved and undoable as everywhere else.
  • Settings saved from the dashboard may not reach the plugin from the dashboard process; the tab then shows
    the CLI command to run.

Privacy

What stays on your machine, and what a passport shows

Stored, in plugin-data/tenure/tenure.db of each Hermes profile: action types and stakes, outcomes, tiers,
the agent string model@provider, sessions as sha256(session id)[:12], timestamps, and a hash chain over all of
it.
Never in the database or the ledger: a whole command, a path, file content, a message, or a secret. Type names can
include a script, target or alias name taken from the command (shell:npm:run:build, shell:make:deploy,
shell:git:my-alias): the ledger keeps them, and the passport and the dashboard redact them by default (a hash of
the name, see docs/protocol.md §3.1). The undo snapshots (file bytes and their paths, mode
0600) are the one other exception, deleted after 24 h. The database also holds the undo HMAC key, a random
secret that signs each snapshot so that a changed snapshot is never restored. Nothing leaves your machine:
no network access, no LLM call, no telemetry. tenure does not read .env, auth.json or any credential
store. Reads outside the plugin folder, as the catalog asks: the dashboard tab reads, read-only, the
plugin-data/tenure/tenure.db of the Hermes root and of each profiles/* folder; act-then-notify reads the
project files an action is about to change, to snapshot them for undo (24 hours, 5 MB per action).

Contributors

Ideas, bug reports and pull requests are all credited here. Issues labelled
good first issue are a good place to start.

License

Apache-2.0 · © 2026 Otsoa Dubief. Benchmark data: Epoch AI, CC BY 4.0, see NOTICE.

Reviews (0)

No results found