{
  "shipped": "1",
  "source": "repo/flashyid",
  "org": "org/flashyid",
  "generated": "2026-09-08T12:10:52.566Z",
  "entries": [
    {
      "id": "ship/flashyid/bf2d5c52a2d3",
      "repo": "repo/flashyid",
      "at": "2026-09-08T12:10:21Z",
      "kind": "other",
      "title": "The index describes the shipping ref, not this laptop",
      "by": [
        "agent/claude"
      ],
      "asserted": "2026-09-08",
      "assertedBy": "agent/flashyid-ci",
      "visibility": "public",
      "detail": "The first version generated from `git ls-files` — the working tree. On a\ncheckout six commits behind its remote that saw three documents where the\nref holds six, so it would have written an index naming half of them and\nreported the repository done. Across this machine 39 of 40 checkouts are\nbehind their remote, so almost every index written yesterday described a\ntree that ships nowhere.\n\nSay which tree you measured — this estate's first house rule, broken by\nthe tool written to make things findable, and the third tool here to\nbreak it. It reads `git ls-tree` and `git show` against the shipping ref\nnow, so a document committed on a laptop and pushed nowhere is\ndeliberately absent: a reader who follows a link to a file only one\nmachine has is a reader the index lied to.\n\nThe generator and the gate also disagreed about what a document IS —\n`SPEC.md` was an entry point to one and not the other — so the gate could\nask for an index in a repository the generator refused to write one for.\nThe population is imported now, one definition.\n\nCo-Authored-By: Claude Opus 5 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01BjzD1kWqueq1ArT1m4mZsy",
      "refs": {
        "commit": "bf2d5c52a2d36b6c4558701d73755530cfa04553"
      },
      "digest": "0338c0209715874be4deebc70795c253d3cb134261cfca00dab5e32ebacf9fdf"
    },
    {
      "id": "ship/flashyid/af1766a5a5c6",
      "repo": "repo/flashyid",
      "at": "2026-09-07T16:54:37-04:00",
      "kind": "feature",
      "title": "Merge pull request #26 from FlashyLabs/claude/og-bolt-logo",
      "by": [
        "person/michael"
      ],
      "asserted": "2026-09-07",
      "assertedBy": "agent/flashyid-ci",
      "visibility": "public",
      "detail": "og: draw the Flashy ID bolt in share cards, not an \"F\" letterbox",
      "refs": {
        "commit": "af1766a5a5c69de6e424c968b86d3228ce808573",
        "pr": "https://github.com/FlashyLabs/flashyid/pull/26"
      },
      "digest": "28bebdc9517395f913e3fd40fe9ccaa96f7b90eb0c508793ada41f748620b6bb"
    },
    {
      "id": "ship/flashyid/c7d143800f21",
      "repo": "repo/flashyid",
      "at": "2026-09-07T15:04:24-04:00",
      "kind": "fix",
      "title": "move bolt/1 under site/ so the deployed build carries it (#25)",
      "by": [
        "person/michael",
        "agent/claude"
      ],
      "asserted": "2026-09-07",
      "assertedBy": "agent/flashyid-ci",
      "visibility": "public",
      "detail": "flashyID's Next app deploys with Vercel Root Directory `site`, so next build\nonly sees files under site/. The egg was committed at the repository root and\nsite/src/components/Bolt.tsx imported ../../../.bolt/bolt.js — a path that\nescapes site/ and resolves to nothing on the runner. It bundled in a full\ncheckout and served no egg in production: the static-import form of the exact\nsilent miss the component's docblock was written to end, and what\ntests/build-isolation.test.ts flags as an import escaping site/.\n\n- Relocate .bolt/{config.json,bolt.html,bolt.js,bolt.d.ts} to site/.bolt/ and\n  point the component's import at ../../.bolt/bolt.js (inside the build root).\n- vendor-bolt.mjs stays at the repo root and is run from site/ (it writes\n  .bolt/ relative to process.cwd()); re-vendored byte-identical to flashyos\n  canon — the copy here had drifted by two unused imports, invisible because\n  the old hunt.test.ts ROOT pointed one directory above the repo and ENOENT'd\n  every read (so the Site CI job was red on a path bug, not the egg).\n- hunt.test.ts: ROOT is now site/, and it additionally asserts the egg import\n  resolves inside site/ — the egg-specific form of the build-isolation rule.\n- Documented the layout and the run-from-site/ rule in CLAUDE.md.\n\nVerified locally: site vitest 131/131 (build-isolation + hunt green); the real\nnext build runs in CI (next is not installed in this sandbox).\n\n\nClaude-Session: https://claude.ai/code/session_014WQ7KxLJpGLvRPCK6yXEk3\n\nCo-authored-by: Claude <noreply@anthropic.com>",
      "refs": {
        "commit": "c7d143800f21d5756ba4067ea40b8daecc179090",
        "pr": "https://github.com/FlashyLabs/flashyid/pull/25"
      },
      "digest": "b83fbe1627161647d052fe8ca0ffb049127d2a3bc609be50da1d683e23b4a046"
    },
    {
      "id": "ship/flashyid/f92cdc83a4e6",
      "repo": "repo/flashyid",
      "at": "2026-09-07T13:52:05-04:00",
      "kind": "feature",
      "title": "consent-token mint primitive + human-flow design (#23)",
      "by": [
        "person/michael",
        "agent/claude"
      ],
      "asserted": "2026-09-07",
      "assertedBy": "agent/flashyid-ci",
      "visibility": "public",
      "detail": "* feat(rail): consent-token mint primitive + human-flow design\n\nRoadmap #7, first increment. Adds mintRailConsentToken to src/lib/rail.ts:\na pure EdDSA minter for the {typ:'consent', draftId, holderId, action,\napprovedAt} token the rail's FlashyIdVerifier.verifyConsent requires,\nsigned with this provider's OIDC key (already in the JWKS the rail\nverifies). It is byte-identical to @flashyid/sdk's mintConsentToken,\npinned by a drift test, and is deliberately NOT exposed as an endpoint —\na consent a caller can request is the auto-approval the consent layer\nrefuses. It is a pure function to be called from ONE place: the\ninteraction flow, after an authenticated human approves a specific draft.\n\ndocs/rail-consent.md designs that human-approval flow and names the two\nproduct decisions it awaits: the relying-party handoff protocol\n(recommendation: a dedicated consent interaction with a one-time-code\nexchange) and that flashyID renders the draft it fetches from the rail\nrather than RP-supplied text (recommendation: required — otherwise an RP\ncould show the human one thing and obtain consent for another).\n\nTests: round-trip proving the published JWKS verifies the consent token\nwith the exact claims verifyConsent reads, plus the SDK drift guard.\n14/14 in src/lib/rail.test.ts; tsc + lint clean.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_014WQ7KxLJpGLvRPCK6yXEk3\n\n* feat(rail): grant-token mint primitive + ratify the chain→grant mapping\n\nRoadmap #7 (grant half) with decision #8 ratified. Adds mintRailGrantToken\nto src/lib/rail.ts: a pure EdDSA minter for the flat {typ:'grant', grantId,\nholderId, spenderId, assetId, capMinor, remainingMinor, purpose, expiresAt?,\nrevoked?, parentGrantId?} token the rail's FlashyIdVerifier.verifyGrant reads,\nsigned with this provider's OIDC key. sub = holderId, jti = grantId (a grant\nis its own replay unit). Byte-identical to @flashyid/sdk's mintGrantToken,\npinned by a drift test.\n\ndocs/rai",
      "refs": {
        "commit": "f92cdc83a4e6c76187b371f77c7e02c6761f7b14",
        "pr": "https://github.com/FlashyLabs/flashyid/pull/23"
      },
      "digest": "4b150eb7aa209891307d895a64ce06235f2ab8db59f125030bf6637a78ac115c"
    },
    {
      "id": "ship/flashyid/aea2cbb89ff8",
      "repo": "repo/flashyid",
      "at": "2026-09-07T13:50:21Z",
      "kind": "docs",
      "title": "Move the house-rules marker below this repository own prose",
      "by": [
        "agent/claude"
      ],
      "asserted": "2026-09-07",
      "assertedBy": "agent/flashyid-ci",
      "visibility": "public",
      "detail": "The opening marker sat ABOVE this repository sections rather than below them,\nso the region the estate sync owns had grown to contain prose that is this\nrepository own. Running the sync deleted it — caught in the diff and reverted,\nthen fixed here.\n\nFive lines move; no content changes. flashyos tools/estate-house-rules.mjs now\nrefuses this shape rather than replacing it, naming the sections it would have\nlost.\n\nKind: docs\n\nCo-Authored-By: Claude Opus 5 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01DryqvxX93nEakD77pNANCt",
      "refs": {
        "commit": "aea2cbb89ff8e0b809f5f274eae006751b6c9643"
      },
      "digest": "14b43fdaa2277f42833c0c1c4862274610740a5cf57373ec68e37e43702c973e"
    },
    {
      "id": "ship/flashyid/cb9c9350953c",
      "repo": "repo/flashyid",
      "at": "2026-09-07T12:28:14-04:00",
      "kind": "feature",
      "title": "Merge pull request #24 from FlashyLabs/claude/trust-routing-network-77xwmg",
      "by": [
        "person/michael"
      ],
      "asserted": "2026-09-07",
      "assertedBy": "agent/flashyid-ci",
      "visibility": "public",
      "detail": "Merge main, and carry the session's estate work to the shipping ref",
      "refs": {
        "commit": "cb9c9350953cbc6e0894ee19df183f9139d032a0",
        "pr": "https://github.com/FlashyLabs/flashyid/pull/24"
      },
      "digest": "67856e801484dce3bfb70df6ef20875c21f745e97b1c6349cbd5b2ca6f43b2cb"
    },
    {
      "id": "ship/flashyid/77fe4734f6b5",
      "repo": "repo/flashyid",
      "at": "2026-09-07T11:05:45-04:00",
      "kind": "feature",
      "title": "Merge pull request #22 from FlashyLabs/claude/source-code-audit-b97g8c",
      "by": [
        "person/michael"
      ],
      "asserted": "2026-09-07",
      "assertedBy": "agent/flashyid-ci",
      "visibility": "public",
      "detail": "feat(rail): flashyID mints the rail's rewards:issue credential",
      "refs": {
        "commit": "77fe4734f6b5571e98b834e3f29e9976dbc1f4b5",
        "pr": "https://github.com/FlashyLabs/flashyid/pull/22"
      },
      "digest": "020fadf5003e7d19c2812a4f3519f85a90cb0977718c6ff39d4471085cc0d163"
    },
    {
      "id": "ship/flashyid/6283de15a0de",
      "repo": "repo/flashyid",
      "at": "2026-09-07T09:59:08-04:00",
      "kind": "feature",
      "title": "Merge pull request #21 from FlashyLabs/claude/source-code-audit-b97g8c",
      "by": [
        "person/michael"
      ],
      "asserted": "2026-09-07",
      "assertedBy": "agent/flashyid-ci",
      "visibility": "public",
      "detail": "feat(sdk): mint the three tokens Flashy Rails verifies (Phase 3)",
      "refs": {
        "commit": "6283de15a0de77f1c8f61aebe065a7be91a03728",
        "pr": "https://github.com/FlashyLabs/flashyid/pull/21"
      },
      "digest": "20483332de5da7aecf73829f0c0ba7be6f39e05942851e39a2903450eb47fd78"
    },
    {
      "id": "ship/flashyid/1e97bc5b6516",
      "repo": "repo/flashyid",
      "at": "2026-09-06T12:20:18+00:00",
      "kind": "fix",
      "title": "Hold the entry that publishes this property's shard in the public record",
      "by": [
        "agent/claude"
      ],
      "asserted": "2026-09-06",
      "assertedBy": "agent/flashyid-ci",
      "visibility": "public",
      "detail": "A shipped/1 entry is served at the well-known surface any stranger can fetch,\nand this one is titled with the word a finder is meant to discover by typing\n`flashy` on the page. The estate's public record was handing out an answer to\nits own hunt while every structural check reported the hunt healthy.\n\nFound by tools/bundle-reach.mjs in flashyos, which walks what a deployed page\ncan reach — and found on its SECOND run, after a merge brought a fresher\nrecord in. A gate that only catches what existed the day it was written is a\nsnapshot; this one caught an entry that arrived afterwards.\n\n.shiplog/held.json maps the sha to the reason. The entry stays in this\nrepository's record, sealed and counted; only the published projection omits\nit. Holding is not remediation — the commit message is still in git history.\n\nKind: fix\n\nCo-Authored-By: Claude Opus 5 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01BjzD1kWqueq1ArT1m4mZsy",
      "refs": {
        "commit": "1e97bc5b65169be2e19d06cde76ac62c6c313e4f"
      },
      "digest": "f4755c345b380d61dd02b63b4a740513636bcebaed5e6684d42c06e52cbc9307"
    },
    {
      "id": "ship/flashyid/5f2cb316ef52",
      "repo": "repo/flashyid",
      "at": "2026-09-06T11:23:51+00:00",
      "kind": "fix",
      "title": "Land the component half of the egg fix, which the previous commit dropped",
      "by": [
        "agent/claude"
      ],
      "asserted": "2026-09-06",
      "assertedBy": "agent/flashyid-ci",
      "visibility": "public",
      "detail": "The previous commit here carried .bolt/bolt.js and the re-vendored emitter and\nNOT the component that imports them, so its message described a fix half of\nwhich was not in it. The cause is worth writing down because it is silent: a\nsingle `git add -A a b c` with one pathspec that does not exist in this\nrepository fails the whole command and stages nothing, and the loop that ran\nit sent stderr to /dev/null. Every repository reported a clean push.\n\nThe component is the half that matters. It imports `.bolt/bolt.js` rather than\ncomputing a path to `.bolt/bolt.html` at request time — a computed path is\ninvisible to Next's output file tracing, so the file is not carried into the\ndeployed function, existsSync returns false, and the component returns null\nsilently. That is why Tier I of bolt/1 was unwinnable a week after it was\nsealed as a permanent puzzle.\n\ntests/hunt.test.ts is the invariant rather than the repair: import and never\nread, a module that exists and carries this property's shard, module and HTML\nthe same bytes, the layout actually rendering it, the emitter reproducing what\nis committed, and the vendored emitter byte-identical to canon. Every\nassertion strips comments before matching, because a test that greps a file\npunishes an explanation.\n\nKind: fix\n\nCo-Authored-By: Claude Opus 5 <noreply@anthropic.com>\n\nClaude-Session: https://claude.ai/code/session_01BjzD1kWqueq1ArT1m4mZsy",
      "refs": {
        "commit": "5f2cb316ef520cbc4a9dd3b74d1b58888b5d36ec"
      },
      "digest": "794213d1cf4288adab87fb076aa4e6ecbc4ec4d76edb3bfcf5e7191c93b1fa26"
    },
    {
      "id": "ship/flashyid/ec0abac28007",
      "repo": "repo/flashyid",
      "at": "2026-09-06T11:18:06+00:00",
      "kind": "fix",
      "title": "The egg is carried by the bundler, never read at runtime",
      "by": [
        "agent/claude"
      ],
      "asserted": "2026-09-06",
      "assertedBy": "agent/flashyid-ci",
      "visibility": "public",
      "detail": "Tier I of bolt/1 was sealed on 2026-08-31 as a permanent puzzle and was\nunwinnable a week later. The correlation is by MECHANISM rather than by\nproperty: every property that bakes the snippet into committed HTML serves\nits shard, and every Next property that reads it at request time serves\nnothing — with the code on the shipping branch, the deploy current, and\nnothing anywhere red.\n\nA path computed from process.cwd() is invisible to Next's output file\ntracing, so the file is never carried into the deployed function, existsSync\nreturns false, and the component returns null. Silently, because the format\nmade absence silent on purpose so a checkout with no shard would still build.\nThat explanation is consistent with every data point available and is NOT\nproven — settling it needs a production build served by `next start`, or the\nVercel build log.\n\nSo this does not argue with the hypothesis; it removes the question.\nvendor-bolt.mjs now emits `.bolt/bolt.js` beside the HTML, and the component\nimports it. A static import is a dependency the bundler can see, and an\nabsent module is a build error rather than a page that quietly has no egg.\nAn entire failure class goes away rather than one property being patched with\nan outputFileTracingIncludes entry the next adopter has to rediscover.\n\nProved in flashyos rather than assumed: before this change the shard appeared\nin nothing the marketing build emitted; after it, in two server chunks.\n\nThis property had no test for its egg at all, which is why nothing said so.\nIt has one now, and it asserts the invariant rather than the repair: the\ncomponent imports and never reads, the module exists and carries this\nproperty's shard, the module and the HTML are the same bytes, the layout\nactually renders it, and the emitter run here reproduces what is committed.\nEvery assertion strips comments before matching, because a test that reads\nprose punishes an explanation — this estate's recorded mistake three times\nover, and made twice more while",
      "refs": {
        "commit": "ec0abac280074972a47e3565dad06c222c6eef2b"
      },
      "digest": "370ead1c00896f6185edd72db2ede0e10eed9a498d6947e8907aaa7194c63e35"
    },
    {
      "id": "ship/flashyid/ecdf566776d9",
      "repo": "repo/flashyid",
      "at": "2026-09-05T18:32:23-04:00",
      "kind": "feature",
      "title": "Add verification/1 content-free notary source (#20)",
      "by": [
        "person/michael"
      ],
      "asserted": "2026-09-07",
      "assertedBy": "agent/flashyid-ci",
      "visibility": "public",
      "detail": "Add verification/1 content-free notary source",
      "refs": {
        "commit": "ecdf566776d93266354697371eb035a58670a17e",
        "pr": "https://github.com/FlashyLabs/flashyid/pull/20"
      },
      "digest": "fd2b874eaec28efbcf2039525c87f07c079e5a315bb78ccbd1b8da0245b44e32"
    },
    {
      "id": "ship/flashyid/dcbd33a50d85",
      "repo": "repo/flashyid",
      "at": "2026-09-05T12:42:05+00:00",
      "kind": "docs",
      "title": "the hunt's size is not written down here",
      "by": [
        "agent/claude"
      ],
      "asserted": "2026-09-06",
      "assertedBy": "agent/flashyid-ci",
      "visibility": "public",
      "detail": "\"ten domains\" was true when the section was written and is not now — the\nestate register decides who plays, and a count in prose decays faster\nthan anything else recorded here. The sentence says what is durable\ninstead: every live property hides one word.\n\nKind: docs\n\nCo-Authored-By: Claude Opus 5 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01BjzD1kWqueq1ArT1m4mZsy",
      "refs": {
        "commit": "dcbd33a50d8587b6524d97480c05297837cb6191"
      },
      "digest": "8b0c607084020a1b4e1f19adf69f88d304a18ea85968e935fec986a04c61b85f"
    },
    {
      "id": "ship/flashyid/6863b8e0b486",
      "repo": "repo/flashyid",
      "at": "2026-09-04T19:19:06Z",
      "kind": "fix",
      "title": "Build the app, not the drift test — flashyid.com's deploy has been dead since 26 August",
      "by": [
        "agent/claude"
      ],
      "asserted": "2026-09-04",
      "assertedBy": "agent/flashyid-ci",
      "visibility": "public",
      "detail": "Kind: fix\n\nThe Vercel build log names it exactly:\n\n    ../packages/sdk/src/sdk/sign.ts:1:39\n    Type error: Cannot find module 'jose' or its corresponding type declarations.\n\n`site/tsconfig.json` included `**/*.ts`, which picks up\n`tests/institutional.test.ts` — a real drift test that imports\n`../../packages/sdk` to assert the SDK methods this site documents are the\nones the package exports. So `next build` typechecked the SDK's source, which\nimports `jose` from the ROOT package.json.\n\nVercel's Root Directory is `site`. It runs `npm ci` here and nowhere else, so\n`jose` is never installed and every production build has failed on that line\nfor nine days. The live domain has served a build from before 26 August the\nwhole time — which is why /icon.svg and /lockup.svg 404 while both are green\nin this checkout, the finding already written up in CLAUDE.md as a Vercel\nsetting only the owner could fix. It was not a setting. It was this.\n\nCI hid it. `ci.yml` installed the site's dependencies and then the\nrepository's, and the second install is what made `jose` resolve — so the\npipeline was green about a build that could not happen. A check that installs\nwhat the real build does not have is not checking the real build.\n\nThree changes:\n\n- `site/tsconfig.json` excludes `tests`. The app build compiles the app.\n- `site/tsconfig.tests.json` typechecks the tests, where reaching outside\n  `site/` is the point. The drift test still runs, unchanged.\n- `ci.yml` runs the app typecheck and the build BEFORE the root install, in\n  that order, so the pipeline fails wherever Vercel would.\n\n`tests/build-isolation.test.ts` pins the rule rather than the symptom: no\nfile the app build compiles may import a path resolving outside `site/`.\n\nReproduced against the real failure before fixing it — with the root and\nnested `node_modules` moved aside, `tsc` emits the two errors from the\nproduction log; with the fix, it is clean and `next build` completes.\n\nCo-Authored-By: Claude Opus 5 <noreply@anthropi",
      "refs": {
        "commit": "6863b8e0b4865aea0a04055037bdc815daeb151e"
      },
      "digest": "af227a7cc8e8f17fc7f2d78d4a0f3722b0067737c63f3daba89337c55362610d"
    },
    {
      "id": "ship/flashyid/f8aa86936836",
      "repo": "repo/flashyid",
      "at": "2026-09-04T17:25:03Z",
      "kind": "other",
      "title": "Re-vendor the directory checker for dependsOn",
      "by": [
        "agent/claude"
      ],
      "asserted": "2026-09-04",
      "assertedBy": "agent/flashyid-ci",
      "visibility": "public",
      "detail": "directory/1 gained an edge type: one published artifact requiring\nanother to run. Not folded into `cites`, which the vocabulary has always\ndocumented as being for sources — a dependency is a hard requirement a\npackage manager enforces, and giving one edge type two meanings is the\nfailure this vocabulary has recorded twice already.\n\nThis copy is byte-identical to packages/directory/vendor-check-directory.mjs\nin flashyos. Changing the source there does nothing here until the copy\nis replaced, and a stale copy does not fail — it disagrees, silently,\nabout exactly the field somebody has just changed.\n\nKind: chore\n\nCo-Authored-By: Claude Opus 5 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01BEaXzktRU5ZPe3R2NY7CKD",
      "refs": {
        "commit": "f8aa86936836534d3110a3f6175b7c39c606cf3d"
      },
      "digest": "364bdb765f629b5ad0500400304b853b5e287598fe1c8cd673e6df80745cba75"
    },
    {
      "id": "ship/flashyid/8e131b5ba0b8",
      "repo": "repo/flashyid",
      "at": "2026-09-03T02:59:11Z",
      "kind": "other",
      "title": "The machine-age doors: /engage names the three ways in",
      "by": [
        "agent/claude"
      ],
      "asserted": "2026-09-03",
      "assertedBy": "agent/flashyid-ci",
      "visibility": "public",
      "detail": "One page in site/, three doors, each cited rather than restated: an AAO\ncharter our agents can read (conformance init, flashyos.com/join, and\nthe handshake this property serves through its declared dotted-path\nrewrites), the human graph (magician.network/join and this property's\nconcierge), and the machine surfaces an agent reads here — jwks and\nopenapi beside the mesh and record files. IntentMesh is named without a\nlink because no URL for it exists yet; the estate ladder is one line,\ncited to gord.holdings/engage. Registered in the footer's Learn column,\nllms.txt and the sitemap — which is what makes the footer link pass the\nlink-integrity sweep; tests/engage.test.ts pins the page, the three\ndoors and both join links.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01EXAA7bi94PPtBupN1jGt9N",
      "refs": {
        "commit": "8e131b5ba0b86029d49d85263d40b02682730b3f"
      },
      "digest": "cfcc947aba5f322f2e2e0b6fc5714b1ded906f6e180d68334718399e12b2a249"
    },
    {
      "id": "ship/flashyid/29c375a952aa",
      "repo": "repo/flashyid",
      "at": "2026-09-02T17:34:02Z",
      "kind": "infra",
      "title": "Pin the hosting configuration where a machine reads it",
      "by": [
        "agent/claude"
      ],
      "asserted": "2026-09-02",
      "assertedBy": "agent/flashyid-ci",
      "visibility": "public",
      "detail": "Creating a Vercel project asks three questions — framework preset, build\ncommand, output directory — and the answers were in a panel that cannot be\nread from a checkout, shown in a diff, or tested. This repository now\nanswers all three in its own vercel.json, at the directory Vercel serves,\nso setting up the project is import, Root Directory, Production Branch,\ndomains, and nothing else.\n\nFor a static root the two keys that matter are `framework: null` — stop\nautodetecting from a parent directory — and `outputDirectory: \".\"`, because\nthe directory is the site; with no package.json there, nothing installs and\nnothing builds. `deploy/1`'s checker now refuses a vercel target whose root\nhas no such file, so it cannot quietly go missing later.\n\n`installCommand` is deliberately not pinned where it was not already: `npm\nci` fails outright where `npm install` forgives a lockfile that has\ndrifted, and changing how a live site installs is not one of the decisions\nthis is removing.\n\nKind: chore\n\nCo-Authored-By: Claude Opus 5 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01BEaXzktRU5ZPe3R2NY7CKD",
      "refs": {
        "commit": "29c375a952aa60aca44cbb43c217116ed169294d"
      },
      "digest": "8ec0c8d6afa7dd95fb7740aef57e50671fb402baba8c00d255400e2ebec1f19d"
    },
    {
      "id": "ship/flashyid/37b388337856",
      "repo": "repo/flashyid",
      "at": "2026-09-02T16:22:39Z",
      "kind": "other",
      "title": "Re-vendor: the ship log learns ritual/1 before its first commit",
      "by": [
        "agent/claude"
      ],
      "asserted": "2026-09-02",
      "assertedBy": "agent/flashyid-ci",
      "visibility": "public",
      "detail": "`vendor-shiplog.mjs` gained `ritual/1: observe the office` in\nBOOKKEEPING_SUBJECTS upstream, so every copy in this estate disagreed with\ncanon about whether that workflow's refresh commits are work. A stale\nvendored copy does not fail — it disagrees, silently, about exactly the\nfield somebody has just changed, and the last three entries on that list\nwere each added only after their commits had already sealed as work under\nagent/unattributed.\n\nReplaced by `node tools/estate-revendor.mjs --write` in flashyos, which\ncompares every copy byte-for-byte against the default branch rather than\nagainst whatever is checked out.\n\nKind: chore\n\nCo-Authored-By: Claude Opus 5 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01BEaXzktRU5ZPe3R2NY7CKD",
      "refs": {
        "commit": "37b388337856ee6a2eb8717ee9d20b64a01aba0a"
      },
      "digest": "4d5f8111c0e815d970bbf60467a105b6c3e13a7e569e06daa4d3d77440e1e148"
    },
    {
      "id": "ship/flashyid/d3d02d6c0d51",
      "repo": "repo/flashyid",
      "at": "2026-09-02T16:13:23Z",
      "kind": "feature",
      "title": "deploy/1: declare where this repository is hosted",
      "by": [
        "agent/claude"
      ],
      "asserted": "2026-09-02",
      "assertedBy": "agent/flashyid-ci",
      "visibility": "public",
      "detail": "Root directory, production branch, framework and registrar, in a file a\nmachine can check instead of in two settings panels nobody can read from a\ncheckout.\n\nThe estate spent an afternoon on 2026-09-02 answering \"which domains are\nhosted and what does each one still need\". Every fact it produced already\nexisted — in a Vercel panel, a GoDaddy zone, and somebody memory — and none\nof it was anywhere a check could reach. Fourteen estate domains were\nresolving to a parking page with finished sites committed behind them.\n\nThe checker is dependency-free and runs before an install. Two of its rules\nare ones nothing else here makes: a root directory that does not exist in\nthe tree is refused, because a hosting project pointed at a typo builds\nnothing and reports success; and a production branch is refused if it does\nnot exist on origin, or if it differs from the default with no written\nreason — an accidental divergence and a deliberate one look identical from\ninside a panel.\n\nIt carries no credentials, no account or project identifiers, and no DNS\nrecord values. The first because the value of this file is that the\nrepository can be handed to somebody else; the last because those belong to\nthe host and they move — Vercel went from 76.76.21.21 to 216.198.79.1, and a\ncopy of that in thirty repositories is thirty copies to update.\n\nEvery value here was measured, not remembered.\n\nKind: feature\n\nCo-Authored-By: Claude Opus 5 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01BEaXzktRU5ZPe3R2NY7CKD",
      "refs": {
        "commit": "d3d02d6c0d5179e6fb79936f0d7cb993dc8d5bd7"
      },
      "digest": "12e5923c910b5722586606743b64cab5b4e0a05567ea0660f10814cbd934269f"
    },
    {
      "id": "ship/flashyid/6a5ae24ff9e3",
      "repo": "repo/flashyid",
      "at": "2026-09-02T01:07:10Z",
      "kind": "other",
      "title": "Roll the deploy: the icons have been on main since c6f9c65 and the domain still 404s them",
      "by": [
        "agent/claude"
      ],
      "asserted": "2026-09-02",
      "assertedBy": "agent/flashyid-ci",
      "visibility": "public",
      "detail": "No render change needed — icon.svg, favicon.ico and apple-icon.png are\nalready on this branch and correct. This commit is the deliberate\ndeploy trigger (no skip markers, per this repository's own rule): if\nthe domain does not pick it up, the diagnosis in CLAUDE.md stands and\nthe fix is the Vercel Production Branch setting, which only the owner\ncan reach.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01X8LDnsexvNjSkqc2ihZR7U",
      "refs": {
        "commit": "6a5ae24ff9e3fc78b5f5536b2bfc05220d2b423f"
      },
      "digest": "10f7bf14a8cb1fe94d467eb9cfa83a5eb65e609c916cb64fd8f594a756521c80"
    },
    {
      "id": "ship/flashyid/54d743af91a4",
      "repo": "repo/flashyid",
      "at": "2026-09-01T21:08:58Z",
      "kind": "feature",
      "title": "Tell the estate the moment this repository pushes a record",
      "by": [
        "agent/claude"
      ],
      "asserted": "2026-09-01",
      "assertedBy": "agent/flashyid-ci",
      "visibility": "public",
      "detail": "graph.yml in flashyos merges every property's fragment on a daily\nschedule, so without a dispatch a change here is invisible to the estate\nfor up to 24 hours — and \"the graph is a day behind\" is\nindistinguishable from \"this property has nothing new to say\".\n\nThe dispatch has been in the shiplog/backlog template since August and\nin no repository, because each vendored its workflow before the template\nhad it. This adds it, gated on the commit step having actually pushed: a\ndispatch per run rather than per change would turn one daily merge into\na merge per push across thirty repositories.\n\nThe commit step is replaced with one canonical form rather than patched,\nbecause the estate had two vintages of it — some repositories carry a\nfive-attempt push retry the template lacked, and re-emitting would have\ndeleted it. Both halves are here now.\n\nThe retry resolves the branch per run instead of resetting to a literal\norigin/main. Eleven repositories in this estate have an agent branch as\ntheir default, and there a rejected push would reset the checkout to a\ndifferent branch and push that over the deploy branch.\n\nUnset ESTATE_DISPATCH_TOKEN means a delay of up to 24 hours, never a\nloss — the daily merge is the floor, and the step says so loudly rather\nthan skipping green.\n\nKind: feature\n\nCo-Authored-By: Claude Opus 5 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01FDosmV9fXV6oZ9NXe7PZ76",
      "refs": {
        "commit": "54d743af91a408de232e7b261af030fea7f8f27e"
      },
      "digest": "7703da101e07b738d95d33d5b1bb1956b859e48fd6542a8835e98e8cdd1b5622"
    },
    {
      "id": "ship/flashyid/ee17000a214f",
      "repo": "repo/flashyid",
      "at": "2026-09-01T19:23:14Z",
      "kind": "feature",
      "title": "Serve the backlog projection at /.well-known/intent.json too",
      "by": [
        "agent/claude"
      ],
      "asserted": "2026-09-01",
      "assertedBy": "agent/flashyid-ci",
      "visibility": "public",
      "detail": "intent/1 is backlog/1's successor name and its readers accept the legacy\nversion key permanently. Here that costs two edits, because this app serves\nwell-known files from an undotted directory with a rewrite per file: the\nserve list gains site/public/well-known/intent.json and next.config.ts gains\nthe dotted rewrite. tests/well-known.test.ts already refuses a served file\nwithout its rewrite, and passes with both halves in place. Validated by the\nintentmesh checker as well as the vendored one.\n\nKind: feat\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01NfXZ2PAsNCENGJupuCQrnH",
      "refs": {
        "commit": "ee17000a214f1dbfe72fe0b48cca1e222ef1739a"
      },
      "digest": "15f248b681a25cc6c1faaf4608ef9378d833de7d1a43f2516c0f63f244730d5d"
    },
    {
      "id": "ship/flashyid/c6c84777240a",
      "repo": "repo/flashyid",
      "at": "2026-09-01T19:08:59Z",
      "kind": "feature",
      "title": "Activate: the Mesh Concierge on flashyid.com",
      "by": [
        "agent/claude"
      ],
      "asserted": "2026-09-01",
      "assertedBy": "agent/flashyid-ci",
      "visibility": "public",
      "detail": "Three of the Activation standard's four artifacts. `/concierge.js` is the\nbuilt bundle of @magician/concierge vendored byte-identical; the root\nlayout includes it once with the charter's own named human, so a filing\nlands in this property's queue rather than a shared one. `/concierge`\ncarries the slot.\n\nThe page says the thing this property in particular has to say: filing\nhere **mints nothing**. No grant, no scope, no claim. An intake door on\nan identity provider is exactly where a visitor might assume otherwise,\nand the rule one layer up — never ship a way to mint authority ahead of\nthe thing that enforces it — reads as decoration if the front door is\nvague about whether it issues anything.\n\nFour tests. The served bundle is asserted to make no network call, keep\nno storage and load no third party — read from the copy a browser runs\nrather than from canon, because checking the source instead of the copy\nis exactly the mistake a vendored file makes easy. It is pinned\nbyte-identical to magician's build when that checkout is beside this one,\nand reported unknown rather than current when it is not. The contact is\nasserted to be the charter's accountableTo rather than an address typed\ntwice. And the accent is asserted to be a hex, because the widget\nmeasures it against its own panel before using it as text.\n\nOne caveat this repository already documents: flashyid.com is serving a\nbuild older than `main`. Committed is not served, so the door is in the\nrepository and will not be at the domain until that deployment is fixed.\n\nKind: feature\n\nCo-Authored-By: Claude Opus 5 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01BEaXzktRU5ZPe3R2NY7CKD",
      "refs": {
        "commit": "c6c84777240a1c931a874feba31fee5b989fc417"
      },
      "digest": "a822c6e6460dc1a213d8b8f4608ba0917fc3088bad12f1211ab9a1266e31479e"
    },
    {
      "id": "ship/flashyid/6d683fe17e75",
      "repo": "repo/flashyid",
      "at": "2026-09-01T17:58:21Z",
      "kind": "other",
      "title": "Re-vendor shiplog: the filter learns directory/1, delivery/1 and intent/1",
      "by": [
        "agent/claude"
      ],
      "asserted": "2026-09-01",
      "assertedBy": "agent/flashyid-ci",
      "visibility": "public",
      "detail": "Three formats gained a workflow that commits a refresh. Without this the\nfirst run of each seals as work under agent/unattributed, inflating the\ntwo numbers the record exists to make honest.\n\nA vendored change does nothing until the copy is replaced, and a stale\ncopy does not fail — it disagrees, silently, about exactly the field\nsomebody has just changed.\n\nKind: chore",
      "refs": {
        "commit": "6d683fe17e75db7d9a0d602d9ee1086a4dbc142e"
      },
      "digest": "2eb2ffdfa5a2a35ea378b86b830fb94a94bd34c2eb2b68c55abe79c52995444d"
    },
    {
      "id": "ship/flashyid/5c9d9b37b122",
      "repo": "repo/flashyid",
      "at": "2026-09-01T14:53:46Z",
      "kind": "feature",
      "title": "Give this repository's directory fragment a machine that refreshes it",
      "by": [
        "agent/claude"
      ],
      "asserted": "2026-09-01",
      "assertedBy": "agent/flashyid-ci",
      "visibility": "public",
      "detail": "shipped/1 and backlog/1 each ship a workflow with their adoption, so\nevery repository filing one has something re-running the emitter.\ndirectory/1 never did — sixteen repositories in this estate got the\nfragment and nothing else, and were still serving the bytes one\nhand-sweep produced on 2026-08-31.\n\nNothing was red, and nothing would have gone red. A fragment nobody\nre-emits does not decay for a year; it stops being true. A machine\nsurface added here never enters the graph, the asserted date freezes,\nand a change to the vendored emitter reaches a copy that never runs it.\n\nThe workflow is generated by workflow() in @flashyos/directory rather\nthan hand-written, gates on the default branch resolved per run, and\ncommits with [skip ci] because a refresh is a record of what already\nhappened.\n\nvendor-shiplog.mjs is re-vendored in the same commit: its bookkeeping\nfilter had never heard of \"directory/1: refresh the fragment\", so the\nfirst refresh would have sealed as work under agent/unattributed.\n\nKind: feature",
      "refs": {
        "commit": "5c9d9b37b1225e5ca7f03932ccf34e86756c22e8"
      },
      "digest": "4bd70fe78abd9404d2249c1736b9c3ade92bfaf3e93a8f25592f7bf1b2c35985"
    },
    {
      "id": "ship/flashyid/084c9b1d8c54",
      "repo": "repo/flashyid",
      "at": "2026-09-01T14:33:33Z",
      "kind": "fix",
      "title": "Re-vendor check-directory.mjs: enforce what every edge type must carry",
      "by": [
        "agent/claude"
      ],
      "asserted": "2026-09-01",
      "assertedBy": "agent/flashyid-ci",
      "visibility": "public",
      "detail": "The vendored checker had hand-written blocks for three of the sixteen edge\ntypes and nothing for the other thirteen, so engaged without a basis,\ndelegatedTo without a scope and issued without a date all validated clean —\nin thirty identical copies that agreed with each other perfectly.\n\nIt reads a requires table now, mirroring EDGE_REQUIRES in\n@flashyos/directory, with one conditional: `declares` needs a role when it\nnames an agent and not when it names a machine surface. That split was\nmeasured, not decided — across the estate all 88 agent declarations carry a\nrole and none of the 43 surface declarations do.\n\nflashyos/tools/vendored-directory.test.mjs differentials this copy against\nthe package by verdict, and asserts every estate copy is byte-identical to\nit. This repository's fragment passes the stricter checker unchanged.\n\nKind: fix",
      "refs": {
        "commit": "084c9b1d8c540ca7945a5036cf8b8c19ce6305aa"
      },
      "digest": "47f5cfcfae6af3c6b1603a16b0618aab0b7ce445749c2bd2b7de35081d88010a"
    },
    {
      "id": "ship/flashyid/6b0a9141393a",
      "repo": "repo/flashyid",
      "at": "2026-09-01T14:23:18Z",
      "kind": "other",
      "title": "The wordmark is in the page now, not fetched from beside it",
      "by": [
        "agent/claude"
      ],
      "asserted": "2026-09-01",
      "assertedBy": "agent/flashyid-ci",
      "visibility": "public",
      "detail": "flashyid.com served /lockup.svg a 404 while the file sat correct in\nsite/public/. The cause is a stale deployment — the CDN age header reads ~5.8\ndays, predating the commit that added the asset — and only its owner can\nchange the Vercel setting behind it. What is fixable here is the shape.\n\nA wordmark fetched as a second request can go missing for reasons that have\nnothing to do with the page: a stale build, a changed Root Directory, a\npublic/ that did not ship, a CDN that cached the 404. Every one renders a\nbroken image where the company name goes, on the front page, and not one of\nthem fails a test. Inline, there is nothing to fetch and nothing to miss.\n\nThis is not the \"rebuilt from spans\" the old comment warned against. The\ngeometry is identical and `mark.test.ts` proves it rather than trusting the\ncopy: it compares every coordinate in the component against public/lockup.svg,\nevery colour by value, and the accessible name — the drift that already bit\nthe consent screen once, where the same shape in the same colours carried a\ndifferent aria-label inside a base64 blob no reviewer reads.\n\nRoot width and height are excluded from that comparison on purpose: the\ncomponent takes them as props so a caller can size the mark, and the viewBox\nis what fixes the proportions.\n\nThe file stays. A partner embedding the mark, or a card unfurling a link,\ngenuinely needs a URL — inlining is for the page.\n\nTwo of my own test bugs, found by running it: the geometry extractor counted\nthe parameterised width/height as drift, and the \"must not fetch the lockup\"\ncheck matched the comment explaining why it no longer does.\n\nAlso: LICENSE now opens with the Apache text rather than a copyright header,\nso a scanner can see it. Same licence, same holder — moved into Apache's own\nAPPENDIX slot. Every repository in this estate reads NOASSERTION on GitHub for\nthis reason; the rule and the rewrite live in flashyos's licence register.\n\n17 tests in mark.test.ts. Build green, 41 pages.",
      "refs": {
        "commit": "6b0a9141393af1f4ccf1582eb85116724ac38c2a"
      },
      "digest": "ee5c181c6cb2206063e941b5860806b2874a98838060459a6abfa04c933b40c5"
    },
    {
      "id": "ship/flashyid/321e5748b864",
      "repo": "repo/flashyid",
      "at": "2026-09-01T07:20:38Z",
      "kind": "other",
      "title": "Source audit — the reviewer is right about the signature",
      "by": [
        "agent/claude"
      ],
      "asserted": "2026-09-01",
      "assertedBy": "agent/flashyid-ci",
      "visibility": "public",
      "detail": "An outside reviewer audited the live surface and asked whether the chain is\nsigned at each hop or attested as a whole. GrantLink declares nine fields and\nnone of them is a signature, so the homepage sentence \"signed at every link\"\nis not a simplification — it is inaccurate, and it is the only false claim on\nthe property.\n\nTwo defects visible only from source, and one hides the other: verifyAssertion\npasses no `algorithms` to jwtVerify while the spec states it tracks RFC 8725,\nand the key installed as FLASHYID_JWKS was generated RSA/RS256 while the site,\nthe spec and signAssertion all say EdDSA/Ed25519. Pin the algorithm and the\nkey mismatch surfaces immediately, which is the correct loud outcome.\n\nAlso: the site publishes seven refusal codes and the SDK declares nine — the\ntwo missing are approval_required and untrusted_root, both security-relevant.\nThree demand fields fail open when omitted. trustedRoots is optional and\ndefaults to accepting any root, against its own comment's advice.\n\nRecommends hash-linked grants with an optional per-link proof rather than\nnested JWS: full per-link signing is a key-distribution problem, not a\ncryptography one, and it is why Macaroons and Biscuit stayed single-vendor.\n\nCo-Authored-By: Claude Opus 5 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01EEAAmijDh3kzFH7SY53jZ7",
      "refs": {
        "commit": "321e5748b86430792668e386bfd6ad564ce6c2aa"
      },
      "digest": "b79c58374a683ab0945284fa3040da5b89be323869e0a3962cd8fdf17a3c5c92"
    },
    {
      "id": "ship/flashyid/89d4c464d049",
      "repo": "repo/flashyid",
      "at": "2026-09-01T03:40:49Z",
      "kind": "docs",
      "title": "Document the shard, and deploy it",
      "by": [
        "agent/claude"
      ],
      "asserted": "2026-09-01",
      "assertedBy": "agent/flashyid-ci",
      "visibility": "public",
      "detail": "This property's bolt/1 shard went in on a commit marked [vercel skip], so the\nsite never rebuilt and the egg is in git and not on the domain. That marker is\nright for the emitters — their refresh commits were 321 of the estate's 594 in\none day against a 100/day build limit — and wrong for a commit that changes\nwhat the site renders. Written down here so the next person does not repeat it.\n\nKind: docs",
      "refs": {
        "commit": "89d4c464d049d85858d041818c8e5a1d62a5a818"
      },
      "digest": "7e46f4201d9df8d75743b51f0ae87410c3cd1bb3bb56bd8a411a86c8e535bf14"
    },
    {
      "id": "ship/flashyid/c4ac1bc06fee",
      "repo": "repo/flashyid",
      "at": "2026-08-31T20:54:13Z",
      "kind": "infra",
      "title": "Hold the attribution line: freeze what sealed, refuse what would seal next",
      "by": [
        "agent/claude"
      ],
      "asserted": "2026-09-01",
      "assertedBy": "agent/flashyid-ci",
      "visibility": "public",
      "detail": "The bookkeeping-filter window let emitter refresh commits seal as shipped\nentries under agent/unattributed. The fixed vendor-shiplog.mjs is already\non this branch; this adds the test that makes the line hold — the sealed\nentries are frozen by id (sealed is final under append-only) and any new\nunattributed entry fails the suite.\n\nKind: test\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01NfXZ2PAsNCENGJupuCQrnH",
      "refs": {
        "commit": "c4ac1bc06feed8f6daddfd742afe60733b046a74"
      },
      "digest": "18e8ed9e39080a72fb7047314d1189a5548ce000c9989bb38057235b611ebe8b"
    },
    {
      "id": "ship/flashyid/b5abbec5c1d2",
      "repo": "repo/flashyid",
      "at": "2026-08-31T19:38:35Z",
      "kind": "fix",
      "title": "Re-vendor the shiplog emitter: the bookkeeping filter learned its suffixes",
      "by": [
        "agent/claude"
      ],
      "asserted": "2026-08-31",
      "assertedBy": "agent/flashyid-ci",
      "visibility": "public",
      "detail": "The emitted refresh subjects grew \", and the checkpoint over it\" and\n\"[skip ci]\", and the exact-match anchor in the old copy missed both — so\nevery refresh commit sealed as a shipped entry under agent/unattributed.\ngda-group sealed six before the fix landed. Byte-identical with\npackages/shiplog/vendor-shiplog.mjs in flashyos as of its fix.\n\nKind: fix\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01NfXZ2PAsNCENGJupuCQrnH",
      "refs": {
        "commit": "b5abbec5c1d241c427270f0d7db1f0910018fa1b"
      },
      "digest": "f69bdc71abb26bc4393908d42ca2abae2a6ed65ba2c8b939a4a7cbaf193b7f1e"
    },
    {
      "id": "ship/flashyid/8b66c575c3f7",
      "repo": "repo/flashyid",
      "at": "2026-08-31T17:55:18Z",
      "kind": "other",
      "title": "Ring the settlement record, and hold the footer to llms.txt",
      "by": [
        "agent/claude"
      ],
      "asserted": "2026-08-31",
      "assertedBy": "agent/flashyid-ci",
      "visibility": "public",
      "detail": "flashyos.com publishes syndicate/1 at /estate-feed.json; its computed ring\nfor this property is the three hubs — coordination, settlement, the parent.\nThe footer's ESTATE_RING carried two of them and not flashynetwork.com,\nwhile llms.txt named it, so the two surfaces of this one site told a reader\ndifferent estates. Identity answers who may act; settlement answers what was\nrecorded and whether it reconciled — the footer now links it too.\n\ntests/estate-feed.test.ts holds the ring to the computed three (every member\nbeyond them carries a written reason, every reason names a real member, so\nthe exemptions self-clean) and holds the footer to llms.txt: every ring href\nmust appear in the route. Writing that test found a third drift on the spot\n— llms.txt never named Flashy Mind while the footer linked it. It does now.\n\nThis property serves no ring manifest of its own, so there is no live half;\nthe computed ring is pinned as data, in the consistency.test.ts house style\nof one canonical value asserted on every surface that repeats it.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01NfXZ2PAsNCENGJupuCQrnH",
      "refs": {
        "commit": "8b66c575c3f7fb7ff704f8f947f832919a986c76"
      },
      "digest": "786465ec93af0afc80823cef2624517fc9ced396d4656880759fa5bbd0e76ac3"
    },
    {
      "id": "ship/flashyid/95aaf035e7e6",
      "repo": "repo/flashyid",
      "at": "2026-08-31T17:00:27Z",
      "kind": "fix",
      "title": "Serve the icon at the two paths that never go through the head link",
      "by": [
        "agent/claude"
      ],
      "asserted": "2026-08-31",
      "assertedBy": "agent/flashyid-ci",
      "visibility": "public",
      "detail": "Same fix as flashy-academy, and here it lands on a site that is not deploying.\n\n/favicon.ico and /apple-icon.png both 404. Chrome asks for the first directly\nfor bookmarks and some tab contexts, a long tail of feed readers and chat\nunfurlers is hard-coded to it, and the second is an iOS home-screen tile with\nno SVG support at all. A client that gets nothing keeps the icon it already\nhad, which is what a stale-looking favicon is from outside.\n\nBoth are generated by site/scripts/make-icons.mjs, which reads the same path\ndata and the same two colours out of icon.svg and rasterises them. A\nhand-drawn second copy would be a second source of truth for the mark, which\nis the failure site/tests/mark.test.ts already exists to catch one surface\nover. icons.test.ts checks that regenerating right now produces the same\nbytes, not merely that the files exist.\n\nThis changes nothing a visitor sees until the site deploys. flashyid.com is\nserving a build from 2026-08-26 — age 424223 on every response, x-vercel-cache\nHIT, and zero icon references in the live HTML — which this repository's own\nCLAUDE.md already documents with the three candidate causes. The icon work is\ncorrect and stranded behind that.\n\nKind: fix\n\nCo-Authored-By: Claude Opus 5 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01VgrPGGUFKMq9zXBHnfcTgs",
      "refs": {
        "commit": "95aaf035e7e6d1c84ea65c3d9bc812fed5bb39a2"
      },
      "digest": "1b9491fa67dd792410afd08c4ac9dd686e0721688b04281c0431f40b848055d3"
    },
    {
      "id": "ship/flashyid/a44be41f8ee3",
      "repo": "repo/flashyid",
      "at": "2026-08-31T16:43:06Z",
      "kind": "fix",
      "title": "An emitted record must not spend a deploy [vercel skip]",
      "by": [
        "agent/claude"
      ],
      "asserted": "2026-08-31",
      "assertedBy": "agent/flashyid-ci",
      "visibility": "public",
      "detail": "The emitters commit a refreshed fragment on every push, and each of those is a\ndeployment. On 2026-08-31 the estate landed 594 commits on default branches and\n321 of them — 54% — were emitters refreshing their own output. Vercel's build\nrate limit is 100 a day across the account, so the record-keeping machinery was\nconsuming the whole estate's deploy budget three times over and starving the\npushes people actually made.\n\nIt was invisible everywhere. Each property sat a few revisions behind, gda.group\nhad stopped on 30 August, nothing was red. The one place it was written down was\na commit status on a dependabot PR nobody had opened: \"Deployment rate limited —\nretry in 24 hours.\"\n\n[skip ci] is the marker Vercel and GitHub Actions both honour. The fragment\nstill reaches the domain on the next deploy a real push triggers, which is the\nright cadence for a record of something that already happened.\n\nThis commit carries [vercel skip] rather than [skip ci] so CI still validates\nit without spending one of the deploys it exists to save.\n\nKind: fix",
      "refs": {
        "commit": "a44be41f8ee32f820b6108e6cafa1af18e14fc02"
      },
      "digest": "7065e3289fff873cc0c60b886a804d5d30534916e4cad8b447909ba59adee65b"
    },
    {
      "id": "ship/flashyid/d10114a0371a",
      "repo": "repo/flashyid",
      "at": "2026-08-31T16:22:01-04:00",
      "kind": "feature",
      "title": "Merge pull request #16 from FlashyLabs/claude/gord-directory-spec-3jx7zk",
      "by": [
        "person/michael"
      ],
      "asserted": "2026-08-31",
      "assertedBy": "agent/flashyid-ci",
      "visibility": "public",
      "detail": "The discovery document advertised http:// endpoints under an https issuer",
      "refs": {
        "commit": "d10114a0371af84a9f8b37eac3147045edb4f0df",
        "pr": "https://github.com/FlashyLabs/flashyid/pull/16"
      },
      "digest": "cb753547a14e30c09565e60340b60b1e60d137e12e8d52aa569e0e90c253d0ed"
    },
    {
      "id": "ship/flashyid/3cfbe1589110",
      "repo": "repo/flashyid",
      "at": "2026-08-31T16:19:02Z",
      "kind": "infra",
      "title": "Name the holder the register names, in the boilerplate too",
      "by": [
        "agent/claude"
      ],
      "asserted": "2026-08-31",
      "assertedBy": "agent/flashyid-ci",
      "visibility": "public",
      "detail": "The register in flashyos tools/estate-licences.mjs puts flashyid at\nApache-2.0 held by Flashy Labs, and the header of this LICENSE already said\nso. The Apache appendix further down still said Flashy Group, left there by\nan earlier pass of mine that guessed the entity instead of reading the\nregister — so the file named two different holders.\n\nSame correction in NOTICE. The register remains the authority; this only\nstops the file disagreeing with itself.\n\nCo-Authored-By: Claude Opus 5 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01EEAAmijDh3kzFH7SY53jZ7",
      "refs": {
        "commit": "3cfbe1589110e74fb9e2a6be7cdec54368cb6dfd"
      },
      "digest": "dca18463e29668f7d91f580e9e2d4cbd2afcc65ee222eb95e79f928df5550d64"
    },
    {
      "id": "ship/flashyid/9e94cb102fc0",
      "repo": "repo/flashyid",
      "at": "2026-08-31T15:53:29Z",
      "kind": "infra",
      "title": "shipped/1: refresh the log, and the checkpoint over it",
      "by": [
        "agent/unattributed"
      ],
      "asserted": "2026-08-31",
      "assertedBy": "agent/flashyid-ci",
      "visibility": "public",
      "refs": {
        "commit": "9e94cb102fc06fd941084a062798c5b372144269"
      },
      "digest": "2e0e6bd16b1bc91bf2dee062d09507eeb8ed44cac661e57fc0c7f724163f01bb"
    },
    {
      "id": "ship/flashyid/3543d7eb0229",
      "repo": "repo/flashyid",
      "at": "2026-08-31T14:26:15Z",
      "kind": "fix",
      "title": "One mechanism for the machine surfaces, not two",
      "by": [
        "agent/claude"
      ],
      "asserted": "2026-08-31",
      "assertedBy": "agent/flashyid-ci",
      "visibility": "public",
      "detail": "Next's app router ignores dot-prefixed directories, so `/.well-known/*`\ncannot be a route folder here. This app's answer is documented in\n`next.config.ts`: the files live under `well-known/` and the canonical dotted\npath rewrites onto them.\n\nThree surfaces did not use it. `shiplog.json`, `backlog.json` and\n`checkpoint.json` were written straight into `site/public/.well-known/` with\nno rewrite, sitting beside five files that had one — two mechanisms for one\njob, in one directory listing, and the emitters' `serve` paths pointed at the\nwrong one so every run put them back.\n\nNothing caught it. Both spellings are a file on disk in a directory that looks\nright, and only a fetch of the deployed site can tell them apart — the deploy\nwas stale, so even that said nothing. flashyid.com currently 404s all six.\n\nThe three moved, their `serve` paths follow, and `tests/well-known.test.ts`\nreads `public/well-known/` rather than listing it: a seventh surface without a\nrewrite fails there instead of at the domain a published standard tells\ncounterparties to fetch. It also asserts no dot-directory comes back, because\na file put back in the old place would look correct in a diff.\n\nKind: fix",
      "refs": {
        "commit": "3543d7eb02298aeb428075041e8dc890a7bd3e44"
      },
      "digest": "0cf804bbdb13c6989d94b2caa4c4a43a5777f1bb077048c9cc5788a77eadda9f"
    },
    {
      "id": "ship/flashyid/a839b932dd76",
      "repo": "repo/flashyid",
      "at": "2026-08-31T12:27:00+00:00",
      "kind": "other",
      "title": "Re-vendor the directory checker, which had drifted in twelve repositories",
      "by": [
        "agent/claude"
      ],
      "asserted": "2026-08-31",
      "assertedBy": "agent/flashyid-ci",
      "visibility": "public",
      "detail": "`scripts/check-directory.mjs` is a copy of\n`packages/directory/vendor-check-directory.mjs` in flashyos, under a different\nname — and `estate-hygiene` matched vendored copies by the `vendor-*` filename\npattern, so it never compared this one. Twelve repositories were running a\ncopy old enough not to read `directory.externals.json` at all, which is the\nfile that tells a borrowed id from a dangling one.\n\nNothing failed. That is how a vendored file fails: not by breaking, but by\ndisagreeing about exactly the field somebody has just started writing.\n\nKind: chore",
      "refs": {
        "commit": "a839b932dd76f91e37c095f6be1f93ea232cb6d5"
      },
      "digest": "1ce89a69a518b9e255c70ea6e3e10084e8fef27839e9f9d7c4effb5efbb1a109"
    },
    {
      "id": "ship/flashyid/ad00f95568bd",
      "repo": "repo/flashyid",
      "at": "2026-08-31T11:53:17-04:00",
      "kind": "feature",
      "title": "Merge pull request #15 from FlashyLabs/claude/gord-directory-spec-3jx7zk",
      "by": [
        "person/michael"
      ],
      "asserted": "2026-08-31",
      "assertedBy": "agent/flashyid-ci",
      "visibility": "public",
      "detail": "Ship the CommonJS build that was written a day ago and never published",
      "refs": {
        "commit": "ad00f95568bd49c053053e6ff1be11fdda837afd",
        "pr": "https://github.com/FlashyLabs/flashyid/pull/15"
      },
      "digest": "7b107cbceee8a99bbc462c791db6952cdae0c06342071b6c1af985951a34beb2"
    },
    {
      "id": "ship/flashyid/56f0c979a7a2",
      "repo": "repo/flashyid",
      "at": "2026-08-31T10:55:55+00:00",
      "kind": "infra",
      "title": "shipped/1: refresh the log, and the checkpoint over it",
      "by": [
        "agent/unattributed"
      ],
      "asserted": "2026-08-31",
      "assertedBy": "agent/flashyid-ci",
      "visibility": "public",
      "refs": {
        "commit": "56f0c979a7a2aefd83ee5de8dd27bd5ffe1411a1"
      },
      "digest": "81e24c7b03dadfef0af90910fd2d1e617e61703cda9a3433417825633670adf6"
    },
    {
      "id": "ship/flashyid/a46cf09132ec",
      "repo": "repo/flashyid",
      "at": "2026-08-31T10:28:07-04:00",
      "kind": "feature",
      "title": "Merge pull request #13 from FlashyLabs/claude/gord-directory-spec-3jx7zk",
      "by": [
        "person/michael"
      ],
      "asserted": "2026-08-31",
      "assertedBy": "agent/flashyid-ci",
      "visibility": "public",
      "detail": "Retire the Actions deploy; Terraform owns this service",
      "refs": {
        "commit": "a46cf09132ec015fe213fbcabbb32886693983c3",
        "pr": "https://github.com/FlashyLabs/flashyid/pull/13"
      },
      "digest": "da213bfd2cc6b3775ad3946f4af1e8ea5264dc76e5125495a28973267fa50aa9"
    },
    {
      "id": "ship/flashyid/dfa7211a76da",
      "repo": "repo/flashyid",
      "at": "2026-08-31T10:26:13-04:00",
      "kind": "feature",
      "title": "Merge pull request #12 from FlashyLabs/claude/gord-directory-spec-3jx7zk",
      "by": [
        "person/michael"
      ],
      "asserted": "2026-08-31",
      "assertedBy": "agent/flashyid-ci",
      "visibility": "public",
      "detail": "Pin the mark, and say what flashyid.com is actually serving",
      "refs": {
        "commit": "dfa7211a76da4379fc8b4c35dd62ba3692e58934",
        "pr": "https://github.com/FlashyLabs/flashyid/pull/12"
      },
      "digest": "36c83b264d139d164959909d4ad941329633aac1d36e7632532b73d5fda84ffe"
    },
    {
      "id": "ship/flashyid/3e297f122136",
      "repo": "repo/flashyid",
      "at": "2026-08-31T09:09:10-04:00",
      "kind": "feature",
      "title": "Merge pull request #11 from FlashyLabs/claude/gord-directory-spec-3jx7zk",
      "by": [
        "person/michael"
      ],
      "asserted": "2026-08-31",
      "assertedBy": "agent/flashyid-ci",
      "visibility": "public",
      "detail": "Name the missing repository instead of reporting a denied permission",
      "refs": {
        "commit": "3e297f122136bec431a792e306e7d05a84e2abd5",
        "pr": "https://github.com/FlashyLabs/flashyid/pull/11"
      },
      "digest": "8c3605f8c929f4bfb6d80dbd244b95ba4af6247a744e7e942f943044edbc0452"
    },
    {
      "id": "ship/flashyid/3598a9f1c586",
      "repo": "repo/flashyid",
      "at": "2026-08-31T03:01:50Z",
      "kind": "infra",
      "title": "shipped/1: refresh the log, and the checkpoint over it",
      "by": [
        "agent/unattributed"
      ],
      "asserted": "2026-08-31",
      "assertedBy": "agent/flashyid-ci",
      "visibility": "public",
      "refs": {
        "commit": "3598a9f1c5866e4248bf6e4ef446223edcdbc46d"
      },
      "digest": "5aea4abf84fe3bdb9b89f7aaf318621ae0fa94cae34a8ea319273f1d1b5dd217"
    },
    {
      "id": "ship/flashyid/46e9011577bf",
      "repo": "repo/flashyid",
      "at": "2026-08-31T03:01:38Z",
      "kind": "feature",
      "title": "Merge coordination/join-the-mesh — the D-AH fix, and one property with two accounts of itself",
      "by": [
        "agent/claude"
      ],
      "asserted": "2026-08-31",
      "assertedBy": "agent/flashyid-ci",
      "visibility": "public",
      "detail": "The branch's code half is what main lacks and is the point of merging it: the\nissuer stops publishing a second identity. `manifest.ts` — a rival account of\nwhat this property knows about an entity — is gone, replaced by\n`entitySurfaces.ts`, which is the one the rest of the estate reads.\n\nThe rest of the branch had been overtaken. Main's charter and front door came\nfrom an estate-wide conformance pass and are gated, so they are kept; the\nbranch's older versions are dropped. Two branches had also each written a\n`site/tests/mesh.test.ts` testing different things — one that the mesh files sit\nwhere this app can serve them, one that the charter and the handshake agree — so\nboth are kept, the second under its own name.\n\nThe merge produced the exact defect this property exists to prevent, and it is\nworth stating plainly. The branch shipped a literal `site/public/.well-known/`\ndirectory while main serves those paths by a Next rewrite from `well-known/`. A\nphysical file wins over a rewrite. Merged as-is, flashyid.com would have served\ntwo handshakes for itself: the stale one, advertising six role names, at the\nexact path a counterparty fetches, and the current one, advertising thirteen\ncapability verbs, at the path nobody types. An outside system that fetched the\nwrong account would have acted on it. The dotted directory is deleted and the\ntests now read what is actually served.\n\nTwo of the branch's tests were pinned to a charter that is not in production —\nan `issuance` role main does not have, and a handshake advertising role names\nrather than capability verbs. Rather than delete them, both are rewritten to\nassert the property they were protecting against the charter that exists: that\nno role outside the risk family is ever gated above one inside it, and that\nevery advertised verb is derived from a declared role rather than typed in\nbeside it. Both fail if either drifts.\n\n31 tests at the root and 69 in site/ pass; directory validator clean at 9 nodes\nand 11 edges. Three Mo",
      "refs": {
        "commit": "46e9011577bf508d1377b68ca871358faf97b6fc"
      },
      "digest": "6c22dc7e04abfda8a50910bc9f5aa832b6be071e4cbe07b9938c08d1ba55a4fb"
    },
    {
      "id": "ship/flashyid/ededd2f1a7da",
      "repo": "repo/flashyid",
      "at": "2026-08-31T02:19:42Z",
      "kind": "infra",
      "title": "shipped/1: refresh the log, and the checkpoint over it",
      "by": [
        "agent/unattributed"
      ],
      "asserted": "2026-08-31",
      "assertedBy": "agent/flashyid-ci",
      "visibility": "public",
      "refs": {
        "commit": "ededd2f1a7daa5ce917c30a344a89266480d8304"
      },
      "digest": "1ac9d8a4592c826a3f284ec4f06d034bc04a53fd79c10d145d703b06b3ad8f21"
    },
    {
      "id": "ship/flashyid/ad3e5305bc26",
      "repo": "repo/flashyid",
      "at": "2026-08-31T02:19:30Z",
      "kind": "other",
      "title": "Re-vendor the backlog emitter: it can revise an item now",
      "by": [
        "agent/claude"
      ],
      "asserted": "2026-08-31",
      "assertedBy": "agent/flashyid-ci",
      "visibility": "public",
      "detail": "`file` has taken `--wants` since the beginning and nothing could add them\nafterwards, so every item filed across the estate — all of them filed without\nwants — was permanently invisible to the matcher, which refuses an item that\nnames no `capabilitiesWanted`. A format whose central field is\nwrite-once-at-creation is a format whose central field is empty.\n\n`revise` changes everything about an item except its visibility. Promotion\nstays a separate verb because it is a separate decision: it refuses anything\nbut a `person/` id, and folding it in would give a revision the power to\npublish. Unmentioned fields are left alone — `close` is a revision too, and\nclearing on absence would strip every want in the repository.\n\nCopied byte-identical from flashyos rather than edited here. A stale vendored\nfile does not break; it disagrees, silently, about exactly the field somebody\nhas just added.\n\nKind: chore",
      "refs": {
        "commit": "ad3e5305bc260256103333fffdbaf39c6622442b"
      },
      "digest": "3fa5d96fb7f9e6b5a000b707a4228ac5771b8caeb7eca0556a0816bc26ac2704"
    },
    {
      "id": "ship/flashyid/e79c4ee87b23",
      "repo": "repo/flashyid",
      "at": "2026-08-31T01:45:09Z",
      "kind": "feature",
      "title": "Close the backlog items this repository has since fixed",
      "by": [
        "agent/claude"
      ],
      "asserted": "2026-08-31",
      "assertedBy": "agent/flashyid-ci",
      "visibility": "public",
      "detail": "These were filed from measurement — a signature citing an identity nothing\ndeclared, a repository sealing a record and publishing no directory fragment\n— and the measurement no longer finds them. An open item naming work that is\nfinished is a record that is wrong about the one thing a backlog is for.\n\nSigned by the filing machine rather than by a person, and that asymmetry is\ndeliberate. Promotion publishes an organisation's intention on its behalf and\nneeds a named human; closure records that a measurement changed, makes\nnothing visible to anyone new, and the identity that made the claim is the\nhonest one to withdraw it.\n\nLeft alone, these would have decayed in about ninety days. Ninety days of a\npublished backlog naming finished work is not a reason to wait.\n\nKind: chore",
      "refs": {
        "commit": "e79c4ee87b230e1856afda8837718c0608e6b77f"
      },
      "digest": "4bf8eac50531036cdf00aedc17ae06ba5e3c4db0a3d84860759542a2740a327a"
    },
    {
      "id": "ship/flashyid/9ce26ba3c7e1",
      "repo": "repo/flashyid",
      "at": "2026-08-31T01:01:20Z",
      "kind": "feature",
      "title": "File the gaps this repository can prove about itself",
      "by": [
        "agent/claude"
      ],
      "asserted": "2026-08-31",
      "assertedBy": "agent/flashyid-ci",
      "visibility": "public",
      "detail": "`backlog/1` was published by thirty repositories and empty in twenty-nine —\nfull distribution and nothing to distribute, which is worse than no adoption,\nbecause a format every property emits and none fills teaches every reader that\nthe format is decorative.\n\nThe temptation was to write some intentions. That would be fabrication: an\nagent inventing what an organisation intends is exactly what `promote()`\nexists to prevent, and a backlog of plausible work nobody agreed to is worse\nthan an empty one.\n\nSo these are derived, not invented. Each item is a gap the estate survey\nmeasures directly — a signature citing an identity nothing declares, a\nrepository sealing records and publishing no directory, a default branch that\nis an agent's scratch branch — and each carries the evidence that establishes\nit, because an item that says what to do without saying how anyone knows is an\ninstruction rather than a finding.\n\nFiled private. Reaching public needs a named human to promote it, which is the\nconsent rule rather than an oversight.\n\nKind: feature\n\nCo-Authored-By: Claude Opus 5 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01FDosmV9fXV6oZ9NXe7PZ76",
      "refs": {
        "commit": "9ce26ba3c7e16ba8e535fab8da111d56a368b550"
      },
      "digest": "94a46572961a8b1deb63cdf12fea050c1bf7de6931ab33983cd7e3d3292e88b9"
    },
    {
      "id": "ship/flashyid/14d87f825142",
      "repo": "repo/flashyid",
      "at": "2026-08-31T01:00:34Z",
      "kind": "infra",
      "title": "shipped/1: refresh the log, and the checkpoint over it",
      "by": [
        "agent/unattributed"
      ],
      "asserted": "2026-08-31",
      "assertedBy": "agent/flashyid-ci",
      "visibility": "public",
      "refs": {
        "commit": "14d87f825142a27bfc7d49e33e8765ce8c548580"
      },
      "digest": "34a6a9950eb31859f275fd6e15d72db72fa5aca9356ae30afd0bf2e8d2408cd9"
    },
    {
      "id": "ship/flashyid/27d4096d4b34",
      "repo": "repo/flashyid",
      "at": "2026-08-31T01:00:02Z",
      "kind": "feature",
      "title": "Declare the machine that files this repository's intentions",
      "by": [
        "agent/claude"
      ],
      "asserted": "2026-08-31",
      "assertedBy": "agent/flashyid-ci",
      "visibility": "public",
      "detail": "Two machines write this repository's record and only one was declared.\n`.shiplog/config.json` stamps `agent/<slug>-ci` on every sealed entry;\n`.backlog/config.json` stamps `agent/<slug>-bot` on every filed item. Both\nappear in published fragments. The second appeared in no declaration anywhere\nin the estate.\n\nIt survived the `-ci` rollout because the declaration looked complete:\n`recordEmitter` listed `backlog/1` among the record emitter's formats, so\neverything comparing formats saw it named and stopped, and nothing compared the\nsignature. A declaration naming the right format and the wrong machine is\ncomplete in every respect except the one that matters.\n\nThe record emitter's scope narrows to `shipped/1`, which is what it signs. The\nbacklog emitter is declared beside it with its own `operates` and its own\n`delegatedTo` from the accountable human, bounded to `backlog/1`.\n\nTwo machines is not an artefact of tooling. The tenses are shaped differently\non purpose — an item decays and is never sealed, an entry is sealed and never\ndecays — and different things write them at different times: the seal on a push\nto the default branch, the filing whenever somebody records an intention.\n\nBoth ids are read from the config that stamps them, never composed.\n\nKind: chore\n\nCo-Authored-By: Claude Opus 5 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01BEaXzktRU5ZPe3R2NY7CKD",
      "refs": {
        "commit": "27d4096d4b34f64ce92506dc267df863aaf94df8"
      },
      "digest": "46dda237527c1da094fe09d73ed45fab136c906cd64870d8e0108c256f9e2f0f"
    },
    {
      "id": "ship/flashyid/cd795a3261bf",
      "repo": "repo/flashyid",
      "at": "2026-08-31T00:50:59Z",
      "kind": "feature",
      "title": "Declare the machine surfaces this property serves",
      "by": [
        "agent/claude"
      ],
      "asserted": "2026-08-31",
      "assertedBy": "agent/flashyid-ci",
      "visibility": "public",
      "detail": "Every property in the estate serves the same handful of documents — a\nhandshake, a charter, backlog/1, shipped/1, checkpoint/1 — and said nothing\nabout them in its own record. That silence is most of why the estate measured\nas thirty graphs rather than one: a fragment describing only its own\norganisation has no reason to name anything another repository defines, so\nnothing crossed a boundary except one person's name on a commit.\n\nServing a format is a fact about this repository; the format belongs to\nflashyos. `cites` is the edge for referencing something somebody else\nauthored, so each of these is a real join rather than a manufactured one.\n\nDetected from disk, never listed. A hand-kept list keeps claiming a surface\nthe day somebody deletes the file, and a declared surface that cannot be\nfetched is worse than an undeclared one — a promise in the record with\nnothing behind it.\n\n`directory.externals.json` is emitted beside the fragment and names what this\nrepository borrows: the standards flashyos authors, and the person\ngord-holdings is the authority for. `check-directory.mjs` reads it instead of\ntaking `--external` flags, so the list cannot drift from the emitter.\n\nThe vendored checker was also one revision behind the canonical copy in\nflashyos and would have rejected an `engaged` edge. Re-vendored.\n\nKind: feature\n\nCo-Authored-By: Claude Opus 5 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01FDosmV9fXV6oZ9NXe7PZ76",
      "refs": {
        "commit": "cd795a3261bf98515e5a528bfe80f8012cc8d872"
      },
      "digest": "bfcdbedc1b4009351cc25fe7910fb707bb0af511e43a32ef302b279340081830"
    },
    {
      "id": "ship/flashyid/e02d038da563",
      "repo": "repo/flashyid",
      "at": "2026-08-31T00:43:37Z",
      "kind": "infra",
      "title": "shipped/1: refresh the log, and the checkpoint over it",
      "by": [
        "agent/unattributed"
      ],
      "asserted": "2026-08-31",
      "assertedBy": "agent/flashyid-ci",
      "visibility": "public",
      "refs": {
        "commit": "e02d038da563e948c04c8050f49257ddedcdef7b"
      },
      "digest": "0f0e76499166fb99af80c2e77a515a22b3eb68e1fca98864282f05720e908011"
    },
    {
      "id": "ship/flashyid/dfbaa1386d93",
      "repo": "repo/flashyid",
      "at": "2026-08-31T00:42:58Z",
      "kind": "feature",
      "title": "Check the estate's emitter ids against the subject format, here",
      "by": [
        "agent/claude"
      ],
      "asserted": "2026-08-31",
      "assertedBy": "agent/flashyid-ci",
      "visibility": "public",
      "detail": "flashyos now declares, for every repository that seals a record, which human\nits record emitter acts for. The layer above that is this package's: which\nFlashy ID subject the machine authenticates as.\n\nThe check lives here rather than there because this package owns the format,\nand because flashyos cannot import it — @flashyid/sdk publishes to a restricted\nregistry, and making that suite need registry auth to run would trade a real\ncheck for a flaky one. It reads sibling checkouts and reports what it could not\nread rather than counting it: a gate that passes when it can see nothing is\nworse than no gate, because it is trusted.\n\nTen emitters on disk, seven of which map cleanly. Three do not, and the reason\nis worth recording rather than fixing:\n\n  ClaimYour.Gold  agent/claimyour.gold-ci   for org/claimyour-gold\n  gda-group       agent/gda-group-ci        for org/gda-capital\n  gold-holdings   agent/gold-holdings-ci    for org/gord-holdings\n\nEach is named after its repository rather than its organisation — in the last\ncase after a repository whose name is itself a typo of the domain, kept because\nrenaming it breaks a Vercel binding. `fromDirectoryId` refuses all three rather\nthan composing a subject anyway, which is the whole point of it taking the org\nslug instead of splitting on the last hyphen: a subject built from a mismatched\npair authenticates while naming an organisation that never declared the\nmachine, and that is worse than having no subject at all.\n\nThey are not renamed. The stamped id is on every sealed entry already and\nchanging it orphans every signature — the estate learned that when a derived id\nwas wrong in two repositories out of ten and every structural check passed for\nboth.\n\nKind: feature\n\nCo-Authored-By: Claude Opus 5 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01BEaXzktRU5ZPe3R2NY7CKD",
      "refs": {
        "commit": "dfbaa1386d936afffb4ad535b475f307e4cadb02"
      },
      "digest": "dc06f38156df3daa14190aaf8e1a980050a80d3332318119b9afc15152459d7f"
    },
    {
      "id": "ship/flashyid/72bf2591f827",
      "repo": "repo/flashyid",
      "at": "2026-08-31T00:31:49Z",
      "kind": "feature",
      "title": "Declare what a machine is called when Flashy ID authenticates it",
      "by": [
        "agent/claude"
      ],
      "asserted": "2026-08-31",
      "assertedBy": "agent/flashyid-ci",
      "visibility": "public",
      "detail": "`GrantLink.sub` has been documented as \"a human email, an org id, or an agent\nsurrogate\" since the delegation profile was written. The agent surrogate\nexisted only in this suite's fixtures — eighteen occurrences of\n`agent:flashyos/settlement`, every one of them a test. Nothing constructed one,\nnothing validated one, and nothing could tell you whether a given string was\none.\n\nThat is the same defect the estate's directory had a week ago, one layer up. Its\nversion was 2,478 edges — 91% of every relationship the estate publishes —\nsigned by `agent/<slug>-ci` ids no fragment declared: an identifier that reads\nas an identity and resolves to nothing. The directory has now declared its\nemitters, and the obvious next step is to say which Flashy ID subject each one\nauthenticates as. Without a format here, that step means inventing one at the\ncall site, in thirty repositories, each free to get it subtly wrong.\n\nSo it is declared once: `agent:<org>/<name>`, with a constructor that throws on\na malformed half rather than returning something plausible, a parser that never\nthrows, and a bridge to and from the directory's `agent/<org>-<name>` ids.\n\nThe two identifiers stay separate on purpose. A directory id is a *record* — a\nrow saying this machine exists and the org operates it. A subject is a\n*principal* — what an assertion is minted for and a chain is held by. One is a\nclaim about the world; the other is something you can authenticate as.\n`fromDirectoryId` is a function rather than a convention so the mapping is\ncheckable in both directions.\n\nIt takes the org slug rather than splitting on the last hyphen, and refuses a\nmismatched pair. `agent/gda-group-ci` reads as either org `gda` machine\n`group-ci` or org `gda-group` machine `ci`, and only the caller knows which. A\nsubject derived from the wrong reading is worse than no subject: it is a\nworking credential naming an organisation that never declared the machine.\n\nLint also goes from 39 errors to 0. Every one was `no-console` in",
      "refs": {
        "commit": "72bf2591f827c27124cd724e4472f867e2ba2c57"
      },
      "digest": "5fdebce64b1b42d91090b50253572d2ad25871f354361023398c1a5a864030dd"
    },
    {
      "id": "ship/flashyid/e53cf38d9339",
      "repo": "repo/flashyid",
      "at": "2026-08-30T22:06:06Z",
      "kind": "other",
      "title": "Re-vendor the checkpoint and frontdoor emitters",
      "by": [
        "agent/claude"
      ],
      "asserted": "2026-08-31",
      "assertedBy": "agent/flashyid-ci",
      "visibility": "public",
      "detail": "Two dead imports were found by running a linter over a repository that vendors\nthese files: a `join` from `node:path` in `vendor-checkpoint.mjs` and another\nin `vendor-emit-frontdoor.mjs`. Both are fixed at their source in flashyos and\ncopied here byte-identical.\n\nNeither changes behaviour. The reason to carry the copy anyway is the estate\nrule that produced the fix: a vendored file that disagrees with its source does\nnot fail, it disagrees — silently, about whichever field somebody has just\nchanged — and `estate-hygiene` compares these byte-for-byte precisely so a copy\ncannot quietly fall behind.\n\nKind: chore\n\nCo-Authored-By: Claude Opus 5 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01BEaXzktRU5ZPe3R2NY7CKD",
      "refs": {
        "commit": "e53cf38d9339e2882c352b3ac2a08a55c723ad7e"
      },
      "digest": "c11e7a1551357d0e677c0eef8f4affa0d589e282869366f33cb9177204e4ec19"
    },
    {
      "id": "ship/flashyid/71e551c7c295",
      "repo": "repo/flashyid",
      "at": "2026-08-30T21:57:45Z",
      "kind": "infra",
      "title": "shipped/1: refresh the log, and the checkpoint over it",
      "by": [
        "agent/unattributed"
      ],
      "asserted": "2026-08-31",
      "assertedBy": "agent/flashyid-ci",
      "visibility": "public",
      "refs": {
        "commit": "71e551c7c295931c1db8e6ea257b3f3953fa5b0a"
      },
      "digest": "418f1e42e58f69677c3887b8f2dd78cfdc52de7c9cd966417e5bda81b21a70de"
    },
    {
      "id": "ship/flashyid/e6d3145202dc",
      "repo": "repo/flashyid",
      "at": "2026-08-30T21:55:53Z",
      "kind": "fix",
      "title": "Make the SDK importable both ways, before anyone installs it",
      "by": [
        "agent/claude"
      ],
      "asserted": "2026-08-30",
      "assertedBy": "agent/flashyid-ci",
      "visibility": "public",
      "detail": "@flashyid/sdk is finished — 87 tests, 17 exports, a licence, a README and a\npublish workflow that already passes --provenance — and has never been\npublished. It also carried the defect that would have met its first adopter:\nan exports map naming \"types\" and \"import\" and nothing else, so\nrequire('@flashyid/sdk') fails with ERR_PACKAGE_PATH_NOT_EXPORTED. A CommonJS\nresolver matches no condition and, an exports map once present being the whole\nanswer, never falls back to main.\n\nFour packages in the sibling monorepo had the identical defect; one meant the\nlargest product in the estate could not import its own conformance checker,\nand the error named the caller's file rather than the package. This is the\ngrant kernel, so the person hitting it would be wiring authority into a\nCommonJS service and would conclude the package was broken.\n\nDual build with no new dependency: a second tsc pass to dist/cjs, plus the\ntype marker Node needs to read those files as CommonJS under a type:module\npackage. src/init/cli.ts is excluded because it reads import.meta.url, which\nis illegal in CJS output — it is the bin, reached through bin rather than the\nbarrel, and stays ESM. Declarations are emitted once and both conditions point\nat them, because two copies are two things to drift.\n\npackaging.test.ts loads both built artefacts rather than reading the manifest,\nand asserts the two surfaces are identical — a dual build that drifts is worse\nthan an ESM-only one, since two consumers reading the same docs would get\ndifferent answers about what exists.\n\ndocs/publishing-flashyid-sdk.md is written. The workflow has referenced it\nsince it was created and it did not exist, which left the one question a\nrelease actually needs answered — where the token goes — written down nowhere.\n\nKind: fix",
      "refs": {
        "commit": "e6d3145202dcad300aadb3eb84512f7dceaa1cb8"
      },
      "digest": "cf4031d31e6eb763885673d1cfb35483135aefe3a05ac3eb50318866174d9d2b"
    },
    {
      "id": "ship/flashyid/5021b43ba2e4",
      "repo": "repo/flashyid",
      "at": "2026-08-30T21:44:31Z",
      "kind": "infra",
      "title": "shipped/1: refresh the log, and the checkpoint over it",
      "by": [
        "agent/unattributed"
      ],
      "asserted": "2026-08-30",
      "assertedBy": "agent/flashyid-ci",
      "visibility": "public",
      "refs": {
        "commit": "5021b43ba2e482bb48e1f2501f81ddda2db3c7cc"
      },
      "digest": "0dbee2d5c5121b4d4078bf3e9df01d6b47475ee1e01177ab674b4b525ab040e0"
    },
    {
      "id": "ship/flashyid/b780e2f9e18f",
      "repo": "repo/flashyid",
      "at": "2026-08-30T21:44:19Z",
      "kind": "fix",
      "title": "Read the emitter id, do not derive it",
      "by": [
        "agent/claude"
      ],
      "asserted": "2026-08-30",
      "assertedBy": "agent/flashyid-ci",
      "visibility": "public",
      "detail": "The declaration added moments ago used `${charter.slug}-ci` and was wrong here:\nthis repository signs its record with an id the charter slug does not produce,\nso it declared an agent that matched no signature anywhere. A declaration that\nmatches nothing is indistinguishable from one that works — every check that\nlooks at shape passes, and the provenance number does not move.\n\nThe id now comes from `.shiplog/config.json`, which is the file that actually\nstamps it. Two of ten repositories were affected: ClaimYour.Gold signs\n`agent/claimyour.gold-ci` against a charter slug of `claimyour-gold`, and\ndais-global signs `agent/dais-global-ci` against a slug of `dais`.\n\n`tools/emitter-declaration.test.mjs` in flashyos now compares the declared id\nagainst the stamped one, which is the check that was missing.\n\nKind: fix\n\nCo-Authored-By: Claude Opus 5 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01FDosmV9fXV6oZ9NXe7PZ76",
      "refs": {
        "commit": "b780e2f9e18facdad8ea5e43788c8dada80715a9"
      },
      "digest": "c0fbd1984ccdfc89c5c05ec3969e2c3d5c6d75066f078da20dcc60ddfe8da32c"
    },
    {
      "id": "ship/flashyid/420302ed7d13",
      "repo": "repo/flashyid",
      "at": "2026-08-30T21:40:07Z",
      "kind": "infra",
      "title": "shipped/1: refresh the log, and the checkpoint over it",
      "by": [
        "agent/unattributed"
      ],
      "asserted": "2026-08-30",
      "assertedBy": "agent/flashyid-ci",
      "visibility": "public",
      "refs": {
        "commit": "420302ed7d13685a45639208b731a89aa9c225cd"
      },
      "digest": "5189d9011a2f53d9e1d2565c99a3f495d477011de30ba512bca5629edccf1ff5"
    },
    {
      "id": "ship/flashyid/a985949045e7",
      "repo": "repo/flashyid",
      "at": "2026-08-30T21:38:21Z",
      "kind": "feature",
      "title": "Declare the machine that signs this repository's record",
      "by": [
        "agent/claude"
      ],
      "asserted": "2026-08-30",
      "assertedBy": "agent/flashyid-ci",
      "visibility": "public",
      "detail": "Every sealed entry and every fragment here carries\n`assertedBy: agent/<slug>-ci`, and until now that was an id nothing in the\nestate declared. Across thirty properties it was 2,478 edges citing an agent\nthat formally did not exist — provenance that reads as provenance and carries\nnone, which is worse than an empty field, because the empty field is honest\nabout not knowing who made the claim.\n\nDeclared as an Agent the organisation `operates`, not as a charter role. A\nrole is a governance label the org answers for and it is rendered into the\nhandshake's advertised capabilities, so a \"ci\" role would tell the network\nthis organisation does continuous integration for other people.\n\nThe canonical form is `declareEmitters` in `@flashyos/directory`. It is\ninlined here because `scripts/directory.mjs` is dependency-free by design, and\n`tools/emitter-declaration.test.mjs` in flashyos is the drift test that keeps\nthe two in step.\n\nKind: feature\n\nCo-Authored-By: Claude Opus 5 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01FDosmV9fXV6oZ9NXe7PZ76",
      "refs": {
        "commit": "a985949045e714423d5bb04c88569cb85851e173"
      },
      "digest": "a5ea3c0e50957611ce43a90d7e634bc387d2f40c081b9d6021b00462a36042d9"
    },
    {
      "id": "ship/flashyid/58ffb8d6323c",
      "repo": "repo/flashyid",
      "at": "2026-08-30T19:45:12Z",
      "kind": "fix",
      "title": "Re-vendor the charter checker: it had drifted from the spec",
      "by": [
        "agent/claude"
      ],
      "asserted": "2026-08-30",
      "assertedBy": "agent/flashyid-ci",
      "visibility": "public",
      "detail": "The vendored checker rejected renamedFrom, which the charter defines and the\nrole-rename sync reads; rejected a digit in a role name, which the spec's own\nregex allows; and enforced no length bound at all, so the 24-character role\nname cap was the one rule this pre-install check could not see.\n\nEleven byte-identical copies across the estate agreed with each other\nperfectly and disagreed with @flashyos/aao in all four places. The monorepo\nnow runs both checkers over the same documents and fails on any disagreement\nabout the verdict.\n\nThis charter still passes.\n\nKind: fix",
      "refs": {
        "commit": "58ffb8d6323c61f470f897cf615cde3fdde67111"
      },
      "digest": "0597db0adbda9615b4278914250d1f742470639468661dc72af53166ed16c0fb"
    },
    {
      "id": "ship/flashyid/ba1973808eae",
      "repo": "repo/flashyid",
      "at": "2026-08-30T19:25:07Z",
      "kind": "feature",
      "title": "Roadmap #2: pin the roots a relying party trusts — the mesh sign-in binding",
      "by": [
        "agent/claude"
      ],
      "asserted": "2026-08-31",
      "assertedBy": "agent/flashyid-ci",
      "visibility": "public",
      "detail": "The grant kernel was complete for one org: it verifies a chain only ever\nnarrows, is held by its subject, and permits a demand. What it did not do\nis the binding the mesh needs. On the network an agent from org A signs in\nat org B; org B verifies the assertion is genuinely from Flashy ID, but a\ngenuine assertion can carry a chain rooted at any accountable human\nanywhere — so \"verified\" quietly meant \"belongs to someone\", not \"belongs\nto someone we trust\". verifyChain already computes the root; nothing\nchecked it.\n\nThis closes that. `rootsWithin(effective, roots)` refuses a sound chain\nthat roots at a principal the party has not agreed to accept, with its own\ncode `untrusted_root` — kept separate from permits so it cannot be masked\nas a missing scope. `authorize` takes an optional `trustedRoots`, checked\nbefore the mandate; omit it and single-issuer behaviour is unchanged, so\nnothing existing breaks. And `trustedRootsFromCharters` derives the set the\nconcrete way an AAO would: every charter names the one human its chains\nroot at (`accountableTo`), so a relying party's trusted roots are the\naccountable humans of the orgs it federates with.\n\nAn empty trusted set trusts nobody and refuses every chain — the safe\ndirection, so a party that forgot to configure its roots rejects rather\nthan admits. A charter with no accountable human contributes no root\nrather than a blank one that would trust every chain that omitted its own.\n\nHolds the estate rules: delegation is still attenuation (this only ever\nnarrows what a verified chain grants); enforcement still precedes minting\n(this is a check, not a mint); and the assertion binds subject to holder\nnow also to a root the party pins. Public-API surface test updated for the\ntwo new exports; README documents the mesh sign-in.\n\nVerified: 90 SDK tests green (10 new), typecheck clean, lint clean, on the\ncurrent origin/main base.\n\nKind: feature\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/co",
      "refs": {
        "commit": "ba1973808eaefe137bb1466dce5de07a584a1588",
        "pr": "https://github.com/FlashyLabs/flashyid/pull/2"
      },
      "digest": "6d35b7ab2f37f994a9dfe794498aae2129cd047f6cd4e3bbbaf4b80a715a2584"
    },
    {
      "id": "ship/flashyid/00c1b6854ae8",
      "repo": "repo/flashyid",
      "at": "2026-08-30T18:37:27Z",
      "kind": "feature",
      "title": "Merge: their charter and their serving design; add the one path L2 needs",
      "by": [
        "agent/claude"
      ],
      "asserted": "2026-08-30",
      "assertedBy": "agent/flashyid-ci",
      "visibility": "public",
      "detail": "Another session did this property's mesh work on main and did it better than\nmy branch in two ways worth naming.\n\nTheir charter's roles are attenuation, enforcement and assertion — the three\nrules this repository's CLAUDE.md actually states, rather than my generic\nidentity/delegation. And their slug is `flashyid`, matching the repo and the\ndomain; I had written `flashy-id`.\n\nTheir serving design is right and mine would have fought it. This app serves\nits mesh files from `site/public/well-known/` with `next.config` rewriting the\ndotted paths onto them, because the app router does not take a dot-prefixed\nroute folder. My branch added `src/app/.well-known/` handlers, which is a\nsecond mechanism for the same URLs. Removed.\n\nWhat was actually missing, and is the whole of L2: their rewrite list covered\nthe handshake and the front door but not the charter. `@flashyos/conformance`\nreads /.well-known/flashyos-charter.json and nowhere else, so all three of\ntheir files could be perfect and this property would still report L1. Charter\nnow served at that path, with the reason written at the rewrite.\n\nTheir handshake convention differs from the one I rolled out elsewhere, and\ntheirs is enforced by a test here: `capabilities` is the union of the roles'\nown capability verbs — issue, attenuate, gate, verify — rather than the role\nnames. For a stranger searching the network that is the better list, because\nthey are looking for an action. The handshake now follows it, and the two\nexisting parity tests pass in both directions.\n\nThat difference is a real incompatibility with the shared audit I published in\n@flashyos/conformance 0.2.0, which only recognises role names and x-capability.\nFixing that there next; it would wrongly fail this property today.\n\nBoth suites green: 56 in site, 13 at the root, plus the site build.\n\nCo-Authored-By: Claude Opus 5 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01VgrPGGUFKMq9zXBHnfcTgs",
      "refs": {
        "commit": "00c1b6854ae80bfd5fcbe41f8fe5a60923b603af"
      },
      "digest": "fbd81982ee67030a94904b8b5f3e52570bce495ee03049316f35546ac2b41df1"
    },
    {
      "id": "ship/flashyid/0a5721db680e",
      "repo": "repo/flashyid",
      "at": "2026-08-30T18:01:32Z",
      "kind": "other",
      "title": "Re-emit against the rebased tree",
      "by": [
        "agent/claude"
      ],
      "asserted": "2026-08-30",
      "assertedBy": "agent/flashyid-ci",
      "visibility": "public",
      "detail": "Kind: chore",
      "refs": {
        "commit": "0a5721db680e5bab0ad88c59f92381653d4ec289"
      },
      "digest": "cbdad8b46f5baf2d02683a5319607154d2a6070dc9516c81a25ecaa1c86b9f22"
    },
    {
      "id": "ship/flashyid/bac24513b16b",
      "repo": "repo/flashyid",
      "at": "2026-08-30T17:59:06+00:00",
      "kind": "fix",
      "title": "Carry the current vendored emitters",
      "by": [
        "agent/claude"
      ],
      "asserted": "2026-08-30",
      "assertedBy": "agent/flashyid-ci",
      "visibility": "public",
      "detail": "A stale copy fails silently and in the dangerous direction: it does not know\nabout rules added since it was vendored, so it ignores them rather than\nerroring. Re-emitted and re-verified against the refreshed copies.\n\nKind: fix",
      "refs": {
        "commit": "bac24513b16b2ec0646c9f11a9f67ff8726623af"
      },
      "digest": "82d04c7f4f2142fadf30c6ecc616a059f0b2082b2a09330efc0e0d5e268471e2"
    },
    {
      "id": "ship/flashyid/5218ec7de7f1",
      "repo": "repo/flashyid",
      "at": "2026-08-30T17:57:26-04:00",
      "kind": "feature",
      "title": "Merge pull request #10 from FlashyLabs/claude/gord-directory-spec-3jx7zk",
      "by": [
        "person/michael"
      ],
      "asserted": "2026-08-30",
      "assertedBy": "agent/flashyid-ci",
      "visibility": "public",
      "detail": "Build the SDK before testing it, not after",
      "refs": {
        "commit": "5218ec7de7f1343dea8c3ff2a6f6db8a01ae5173",
        "pr": "https://github.com/FlashyLabs/flashyid/pull/10"
      },
      "digest": "47e63d2d119dd6e5ec00119e6337b45533dc376ecab836bec758c9951e21168b"
    },
    {
      "id": "ship/flashyid/9878db1df5a6",
      "repo": "repo/flashyid",
      "at": "2026-08-30T17:48:50-04:00",
      "kind": "feature",
      "title": "Publish the SDK where the estate can actually install it (#8)",
      "by": [
        "person/michael"
      ],
      "asserted": "2026-08-30",
      "assertedBy": "agent/flashyid-ci",
      "visibility": "public",
      "detail": "Publish the SDK where the estate can actually install it",
      "refs": {
        "commit": "9878db1df5a68b44f3d80558b4e9e9834873ebb5",
        "pr": "https://github.com/FlashyLabs/flashyid/pull/8"
      },
      "digest": "92932809528a902510b9f066a5d1ee81288ba7c61594ca115ec44eac726a5386"
    },
    {
      "id": "ship/flashyid/26362253d17b",
      "repo": "repo/flashyid",
      "at": "2026-08-30T17:38:44+00:00",
      "kind": "fix",
      "title": "Fail loudly on a fragment that exists and cannot be parsed",
      "by": [
        "agent/claude"
      ],
      "asserted": "2026-08-30",
      "assertedBy": "agent/flashyid-ci",
      "visibility": "public",
      "detail": "The emitter treated an unparseable fragment as an absent one and built a head\nover whatever else it could read. A conflicted fragment produced a\nvalid-looking head over nothing.\n\nKind: fix",
      "refs": {
        "commit": "26362253d17b5a74f704b2ba4c8b6c67bc2450d0"
      },
      "digest": "07a8633abba8f0b8fd1528cc386dbe083d4a8e3f7fffa270d56f80d4478dac21"
    },
    {
      "id": "ship/flashyid/e9de27f952d9",
      "repo": "repo/flashyid",
      "at": "2026-08-30T17:23:14+00:00",
      "kind": "infra",
      "title": "shipped/1: refresh the log, and the checkpoint over it",
      "by": [
        "agent/unattributed"
      ],
      "asserted": "2026-08-30",
      "assertedBy": "agent/flashyid-ci",
      "visibility": "public",
      "refs": {
        "commit": "e9de27f952d9c820a7716dc426700a6715feb5a1"
      },
      "digest": "338d3b1689b367ae4e5cb002e234a1de5b66f74e50f699da48ed5c4df6081084"
    },
    {
      "id": "ship/flashyid/b0f03a270ba2",
      "repo": "repo/flashyid",
      "at": "2026-08-30T17:23:02Z",
      "kind": "other",
      "title": "Re-emit the log and its checkpoint after rebase",
      "by": [
        "agent/claude"
      ],
      "asserted": "2026-08-30",
      "assertedBy": "agent/flashyid-ci",
      "visibility": "public",
      "detail": "Kind: chore",
      "refs": {
        "commit": "b0f03a270ba22106714b3bfe77ca10de2fa1309a"
      },
      "digest": "680e4cc79a575193ea7ad4900855e5f368cf3fe28bfc9dc34b5a1038c913296b"
    },
    {
      "id": "ship/flashyid/06b4f7412515",
      "repo": "repo/flashyid",
      "at": "2026-08-30T17:18:12+00:00",
      "kind": "feature",
      "title": "Adopt checkpoint/1 — a tree head over what this repository seals",
      "by": [
        "agent/claude"
      ],
      "asserted": "2026-08-30",
      "assertedBy": "agent/flashyid-ci",
      "visibility": "public",
      "detail": "An RFC 6962 Merkle root over the sealed claims already published here, served\nbeside them. Anyone holding the fragments can recompute it and see whether the\nrecord still describes what it said it did.\n\nThe head is deliberately unsigned. A signature over a root computed and checked\nby the same party is ceremony without a property — what makes history provably\nappend-only is a witness who is not us, and that is not built. The root catches\ndrift and after-the-fact edits, and nothing here claims more.\n\nIt is refreshed by the shiplog workflow rather than its own, so the head and\nthe log it commits to always move in one commit. A separate workflow would\nleave a window in which the published root and the published record disagree,\nand a reader hitting that window sees a forged-looking estate.\n\nKind: feature",
      "refs": {
        "commit": "06b4f74125152a9080d7f047f19374319e4abb23"
      },
      "digest": "f5de84954f38fb83056b03adaef0d383e135f0c9b637cff10dec438a7a752edb"
    },
    {
      "id": "ship/flashyid/6c9d2df305be",
      "repo": "repo/flashyid",
      "at": "2026-08-30T16:18:23+00:00",
      "kind": "fix",
      "title": "Map the estate's commit addresses to who they belong to",
      "by": [
        "agent/claude"
      ],
      "asserted": "2026-08-30",
      "assertedBy": "agent/flashyid-ci",
      "visibility": "public",
      "detail": "`authors` was empty and `defaultAuthor` filed every entry under one identity,\nso this log looked fully attributed while agent-authored commits were recorded\nas the person named as the default.\n\nThe map is declared once in flashyos `tools/estate-authors.mjs` and synced\nhere. Five addresses are left unmapped on purpose, each with a stated reason.\n\nKind: fix",
      "refs": {
        "commit": "6c9d2df305be0c4e4c02d7d8052bb08d77e9fe31"
      },
      "digest": "f3b8a5c7da1504a7829c2b1d1795f47d736c56cbb1a0bb9b64c2fc951f1ed348"
    },
    {
      "id": "ship/flashyid/466299ed5d64",
      "repo": "repo/flashyid",
      "at": "2026-08-30T15:46:15+00:00",
      "kind": "fix",
      "title": "Stop pinning the shiplog and backlog workflows to a branch name",
      "by": [
        "agent/claude"
      ],
      "asserted": "2026-08-30",
      "assertedBy": "agent/flashyid-ci",
      "visibility": "public",
      "detail": "Each workflow triggered on `branches: ['<the default branch at adoption>']`.\nEleven repositories in this estate have a `claude/*` branch as their GitHub\ndefault; renaming one to `main` is the right thing to do and would have stopped\nits workflow firing. Nothing would have failed — the fragment would simply have\nstopped advancing, and a stale changelog reads exactly like a current one.\n\nThe trigger now matches any push and the job is gated on\n`github.ref_name == github.event.repository.default_branch`, resolved per run,\nso a rename is survived rather than discovered. `branch` is dropped from the\nconfig: nothing read it, and a stored branch name is a snapshot of something\nthat changes.\n\nKind: fix",
      "refs": {
        "commit": "466299ed5d648062f97f0bcf9d8151aadfe06bee"
      },
      "digest": "8cd423ab1f94d43305b69f4f0e0063391385e6d7537cc97cf1a77ce1d344dbc0"
    },
    {
      "id": "ship/flashyid/22eeb79e0fd1",
      "repo": "repo/flashyid",
      "at": "2026-08-30T13:21:27+00:00",
      "kind": "infra",
      "title": "Reclassify the log against the convention this estate writes in",
      "by": [
        "agent/claude"
      ],
      "asserted": "2026-08-30",
      "assertedBy": "agent/flashyid-ci",
      "visibility": "public",
      "detail": "The derived log was classified only by conventional-commit prefixes, and\nthis repository writes declarative English. Unclassified went from 68%\nto 25% by reading the estate's declared imperative lexicon, looking\npast a project prefix to the verb behind it, and dropping merges of\nanother branch into this line — which are not things that shipped.\n\nNothing is published: entries remain private and the served copy is the\npublic projection.\n\nKind: infra\n\nCo-Authored-By: Claude Opus 5 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01FDosmV9fXV6oZ9NXe7PZ76",
      "refs": {
        "commit": "22eeb79e0fd1e395eb0923977a583334dda9f6b2"
      },
      "digest": "43f28d6822d12a3c8d64d70d9b056d6d4449918d1ef8accfb13a331e546796d4"
    },
    {
      "id": "ship/flashyid/50c7e08261b7",
      "repo": "repo/flashyid",
      "at": "2026-08-30T05:48:08+00:00",
      "kind": "feature",
      "title": "Adopt backlog/1 and shipped/1",
      "by": [
        "agent/claude"
      ],
      "asserted": "2026-08-30",
      "assertedBy": "agent/flashyid-ci",
      "visibility": "public",
      "detail": "This repository now publishes the two tenses the estate records: what it\nintends, and what it shipped. Both are emitted by a dependency-free\nvendored script, so nothing here gains a toolchain it did not have.\n\nNothing is published by this commit. Backlog items are filed private and\nreach the served fragment only when a named human promotes one; shipped\nentries land private until someone changes one field in\n.shiplog/config.json. The served copy is the public projection and the\nemitter writes it, so a private record cannot reach a URL through a\nforgotten copy step.\n\nDerived 44 entries from this repository's own history, every seal\nrecomputed. Org org/flashyid, served at site/public/.well-known/shiplog.json.\n\nCo-Authored-By: Claude Opus 5 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01FDosmV9fXV6oZ9NXe7PZ76",
      "refs": {
        "commit": "50c7e08261b7b180fcda570e223d92376c74dcac"
      },
      "digest": "8a8451bb5b2faa345db171e3a86a28d76518516901183090107cdddd28b8fb62"
    },
    {
      "id": "ship/flashyid/2f0242bfea02",
      "repo": "repo/flashyid",
      "at": "2026-08-30T05:46:58+00:00",
      "kind": "feature",
      "title": "Adopt backlog/1 and shipped/1",
      "by": [
        "agent/claude"
      ],
      "asserted": "2026-08-30",
      "assertedBy": "agent/flashyid-ci",
      "visibility": "public",
      "detail": "This repository now publishes the two tenses the estate records: what it\nintends, and what it shipped. Both are emitted by a dependency-free\nvendored script, so nothing here gains a toolchain it did not have.\n\nNothing is published by this commit. Backlog items are filed private and\nreach the served fragment only when a named human promotes one; shipped\nentries land private until someone changes one field in\n.shiplog/config.json. The served copy is the public projection and the\nemitter writes it, so a private record cannot reach a URL through a\nforgotten copy step.\n\nDerived 43 entries from this repository's own history, every seal\nrecomputed. Org org/flashyid, served at none.\n\nCo-Authored-By: Claude Opus 5 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01FDosmV9fXV6oZ9NXe7PZ76",
      "refs": {
        "commit": "2f0242bfea024fdb6b50d75e17a73a98a6981f7f"
      },
      "digest": "021575db9ad86ce017036d946912393a9f01ce024faf217a0399acfb40846822"
    },
    {
      "id": "ship/flashyid/358ca9d62776",
      "repo": "repo/flashyid",
      "at": "2026-08-30T03:51:58+00:00",
      "kind": "infra",
      "title": "Drop the SDK lockfile I added by accident",
      "by": [
        "agent/claude"
      ],
      "asserted": "2026-08-30",
      "assertedBy": "agent/flashyid-ci",
      "visibility": "public",
      "detail": "packages/sdk deliberately has no lockfile — ci.yml says so where it runs\n`npm install` rather than `npm ci`: the package is what `npm publish` resolves\nfrom scratch, so installing without a lockfile is parity with what a consumer\nactually gets, not a shortcut. Adding one would have quietly made this job\ntest a resolution no consumer will ever see.\n\nIt came in as a side effect of installing @types/node.\n\nCo-Authored-By: Claude Opus 5 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01BEaXzktRU5ZPe3R2NY7CKD",
      "refs": {
        "commit": "358ca9d62776fe4dab2add2cb76c778078433dbc"
      },
      "digest": "03a3315f38369489b3d8e2ce86fb2d0c2b484fd8b59b1c8fff0f19b1b09e271b"
    },
    {
      "id": "ship/flashyid/f9582d477355",
      "repo": "repo/flashyid",
      "at": "2026-08-30T03:51:46+00:00",
      "kind": "infra",
      "title": "Make CI pass again, so this property can deploy",
      "by": [
        "agent/claude"
      ],
      "asserted": "2026-08-30",
      "assertedBy": "agent/flashyid-ci",
      "visibility": "public",
      "detail": "flashyid.com has not deployed since 26 August. CI last passed at 19:29 that\nevening and has failed on every commit since — thirteen runs, four days, and\nthree separate causes that had nothing to do with each other. Nothing said so\nout loud, which is why the mesh files I added earlier tonight were never going\nto appear no matter how correct they were.\n\nThe site job. tests/institutional.test.ts asserts that the SDK methods this\nsite documents are the ones @flashyid/sdk actually exports. That is a real\ndrift test and it should stay — but it means the site's typecheck reaches into\n../packages/sdk, whose dependencies live in the root package.json, while the\njob installed only site/. `tsc` could not resolve jose, and had not been able\nto since the commit that added the test. The job now installs both.\n\nThe SDK job. packages/sdk sets lib ES2022 and no types, so setTimeout, URL,\nconsole, process and node:fs were all undeclared — eleven errors. This job was\nadded on 28 August and has never once passed. @types/node, as a devDependency,\nso nothing changes in what gets published.\n\nThe issuer job. Forty lint errors, every one of them no-undef reporting\nconsole and process as undefined: the config declared no globals, so the\nlinter did not know what runtime it was reading. Node globals declared, and\nscripts/ exempted from no-console alongside src/scripts/ — those files are\nvendored byte-identical across the estate with a drift test asserting no\nrepository has edited its copy, their output is their entire purpose, and this\nrepository is not allowed to change them to satisfy its own linter.\n\nAll four jobs verified locally exactly as CI runs them: site typecheck, 56\ntests and build; issuer typecheck, lint at zero errors, and build; SDK\ntypecheck and 80 tests.\n\nCo-Authored-By: Claude Opus 5 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01BEaXzktRU5ZPe3R2NY7CKD",
      "refs": {
        "commit": "f9582d477355b84dda3f0cde3ae11aa12c52d8fa"
      },
      "digest": "7fd30556513262ea4aac069450ba3e7d98eb5f6c963472305b319b5505c4036e"
    },
    {
      "id": "ship/flashyid/299477b4422d",
      "repo": "repo/flashyid",
      "at": "2026-08-30T03:07:48+00:00",
      "kind": "feature",
      "title": "Advertise a way in a stranger can actually use",
      "by": [
        "agent/claude"
      ],
      "asserted": "2026-08-30",
      "assertedBy": "agent/flashyid-ci",
      "visibility": "public",
      "detail": "The handshake's `join` field is the one thing in that document somebody\nactually follows. Every handshake in the estate pointed it at\napp.flashyos.com/onboard, which redirects anyone without a session to a\npassword form. A stranger following the URL our own standard tells them to\nfollow arrived at a login they had no account for.\n\nIt now points at https://flashyos.com/join — open, no account, nothing to\ninstall.\n\nCo-Authored-By: Claude Opus 5 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01BEaXzktRU5ZPe3R2NY7CKD",
      "refs": {
        "commit": "299477b4422de8f2d177928693e06571df337bff"
      },
      "digest": "1ba06971f951cf32972827b12759139f6f8311c119de5bd5f52a06acb3e95eef"
    },
    {
      "id": "ship/flashyid/a0b177244c87",
      "repo": "repo/flashyid",
      "at": "2026-08-30T02:42:32+00:00",
      "kind": "feature",
      "title": "Serve the mesh files, which this property served none of",
      "by": [
        "agent/claude"
      ],
      "asserted": "2026-08-30",
      "assertedBy": "agent/flashyid-ci",
      "visibility": "public",
      "detail": "flashyid.com returned 404 on all three: the charter, the directory fragment\nand the front door. The handshake did not exist at all, so this identity\nprovider — the estate's own authority layer — published nothing a\ncounterparty could fetch while the group published a standard telling\neveryone else to serve exactly those paths.\n\nThe cause is that this repository holds two applications. The website is\nsite/, and that is what deploys; the mesh files were written to a public/ at\nthe repository root, which nothing serves. Every check passed the whole time,\nbecause every check diffed a file against another file in the same checkout.\nCommitted is not served, and no check here could tell the difference.\n\nThe files move into site/public, where this app actually serves from. The two\ndotted paths get rewrites, which is the pattern next.config.ts already\ndocuments for jwks and openapi — Next ignores dot-prefixed route folders, so\nsite/public/.well-known would have been just as unreachable.\n\nThe handshake is new and its capabilities are derived from this property's own\ncharter — every one of the thirteen is a capability a role in\nflashyos.roles.json actually holds. A test asserts that in both directions:\nthe handshake may claim nothing the charter does not grant, and may not\nquietly drop something it does. Copying a sibling's handshake is how another\nproperty in this estate nearly shipped claiming it does curriculum and\nplacement, and that test now fails on exactly that.\n\nThe repository-root public/ is deleted rather than left. A directory that\nserves nothing but looks like it does is what produced this bug.\n\n14 tests, 48 in the site suite.\n\nCo-Authored-By: Claude Opus 5 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01BEaXzktRU5ZPe3R2NY7CKD",
      "refs": {
        "commit": "a0b177244c871c13b522fdce45b7a9b8f140277c"
      },
      "digest": "dba4f67dd21f8a8ba69db2afe48ee7211942d4f4bc4a34a3eae8ea6435a1c909"
    },
    {
      "id": "ship/flashyid/c01dd206f442",
      "repo": "repo/flashyid",
      "at": "2026-08-30T02:26:32+00:00",
      "kind": "infra",
      "title": "Point the front door at the ladder's new home",
      "by": [
        "agent/claude"
      ],
      "asserted": "2026-08-30",
      "assertedBy": "agent/flashyid-ci",
      "visibility": "public",
      "detail": "The ladder moved from gord.ventures to gord.holdings. It is an estate-wide\nclaim — every door in the estate points at it — and estate-wide claims belong\nto the parent rather than to one sibling that also has its own lanes. The old\nURL had no deployment behind it, so this door was directing anyone who read it\nto a 404.\n\nConfig and emitted door, nothing else.\n\nCo-Authored-By: Claude Opus 5 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01BEaXzktRU5ZPe3R2NY7CKD",
      "refs": {
        "commit": "c01dd206f442107607a37275b4825bd9029ac584"
      },
      "digest": "12551846b5e6fc61ec868794d0f986ece83f0492b24fc7f07c80178b3da1d73e"
    },
    {
      "id": "ship/flashyid/6866190e4318",
      "repo": "repo/flashyid",
      "at": "2026-08-30T01:34:54+00:00",
      "kind": "feature",
      "title": "Serve the directory fragment, which this property was not doing",
      "by": [
        "agent/claude"
      ],
      "asserted": "2026-08-30",
      "assertedBy": "agent/flashyid-ci",
      "visibility": "public",
      "detail": "The fragment lived only at the repository root. A Next.js app does not\nserve the repository root, so https://<this property>/directory.fragment.json\nreturned 404 — and the estate's directory is federated, meaning every\nproperty is supposed to publish its own fragment for anyone to fetch and\nmerge.\n\nThirteen of fourteen properties were in this state. The consequence is\nlarger than a missing file: the estate graph could only be assembled by\nsomeone with a git checkout of every repository, which defeats the entire\nreason for federating it. A graph you can only build from a laptop proves\nthe files are on that laptop. A graph assembled from published URLs proves\nthe estate publishes what it says it does, can be reproduced by somebody\nwho does not trust us, and is the only shape that lets an organisation we\ndo not own ever join it.\n\nSame defect as the charter, found the same way and fixed the same way: the\nfragment is copied into the served directory and CI diffs the served copy\nagainst the source so the two cannot drift.\n\nCo-Authored-By: Claude Opus 5 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01BEaXzktRU5ZPe3R2NY7CKD",
      "refs": {
        "commit": "6866190e43188fb6988b9237a9e075a93588d8b3"
      },
      "digest": "a45a8566f3dbdac51820e0cc03751de466da57029b2e25f520695f84df62bb8c"
    },
    {
      "id": "ship/flashyid/5547621a4e1e",
      "repo": "repo/flashyid",
      "at": "2026-08-30T00:19:00+00:00",
      "kind": "feature",
      "title": "Serve the charter, which this property was not doing",
      "by": [
        "agent/claude"
      ],
      "asserted": "2026-08-30",
      "assertedBy": "agent/flashyid-ci",
      "visibility": "public",
      "detail": "The AAO charter lived only at the repository root. A Next.js app does not\nserve the repository root, so https://<this property>/flashyos.roles.json\nreturned 404 while the standard this estate publishes tells every\norganisation to serve exactly that path.\n\nFound by running the estate's own properties through the verifier written\nto mark a stranger's homework. Nine of the ten live properties failed at\nrung 1 — not because a charter was missing, but because nobody could read\nit. gord.holdings was the only one that passed, and only because it is a\nstatic site that happens to serve from the repository root.\n\nThe charter is now copied into the served directory, and the front door\nworkflow diffs the served copy against the source so the two cannot drift.\nA charter that exists and cannot be fetched is worth exactly as much as no\ncharter at all — less, because it produces the belief that the work is\ndone.\n\nCo-Authored-By: Claude Opus 5 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01BEaXzktRU5ZPe3R2NY7CKD",
      "refs": {
        "commit": "5547621a4e1ec182d575dfbee9f5b6472c636f34"
      },
      "digest": "904c542ff4d78dbe9aaf31423e68732fb115015acf608f13cbf460ca7c20ab70"
    },
    {
      "id": "ship/flashyid/efb6a9190ac1",
      "repo": "repo/flashyid",
      "at": "2026-08-30T00:14:31+00:00",
      "kind": "feature",
      "title": "Publish a front door (frontdoor/1)",
      "by": [
        "agent/claude"
      ],
      "asserted": "2026-08-30",
      "assertedBy": "agent/flashyid-ci",
      "visibility": "public",
      "detail": "This property now serves /.well-known/frontdoor.json: which lanes it\nopens, what it asks at each, and what it owes in return. It completes the\ntrio the estate already half had — the handshake says who this is, the\ncharter says how it is governed, the door says how to reach it.\n\nLanes are declared per property class rather than per property, so the\nrestraint is checkable: a consumer app opens one lane and it is not\ncapital, and no property outside the parent and the bank opens the capital\nlane at all. frontdoor.config.json is the only file here that carries\nanything specific to this repository.\n\nThe rungs are identical across the estate on purpose. Standing is\nportable — the credential is a charter published at the applicant's own\ndomain, not a row in our store — so an applicant who climbs at one door\nand arrives at another must be owed the same thing. The estate-wide merge\nfails if two properties promise different terms for the same rung.\n\nCarried verbatim in every door: a rung buys a reply and a place in a\nqueue. It never buys authority, money, or access. Publishing a file at a\ndomain proves someone can write to that host and nothing more. Where real\nauthority is needed it is delegated and verified through flashyID. Both\nthe checker and the library reject a door that drops that paragraph,\nbecause a door quietly treated as an authorisation is the one way this\nbecomes a vulnerability rather than a front door.\n\nscripts/check-frontdoor.mjs and scripts/emit-frontdoor.mjs are vendored\nbyte-identical across every repository publishing a door; the canonical\ncopies and the drift test live in @flashyos/frontdoor. Both are\ndependency-free, so CI needs no install and the same two scripts work on a\nNext.js app and a static generator alike.\n\nCo-Authored-By: Claude Opus 5 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01BEaXzktRU5ZPe3R2NY7CKD",
      "refs": {
        "commit": "efb6a9190ac1d82eed8ca31bb24fcbda1675a5ae"
      },
      "digest": "91c7678ce9ba34b2d975f4337b6b704254fc40b15b5781b6f698015bc4ca73a2"
    },
    {
      "id": "ship/flashyid/1ab81739fa32",
      "repo": "repo/flashyid",
      "at": "2026-08-28T19:51:34+00:00",
      "kind": "infra",
      "title": "Make every charter in the estate conform, and gate it",
      "by": [
        "person/michael"
      ],
      "asserted": "2026-08-30",
      "assertedBy": "agent/flashyid-ci",
      "visibility": "public",
      "detail": "Ran the estate's own published validator - validateCharterDocument from\n@flashyos/aao - against every charter for the first time. None passed,\nincluding FlashyOS's own production charter and flashy-academy's. Two real\nclasses of failure:\n\n  _comment is not part of aao 0.1. The spec's own extension convention is an\n  x- prefix, and the validator says so in the error. Ten charters carried a\n  bare key the standard does not recognise.\n\n  Four family names were invented: trust, release, inbound, network-effects.\n  The ten declared families are growth, revenue, product, engineering,\n  operations, data, finance, risk, governance, support. Remapped trust to risk\n  (compliance, security, audit), release to engineering, and inbound and\n  network-effects to growth.\n\n10/10 charters now clean against the published validator.\n\nAdds scripts/check-charter.mjs, mirroring the static half of the conformance\nsuite, dependency-free so it runs before an install, vendored byte-identical\nacross the estate. Wired into the Directory workflow ahead of the fragment\ncheck. The published validator stays authoritative; when @flashyos/agent is\navailable, `npx @flashyos/agent conform` supersedes this.\n\nVerified against six failure modes, all caught: a bare non-spec key, an\ninvented family, a codename role, the template placeholder as accountable\nhuman, a capability naming a department rather than an action, and an\nescalation pointing at no declared role.\n\nOne correction along the way: the checker first flagged CRITICAL as an invalid\napproval threshold in flashyos and flashy-ledger. IMPACT_ORDER is LOW, MEDIUM,\nHIGH, CRITICAL - the charters were right and the checker was wrong. Fixed.\n\nmetaverse-group gains the charter it never had: six roles, four families left\ndeliberately empty, and its emitter now reads the charter so the two cannot\ndisagree.\n\n11 fragments, 199 nodes, 188 edges, 100% freshness, zero errors.",
      "refs": {
        "commit": "1ab81739fa3217e1dc37469d93370efaeb2becb4"
      },
      "digest": "905b4060616473de2c2aefce9eecbed02255c45314d377f35556b66da8d157b3"
    },
    {
      "id": "ship/flashyid/0459ebebee6b",
      "repo": "repo/flashyid",
      "at": "2026-08-28T18:04:13+00:00",
      "kind": "infra",
      "title": "Gate the directory fragment in CI, in the repository that produces it",
      "by": [
        "person/michael"
      ],
      "asserted": "2026-08-30",
      "assertedBy": "agent/flashyid-ci",
      "visibility": "public",
      "detail": "The estate-wide merge catches contested authority and dangling references, but\nit runs elsewhere and cannot say which repository caused them. This runs here,\non every push, and fails at the point the mistake is made.\n\nscripts/check-directory.mjs is dependency-free on purpose - a validator that\nneeds an install is a validator that gets skipped. It is vendored byte-identical\ninto every repository in the estate; repository-specific values are passed as\n--external flags rather than edited in, so the copies cannot drift.\n\n.github/workflows/directory.yml runs three steps: emit from the charter, check\nthe fragment, then `git diff --exit-code` on the committed fragment. The third\nis the one that matters - a committed fragment differing from a freshly emitted\none means someone edited the JSON instead of the source it comes from.\n\nVerified against six real failure modes, each caught with the right code:\na claim defined twice, a deleted accountability edge, a reference to a node\nnobody emits, an expiry before its assertion, an ownership edge with no\ninstrument, and hand-reordered nodes.\n\nEleven repositories still merge clean: 193 nodes, 182 edges, 100% freshness.",
      "refs": {
        "commit": "0459ebebee6bd1061c6530ee285efd9fbc26673f"
      },
      "digest": "895f03cad898241649645b983be8473dc291e531f769f14484f1508f1455fd60"
    },
    {
      "id": "ship/flashyid/ba29ae5c7e7f",
      "repo": "repo/flashyid",
      "at": "2026-08-28T17:43:35+00:00",
      "kind": "feature",
      "title": "Declare the AAO charter, and emit the directory fragment",
      "by": [
        "person/michael"
      ],
      "asserted": "2026-08-30",
      "assertedBy": "agent/flashyid-ci",
      "visibility": "public",
      "detail": "Three of the four roles are trust roles, which is the shape of a repository that issues authority: attenuation, enforcement and assertion are declared separately because they fail separately. Five families deliberately empty - identity is consumed by the estate and sells nothing of its own.\n\nscripts/directory.mjs reads the charter and emits the organisation, each\ndeclared role as an agent, the accountability edge, and the property this\nrepository operates. The charter and the fragment cannot disagree because the\nfragment is generated from the charter.\n\nReferences person/michael rather than defining it - only repo/gord-holdings is\nthe authority for people. Purely additive: no existing file is touched.\n\nMerges clean across eleven repositories: 193 nodes, 182 edges, 100% freshness.",
      "refs": {
        "commit": "ba29ae5c7e7fd243604845b510873318fd8c2e0e"
      },
      "digest": "4a534669a54c386fbf03ae89e9467a54d0455f6b0d6ebf02b1c77c8f355cae2f"
    },
    {
      "id": "ship/flashyid/e2adc9edb102",
      "repo": "repo/flashyid",
      "at": "2026-08-28T02:37:58+00:00",
      "kind": "infra",
      "title": "give the lint script a config, and run it in CI",
      "by": [
        "agent/claude"
      ],
      "asserted": "2026-08-30",
      "assertedBy": "agent/flashyid-ci",
      "visibility": "public",
      "detail": "`lint` has been `eslint .` since this repo was created, but no\n`eslint.config.*` ever existed — every invocation exited non-zero with\n\"couldn't find an eslint.config file\" and checked nothing. Nothing in CI\ncalled it, so the failure was never seen.\n\nThe evidence that authors assumed otherwise is in the source: three\n`eslint-disable-next-line` directives for `no-console` and\n`no-await-in-loop`, rules no config had ever enabled. Both are now on, so\nthose directives mean what they were written to mean. Console is scoped\noff for `src/scripts/**` and the SDK's `init/cli.ts`, where stdout is the\ninterface; everywhere else this service logs through pino.\n\ntypescript-eslint recommended on top. One warning stands (an `any` in the\noidc-provider ambient declaration), zero errors. CI runs it on the issuer\njob: errors fail, warnings do not.\n\nCo-Authored-By: Claude Opus 5 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01VgrPGGUFKMq9zXBHnfcTgs",
      "refs": {
        "commit": "e2adc9edb1029587f4f88e33aa85f5bdfc9a0ca2"
      },
      "digest": "0476b8656f9763faada771cd1d06fabd16f1f8c1ab48b2fc467482f3070813de"
    },
    {
      "id": "ship/flashyid/baa3178d11f7",
      "repo": "repo/flashyid",
      "at": "2026-08-28T02:21:01+00:00",
      "kind": "fix",
      "title": "the 'language' input was never valid, so it was ignored",
      "by": [
        "agent/claude"
      ],
      "asserted": "2026-08-30",
      "assertedBy": "agent/flashyid-ci",
      "visibility": "public",
      "detail": "The action's own warning names it: \"Unexpected input(s) 'language',\nvalid inputs are [... 'languages' ...]\". Every CodeQL workflow in the\nestate passed the singular form, which GitHub discarded — so the matrix\nlanguage selection has never actually been applied.\n\nFound while checking whether the earlier scoping fix worked. It had not,\nand the real blocking error is unchanged: code scanning is not enabled\non the repository, which is a settings toggle.",
      "refs": {
        "commit": "baa3178d11f7f609bbe7345dc6a4c969d745546f"
      },
      "digest": "79675778dd60855cf9078aab64667a3162baad0d087a9b730aec8fe7d16c2213"
    },
    {
      "id": "ship/flashyid/aedd0816b816",
      "repo": "repo/flashyid",
      "at": "2026-08-28T01:54:37+00:00",
      "kind": "other",
      "title": "hygiene: agent guidance, so conventions survive the next contributor",
      "by": [
        "agent/claude"
      ],
      "asserted": "2026-08-30",
      "assertedBy": "agent/flashyid-ci",
      "visibility": "public",
      "detail": "Thirteen of sixteen repos had no CLAUDE.md or AGENTS.md, which meant every\nagent and every new human landing here started with no conventions and\ninvented their own — the reason quality varied repo to repo.\n\nEach guide is written from this repository's real scripts, layout and\nrules, not a template: the commands are the ones that exist, and the\nrules are the ones a mistake here has already taught us.\n\nCo-Authored-By: Claude <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01VgrPGGUFKMq9zXBHnfcTgs",
      "refs": {
        "commit": "aedd0816b8167f7f1868c9100957342dc30ef928"
      },
      "digest": "a4dc3ac7ace8aeb097e2243df6e5f1ee622d14b181362509050d31524be5bc72"
    },
    {
      "id": "ship/flashyid/3973dc19a849",
      "repo": "repo/flashyid",
      "at": "2026-08-27T20:02:07+00:00",
      "kind": "other",
      "title": "sdk: enforce the approval bar in permits, validate wire chains, fix CLI + packaging",
      "by": [
        "agent/claude"
      ],
      "asserted": "2026-08-30",
      "assertedBy": "agent/flashyid-ci",
      "visibility": "public",
      "detail": "Security fixes from the P0 audit of @flashyid/sdk:\n\n- permits() now refuses (new RefusalCode 'approval_required') a demand whose\n  impact is at or above the chain's effective approval_at_or_above bar, so\n  authorize() can no longer silently allow a CRITICAL action under a HIGH bar.\n  evaluateGrant maps that one refusal to ESCALATE (unchanged behavior for the\n  gate); every other refusal stays DENY. Contract documented in both docstrings.\n- verifyAssertion shape-validates the del claim instead of casting it, and\n  authorize refuses (broken_chain) a malformed del and a chain whose leaf\n  holder is not the assertion's subject.\n- flashyid init: skip a leading literal 'init' subcommand token instead of\n  reading a file named \"init\"; bin guard now realpaths process.argv[1] and\n  compares via pathToFileURL so it fires through npm's .bin symlink.\n\nPackaging and CI:\n\n- package.json license corrected to Apache-2.0 (matches the repo LICENSE,\n  which now ships in the tarball along with docs/).\n- CI gains an sdk job: install, typecheck, vitest, build in packages/sdk.\n- sdk barrel re-exports impactRank, IMPACT_ORDER, IssueRootInput,\n  AttenuateInput; a hand-enumerated public-api test pins the export surface.\n- tsconfig.test.json typechecks the test files (wired into npm run typecheck);\n  the two grants test files import with explicit .js extensions.\n- README: Install section, valid authorize snippet, enforcement-gate section,\n  flashyid init docs, RefusalCode table.\n\nCo-Authored-By: Claude <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01VgrPGGUFKMq9zXBHnfcTgs",
      "refs": {
        "commit": "3973dc19a849557307485b38ff976f6d7a8bb7ac"
      },
      "digest": "63597c25eed80e940358bfa2f91b0395f6a2794904470e940a61fdd96f1270ee"
    },
    {
      "id": "ship/flashyid/15003c579be9",
      "repo": "repo/flashyid",
      "at": "2026-08-27T17:36:46+00:00",
      "kind": "feature",
      "title": "enforcement gate — expose the grant kernel as an ALLOW/DENY/ESCALATE gate",
      "by": [
        "agent/claude"
      ],
      "asserted": "2026-08-30",
      "assertedBy": "agent/flashyid-ci",
      "visibility": "public",
      "detail": "The response to the institutional brief's #1-CRITICAL ask: a governance decision\nthat can gate, not just record. The grant kernel already answers whether a\nsigned, unrevoked, in-mandate grant permits an action — this maps that onto the\nthree outcomes a caller acts on, and adds the operational contract.\n\n- src/enforce/gate.ts (pure core): evaluateGrant(chain, demand, {nowSec,\n  revokedJtis}) → ALLOW (in mandate, below the approval bar) / ESCALATE (at or\n  above approval_at_or_above — a human must co-sign) / DENY (unsound chain or\n  out of mandate, carrying the RefusalCode).\n- EnforcementAdapter seam; grantAdapter() backed by evaluateGrant; recordOnly\n  default (always ALLOW — never block); enforce() with a timeout that falls back\n  to record-only + an onUnavailable CRITICAL alert on an unreachable adapter.\n- Exported from @flashyid/sdk; docs/enforcement-gate.md.\n\nPreserves \"never block\" as the default — gating is opt-in, and even a\nconfigured-but-unreachable gate falls back rather than halting an agent. The\nnatural home for a Governance Pro tier.\n\nTests: ALLOW/ESCALATE/DENY across scope, spend, expiry, revocation; record-only;\nadapter throw + fake-timer timeout fallback with the alert. SDK suite green —\n66 tests; typecheck clean.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01VgrPGGUFKMq9zXBHnfcTgs",
      "refs": {
        "commit": "15003c579be925454cd6485203c713b6b85d9941"
      },
      "digest": "a124000ff931ca45cc8a9c64dc6df9c15a4c15b5e9b6f67071c334588b4146f8"
    },
    {
      "id": "ship/flashyid/aabebd824648",
      "repo": "repo/flashyid",
      "at": "2026-08-26T20:32:55Z",
      "kind": "infra",
      "title": "Phase 3: gate mesh reporting on conformance, and report the live checks",
      "by": [
        "agent/claude"
      ],
      "asserted": "2026-08-30",
      "assertedBy": "agent/flashyid-ci",
      "visibility": "public",
      "detail": "Reporting to the public directory is now a privilege a charter buys. The\nmesh sync will not run unless the charter passes conformance first — an org\nwhose charter does not parse has no roles, so every agent it reports is an\nagent nobody declared. That is not hypothetical: the first version of the\nbranch sync made every git branch its own agent, and the roster filled with\nbuild logs.\n\nThe gate runs static checks only, on purpose. The live checks read the\npublic directory this workflow is about to write to, so gating on them\nwould make the gate depend on its own output.\n\nThe live checks now run too, as a separate report-only job. They are\ndeliberately not required yet, because today they fail on real\norganizations for reasons no pull request can fix — rosters still carrying\nagents minted before the charter existed, and orgs that have not opted into\na public record at all. A gate that fires on those gets disabled within a\nweek, which is how a gate becomes decoration. It reports until the estate\nis clean and becomes required after. That ordering is the point.",
      "refs": {
        "commit": "aabebd82464871589aea5ded6a08bc5eb314bbdc"
      },
      "digest": "60e626f84d995131d8cc3c3bfa6509921701954cd9e9ad1ea10eae4d06662cc2"
    },
    {
      "id": "ship/flashyid/8e298cebfd89",
      "repo": "repo/flashyid",
      "at": "2026-08-26T20:13:10+00:00",
      "kind": "feature",
      "title": "flashyid init — read a charter, issue its grants (proof-layer Phase 03)",
      "by": [
        "agent/claude"
      ],
      "asserted": "2026-08-30",
      "assertedBy": "agent/flashyid-ci",
      "visibility": "public",
      "detail": "The 'one command' from the estate proof-layer plan, built on the grant kernel:\n'flashyid init' reads an organization's charter (flashyos.roles.json by default)\nand issues the root grant each role holds — the charter is already the grant, so\nit's a file read and a mapping, not a policy language to learn.\n\n- packages/sdk/src/init/cli.ts: parseInitArgs (pure), runInit (dependency-\n  injected — readFile/clock/jti/log — so a command, a test, and an audit produce\n  the same output), and a bin entry wiring the real fs/clock/randomUUID. Exits 1\n  on a missing/malformed charter or any unmapped capability, so a run never\n  registers a client with silently-dropped authority. Human summary + --json.\n- Added the 'flashyid' bin to package.json (dist/init/cli.js; shebang preserved\n  through tsc).\n- The RFC 7591 dynamic client registration remains the ClientRegistrar network\n  seam — kept out of the mapping so init stays offline-verifiable.\n\nVerified live against the real 10-role flashyos charter: every role maps to a\nsound grant rooted at michael@gda.capital, in the brief's exact output shape.\n9 CLI tests; package suite 53 green; build clean (shebang intact).\n\nCohesion: this is the protocol axis — packages/sdk is touched by no other branch.\nMy branch also merged origin/main (LICENSE, disclosure route, grouped dependabot)\nso it stays current with the estate.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01VgrPGGUFKMq9zXBHnfcTgs",
      "refs": {
        "commit": "8e298cebfd890a91029ca4849015f209ab64f405"
      },
      "digest": "4185b57a3047a845db805564b8920f78c420935fda9851514a046a8d565aef97"
    },
    {
      "id": "ship/flashyid/36c2d5b91648",
      "repo": "repo/flashyid",
      "at": "2026-08-26T20:09:30Z",
      "kind": "feature",
      "title": "Join the FlashyOS mesh: declare a charter and check it in CI",
      "by": [
        "agent/claude"
      ],
      "asserted": "2026-08-30",
      "assertedBy": "agent/flashyid-ci",
      "visibility": "public",
      "detail": "Phase 2 of the estate rollout. This repository declares the standing roles\nit actually has, names the human accountable for them, and checks the\ncharter against the AAO conformance suite on every pull request.\n\nA role is a standing responsibility that exists whether or not work is in\nflight. A branch is an assignment and lives under its role as\n<role>/<workstream>. Naming both with one string is how a public roster\nends up reading like a git log — fifty-five of the first hundred and two\nagents on the network were branch names, which is the regression this\nordering exists to prevent.\n\nFamilies left empty are left empty. Inventing a role to fill one is the\nroster inflation the standard exists to stop, and an empty family is an\nhonest statement about what this property does not yet do.\n\nCODEOWNERS is the other half. A charter that names an accountable human\nwhile anyone can merge anything is a declaration rather than a control, so\nthe roles and the branch rules have to say the same thing.\n\nVerified with `npx @flashyos/aao <slug>.roles.json` — five static checks\npass, three live checks deferred because they are runtime facts that\ncannot be declared.",
      "refs": {
        "commit": "36c2d5b9164842fcc6e6f0d563cb1bd9c9d6ee10"
      },
      "digest": "df4f2a7c2b1da4ad606105746841cb3957b8b1e4ffaaae65741ed25e64b88276"
    },
    {
      "id": "ship/flashyid/7b58eaf7f85d",
      "repo": "repo/flashyid",
      "at": "2026-08-26T19:51:37+00:00",
      "kind": "feature",
      "title": "signAssertion — the issuer half, completing the round trip",
      "by": [
        "agent/claude"
      ],
      "asserted": "2026-08-30",
      "assertedBy": "agent/flashyid-ci",
      "visibility": "public",
      "detail": "The SDK could verify assertions and build grant chains but not mint the JWS a\nrelying party verifies. signAssertion closes that: an EdDSA-signed Flashy ID\nassertion carrying a subject and a delegation chain (iss/aud/sub/exp/jti/del).\nThe private key never leaves the issuer; a relying party holds only the public\nJWKS. Anything this signs, verifyAssertion accepts.\n\nTests: sign → decode claims; sign → verifyAssertion round trip; sign → authorize\n(in-mandate authorized, over-limit refused out_of_mandate); a rotated-away key\nno longer verifies an old assertion. Package suite 44 green, build clean.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01VgrPGGUFKMq9zXBHnfcTgs",
      "refs": {
        "commit": "7b58eaf7f85d0dfb46d05969a8784c90f957fe57"
      },
      "digest": "5f737280898676833f375682dc078c69174d93f453e543761833d050e1614546"
    },
    {
      "id": "ship/flashyid/ff951de0e33e",
      "repo": "repo/flashyid",
      "at": "2026-08-26T19:43:59+00:00",
      "kind": "feature",
      "title": "make @flashyid/sdk a publishable package + publish workflow",
      "by": [
        "agent/claude"
      ],
      "asserted": "2026-08-30",
      "assertedBy": "agent/flashyid-ci",
      "visibility": "public",
      "detail": "Relocate the grant kernel, verify path, and charter→grants mapping from src/\ninto packages/sdk/ as a standalone, publishable npm package — the code that\nmakes flashyid.com's SDK claim true and closes the public npm 404.\n\n- packages/sdk: package.json (@flashyid/sdk 0.1.0, ESM, exports + types, files\n  [dist]), tsconfig (NodeNext, declarations), vitest config, README. jose is the\n  only runtime dependency; the whole thing is pure verify + grant logic.\n- src/index.ts barrel: the verify surface (verifyAssertion, authorize) + the\n  grant kernel (issueRoot/attenuate/verifyChain/permits/grantFromCharterRole) +\n  the charter mapping (grantsFromCharter, summarizeGrants).\n- .github/workflows/publish-sdk.yml: on a sdk-v* tag (or manual dispatch),\n  typecheck → test → build → npm publish --provenance. Requires one repo secret,\n  NPM_TOKEN.\n- Standalone (not a root workspace), so the OIDC backend's build and deploy are\n  untouched. site/tests import path updated to the new location.\n\nVerified: package builds to dist (.js + .d.ts) and its 39 tests pass; backend\nsuite 13 + 3 Mongo skips, typecheck clean; site suite 41 green.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01VgrPGGUFKMq9zXBHnfcTgs",
      "refs": {
        "commit": "ff951de0e33e3622bff260bb344b6e8d765d54dd"
      },
      "digest": "b35244acd82ba1bca98ffaa148889d1b837636420dd3f3b098688e5df612d036"
    },
    {
      "id": "ship/flashyid/c6f9c65973c6",
      "repo": "repo/flashyid",
      "at": "2026-08-26T19:27:43+00:00",
      "kind": "feature",
      "title": "institutionalize flashyid.com — accuracy + brand kit + real builds",
      "by": [
        "agent/claude"
      ],
      "asserted": "2026-08-30",
      "assertedBy": "agent/flashyid-ci",
      "visibility": "public",
      "detail": "A full audit found the site predated the just-built SDK/grants and the estate\nbrand kit. This reconciles every load-bearing claim with reality and adopts the\ncanonical Flashy brand.\n\nAccuracy (site now matches the backend + the shipped code):\n- Issuer: bare flashyid.com → id.flashyid.com everywhere it names the token\n  issuer or the JWKS origin (config.ts is the source of truth). flashyid.com\n  stays the site host; id.flashyid.com is the issuer. Dropped the confusing\n  third hostname (id.flashy.gold).\n- Algorithm: RS256 / kid flshy-01 → EdDSA (Ed25519), the algorithm the backend\n  actually signs with; the JWKS sample is now an OKP/Ed25519 key, and the\n  active kid is described as published-in-the-JWKS rather than hardcoded.\n- SDK: the /docs surface was fabricated (FlashyID class, grants.issue, r.valid).\n  Rewritten to the real @flashyid/sdk exports — verifyAssertion, authorize,\n  issueRoot, attenuate, verifyChain, permits, grantFromCharterRole — with honest\n  status (source-available in src/sdk; npm release pending). Removed 'everything\n  works today' / 'CI green' / '7 methods'.\n- Refusal vocabulary reconciled with the kernel (chain_widened, broken_chain,\n  expired, revoked, out_of_mandate, scope_unmapped, empty_chain) and the JWS\n  layer (bad signature etc. → verifyAssertion returns null). Limit model fixed:\n  approval is a severity (at/above HIGH), not a dollar figure; no cnf field.\n\nBranding (the canonical kit, vendored + drift-tested):\n- Property accent → Signal Blue #5B8CFF (was #4C9BFF); ground → Ink #08090A.\n- Fonts → Archivo Black / Plus Jakarta Sans / JetBrains Mono, self-hosted via\n  next/font (removed the Google Fonts CDN link the kit forbids).\n- Favicon → the Flashy ID mark (blue bolt on ink) at app/icon.svg — the site\n  had none. Kit gold #FFC93C for the semantic draft state.\n\nTests: new tests/institutional.test.ts — the documented SDK methods match the\nreal @flashyid/sdk exports (and nothing extra); no stale RS256/flshy-01/wrong\nissuer/'CI green'; acce",
      "refs": {
        "commit": "c6f9c65973c6763d8c3548ae06ca6917b7eb3353"
      },
      "digest": "f2068f66e0585c36c6851286365451cd9d89ea5a28b2c7bd6afa81f856107aab"
    },
    {
      "id": "ship/flashyid/e0659d75465f",
      "repo": "repo/flashyid",
      "at": "2026-08-26T19:11:52+00:00",
      "kind": "infra",
      "title": "vendor the canonical Flashy brand kit + drift test",
      "by": [
        "agent/claude"
      ],
      "asserted": "2026-08-30",
      "assertedBy": "agent/flashyid-ci",
      "visibility": "public",
      "detail": "Every Flashy repo vendors flashy-group/brand verbatim and carries a hash drift\ntest against MANIFEST.sha256 (USAGE.md); flashyID was missing both. This adds\nthe vendored brand/ directory and the drift test so a local edit to a brand\nfile fails CI instead of silently forking the estate identity.\n\nflashyID's one accent is Signal Blue #5B8CFF (the ID lozenge) — the site maps\nit to --brand-accent next. Manifest verified on copy; 2 tests green.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01VgrPGGUFKMq9zXBHnfcTgs",
      "refs": {
        "commit": "e0659d75465fcd000a8e2ac4d7d89b2ddd6144ff"
      },
      "digest": "914e2516d5ea9b5076bee0c6742c0ddc3fc9b9c200f389e2f0be3539d71d0e9e"
    },
    {
      "id": "ship/flashyid/0c71c6e5f3a3",
      "repo": "repo/flashyid",
      "at": "2026-08-26T18:40:58+00:00",
      "kind": "feature",
      "title": "@flashyid/sdk verify surface — assertion + delegation in one import",
      "by": [
        "agent/claude"
      ],
      "asserted": "2026-08-30",
      "assertedBy": "agent/flashyid-ci",
      "visibility": "public",
      "detail": "The relying-party half of Flashy ID: verify that an assertion is genuinely from\nthe provider AND that the delegation it carries authorizes a specific action —\nfrom a single import, holding no secret (only the public JWKS).\n\n- verify.ts: verifyAssertion (jose: signature against JWKS + iss/aud/exp → the\n  identity and any delegation chain; never throws, a bad token is null), and\n  authorize (verify assertion → verify its delegation chain → check the demand,\n  returning null for a 401, or a specific refusal for a 403).\n- index.ts: the consumer surface, with the grant kernel re-exported so a relying\n  party has one import for everything.\n- Adds jose ^5.10.0 as a direct dependency.\n\nThis is the code half of proof-layer Phase 00 (the @flashyid/sdk verify path);\npublishing the package to npm — closing the public 404 — remains a workspace +\nnpm-token step for CI/Michael.\n\nTests sign real EdDSA assertions with a local key (no network) and exercise the\nfull path: genuine assertion → identity + 2-link delegation; wrong aud / bad\nsignature / missing → null; in-mandate → authorized; over-limit, missing scope,\nrevoked link, no-delegation → the specific refusal. 10 tests; full flashyid\nsuite 50 passed / 3 skipped (Mongo memory-server binary 403 in sandbox);\ntypecheck clean.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01VgrPGGUFKMq9zXBHnfcTgs",
      "refs": {
        "commit": "0c71c6e5f3a3e5d2eb3a896d44600085ae6d8fc7"
      },
      "digest": "91c1ebb787dcf245e183c8a79af484d43cef11646c7ecba03bb4f336d6132d28"
    },
    {
      "id": "ship/flashyid/57d09f6da692",
      "repo": "repo/flashyid",
      "at": "2026-08-26T18:40:26Z",
      "kind": "feature",
      "title": "Adopt Flashy Brand Standards Rev 01",
      "by": [
        "agent/claude"
      ],
      "asserted": "2026-08-30",
      "assertedBy": "agent/flashyid-ci",
      "visibility": "public",
      "detail": "The property had no favicon at all — the most visible part of being out of\ndate. It now ships src/app/icon.svg: the single-path bolt in Signal Blue on\nInk, which survives the 16px crop.\n\nNav lockup: replaces a boxed \"F\" beside \"FLASHY ID\" with the real lockup —\nthe bolt sitting inside FLASHY as the S, and ID in a Signal Blue lozenge\nriding high. The standards fix both positions, and neither survives being\nrebuilt from spans, so the lockup ships as one asset.\n\nTokens: Ink #08090A and Paper #F5F5F3 replace #0A0C10 and #E7EBF2, so the\nneutrals are byte-identical to every other property. The accent moves to\nSignal Blue #5B8CFF. Where another property's colour appears it now uses\nthat property's canonical hex — Volt Mint for Flashy OS, Flashy Gold,\nDeep Violet for Flashy Mind — so a cross-reference reads as a citation\nrather than as a second brand colour.\n\nType: Archivo Black for display, Plus Jakarta Sans for body and UI,\nJetBrains Mono for domains, tokens and timestamps, replacing Space Grotesk\nand the IBM Plex pair.",
      "refs": {
        "commit": "57d09f6da692de76de2b916a5b3e81ef994708a6"
      },
      "digest": "424e7a540bc790dcc9058cd6f41cc3ae2f5e89606533894fe249f280b017d6fb"
    },
    {
      "id": "ship/flashyid/0b1947601907",
      "repo": "repo/flashyid",
      "at": "2026-08-26T18:35:36+00:00",
      "kind": "feature",
      "title": "flashyid init — charter to grants (proof-layer Phase 03 core)",
      "by": [
        "agent/claude"
      ],
      "asserted": "2026-08-30",
      "assertedBy": "agent/flashyid-ci",
      "visibility": "public",
      "detail": "Turn an organization's charter into the root grants its roles hold, on top of\nthe grant kernel. grantsFromCharter maps every role in a charter at once (one\nroot grant per role, issued from accountableTo) — the mapping the init command\nruns when it reads a repository's flashyos.roles.json.\n\n- charterGrants.ts: grantsFromCharter (pure, deterministic — caller supplies\n  clock + jti factory), summarizeGrants (the command's per-role output, each\n  grant verified as it renders), and ClientRegistrar as the RFC 7591\n  network seam kept OUT of the mapping so it stays offline-verifiable.\n- Any unmapped capability under a scope registry fails the WHOLE run (ok:false)\n  rather than registering a client with silently-dropped authority.\n\nTests over the real 10-role flashyos.roles.json charter: every role maps to a\nsound grant rooted at michael@gda.capital; charter fields land on the grant\nrole-for-role (capabilities→scp, worksIn→res, humanApprovalAtOrAbove→lim); an\nunmapped capability refuses the run; summary renders. 29 grants+init tests green,\nfull flashyid suite 40 passed / 3 skipped (Mongo memory-server binary 403 in\nsandbox, pre-existing). Typecheck clean.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01VgrPGGUFKMq9zXBHnfcTgs",
      "refs": {
        "commit": "0b19476019077d2c7681b3c28874b001d125dd13"
      },
      "digest": "6f75c201527230f38c2201f338182e45092594cf893c08a0a88b40f237669ee5"
    },
    {
      "id": "ship/flashyid/67d6191314c6",
      "repo": "repo/flashyid",
      "at": "2026-08-26T18:27:23+00:00",
      "kind": "feature",
      "title": "the delegated-authority grant kernel (Flashy ID v0.3)",
      "by": [
        "agent/claude"
      ],
      "asserted": "2026-08-30",
      "assertedBy": "agent/flashyid-ci",
      "visibility": "public",
      "detail": "The piece that lets an agent act on a person's authority without ever being\nable to exceed it. A grant is a delegation chain, not a token: the root is\nissued from the human a charter names as accountableTo, and every link below is\nan attenuation. One rule holds it together — a chain only ever narrows.\n\nsrc/grants/ — pure functions, no I/O, no clock (time passed in), no dependency,\nso the same code runs in the issuer, a relying party, and a stranger's audit:\n- types.ts: GrantLink / GrantChain / Limit / refusal vocabulary / EffectiveGrant.\n- grants.ts: issueRoot, attenuate (refuses chain_widened rather than clamping),\n  verifyChain (continuity + narrowing + expiry + revocation → EffectiveGrant),\n  permits (does a verified chain authorize THIS action → out_of_mandate).\n- fromCharter.ts: the charter IS the grant — capabilities→scp, worksIn→res,\n  humanApprovalAtOrAbove→lim, accountableTo→root. Injectable scope registry\n  refuses an unmapped capability rather than guessing.\n\nThree invariants, each enforced and each control-tested (a valid chain is\nmutated to violate it and the WHOLE chain is asserted to fail, not just that the\nconstructor would have refused): never widens; effective expiry is the minimum\nacross the chain; revocation walks down. contract.sign is deliberately absent —\nagents move value within a mandate, a named human signs.\n\n22 tests, pure, no network. Typecheck clean; full flashyid suite green (Mongo\nmemory-server suites skip in sandbox on binary-download 403, unrelated).\n\nThis is Phase 02 of the estate proof-layer plan and the concrete agent-identity\nlayer of the Identity Plane architecture — realized via charter-as-grant.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01VgrPGGUFKMq9zXBHnfcTgs",
      "refs": {
        "commit": "67d6191314c6938347a84b10a42aa99eda9d88a1"
      },
      "digest": "76db765d0b6ef288ad56134dd146a81a6f6990450948c2d15b09d1652218df7a"
    },
    {
      "id": "ship/flashyid/b54a9ecca8b9",
      "repo": "repo/flashyid",
      "at": "2026-08-26T18:03:27+00:00",
      "kind": "feature",
      "title": "register FlashyOS as an OIDC relying party",
      "by": [
        "agent/claude"
      ],
      "asserted": "2026-08-30",
      "assertedBy": "agent/flashyid-ci",
      "visibility": "public",
      "detail": "Part of T3 (flashyID as identity provider of record) in the flashyos estate.\nAdds the 'flashyos' first-party client so app.flashyos.com can delegate login\nto flashyID once the unified identity store lands — redirect terminates at\napi.flashyos.com/api/v1/auth/flashyid/callback, which maps the flashyID sub to\na flashyOS user and issues a flashyOS session.\n\nConfig only; idempotent upsert like the other clients. No behavior change until\nflashyOS wires its callback (flag-gated, off by default) — see flashyos\ndocs/flashyid-sso.md.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01VgrPGGUFKMq9zXBHnfcTgs",
      "refs": {
        "commit": "b54a9ecca8b9e7eaa959299f102d574d40a3b02e"
      },
      "digest": "50d2b7e22454ee7f94328f6151c0b92a744152e89980ab6186d839488b073942"
    },
    {
      "id": "ship/flashyid/27d62735a872",
      "repo": "repo/flashyid",
      "at": "2026-08-26T13:10:32+00:00",
      "kind": "infra",
      "title": "add Dependabot, secret scanning, and CodeQL",
      "by": [
        "agent/claude"
      ],
      "asserted": "2026-08-30",
      "assertedBy": "agent/flashyid-ci",
      "visibility": "public",
      "detail": "Estate-wide hardening baseline (Estate Hardening Doctrine, Phase 1):\n- Dependabot weekly updates (dependencies + GitHub Actions)\n- gitleaks working-tree secret scan on push/PR/weekly\n- CodeQL SAST on default branches and PRs (where applicable)\n\nThe secret scan is the control that would have caught the committed\nAUTH_SECRET; the buildos/kopman root .gitignore that was missing entirely\nis restored so env files can never be committed again.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01VgrPGGUFKMq9zXBHnfcTgs",
      "refs": {
        "commit": "27d62735a8724e126a5a6b4184fcfd47b1efe43e"
      },
      "digest": "abdbbbaa7714b9ff21a6d59b56550f1bac958d6675395c6858580041e93fc294"
    },
    {
      "id": "ship/flashyid/0ceeea56752e",
      "repo": "repo/flashyid",
      "at": "2026-08-25T17:44:11+00:00",
      "kind": "other",
      "title": "The identity lens on the AAO Stack canon",
      "by": [
        "agent/claude"
      ],
      "asserted": "2026-08-30",
      "assertedBy": "agent/flashyid-ci",
      "visibility": "public",
      "detail": "llms.txt gains the canon section — authority is the clause of every\nterm: the protocol's authorization clause is what Flashy ID proves, and\nthe enterprise problem's first question is answered here. flashyid.json\nknowsAbout gains the five terms as DefinedTerm references, url-only by\ndesign: a reference carrying a description would be a second definition,\nwhich the estate rule forbids — and the consistency suite now asserts\nexactly that, plus that both surfaces agree on every canonical URL.\n\n33 tests green; typecheck clean.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01VgrPGGUFKMq9zXBHnfcTgs",
      "refs": {
        "commit": "0ceeea56752e6fff896e83c6f5f5b31f2ba7cfe6"
      },
      "digest": "9594006b1c1d0385857325ecaf8965dac482762074bf106f12e594142e93525d"
    },
    {
      "id": "ship/flashyid/cd59d4acc838",
      "repo": "repo/flashyid",
      "at": "2026-08-25T14:03:36+00:00",
      "kind": "other",
      "title": "Hidden Bolts 404: the kit bolt drawn cracked over a page that did not settle",
      "by": [
        "agent/claude"
      ],
      "asserted": "2026-08-30",
      "assertedBy": "agent/flashyid-ci",
      "visibility": "public",
      "detail": "The one surface where the mark may break (Hidden Bolts doctrine:\ndecorative only, nothing gated). Same single kit path drawn twice\nthrough two clip halves in Signal Blue, the lower half slipped off the\nbreak line.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01VgrPGGUFKMq9zXBHnfcTgs",
      "refs": {
        "commit": "cd59d4acc83832daffb8bf4e5ec9dddc47ecffa1"
      },
      "digest": "467517bbdd45be32fe89a365841942715ea0ebe0368b78bea67bb158fba10bf8"
    },
    {
      "id": "ship/flashyid/db51b027e249",
      "repo": "repo/flashyid",
      "at": "2026-08-25T02:46:41+00:00",
      "kind": "other",
      "title": "Per-property kit favicon",
      "by": [
        "agent/claude"
      ],
      "asserted": "2026-08-30",
      "assertedBy": "agent/flashyid-ci",
      "visibility": "public",
      "detail": "Same kit tile geometry, this property's accent on the bolt — the tab\nicon now follows the one-accent-per-property lockup grammar. Stale\npre-kit icon assets removed where present.\n\nCo-Authored-By: Claude Opus 5 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01VgrPGGUFKMq9zXBHnfcTgs",
      "refs": {
        "commit": "db51b027e249712596df5e538f59f53b7d546ac9"
      },
      "digest": "829b6187456fa44778baa56dd8e5555fd368425bb303ad1646c2e188a0d840ae"
    },
    {
      "id": "ship/flashyid/711a37d0d6a7",
      "repo": "repo/flashyid",
      "at": "2026-08-25T02:37:01+00:00",
      "kind": "other",
      "title": "Deploy pipeline from the family template",
      "by": [
        "agent/claude"
      ],
      "asserted": "2026-08-30",
      "assertedBy": "agent/flashyid-ci",
      "visibility": "public",
      "detail": "Instance of flashy-group/deploy/cloud-run-deploy.yml (service:\nflashyid). Inert until the GCP_WIF_PROVIDER / GCP_DEPLOY_SA repo\nvariables are set — see the header for the one-time bootstrap.\n\nCo-Authored-By: Claude Opus 5 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01VgrPGGUFKMq9zXBHnfcTgs",
      "refs": {
        "commit": "711a37d0d6a7303da686e9276f6d846a0790e292"
      },
      "digest": "141a5d41e4423a5362d9d58da1f89853ccac0fd216d272eee804e501cb8579e9"
    },
    {
      "id": "ship/flashyid/96f0fbb9b72b",
      "repo": "repo/flashyid",
      "at": "2026-08-25T01:08:13+00:00",
      "kind": "other",
      "title": "Bolt Rollout: Flashy ID takes Signal Blue",
      "by": [
        "agent/claude"
      ],
      "asserted": "2026-08-30",
      "assertedBy": "agent/flashyid-ci",
      "visibility": "public",
      "detail": "The OIDC interaction pages move onto the kit: Ink ground, Signal Blue\n#5B8CFF on generic primary actions, kit-tracking uppercase brand line\nwith the ID suffix in accent. The \"Continue in Telegram\" button keeps\nTelegram's own blue — platform button conventions beat house accents on\na third-party auth affordance. System font stack stays deliberately: an\nauth redirect page should not spend a webfont fetch.\n\nTypecheck clean; test suite as before (the one Mongo-memory suite skips\nin this sandbox — its binary download is blocked, unrelated to this\nchange).\n\nCo-Authored-By: Claude Opus 5 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01VgrPGGUFKMq9zXBHnfcTgs",
      "refs": {
        "commit": "96f0fbb9b72b9e2b7085af7e2511912344f72553"
      },
      "digest": "eb8d9be450a8c894257d432e1b7be04773c209a07979441493a8333b9b091c21"
    },
    {
      "id": "ship/flashyid/812d1138d490",
      "repo": "repo/flashyid",
      "at": "2026-08-21T16:18:17+00:00",
      "kind": "infra",
      "title": "Name the two lenses this property already hands work to",
      "by": [
        "agent/claude"
      ],
      "asserted": "2026-08-30",
      "assertedBy": "agent/flashyid-ci",
      "visibility": "public",
      "detail": "The rule sentence routed settlement and procurement queries nowhere: the\ngroup section listed four properties while the estate runs seven lens\nholders. A reader told that settlement questions belong elsewhere, and not\ntold where, has been given a dangling pointer.\n\nThe new test derives the check from the file itself — every domain the rule\nroutes to must appear in the group section — so adding a lens without\nlisting it fails rather than ships.\n\nCo-Authored-By: Claude Opus 5 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01EEAAmijDh3kzFH7SY53jZ7",
      "refs": {
        "commit": "812d1138d490e467899180eafcaa9599c0ae223c"
      },
      "digest": "9b0613befb9b755c38cb8adcf03e2dddc92ffc33ff75391d1784842ba2564d8d"
    },
    {
      "id": "ship/flashyid/38a5e81a663c",
      "repo": "repo/flashyid",
      "at": "2026-08-21T16:14:54+00:00",
      "kind": "feature",
      "title": "Give the phone a navigation",
      "by": [
        "agent/claude"
      ],
      "asserted": "2026-08-30",
      "assertedBy": "agent/flashyid-ci",
      "visibility": "public",
      "detail": "Below 860px .fl-navlinks was display:none and nothing replaced it, so every\nroute on this site was unreachable from the header on a phone — the spec, the\nregistries, the trust page, all of it, reachable only from the footer.\n\nThe sheet is a <details>, not a state-gated panel, so it opens with CSS alone:\na navigation that needs a bundle is a navigation a crawler does not have, and\nthis property argues for machine-readable surfaces everywhere else. It folds\nover the same MENUS array the desktop nav folds over, so a route cannot be\nreachable on a laptop and missing on a phone.\n\nBelow 560px the wordmark, the CTA and the trigger cannot share a row. The CTA\nloses and reappears as the first item inside the sheet.\n\nCo-Authored-By: Claude Opus 5 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01EEAAmijDh3kzFH7SY53jZ7",
      "refs": {
        "commit": "38a5e81a663c425bd71aeed75d1a7dfb58adfa1b"
      },
      "digest": "01fcea090bc0710f5e87b326480a952b94494f310615486536768b3b29596d2a"
    },
    {
      "id": "ship/flashyid/f89174d9544d",
      "repo": "repo/flashyid",
      "at": "2026-08-20T20:09:29+00:00",
      "kind": "other",
      "title": "site: Flashy Labs is the R&D department of Flashy Group, not an alias",
      "by": [
        "agent/claude"
      ],
      "asserted": "2026-08-30",
      "assertedBy": "agent/flashyid-ci",
      "visibility": "public",
      "detail": "D-AC resolved by the principal: Flashy Labs is public. The canon that\nlanded on flashyos.com models it as the parent's research and\ndevelopment department, and this property now tells the same story in\nits Organization JSON-LD, its entity manifest and its llms.txt — two\nproperties, one account of the parent. A test pins the model.\n\nCo-Authored-By: Claude Opus 5 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01EEAAmijDh3kzFH7SY53jZ7",
      "refs": {
        "commit": "f89174d9544d27c21cfcf308226142975c9aea4c"
      },
      "digest": "3d47f072c98ccd654d00597daa0404da93f825a0d17982554d04356d096b5920"
    },
    {
      "id": "ship/flashyid/1500b69d6467",
      "repo": "repo/flashyid",
      "at": "2026-08-20T08:42:43-04:00",
      "kind": "other",
      "title": "ID-5 deploy readiness: first tests, CI, Node 22, and a lazy-config fix (#1)",
      "by": [
        "person/michael",
        "agent/claude"
      ],
      "asserted": "2026-08-30",
      "assertedBy": "agent/flashyid-ci",
      "visibility": "public",
      "detail": "* ID-5 deploy readiness: first tests, CI, Node 22, and a lazy-config fix\n\nflashyid was one commit of solid code with nothing proving it: no tests,\nno CI, and a Node 20 image in a Node 22 estate (20 is EOL since April).\nClosing the gap between built and deployable:\n\n- Tests for the trust root (verifyTelegramAuth: tamper, replay, future\n  auth_date, malformed hashes, unsigned-extra-field tolerance), the config\n  contract (lazy, names the missing var), the machine surfaces (llms.txt\n  and entity JSON point at their own issuer), and the read-only Customer\n  boundary against a real in-memory mongod (skips itself only where the\n  binary cannot be downloaded — it runs in CI).\n- The manifest test caught a real bug: manifest.ts captured\n  config.issuer.url at module level, defeating the lazy-config convention\n  the file itself cites. Now read through a getter at render time.\n- CI: typecheck, tests, build, and a Docker image build as a checked fact.\n- Dockerfile: node 20-alpine → 22-alpine, all three stages.\n- tsconfig excludes test files from the dist build.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_019pUgSYP9uuYUPC3BJUmCxo\n\n* Scope the root test run to the service; site/ runs its own suite\n\nMain grew a site/ workspace with its own vitest config and @/ aliases;\nthe root runner was swallowing its tests and failing on the aliases it\ndoes not have.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_019pUgSYP9uuYUPC3BJUmCxo\n\n---------\n\nCo-authored-by: Claude <noreply@anthropic.com>",
      "refs": {
        "commit": "1500b69d6467f7087fed00d3d7772840dc75efb0",
        "pr": "https://github.com/FlashyLabs/flashyid/pull/1"
      },
      "digest": "3a648bf2a877e55538f414446a64627354c30070990c913f3735e9332e876c31"
    },
    {
      "id": "ship/flashyid/77fd8cee453b",
      "repo": "repo/flashyid",
      "at": "2026-08-19T20:01:20+00:00",
      "kind": "other",
      "title": "site: the Policy object card carried a second date too — Q1 2027 everywhere",
      "by": [
        "agent/claude"
      ],
      "asserted": "2026-08-30",
      "assertedBy": "agent/flashyid-ci",
      "visibility": "public",
      "detail": "Same defect class as the fm-revoke split fixed earlier tonight: the\nspec roadmap dates the policy engine v0.5 · Q1 2027, the #policy panel\nsays Q1 2027, and the Object 03 card on the same page said Q4 2026.\nOne debt, one date. The regression test now sweeps every dated marker\non the how-it-works page rather than pinning single strings, so a\nthird occurrence cannot ship either.\n\nCo-Authored-By: Claude Opus 5 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01EEAAmijDh3kzFH7SY53jZ7",
      "refs": {
        "commit": "77fd8cee453b8bb7cb716e3748d6b042222f702f"
      },
      "digest": "e6db9c662218cc2056c5d54ab1345bb30a8ddbac953ce6c6254912aa3208fdaf"
    },
    {
      "id": "ship/flashyid/5c75cd58b462",
      "repo": "repo/flashyid",
      "at": "2026-08-19T19:24:38+00:00",
      "kind": "fix",
      "title": "site: fix the date split, honesty-soften the redirect claim, add the consistency suite",
      "by": [
        "agent/claude"
      ],
      "asserted": "2026-08-30",
      "assertedBy": "agent/flashyid-ci",
      "visibility": "public",
      "detail": "FID-3: /how-it-works dated cross-org revocation propagation Q4 2026\nwhile /spec and /trust said Q1 2027 — aligned to the spec, and a test\nnow fails if any surface ever re-dates it.\n\nFID-4: the footer and llms.txt claimed \"id.flashy.gold 301s here\"\nbefore the DNS redirect exists. Softened to \"will 301 here once DNS is\nconfigured\" — a machine that tests the claim must not find it false on\nthe property whose product is that its statements agree. Restore the\noriginal wording in the same commit that configures the redirect.\n\nTests (vitest, 22): one-date-per-debt regression; llms.txt carries the\n\"Not built\" section with dates agreeing with the spec roadmap; the\nentity manifest uses only estate status vocabulary, keeps Policy\nPLANNED, and declares the reciprocal edge at the URL flashygroup.com\nactually serves; the JWKS route fails closed (503 unconfigured, 500 on\nmalformed input, spec cache header on success); OpenAPI documents only\nthe implemented surface; every nav, footer, evidence and OG-card link\nresolves to a real route; answer/comparison slugs unique; every\ncomparison carries a real loss-row; the banned adjectives stay banned.\n\nCo-Authored-By: Claude Opus 5 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01EEAAmijDh3kzFH7SY53jZ7",
      "refs": {
        "commit": "5c75cd58b462f4e5556c091c5a45e892d05f3f4c"
      },
      "digest": "c6713e1c0864618731c6e4d549316e563456c46cdbf3b501fafecd01c9e88d34"
    },
    {
      "id": "ship/flashyid/ada847e53965",
      "repo": "repo/flashyid",
      "at": "2026-08-19T19:04:40+00:00",
      "kind": "docs",
      "title": "the commitments ledger — vision and execution roadmap",
      "by": [
        "agent/claude"
      ],
      "asserted": "2026-08-30",
      "assertedBy": "agent/flashyid-ci",
      "visibility": "public",
      "detail": "Boardroom pass over the live site, the design handoff's ROADMAP.md and\nthe Authority Graph audit, written the evening the site launched.\n\nThe operating premise: the website is now the spec. Every gold marker\non flashyid.com is a public promise with a printed date, and this\ndocument is the ledger of those promises with the build order that\npays them — six tracks (protocol, SDK+docs CI, issuer deployment,\nFlashyOS convergence, policy+revocation, trust ops), each with the\nhandoff's pass/fail gates.\n\nScoreboard as of tonight: launch gates 0.1 (live JWKS, real key),\n0.3 (machine layer in the first PR) and 0.4 (canonical hostname,\nreciprocal edge live both ends) closed today; 0.2 (two real signed\nassertions) is the open item and the next Monday.\n\nAlso records the one ledger inconsistency to fix: /how-it-works dates\ncross-org revocation propagation Q4 2026 while /spec and /trust say\nQ1 2027 — align to the spec.\n\nCo-Authored-By: Claude Opus 5 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01EEAAmijDh3kzFH7SY53jZ7",
      "refs": {
        "commit": "ada847e539653199951221e3a2eab1a96fdb3449"
      },
      "digest": "7d2d75827093f150bb5b86dc176353ccacd514dadde09dd0d5c1a7be5ef1e247"
    },
    {
      "id": "ship/flashyid/0a887cd3cfc4",
      "repo": "repo/flashyid",
      "at": "2026-08-19T18:52:32+00:00",
      "kind": "infra",
      "title": "site: point sameAs at the real property page — /properties/flashy-id",
      "by": [
        "agent/claude"
      ],
      "asserted": "2026-08-30",
      "assertedBy": "agent/flashyid-ci",
      "visibility": "public",
      "detail": "flashygroup.com's directory registers this property at the hyphenated\nslug flashy-id, consistent with its other slugs (claimyour-gold,\nflashy-gold, flashy-mind). The sameAs here pointed at /flashyid, which\nwould have 404'd — and a sameAs pointing at a 404 is worse than none.\nBoth ends of the edge now name the same URL, which is what lets a\nresolver treat the relationship as fact rather than a one-sided claim.\n\nCo-Authored-By: Claude Opus 5 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01EEAAmijDh3kzFH7SY53jZ7",
      "refs": {
        "commit": "0a887cd3cfc4d2dae51b5e9399467c84dc769ccd"
      },
      "digest": "7a3fbd38cbe46c032cd7e175b7f170f7e06a6df9cb01ad04746a68f737ba6895"
    },
    {
      "id": "ship/flashyid/456ccf349ff1",
      "repo": "repo/flashyid",
      "at": "2026-08-19T18:36:23+00:00",
      "kind": "feature",
      "title": "Merge Vercel Analytics",
      "by": [
        "agent/claude"
      ],
      "asserted": "2026-08-30",
      "assertedBy": "agent/flashyid-ci",
      "visibility": "public",
      "refs": {
        "commit": "456ccf349ff1f452cebb8ee2071b358b53cbfc5d"
      },
      "digest": "633dea393ba2543831b5b6defab8111c28135f43f94408f3fe8f2e117731e81b"
    },
    {
      "id": "ship/flashyid/3e569704c269",
      "repo": "repo/flashyid",
      "at": "2026-08-19T18:23:02+00:00",
      "kind": "feature",
      "title": "Merge flashyid.com site (site/) — verifier, mega-nav, machine-readable layer",
      "by": [
        "agent/claude"
      ],
      "asserted": "2026-08-30",
      "assertedBy": "agent/flashyid-ci",
      "visibility": "public",
      "refs": {
        "commit": "3e569704c269a9bdceb4d2b14d0260a7cbedbef2"
      },
      "digest": "54509618b01ddd4d09accb9106255e1f18189cb31b5adf82ed3daa5fef362106"
    },
    {
      "id": "ship/flashyid/95d9f01d1418",
      "repo": "repo/flashyid",
      "at": "2026-08-18T21:27:33+00:00",
      "kind": "other",
      "title": "Flashy ID: OAuth 2.1 / OIDC identity provider for inter-organizational agent coordination",
      "by": [
        "agent/claude"
      ],
      "asserted": "2026-08-30",
      "assertedBy": "agent/flashyid-ci",
      "visibility": "public",
      "detail": "Initial implementation of ID-9 in the roadmap: a standalone Express +\noidc-provider service that lets a Flashy account holder sign in to a\nrelying organization (claimyour.gold, flashy.academy today) without\nthat organization ever holding a credential capable of impersonating\nthem. Authorization Code flow, PKCE required for every client,\nasymmetric (EdDSA) signing.\n\n- src/lib/provider.ts, src/lib/oidcMongoAdapter.ts: the oidc-provider\n  instance and a generic Mongo-backed Adapter implementation, one\n  collection per model with a TTL index so tokens/interactions/grants\n  self-expire.\n- src/lib/customerLookup.ts: read-only resolution of a Telegram id or\n  Customer id to OIDC claims against flashygoldams' Customer\n  collection. Deliberately never writes — see the module doc for why\n  a second writer of that collection is a bug class this estate has\n  already paid for once.\n- src/routes/interactions.ts: the login/consent pages. Sign-in is a\n  Telegram deep link (t.me/<bot>?start=flashyid_<uid>), not the\n  domain-bound Telegram Login Widget, because the widget's\n  BotFather-configured domain can't be shared across properties.\n  src/lib/redis.ts is the one-time handshake channel flashygoldams'\n  bot webhook writes the confirmed Telegram id to.\n- src/lib/manifest.ts: /llms.txt and /flashyid.json, shipped in the\n  first PR rather than bolted on later — implements ID-9's positioning\n  (infrastructure, not a consumer product; sibling to FlashyOS, not a\n  child of it).\n- src/scripts/seedClients.ts: registers claimyour-gold and\n  flashy-academy as first-party OIDC clients until ID-7 (dynamic\n  client registration) exists.\n\nNot yet done: refresh tokens, dynamic client registration, the\ngold:grant scope, and the relying-party side of the integration (a\nclaimyour.gold/flashy.academy route that actually starts this flow) —\nall called out inline where they'll plug in.",
      "refs": {
        "commit": "95d9f01d14184181b37c0ef2757e0949c45fcd53"
      },
      "digest": "9fd27f07e2830426a40c5bf8de600a433f37fb46010582d346f25bc02b0a9ed7"
    }
  ]
}
