Skip to content

Knowledge: Introduce the wp_knowledge custom post type#12201

Open
gziolo wants to merge 7 commits into
WordPress:trunkfrom
gziolo:feature/knowledge-cpt
Open

Knowledge: Introduce the wp_knowledge custom post type#12201
gziolo wants to merge 7 commits into
WordPress:trunkfrom
gziolo:feature/knowledge-cpt

Conversation

@gziolo

@gziolo gziolo commented Jun 17, 2026

Copy link
Copy Markdown
Member

Trac ticket: https://core.trac.wordpress.org/ticket/65476

Summary

Introduces wp_knowledge, a private-by-default custom post type that acts as a storage primitive for structured site knowledge (guidelines, memories, notes), along with its wp_knowledge_type taxonomy and a dedicated REST controller.

This is the WordPress core counterpart to the Knowledge storage primitive being explored in Gutenberg (WordPress/gutenberg#79149). It deliberately lands the storage primitive only — the Guidelines admin UI and the content-guidelines singleton remain consumer-side concerns and are out of scope here.

Details

  • Post type & taxonomy: wp_knowledge and wp_knowledge_type are registered as built-ins in create_initial_post_types() / create_initial_taxonomies(). Both are non-public and headless (show_ui => false); rows are managed via the REST API rather than a wp-admin screen.
  • REST API: WP_REST_Knowledge_Controller serves /wp/v2/knowledge. Reads require an authenticated user with the read capability, collection queries are scoped to rows the current user can read (so totals/pagination respect per-user visibility), callers without the publish capability are limited to the private status, and new rows default to private. Revision history uses the default revisions controller; autosave endpoints are disabled (following the wp_global_styles precedent), since knowledge has no editor session.
  • Capabilities: a graded model is synthesized through the user_has_cap filter (wp_maybe_grant_knowledge_caps()), matching the existing wp_maybe_grant_* pattern. Administrators manage all knowledge; contributors and above may create and fully manage their own private rows. Subscribers and anonymous users are blocked at the post-type door.
  • Type registry: wp_knowledge_types() exposes a filterable set of types (guideline, memory, note); rows saved without a type fall back to the note term.

Testing

New unit tests cover registration, the capability matrix across all roles, the REST controller (CRUD, permission gating, private-by-default), and the type registry. The REST route snapshot in tests/phpunit/tests/rest-api/rest-schema-setup.php is updated accordingly.

npm run test:php -- --group knowledge

Note

The large tests/qunit/fixtures/wp-api-generated.js diff is the auto-generated REST API client fixture, regenerated to add the new /wp/v2/knowledge routes and the wp_knowledge / wp_knowledge_type entries.

🤖 Generated with Claude Code

@github-actions

Copy link
Copy Markdown

Hi there! 👋

Thank you for your contribution to WordPress! 💖

It looks like this is your first pull request to wordpress-develop. Here are a few things to be aware of that may help you out!

No one monitors this repository for new pull requests. Pull requests must be attached to a Trac ticket to be considered for inclusion in WordPress Core. To attach a pull request to a Trac ticket, please include the ticket's full URL in your pull request description.

Pull requests are never merged on GitHub. The WordPress codebase continues to be managed through the SVN repository that this GitHub repository mirrors. Please feel free to open pull requests to work on any contribution you are making.

More information about how GitHub pull requests can be used to contribute to WordPress can be found in the Core Handbook.

Please include automated tests. Including tests in your pull request is one way to help your patch be considered faster. To learn about WordPress' test suites, visit the Automated Testing page in the handbook.

If you have not had a chance, please review the Contribute with Code page in the WordPress Core Handbook.

The Developer Hub also documents the various coding standards that are followed:

Thank you,
The WordPress Project

@github-actions

github-actions Bot commented Jun 17, 2026

Copy link
Copy Markdown

The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the props-bot label.

Core Committers: Use this line as a base for the props when committing in SVN:

Props gziolo, jorgefilipecosta, peterwilsoncc.

To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook.

@gziolo gziolo self-assigned this Jun 17, 2026
@github-actions

Copy link
Copy Markdown

Test using WordPress Playground

The changes in this pull request can previewed and tested using a WordPress Playground instance.

WordPress Playground is an experimental project that creates a full WordPress instance entirely within the browser.

Some things to be aware of

  • All changes will be lost when closing a tab with a Playground instance.
  • All changes will be lost when refreshing the page.
  • A fresh instance is created each time the link below is clicked.
  • Every time this pull request is updated, a new ZIP file containing all changes is created. If changes are not reflected in the Playground instance,
    it's possible that the most recent build failed, or has not completed. Check the list of workflow runs to be sure.

For more details about these limitations and more, check out the Limitations page in the WordPress Playground documentation.

Test this pull request with WordPress Playground.

@gziolo gziolo force-pushed the feature/knowledge-cpt branch from 5530424 to 41b499b Compare June 17, 2026 10:24
@gziolo gziolo changed the title Knowledge: Introduce the wp_knowledge custom post type Knowledge: Introduce the wp_knowledge custom post type Jun 17, 2026
@gziolo gziolo force-pushed the feature/knowledge-cpt branch 3 times, most recently from 2f83ce3 to 69b1806 Compare June 17, 2026 13:51
Register wp_knowledge, a private-by-default storage primitive for structured
site knowledge, together with the wp_knowledge_type taxonomy. Both are built-in
and headless (no admin UI); rows are managed through the REST API.

Add WP_REST_Knowledge_Controller at /wp/v2/knowledge: reads require an
authenticated user, collections are scoped to rows the current user can read,
callers without the publish capability are limited to the private status, and
new rows default to private. Revisions use the default controller; autosave
endpoints are disabled.

Synthesize a graded capability set through the user_has_cap filter:
administrators manage all knowledge, while contributors and above create and
manage their own private rows. Knowledge types are filterable via
wp_knowledge_types(), with note as the save-time fallback.

Trac ticket: https://core.trac.wordpress.org/ticket/65476

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@gziolo gziolo requested a review from jorgefilipecosta June 17, 2026 13:56
@gziolo gziolo force-pushed the feature/knowledge-cpt branch from 69b1806 to d008aaa Compare June 17, 2026 13:56
gziolo added a commit to WordPress/gutenberg that referenced this pull request Jun 17, 2026
Aligns the experimental Knowledge implementation with the refined version
ported to WordPress core in WordPress/wordpress-develop#12201:

- Built-in type `instruction` renamed to `guideline`; the core type
  registry consolidated on `guideline`/`memory`/`note`. The migration
  target slug, the TERM_GUIDELINE constant, and the content-guidelines
  singleton follow.
- Type titles now use the `_x( ..., 'knowledge type' )` context.
- Capability filter `_wp_knowledge_synthesize_caps` becomes the public
  `wp_maybe_grant_knowledge_caps`, hooked at priority 1 to match the
  `wp_maybe_grant_*` family.
- Disable autosave support for `wp_knowledge` (headless storage with no
  editor session); revision history is retained.
- Register the `wp_knowledge_type` taxonomy as headless (`show_ui => false`).
- Align the private-status REST error message with core.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
gziolo added a commit to WordPress/gutenberg that referenced this pull request Jun 17, 2026
Aligns the experimental Knowledge implementation with the refined version
ported to WordPress core in WordPress/wordpress-develop#12201:

- Built-in type `instruction` renamed to `guideline`; the core type
  registry consolidated on `guideline`/`memory`/`note`. The migration
  target slug, the TERM_GUIDELINE constant, and the content-guidelines
  singleton follow.
- Type titles now use the `_x( ..., 'knowledge type' )` context.
- Capability filter `_wp_knowledge_synthesize_caps` becomes the public
  `wp_maybe_grant_knowledge_caps`, hooked at priority 1 to match the
  `wp_maybe_grant_*` family.
- Disable autosave support for `wp_knowledge` (headless storage with no
  editor session); revision history is retained.
- Register the `wp_knowledge_type` taxonomy as headless (`show_ui => false`).
- Align the private-status REST error message with core.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Comment thread src/wp-includes/capabilities.php Outdated
Comment thread src/wp-includes/post.php
@jorgefilipecosta

Copy link
Copy Markdown
Member

Knowledge, is something done mostly though for LLMS, similar to abilities, I wonder if for knowledge we avoid a specific REST endpoint and we just use abilities as the interface to manage the knowledge everywhere? Instead of calling REST we would always call the abilities.

Comment thread src/wp-includes/capabilities.php Outdated
Comment thread src/wp-includes/taxonomy.php Outdated
Comment thread tests/phpunit/tests/rest-api/wpRestKnowledgeController.php Outdated
Comment thread src/wp-includes/taxonomy.php Outdated
Comment thread src/wp-includes/post.php
);

register_post_type(
'wp_knowledge',

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We are not setting delete_with_user, so we use the default and knowledge created by an user is deleted when that user is deleted. I guess that behaviour is correct if the knowledge is private, but it may have unintended consequences for knowledge memory shared between users.

Comment thread src/wp-includes/rest-api/endpoints/class-wp-rest-knowledge-controller.php Outdated
Comment thread tests/phpunit/tests/knowledge/postType.php
@jorgefilipecosta

Copy link
Copy Markdown
Member

Great work here, things look, just left some comments for considering but it seems to be on a good shape.

@peterwilsoncc peterwilsoncc left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've added a few first pass notes inline...

Comment thread src/wp-includes/knowledge.php Outdated
Comment thread src/wp-includes/knowledge.php Outdated
Comment thread src/wp-includes/post.php Outdated
Comment thread src/wp-includes/taxonomy.php Outdated
gziolo and others added 2 commits June 18, 2026 09:36
Drop the underscore prefix from the private wp_knowledge_ensure_default_type_term()
and wp_knowledge_maybe_map_term_label() functions, following the coding standards
change that annotates private functions with @access private instead of a name
prefix. Update the corresponding hooks and @Covers tags.

Remove the scalar/array type hints from wp_maybe_grant_knowledge_caps() so it
matches the graceful coercion used by the sibling user_has_cap callbacks
(wp_maybe_grant_site_health_caps() et al.).

Assert in the controller test that the revisions routes are registered while the
autosaves routes are not, documenting the disabled autosave support.

Follow-up to [d008aaa].
Trac ticket: https://core.trac.wordpress.org/ticket/65476

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Switch the wp_knowledge capability_type from array( 'knowledge_item',
'knowledge' ) to array( 'knowledge_item', 'knowledge_items' ) so the primitive
capabilities follow the standard plural form (edit_knowledge_items) while the
per-post meta capabilities keep the singular form (edit_knowledge_item), the
same primitive/meta split WordPress uses for posts (edit_posts vs edit_post).

Rename the synthesized primitives in wp_maybe_grant_knowledge_caps(), the read
remap, and the wp_knowledge_type taxonomy term capabilities that borrow them.

Follow-up to [d008aaa].
Trac ticket: https://core.trac.wordpress.org/ticket/65476

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@gziolo gziolo force-pushed the feature/knowledge-cpt branch from fdb8d2c to ce880e5 Compare June 18, 2026 08:01
gziolo and others added 4 commits June 18, 2026 10:16
Assert a fixed 403 (rather than 401 or 403) when an authenticated contributor
reads another user's private row, and add coverage proving a contributor can
update and delete their own private row over REST while being forbidden from
updating or deleting another user's row.

Follow-up to [d008aaa].
Trac ticket: https://core.trac.wordpress.org/ticket/65476

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The per-post capability grant in wp_maybe_grant_knowledge_caps() gated on the
current post status being private, so trashing a private row (which flips the
status to trash) stripped the author's delete_knowledge_items grant and left
them unable to permanently delete or restore their own row.

Resolve the effective status before the check by falling back to the pre-trash
status stored in _wp_trash_meta_status, so a row trashed from private keeps the
grant while a row trashed from another status stays outside it. Add a regression
test covering a contributor deleting their own trashed row.

Follow-up to [d008aaa].
Trac ticket: https://core.trac.wordpress.org/ticket/65476

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Return rest_cannot_read instead of rest_forbidden when an unauthorized user
requests the knowledge collection, matching the font families, global styles,
and comments controllers. Tighten the authentication test to assert the error
code rather than only the HTTP status, which both codes share.

Follow-up to [d008aaa].
Trac ticket: https://core.trac.wordpress.org/ticket/65476

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
show_admin_column only adds a taxonomy column to a post type's edit screen list
table, which requires the post type to have show_ui enabled. wp_knowledge sets
show_ui to false, so the flag rendered nothing and only surfaced a misleading
true in the /wp/v2/taxonomies response. Let it default to false, matching the
taxonomy's other admin-facing flags.

Follow-up to [d008aaa].
Trac ticket: https://core.trac.wordpress.org/ticket/65476

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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.

3 participants