agents: refine Starlark data serialization, docstring, and WORKSPACE rules (#4364)

Capture review feedback from #4360 in the workspace agent rules so
future Starlark and WORKSPACE implementations follow the same patterns:

- Direct repository rules to serialize JSON-compatible data constants in
  generated `.bzl` files with `json.encode_indent()` instead of custom
  `render.*` helpers.
- Keep `.bzl` API docstrings brief and place multi-scenario examples and
  setup guides in narrative `docs/` pages linked via `{ref}` or `{obj}`.
- Require `WORKSPACE` macros to match Bzlmod extension defaults, tag
  schemas, and single-hub multi-version structure, splitting manifest
  downloads into a manifest repo rule and a bound registration macro.
diff --git a/.agents/rules/docs.md b/.agents/rules/docs.md
index d292316..e463527 100644
--- a/.agents/rules/docs.md
+++ b/.agents/rules/docs.md
@@ -11,6 +11,9 @@
 * Use hyphens (`-`) in file names instead of underscores (`_`).
 * Document user-visible behavior, not internal workarounds or implementation
   details.
+* **API Docstrings vs. Narrative Docs**: Keep `.bzl` docstrings brief (purpose
+  and arguments). Put setup guides and multi-scenario examples in `docs/`, and
+  link to them with `{ref}` or `{obj}` instead of repeating rules.
 * **How-to Guides (`docs/howto/`)**:
   * Prefer adding sections to an existing topical guide (e.g.
     `docs/howto/build-a-wheel.md`) over creating a separate granular file.
diff --git a/.agents/rules/rules_python.md b/.agents/rules/rules_python.md
index b18c178..701a9c3 100644
--- a/.agents/rules/rules_python.md
+++ b/.agents/rules/rules_python.md
@@ -28,6 +28,16 @@
   `//python/private/toolchain_types:BUILD.bazel`.
 * **`render` Helpers (`//python/private:text_util.bzl`)**: Use `render.*`
   (`render.string`, `render.toolchain`, `render.call`, `render.list`) instead of
-  `repr()` when generating Starlark calls.
+  `repr()` for Starlark calls; use `json.encode_indent()` for data constants.
 * **`@bazel_tools` `bzl_library` Deps**: Use `"//python/private:bazel_tools"` in
   `bzl_library` `deps` for files loading `@bazel_tools//...`.
+
+## WORKSPACE & Bzlmod Parity
+* Match Bzlmod extension defaults, tag schemas (e.g., `configure` list of
+  dicts), and single-hub multi-version structure in `WORKSPACE` macros. Share
+  configuration and hub logic in common private `.bzl` helpers.
+* When `WORKSPACE` repos depend on downloaded manifests, split setup into a
+  manifest repo rule (writes unfiltered `DIST_MANIFESTS` and a bound
+  registration macro to `dist_manifest.bzl`) and a registration macro (filters
+  platforms, instantiates tool repos, and registers the hub; also accepts
+  explicit `urls` without a manifest).
diff --git a/.agents/rules/starlark.md b/.agents/rules/starlark.md
index be11bf0..e4becec 100644
--- a/.agents/rules/starlark.md
+++ b/.agents/rules/starlark.md
@@ -72,6 +72,9 @@
   render `BUILD.bazel` in the rule implementation.
 * **Single-Value Templates**: For generated file templates with one interpolated
   value, use a top-level string and `.format()`.
+* **Data Constants in Generated `.bzl` Files**: Use `json.encode_indent()` to
+  write JSON-compatible data (`dict`, `list`, `str`, `int` without `bool` or
+  `None`) as `.bzl` constants instead of custom formatting helpers.
 * **Reuse `http_file`**: Use `http_file` from
   `@bazel_tools//tools/build_defs/repo:http.bzl` for single-file downloads. Omit
   `downloaded_file_path` unless required and reference `@<repo>//file`.
@@ -124,6 +127,9 @@
   instead of passing them through `**kwargs`. Document `Args:` and `Returns:`.
 * **Docstring Formatting Invariants**: Use triple-quoted strings for multi-line
   docstrings without trailing backslashes (`\`) for line continuation.
+* **Concise API Docstrings**: Keep docstrings brief: state purpose and
+  arguments, link to shared symbols (`{obj}`) or guides (`{ref}`) instead of
+  repeating rules, and put extended examples in `docs/`.
 * **Workaround Comments**: Comment non-obvious workarounds with the intent, why
   the direct approach fails, and why the workaround works.
 * **No Bazel Copyright Headers**: Do not add Bazel copyright headers to new or