Skip to content

feat(layer-101): Content Verification System#26

Draft
slavazeph-coder wants to merge 8 commits into
mainfrom
claude/content-verification-system-zXAXz
Draft

feat(layer-101): Content Verification System#26
slavazeph-coder wants to merge 8 commits into
mainfrom
claude/content-verification-system-zXAXz

Conversation

@slavazeph-coder

Copy link
Copy Markdown
Owner

Summary

Layer 101 implements the chain-of-custody / humanity-signaling idea from the referenced Instagram post — flawless AI imagery is cheap, so the durable competitive edge is verifiable provenance + visible humanity.

Two pieces, both fully in-browser:

  • contentProvenance.js — ECDSA P-256 keypair via Web Crypto, persisted locally. signContent() issues a brainsnn-prov/1 manifest carrying the pub key + handle + an ordered chain of signed steps. appendEdit() chains a new edit step whose prevHash references the previous step's hash (lite-C2PA). verifyManifest() walks every step, re-derives its hash, verifies the signature, checks prevHash linkage, and confirms the latest payload hash matches. Plus a humanityScore() heuristic across cadence variance / candid markers / contractions / irregularities / AI boilerplate.
  • ContentProvenancePanel.jsx — Sign / Verify / Humanity / Log tabs. Identity card with handle + fingerprint, manifest copy-to-clipboard, recent-manifest log.

Wired into App.jsx and registered in layerCatalog.js. Notes added to MEMORY.md.

Test plan

  • npm run build — succeeds, no new warnings
  • Identity generation + sign + verify roundtrip
  • Tampered payload rejected with payload-tampered
  • 2-step chain verifies end-to-end
  • prevHash tamper rejected with chain-broken
  • Humanity score: AI-perfect prose → 0/100, candid prose → mid-tier
  • Manual UI smoke in dev server (Sign → Copy → Verify → Append edit)
  • Round-trip a manifest between two browser profiles

Notes

  • All key material stays in localStorage — exportable via Layer 57 (Data Portability) once the bundle export picks up the new keys
  • Verification gracefully reports subtle-unavailable on non-HTTPS hosts so the Humanity tab still works in those environments

Generated by Claude Code

claude added 8 commits May 2, 2026 02:19
…, humanity score

Implements ECDSA P-256 in-browser signing with a hash-linked chain of edit
steps (lite C2PA), plus a heuristic humanity score so creators can tell
whether a draft reads polished or unmistakably human. Inspired by the IG
post on cryptographic provenance for content in the AI era.

- contentProvenance.js: ensureIdentity / signContent / appendEdit /
  verifyManifest / humanityScore. SubtleCrypto-backed, FNV fallback for
  display-only environments. Manifest schema brainsnn-prov/1.
- ContentProvenancePanel.jsx: Sign / Verify / Humanity / Log tabs.
  Identity card with handle + fingerprint. Manifest copy-to-clipboard.

Smoke-tested: legitimate verify passes, tampered payload caught,
2-step chain verifies end-to-end, prevHash tamper caught.
…re modes

Cannibalized the loop pattern from context-labs/halo (not its Python code):
the harness watches itself via OpenTelemetry-shaped spans, clusters them
into named failure modes, and emits a structured fix-report a coding
agent can act on.

- telemetry.js: unified span buffer (cap 500). OTel schema with
  trace_id/span_id/parent_span_id/name/kind/status/attributes/events.
  Ring buffer + debounced localStorage mirror + pub/sub subscribers
  + withSpan() helper.
- harnessLift.js: generalizes Layer 27's n-gram lift miner into a
  pure mineLift({ records, features, isPositive }) primitive +
  mineSpansByOutcome() OTel-aware wrapper.
- harnessFailureModes.js: codifies The Brain's HALO-equivalent
  failure-mode taxonomy — error-burst, slow-scan, hung-mcp,
  dead-patterns, fp-heavy, refusal-loop. runDiagnostic() emits a
  harness-report-v1 envelope; renderReportText() flattens for
  paste-into-coding-agent.
- cognitiveFirewall.scoreContent() instrumented: emits a
  firewall.scan span on every call (lang, ruleset, pressure,
  evidence count, template count, text length). First instrumented
  call site; the rest of the harness wires up incrementally.
- HarnessDiagnosticPanel: live-reads spans via subscribe(), shows
  the report tier, per-finding hints, top operations p50, lift
  candidates. Copy-as-text and copy-as-JSON for handoff.

Smoke-tested: 16-span fixture surfaces error-burst + slow-scan +
dead-patterns at CRITICAL tier; 5-span healthy fixture shows 0
findings. Build succeeds; +13 kB to main chunk.
… tools

Closes the HALO-style autonomous loop: agents can now pull the harness
report and a candidate rule diff over the existing Layer 19 bridge.

- mcpBridge.handleToolCall(): every tool dispatch emits an mcp.tool
  span (ok/error) with tool name + arg keys.
- brainSteward.runTick(): each tick is now a steward.tick span with
  per-phase events (anomaly, narration) and propagates error status.
- harnessProposer.js: pure function turning a harness-report-v1 into
  rule-diff-v1 — additions[] derived from error-correlated lift
  candidates classified by manipulation vocabulary (urgency / outrage
  / fear / certainty), followUps[] mapping findings to next-layer
  actions (L31 evolve, L61 diagnostic, L66 coverage, L19 inspect,
  L21 pause).
- Two new MCP tools: get_harness_report({ format }) and
  propose_rule_diff({ topK }). Claude Code / Codex can now run the
  loop autonomously over the existing JSON-RPC bridge.

Smoke-tested: lift miner correctly identifies error-correlated phrases,
proposer emits a `\\bact\\s+now\\s+urgent\\b` urgency rule, followUps
include L21 pause-steward on error-burst.
…e + Replay

Four-layer stretch on top of the Layer 102 telemetry foundation,
closing the HALO loop end-to-end with operator feedback + before/after
measurement + scrubbable replay.

- Layer 103 — Auto-Apply Rule Steward
  autoSteward.js: poll runDiagnostic + proposeRuleDiff, filter to
  low-risk additions (lift / length / quota gates), apply via
  Layer 55 addCustomRule. Default dryRun + paused. Each cycle emits
  an auto-steward.cycle span. Reversible from the applied log.

- Layer 104 — Harness Comparator
  harnessComparator.js: compareReports → harness-diff-v1 envelope
  with findings split into added/removed/shifted, aggregates ranked
  by errorRate delta, tier shift labelled improved/regressed/unchanged.
  Snapshot store cap 20 in localStorage.

- Layer 105 — Span Annotation
  spanAnnotation.js: annotate({ spanId, label, note }) with five
  standard labels (false-positive / false-negative / real-bug /
  benign / investigate). decorateSpansWithAnnotations folds labels
  into attributes._annotation so the lift miner picks them up. New
  detector detectAnnotatedFalsePositives surfaces operator-flagged
  FPs as a first-class finding.

- Layer 106 — Trace Replay
  traceReplay.js: buildFrames buckets the buffer chronologically,
  rollForward computes cumulative per-name totals up to a cursor.
  Panel: scrubber, play/pause/step/reset, current-frame inspector,
  cumulative ladder.

Smoke-tested: 12-span healthy baseline → 2 false-positive annotations
→ re-diagnosis goes warn with new annotated-fp finding → comparator
labels REGRESSED with findings.added containing annotated-fp →
replay builds 12 frames across 56s window. Build clean, +27 kB to
main chunk. All four panels registered in App.jsx + layerCatalog.
Four more on top of Layer 102. Closes the HALO observability stack:
spans now have a path to a real collector, PII gets redacted on the
way out, the operator gets toasted when the tier shifts, and the tour
mirrors actual usage instead of static role steps.

- Layer 107 — OTLP HTTP Exporter
  otlpExporter.js maps the internal span schema → OTel ResourceSpans
  (hex-padded ids, ms→ns, typeAttrValue, kind enum, status code).
  Optional auth header, configurable service.name, dry-run for local
  inspection. Always pipes through Layer 108 sanitizer before egress.

- Layer 108 — Telemetry Sanitizer
  telemetrySanitizer.js: 6 standard PII patterns (email / phone /
  IPv4 / SSN-like / credit-card / bearer-token) + custom regex with
  compile validation. sanitizeSpan walks attributes, event attrs,
  status.message. piiAuditSummary nudges users when the buffer
  contains PII.

- Layer 109 — Harness Alerts
  harnessAlerts.js: subscribes to telemetry, debounces 4s, runs the
  diagnostic, toasts new findings (severity-tinted) and tier shifts
  (red on regression / info on recovery). Off by default.

- Layer 110 — Trace-Driven Tour
  traceDrivenTour.js: deriveTour reads aggregate-by-name buckets,
  walks a 7-step recipe library whose `when` predicates check the
  usage context, emits a tour-v1 envelope. Replaces Layer 94's
  static role tour with one derived from what you actually do.

Smoke: PII audit catches email + 2× phone + IPv4 in seeded spans.
OTLP payload assembles 9 spans with correct OTel envelope. Tour
produces 3 steps reflecting "scan-heavy + steward usage". Build
clean, +21 kB to main chunk.
… MCP Usage

Round 3 on top of Layer 102. Power-user observability + a fix for a
small telemetry bug found while smoke-testing.

- Layer 111 — Span Distribution
  spanDistribution.js: log-scale 9-bucket duration histogram +
  p50/p90/p95/p99 per span name. Catches the slow tail outliers that
  aggregate p50/p95 alone hide.

- Layer 112 — Trace Search
  traceSearch.js: parseQuery tokenizes a mini DSL —
  `name=foo status=error duration>200`. Operators =/!=/>/</>=/<=,
  bare words become free-text matches over name + JSON-stringified
  attrs.

- Layer 113 — Diagnostic Snapshots
  diagnosticSnapshots.js: subscribes to telemetry, debounces, calls
  Layer 104 saveSnapshot whenever the harness tier changes. Keeps a
  longitudinal timeline so "when did we go critical?" has a real
  answer. Auto-snaps tagged for clean prune.

- Layer 114 — MCP Tool Usage
  mcpToolUsage.js: cross-references BRAIN_TOOLS against mcp.tool
  spans. Hot (top by count) / Slow (top by p95) / Flaky (top by
  errorRate) / Dead (registered, never called). MCP-side cousin of
  Layer 102's dead-pattern detector.

Bug fix: telemetry.recordSpan was only computing duration_ms when
end_time was auto-filled, leaving callers who set end_time explicitly
with null durations. Distribution + search rely on it.

Smoke: 20-span fixture with 4 slow scans → distribution histogram
[15 ≤10ms, 5 ≤500ms, p95=350ms]. Search query `name=firewall.scan
duration>100` returns exactly the 5 slow ones. MCP usage groups
scan_content×4 / get_brain_state×4 with correct error count + p95.
The IG post argues simple beats overwhelming. App.jsx was rendering 167
panels in one scroll column. Now there's a two-tab top bar:

- Home  : just the 3D brain + scenario metrics + a single quick-action
          card pointing at the firewall and the Layer Explorer.
- All   : current behavior, every panel.

Power-user navigation already exists (⌘K command palette · Layer
Explorer · Role Tour · Trace-Driven Tour). Home mode persists in
localStorage so the first-paint stays clean across reloads.

Surgical change: just the conditional `{viewMode === 'all' && (<>…</>)}`
wrap around the existing panel column, plus two tiny inline components
(ViewModeTabs, HomeQuickActions) and ~50 lines of CSS. No panels moved,
no panels deleted.
…scan

The Home view was a static "go to All" card. Now it does the most
common thing in-place: paste text, click Quick scan, see pressure
tier + templates. No navigation needed.

Adds two focused workflows to the existing Home / All split:

- Scan      : CognitiveFirewall + Coverage + Tone Shifter + Context
              Memory + Scan Archive + Content Provenance — paste,
              score, see which pattern fired, archive, sign.
- Diagnose  : Layer 102–114 stack — diagnostic, alerts, auto-steward,
              comparator, snapshots, distribution, search, MCP usage,
              annotation, replay, OTLP exporter, sanitizer.

Each focused deck renders existing panel components inline; only one
viewMode mounts at a time so there's no double-render. The All tab
stays the escape hatch for the 110+ panel surface.

HomeDeck additions: inline scan textarea + Quick scan button →
shows manipulation pressure tier (Calm / Tilted / High pressure)
with template chips and recommended action. Immunity score +
streak as a side card. Quick-jump buttons to focused workflows.

Bundle: CSS +0.3 kB, JS +3 kB. Build clean.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants