feat(surface-client): expose write-attribution fields on Note/NoteSummary contracts - #195
Merged
Conversation
…mary contracts (0.3.5) The vault has carried write-attribution (createdBy/createdVia/lastUpdatedBy/ lastUpdatedVia, vault#298) on note responses for a while; surface-client's public Note/NoteSummary contracts didn't expose it. Adds all four as optional `string | null` on both types — strictly additive, legacy notes carry null. Reimplemented from the 2026-07-15 Hermes handoff spec (the reviewed commit a9c5c36 exists only on the Hermes host and was never pushed to origin, so this checkout cherry-picks nothing — verified field names/types directly against parachute-vault core/src/types.ts + notes.ts). Adds a compile-time-only contract fixture (src/__tests__/vault-types.contract.test.ts) plus a narrowly-scoped tsconfig.test.json (globs only *.contract.test.ts — the rest of __tests__ has pre-existing type debt never under tsc, deliberately not swept in) so tsc actually catches contract drift; wired into both the package's own typecheck script and the root typecheck:all. Stable patch bump per this repo's surface-ships-stable-patches convention (not rc) — 0.3.4 -> 0.3.5.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Adds
createdBy,createdVia,lastUpdatedBy,lastUpdatedViaas optionalstring | nullfields to the publicNoteandNoteSummarycontracts inpackages/surface-client. Strictly additive — every field is optional; legacy notes (predating attribution) carrynullon these fields, not a breaking absence.Why
The vault has carried write-attribution on note responses since vault#298, but
surface-client's public contracts never exposed it, so consuming surfaces had no typed way to read it. This unblocks the app'sProvenanceBadgework (track 2, A2).Semantics — factual only. These are provenance fields, not a semantic judgment:
*Byis the writing principal (JWTsub, operator, ortoken:<id>label),*Viais the interface the write arrived through (mcp,surface:<name>,agent:<id>,operator/cli,api).nullmeans unknown/pre-attribution, distinct from any real principal. Do not infer "human vs AI" from these fields — a surface that wants that distinction maps known principals to it separately, on top of this contract.Provenance note
Reimplemented from the 2026-07-15 Hermes-session handoff spec — the reviewed commit
a9c5c36exists only on the Hermes host's local clone (/root/Code/parachute) and was never pushed toorigin, so it doesn't exist in this checkout (verified: absent fromgit log --allandgit fsck --unreachable). Per the handoff note's own sanctioned fallback ("review/cherry-pick OR reimplement this narrowly"), this PR reimplements the four fields from the spec directly, with field names/types verified against the actual vault wire truth rather than the brief's memory of it —parachute-vault/core/src/types.ts:46-49andcore/src/notes.ts:2617-2620confirmcreatedBy?: string | nulletc., camelCase, exactly matching what's added here.Compile-time contract
Adds
packages/surface-client/src/__tests__/vault-types.contract.test.ts— a compile-time-only fixture (positive: fields as strings, asnull, and omitted entirely; negative:@ts-expect-erroron a wrong-typed value) that failstscif the barrel's exportedNote/NoteSummaryshapes drift. The package's owntsconfig.jsonexcludes__tests__from the build, andbun testalone doesn't typecheck (it transpiles, stripping types) — so this needed a newtsconfig.test.json, wired into both the package'stypecheckscript and the roottypecheck:all.That sibling config deliberately globs only
src/__tests__/*.contract.test.ts, not the whole__tests__directory: the rest of__tests__has never been undertscand carries pre-existing, unrelated type debt (stale.ts-extension imports needingallowImportingTsExtensions, a couple of drifted fixtures) that surfaced immediately when I tried the broader glob. Fixing that is out of scope for this narrow, additive change — flagging it as a follow-up rather than scope-creeping it in here.Versioning
Stable patch bump per this repo's convention (
docs/process/governance.mdrule 2 +RELEASING.md: "parachute-surface ships stable patch bumps, not rc") —0.3.4→0.3.5.src/version.tsregenerated viabun run gen-version;bun.locksynced. Package CHANGELOG updated (packages/surface-client/CHANGELOG.md).Gates (all run in full, no piping through tail/head)
packages/surface-clientbun run typecheck(tsc --noEmit && tsc -p tsconfig.test.json): clean, zero errors.bun run typecheck:all(surface-host, surface-client, account-client, surface-server, surface-render, notes-ui, pebble-config, doc-schema, docs-editor, meeting-ingest, meeting-mcp, web/admin): clean, zero errors.packages/surface-clientbun test src/: 302 pass, 0 fail (608expect()calls, 18 files — 17 pre-existing + the new contract fixture).bun run test: 1599 pass, 0 fail (94 files, bun-native packages) + notes-ui (vitest) 1140 passed (115 files) + surface-render (vitest) 61 passed (8 files).bun run build:surface-client: succeeds; verifieddist/vault-types.d.tscarries the four new fields and no test fixture leaked intodist/.bun run lint(biome, repo-wide): 26 errors, 8 warnings — identical before and after this diff (verified viagit stash/stash popagainst unmodifiedmain; none of the flagged files are ones this PR touches). Pre-existing debt, not introduced here.Compatibility
surface-client has real users — this change is additive-only. No existing field renamed, removed, or narrowed; no existing export removed from the barrel.