Review of 3073a5061 found the remaining registration hole: Register
rejected canonical descriptor overrides but still accepted a canonical
NAME with a nil override, inheriting the canonical descriptor while
replacing the governed handler in the map - an extension could re-register
pulse_read and bypass its execution-intent enforcement.
Registration authority is now split. registerBuiltin is the unexported
construction-time path for canonical Pulse tools: shared descriptor
mandatory, overrides rejected. RegisterExtension - the only path exposed
through PulseToolExecutor.RegisterTool - rejects every canonical tool
name outright and requires the extension to declare its own descriptor.
Both paths are append-only: a name registers exactly once, so no later
registration can swap out an already-governed handler.
Proofs cover the exact bypass (canonical name, nil override), extension
and builtin duplicate rejection, builtin override rejection, and
descriptor-less extension rejection. Tests that previously swapped
handlers by re-registering now use fresh executors per scenario.
Contract prose and source pins updated.
Two AI write paths asserted unverified success while the Proxmox guest
and Docker start/stop/restart handlers already do read-after-write
checks. Bring both in line with that idiom:
- pulse_kubernetes scale: re-read the deployment's spec/ready replicas
via kubectl through the same agent (bounded settle-and-retry window)
and return a JSON response with a verification block instead of
"Action complete - no verification needed".
- pulse_docker update: the docker agent already recreates the container,
health-checks it, rolls back on failure, and acks a terminal command
status; expose that status through a new Monitor lookup
(GetDockerCommandStatus) plus UpdatesProvider.GetCommandStatus, and
poll it within a bounded window. Responses now report verified
success, verified failure (is_error), or an explicit inconclusive,
never unverified success.
kubernetes_control_test.go also carries a small in-flight fix from the
parallel remediation-lock work (in-memory ActionAuditStore in the test
helper) that these tests require to run on this tree.
Manifest-backed MCP tools, prompts, and resources with surface affordance contracts; agent capability manifest and governance projection; API contract tests and capability route projection; operations-loop and intelligence-funnel telemetry; release-control subsystem documentation, registry, and tooling; licensing and configuration.
Persist approval requests as governed planned actions with context confidence and stream that plan into Pulse Assistant approvals.
Reuse the planned action identity when approved actions execute so the unified audit trail stays continuous.
- Merge tools_infrastructure.go, tools_intelligence.go, tools_patrol.go,
tools_profiles.go into their respective domain tools
- Expand tools_control.go with command execution logic
- Expand tools_discovery.go with resource discovery handlers
- Expand tools_storage.go with storage-related operations
- Expand tools_metrics.go with metrics functionality
- Update tests to match new structure
This consolidation reduces file count and groups related functionality together.