# constitution-console.js — return shape and status meanings

Browser API documentation for the memory demo on `/constitution`. No schema service, no
dependency, no network contract. This file describes what the four added console
methods return so a reader does not have to infer it from console text.

## Added methods

| Method | Returns |
| --- | --- |
| `constitution.remember()` | result object — inspects only, never writes |
| `constitution.remember('yes')` | result object — one save, confirmed by readback |
| `constitution.remember('no')` | result object — declines; reads and writes nothing |
| `constitution.forget()` | result object — removes this demo's key, verifies absence |
| `constitution.verifyAll()` | Promise of a verification object |
| `constitution.guide()` | string — prints the command list |

The page's pre-existing members (`version`, `help`, `article`, `articles`, `spine`,
`credits`, `forAI`, `plain`, `verify`, `breadcrumbs`, `game`) are untouched. In
particular `constitution.verify()` keeps its existing Promise contract
`{pass, actual, expected, bytes, source}`; the two-file check is the separate
`verifyAll()`.

## Result object

```json
{
  "ok": true,
  "status": "SAVED",
  "persisted": "present",
  "record": { "first": "2026-09-07", "last": "2026-09-07", "visits": 1 },
  "message": "Saved once in this browser."
}
```

* `ok` — the requested outcome was **verified**, or an inspection/refusal completed
  correctly. It does not mean "no exception escaped".
* `status` — one of the names below.
* `persisted` — `present`, `absent`, or `unknown`.
* `record` — the validated record, or `null`. Never a partially trusted one.
* `message` — the same sentence shown in the visible demo's live region.

## Statuses

| Status | `ok` | Meaning |
| --- | --- | --- |
| `INSPECTED` | true | Storage was read and reported. Nothing changed. |
| `DECLINED` | true | Refusal honoured. Storage was neither read nor written. |
| `INVALID_INPUT` | false | Not the exact string `yes` or `no`. No storage access at all. |
| `INVALID_RECORD` | false | Data exists under the key but is not a valid demo record. Left untouched. |
| `STORAGE_UNAVAILABLE` | false | Obtaining or reading storage threw. Distinct from "nothing stored". |
| `SAVED` | true | Written, and the exact bytes were read back. |
| `NOT_SAVED` | false | The write did not take effect, or stored something different. |
| `UNVERIFIED` | false | The outcome could not be confirmed. Not a success and not a claim the old value survived. |
| `REMOVED` | true | The key is verified absent after an explicit `forget()`. |
| `ALREADY_ABSENT` | true | Nothing was stored to begin with. |
| `NOT_REMOVED` | false | A value is still present after the removal attempt. |

`DECLINED` and `INVALID_INPUT` report `persisted: "unknown"` because they deliberately
do not inspect storage.

When `forget()` observes absence but the removal call itself errored, the result carries
`removalCallErrored: true` and the message says the demo does not claim it performed the
deletion. Absence is what was observed; authorship of the deletion is not.

## verifyAll()

```json
{
  "ok": true,
  "status": "MATCH",
  "files": [
    { "path": "/constitution.txt", "status": "MATCH", "expected": "...", "actual": "...", "bytes": 47013 },
    { "path": "/constitution-v2.0-core.md", "status": "MATCH", "expected": "...", "actual": "...", "bytes": 45649 }
  ],
  "message": "Both documents match the hashes this page expects."
}
```

Overall `status` is `MATCH`, `MISMATCH`, or `INCOMPLETE`. Per-file `status` is `MATCH`,
`MISMATCH`, `UNAVAILABLE` (fetch or digest failed) or `UNSUPPORTED` (no fetch/SubtleCrypto
here). One file failing never discards the other's result, and neither a failed fetch nor
missing crypto can ever read as a pass. Requests are same-origin, `cache: 'no-store'`,
`redirect: 'error'`, and carry no user data. Verification never runs on page load.

## What this is not

The counter counts **confirmed saves**, not measured page visits, and a record written by
an earlier version of this demo may include increments made on load. Nothing here is
hosted memory, an account, or identity recognition; the record never leaves the browser,
which is also why deleting it here cannot speak for copies anywhere else. The page's
ordinary requests are unaffected by these methods — the memory methods make none.
