tenure
Health Uyari
- License — License: Apache-2.0
- Description — Repository has a description
- Active repo — Last push 0 days ago
- Low visibility — Only 8 GitHub stars
Code Basarisiz
- 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 Gecti
- Permissions — No dangerous permissions requested
Bu listing icin henuz AI raporu yok.
Revocable trust for your Hermes agent: given by default, taken back on a mistake, earned back on evidence.
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.
Install · How it works · The study · The guarantee · Self-protection · Commands

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.
![]() |
![]() |
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. |
![]() |
![]() |
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 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 undersudo(a plainrm,mv,cp,sed -i,touch,echo > file
orcat <<'EOF' > fileon 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/newstarts 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) anddocker. 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 intests/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...) andfinance(IBAN, BIC, card number,
payout, payment method...). Both are high stakes, and so is@unclassified(below). Under the defaultbalanced
preset, high stakes has no accepted risk: a call that touches any of them always asks. Trust per category
matters undercareful, or if you lower a category's stakes. - Shipped off, medium stakes:
amount,access,recipients,identity,lifecycle. Turn them on withfields: {enable: [...]}. @unclassified: what cannot be read is treated as the most sensitive. Opaque field ids (Jiracustomfield_10016,
Airtablefld…, Salesforce00N…, numeric or UUID keys under Asana and ClickUpcustom_fields), a free string that
writes (sql,query,statement,formula,jql,script), a generic REST call (methodPOST, PUT, PATCH or
DELETE with apath,endpointorurl), 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_writegoes from medium to high stakes.fetchwithmethod: DELETEwas free; it now asks (so do POST, PUT and PATCH on a free tool).gmailcreate_filterwith aquerygoes from medium stakes to@unclassified.- Custom fields written by id (Jira
customfield_*, Airtablefld…, Asana and ClickUpcustom_fields) go from
medium stakes to@unclassified. - An
mcp:ortool: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 underbalanced; 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,PATHand 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 flaglists 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 unmaskedterminalcommand 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, aterminalcommand included, unmasked, as in a prompt.hermes tenure flaglists 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
recentholds 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 samefault/flagoutcome. 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 intests/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:pythonruns any Python, and Hermes'
memory tool counts as low stakes: reclassify a broad type ascapif that matters to you. A profile copied
outside its install (anotherHERMES_HOME, another machine) keeps the original's record. - Only a person teaches. Approvals count when someone answers; under
--yolo,offor 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 withverify --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,cporsed -ikeep 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 showsStored, 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, theplugin-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
- Otsoa Dubief: code, study, docs.
- Assia Aittaleb: ideas and code. Field-level sensitivity (#1, shipped in #3), intent checks (#2), Unicode camelCase splitting (#5).
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.
Yorumlar (0)
Yorum birakmak icin giris yap.
Yorum birakSonuc bulunamadi



