Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/maintain-docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: Maintain Docs

env:
# Advance this revision and all package digests together when package bytes change.
DOCS_AGENT_PACKAGE_REVISION: a39d9db230eb9e0b72ed84465f4d61bd8dda1bab
DOCS_AGENT_PACKAGE_REVISION: a51e79ac698610177852170332a1135a9c315951
# Advance independently when the post-command completion validator changes.
DOCS_AGENT_COMPLETION_CONTRACT_REVISION: b136f9bc84e6f0ad9d5d0d5cdbb3df9c62e382e2

Expand Down Expand Up @@ -153,7 +153,7 @@ jobs:
technical:bootstrap)
package_path="bundles/technical-docs-agent/native/technical-docs-bootstrap-agent.agent.json"
agent_slug="technical-docs-bootstrap-agent"
package_digest="sha256-bytes-v1:0230e0e3fd8a4f045a545407d3d01c22df537b05f031260e29d6b531285b7839"
package_digest="sha256-bytes-v1:124924f004474d5296294a3f2c99285d0848c46ed622926b1b283ed018b2bcf0"
lane_requires_pr=true
default_prompt="Bootstrap source-grounded developer documentation that helps developers understand, use, and extend the code in the repository."
;;
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -230,11 +230,11 @@ Docs Agent has one canonical architecture: five standalone native Agents API pac
- `bundles/user-docs-agent/native/user-docs-maintenance-agent.agent.json`
- `bundles/skills-agent/native/skills-maintenance-agent.agent.json`

These five `.agent.json` files are the complete executable package surface. Each package is the sole executable instruction authority for its lane. The reusable workflow maps `audience` and `run_kind` to exactly one package and its canonical agent slug; it does not select a separate manifest, flow, pipeline, or memory envelope. Every descriptor uses the package-source revision `a39d9db230eb9e0b72ed84465f4d61bd8dda1bab`, independently of the revision that invokes the reusable workflow, and supplies a byte-level `sha256-bytes-v1` digest.
These five `.agent.json` files are the complete executable package surface. Each package is the sole executable instruction authority for its lane. The reusable workflow maps `audience` and `run_kind` to exactly one package and its canonical agent slug; it does not select a separate manifest, flow, pipeline, or memory envelope. Every descriptor uses the package-source revision `a51e79ac698610177852170332a1135a9c315951`, independently of the revision that invokes the reusable workflow, and supplies a byte-level `sha256-bytes-v1` digest.

Package updates advance the package-source revision and all five declared digests atomically. The immutable-source validator reads each package blob from that Git revision, recomputes its digest and canonical slug, and rejects a descriptor that does not match those historical bytes.

All five packages support direct import through `wp_agent_import_runtime_bundles()` and retain the source-grounded workspace-only editing boundary. They intentionally have no required write-tool gate: deterministic report/diff postconditions reject no-op writes while allowing honest no-change maintenance.
All five packages support direct import through `wp_agent_import_runtime_bundles()` and retain the source-grounded workspace-only editing boundary. Technical bootstrap has an Agents API completion gate that requires a workspace documentation write before it can finish, so a fresh surface cannot complete as prose only. Maintenance and the other no-change-capable lanes intentionally have no required write-tool gate; deterministic report/diff postconditions continue to reject no-op writes while allowing honest no-change maintenance.

### Compatibility Impact

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
"schema_version": 1,
"bundle_slug": "technical-docs-bootstrap-agent",
"bundle_version": "0.1.0",
"source_ref": "Automattic/docs-agent@3da1b8076359db9bf9f4ee7dadcc3932c080ed71",
"source_revision": "3da1b8076359db9bf9f4ee7dadcc3932c080ed71",
"source_ref": "Automattic/docs-agent@a51e79ac698610177852170332a1135a9c315951",
"source_revision": "a51e79ac698610177852170332a1135a9c315951",
"agent": {
"agent_slug": "technical-docs-bootstrap-agent",
"agent_name": "Technical Docs Bootstrap Agent",
Expand All @@ -30,12 +30,23 @@
"workspace_git_status",
"workspace_git_diff"
],
"tool_call_rules": []
"tool_call_rules": [
{
"id": "require-bootstrap-workspace-write",
"require_tool_use": true,
"min_tool_calls": 1,
"require_one_of": [
"workspace_write",
"workspace_edit",
"workspace_apply_patch"
]
}
]
},
"meta": {
"source_type": "runtime-agent-package",
"source_package": "technical-docs-agent",
"source_version": "3da1b8076359db9bf9f4ee7dadcc3932c080ed71",
"source_version": "a51e79ac698610177852170332a1135a9c315951",
"role": "technical-docs-bootstrap",
"runtime": "agents-api-native-chat",
"default_provider": "openai",
Expand Down
2 changes: 1 addition & 1 deletion ci/docs-agent-runner-recipe.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"docsAgent": {
"externalPackageSource": {
"repository": "Automattic/docs-agent",
"revision": "a39d9db230eb9e0b72ed84465f4d61bd8dda1bab",
"revision": "a51e79ac698610177852170332a1135a9c315951",
"path": "bundles/technical-docs-agent/native/technical-docs-maintenance-agent.agent.json",
"digest": "sha256-bytes-v1:975c7b0a0a7aff52897c52be5ac903a7fb110ea3c33e16227f8694c74c932519"
},
Expand Down
2 changes: 1 addition & 1 deletion examples/runner-recipe.example.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"docsAgent": {
"externalPackageSource": {
"repository": "Automattic/docs-agent",
"revision": "a39d9db230eb9e0b72ed84465f4d61bd8dda1bab",
"revision": "a51e79ac698610177852170332a1135a9c315951",
"path": "bundles/technical-docs-agent/native/technical-docs-maintenance-agent.agent.json",
"digest": "sha256-bytes-v1:975c7b0a0a7aff52897c52be5ac903a7fb110ea3c33e16227f8694c74c932519"
},
Expand Down
18 changes: 17 additions & 1 deletion tests/native-agent-import.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ public function get_error_data(): mixed {
$passes = 0;

require_once $agents_api_dir . '/tests/agents-api-smoke-helpers.php';
require_once $agents_api_dir . '/src/Runtime/class-wp-agent-message.php';
require_once $agents_api_dir . '/src/Runtime/class-wp-agent-tool-call-gate.php';
agents_api_smoke_require_module();
do_action( 'init' );

Expand Down Expand Up @@ -69,7 +71,21 @@ public function get_error_data(): mixed {
$rules = is_array( $config['tool_call_rules'] ?? null ) ? $config['tool_call_rules'] : array();

agents_api_smoke_assert_equals( true, in_array( 'workspace_write', $config['enabled_tools'] ?? array(), true ), "{$slug} preserves the workspace write tool", $failures, $passes );
agents_api_smoke_assert_equals( array(), $rules, "{$slug} permits clean evidence-backed no-change completion", $failures, $passes );
if ( 'technical-docs-bootstrap-agent' === $slug ) {
$gate = AgentsAPI\AI\WP_Agent_Tool_Call_Gate::from_config( $rules );
agents_api_smoke_assert_equals( true, $gate instanceof AgentsAPI\AI\WP_Agent_Tool_Call_Gate, "{$slug} creates a completion gate for a fresh documentation surface", $failures, $passes );

$fresh_surface = array( AgentsAPI\AI\WP_Agent_Message::text( 'user', 'The workspace has no docs/README.md. Create the caller-required documentation paths.' ) );
$blocked = $gate instanceof AgentsAPI\AI\WP_Agent_Tool_Call_Gate ? $gate->evaluate_completion( $fresh_surface ) : array();
agents_api_smoke_assert_equals( false, $blocked['allowed'] ?? null, "{$slug} blocks prose-only completion on a fresh documentation surface", $failures, $passes );
agents_api_smoke_assert_equals( 'require-bootstrap-workspace-write', $blocked['context']['rule_id'] ?? '', "{$slug} identifies the required bootstrap write gate", $failures, $passes );

$after_write = array_merge( $fresh_surface, array( AgentsAPI\AI\WP_Agent_Message::toolCall( '', 'workspace_write', array( 'path' => 'docs/README.md' ), 1, array( 'tool_call_id' => 'bootstrap-docs-index' ) ) ) );
$allowed = $gate instanceof AgentsAPI\AI\WP_Agent_Tool_Call_Gate ? $gate->evaluate_completion( $after_write ) : array();
agents_api_smoke_assert_equals( true, $allowed['allowed'] ?? null, "{$slug} accepts completion after a required workspace write", $failures, $passes );
} else {
agents_api_smoke_assert_equals( array(), $rules, "{$slug} permits clean evidence-backed no-change completion", $failures, $passes );
}

$chat = AgentsAPI\AI\Channels\WP_Agent_Default_Chat_Handler::execute( array( 'agent' => $slug, 'message' => 'Verify native registration.' ) );
agents_api_smoke_assert_equals( 'agents_chat_provider_required', $chat instanceof WP_Error ? $chat->get_error_code() : '', "{$slug} resolves through the default native chat handler", $failures, $passes );
Expand Down
8 changes: 7 additions & 1 deletion tests/native-agent.validate-package-spec.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
"technical-docs-bootstrap-agent.agent.json": {
"package": "technical-docs-agent",
"agent_slug": "technical-docs-bootstrap-agent",
"source_revision": "3da1b8076359db9bf9f4ee7dadcc3932c080ed71",
"source_revision": "a51e79ac698610177852170332a1135a9c315951",
"required_tools": [
"get_github_file",
"workspace_read",
Expand All @@ -26,6 +26,12 @@
"workspace_git_diff"
],
"permitted_workspace_tools": ["workspace_show", "workspace_ls", "workspace_read", "workspace_grep", "workspace_write", "workspace_edit", "workspace_apply_patch", "workspace_git_status", "workspace_git_diff"],
"required_tool_call_rule": {
"id": "require-bootstrap-workspace-write",
"require_tool_use": true,
"min_tool_calls": 1,
"require_one_of": ["workspace_write", "workspace_edit", "workspace_apply_patch"]
},
"instructions_must_contain": [
"living documentation",
"understand, use, and extend",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@
"called_workflow_context": {
"job_workflow_sha": ""
},
"expected_package_revision": "a39d9db230eb9e0b72ed84465f4d61bd8dda1bab"
"expected_package_revision": "a51e79ac698610177852170332a1135a9c315951"
}
9 changes: 7 additions & 2 deletions tests/validate-docs-agent-packages.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
$assert( 'docs-agent/runner-recipe/v1' === ( $recipe['schema'] ?? null ), 'Runner recipe must use the portable Docs Agent runner recipe schema.' );
$expected_package_source = array(
'repository' => 'Automattic/docs-agent',
'revision' => 'a39d9db230eb9e0b72ed84465f4d61bd8dda1bab',
'revision' => 'a51e79ac698610177852170332a1135a9c315951',
'path' => 'bundles/technical-docs-agent/native/technical-docs-maintenance-agent.agent.json',
'digest' => 'sha256-bytes-v1:975c7b0a0a7aff52897c52be5ac903a7fb110ea3c33e16227f8694c74c932519',
);
Expand Down Expand Up @@ -217,7 +217,12 @@
);
$assert( ( $native_assertions['permitted_workspace_tools'] ?? array() ) === $workspace_tools, "Native package {$native_file} workspace tools do not match its permitted workspace tool policy." );

$assert( array() === ( $config['tool_call_rules'] ?? null ), "Native package {$native_file} must allow evidence-backed no-change completion without a no-op write." );
$required_tool_call_rule = $native_assertions['required_tool_call_rule'] ?? null;
if ( is_array( $required_tool_call_rule ) ) {
$assert( in_array( $required_tool_call_rule, $config['tool_call_rules'] ?? array(), true ), "Native package {$native_file} must enforce its required tool-call rule." );
} else {
$assert( array() === ( $config['tool_call_rules'] ?? null ), "Native package {$native_file} must allow evidence-backed no-change completion without a no-op write." );
}

// Runner-neutral boundary: no agent-owned publication tools.
foreach ( $native_spec['forbidden_publication_tools'] ?? array() as $forbidden_tool ) {
Expand Down
4 changes: 2 additions & 2 deletions tests/validate-external-native-package-sources.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,9 @@
return $contents;
};

$package_revision = 'a39d9db230eb9e0b72ed84465f4d61bd8dda1bab';
$package_revision = 'a51e79ac698610177852170332a1135a9c315951';
$packages = array(
'technical:bootstrap' => array( 'path' => 'bundles/technical-docs-agent/native/technical-docs-bootstrap-agent.agent.json', 'slug' => 'technical-docs-bootstrap-agent', 'digest' => '0230e0e3fd8a4f045a545407d3d01c22df537b05f031260e29d6b531285b7839' ),
'technical:bootstrap' => array( 'path' => 'bundles/technical-docs-agent/native/technical-docs-bootstrap-agent.agent.json', 'slug' => 'technical-docs-bootstrap-agent', 'digest' => '124924f004474d5296294a3f2c99285d0848c46ed622926b1b283ed018b2bcf0' ),
'technical:maintenance' => array( 'path' => 'bundles/technical-docs-agent/native/technical-docs-maintenance-agent.agent.json', 'slug' => 'technical-docs-maintenance-agent', 'digest' => '975c7b0a0a7aff52897c52be5ac903a7fb110ea3c33e16227f8694c74c932519' ),
'user:bootstrap' => array( 'path' => 'bundles/user-docs-agent/native/user-docs-bootstrap-agent.agent.json', 'slug' => 'user-docs-bootstrap-agent', 'digest' => 'a3ada797a125f638364caac43004bbb47fcc8c7bdc89021f25fcfcdc4c2d502f' ),
'user:maintenance' => array( 'path' => 'bundles/user-docs-agent/native/user-docs-maintenance-agent.agent.json', 'slug' => 'user-docs-maintenance-agent', 'digest' => '747de10fdb52d7c1543b404030e0e0a2604b6496e95d50143149f72c975a98fb' ),
Expand Down
2 changes: 1 addition & 1 deletion tests/validate-wp-codebox-run-agent-task-contract.php
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@

$assert( isset( $caller_inputs['external_package_source'] ), 'Docs Agent must provide the required external package descriptor.' );
$assert( ! isset( $caller_inputs['agent_bundle'] ), 'Docs Agent must not pass the removed agent_bundle input.' );
$assert( str_contains( $workflow, 'DOCS_AGENT_PACKAGE_REVISION: a39d9db230eb9e0b72ed84465f4d61bd8dda1bab' ), 'Docs Agent must use the fixed native package source revision.' );
$assert( str_contains( $workflow, 'DOCS_AGENT_PACKAGE_REVISION: a51e79ac698610177852170332a1135a9c315951' ), 'Docs Agent must use the fixed native package source revision.' );
$assert( ! str_contains( $workflow, 'github.job_workflow_sha' ), 'Docs Agent must not depend on unavailable called-workflow provenance.' );

preg_match( "/runtime_sources='(?<json>[^']+)'/", $workflow, $runtime_sources_match );
Expand Down
Loading