1515# agents_md_guidance_register <section_id> <priority> <label> <description> <content>
1616# agents_md_guidance_unregister <section_id>
1717# agents_md_guidance_sync_wordpress_agent_boundaries
18- # agents_md_guidance_sync_homeboy_cli # presence-gated on `command -v homeboy`
19- # agents_md_guidance_register_homeboy_cli # writes a LIVE-enumeration PHP block
18+ # agents_md_guidance_sync_homeboy_cli # presence-gated on an executable Homeboy binary
19+ # agents_md_guidance_register_homeboy_cli # writes a live presence-checked PHP block
2020# agents_md_guidance_unregister_homeboy_cli
2121#
22- # The homeboy-cli section is generated LIVE at AGENTS.md compose time: the
23- # mu-plugin callback shells out to `homeboy --help` on every compose (cached
24- # briefly on the binary mtime + version), so a `homeboy upgrade` converges on
25- # the next compose without requiring a wp-coding-agents sync. See issue #254.
22+ # The homeboy-cli callback checks the current PATH at AGENTS.md compose time, so
23+ # an unavailable binary contributes no stale guidance. The live CLI help remains
24+ # authoritative for Homeboy's complete command surface.
2625#
2726# Honors DRY_RUN (logs intent, makes no changes).
2827
@@ -221,27 +220,31 @@ agents_md_guidance_unregister() {
221220agents_md_guidance_sync_wordpress_agent_boundaries () {
222221 local source_content abilities_content
223222
224- source_content=' ## WordPress Source (Read-Only Reference )
223+ source_content=' ## WordPress Source (Direct Reference, Read-Only)
225224
226- These directories are **read-only reference material** — grep and read them to understand code, but never edit them directly.
225+ Use the installed WordPress source to verify core APIs, hooks, conventions, and runtime behavior instead of relying on assumptions. Search and read these directories directly when working on WordPress:
227226
228227- `wp-content/plugins/` — plugin source (read-only)
229228- `wp-content/themes/` — theme source (read-only)
230- - `wp-includes/` — WordPress core (read-only)'
229+ - `wp-includes/` — WordPress core (read-only)
230+
231+ These paths are **read-only references**. Make code changes in the configured managed workspace, not in the installed source tree.'
231232
232233 abilities_content=' ## Abilities
233234
234235WordPress Abilities are the universal tool surface. Plugins expose abilities through the active runtime, REST API, MCP, and chat.
235236
236- Inspect the active runtime tool listings and plugin-specific `--help` output before assuming what is available.'
237+ **Default routing**
238+ - Use abilities exposed by the active runtime when they match the task.
239+ - Inspect the active runtime tool listings and plugin-specific `--help` before assuming a capability or argument is available.'
237240
238241 AGENTS_MD_GUIDANCE_FRESHNESS=static \
239242 AGENTS_MD_GUIDANCE_CONDITIONS=' Registered by wp-coding-agents on managed WordPress coding-agent installations.' \
240243 agents_md_guidance_register \
241244 ' wordpress-source' \
242245 1 \
243246 ' WordPress Source' \
244- ' Generic boundaries for installed WordPress source.' \
247+ ' Direct-reference and read-only boundaries for installed WordPress source.' \
245248 " $source_content "
246249
247250 AGENTS_MD_GUIDANCE_FRESHNESS=static \
@@ -255,21 +258,16 @@ Inspect the active runtime tool listings and plugin-specific `--help` output bef
255258}
256259
257260# ---------------------------------------------------------------------------
258- # Homeboy CLI command map (issues #208, #254)
261+ # Homeboy routing guidance (issues #208, #254, #298 )
259262#
260263# homeboy is an OPTIONAL host binary. The map is strictly presence-gated:
261264# - present (`command -v homeboy` succeeds) -> emit a first-class section
262- # whose callback ENUMERATES `homeboy --help` LIVE at AGENTS.md compose
263- # time. A `homeboy upgrade` therefore converges on the next compose,
264- # with no wp-coding-agents sync required (the #254 trigger gap).
265+ # whose callback verifies Homeboy is still present at compose time.
265266# - absent -> complete no-op (unregister any stale section, emit nothing).
266267#
267- # The command list is NEVER baked into the mu-plugin as a frozen string;
268- # the previous static-bake design was the #254 defect. The PHP helper that
269- # performs the live enumeration is shipped inline in the homeboy-cli
270- # section block (see _agents_md_guidance_render_homeboy_live_block), with
271- # a WP transient cache keyed on the homeboy binary path + mtime + version
272- # so steady-state compiles are free and the cache self-heals on upgrade.
268+ # The generated section intentionally contains routing, ownership, safety, and
269+ # discovery guidance rather than a copy of `homeboy --help`. The live CLI is the
270+ # authoritative command map.
273271# ---------------------------------------------------------------------------
274272
275273# agents_md_guidance_sync_homeboy_cli
@@ -279,7 +277,9 @@ Inspect the active runtime tool listings and plugin-specific `--help` output bef
279277# agree on presence. When homeboy is present, registers a LIVE-enumeration
280278# section block (no content is baked at setup time).
281279agents_md_guidance_sync_homeboy_cli () {
282- if command -v homeboy > /dev/null 2>&1 ; then
280+ local homeboy_path
281+ homeboy_path=" $( type -P homeboy 2> /dev/null || true) "
282+ if [ -n " $homeboy_path " ] && [ -f " $homeboy_path " ] && [ -x " $homeboy_path " ]; then
283283 agents_md_guidance_register_homeboy_cli
284284 else
285285 agents_md_guidance_unregister_homeboy_cli
@@ -288,14 +288,9 @@ agents_md_guidance_sync_homeboy_cli() {
288288
289289# agents_md_guidance_register_homeboy_cli
290290#
291- # Writes a self-contained PHP block whose SectionRegistry callback shells
292- # out to `homeboy --help` at compose time and parses the Commands: block in
293- # PHP. The block is marker-delimited (BEGIN/END agents-md-guidance:homeboy-cli)
291+ # Writes a self-contained PHP block whose SectionRegistry callback verifies the
292+ # Homeboy binary remains available at compose time. The block is marker-delimited
294293# so it is idempotent and removable by the standard unregister path.
295- #
296- # No homeboy output is captured at setup time — that was the #254 bug. The
297- # callback is the only thing that touches homeboy, and it runs on every
298- # `wp datamachine memory compose AGENTS.md`.
299294agents_md_guidance_register_homeboy_cli () {
300295 local file
301296 file=" $( agents_md_guidance_mu_plugin_path) " || {
@@ -313,12 +308,6 @@ agents_md_guidance_register_homeboy_cli() {
313308
314309 agents_md_guidance_ensure_mu_plugin_file || return 1
315310
316- local new_block
317- new_block=" $( _agents_md_guidance_render_homeboy_live_block) " || {
318- warn " agents_md_guidance_register_homeboy_cli: could not render live block — skipping"
319- return 1
320- }
321-
322311 if [ " ${DRY_RUN:- false} " = true ]; then
323312 echo -e " ${BLUE} [dry-run]${NC} Would register live AGENTS.md guidance section 'homeboy-cli' in $file "
324313 echo -e " ${BLUE} [dry-run]${NC} Block:"
@@ -354,25 +343,9 @@ agents_md_guidance_unregister_homeboy_cli() {
354343# _agents_md_guidance_render_homeboy_live_block
355344#
356345# Emits the PHP for the homeboy-cli section block. The block is
357- # self-contained: it defines two helper functions (guarded by
358- # `function_exists` so re-firing the datamachine_sections action does not
359- # fatally redeclare them) and then registers a SectionRegistry section
360- # whose callback invokes the live enumerator.
361- #
362- # The helpers:
363- # wp_coding_agents_render_homeboy_cli_section()
364- # Top-level orchestrator. Resolves `homeboy` on PATH, reads
365- # `--version` and the binary mtime for the cache key, checks the WP
366- # transient cache, shells out to `homeboy --help`, hands the help
367- # text to the parser, caches the rendered markdown, and returns it.
368- # Returns '' (section contributes nothing) when homeboy is absent,
369- # shell_exec is unavailable, the binary fails, or the help text has
370- # no parseable Commands: block.
371- # wp_coding_agents_parse_homeboy_cli_help( $help )
372- # Pure parser. Faithful PHP port of the original python parser:
373- # recognizes the `Commands:` block, ends at blank line / Options:,
374- # drops the `help`/`list` meta commands, renders the same markdown
375- # shape (intro, optional "Common entrypoints", full list, footer).
346+ # self-contained: it defines one helper (guarded by `function_exists` so
347+ # re-firing the datamachine_sections action does not fatally redeclare it) and
348+ # registers a SectionRegistry section whose callback checks live presence.
376349#
377350# Quoted heredoc ('PHP_BLOCK') so PHP $variables, backticks, and ${...}
378351# are emitted verbatim — bash never touches them.
@@ -402,161 +375,41 @@ _agents_md_guidance_render_homeboy_live_block() {
402375 return '';
403376 }
404377
405- // shell_exec is the safe argv form here (hard-coded `homeboy`
406- // subcommands, no user input). It can be disabled in php.ini —
407- // in that case we degrade to a no-op rather than emit a broken
408- // section.
409- if ( ! is_callable( 'shell_exec' ) ) {
410- return '';
411- }
378+ return <<<'MD'
379+ ## Homeboy
412380
413- // Cache key on the Homeboy identity and this installed renderer.
414- // Homeboy upgrades change the binary signals; wp-coding-agents
415- // upgrades change the generated MU-plugin hash. Either change
416- // must re-render the complete section because the cached value
417- // includes both command output and static guidance prose.
418- $version_out = @shell_exec( escapeshellarg( $homeboy ) . ' --version 2>/dev/null' );
419- $version = ( is_string( $version_out ) ) ? trim( $version_out ) : '';
420- $mtime = @filemtime( $homeboy );
421- $renderer_rev = @md5_file( __FILE__ );
422- $cache_key = 'wca_homeboy_cli_agents_md_' . md5( $homeboy . '|' . $version . '|' . ( $mtime ?: '0' ) . '|' . ( $renderer_rev ?: 'unknown' ) );
423-
424- if ( is_callable( 'get_transient' ) ) {
425- $cached = get_transient( $cache_key );
426- if ( is_string( $cached ) && $cached !== '' ) {
427- return $cached;
428- }
429- }
381+ Homeboy orchestrates coding agents, deterministic gates, evidence, promotion, review, releases, and deployments. Data Machine Code owns authoritative repository and worktree state; Homeboy consumes managed worktrees to execute and finalize work.
430382
431- $help = @shell_exec( escapeshellarg( $homeboy ) . ' --help 2>/dev/null' );
432- if ( ! is_string( $help ) || $help === '' ) {
433- return '';
434- }
435-
436- $content = wp_coding_agents_parse_homeboy_cli_help( $help );
437- if ( $content === '' ) {
438- return '';
439- }
440-
441- if ( is_callable( 'set_transient' ) ) {
442- set_transient( $cache_key, $content, 3600 );
443- }
444-
445- return $content;
446- }
447- }
448-
449- if ( ! function_exists( 'wp_coding_agents_parse_homeboy_cli_help' ) ) {
450- function wp_coding_agents_parse_homeboy_cli_help( $help ) {
451- // Faithful PHP port of the original python parser. See
452- // lib/agents-md-guidance.sh history.
453- $commands = array();
454- $in_commands = false;
455- foreach ( preg_split( '/\r\n|\r|\n/', (string) $help ) as $raw ) {
456- $stripped = trim( $raw );
457- if ( ! $in_commands ) {
458- if ( $stripped === 'Commands:' ) {
459- $in_commands = true;
460- }
461- continue;
462- }
463-
464- // The commands block ends at the first blank line or the
465- // Options: header.
466- if ( $stripped === '' || $stripped === 'Options:' || strpos( $raw, 'Options:' ) === 0 ) {
467- break;
468- }
469-
470- if ( ! preg_match( '/^\s+([A-Za-z0-9][A-Za-z0-9_-]*)\s{2,}(.+?)\s*$/', $raw, $matches ) ) {
471- // Continuation / wrapped summary lines have no command
472- // token; ignore them.
473- continue;
474- }
475-
476- $commands[] = array( $matches[1], trim( $matches[2] ) );
477- }
478-
479- if ( ! $commands ) {
480- return '';
481- }
482-
483- // `help` / `list` are meta commands; drop them from the map.
484- // The footer already tells the agent how to discover
485- // everything.
486- $skip = array( 'help' => true, 'list' => true );
487- $commands = array_values(
488- array_filter(
489- $commands,
490- static function ( $c ) use ( $skip ) {
491- return ! isset( $skip[ $c[0] ] );
492- }
493- )
494- );
495-
496- if ( ! $commands ) {
497- return '';
498- }
499-
500- $summaries = array();
501- foreach ( $commands as $c ) {
502- $summaries[ $c[0] ] = $c[1];
503- }
504-
505- $common_order = array(
506- 'status',
507- 'triage',
508- 'worktree',
509- 'review',
510- 'build',
511- 'test',
512- 'agent-task',
513- 'runs',
514- );
515-
516- $lines = array();
517- $lines[] = 'Homeboy is the host orchestrator binary — build, deploy, release, triage, test, and inspect components from the CLI. The command map below is generated live from `homeboy --help` at AGENTS.md compose time, so it always reflects the currently-installed homeboy binary.';
518-
519- $common_entrypoints = array();
520- foreach ( $common_order as $name ) {
521- if ( isset( $summaries[ $name ] ) ) {
522- $common_entrypoints[] = $name;
523- }
524- }
525- if ( $common_entrypoints ) {
526- $lines[] = '';
527- $lines[] = 'Common entrypoints:';
528- foreach ( $common_entrypoints as $name ) {
529- $lines[] = '- `homeboy ' . $name . '` — ' . $summaries[ $name ];
530- }
531- }
532-
533- $lines[] = '';
534- foreach ( $commands as $c ) {
535- $lines[] = '- `homeboy ' . $c[0] . '` — ' . $c[1];
536- }
383+ **Default routing**
384+ - One tracked change: `homeboy agent-task cook`
385+ - Multiple independent changes: `homeboy agent-task fanout cook-batch`
386+ - Review a candidate: `homeboy review`
387+ - Inspect runs and evidence: `homeboy runs`
388+ - Repeating workflows: `homeboy agent-task loop`; explicitly stateful workflows: `homeboy agent-task controller`
389+ - Component and runner health: `homeboy status` and `homeboy runner status`
537390
538- $lines[] = '';
539- $lines[] = 'For agent work, use `homeboy agent-task cook` for one issue or reviewable PR, `homeboy agent-task fanout cook-batch` for multiple independent issues, `homeboy agent-task loop` for a named repeating workflow, and `homeboy agent-task controller` for workflows with explicit actions, events, waits, or policy state.';
540- $lines[] = 'Inspect live configuration with `homeboy config show`. Discover current agent-task providers with `homeboy agent-task providers`.';
541- $lines[] = 'Discover everything: `homeboy --help`. Drill into a command with `homeboy <command> --help`, including `homeboy config --help` and `homeboy agent-task --help`. Releases (`homeboy release`) and deploys (`homeboy deploy`) are operator actions — run them only when the user explicitly asks.';
391+ **Operator boundary**
392+ Run `homeboy release` or `homeboy deploy` only when the user explicitly asks.
542393
543- return implode( "\n", $lines );
394+ **Discovery**
395+ Use `homeboy --help` and `homeboy <command> --help` for the live command contract. Inspect active configuration with `homeboy config show` and provider readiness with `homeboy agent-task providers`.
396+ MD;
544397 }
545398 }
546399
547400 \DataMachine\Engine\AI\SectionRegistry::register(
548401 'AGENTS.md',
549402 'homeboy-cli',
550- 34 ,
403+ 30 ,
551404 static function () {
552405 return wp_coding_agents_render_homeboy_cli_section();
553406 },
554407 array(
555- 'label' => 'Homeboy CLI ',
556- 'description' => 'Host orchestrator command map, enumerated live from \'homeboy --help\' at AGENTS.md compose time .',
408+ 'label' => 'Homeboy',
409+ 'description' => 'Host orchestration routing, safety, and discovery guidance .',
557410 'owner' => 'wp-coding-agents',
558411 'freshness' => 'live',
559- 'conditions' => 'Generated live from \'homeboy --help\' at AGENTS.md compose time on hosts where the homeboy binary is installed; removed when homeboy is absent. Cached briefly via WP transient keyed on the homeboy binary mtime and version, so a `homeboy upgrade` converges on the next compose without a wp-coding-agents sync .',
412+ 'conditions' => 'Registered on hosts where the homeboy binary is installed and omitted at compose time when the binary is unavailable .',
560413 )
561414 );
562415 // END agents-md-guidance:homeboy-cli
0 commit comments