Description
TIP Protocol is the WordPress plugin for content provenance, AI disclosure, and verified publisher identity. Sign every post with a cryptographic publisher key, label whether each piece was written by a human or with AI assistance, and let readers verify it all from any browser without installing an extension.
The plugin gives news outlets, blogs, marketing teams, academic publishers, and individual creators a practical way to answer the two questions readers and search engines increasingly demand: who actually published this, and how was it made? Every signed article carries a verifiable origin label (Original Human, AI-Assisted, AI-Generated, or Mixed), a post-quantum cryptographic signature, and a permanent record on the open TIP network.
If you have looked at Content Credentials, C2PA, or browser-based provenance extensions and wished there was a self-contained workflow inside WordPress, TIP Protocol is that workflow.
Why publishers and creators use TIP Protocol
- Verifiable AI content labels. Tag every post as Original Human (OH), AI-Assisted (AA), AI-Generated (AG), or Mixed (MX). The label is cryptographically signed, so it is not a self-claim that anyone can copy. Readers, search engines, and automated verifiers can all confirm it.
- Cryptographic publisher identity. A site-level TIP-ID and optional per-author TIP-IDs sign your content with post-quantum ML-DSA-65 signatures (FIPS 204). Readers see a verified trust badge; verifiers see a tamper-proof signature trail back to your domain.
- No browser extension required. Reader-facing verification works in any modern browser through HTTP response headers, HTML meta tags, JSON-LD provenance, and an accessible bundled
<tip-badge>web component. Your audience does not need to install anything. - Plays nicely with your SEO stack. When Yoast SEO or Rank Math is active, TIP Protocol merges provenance into the existing JSON-LD graph instead of competing with it. No duplicate schema, no conflicting article markup.
- Versioned and correction-aware. Each registration is versioned. An article that gets corrected, updated, or expanded later still resolves to a clean provenance trail with a clear change history.
- Encrypted-at-rest identities. Private signing keys never leave WordPress. They are AES-256-GCM encrypted with PBKDF2-derived keys using WordPress salts as input, and the admin UI never echoes them back to the browser.
- Open, free, and global. The TIP Protocol specification is open. The plugin is GPL-2.0-or-later. The workflow is the same whether you publish from Tokyo, Berlin, Sao Paulo, Lagos, Mumbai, or New York.
Who is this for
- News publishers and editorial teams that need verifiable authorship and AI-disclosure signals on every article.
- Independent bloggers and content creators who want to prove their work is genuine and protect against impersonation.
- Marketing, brand, and communications teams that have integrated AI into their content workflow and want to be transparent about how each piece was produced.
- Academic publishers, research organizations, and institutional websites that need an auditable provenance trail per article.
- Government, nonprofit, and public-interest websites where verified authorship and tamper evidence matter.
- Multi-author publications that need per-byline TIP-IDs alongside a single verified publisher identity.
- Publishers preparing for AI transparency expectations from regulators, search platforms, and discerning readers.
Key capabilities
- Register posts, pages, news items, events, products, and other public editor-supported content types on the TIP network with one click.
- Emit TIP verification response headers and provenance meta tags from WordPress on every public page.
- Enrich article JSON-LD schema with provenance fields, with smart handoff to Yoast SEO and Rank Math when they already manage the site schema graph.
- Render accessible verification badges with a bundled local web component so no third-party CDN is required by default.
- Manage publisher and creator TIP identities with encrypted private keys stored inside WordPress.
- Import reviewed publisher TIP-IDs from The AI Lab, or per-author creator TIP-IDs exported from vp.theailab.org, through the built-in
.tip.jsonconnection flow with optional DOB-based key unlock. - Domain binding via
.well-known/tip-protocol.jsonor DNS TXT records so the network can confirm a publisher legitimately claims a domain. - Multi-author byline rosters with per-author roles (reporter, editor, photographer, columnist, guest, contributor) and optional per-author co-signatures.
- Audit log of registrations with CTID, change type, version history, signing officer roster, and registration status visible inside the admin.
- GDPR-friendly. Integrates with WordPress personal data export and erasure tooling.
- Optional WebAuthn biometric step-up for personal-mode signing. Opt-in per writer, never a barrier.
How TIP Protocol differs from other provenance systems
TIP Protocol is built for the publishing surface that already exists in WordPress, not for the camera-to-cloud capture flow that systems like C2PA Content Credentials were designed around. Where C2PA focuses on signing images and videos at the moment of capture, TIP Protocol focuses on signing the final published article (text, media manifest, author roster, origin label) at the moment a publisher hits Publish in WordPress. Both approaches can coexist; TIP Protocol fills the editorial gap.
Legal
This plugin is distributed under GPL-2.0-or-later.
Bundled legal and notice files:
* LICENSE.txt for the GPL software license notice
* NOTICE.txt for the bundle notice summary shown in the admin UI
* PATENTS.txt for informational patent disclosure
* TRADEMARKS.txt for informational trademark notice
Plugin attribution is optional and can be enabled in settings.
Accessibility
TIP Protocol includes keyboard-accessible verification badges, focus-visible controls, descriptive editor help text, semantic public trust UI, and screen-reader-friendly verification details. The public badge details panel supports keyboard open/close behavior and Escape to dismiss.
External services
This plugin connects to external TIP services to deliver its core provenance features.
TIP node API
The plugin sends registration, verification, and trust-score requests to the configured TIP node endpoint.
Data sent:
* publisher or creator TIP-ID
* content registration payloads
* canonical, exact, and perceptual hashes
* content signatures
* verification lookups for trust scores
Service provider: The AI Lab Intelligence Unobscured, Inc.
Service URLs: https://node.theailab.org by default, or your configured TIP node URL
Service purpose: content registration, provenance verification, trust score retrieval
Optional badge CDN
If you switch the badge delivery mode from Bundled local copy to CDN, reader browsers will load the public badge script from the TIP badge CDN.
Data sent:
* standard browser request metadata needed to fetch the script
Service provider: The AI Lab Intelligence Unobscured, Inc.
Service URL: https://badge.theailab.org
Service purpose: optional remote delivery of the TIP badge web component
Privacy
TIP Protocol adds suggested privacy-policy text in WordPress and integrates with WordPress personal data export and erasure tools for stored user TIP identity data.
Blocks
This plugin provides 1 block.
- TIP Verification Badge
Installation
- Upload the plugin folder to
/wp-content/plugins/. - Activate the plugin in WordPress.
- Open
TIP Protocolin the WordPress admin menu. - Import a reviewed
.tip.jsonpackage for a publisher TIP-ID or creator TIP-ID. - Verify your domain and review the publishing defaults.
- Publish content and confirm the TIP badge, headers, and provenance metadata on the front end.
FAQ
-
What is TIP Protocol and what does the plugin do?
-
TIP Protocol (Trust Identity Protocol) is an open content-provenance specification. The WordPress plugin lets publishers and creators sign their published content with a cryptographic identity, label whether AI was used to write it, and surface a verifiable trust badge to readers. It works as an editorial layer on top of WordPress without requiring a browser extension.
-
How does TIP Protocol handle AI-generated content?
-
Every post can carry one of four origin labels: Original Human (OH), AI-Assisted (AA), AI-Generated (AG), or Mixed (MX). The label is part of the cryptographically signed payload, so it cannot be modified after publication without invalidating the signature. Readers and verifiers see a verified AI-disclosure label, not a self-claim.
-
Does TIP Protocol replace C2PA or Content Credentials?
-
No. They solve adjacent problems. C2PA and Content Credentials focus on signing images and video at capture time, typically inside a camera or generative tool. TIP Protocol focuses on signing the final published article (text, media manifest, author roster, AI label) at the moment a publisher hits Publish in WordPress. They can coexist on the same site.
-
What is a TIP-ID?
-
A TIP-ID is a unique cryptographic identifier in the format
tip://id/REGION-xxxxxxxxxxxxxxxx. Publishers receive a reviewed publisher TIP-ID from The AI Lab. Individual writers can generate a personal creator TIP-ID on vp.theailab.org. Both types are imported into WordPress as a signed.tip.jsonpackage. -
Where do editors set the AI / origin label?
-
In the block editor, open the post sidebar and use the TIP Protocol panel. In the classic editor, use the TIP Origin Declaration metabox. Each writer can also opt in to a biometric step-up (WebAuthn) before signing with their personal Author TIP-ID.
-
Yes. A site can carry a single verified publisher TIP-ID for the organization, plus per-writer creator TIP-IDs for individual bylines. The plugin supports byline ordering, multiple co-authors per post, role tagging (reporter, editor, photographer, columnist, guest, contributor), and optional per-author co-signatures.
-
Does this work with WooCommerce, multisite, custom post types, and page builders?
-
Yes. TIP Protocol registers any public editor-supported content type, which includes WooCommerce products, custom post types, news/event types, and pages built with Elementor, Beaver Builder, Bricks, and similar tools. Multisite installations are supported.
-
Does the plugin add duplicate SEO schema if I already use Yoast SEO or Rank Math?
-
No. TIP Protocol detects active major SEO plugins. When Yoast SEO or Rank Math is present, TIP Protocol merges TIP provenance into their existing JSON-LD graph instead of emitting a competing article-schema block. When neither is active, TIP Protocol emits its own complete provenance-enriched article schema.
-
Does the public verification badge require a third-party CDN?
-
No. The badge ships as a bundled local web component by default. A CDN option is available in plugin settings if you explicitly choose it, but the default works fully offline and respects strict CSP environments.
-
What happens to private signing keys stored in WordPress?
-
Private keys are encrypted at rest with AES-256-GCM. The key-derivation input includes WordPress salts plus a PBKDF2 stretch (200,000 iterations of SHA-256). The admin UI never exposes the stored encrypted private key back to the browser. Decryption only happens server-side at the moment of signing.
-
What file should I import into WordPress to connect an identity?
-
A reviewed
.tip.jsonpackage that containstip_id,public_key,private_key,algorithm,region,created_at, and (for organizational identities)vp_id. Publisher packages come from The AI Lab after organization review. Personal creator packages are exported from vp.theailab.org and can be DOB-locked for additional protection. -
Is this plugin free and open source?
-
Yes. The plugin is licensed under GPL-2.0-or-later. The TIP Protocol specification is open. The plugin can be used commercially on any number of sites.
-
Where is the TIP network and where does my data go?
-
By default the plugin talks to the TIP node at
https://node.theailab.orgfor registration and verification calls. You can configure a different node URL in plugin settings if you operate a self-hosted TIP node. Content registration sends the canonical hash, signature, origin label, and author metadata, not the full article body. -
Will TIP Protocol slow down my site?
-
No. Reader-facing badges use a small bundled web component (about 8 KB), all provenance meta is emitted server-side as HTTP headers and HTML meta tags during the normal page render, and verification lookups for trust scores are cached. There is no extra browser fetch on every page load.
Reviews
There are no reviews for this plugin.
Contributors & Developers
“TIP Protocol” is open source software. The following people have contributed to this plugin.
ContributorsTranslate “TIP Protocol” into your language.
Interested in development?
Browse the code, check out the SVN repository, or subscribe to the development log by RSS.
Changelog
2.1.6
- Plugin-directory listing: complete readme rewrite to improve discoverability on WordPress.org search and external search engines. Sharper short description, new “Why publishers and creators use TIP Protocol” value-prop block, new “Who is this for” industry-targeting block, expanded FAQ with high-volume questions (AI-generated content handling, C2PA / Content Credentials comparison, multi-author and multisite workflows, security model, network endpoints), updated tag list (ai disclosure, content provenance, content authenticity, trust badge, publisher). No code changes.
- Removed the local-development / Docker section from the user-facing readme. That content now lives only in the repository docs where it belongs; it was diluting the SEO signal of the public plugin page and listed local-development credentials that should not appear on a public listing.
2.1.5
- Security: Restructured the byline metabox nonce check (admin/class-tip-metabox.php) into the canonical isset wp_verify_nonce current_user_can sequence, with each gate an independent early-return so the conditional logic cannot be bypassed. Sanitized $_POST input at the boundary with explicit wp_unslash + is_array check before the per-entry sanitize_text_field loop.
- Security: Sanitized every $_SERVER access. includes/class-tip-webauthn.php and includes/class-tip-visitor-context.php now apply sanitize_text_field( wp_unslash( … ) ) in a single expression so the WordPress coding-standard analyser sees the sanitization chain, and the phpcs:ignore comments that previously masked these reads have been removed.
- Security: Rewrote the legacy-slug admin redirect (admin/class-tip-admin.php redirect_legacy_menu_slug) to use an explicit allow-list of forwardable query params (tab, section, paged), each sanitized via sanitize_text_field and rawurlencoded before reaching add_query_arg. The previous raw $query_args = $_GET assignment is replaced. Capability check moved above all $_GET access so unauthorized requests never touch the superglobal.
- Security: Added a defence-in-depth current_user_can( theailab_set_origin ) gate to Theailab_Admin::build_editor_state() before reading $_GET[‘post’]; absint() now wraps the post-ID lookup explicitly.
- Prefix uniqueness: Removed the legacy un-prefixed shortcode registrations ([tip-badge], [download_button]) and the legacy register_block_type call for tip/verification-badge. Replaced the alias approach with a the_content filter (Theailab_Public::rewrite_legacy_tokens) that rewrites legacy tokens to their prefixed names at render time, so existing post content authored against earlier versions keeps rendering after upgrade. Updated the Gutenberg JS to register theailab/verification-badge, theailab-origin-panel, and theailab-pre-publish-check (previously tip/verification-badge, tip-origin-panel, tip-pre-publish-check).
- No functional changes for end users.
2.1.4
- Compatibility: Bump “Tested up to” header to 7.0 (current WordPress release). No code changes; the WordPress.org automated scanner blocks uploads whose declared compatibility falls below the latest WP version, and this metadata bump unblocks the resubmission of the 2.1.3 prefix-uniqueness fixes.
2.1.3
- Compliance: Address WordPress.org Plugin Directory review feedback on prefix uniqueness. Three PHP-level identifiers carried short or generic prefixes that could collide with other plugins:
- Bootstrap function
tip_protocol()renamed totheailab_tip_bootstrap(). A guarded backward-compat alias preserves the old name for any third-party code or theme snippet that referenced it. - Gutenberg block namespace
tip/verification-badgerenamed totheailab/verification-badge. The legacy block name is also re-registered as an alias so existing post content that embeds the old block continues to render unchanged. - Admin menu slug
tip-protocol(previously routed to admin.php?page=tip-protocol) was already moved totheailabin an earlier release; this version adds a 301 redirect from the legacy URL to the new one so bookmarked admin URLs keep working. - Shortcodes
[tip-badge]and[download_button]continue to render via backward-compat aliases registered alongside the canonical[theailab-tip-badge]and[theailab_download_button]names.
- Bootstrap function
- No functional changes for end users. Existing content keeps working; the renames are purely to satisfy the WordPress.org plugin uniqueness rule.
- Bump version forces a cache-buster URL refresh.
2.1.2
- UI fix: The scope picker dropdown clipped the descenders of “publishers” because the wp-components SelectControl forced a fixed height that conflicted with the picker’s padding. Replaced the height constraint with
height: auto, increased line-height to 1.5, switched to a custom-drawn navy chevron with explicit right-padding so the option text isn’t crowded, and bumped vertical padding to 12px. The dropdown now renders the full option text cleanly at any zoom level. - Sign reliability: Added a server-side self-verification step right after each ML-DSA signature is produced and before the registration request is sent to the TIP node. If the stored public key doesn’t correspond to the private key the plugin just signed with — most often because a personal Author ID was imported with a derived (not original) public key — the user gets a precise local error pointing at the cause and remediation, instead of the opaque “Content signature verification failed” the node returns.
- Sign reliability: The registration payload sent to the TIP node now includes the
public_keyfield. Without it, the node had to look up the TIP-ID’s public key on the DAG to verify, which fails for newly-imported personal Author IDs that haven’t been published to the network yet. Including the key gives the node a deterministic verification path; the node should still cross-check this against its DAG record when one exists. - Sign reliability: When the TIP node rejects a registration with a “signature verification” error AND the local self-verify passed, the editor now surfaces a guided message explaining that the TIP-ID likely isn’t yet published to the TIP DAG (and pointing the user at vp.theailab.org), instead of relaying the raw node error verbatim.
- Bump version forces a cache-buster URL refresh.
2.1.1
- UI: The “What kind of identity is this?” dropdown on the Connect-an-Identity card was easy to overlook even though it controls the most important decision in the import flow (publisher vs. personal). Wrapped it in a high-contrast picker with a colored border, gradient background, “REQUIRED” tag, large icon (🏢 / 👤), and a prominent uppercase label. The picker color-shifts to blue when “Site identity” is selected and green when “Personal Author ID” is selected, so the user gets instant visual confirmation that their choice registered.
- Bump version forces a cache-buster URL refresh.
2.1.0
- Feature: Optional WebAuthn / biometric step-up for personal-mode signing. Writers who choose to can now require a fingerprint, Face ID, Windows Hello, or hardware security-key tap before each post is signed with their personal Author TIP-ID. Configured per-user in WordPress profile, defaults OFF for everyone, and is never a barrier — publisher-mode signing, scheduled posts, WP-CLI, REST automation, and cron-driven workflows always bypass step-up. If a user enables the toggle but has no enrolled key, signing still proceeds; if they remove their last key, the toggle auto-disables.
- New REST surface under /theailab/v1/webauthn/ (status, register/begin, register/complete, auth/begin, auth/complete, required, credentials/remove). All routes are nonce-protected and operate only on the calling user’s row.
- Server-side verifier uses native PHP openssl_verify() with public keys exported directly from the browser via AuthenticatorAttestationResponse.getPublicKey() — no third-party dependency, no CBOR parser, supports ES256 and RS256 algorithms, enforces userVerified flag and signCount monotonic check.
- Editor integration: Both classic and Gutenberg editors detect a 428 Precondition-Required response from /origin/register, run the WebAuthn assertion ceremony, and retry with the resulting single-use ticket. Errors are surfaced via the existing inline-status banner with clear remediation guidance.
- Security audit: WebAuthn step-up is a defense-in-depth layer over the existing capability/nonce model — it gates the API call but does not replace any existing check, and the actual content signature remains ML-DSA-65 over the canonical hash, server-side, exactly as before.
2.0.11
- Fix: When the TIP node returned a structured error response (e.g.
{"error":{"message":"…"}}), the plugin’s API client cast the nested object to a string and surfaced the literal word “Array” in the editor — users saw “Couldn’t sign this post / Array” with no actual reason. The client now walks the common shapes (erroras string or{message,detail,description,code,reason,details[]}, top-levelmessage, pluralerrors[]) and falls back to a short raw body snippet or a status-code message, so the real reason from the node always reaches the user. - Bump version forces a cache-buster URL refresh.
2.0.10
- Fix: Personal Author IDs exported from vp.theailab.org (DOB-locked
tip-key-export-v2files) failed to import withTIP-PKG-2 packages must declare vp_id.. Personal identities are self-claimed and never carry a publisher review, so the importer no longer requiresvp_idfortip_id_type === "personal". Publisher and platform identities continue to require a well-formedvp_id, and personal exports that do include one are still validated againstTHEAILAB_VP_ID_REGEX. - Bump version forces a cache-buster URL refresh.
2.0.9
- Apply the v2.0.8 inline status banner pattern to every action button across the admin UI: Connect identity, Inspect article, Verify domain (HTTP / DNS), Save settings (Network / Publishing defaults), Add/Save writer to editorial team, Refresh roster, classic-editor “Register Content as …” button, and the Gutenberg sidebar Sign button. Errors and successes now appear as prominent red / green banners with icon + title + detail, immediately at the click site, instead of as small notices at the top of cards the user has scrolled past.
- New reusable
InlineStatusReact component centralizes the banner so all panels share one look and one set of accessibility semantics (role="alert"for errors witharia-live="assertive",role="status"for successes witharia-live="polite"). - Classic-editor metabox: status banner moved from below the Register button to above it (the user’s eye is on the button), and upgraded from plain text to the same banner style.
- Bump version forces a cache-buster URL refresh.
2.0.8
- Fix two issues that surfaced after the v2.0.7 DOB-unlock improvements: (1) the synthetic post-unlock package shipped with
package_version: "tip-key-export-v2-unlocked", which the importer rejected withUnsupported .tip.json package_version. Synthetic packages now use the canonicalTIP-PKG-2version string. (2) The import error notice rendered as a small banner at the top of the import card, far from the Connect button the user just clicked, so it was easy to miss. The error / success message now renders as a prominent red (or green) banner immediately above the Connect button with an icon, title, and dismiss button. - Bump version forces a cache-buster URL refresh.
2.0.7
- Fix import for
.tip.jsonfiles wherepublicKeyis empty in the clear (a known property of vp.theailab.org’stip-key-export-v2exports when the user’s record had no stored public key at export time). The server-side/identity/importendpoint now derives the public key from the private key via the bundledbin/tip-ml-dsa.mjshelper (action: derive-public) before passing the package to the key manager. The derived key is injected at top-levelpublic_keyand intoidentity.public_key(mirroring the original path) so downstream parsing succeeds whether the importer reads from one or the other. - Loosen the client-side dropzone parser to accept files with an empty public_key value as long as a private_key is present. The Connect button is no longer disabled by this condition; the server completes the derivation during import.
- Bump version forces a cache-buster URL refresh.
2.0.6
- Fix DOB unlock for
tip-key-export-v2files. After reading the actual producer code at vp.theailab.org (settings.html+src/crypto.js), the format is now pinned exactly: byte layout[salt:16][iv:12][ct+gcm-tag], PBKDF2-SHA-256 with 200,000 iterations, AES-256-GCM, password is the user’s date of birth normalized to 8 digits inMMDDYYYYorder, and the plaintext is the raw private-key hex string (not a JSON wrapper). Previous fallback-by-trying-many-layouts code is replaced with this single deterministic decryption. Wrong DOB now produces a clear “That date of birth doesn’t unlock this file” message. - Replace the
<input type="date">(which forced YYYY-MM-DD) with a<input type="text" placeholder="MM/DD/YYYY">that auto-inserts slashes as the user types — same behavior as the producer’s input field. The Unlock button stays disabled until exactly 8 digits are entered. - Decrypted private-key hex is wrapped in a synthetic parser-friendly package using the
tip_idandpublicKeyfields from the outer file; the existing parser then takes over and unlocks the Connect button as it would for any.tip.jsonfile. - Gutenberg sidebar: panel renamed from “TIP Origin” to “TIP Protocol”. Field label changed from “Origin code” to “How was this written? Human or AI”. Option labels (
OH - Original Human / AA - AI-Assisted / AG - AI-Generated / MX - Mixed) and the Register button label remain unchanged. The “Next update type” field is moved into a collapsible “Advanced options” disclosure (collapsed by default) so writers see only the question that matters. - Bump version forces a cache-buster URL refresh.
2.0.5
- Add support for the new
tip-key-export-v2personal Author ID file format from vp.theailab.org. These files are encrypted with the user’s date of birth using PBKDF2 (SHA-256, 200,000 iterations) + AES-256-GCM. The plugin now detects the locked format, shows a dedicated “This file is locked” card with a date-of-birth input, decrypts the file client-side via Web Crypto API, and hands the unwrapped public_key + private_key to the existing import flow. The DOB never leaves the browser. Site identity files (publishers) continue to use the existing flat /identity.*format with no DOB step. - Replace the muted yellow warning notice with a prominent RED error banner for hard parse failures (invalid JSON, missing required fields, encrypted blob without unlock support). The error appears immediately under the dropzone with a red icon, red title, and the diagnostic detail.
- Bump version forces a cache-buster URL refresh.
2.0.4
- Connect button stayed disabled because the .tip.json parser only checked 6 hard-coded paths for the public key and private key. Expanded the parser to recognize 21 paths each (top-level snake/camel/lowercase variants,
identity.*,keys.*,data.*,key_package.*wrappers). Now handles TIP-PKG-1, TIP-PKG-2, vp.theailab.org exports, AI-Lab-issued packages, and reasonable variants of all of the above. - When a required field is missing, the error message now lists the fields the parser actually detected in the file, instead of just saying “field X missing”. This makes it possible to diagnose schema mismatches without opening DevTools.
- Bump version forces a cache-buster URL refresh.
2.0.3
- Fix Connect button not working after .tip.json upload. The double-prompt confirmation modal was using
wp.components.Modal, which can render as undefined in certain wp-components versions and prevent the entire panel from re-rendering. Replaced with a self-contained<div>overlay using pure CSS (no wp-components dependency), so the modal always renders regardless of host WordPress version. - The modal still supports clicking the backdrop to dismiss, an explicit close button, ARIA dialog semantics, and the same content (file name, detected Author ID, identity type, scope-mismatch warning).
- Bump version forces a cache-buster URL refresh.
2.0.2
- Fix REST nonce parameter mismatch that broke every nonce-protected admin call (identity import, identity remove, contributor CRUD, byline save, origin save, “Register Content” button, settings save, domain verify). The PHP validator was renamed to read
theailab_noncein v1.5.0 but the JavaScript continued to sendtip_nonce. Renamed the parameter on the JS side inadmin/js/tip-admin.js,admin/js/tip-gutenberg.js, andadmin/js/tip-origin-classic.js. - Add
tests/test-rest-nonce-consistency.php(10 assertions) so this regression cannot recur silently. Test suite is now 344 assertions across 11 standalone files. - Add a double-prompt confirmation modal before the .tip.json import API call fires. The modal shows the file name, the detected Author ID and identity type from the file, the scope the user selected (Site identity vs Personal Author ID), and a plain-language explanation of what each scope does. When the file’s identity type does not match the chosen scope (e.g., a personal-typed file imported as a site identity, or a publisher-typed file imported as personal), the modal displays a warning notice explaining what the mismatch will do. The user must explicitly confirm before the import proceeds.
- Bump version (also forces cache-buster URL refresh for any browsers still holding the broken 2.0.1 JS).
2.0.1
- Address WordPress.org plugin review feedback on prefix uniqueness:
- Remove legacy unprefixed shortcode aliases
[tip-badge]and[download_button]. The canonical shortcodes[theailab-tip-badge]and[theailab_download_button]continue to work. - Rename admin menu slug from
tip-protocoltotheailab(admin URL is nowwp-admin/admin.php?page=theailab). - Rename the screen-hook check accordingly.
- Rename WordPress script and style handles from
tip-protocol-*totheailab-*(theailab-admin,theailab-editor,theailab-origin-classic,theailab-gutenberg,theailab-public,theailab-badge). - Rename Privacy Exporter / Eraser registration key from
tip-protocol-identitytotheailab-identity. - Rename admin app DOM root id from
tip-protocol-admin-roottotheailab-admin-root. - Rename classic-editor metabox ID, form-field IDs, and
nameattributes fromtip-origin-*andtip_origin_*totheailab-origin-*andtheailab_origin_*.
- Remove legacy unprefixed shortcode aliases
- Verify all REST permission_callbacks use
current_user_can()with prefixed custom capabilities (theailab_manage_settings,theailab_register_content,theailab_set_origin,theailab_view_dashboard). - No functional changes: the protocol, signing, byline picker, contributor registry, and CNA-2.2 wire format are unchanged.
2.0.0
- Add Contributor Registry: an org-scoped registry of personal TIP-IDs (journalists, editors, photographers, freelancers) under a publisher / platform identity. Manage from Settings Contributors. Each contributor record carries a TIP-ID, display name, role, optional WordPress user link, key-custody mode (attribution-only or self-signing), and optional public key.
- Add per-post byline picker: a new section in the classic-editor metabox and the Gutenberg sidebar lets editors choose a primary author plus optional co-authors from the contributor registry. The selection is persisted as ordered post meta
_theailab_author_tip_ids. - Auto-fill the byline from the WordPress post-author when that user has a contributor-registry mapping. Editors can override.
- Bump canonical normalization to CNA-2.2: the publisher-signed payload now carries an ordered
authors[]array (primary at index 0) with per-authorkey_modeandsignedflags. Solo-author posts and authorless hosted content remain supported. - Add CNA-2.2 crypto helpers:
build_cna_2_2_payload(),sign_publisher_v3(),verify_publisher_v3(),sign_co_signer(),verify_co_signer(). CNA-2.1 verification preserved for backward compatibility (THEAILAB_CNA_VERSION_PREVIOUS). - Add
co_signatures[]collection: when a contributor is in self-signing mode, the registrar records a pending co-signature placeholder so the node can ingest the contributor’s own ML-DSA-65 signature out-of-band. - Add REST routes:
GET/POST /theailab/v1/contributors— list or add a contributorPATCH/DELETE /theailab/v1/contributors/{tip_id}— update or removeGET/POST /theailab/v1/post-authors/{post_id}— read or set the byline
- Extend public output: schema.org JSON-LD
authorbecomes an array of Person objects when multiple authors are bound; new meta tagstip:co-authorsandtip:authors-count. - Add new tests:
test-contributor-registry.php(55 assertions),test-cna-2-2-payload.php(10 assertions covering canonical determinism + alphabetical key ordering withauthors[]). - Register
_theailab_author_tip_idspost meta with REST schema so the Gutenberg sidebar can read/write it throughcore/editor. - Storage: new option
theailab_contributors(autoload no), new user metatheailab_contributor_tip_id(back-pointer for fast WP-user contributor lookup).
1.5.0
- Rename all plugin-internal identifiers from
tip_/TIP_totheailab_/THEAILAB_to comply with WordPress.org plugin guideline on prefix uniqueness (4+ char distinct prefix). Affects classes, constants, functions, options, capabilities, post meta keys, user meta keys, cron events, transients, REST namespace, and database tables. - Add automatic one-time migration in the activator: copies legacy
tip_*options, capabilities, post meta, user meta to the newtheailab_*keys; renameswp_tip_contentwp_theailab_contentandwp_tip_transactionswp_theailab_transactions; unschedules legacy cron events. - Register backward-compatible shortcode aliases:
[tip-badge]continues to render alongside the new canonical[theailab-tip-badge]. - Sanitize
$_SERVERreads withsanitize_text_fieldimmediately afterwp_unslashto satisfy the WordPress coding standard’s “sanitize early” rule for superglobals. - Rename
WP_Errorcodes from the legacy prefix to the canonical prefix. - Preserve TIP Protocol JSON wire-format field names (
tip_id,tip_id_type,tip_ids,tip_key) which are protocol-spec values defined in the patent and not plugin-internal identifiers.
1.4.0
- Add typed identity taxonomy (
personal,publisher,platform) with reserved values for future Phase 2 release - Add relational
attribution_modefield (self,employed,hosted) carried in CNA-2.1 canonical content payload - Add Signing Officer roster awareness with central genesis-node policy (
disabled/optional/required); Phase 1 default isoptionalso manual publisher onboarding works without a roster - Add per-post
edit_post/read_postpermission checks to/tip/v1/register,/update,/status,/origin/save,/origin/register - Move temporary crypto scratch files from
get_temp_dir()towp-content/uploads/tip-protocol-private/with.htaccess,web.config, andindex.phpdeny files plus chmod 0600/0700 - Drop
JSON_UNESCAPED_SLASHESfromapplication/tip+jsonandapplication/ld+jsonscript-tag output to prevent</script>break-out - Fix vendored
@noble/post-quantumML-DSA-65 imports so the post-quantum signing helper resolves dependencies withoutnode_modules - Add identity removal: REST endpoint
/tip/v1/identity/removeplus admin UI controls for both Publisher and Creator identities, with typed-confirmation guard for the destructive Publisher case - Add fluid typography across the admin UI; new
560pxmobile breakpoint;:focus-visible,prefers-reduced-motion, andprefers-contrastsupport; WCAG 2.5.5 minimum touch-target sizing - Remove
load_plugin_textdomain()(auto-loaded by WordPress 4.6+ for directory-hosted plugins) - Bump
Contributorsto includetheailaborg
1.3.0
- Align WordPress registration hashing with the current developer hashing guide
- Build the content hash input from a structured WordPress content string instead of raw rendered body text alone
- Add guide-compliant body cleaning with
tipmediaimage,tipmediavideo, andtipmediaaudioindicators - Add
CNA-MIX-1top-level content hashing when attached media participates in the registration hash - Store and expose
text_canonical_hashplus attached-media hash fields in the local record and public TIP manifest - Add test coverage for content-string ordering, guide body cleaning, and mixed-hash composition
1.2.3
- Change TIP identity setup to import-only onboarding for reviewed publisher and VP creator identities
- Add
.tip.jsonpackage import support and clearer rejection for browser-connected WebAuthn blobs - Add local sign-and-verify checks for imported key material before WordPress stores it
- Upgrade key-at-rest encryption to a TIP-ID-specific SHAKE-256 plus PBKDF2 AES-256-GCM payload while keeping backward decryption support
- Emit the canonical
registered_urldirectly inX-TIP-Content-Bind
1.0.2
- Add richer fallback schema and merge TIP provenance into Yoast SEO and Rank Math graphs without duplicating article JSON-LD
- Improve badge and public trust UI accessibility with stronger semantics, focus handling, and keyboard-safe details
- Add privacy-policy guidance plus personal data exporter and eraser integration for stored user TIP identity data
- Bundle the official TIP mark locally for admin branding and WordPress.org packaging
- Default the public badge script to the bundled local copy and add release packaging hardening files
1.0.1
- Simplify plugin branding to TIP Protocol with Publisher Provenance for WP as the subtitle
- Align content hashing and verification badges with the CNA-2 registration spec
1.0.0
- Initial release