Niyoos
Niyoos
← Back to home

Record Integrity Register

An append-only record of the times our own audit records have proved wrong, what that means for reading them, and what cannot be corrected.

Effective date
15 August 2026
Last updated
24 August 2026

What this register is

Niyoos sells a tamper-evident audit ledger. A ledger is only worth what its keeper's honesty is worth, so this page exists to record the times our own records have turned out to be wrong, and what we did about them.

Three rules govern it:

  1. It is append-only. Entries are added at the top; existing entries are never rewritten or removed. If an entry later turns out to be incomplete, that is recorded as a new entry referring back to it.
  2. It records defects in the record itself — misattribution, omission, anything that would cause a reader to draw a conclusion the underlying facts do not support. It is not an incident page for outages, and it is not a changelog.
  3. It states what cannot be fixed. Our ledger is immutable by design. When a defect is sealed into it, the honest remedy is disclosure, not correction, and this page is that disclosure.

Entries are listed newest first.


2026-09-09 — A verification we told you had got stronger had never once worked, and three corrections this page owed you

(Published under P-53, P-105, P-52 and P-217. The first section is the one that matters: we announced an improvement to archive verification on 24 August, shipped it on 31 August, and it did not succeed a single time in production until 17:56 on 9 September. Nobody was told, because nobody knew.)

This entry supersedes two statements below — the caveat published on 24 August about what a passing archive check is worth, and the statement published on 18 August that our dashboard does not show which control made an enforcement decision. Neither correction makes the record wrong. Both make this page wrong about the record, which is the defect this register is for. The first section goes further than that: it records a period in which a verification we had described as working could not have worked for anyone.

1. The version-pinned archive read was broken for nine days, and we did not know

On 24 August we published that our archive recorded a location with no version identifier, and said the correction was to record the version our storage provider gives us when a batch is written, and to read that exact version back.

That code reached production on 31 August 2026 — the date the first version-recording batch appears in our archive. It did not work. From that day until 17:56 on 9 September 2026, every attempt to read an archived batch at its pinned version failed. Our service had permission to read the current version of an archived object and had never been granted permission to read a named version — the exact operation the correction introduced. Nine days.

What a customer would have seen. The Verify control on the audit page would have answered "Chain broken — ledger verification FAILED", naming a sequence number and an archive batch. As far as our logs show, the first person to press it in that window did so on 9 September; had anyone pressed it earlier, they would have been told the same thing.

⛔ The ledger was never in question, and the distinction is the whole point. The archived batch was intact: one version, unaltered, nothing deleted, matching the database when it was finally read. What failed was our permission to read our own evidence — not the evidence. Our software could not tell those two apart and reported the more alarming one.

How it was found: a customer-facing click, not monitoring. Our own hourly check had been failing since 12:35 that day and had been reporting it to us as a chain failure — the same wrong message, aimed at ourselves. We found it because someone pressed the button and read the screen. A check that reports a storage permission as tampering is not a check that would have caught this, and ours did not.

What we have changed. The permission was granted at 17:12 on 9 September and the first successful pinned read in production followed at 17:56. We have also corrected the software that could not tell these two situations apart, so that "we could not read the evidence" and "the record is contradicted" stop being the same answer; that correction is in the release that carries this entry. It matters more than the permission did, because the permission was one mistake and the conflation would have mis-reported the next one too.

2. Archived batches are now read back by version — narrowed, not lifted

The correction described in section 1 now works. New batches record the version and are read back at that version, so for those batches a passing archive check means what the original sentence claimed.

The caveat is narrowed, not lifted, and the difference matters. Batches archived before this shipped carry no version identifier. Nothing retrofits one: the version exists in our storage, but the location we stored does not name it. Those batches are still read unpinned, and for them the 24 August caveat stands exactly as written. We are stating the boundary rather than the improvement, because the improvement is the part that is easy to overstate, and this page already has one overstatement about this sentence on it.

What has not changed: the locked original of a superseded batch still survives and is still never read again, and we still have no verification that would notice a superseding write to an unpinned location.

3. The dashboard now names the control that decided

On 18 August we published that the corrected enforcement actors — policy:cost-limit and policy:kill-switch — were sealed correctly but that our dashboard rendered both as "System", and we said we were recording that rather than waiting for the display to catch up.

The display has caught up. An entry written by an enforcement control now shows the control by name alongside "System", so the dashboard and the sealed value say the same thing. The sealed value was always the authoritative one and is unchanged.

Why this is an entry and not a correction in place

Nothing in the ledger is wrong because of any of this. What was wrong is this page: for some weeks it told you to discount a check that had become stronger, told you a display was less precise than it was, and — worst of the three — let an announced improvement stand for nine days without anyone establishing that it worked. Two of those errors ran in our favour. The third told us we were protected when we were not, and we found it the way a customer would have.

We are recording this the same way we would record a defect in a sealed entry, because a register that only catches the record and never catches itself is not doing the job.

The record stays as written. This entry is the correction.


2026-09-08 — What write-once storage means for erasure, and the two organisations it cannot release

(Published under P-106 and P-108. Both facts were true and undisclosed; both are the kind a customer discovers at the worst moment — during an erasure request, or during an audit where the archive they were told about has expired.)

Our archive is write-once by design: once a batch is written with a retention period, nothing can alter or remove it until that period ends — not us, not our cloud provider. That is what makes it evidence. It also means erasure has a boundary we cannot move: if you delete your account, your live records go immediately and the archived copies go when their retention lapses. Two organisations deleted before 22 August 2026 have archived batches under a longer retention than the ninety days we now use; those batches contain ledger metadata only, and they cannot be released early by anyone.

After a batch's retention ends, the archived copy is gone and the database copy remains. Before that point the archive is the stronger record; after it, the database is the only one. Verification reflects whichever copies exist at the time you ask.


2026-09-03 — A self-verifiable export now exists; what it proves, what it does not, and one thing it discloses that the API withholds

This entry partly supersedes section 4 of the 24 August entry below, which said that a self-verifiable export "does not exist today" and attached no date to one. One exists now. It supersedes nothing else on this page: the two immutability corrections stand, and section 3 (an entry that was never written) stands with one narrowing stated below.

What is new

An organisation administrator can download, from the Audit Log page, a verify bundle: the organisation's entire ledger with every seal field — the previous hash, the entry hash, the sealed payload, the chain position and the sealed metadata — together with every signed anchor issued for that ledger and the public keys that verify them. The bundle is served and saved byte for byte; nothing in it is reformatted on the way to you.

A verifier for it, verify-ledger.mjs, is published in our source repository. It has no dependencies beyond Node itself, makes no network call, and needs no Niyoos account. Run against a bundle it reports two verdicts, never one:

  • Integrity — whether any entry has been altered since it was sealed. Each entry hash is recomputed from its two inputs, each metadata blob is recomputed against the hash sealed inside its payload, and each entry is checked against the one before it.
  • Completeness — whether anything has been removed from the end of the ledger since the newest anchor in the bundle whose signature verifies under a published key. An anchor that does not verify is rejected by name and not used; with no usable anchor the verdict is not checked, never a pass.

Both verdicts are printed with a list of what the tool cannot tell you, so a green result carries its own limits.

What it proves, stated at its true size

Against a party who can rewrite our database but cannot sign anchors, a bundle you hold is conclusive: alteration breaks the entry seals, and removal from the end contradicts a signed anchor. That covers the attacker section 2 of the 24 August entry was written about, up to its last step. It does not cover the signer, and the signer is us.

Against us, the bundle proves exactly as much as the anchor you compare it to is independent of us. The anchors inside a bundle were issued by Niyoos, at export time, under a key we hold. If the only anchor you have is the one we sent you in the same file, then a removal we carried out before export and re-anchored afterwards would verify as complete. Anchors are still not published anywhere outside Niyoos, as the 20 August entry said and as remains true. Until they are, the witness that catches removal by anyone — including us — is a bundle you saved earlier. Keep them. Two bundles from different dates, each verifying on its own, whose earlier head is missing from the later one, is the evidence this page cannot give you and the earlier file can.

The keyed seal is not in the bundle and is not checked. Each entry also carries a seal under a secret we hold and never publish; it defends against an attacker who can rewrite rows and recompute the unkeyed chain. A tool that runs without us cannot check it, and the tool says so.

What the 24 August entry said that is now different

  • "A self-verifiable export does not exist today." — It does, for organisation administrators, in the form described above.
  • "The export contains no seal, hash or chain position at all." — True of the three row exports, which are unchanged. The verify bundle is a fourth export and contains all three.
  • "The entry hash is computed from two inputs … and the response contains neither." — Still true of the API. The inspect route is not changed by this entry; the export route is.
  • Section 3's narrowing. Since 2 September, when a ledger write fails after its action has completed, the intent to write it is kept durably and retried by a scheduled job, and an intent that cannot be replayed is reported rather than discarded. That closes the gap for most actions. It does not close it for three enforcement refusals — a request refused by a cost limit, a request refused by the kill switch, and an enforcement control that degraded to fail-open — which write no database record of their own and remain best-effort. A missing entry from one of those three is invisible to both verdicts and to any tool of this kind. A replayed entry is appended at the current head with its true time of occurrence sealed alongside, and marked as replayed; the ledger restores the entry's presence, not its original position.

The thing this discloses that the API withholds

The 24 August entry said, of the sealed actor value, that withholding it was deliberate and that we were not proposing to reverse that. The bundle contains it. It cannot not: the sealed payload is hashed as exact bytes, and the actor reference is inside it, so a bundle that omitted it would fail its own seal. The value is a per-organisation pseudonym, an HMAC that correlates nothing across organisations and resolves to a person only through a mapping we hold and delete on erasure. What changes is that an administrator of your own organisation can now see, in an export, the pseudonym that stands for a member of that organisation — the same member whose account identifier that administrator already sees in the dashboard. We think that is a narrower disclosure than it sounds and we have gated the bundle to administrators because of it. We record it here because we said we would not publish the value, and we now do, to one role, for this reason.

What this entry does not fix

A superseding write to an archived location is still possible and still undetected by our verification. Anchors are still not published outside Niyoos, so the completeness verdict against us rests on files you keep, not on anything we publish. Three enforcement refusals can still leave no entry. The keyed seal is still ours to check and nobody else's. The record stays as written. This entry is the correction to what was said about checking it.


2026-08-24 — Three corrections: what Object Lock protects, what we could do undetectably, and a kind of defect this register had no room for

This entry supersedes four statements below: two published on 15 August about immutability, and the instruction — published on 15 August and repeated on 18 August — that you do not have to take our word for what this page says. Each was wrong or unsupportable when we published it. This entry also adds a third kind of record defect that this register's own reasoning had no place for, and that neither of our verification verdicts can see.

What we wrote, and the position now

We wroteThe position now
Archived copies are held under S3 Object Lock with deletion denied to every principal, including us, "and cannot be rewritten at all" (15 August)Wrong. Object Lock protects a version, not a name. Nothing prevents a new version being written at the same location. The original survives, locked and unaltered — and nothing we run ever reads it again, because the location we record carries no version identifier and our verification reads whichever version is current
"We will not alter historical entries to make our records look better, and we could not do so undetectably even if we chose to" (15 August)The first half stands, as a commitment. The second half is withdrawn: we could. Every step is set out in section 2, and each uses a permission the running system already holds
"You do not have to take our word for any statement in this entry" (15 August)Withdrawn. Today you do. What we publish is not sufficient to check any statement about the seal independently, for the reasons in section 4
"Exporting or inspecting your organisation's ledger will show you both the affected values and the fact that they are sealed" (18 August)Wrong on both routes. The export contains no seal, hash or chain position at all; the API publishes an entry's hash while withholding both of the values that hash is computed from

None of the four is repaired by publishing this. Rule 3 of this register is that it states what cannot be fixed, and this entry is disclosure, not remedy.

1. What the archive guarantee actually is

What we verified and are keeping, unchanged. Archived copies are held under S3 Object Lock, and deletion is denied to every principal, including us: an explicit deny on object deletion, on version deletion and on bypassing the retention setting, applied to every principal, with no role in our account holding a delete permission on that bucket. That configuration was verified on 22 August 2026, and every figure and finding in this entry is as measured on that date. Every version ever written is retained, no stored version can be deleted, and no stored version can be altered in place. Those are real guarantees and we are not weakening them.

What was false is the sentence that followed them. Object Lock protects each stored version of an object. It does not prevent a new version being written at the same name. When that happens the locked original is retained as a previous version — perfectly protected, and never read again. Our archive records a location that carries no version identifier, and the code that fetches an archived batch asks for the name rather than for a specific version, so it receives whatever is current. An archived batch can therefore be superseded in the only sense that matters to a reader: the bytes returned for that location change, and our verification compares against the new ones.

This is not hypothetical, and it has already happened here. As measured on 22 August 2026, one archived audit batch was stored under a single name with at least three versions and at least two distinct contents, two of them differing by seven bytes. Those versions were written within the same second on 18 July 2026, so this instance is consistent with an ordinary client retry rather than with anything deliberate. That is the part worth stating plainly: our archive already holds a batch whose current contents are not the first thing written to it, produced by normal operation, and no verification surface of ours noticed — because none of them is capable of noticing.

The correction is to record the version identifier that S3 already returns to us when a batch is written, and to read that exact version back. Until that has shipped and this page says so, read a passing archive cross-check as confirming that the current contents of an archived location match the database — not that they are the bytes that were originally archived.

2. What we could do undetectably

The withdrawn sentence was a claim about detectability, and its threat model was explicitly us — "even if we chose to". It therefore has to hold against a party holding our own credentials, and it does not. Set out in full, because a vague admission here would be worse than the original overstatement:

  1. Rewrite the entries in the database. On its own this breaks the hash chain and our verification catches it — unless the chain from the edited entry onward is recomputed, which requires the key the entries are sealed with.
  2. Write matching content over the archived batches, at the same names, as described in section 1. The locked originals survive, and nothing reads them.
  3. Run the verification. It compares the database against what the archive fetch returned. Both sides now agree, so it reports the archive as verified, and the dashboard renders that as every hash, seal and archive copy matching.

No privilege escalation, no policy change and no break-glass procedure is involved at any step. The archive exists in order to be a copy held outside the blast radius of the database it backstops. It is not outside it. A compromise sufficient to rewrite the ledger is also sufficient to rewrite the copy that is supposed to catch the rewrite, and our verification would then report the two agreeing. A control that fails against precisely the party it was built to detect is not much of a control, and we described it as one.

The signed anchors in the 20 August entry are the one remaining obstacle, and that entry already records their limit: anchors are not yet published anywhere outside Niyoos, so for now that detection is ours, not yet yours. A detection that is ours cannot support a sentence about what we could not do. We should not have written it, and we are not replacing it with a weaker version of the same promise.

What remains is a commitment rather than a guarantee: we will not alter historical entries to make our records look better. You now have this page's account of exactly how much that is worth, which is what it should have said in the first place.

3. A third kind of defect: an entry that was never written

This register has so far reasoned about two ways a record can fail — an entry altered after it was written, which the hash chain addresses, and entries removed from the end, which anchoring addresses since 19 August. There is a third, and until now this page had no place for it.

Some actions complete before their ledger entry is attempted. Where that is so, the action stands and the entry can simply fail to be written. In some of those places the ordering is deliberate and we would choose it again — a kill switch must not be blocked because record-keeping is unavailable, least of all during an incident — but the shape has been applied more widely than that argument justifies, and there is no count, alarm or reconciliation on any of them.

Neither of our verdicts can see the result:

  • Integrity walks the chain across the entries that exist. An entry that was never written is not a broken link; the chain is contiguous. The verdict is unaltered.
  • Completeness compares the head of the ledger against a signed anchor, which detects entries removed after an anchor was taken. An entry that was never written was never in any anchor, so the anchored head and the current head agree exactly. The verdict is complete.

Both verdicts return their healthy value for a ledger with holes in it. We are not aware of a specific missing entry, and that sentence is worth less than it sounds: we have no means by which we could become aware of one. That is the disclosure.

So the statement this register has carried since 15 August needs a third clause. A passing integrity check attests that an entry has not been altered since it was written. It does not attest that what was written was right. And it does not attest that everything which should have been written, was.

4. What "verify this yourself" is worth today

The 15 August entry told you that you do not have to take our word for it, and the 18 August entry told you that exporting or inspecting your ledger would show you the affected values and the fact that they are sealed. Both named routes that cannot do it.

Inspecting through the API. Each entry now carries its position in the chain and its entry hash. That was a deliberate improvement and it is genuinely useful for pinning a value you have already been shown. It is not enough to check anything. The entry hash is computed from two inputs — the previous entry's hash, and the hash of the sealed payload — and the response contains neither. You cannot recompute the hash, you cannot confirm that one entry's chain link matches the entry before it, and you cannot confirm that the metadata shown to you is the metadata that was sealed.

Exporting. The export is an operational and analytics extract — timestamp, action, agent, provider, model, tokens, cost, latency, endpoint, status. It contains no chain position, no hash and no seal field of any kind. It is a reasonable export for what it is for, and it cannot confirm that anything is sealed.

And the actor, which is the subject of both of the entries below. What the API returns is our classification of the sealed actor value, not the sealed value itself. Withholding the sealed value is deliberate and we think it is right: it is a stable per-organisation-and-user pseudonym, it would outlive the mapping that gives it meaning, and publishing it would hand out a durable correlation handle. We are not proposing to reverse that. But it has a consequence we did not state: on the one field these entries are actually about, our word is exactly what you have.

So, plainly: a self-verifiable export does not exist today. We are not attaching a date to one, because a date is the kind of thing this page exists to catch us on.

The inconvenient part, which we would rather not have to write. The artefact that would satisfy the original claim already exists. Each archived batch is self-contained — it carries the previous hash, the entry hash, the sealed payload and the underlying metadata, so both the chain link and the metadata seal can be recomputed from the file alone, with nothing from us and no access to our database. We built the thing we told you that you could do, and it is readable only by us.

What this entry does not fix

Three defects are disclosed above and none of them is repaired by disclosing it. A superseding write to an archived location is still possible and still undetected by our verification. An entry that was never written is still invisible to both verdicts. There is still no route by which you can check a seal without us. The record stays as written. This entry is the correction.


2026-08-20 — Ledger anchoring has begun; what it cannot say about the past

Since 19 August 2026 at 18:05 UTC, the head of each organisation's audit ledger is periodically sealed into a signed anchor, so that entries removed from the end of the ledger after an anchor is taken are detectable on verification. Before then the ledger was tamper-evident against alteration but not against removal from its end, and no verification can establish, after the fact, whether any entry was removed before an organisation's first anchor was taken. Each organisation's first-anchor time is shown in its verification result as "anchored since". This cannot be repaired; it is disclosed.

Anchoring began in production approximately nine hours before this disclosure was published. The delay was a deployment step that was not completed, not a decision to withhold — this page ships with the product's frontend, and the release that carried this entry was built in time but not put live until now. We had committed to publishing this disclosure no later than the first anchor, and we did not meet that.

Anchors are not yet published anywhere outside Niyoos, so for now this detection is ours, not yet yours — that changes when anchors are published and delivered to you, and this page will say when.


2026-08-18 — Enforcement entries name the agent as their own author, and our 15 August entry understated this

This entry supersedes part of the 15 August entry below. Two event types we described as unchanged have now been fixed; one statement we published about them was wrong when we published it.

What is wrong

Every AGENT_COST_LIMIT_REACHED and AGENT_KILL_SWITCH_BLOCKED entry written before the fix described below seals the actor as agent:<agent-id> — the identifier of the agent the enforcement was applied to.

Both of these events record the platform acting against an agent: a spend cap refusing a request, or a kill switch turning one away. The deciding party is the control, never the agent. The record says otherwise.

What this supersedes

The 15 August entry closed with a section titled "Related entries still attributed this way, deliberately." Three statements in it no longer hold, and we are recording each rather than letting the older entry stand uncorrected:

We wroteThe position now
These two event types are "not changed by the fix above"They are fixed as of the deploy below. Entries written after it seal the deciding control
"the truthful actor would be system"system was too coarse. What shipped is policy:cost-limit and policy:kill-switch — naming which control decided, not merely that one did
Correcting them was "deferred to a planned change to that vocabulary rather than done piecemeal"This was wrong when we published it. The fix required two call sites and a parameter that already existed. No vocabulary change was needed, and none was made. We described a correction as harder than it was, and then made it piecemeal three days later

The third is the one that matters. This register exists so that our account of our own records can be trusted. An overstatement of how hard something was to fix is exactly the kind of thing it should catch, including when the subject is us.

What the old value means

On these two event types, agent:<agent-id> means "the actor was not captured." It does not mean the agent capped its own spending or refused its own request. Neither event can be caused by an agent: both are written by platform code, on paths an agent's API key cannot reach. Any conclusion drawn from these entries about who decided is unsupported by the record.

Affected entries and date range

Affected actionsAGENT_COST_LIMIT_REACHED, AGENT_KILL_SWITCH_BLOCKED
Start of affected rangeAGENT_COST_LIMIT_REACHED from 13 August 2026; AGENT_KILL_SWITCH_BLOCKED from 14 August 2026 — in each case the date the code that writes the entry first shipped. No entry of either type can predate its own date. The earliest entry we can actually observe is later than both — 13 August for the spend cap, 15 August for the kill switch — but an observed entry records only when a control first fired, not when the code that misattributed it began running. We publish this conservative bound rather than a narrower one we would have to ask you to trust
End of affected range18 August 2026, 04:49:04 UTC — the moment the corrected build began serving. Entries written after it seal the deciding control
Entries affected3, across 2 organisations, as counted directly from the sealed payloads

Three is not a small problem

Three is the number of times these controls fired at all in that window, not the number of times attribution failed. Every entry either writer produced during the affected range was wrong — the error rate was total; the opportunity was rare. A larger customer, or one hitting spend caps regularly, would have accumulated proportionally more.

The count is also a floor, not a total. Organisations that have been fully deleted had their ledger rows removed from our operational database, while their sealed archive copies survive under Object Lock. Entries belonging to deleted organisations are therefore not included in the three.

These entries are immutable and will not be corrected

The actor is inside the sealed payload the hash chain is computed over. Rewriting it would invalidate every subsequent entry in that organisation's chain and would be caught by our own verification endpoint. Archived copies are held under S3 Object Lock with deletion denied to every principal, including us.

The record stays as written. This entry is the correction.

One thing that is fixed in the record but not yet in the display

The corrected actor is sealed correctly from the deploy onward. Our dashboard does not yet render the distinction: policy:cost-limit and policy:kill-switch both currently display as "System". That is truthful but less precise than what the ledger now holds. The sealed value — the one that is permanent, and the one an export or verification will show you — carries the specific control. We are recording this rather than waiting until the display catches up.

How to verify this yourself

The actor is part of each entry's sealed payload. Exporting or inspecting your organisation's ledger will show you both the affected values and the fact that they are sealed. [Superseded 24 August 2026 — neither route can do this today; see the entry of that date above.]

Our chain-verification endpoint will report these entries as valid, because they are: correctly sealed records containing an incorrect actor. A passing integrity check attests that an entry has not been altered since it was written. It does not attest that what was written was right.


2026-08-15 — AGENT_KILLED entries name the agent, not the person who killed it

Some entries in the audit ledger name the wrong actor. They cannot be corrected. This entry states which entries, what the wrong value means, and how to check it yourself.

What is wrong

Every AGENT_KILLED entry written before the fix described below seals the actor as agent:<agent-id> — the identifier of the agent that was killed. The kill switch is operated by a person, through the dashboard. The person's identity was never recorded on these entries.

What that value means

agent:<agent-id> on an AGENT_KILLED entry means "the actor was not captured." It does not mean the agent killed itself, and it must never be read as evidence that an agent acted, or as evidence about which person acted. Any conclusion drawn from these entries about who performed a kill is unsupported by the record.

Verified against the source, 15 August 2026. Exactly two code paths can put an agent into the killed state:

  • The kill switch, reachable only through an authenticated dashboard session — that is, by a person. It is the only path that writes an AGENT_KILLED entry.
  • Account deletion, which kills every agent in the organisation as its first step, to cut off access before any data is removed. It deliberately writes no AGENT_KILLED entry. This is why a deleted organisation's agents can sit in the killed state with no matching ledger entry: that is expected, not a missing record.

No scheduled job, cost limit, alert, or other automated process can kill an agent, and an agent's own API key cannot reach the kill endpoint at all. No agent has ever had the ability to kill itself, or any other agent.

Why it happened

The internal function that writes these entries had no parameter for an actor, so the kill path could not supply one, and a default attributed the event to the agent it was performed on. This was a defect in our code. It was not a customer action, and it was not tampering.

Affected entries and date range

Affected actionAGENT_KILLED only
Start of affected range3 July 2026 — the date the code that writes these entries first shipped. No AGENT_KILLED entry can predate it. We publish this conservative bound rather than a narrower one we would have to ask you to trust
End of affected range15 August 2026 — entries written after that deploy seal the identifier of the person who performed the kill

These entries are immutable and will not be corrected

The actor value is inside the sealed payload that the hash chain is computed over. Rewriting it would invalidate every subsequent entry in that organisation's chain and would be detected by our own verification endpoint — which is the entire point of a tamper-evident ledger. Archived copies are held under S3 Object Lock with deletion denied to every principal, including us (see section 9.3 of the Privacy Policy), and cannot be rewritten at all. [Superseded 24 August 2026 — the final clause of this sentence is wrong; see the entry of that date above.]

We will not alter historical entries to make our records look better, and we could not do so undetectably even if we chose to. [Superseded 24 August 2026 — the second half of this sentence is withdrawn; see the entry of that date above.] The record stays as written. This entry is the correction.

Related entries still attributed this way, deliberately

Two further event types also seal agent:<agent-id>, and are not changed by the fix above:

  • AGENT_COST_LIMIT_REACHED
  • AGENT_KILL_SWITCH_BLOCKED

On these, agent:<agent-id> again means "not a person". Both record automatic enforcement by the system, not a human decision, so no person's identity exists to record; the truthful actor would be system. Correcting them changes vocabulary that is sealed into the chain, so it is deferred to a planned change to that vocabulary rather than done piecemeal. Until then, treat the actor on these two action types as carrying no information about who acted.

How to verify this yourself

The actor is part of each entry's sealed payload. If you export or inspect your organisation's ledger, you can confirm both the affected values and the claim that they are sealed — you do not have to take our word for any statement in this entry. [Superseded 24 August 2026 — neither route can do this today; see the entry of that date above.]

Our chain-verification endpoint will report these entries as valid, because they are: they are correctly sealed records containing an incorrect actor. A passing integrity check attests that an entry has not been altered since it was written. It does not attest that what was written was right.

Published by

Legal entity
Loktara Ventures Private Limited
CIN
U62099PB2026PTC069238
Registered office
5th Floor, F-547, 8A, Ind. Area, Sector 75, Chandigarh Sector 55, S.A.S. Nagar (Mohali), Rupnagar - 160055, Punjab
Telephone
+91 96993 51139
Email
support@niyoos.com

Disclosed as required by section 12(3)(c) of the Companies Act, 2013.