guild-cli 0.19.1__tar.gz → 0.19.3__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (121) hide show
  1. {guild_cli-0.19.1 → guild_cli-0.19.3}/.claude/skills/guild/SKILL.md +4 -1
  2. {guild_cli-0.19.1 → guild_cli-0.19.3}/.claude/skills/guild/scripts/configure-repo.sh +44 -8
  3. guild_cli-0.19.3/.eidetic/memory/default__public.jsonl +1 -0
  4. {guild_cli-0.19.1 → guild_cli-0.19.3}/.eidetic/memory/guildmaster__public.jsonl +4 -2
  5. {guild_cli-0.19.1 → guild_cli-0.19.3}/CHANGELOG.md +49 -0
  6. {guild_cli-0.19.1 → guild_cli-0.19.3}/CLAUDE.md +1 -1
  7. {guild_cli-0.19.1 → guild_cli-0.19.3}/PKG-INFO +1 -1
  8. {guild_cli-0.19.1 → guild_cli-0.19.3}/docs/skill-sources.md +12 -12
  9. {guild_cli-0.19.1 → guild_cli-0.19.3}/pyproject.toml +1 -1
  10. guild_cli-0.19.3/tests/test_configure_repo_sonar.py +165 -0
  11. {guild_cli-0.19.1 → guild_cli-0.19.3}/uv.lock +1 -1
  12. {guild_cli-0.19.1 → guild_cli-0.19.3}/.claude/skills/agent-config/SKILL.md +0 -0
  13. {guild_cli-0.19.1 → guild_cli-0.19.3}/.claude/skills/agent-config/data/backend-fingerprints.yaml +0 -0
  14. {guild_cli-0.19.1 → guild_cli-0.19.3}/.claude/skills/agent-config/scripts/show.sh +0 -0
  15. {guild_cli-0.19.1 → guild_cli-0.19.3}/.claude/skills/ask-colleague/SKILL.md +0 -0
  16. {guild_cli-0.19.1 → guild_cli-0.19.3}/.claude/skills/ask-colleague/prompts/explore.md +0 -0
  17. {guild_cli-0.19.1 → guild_cli-0.19.3}/.claude/skills/ask-colleague/prompts/review.md +0 -0
  18. {guild_cli-0.19.1 → guild_cli-0.19.3}/.claude/skills/ask-colleague/prompts/write.md +0 -0
  19. {guild_cli-0.19.1 → guild_cli-0.19.3}/.claude/skills/ask-colleague/scripts/ask-colleague.sh +0 -0
  20. {guild_cli-0.19.1 → guild_cli-0.19.3}/.claude/skills/assign-to-workforce/SKILL.md +0 -0
  21. {guild_cli-0.19.1 → guild_cli-0.19.3}/.claude/skills/assign-to-workforce/scripts/assign-to-workforce.sh +0 -0
  22. {guild_cli-0.19.1 → guild_cli-0.19.3}/.claude/skills/cicd/SKILL.md +0 -0
  23. {guild_cli-0.19.1 → guild_cli-0.19.3}/.claude/skills/cicd/scripts/_resolve-nick.sh +0 -0
  24. {guild_cli-0.19.1 → guild_cli-0.19.3}/.claude/skills/cicd/scripts/portability-lint.sh +0 -0
  25. {guild_cli-0.19.1 → guild_cli-0.19.3}/.claude/skills/cicd/scripts/pr-reply.sh +0 -0
  26. {guild_cli-0.19.1 → guild_cli-0.19.3}/.claude/skills/cicd/scripts/pr-status.sh +0 -0
  27. {guild_cli-0.19.1 → guild_cli-0.19.3}/.claude/skills/cicd/scripts/workflow.sh +0 -0
  28. {guild_cli-0.19.1 → guild_cli-0.19.3}/.claude/skills/communicate/SKILL.md +0 -0
  29. {guild_cli-0.19.1 → guild_cli-0.19.3}/.claude/skills/communicate/scripts/fetch-issues.sh +0 -0
  30. {guild_cli-0.19.1 → guild_cli-0.19.3}/.claude/skills/communicate/scripts/mesh-message.sh +0 -0
  31. {guild_cli-0.19.1 → guild_cli-0.19.3}/.claude/skills/communicate/scripts/post-comment.sh +0 -0
  32. {guild_cli-0.19.1 → guild_cli-0.19.3}/.claude/skills/communicate/scripts/post-issue.sh +0 -0
  33. {guild_cli-0.19.1 → guild_cli-0.19.3}/.claude/skills/communicate/scripts/templates/skill-new-brief.md +0 -0
  34. {guild_cli-0.19.1 → guild_cli-0.19.3}/.claude/skills/communicate/scripts/templates/skill-update-brief.md +0 -0
  35. {guild_cli-0.19.1 → guild_cli-0.19.3}/.claude/skills/doc-test-alignment/SKILL.md +0 -0
  36. {guild_cli-0.19.1 → guild_cli-0.19.3}/.claude/skills/doc-test-alignment/scripts/check.sh +0 -0
  37. {guild_cli-0.19.1 → guild_cli-0.19.3}/.claude/skills/guild/scripts/create.sh +0 -0
  38. {guild_cli-0.19.1 → guild_cli-0.19.3}/.claude/skills/guild/scripts/overview.sh +0 -0
  39. {guild_cli-0.19.1 → guild_cli-0.19.3}/.claude/skills/onboard/SKILL.md +0 -0
  40. {guild_cli-0.19.1 → guild_cli-0.19.3}/.claude/skills/onboard/scripts/onboard.sh +0 -0
  41. {guild_cli-0.19.1 → guild_cli-0.19.3}/.claude/skills/outsource/SKILL.md +0 -0
  42. {guild_cli-0.19.1 → guild_cli-0.19.3}/.claude/skills/outsource/prompts/explore.md +0 -0
  43. {guild_cli-0.19.1 → guild_cli-0.19.3}/.claude/skills/outsource/prompts/review.md +0 -0
  44. {guild_cli-0.19.1 → guild_cli-0.19.3}/.claude/skills/outsource/prompts/write.md +0 -0
  45. {guild_cli-0.19.1 → guild_cli-0.19.3}/.claude/skills/outsource/scripts/outsource.sh +0 -0
  46. {guild_cli-0.19.1 → guild_cli-0.19.3}/.claude/skills/pypi-maintainer/SKILL.md +0 -0
  47. {guild_cli-0.19.1 → guild_cli-0.19.3}/.claude/skills/pypi-maintainer/scripts/switch-source.sh +0 -0
  48. {guild_cli-0.19.1 → guild_cli-0.19.3}/.claude/skills/recall/SKILL.md +0 -0
  49. {guild_cli-0.19.1 → guild_cli-0.19.3}/.claude/skills/recall/scripts/recall.sh +0 -0
  50. {guild_cli-0.19.1 → guild_cli-0.19.3}/.claude/skills/remember/SKILL.md +0 -0
  51. {guild_cli-0.19.1 → guild_cli-0.19.3}/.claude/skills/remember/scripts/remember.sh +0 -0
  52. {guild_cli-0.19.1 → guild_cli-0.19.3}/.claude/skills/run-tests/SKILL.md +0 -0
  53. {guild_cli-0.19.1 → guild_cli-0.19.3}/.claude/skills/run-tests/scripts/test.sh +0 -0
  54. {guild_cli-0.19.1 → guild_cli-0.19.3}/.claude/skills/sonarclaude/SKILL.md +0 -0
  55. {guild_cli-0.19.1 → guild_cli-0.19.3}/.claude/skills/sonarclaude/scripts/sonar.sh +0 -0
  56. {guild_cli-0.19.1 → guild_cli-0.19.3}/.claude/skills/spec-to-plan/SKILL.md +0 -0
  57. {guild_cli-0.19.1 → guild_cli-0.19.3}/.claude/skills/spec-to-plan/scripts/spec-to-plan.sh +0 -0
  58. {guild_cli-0.19.1 → guild_cli-0.19.3}/.claude/skills/teach/SKILL.md +0 -0
  59. {guild_cli-0.19.1 → guild_cli-0.19.3}/.claude/skills/teach/scripts/teach.sh +0 -0
  60. {guild_cli-0.19.1 → guild_cli-0.19.3}/.claude/skills/think/SKILL.md +0 -0
  61. {guild_cli-0.19.1 → guild_cli-0.19.3}/.claude/skills/think/scripts/think.sh +0 -0
  62. {guild_cli-0.19.1 → guild_cli-0.19.3}/.claude/skills/version-bump/SKILL.md +0 -0
  63. {guild_cli-0.19.1 → guild_cli-0.19.3}/.claude/skills/version-bump/scripts/bump.py +0 -0
  64. {guild_cli-0.19.1 → guild_cli-0.19.3}/.claude/skills.local.yaml.example +0 -0
  65. {guild_cli-0.19.1 → guild_cli-0.19.3}/.devague/frames/guildmaster-ships-teach-and-onboard-two-agent-firs.json +0 -0
  66. {guild_cli-0.19.1 → guild_cli-0.19.3}/.devague/plans/guildmaster-ships-teach-and-onboard-two-agent-firs.json +0 -0
  67. {guild_cli-0.19.1 → guild_cli-0.19.3}/.flake8 +0 -0
  68. {guild_cli-0.19.1 → guild_cli-0.19.3}/.github/workflows/publish.yml +0 -0
  69. {guild_cli-0.19.1 → guild_cli-0.19.3}/.github/workflows/tests.yml +0 -0
  70. {guild_cli-0.19.1 → guild_cli-0.19.3}/.gitignore +0 -0
  71. {guild_cli-0.19.1 → guild_cli-0.19.3}/.markdownlint-cli2.yaml +0 -0
  72. {guild_cli-0.19.1 → guild_cli-0.19.3}/LICENSE +0 -0
  73. {guild_cli-0.19.1 → guild_cli-0.19.3}/README.md +0 -0
  74. {guild_cli-0.19.1 → guild_cli-0.19.3}/culture.yaml +0 -0
  75. {guild_cli-0.19.1 → guild_cli-0.19.3}/docs/cutover.md +0 -0
  76. {guild_cli-0.19.1 → guild_cli-0.19.3}/docs/onboarding/reachy-mini-mcp.json +0 -0
  77. {guild_cli-0.19.1 → guild_cli-0.19.3}/docs/plans/2026-05-24-guildmaster-ships-teach-and-onboard-two-agent-firs.md +0 -0
  78. {guild_cli-0.19.1 → guild_cli-0.19.3}/docs/specs/2026-05-24-guildmaster-ships-teach-and-onboard-two-agent-firs.md +0 -0
  79. {guild_cli-0.19.1 → guild_cli-0.19.3}/guild/__init__.py +0 -0
  80. {guild_cli-0.19.1 → guild_cli-0.19.3}/guild/__main__.py +0 -0
  81. {guild_cli-0.19.1 → guild_cli-0.19.3}/guild/cli/__init__.py +0 -0
  82. {guild_cli-0.19.1 → guild_cli-0.19.3}/guild/cli/_commands/__init__.py +0 -0
  83. {guild_cli-0.19.1 → guild_cli-0.19.3}/guild/cli/_commands/_broadcast.py +0 -0
  84. {guild_cli-0.19.1 → guild_cli-0.19.3}/guild/cli/_commands/_provision_template.py +0 -0
  85. {guild_cli-0.19.1 → guild_cli-0.19.3}/guild/cli/_commands/create.py +0 -0
  86. {guild_cli-0.19.1 → guild_cli-0.19.3}/guild/cli/_commands/explain.py +0 -0
  87. {guild_cli-0.19.1 → guild_cli-0.19.3}/guild/cli/_commands/learn.py +0 -0
  88. {guild_cli-0.19.1 → guild_cli-0.19.3}/guild/cli/_commands/onboard.py +0 -0
  89. {guild_cli-0.19.1 → guild_cli-0.19.3}/guild/cli/_commands/overview.py +0 -0
  90. {guild_cli-0.19.1 → guild_cli-0.19.3}/guild/cli/_commands/show.py +0 -0
  91. {guild_cli-0.19.1 → guild_cli-0.19.3}/guild/cli/_commands/teach.py +0 -0
  92. {guild_cli-0.19.1 → guild_cli-0.19.3}/guild/cli/_commands/whoami.py +0 -0
  93. {guild_cli-0.19.1 → guild_cli-0.19.3}/guild/cli/_errors.py +0 -0
  94. {guild_cli-0.19.1 → guild_cli-0.19.3}/guild/cli/_output.py +0 -0
  95. {guild_cli-0.19.1 → guild_cli-0.19.3}/guild/cli/_repo.py +0 -0
  96. {guild_cli-0.19.1 → guild_cli-0.19.3}/guild/scaffold/__init__.py +0 -0
  97. {guild_cli-0.19.1 → guild_cli-0.19.3}/guild/scaffold/instantiate.py +0 -0
  98. {guild_cli-0.19.1 → guild_cli-0.19.3}/guild/skills/__init__.py +0 -0
  99. {guild_cli-0.19.1 → guild_cli-0.19.3}/guild/skills/identity.py +0 -0
  100. {guild_cli-0.19.1 → guild_cli-0.19.3}/guild/skills/ledger.py +0 -0
  101. {guild_cli-0.19.1 → guild_cli-0.19.3}/guild/skills/render.py +0 -0
  102. {guild_cli-0.19.1 → guild_cli-0.19.3}/guild/skills/sources.py +0 -0
  103. {guild_cli-0.19.1 → guild_cli-0.19.3}/sonar-project.properties +0 -0
  104. {guild_cli-0.19.1 → guild_cli-0.19.3}/tests/__init__.py +0 -0
  105. {guild_cli-0.19.1 → guild_cli-0.19.3}/tests/test_broadcast_post.py +0 -0
  106. {guild_cli-0.19.1 → guild_cli-0.19.3}/tests/test_cli.py +0 -0
  107. {guild_cli-0.19.1 → guild_cli-0.19.3}/tests/test_cli_create.py +0 -0
  108. {guild_cli-0.19.1 → guild_cli-0.19.3}/tests/test_cli_explain.py +0 -0
  109. {guild_cli-0.19.1 → guild_cli-0.19.3}/tests/test_cli_learn.py +0 -0
  110. {guild_cli-0.19.1 → guild_cli-0.19.3}/tests/test_cli_onboard.py +0 -0
  111. {guild_cli-0.19.1 → guild_cli-0.19.3}/tests/test_cli_overview.py +0 -0
  112. {guild_cli-0.19.1 → guild_cli-0.19.3}/tests/test_cli_show.py +0 -0
  113. {guild_cli-0.19.1 → guild_cli-0.19.3}/tests/test_cli_teach.py +0 -0
  114. {guild_cli-0.19.1 → guild_cli-0.19.3}/tests/test_cli_whoami.py +0 -0
  115. {guild_cli-0.19.1 → guild_cli-0.19.3}/tests/test_scaffold_instantiate.py +0 -0
  116. {guild_cli-0.19.1 → guild_cli-0.19.3}/tests/test_skills_convention.py +0 -0
  117. {guild_cli-0.19.1 → guild_cli-0.19.3}/tests/test_skills_identity.py +0 -0
  118. {guild_cli-0.19.1 → guild_cli-0.19.3}/tests/test_skills_ledger.py +0 -0
  119. {guild_cli-0.19.1 → guild_cli-0.19.3}/tests/test_skills_render.py +0 -0
  120. {guild_cli-0.19.1 → guild_cli-0.19.3}/tests/test_skills_sources.py +0 -0
  121. {guild_cli-0.19.1 → guild_cli-0.19.3}/tests/test_version_fallback.py +0 -0
@@ -146,7 +146,10 @@ Provision a new sibling by instantiating the GitHub template and customising it:
146
146
  (`[project].name`, the `importlib.metadata` lookup, the TestPyPI install
147
147
  pin) — the command + import package stay the repo name
148
148
  4. Runs `configure-repo.sh` to apply GitHub settings (branch protection,
149
- environments, `SONAR_TOKEN` placeholder).
149
+ environments, and the `SONAR_TOKEN` secret — seeded from the operator's own
150
+ exported `$SONAR_TOKEN` so SonarCloud runs from the sibling's first PR;
151
+ created empty with a warning only if that env var is unset; an existing
152
+ secret is never clobbered).
150
153
  5. Stages, commits (`scaffold <bare> from culture-agent-template`), and pushes.
151
154
  6. Registers the new agent in `docs/skill-sources.md` (idempotent).
152
155
 
@@ -9,8 +9,9 @@ set -euo pipefail
9
9
  # 1. delete_branch_on_merge = true (auto-delete head branches on merge)
10
10
  # 2. environments: pypi, testpypi (Trusted Publishing targets for publish.yml)
11
11
  # 3. ruleset "Protect main" (block deletion + non-fast-forward; require a PR)
12
- # 4. secret SONAR_TOKEN (created EMPTY if absent; never clobbers an
13
- # existing value override it in the GitHub UI)
12
+ # 4. secret SONAR_TOKEN (seeded from the operator's exported
13
+ # $SONAR_TOKEN; created EMPTY only if that is
14
+ # unset; never clobbers an existing value)
14
15
  #
15
16
  # Idempotent: the ruleset is created only if no ruleset of that name exists, and
16
17
  # the secret is set only if it is not already present. Dry-run by default.
@@ -111,14 +112,49 @@ else
111
112
  JSON
112
113
  fi
113
114
 
114
- # 4. SONAR_TOKEN secret (empty placeholder; never clobber an override) -------
115
+ # 4. SONAR_TOKEN secret (seed from the operator's env; never clobber) --------
116
+ #
117
+ # The template's tests.yml gates its SonarCloud step on `env.SONAR_TOKEN != ''`,
118
+ # so an EMPTY secret does not mean "unconfigured" — it means the sibling is
119
+ # never analysed, silently. Seed it from the operator's own exported
120
+ # $SONAR_TOKEN so a new repo is analysed from its first PR. An already-present
121
+ # secret is never clobbered: the value in GitHub wins.
122
+ sonar_token="${SONAR_TOKEN:-}"
123
+ # A whitespace-only value is as useless as an empty one; treat it as absent.
124
+ [[ -z "${sonar_token//[[:space:]]/}" ]] && sonar_token=""
125
+
115
126
  if ! $apply; then
116
- echo " would: ensure secret '$SONAR_SECRET' (created empty if absent; never clobbers an override)"
117
- elif gh secret list --repo "$repo" 2>/dev/null | grep -q "^${SONAR_SECRET}\b"; then
118
- echo " • secret '$SONAR_SECRET' already set — leaving it (override lives in GitHub)"
127
+ if [[ -n "$sonar_token" ]]; then
128
+ echo " would: set secret '$SONAR_SECRET' from the exported \$SONAR_TOKEN (never clobbers an existing secret)"
129
+ else
130
+ echo " would: create EMPTY secret '$SONAR_SECRET' — \$SONAR_TOKEN is not exported, so SonarCloud would never run here"
131
+ fi
119
132
  else
120
- echo " create empty secret '$SONAR_SECRET' (override it in the GitHub UI)"
121
- printf '' | gh secret set "$SONAR_SECRET" --repo "$repo" >/dev/null
133
+ # "Never clobber" is a safety guarantee, so the presence check must fail
134
+ # CLOSED: if we cannot reliably list the repo's secrets, refuse to set
135
+ # rather than risk overwriting an operator's token. (In an `elif`
136
+ # condition, a `gh` failure is invisible to `set -e` and would otherwise
137
+ # fall through to `gh secret set`.) Match the secret NAME in the first
138
+ # column only — no `grep \b`, which is a GNU/PCRE extension and not portable
139
+ # across grep implementations (this box ships ugrep, not GNU grep).
140
+ if ! secrets_out=$(gh secret list --repo "$repo" 2>&1); then
141
+ printf '%s\n' "$secrets_out" >&2
142
+ echo " ✗ cannot list secrets for '$repo' — refusing to set '$SONAR_SECRET' (never-clobber)" >&2
143
+ exit 1
144
+ fi
145
+ if printf '%s\n' "$secrets_out" | awk '{print $1}' | grep -Fxq "$SONAR_SECRET"; then
146
+ echo " • secret '$SONAR_SECRET' already set — leaving it (the value in GitHub wins)"
147
+ elif [[ -n "$sonar_token" ]]; then
148
+ # stdin, not argv: the token must not reach the process table.
149
+ printf '%s' "$sonar_token" | gh secret set "$SONAR_SECRET" --repo "$repo" >/dev/null
150
+ echo " ✓ set secret '$SONAR_SECRET' from the exported \$SONAR_TOKEN"
151
+ else
152
+ printf '' | gh secret set "$SONAR_SECRET" --repo "$repo" >/dev/null
153
+ echo " ✓ create empty secret '$SONAR_SECRET'"
154
+ echo " ! \$SONAR_TOKEN was not exported, so '$SONAR_SECRET' is EMPTY and SonarCloud" >&2
155
+ echo " analysis will be SKIPPED on this repo (tests.yml gates on env.SONAR_TOKEN != '')." >&2
156
+ echo " hint: export SONAR_TOKEN=<token> && gh secret set $SONAR_SECRET --repo $repo" >&2
157
+ fi
122
158
  fi
123
159
 
124
160
  echo "── done ──"
@@ -0,0 +1 @@
1
+ {"id": "plan-3layer-memory-evolution-2026-06-20", "hash": "db353fae964d96158a26d878e9a159ec5f6e8877cf3dba0a6c34e7e86b7535c3", "content": "3-layer memory evolution plan for eidetic-cli (requested 2026-06-20 by Ori). Layer 1 Migration: migrate the old ~/.claude memory skill data into eidetic across all stores \u2014 files (core.md, notes.md), Neo4j knowledge graph, MongoDB RAG. Eidetic becomes the drop-in replacement. Layer 2 Freshness/Temporal: every record carries a date signature and is temporal; signal strength degrades over time (a year-old fact is weaker than a fresh one); recalling and validating a fact reinforces its signal; remembering a new fact connected to an old one keeps them linked and the stronger validated one gains signal. Layer 3 No active deletion: memory is never actively deleted; a conflicting memory with a stronger signal shadows (supersedes but preserves) the older one; memory older than one year is archived. Open question to investigate: does the old memory solution already have a freshness mechanism. Skills to use: think (devague spec), remember, ask-colleague (explore/work/review).", "scope": {"name": "default", "visibility": "public"}, "metadata": {"type": "note", "record_metadata": {"source": "claude-code-session", "author": "Ori", "timestamp": "2026-06-20", "topic": "memory-architecture", "status": "proposed-spec", "relates_to": "eidetic-memory-surface"}, "created": "date-unknown", "last_recall": "2026-07-10T14:54:03.866682+00:00", "recall_count": 13, "links": [], "supersedes": null, "lifecycle": "active", "added_by": null}}
@@ -1,2 +1,4 @@
1
- {"id": "league-of-agents-platform-created-2026-07-10", "hash": "f380d634b886b82f4384e756bbfc3c2ac06c649a0b9577ae3bc231ccc8584b3d", "content": "2026-07-10: guild create --apply provisioned public agentculture/league-of-agents-platform \u2014 the HOSTING layer that runs the league-of-agents arena online at https://league-of-agents.ai as a turn-based game for humans AND agents (fun + benchmark). It does not reimplement the arena; it runs it. Distinct lane from league-of-agents (the runtime) \u2014 do not conflate. Identifiers: command league-site, import pkg league_site, dist league-of-agents-platform (= repo token, so no --dist override), backend claude, public, full 14-skill kit. Four defining properties: (1) turn-based for humans+agents \u2014 one state projected into two faces via the agentfront contract; (2) works everywhere \u2014 polling is a legitimate client; (3) continuable \u2014 the arena's append-only event log with a stable state_hash IS the resume substrate, do not invent session storage; (4) safeguards vs overload \u2014 enforced safe capacity (queue or refuse, never degrade silently), price-aware S3 archival, cleanup of abandoned matches; the last two are destructive so dry-run by default. AWS-hosted; long-term storage is cloud: S3 for logs/replays (the arena's self-contained single-file HTML replay is a perfect S3 object, and archived matches must stay replayable straight from the bucket), MongoDB + Neo4j for live state and standings. Ledger registration = guildmaster PR #86 (v0.19.1, PATCH). Build brief = league-of-agents-platform#1. Cross-link ask = katvan#59. Closest repo-shape precedent is culture-tools: a Python CLI package plus a web app (site-astro/) in one repo, against the agentfront contract. Owed: Trusted Publisher on PyPI + TestPyPI, /init, backend reconcile (culture.yaml inherits backend colleague from the template while the CLAUDE.md seed prose says claude).", "scope": {"name": "guildmaster", "visibility": "public"}, "metadata": {"type": "project", "record_metadata": {"scope": "guildmaster", "repo": "guildmaster", "agent": "league-of-agents-platform", "pr": 86, "date": "2026-07-10"}, "created": "2026-07-10T03:58:39.269155+00:00", "last_recall": "2026-07-10T03:59:10.523667+00:00", "recall_count": 1, "links": ["guild-create-desc-350-char-limit"], "supersedes": null, "lifecycle": "active", "added_by": null}}
2
- {"id": "guild-create-desc-350-char-limit", "hash": "d39fd8769ee9db74d1dd5d0e728dbc446cfd979fafff781632bab7e4b3095d9f", "content": "GOTCHA x4 \u2014 guild create emits a clone that fails its OWN CI (2026-07-10, provisioning league-of-agents-platform; filed upstream as guildmaster issue #87). One class of bug: --desc and the repo token are untrusted input to a text transform whose output must satisfy the template's own CI, and the dry-run models none of it. Durable fix recommended in #87: a post-transform CI gate that runs the clone's lint + test jobs after the rename and before the genesis commit \u2014 it catches 2,3,4 and the next one; only 1 needs a separate guard. (1) --desc over 350 chars breaks gh repo create: GitHub caps repo descriptions at 350 chars; the dry-run prints a clean plan and full ledger diff, then --apply dies with 'GraphQL: Could not clone: Description cannot be more than 350 characters'. Benign because ATOMIC \u2014 it fails before the clone, so no repo, no clone dir, no ledger write; verify with gh repo view (expect Could not resolve), ls -d ../<repo>, git status --short docs/. Contrast agent-lifecycle, where a configure-repo abort mid-apply DID leave partial state and needed register_consumer recovery. Measure with: echo -n \"$DESC\" | wc -m. Long-form scope belongs in the build-brief issue, not --desc. (2) A repo token longer than the template's overflows flake8: the rename is culture-agent-template (22 chars) to the repo token; league-of-agents-platform is 25, the first sibling token longer than the template's own, so two lines just under flake8's 100-char limit spilled over and the genesis Tests run landed red. Every earlier sibling had a shorter token so the rename always SHORTENED these lines and the latent overflow never fired. It fires again for any token over 22 chars. (3) A bare URL in --desc fails the clone's markdownlint: --desc is injected verbatim into the README.md intro AND the CLAUDE.md seed; a bare https:// URL is MD034/no-bare-urls and the template's lint job runs markdownlint-cli2 '**/*.md'. Angle-bracket it. The right upstream fix is to autolink, not to refuse \u2014 naming your site in your description is reasonable. (4) THE CONSEQUENTIAL ONE \u2014 --command different from the repo token fails the rubric gate: teken cli doctor --strict's explain_self check runs '<console-script> explain <console-script>'. The explain catalog keys its root entry by the REPO TOKEN (what the rename tracks) while --command retargets only the [project.scripts] entry-point key. When they differ you get 'FAIL explain_self: explain league-site exit=1', 25/26 checks, and the lint job goes red. Evidence this is a recurring MANUAL repair: every sibling whose command differs from its token carries BOTH root keys, hand-added \u2014 reachy-mini-cli (reachy), discord-bot-cli (discord), jetson-ai-lab-cli (jlab), dgx-spark-cli (spark), unsloth-cli (sloth). Six repos, six identical hand-fixes. Fix: guild create should add the console-script alias to the catalog root when --command differs from the token; it is a no-op when they are equal, so the byte-identical no-override guarantee holds. So the --command retarget gap is NOT merely cosmetic \u2014 CI enforces the catalog. Docstrings and learn prose are a softer, separate call.", "scope": {"name": "guildmaster", "visibility": "public"}, "metadata": {"type": "gotcha", "record_metadata": {"scope": "guildmaster", "repo": "guildmaster", "tool": "guild create", "issue": 87, "date": "2026-07-10"}, "created": "2026-07-10T04:08:22.598281+00:00", "last_recall": null, "recall_count": 0, "links": ["league-of-agents-platform-created-2026-07-10"], "supersedes": null, "lifecycle": "active", "added_by": null}}
1
+ {"id": "league-of-agents-platform-created-2026-07-10", "hash": "f380d634b886b82f4384e756bbfc3c2ac06c649a0b9577ae3bc231ccc8584b3d", "content": "2026-07-10: guild create --apply provisioned public agentculture/league-of-agents-platform \u2014 the HOSTING layer that runs the league-of-agents arena online at https://league-of-agents.ai as a turn-based game for humans AND agents (fun + benchmark). It does not reimplement the arena; it runs it. Distinct lane from league-of-agents (the runtime) \u2014 do not conflate. Identifiers: command league-site, import pkg league_site, dist league-of-agents-platform (= repo token, so no --dist override), backend claude, public, full 14-skill kit. Four defining properties: (1) turn-based for humans+agents \u2014 one state projected into two faces via the agentfront contract; (2) works everywhere \u2014 polling is a legitimate client; (3) continuable \u2014 the arena's append-only event log with a stable state_hash IS the resume substrate, do not invent session storage; (4) safeguards vs overload \u2014 enforced safe capacity (queue or refuse, never degrade silently), price-aware S3 archival, cleanup of abandoned matches; the last two are destructive so dry-run by default. AWS-hosted; long-term storage is cloud: S3 for logs/replays (the arena's self-contained single-file HTML replay is a perfect S3 object, and archived matches must stay replayable straight from the bucket), MongoDB + Neo4j for live state and standings. Ledger registration = guildmaster PR #86 (v0.19.1, PATCH). Build brief = league-of-agents-platform#1. Cross-link ask = katvan#59. Closest repo-shape precedent is culture-tools: a Python CLI package plus a web app (site-astro/) in one repo, against the agentfront contract. Owed: Trusted Publisher on PyPI + TestPyPI, /init, backend reconcile (culture.yaml inherits backend colleague from the template while the CLAUDE.md seed prose says claude).", "scope": {"name": "guildmaster", "visibility": "public"}, "metadata": {"type": "project", "record_metadata": {"scope": "guildmaster", "repo": "guildmaster", "agent": "league-of-agents-platform", "pr": 86, "date": "2026-07-10"}, "created": "2026-07-10T03:58:39.269155+00:00", "last_recall": "2026-07-10T14:54:03.866682+00:00", "recall_count": 2, "links": ["guild-create-desc-350-char-limit"], "supersedes": null, "lifecycle": "active", "added_by": null}}
2
+ {"id": "guild-create-desc-350-char-limit", "hash": "d39fd8769ee9db74d1dd5d0e728dbc446cfd979fafff781632bab7e4b3095d9f", "content": "GOTCHA x4 \u2014 guild create emits a clone that fails its OWN CI (2026-07-10, provisioning league-of-agents-platform; filed upstream as guildmaster issue #87). One class of bug: --desc and the repo token are untrusted input to a text transform whose output must satisfy the template's own CI, and the dry-run models none of it. Durable fix recommended in #87: a post-transform CI gate that runs the clone's lint + test jobs after the rename and before the genesis commit \u2014 it catches 2,3,4 and the next one; only 1 needs a separate guard. (1) --desc over 350 chars breaks gh repo create: GitHub caps repo descriptions at 350 chars; the dry-run prints a clean plan and full ledger diff, then --apply dies with 'GraphQL: Could not clone: Description cannot be more than 350 characters'. Benign because ATOMIC \u2014 it fails before the clone, so no repo, no clone dir, no ledger write; verify with gh repo view (expect Could not resolve), ls -d ../<repo>, git status --short docs/. Contrast agent-lifecycle, where a configure-repo abort mid-apply DID leave partial state and needed register_consumer recovery. Measure with: echo -n \"$DESC\" | wc -m. Long-form scope belongs in the build-brief issue, not --desc. (2) A repo token longer than the template's overflows flake8: the rename is culture-agent-template (22 chars) to the repo token; league-of-agents-platform is 25, the first sibling token longer than the template's own, so two lines just under flake8's 100-char limit spilled over and the genesis Tests run landed red. Every earlier sibling had a shorter token so the rename always SHORTENED these lines and the latent overflow never fired. It fires again for any token over 22 chars. (3) A bare URL in --desc fails the clone's markdownlint: --desc is injected verbatim into the README.md intro AND the CLAUDE.md seed; a bare https:// URL is MD034/no-bare-urls and the template's lint job runs markdownlint-cli2 '**/*.md'. Angle-bracket it. The right upstream fix is to autolink, not to refuse \u2014 naming your site in your description is reasonable. (4) THE CONSEQUENTIAL ONE \u2014 --command different from the repo token fails the rubric gate: teken cli doctor --strict's explain_self check runs '<console-script> explain <console-script>'. The explain catalog keys its root entry by the REPO TOKEN (what the rename tracks) while --command retargets only the [project.scripts] entry-point key. When they differ you get 'FAIL explain_self: explain league-site exit=1', 25/26 checks, and the lint job goes red. Evidence this is a recurring MANUAL repair: every sibling whose command differs from its token carries BOTH root keys, hand-added \u2014 reachy-mini-cli (reachy), discord-bot-cli (discord), jetson-ai-lab-cli (jlab), dgx-spark-cli (spark), unsloth-cli (sloth). Six repos, six identical hand-fixes. Fix: guild create should add the console-script alias to the catalog root when --command differs from the token; it is a no-op when they are equal, so the byte-identical no-override guarantee holds. So the --command retarget gap is NOT merely cosmetic \u2014 CI enforces the catalog. Docstrings and learn prose are a softer, separate call.", "scope": {"name": "guildmaster", "visibility": "public"}, "metadata": {"type": "gotcha", "record_metadata": {"scope": "guildmaster", "repo": "guildmaster", "tool": "guild create", "issue": 87, "date": "2026-07-10"}, "created": "2026-07-10T04:08:22.598281+00:00", "last_recall": "2026-07-10T14:54:03.866682+00:00", "recall_count": 1, "links": ["league-of-agents-platform-created-2026-07-10"], "supersedes": null, "lifecycle": "active", "added_by": null}}
3
+ {"id": "org-created-private-2026-07-10", "hash": "aa3a32ca4e097147695076329d3b04b616826cf5eb5aa6a203b91556e80b7ead", "content": "2026-07-10: guild create --apply provisioned PRIVATE agentculture/org \u2014 the AgentCulture org site: source of the web presence published to AgentCulture.org, REPLACING the deleted landing-page repo (deleted outright, never registered in the ledger, no redirect, no surviving local checkout \u2014 no content migration, the site starts fresh). Identifiers: command = pkg = dist = repo token org, backend claude. FIRST no-PyPI sibling: the user asked for no PyPI package, and guild create has no flag for it, so the PyPI lane was stripped post-create as operator-side provisioning (NOT product hand-building): deleted publish.yml, dropped the vendored pypi-maintainer skill + its row in org docs/skill-sources.md, reworded README baseline bullet + version-check comment; org is intentionally excluded from guildmaster pypi-maintainer ledger row WITH an explicit note so the gap reads as intent. TWO OPERATIONAL FACTS: (1) the genesis push fires one doomed Publish-to-PyPI run before you can strip it \u2014 completed red before it could be cancelled, one-time and harmless; (2) main-requires-PR ruleset is active on private repos (paid plan), so the post-create fix could NOT be pushed to main directly \u2014 it needed branch + version bump (org 0.4.0\u21920.4.1) + PR: landed as org#1 (merged), which also means the build brief landed at org#2 (same slot-shift as league-of-agents). Ledger registration = guildmaster PR #88 (v0.19.2, PATCH). Owed: /init, backend reconcile (template culture.yaml ships backend colleague vs seed prose claude), site stack + IA proposal on org#2, deploy workflow (Pages/S3/Cloudflare \u2014 private repo, public site) + operator-owned DNS cutover for AgentCulture.org. Repo-shape precedent for the brief = culture-tools (CLI + site dir in one repo).", "scope": {"name": "guildmaster", "visibility": "public"}, "metadata": {"type": "project", "record_metadata": {"scope": "guildmaster", "repo": "guildmaster", "agent": "org", "pr": 88, "date": "2026-07-10"}, "created": "2026-07-10T15:08:06.175651+00:00", "last_recall": null, "recall_count": 0, "links": ["league-of-agents-platform-created-2026-07-10", "guild-create-desc-350-char-limit"], "supersedes": null, "lifecycle": "active", "added_by": null}}
4
+ {"id": "guild-create-seeds-sonar-token-2026-07-10", "hash": "0cefcc3f176f52199c30273f51cbc74271e20c6921caa45115b41e2ffe87c1b6", "content": "Fixed 2026-07-10, guildmaster PR #89 (v0.19.3). guild create's configure-repo.sh step 4 used to create the new sibling's SONAR_TOKEN repo secret EMPTY. The culture-agent-template tests.yml gates its SonarCloud step on env.SONAR_TOKEN != '', so an empty secret means SonarCloud NEVER runs on that repo, silently \u2014 and the operator had been pasting the token into each new repo's GitHub UI by hand. The fix: step 4 now seeds the secret from the operator's own exported $SONAR_TOKEN, passed on STDIN not argv (the process table is world-readable). When $SONAR_TOKEN is unset it still writes the empty placeholder but WARNS to stderr with the exact gh secret set command to fix it. An already-present secret is NEVER clobbered (the value in GitHub wins); a whitespace-only token is treated as absent. Test: tests/test_configure_repo_sonar.py runs the REAL configure-repo.sh in --apply against a fake gh on PATH (no network) covering seed-from-env, empty+warn, never-clobber, whitespace-as-absent. Reusable pattern for testing shell scripts guildmaster ships: fake gh echoes benign responses for api and secret list and logs secret set stdin; make api .../rulesets echo the ruleset name so the script's already-present branch skips the heredoc create. GOTCHA for backfilling live repos: because the fix (correctly) never clobbers an existing secret, re-running configure-repo.sh does NOT fix a repo that already has the empty placeholder \u2014 that needs a direct 'printf %s \"$SONAR_TOKEN\" | gh secret set SONAR_TOKEN --repo <r>' override. league-of-agents-platform and org (created 2026-07-10) still carry empty secrets. Distinct still-OPEN sibling bug in the same area: cicd's pr-status.sh reads SonarCloud ANONYMOUSLY (no Authorization header, no curl -f), so for PRIVATE projects it gets HTTP 404 and reports 'Quality Gate UNKNOWN, 0 issues, 0 hotspots' \u2014 a false clean \u2014 and workflow.sh await only greps for the literal 'Quality Gate ERROR', so a missing/unreadable gate reads as PASS. Not fixed yet (operator chose the create-flow fix, option B).", "scope": {"name": "guildmaster", "visibility": "public"}, "metadata": {"type": "project", "record_metadata": {"scope": "guildmaster", "repo": "guildmaster", "pr": 89, "date": "2026-07-10"}, "created": "2026-07-10T15:49:28.579056+00:00", "last_recall": null, "recall_count": 0, "links": ["league-of-agents-platform-created-2026-07-10"], "supersedes": null, "lifecycle": "active", "added_by": null}}
@@ -5,6 +5,55 @@ All notable changes to this project will be documented in this file.
5
5
  Format follows [Keep a Changelog](https://keepachangelog.com/). This project
6
6
  adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [0.19.3] - 2026-07-10
9
+
10
+ ### Fixed
11
+
12
+ - `guild create` provisioned every new sibling with an **empty** `SONAR_TOKEN`
13
+ secret, so SonarCloud analysis never ran on it — the template's `tests.yml`
14
+ gates its Sonar step on `env.SONAR_TOKEN != ''`, and an empty secret reads as
15
+ "unconfigured", silently. The operator then had to paste the token into each
16
+ new repo's GitHub UI by hand. `configure-repo.sh` step 4 now **seeds the
17
+ secret from the operator's own exported `$SONAR_TOKEN`** (via stdin, never
18
+ argv — the process table is world-readable), so a new repo is analysed from
19
+ its first PR. When `$SONAR_TOKEN` is unset it still creates the empty
20
+ placeholder but now **warns to stderr** that SonarCloud will be skipped, with
21
+ the exact `gh secret set` command to fix it. A secret that already exists is
22
+ never clobbered — the value in GitHub wins. A whitespace-only token is treated
23
+ as absent. Covered by `tests/test_configure_repo_sonar.py`, which runs the
24
+ real script against a fake `gh` (no network).
25
+ - Hardened the never-clobber presence check in the same step (Qodo review on
26
+ PR #89): the old `grep "^SONAR_TOKEN\b"` relied on a GNU/PCRE `\b` word
27
+ boundary that is not portable (this repo's own portability invariant, and CI
28
+ boxes may ship `ugrep`/BusyBox `grep`), and `gh secret list 2>/dev/null` in an
29
+ `elif` condition made a *listing failure* invisible to `set -e` — both could
30
+ fall through to `gh secret set` and overwrite an existing token. The check now
31
+ extracts the first column with `awk` and matches with `grep -Fxq` (fixed
32
+ string, no regex), and **fails closed**: if `gh secret list` errors, the
33
+ script aborts rather than set the secret blind. New tests assert the token
34
+ reaches `gh` on stdin and never on argv, and that a listing failure aborts
35
+ without calling `secret set`.
36
+
37
+ ### Changed
38
+
39
+ - `guild`/`SKILL.md` + `CLAUDE.md`: describe step 4 as seeding the `SONAR_TOKEN`
40
+ secret from `$SONAR_TOKEN` rather than "placeholder".
41
+
42
+ ## [0.19.2] - 2026-07-10
43
+
44
+ ### Added
45
+
46
+ - Provision `org` as a downstream consumer (private) — the AgentCulture org
47
+ site: the source of the web presence published to AgentCulture.org,
48
+ replacing the deleted `landing-page` repo. Command, import package, and
49
+ dist all default to the repo token `org`; backend `claude`.
50
+ - **No PyPI distribution** — the repo's deliverable is the published site,
51
+ not a package. The clone's `publish.yml` and vendored `pypi-maintainer`
52
+ skill were stripped post-create ([org#1](https://github.com/agentculture/org/pull/1)),
53
+ and `org` is intentionally excluded from the `pypi-maintainer` ledger row.
54
+ - `landing-page` was never registered in the ledger, so the replacement is
55
+ recorded here and in the org repo's brief, not as a ledger row migration.
56
+
8
57
  ## [0.19.1] - 2026-07-10
9
58
 
10
59
  ### Added
@@ -108,7 +108,7 @@ two live broadcasters.
108
108
 
109
109
  **Provisioning verb — `guild create` (template-instantiate a new sibling).**
110
110
 
111
- - `guild create --agent OWNER/REPO --desc TEXT [--backend claude|acp] [--workspace-root DIR] [--template agentculture/culture-agent-template] [--command NAME] [--pkg NAME] [--dist NAME] [--public] [--apply] [--json]` — provision a brand-new AgentCulture sibling by instantiating the GitHub template, renaming identifiers throughout the clone, writing a self-init CLAUDE.md seed, configuring the GitHub repo (branch protection, environments, SONAR_TOKEN placeholder), pushing the genesis commit, and registering the agent in `docs/skill-sources.md`. Dry-run by default; `--apply` executes. **New repos are private by default** (the `culture-agent-template` is itself private); pass `--public` to create an open sibling. Branch-protection rulesets (and environments) are GitHub Pro/Team-gated for private repos on free-tier accounts, so `configure-repo.sh` warns-and-skips the gated `gh` calls (any other failure stays fatal) and applies the rest — a private create still completes; re-run `configure-repo.sh` after a Pro upgrade or after going public to add the ruleset. The transform is **pure** (unit-testable against a fixture dir; no network): `culture_agent_template` → pkg (underscore form, e.g. `my_agent`), `culture-agent-template` → repo token (hyphen form, e.g. `my-agent`). **The repo token is the repo/agent identity only** — it always drives the README heading, `culture.yaml` suffix, CLAUDE.md seed, and repo URL. The **command**, **import package**, and **dist** are each independently retargetable and default to the repo token (or, for `--pkg`, the underscore form of `--command`); with no overrides the output is byte-identical to a plain rename. `--command NAME` sets the **console-command (binary) name** (default: the repo token) and retargets **only** the `[project.scripts]` entry-point key — e.g. `--command reachy` for repo `reachy-mini-cli` ships the command as `reachy`. `--pkg NAME` sets the **importable Python package** (default: the underscore form of `--command`, so command and import package stay in lock-step like `guild`/`guild`); pass it only to decouple the two. `--dist NAME` sets the **PyPI distribution name** (default: the repo token); pass e.g. `--dist jetson-cli` to publish as `jetson-cli` while keeping the command and import package as the repo token (`jetson`) — this retargets only `[project].name`, the `importlib.metadata` lookup, and the TestPyPI install pin, matching the `guild-cli`/`guild` convention without a manual post-create edit. (Renaming the dist or command does **not** register a Trusted Publisher — that needs a matching Trusted Publisher registered for the project name on PyPI/TestPyPI; `guild create` configures the GitHub side only.) The CLAUDE.md seed is a `/init`-style bootstrap placeholder — run `/init` in the new repo after provisioning to expand it into a full runtime prompt. Implementation: `guild/scaffold/instantiate.py` (pure transform: `_resolve_identifiers` + `_retarget_command` / `_retarget_dist`), `guild/cli/_commands/create.py` (CLI), `guild/cli/_commands/_provision_template.py` (injectable-runner executor), `.claude/skills/guild/scripts/create.sh` (thin wrapper).
111
+ - `guild create --agent OWNER/REPO --desc TEXT [--backend claude|acp] [--workspace-root DIR] [--template agentculture/culture-agent-template] [--command NAME] [--pkg NAME] [--dist NAME] [--public] [--apply] [--json]` — provision a brand-new AgentCulture sibling by instantiating the GitHub template, renaming identifiers throughout the clone, writing a self-init CLAUDE.md seed, configuring the GitHub repo (branch protection, environments, and the `SONAR_TOKEN` secret — seeded from the operator's own exported `$SONAR_TOKEN` so the sibling is analysed from its first PR, or created empty with a warning if that env var is unset; never clobbers an existing secret), pushing the genesis commit, and registering the agent in `docs/skill-sources.md`. Dry-run by default; `--apply` executes. **New repos are private by default** (the `culture-agent-template` is itself private); pass `--public` to create an open sibling. Branch-protection rulesets (and environments) are GitHub Pro/Team-gated for private repos on free-tier accounts, so `configure-repo.sh` warns-and-skips the gated `gh` calls (any other failure stays fatal) and applies the rest — a private create still completes; re-run `configure-repo.sh` after a Pro upgrade or after going public to add the ruleset. The transform is **pure** (unit-testable against a fixture dir; no network): `culture_agent_template` → pkg (underscore form, e.g. `my_agent`), `culture-agent-template` → repo token (hyphen form, e.g. `my-agent`). **The repo token is the repo/agent identity only** — it always drives the README heading, `culture.yaml` suffix, CLAUDE.md seed, and repo URL. The **command**, **import package**, and **dist** are each independently retargetable and default to the repo token (or, for `--pkg`, the underscore form of `--command`); with no overrides the output is byte-identical to a plain rename. `--command NAME` sets the **console-command (binary) name** (default: the repo token) and retargets **only** the `[project.scripts]` entry-point key — e.g. `--command reachy` for repo `reachy-mini-cli` ships the command as `reachy`. `--pkg NAME` sets the **importable Python package** (default: the underscore form of `--command`, so command and import package stay in lock-step like `guild`/`guild`); pass it only to decouple the two. `--dist NAME` sets the **PyPI distribution name** (default: the repo token); pass e.g. `--dist jetson-cli` to publish as `jetson-cli` while keeping the command and import package as the repo token (`jetson`) — this retargets only `[project].name`, the `importlib.metadata` lookup, and the TestPyPI install pin, matching the `guild-cli`/`guild` convention without a manual post-create edit. (Renaming the dist or command does **not** register a Trusted Publisher — that needs a matching Trusted Publisher registered for the project name on PyPI/TestPyPI; `guild create` configures the GitHub side only.) The CLAUDE.md seed is a `/init`-style bootstrap placeholder — run `/init` in the new repo after provisioning to expand it into a full runtime prompt. Implementation: `guild/scaffold/instantiate.py` (pure transform: `_resolve_identifiers` + `_retarget_command` / `_retarget_dist`), `guild/cli/_commands/create.py` (CLI), `guild/cli/_commands/_provision_template.py` (injectable-runner executor), `.claude/skills/guild/scripts/create.sh` (thin wrapper).
112
112
 
113
113
  **Inventory verbs — `overview` & `show` (the read-only surfaces).** guildmaster
114
114
  owns the mesh's *inventory* surfaces per
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: guild-cli
3
- Version: 0.19.1
3
+ Version: 0.19.3
4
4
  Summary: guildmaster — an agent and CLI that manages skills for the AgentCulture mesh.
5
5
  Project-URL: Homepage, https://github.com/agentculture/guildmaster
6
6
  Project-URL: Issues, https://github.com/agentculture/guildmaster/issues
@@ -32,14 +32,14 @@ current by `guild overview --scope mesh`.
32
32
 
33
33
  | Skill | Upstream | Downstream copies (known) | Notes |
34
34
  |-------|----------|---------------------------|-------|
35
- | `agent-config` | `guildmaster` (`.claude/skills/agent-config/`) | `agenda`, `dominion-breaker`, `colleague`, `jetson`, `reachy-mini-cli`, `jetson-ai-lab-cli`, `dgx-spark-cli`, `unsloth-cli`, `discord-bot-cli`, `arxivist`, `rtx-spark-cli`, `reachy-mini-mcp`, `tensor-cli`, `climate-cli`, `eidetic-cli`, `prove-cli`, `reduce-cli`, `refactor-cli`, `rollout-cli`, `coherence-cli`, `agent-lifecycle`, `reterminal`, `operator-cli`, `culture-core`, `ec2-cli`, `qodo-cli`, `knowledgebase-cli`, `cloudai-cli`, `ec2bedrock-cli`, `arm101-cli`, `amazing-hand-cli`, `agentculture-cli`, `data-refinery-cli`, `culture-tools`, `webglass-cli`, `jetson-orin-cli`, `jetson-thor-cli`, `drone-cli`, `fleet-cli`, `league-of-agents`, `harmonics-cli`, `french-cli`, `spanish-cli`, `league-of-agents-platform` | Inventory variant backing `guild show` ([#12](https://github.com/agentculture/guildmaster/issues/12)); `show.sh` + `data/backend-fingerprints.yaml` vendored verbatim from steward, SKILL.md reframed from alignment-judgment to inventory + `type: command` added. **Forked from steward:** steward retains its own alignment-focused `agent-config` variant; the inventory variant is guildmaster's to supply. |
36
- | `cicd` | `guildmaster` (`.claude/skills/cicd/`) — layered on `devex pr` (in `agentculture/devex`) | `afi-cli`, `devex` (adapted-thin delegate — owns `devex pr`; see [devex#53](https://github.com/agentculture/devex/pull/53)), `agtag`, `antoine`, `appsec`, `auntiepypi`, `cfafi` (still named `pr-review`), `code-lens-cli`, `culture` (still named `pr-review`), `devague`, `katvan`, `lecodeur`, `lepenseur`, `seer-cli`, `telek`, `agenda`, `dominion-breaker`, `colleague`, `jetson`, `grant` (still named `pr-review`), `reachy-mini-cli`, `jetson-ai-lab-cli`, `dgx-spark-cli`, `unsloth-cli`, `discord-bot-cli`, `arxivist`, `rtx-spark-cli`, `reachy-mini-mcp`, `tensor-cli`, `climate-cli`, `eidetic-cli`, `prove-cli`, `reduce-cli`, `refactor-cli`, `rollout-cli`, `coherence-cli`, `agent-lifecycle`, `reterminal`, `operator-cli`, `culture-core`, `ec2-cli`, `qodo-cli`, `knowledgebase-cli`, `cloudai-cli`, `ec2bedrock-cli`, `arm101-cli`, `amazing-hand-cli`, `agentculture-cli`, `data-refinery-cli`, `culture-tools`, `webglass-cli`, `jetson-orin-cli`, `jetson-thor-cli`, `drone-cli`, `fleet-cli`, `league-of-agents`, `harmonics-cli`, `french-cli`, `spanish-cli`, `league-of-agents-platform` | Thin delegate to `devex pr` for lint / open / read / reply / delta, plus guildmaster's `status` (SonarCloud quality gate + hotspots + unresolved-thread tally) and `await` (composes `devex pr read --wait` with `status`, non-zero exit on Sonar ERROR / unresolved threads) extensions. **Inverted case:** devex, as the `devex pr` upstream, vendors the skill adapted-thin — a `workflow.sh`-only pure delegate ([devex#53](https://github.com/agentculture/devex/pull/53)). Renamed from `pr-review` in steward 0.7.0; downstream copies may keep the old name on their own cadence. |
37
- | `communicate` | `guildmaster` (`.claude/skills/communicate/`) | `afi-cli`, `devex` (identifier-only — vendored steward 0.11.0; scripts current as of 0.18.0), `agtag`, `antoine`, `appsec`, `auntiepypi`, `code-lens-cli`, `culture` (still named `coordinate`), `devague`, `katvan`, `lecodeur`, `lepenseur`, `seer-cli`, `telek`, `agenda`, `dominion-breaker`, `colleague`, `jetson`, `reachy-mini-cli`, `jetson-ai-lab-cli`, `dgx-spark-cli`, `unsloth-cli`, `discord-bot-cli`, `arxivist`, `rtx-spark-cli`, `reachy-mini-mcp`, `tensor-cli`, `climate-cli`, `eidetic-cli`, `prove-cli`, `reduce-cli`, `refactor-cli`, `rollout-cli`, `coherence-cli`, `agent-lifecycle`, `reterminal`, `operator-cli`, `culture-core`, `ec2-cli`, `qodo-cli`, `knowledgebase-cli`, `cloudai-cli`, `ec2bedrock-cli`, `arm101-cli`, `amazing-hand-cli`, `agentculture-cli`, `data-refinery-cli`, `culture-tools`, `webglass-cli`, `jetson-orin-cli`, `jetson-thor-cli`, `drone-cli`, `fleet-cli`, `league-of-agents`, `harmonics-cli`, `french-cli`, `spanish-cli`, `league-of-agents-platform` | Cross-repo + mesh communication: file issues / hand off briefs to sibling-repo agents (auto-signed), comment on existing issues, fetch issues to inline state into briefs, and send live messages to Culture mesh channels (unsigned — nick is the speaker). Renamed from `coordinate` in steward 0.8.0; absorbed `gh-issues` (as `fetch-issues.sh`) in 0.9.1. Issue I/O backed by `agtag` (>=0.1) since steward 0.11.0 — signature resolves from local `culture.yaml` (override via `--as`). |
38
- | `doc-test-alignment` | `guildmaster` (`.claude/skills/doc-test-alignment/`) | `devague`, `lecodeur`, `lepenseur`, `agenda`, `dominion-breaker`, `colleague`, `jetson`, `reachy-mini-cli`, `jetson-ai-lab-cli`, `dgx-spark-cli`, `unsloth-cli`, `discord-bot-cli`, `arxivist`, `rtx-spark-cli`, `reachy-mini-mcp`, `tensor-cli`, `climate-cli`, `eidetic-cli`, `prove-cli`, `reduce-cli`, `refactor-cli`, `rollout-cli`, `coherence-cli`, `agent-lifecycle`, `reterminal`, `operator-cli`, `culture-core`, `ec2-cli`, `qodo-cli`, `knowledgebase-cli`, `cloudai-cli`, `ec2bedrock-cli`, `arm101-cli`, `amazing-hand-cli`, `agentculture-cli`, `data-refinery-cli`, `culture-tools`, `webglass-cli`, `jetson-orin-cli`, `jetson-thor-cli`, `drone-cli`, `fleet-cli`, `league-of-agents`, `harmonics-cli`, `french-cli`, `spanish-cli`, `league-of-agents-platform` | Stub; real implementation TBD. `scripts/check.sh` exits not-yet-implemented today. |
39
- | `pypi-maintainer` | `guildmaster` (`.claude/skills/pypi-maintainer/`) | `agtag`, `agenda`, `dominion-breaker`, `colleague`, `jetson`, `reachy-mini-cli`, `jetson-ai-lab-cli`, `dgx-spark-cli`, `unsloth-cli`, `discord-bot-cli`, `arxivist`, `rtx-spark-cli`, `reachy-mini-mcp`, `tensor-cli`, `climate-cli`, `eidetic-cli`, `prove-cli`, `reduce-cli`, `refactor-cli`, `rollout-cli`, `coherence-cli`, `agent-lifecycle`, `reterminal`, `operator-cli`, `culture-core`, `ec2-cli`, `qodo-cli`, `knowledgebase-cli`, `cloudai-cli`, `ec2bedrock-cli`, `arm101-cli`, `amazing-hand-cli`, `agentculture-cli`, `data-refinery-cli`, `culture-tools`, `webglass-cli`, `jetson-orin-cli`, `jetson-thor-cli`, `drone-cli`, `fleet-cli`, `league-of-agents`, `harmonics-cli`, `french-cli`, `spanish-cli`, `league-of-agents-platform` | Switches a PyPI package install between pypi / test-pypi / local. Generalised from the original culture-specific `change-package`. |
40
- | `run-tests` | `guildmaster` (`.claude/skills/run-tests/`) | `agtag`, `antoine`, `appsec`, `code-lens-cli`, `culture`, `culture-sonar-cli`, `devague`, `lecodeur`, `lepenseur`, `seer-cli`, `grant`, `telek`, `agenda`, `dominion-breaker`, `colleague`, `jetson`, `reachy-mini-cli`, `jetson-ai-lab-cli`, `dgx-spark-cli`, `unsloth-cli`, `discord-bot-cli`, `arxivist`, `rtx-spark-cli`, `reachy-mini-mcp`, `tensor-cli`, `climate-cli`, `eidetic-cli`, `prove-cli`, `reduce-cli`, `refactor-cli`, `rollout-cli`, `coherence-cli`, `agent-lifecycle`, `reterminal`, `operator-cli`, `culture-core`, `ec2-cli`, `qodo-cli`, `knowledgebase-cli`, `cloudai-cli`, `ec2bedrock-cli`, `arm101-cli`, `amazing-hand-cli`, `agentculture-cli`, `data-refinery-cli`, `culture-tools`, `webglass-cli`, `jetson-orin-cli`, `jetson-thor-cli`, `drone-cli`, `fleet-cli`, `league-of-agents`, `harmonics-cli`, `french-cli`, `spanish-cli`, `league-of-agents-platform` | Coverage source resolves from `[tool.coverage.run]` in `pyproject.toml`, so the script is portable across siblings without modification. |
41
- | `sonarclaude` | `guildmaster` (`.claude/skills/sonarclaude/`) | `antoine`, `appsec`, `code-lens-cli`, `devague`, `lecodeur`, `lepenseur`, `seer-cli`, `telek`, `agenda`, `dominion-breaker`, `colleague`, `jetson`, `reachy-mini-cli`, `jetson-ai-lab-cli`, `dgx-spark-cli`, `unsloth-cli`, `discord-bot-cli`, `arxivist`, `rtx-spark-cli`, `reachy-mini-mcp`, `tensor-cli`, `climate-cli`, `eidetic-cli`, `prove-cli`, `reduce-cli`, `refactor-cli`, `rollout-cli`, `coherence-cli`, `agent-lifecycle`, `reterminal`, `operator-cli`, `culture-core`, `ec2-cli`, `qodo-cli`, `knowledgebase-cli`, `cloudai-cli`, `ec2bedrock-cli`, `arm101-cli`, `amazing-hand-cli`, `agentculture-cli`, `data-refinery-cli`, `culture-tools`, `webglass-cli`, `jetson-orin-cli`, `jetson-thor-cli`, `drone-cli`, `fleet-cli`, `league-of-agents`, `harmonics-cli`, `french-cli`, `spanish-cli`, `league-of-agents-platform` | SonarCloud API client. Project key resolves from `$SONAR_PROJECT` or `--project KEY`. |
42
- | `version-bump` | `guildmaster` (`.claude/skills/version-bump/`) | `afi-cli`, `agtag`, `antoine`, `appsec`, `auntiepypi`, `cfafi`, `code-lens-cli`, `culture`, `devague`, `lecodeur`, `lepenseur`, `seer-cli`, `grant`, `telek`, `agenda`, `dominion-breaker`, `colleague`, `jetson`, `reachy-mini-cli`, `jetson-ai-lab-cli`, `dgx-spark-cli`, `unsloth-cli`, `discord-bot-cli`, `arxivist`, `rtx-spark-cli`, `reachy-mini-mcp`, `tensor-cli`, `climate-cli`, `eidetic-cli`, `prove-cli`, `reduce-cli`, `refactor-cli`, `rollout-cli`, `coherence-cli`, `agent-lifecycle`, `reterminal`, `operator-cli`, `culture-core`, `ec2-cli`, `qodo-cli`, `knowledgebase-cli`, `cloudai-cli`, `ec2bedrock-cli`, `arm101-cli`, `amazing-hand-cli`, `agentculture-cli`, `data-refinery-cli`, `culture-tools`, `webglass-cli`, `jetson-orin-cli`, `jetson-thor-cli`, `drone-cli`, `fleet-cli`, `league-of-agents`, `harmonics-cli`, `french-cli`, `spanish-cli`, `league-of-agents-platform` | Pure Python, prepends a Keep-a-Changelog entry; no per-repo customization needed. |
35
+ | `agent-config` | `guildmaster` (`.claude/skills/agent-config/`) | `agenda`, `dominion-breaker`, `colleague`, `jetson`, `reachy-mini-cli`, `jetson-ai-lab-cli`, `dgx-spark-cli`, `unsloth-cli`, `discord-bot-cli`, `arxivist`, `rtx-spark-cli`, `reachy-mini-mcp`, `tensor-cli`, `climate-cli`, `eidetic-cli`, `prove-cli`, `reduce-cli`, `refactor-cli`, `rollout-cli`, `coherence-cli`, `agent-lifecycle`, `reterminal`, `operator-cli`, `culture-core`, `ec2-cli`, `qodo-cli`, `knowledgebase-cli`, `cloudai-cli`, `ec2bedrock-cli`, `arm101-cli`, `amazing-hand-cli`, `agentculture-cli`, `data-refinery-cli`, `culture-tools`, `webglass-cli`, `jetson-orin-cli`, `jetson-thor-cli`, `drone-cli`, `fleet-cli`, `league-of-agents`, `harmonics-cli`, `french-cli`, `spanish-cli`, `league-of-agents-platform`, `org` | Inventory variant backing `guild show` ([#12](https://github.com/agentculture/guildmaster/issues/12)); `show.sh` + `data/backend-fingerprints.yaml` vendored verbatim from steward, SKILL.md reframed from alignment-judgment to inventory + `type: command` added. **Forked from steward:** steward retains its own alignment-focused `agent-config` variant; the inventory variant is guildmaster's to supply. |
36
+ | `cicd` | `guildmaster` (`.claude/skills/cicd/`) — layered on `devex pr` (in `agentculture/devex`) | `afi-cli`, `devex` (adapted-thin delegate — owns `devex pr`; see [devex#53](https://github.com/agentculture/devex/pull/53)), `agtag`, `antoine`, `appsec`, `auntiepypi`, `cfafi` (still named `pr-review`), `code-lens-cli`, `culture` (still named `pr-review`), `devague`, `katvan`, `lecodeur`, `lepenseur`, `seer-cli`, `telek`, `agenda`, `dominion-breaker`, `colleague`, `jetson`, `grant` (still named `pr-review`), `reachy-mini-cli`, `jetson-ai-lab-cli`, `dgx-spark-cli`, `unsloth-cli`, `discord-bot-cli`, `arxivist`, `rtx-spark-cli`, `reachy-mini-mcp`, `tensor-cli`, `climate-cli`, `eidetic-cli`, `prove-cli`, `reduce-cli`, `refactor-cli`, `rollout-cli`, `coherence-cli`, `agent-lifecycle`, `reterminal`, `operator-cli`, `culture-core`, `ec2-cli`, `qodo-cli`, `knowledgebase-cli`, `cloudai-cli`, `ec2bedrock-cli`, `arm101-cli`, `amazing-hand-cli`, `agentculture-cli`, `data-refinery-cli`, `culture-tools`, `webglass-cli`, `jetson-orin-cli`, `jetson-thor-cli`, `drone-cli`, `fleet-cli`, `league-of-agents`, `harmonics-cli`, `french-cli`, `spanish-cli`, `league-of-agents-platform`, `org` | Thin delegate to `devex pr` for lint / open / read / reply / delta, plus guildmaster's `status` (SonarCloud quality gate + hotspots + unresolved-thread tally) and `await` (composes `devex pr read --wait` with `status`, non-zero exit on Sonar ERROR / unresolved threads) extensions. **Inverted case:** devex, as the `devex pr` upstream, vendors the skill adapted-thin — a `workflow.sh`-only pure delegate ([devex#53](https://github.com/agentculture/devex/pull/53)). Renamed from `pr-review` in steward 0.7.0; downstream copies may keep the old name on their own cadence. |
37
+ | `communicate` | `guildmaster` (`.claude/skills/communicate/`) | `afi-cli`, `devex` (identifier-only — vendored steward 0.11.0; scripts current as of 0.18.0), `agtag`, `antoine`, `appsec`, `auntiepypi`, `code-lens-cli`, `culture` (still named `coordinate`), `devague`, `katvan`, `lecodeur`, `lepenseur`, `seer-cli`, `telek`, `agenda`, `dominion-breaker`, `colleague`, `jetson`, `reachy-mini-cli`, `jetson-ai-lab-cli`, `dgx-spark-cli`, `unsloth-cli`, `discord-bot-cli`, `arxivist`, `rtx-spark-cli`, `reachy-mini-mcp`, `tensor-cli`, `climate-cli`, `eidetic-cli`, `prove-cli`, `reduce-cli`, `refactor-cli`, `rollout-cli`, `coherence-cli`, `agent-lifecycle`, `reterminal`, `operator-cli`, `culture-core`, `ec2-cli`, `qodo-cli`, `knowledgebase-cli`, `cloudai-cli`, `ec2bedrock-cli`, `arm101-cli`, `amazing-hand-cli`, `agentculture-cli`, `data-refinery-cli`, `culture-tools`, `webglass-cli`, `jetson-orin-cli`, `jetson-thor-cli`, `drone-cli`, `fleet-cli`, `league-of-agents`, `harmonics-cli`, `french-cli`, `spanish-cli`, `league-of-agents-platform`, `org` | Cross-repo + mesh communication: file issues / hand off briefs to sibling-repo agents (auto-signed), comment on existing issues, fetch issues to inline state into briefs, and send live messages to Culture mesh channels (unsigned — nick is the speaker). Renamed from `coordinate` in steward 0.8.0; absorbed `gh-issues` (as `fetch-issues.sh`) in 0.9.1. Issue I/O backed by `agtag` (>=0.1) since steward 0.11.0 — signature resolves from local `culture.yaml` (override via `--as`). |
38
+ | `doc-test-alignment` | `guildmaster` (`.claude/skills/doc-test-alignment/`) | `devague`, `lecodeur`, `lepenseur`, `agenda`, `dominion-breaker`, `colleague`, `jetson`, `reachy-mini-cli`, `jetson-ai-lab-cli`, `dgx-spark-cli`, `unsloth-cli`, `discord-bot-cli`, `arxivist`, `rtx-spark-cli`, `reachy-mini-mcp`, `tensor-cli`, `climate-cli`, `eidetic-cli`, `prove-cli`, `reduce-cli`, `refactor-cli`, `rollout-cli`, `coherence-cli`, `agent-lifecycle`, `reterminal`, `operator-cli`, `culture-core`, `ec2-cli`, `qodo-cli`, `knowledgebase-cli`, `cloudai-cli`, `ec2bedrock-cli`, `arm101-cli`, `amazing-hand-cli`, `agentculture-cli`, `data-refinery-cli`, `culture-tools`, `webglass-cli`, `jetson-orin-cli`, `jetson-thor-cli`, `drone-cli`, `fleet-cli`, `league-of-agents`, `harmonics-cli`, `french-cli`, `spanish-cli`, `league-of-agents-platform`, `org` | Stub; real implementation TBD. `scripts/check.sh` exits not-yet-implemented today. |
39
+ | `pypi-maintainer` | `guildmaster` (`.claude/skills/pypi-maintainer/`) | `agtag`, `agenda`, `dominion-breaker`, `colleague`, `jetson`, `reachy-mini-cli`, `jetson-ai-lab-cli`, `dgx-spark-cli`, `unsloth-cli`, `discord-bot-cli`, `arxivist`, `rtx-spark-cli`, `reachy-mini-mcp`, `tensor-cli`, `climate-cli`, `eidetic-cli`, `prove-cli`, `reduce-cli`, `refactor-cli`, `rollout-cli`, `coherence-cli`, `agent-lifecycle`, `reterminal`, `operator-cli`, `culture-core`, `ec2-cli`, `qodo-cli`, `knowledgebase-cli`, `cloudai-cli`, `ec2bedrock-cli`, `arm101-cli`, `amazing-hand-cli`, `agentculture-cli`, `data-refinery-cli`, `culture-tools`, `webglass-cli`, `jetson-orin-cli`, `jetson-thor-cli`, `drone-cli`, `fleet-cli`, `league-of-agents`, `harmonics-cli`, `french-cli`, `spanish-cli`, `league-of-agents-platform` | Switches a PyPI package install between pypi / test-pypi / local. Generalised from the original culture-specific `change-package`. `org` is intentionally not a consumer — it ships no PyPI distribution (site repo). |
40
+ | `run-tests` | `guildmaster` (`.claude/skills/run-tests/`) | `agtag`, `antoine`, `appsec`, `code-lens-cli`, `culture`, `culture-sonar-cli`, `devague`, `lecodeur`, `lepenseur`, `seer-cli`, `grant`, `telek`, `agenda`, `dominion-breaker`, `colleague`, `jetson`, `reachy-mini-cli`, `jetson-ai-lab-cli`, `dgx-spark-cli`, `unsloth-cli`, `discord-bot-cli`, `arxivist`, `rtx-spark-cli`, `reachy-mini-mcp`, `tensor-cli`, `climate-cli`, `eidetic-cli`, `prove-cli`, `reduce-cli`, `refactor-cli`, `rollout-cli`, `coherence-cli`, `agent-lifecycle`, `reterminal`, `operator-cli`, `culture-core`, `ec2-cli`, `qodo-cli`, `knowledgebase-cli`, `cloudai-cli`, `ec2bedrock-cli`, `arm101-cli`, `amazing-hand-cli`, `agentculture-cli`, `data-refinery-cli`, `culture-tools`, `webglass-cli`, `jetson-orin-cli`, `jetson-thor-cli`, `drone-cli`, `fleet-cli`, `league-of-agents`, `harmonics-cli`, `french-cli`, `spanish-cli`, `league-of-agents-platform`, `org` | Coverage source resolves from `[tool.coverage.run]` in `pyproject.toml`, so the script is portable across siblings without modification. |
41
+ | `sonarclaude` | `guildmaster` (`.claude/skills/sonarclaude/`) | `antoine`, `appsec`, `code-lens-cli`, `devague`, `lecodeur`, `lepenseur`, `seer-cli`, `telek`, `agenda`, `dominion-breaker`, `colleague`, `jetson`, `reachy-mini-cli`, `jetson-ai-lab-cli`, `dgx-spark-cli`, `unsloth-cli`, `discord-bot-cli`, `arxivist`, `rtx-spark-cli`, `reachy-mini-mcp`, `tensor-cli`, `climate-cli`, `eidetic-cli`, `prove-cli`, `reduce-cli`, `refactor-cli`, `rollout-cli`, `coherence-cli`, `agent-lifecycle`, `reterminal`, `operator-cli`, `culture-core`, `ec2-cli`, `qodo-cli`, `knowledgebase-cli`, `cloudai-cli`, `ec2bedrock-cli`, `arm101-cli`, `amazing-hand-cli`, `agentculture-cli`, `data-refinery-cli`, `culture-tools`, `webglass-cli`, `jetson-orin-cli`, `jetson-thor-cli`, `drone-cli`, `fleet-cli`, `league-of-agents`, `harmonics-cli`, `french-cli`, `spanish-cli`, `league-of-agents-platform`, `org` | SonarCloud API client. Project key resolves from `$SONAR_PROJECT` or `--project KEY`. |
42
+ | `version-bump` | `guildmaster` (`.claude/skills/version-bump/`) | `afi-cli`, `agtag`, `antoine`, `appsec`, `auntiepypi`, `cfafi`, `code-lens-cli`, `culture`, `devague`, `lecodeur`, `lepenseur`, `seer-cli`, `grant`, `telek`, `agenda`, `dominion-breaker`, `colleague`, `jetson`, `reachy-mini-cli`, `jetson-ai-lab-cli`, `dgx-spark-cli`, `unsloth-cli`, `discord-bot-cli`, `arxivist`, `rtx-spark-cli`, `reachy-mini-mcp`, `tensor-cli`, `climate-cli`, `eidetic-cli`, `prove-cli`, `reduce-cli`, `refactor-cli`, `rollout-cli`, `coherence-cli`, `agent-lifecycle`, `reterminal`, `operator-cli`, `culture-core`, `ec2-cli`, `qodo-cli`, `knowledgebase-cli`, `cloudai-cli`, `ec2bedrock-cli`, `arm101-cli`, `amazing-hand-cli`, `agentculture-cli`, `data-refinery-cli`, `culture-tools`, `webglass-cli`, `jetson-orin-cli`, `jetson-thor-cli`, `drone-cli`, `fleet-cli`, `league-of-agents`, `harmonics-cli`, `french-cli`, `spanish-cli`, `league-of-agents-platform`, `org` | Pure Python, prepends a Keep-a-Changelog entry; no per-repo customization needed. |
43
43
 
44
44
  > **How the downstream column is maintained.** The "Downstream copies (known)"
45
45
  > entries are kept in sync with guildmaster's own drift detector:
@@ -86,9 +86,9 @@ harmless on `claude-code`. This is the only divergence from upstream.
86
86
 
87
87
  | Skill | Origin | Downstream copies (known) | Notes |
88
88
  |-------|--------|---------------------------|-------|
89
- | `think` | `devague` (`agentculture/devague`, `../devague/.claude/skills/think/`) | — (broadcast pending), `agenda`, `dominion-breaker`, `colleague`, `jetson`, `reachy-mini-cli`, `jetson-ai-lab-cli`, `dgx-spark-cli`, `unsloth-cli`, `discord-bot-cli`, `arxivist`, `rtx-spark-cli`, `reachy-mini-mcp`, `tensor-cli`, `climate-cli`, `eidetic-cli`, `prove-cli`, `reduce-cli`, `refactor-cli`, `rollout-cli`, `coherence-cli`, `agent-lifecycle`, `reterminal`, `operator-cli`, `culture-core`, `ec2-cli`, `qodo-cli`, `knowledgebase-cli`, `cloudai-cli`, `ec2bedrock-cli`, `arm101-cli`, `amazing-hand-cli`, `agentculture-cli`, `data-refinery-cli`, `culture-tools`, `webglass-cli`, `jetson-orin-cli`, `jetson-thor-cli`, `drone-cli`, `fleet-cli`, `league-of-agents`, `harmonics-cli`, `french-cli`, `spanish-cli`, `league-of-agents-platform` | Operator for the **idea→spec** leg (announcement frame → capture/classify claims → interrogate with honesty conditions → park open vagueness → `export` once the frame converges). Renamed from `devague` in devague 0.4.0. **Divergence:** `type: command` added. Runtime dep: `uv tool install devague`. |
90
- | `spec-to-plan` | `devague` (`agentculture/devague`, `../devague/.claude/skills/spec-to-plan/`) | — (broadcast pending), `agenda`, `dominion-breaker`, `colleague`, `jetson`, `reachy-mini-cli`, `jetson-ai-lab-cli`, `dgx-spark-cli`, `unsloth-cli`, `discord-bot-cli`, `arxivist`, `rtx-spark-cli`, `reachy-mini-mcp`, `tensor-cli`, `climate-cli`, `eidetic-cli`, `prove-cli`, `reduce-cli`, `refactor-cli`, `rollout-cli`, `coherence-cli`, `agent-lifecycle`, `reterminal`, `operator-cli`, `culture-core`, `ec2-cli`, `qodo-cli`, `knowledgebase-cli`, `cloudai-cli`, `ec2bedrock-cli`, `arm101-cli`, `amazing-hand-cli`, `agentculture-cli`, `data-refinery-cli`, `culture-tools`, `webglass-cli`, `jetson-orin-cli`, `jetson-thor-cli`, `drone-cli`, `fleet-cli`, `league-of-agents`, `harmonics-cli`, `french-cli`, `spanish-cli`, `league-of-agents-platform` | Operator for the **spec→plan** leg (`devague plan ...`): seed from a converged frame, cover every coverage target with acceptance-gated, acyclically-ordered tasks, park unknowns as risks, `export` once the plan converges. New in devague 0.4.0. **Divergence:** `type: command` added. Runtime dep: `uv tool install devague`. |
91
- | `assign-to-workforce` | `devague` (`agentculture/devague`, `../devague/.claude/skills/assign-to-workforce/`) | — (broadcast pending), `agenda`, `dominion-breaker`, `colleague`, `jetson`, `reachy-mini-cli`, `jetson-ai-lab-cli`, `dgx-spark-cli`, `unsloth-cli`, `discord-bot-cli`, `arxivist`, `rtx-spark-cli`, `reachy-mini-mcp`, `tensor-cli`, `climate-cli`, `eidetic-cli`, `prove-cli`, `reduce-cli`, `refactor-cli`, `rollout-cli`, `coherence-cli`, `agent-lifecycle`, `reterminal`, `operator-cli`, `culture-core`, `ec2-cli`, `qodo-cli`, `knowledgebase-cli`, `cloudai-cli`, `ec2bedrock-cli`, `arm101-cli`, `amazing-hand-cli`, `agentculture-cli`, `data-refinery-cli`, `culture-tools`, `webglass-cli`, `jetson-orin-cli`, `jetson-thor-cli`, `drone-cli`, `fleet-cli`, `league-of-agents`, `harmonics-cli`, `french-cli`, `spanish-cli`, `league-of-agents-platform` | Operator for the **implementation** leg: reads `devague plan waves` (read-only) and fans out independent tasks to one agent per task per wave in isolated git worktrees, with main-agent TDD-gated merges. Three human gates: spec / split plan / final PR. The CLI stays non-orchestrating ([devague#20](https://github.com/agentculture/devague/issues/20)). New in devague 0.10.0. **Divergence:** `type: command` added. Runtime deps: `uv tool install devague`, `git worktree`, the vendored `cicd` skill (for gate-3 `devex pr open`). |
89
+ | `think` | `devague` (`agentculture/devague`, `../devague/.claude/skills/think/`) | — (broadcast pending), `agenda`, `dominion-breaker`, `colleague`, `jetson`, `reachy-mini-cli`, `jetson-ai-lab-cli`, `dgx-spark-cli`, `unsloth-cli`, `discord-bot-cli`, `arxivist`, `rtx-spark-cli`, `reachy-mini-mcp`, `tensor-cli`, `climate-cli`, `eidetic-cli`, `prove-cli`, `reduce-cli`, `refactor-cli`, `rollout-cli`, `coherence-cli`, `agent-lifecycle`, `reterminal`, `operator-cli`, `culture-core`, `ec2-cli`, `qodo-cli`, `knowledgebase-cli`, `cloudai-cli`, `ec2bedrock-cli`, `arm101-cli`, `amazing-hand-cli`, `agentculture-cli`, `data-refinery-cli`, `culture-tools`, `webglass-cli`, `jetson-orin-cli`, `jetson-thor-cli`, `drone-cli`, `fleet-cli`, `league-of-agents`, `harmonics-cli`, `french-cli`, `spanish-cli`, `league-of-agents-platform`, `org` | Operator for the **idea→spec** leg (announcement frame → capture/classify claims → interrogate with honesty conditions → park open vagueness → `export` once the frame converges). Renamed from `devague` in devague 0.4.0. **Divergence:** `type: command` added. Runtime dep: `uv tool install devague`. |
90
+ | `spec-to-plan` | `devague` (`agentculture/devague`, `../devague/.claude/skills/spec-to-plan/`) | — (broadcast pending), `agenda`, `dominion-breaker`, `colleague`, `jetson`, `reachy-mini-cli`, `jetson-ai-lab-cli`, `dgx-spark-cli`, `unsloth-cli`, `discord-bot-cli`, `arxivist`, `rtx-spark-cli`, `reachy-mini-mcp`, `tensor-cli`, `climate-cli`, `eidetic-cli`, `prove-cli`, `reduce-cli`, `refactor-cli`, `rollout-cli`, `coherence-cli`, `agent-lifecycle`, `reterminal`, `operator-cli`, `culture-core`, `ec2-cli`, `qodo-cli`, `knowledgebase-cli`, `cloudai-cli`, `ec2bedrock-cli`, `arm101-cli`, `amazing-hand-cli`, `agentculture-cli`, `data-refinery-cli`, `culture-tools`, `webglass-cli`, `jetson-orin-cli`, `jetson-thor-cli`, `drone-cli`, `fleet-cli`, `league-of-agents`, `harmonics-cli`, `french-cli`, `spanish-cli`, `league-of-agents-platform`, `org` | Operator for the **spec→plan** leg (`devague plan ...`): seed from a converged frame, cover every coverage target with acceptance-gated, acyclically-ordered tasks, park unknowns as risks, `export` once the plan converges. New in devague 0.4.0. **Divergence:** `type: command` added. Runtime dep: `uv tool install devague`. |
91
+ | `assign-to-workforce` | `devague` (`agentculture/devague`, `../devague/.claude/skills/assign-to-workforce/`) | — (broadcast pending), `agenda`, `dominion-breaker`, `colleague`, `jetson`, `reachy-mini-cli`, `jetson-ai-lab-cli`, `dgx-spark-cli`, `unsloth-cli`, `discord-bot-cli`, `arxivist`, `rtx-spark-cli`, `reachy-mini-mcp`, `tensor-cli`, `climate-cli`, `eidetic-cli`, `prove-cli`, `reduce-cli`, `refactor-cli`, `rollout-cli`, `coherence-cli`, `agent-lifecycle`, `reterminal`, `operator-cli`, `culture-core`, `ec2-cli`, `qodo-cli`, `knowledgebase-cli`, `cloudai-cli`, `ec2bedrock-cli`, `arm101-cli`, `amazing-hand-cli`, `agentculture-cli`, `data-refinery-cli`, `culture-tools`, `webglass-cli`, `jetson-orin-cli`, `jetson-thor-cli`, `drone-cli`, `fleet-cli`, `league-of-agents`, `harmonics-cli`, `french-cli`, `spanish-cli`, `league-of-agents-platform`, `org` | Operator for the **implementation** leg: reads `devague plan waves` (read-only) and fans out independent tasks to one agent per task per wave in isolated git worktrees, with main-agent TDD-gated merges. Three human gates: spec / split plan / final PR. The CLI stays non-orchestrating ([devague#20](https://github.com/agentculture/devague/issues/20)). New in devague 0.10.0. **Divergence:** `type: command` added. Runtime deps: `uv tool install devague`, `git worktree`, the vendored `cicd` skill (for gate-3 `devex pr open`). |
92
92
 
93
93
  Downstream is empty by design: these are still being introduced to the mesh.
94
94
  `guild teach --new --skill <name> --to <repos>` frames them as *new* skills to
@@ -136,7 +136,7 @@ the CLI, the wrapper exits with a clear install hint rather than crashing.
136
136
 
137
137
  | Skill | Origin | Downstream copies (known) | Notes |
138
138
  |-------|--------|---------------------------|-------|
139
- | `outsource` | `colleague` (`agentculture/colleague`, `../colleague/.claude/skills/outsource/`) | — (broadcast pending; [`culture-agent-template#8`](https://github.com/agentculture/culture-agent-template/issues/8) proposes adding it to the clone template), `rtx-spark-cli`, `reachy-mini-mcp`, `tensor-cli`, `climate-cli`, `eidetic-cli`, `prove-cli`, `reduce-cli`, `refactor-cli`, `rollout-cli`, `coherence-cli`, `agent-lifecycle`, `reterminal`, `operator-cli`, `culture-core`, `ec2-cli`, `qodo-cli`, `knowledgebase-cli`, `cloudai-cli`, `ec2bedrock-cli`, `arm101-cli`, `amazing-hand-cli`, `agentculture-cli`, `data-refinery-cli`, `culture-tools`, `webglass-cli`, `jetson-orin-cli`, `jetson-thor-cli`, `drone-cli`, `fleet-cli`, `league-of-agents`, `harmonics-cli`, `french-cli`, `spanish-cli`, `league-of-agents-platform` | First-party colleague skill: hand a scoped task to a *different* engine/mind. Verbs `explore` / `review` / `write`. **Divergence:** Provenance paragraph reframed for re-broadcast (above); `type: command` already present upstream. Runtime dep: `uv tool install colleague-cli` + a reachable engine. |
139
+ | `outsource` | `colleague` (`agentculture/colleague`, `../colleague/.claude/skills/outsource/`) | — (broadcast pending; [`culture-agent-template#8`](https://github.com/agentculture/culture-agent-template/issues/8) proposes adding it to the clone template), `rtx-spark-cli`, `reachy-mini-mcp`, `tensor-cli`, `climate-cli`, `eidetic-cli`, `prove-cli`, `reduce-cli`, `refactor-cli`, `rollout-cli`, `coherence-cli`, `agent-lifecycle`, `reterminal`, `operator-cli`, `culture-core`, `ec2-cli`, `qodo-cli`, `knowledgebase-cli`, `cloudai-cli`, `ec2bedrock-cli`, `arm101-cli`, `amazing-hand-cli`, `agentculture-cli`, `data-refinery-cli`, `culture-tools`, `webglass-cli`, `jetson-orin-cli`, `jetson-thor-cli`, `drone-cli`, `fleet-cli`, `league-of-agents`, `harmonics-cli`, `french-cli`, `spanish-cli`, `league-of-agents-platform`, `org` | First-party colleague skill: hand a scoped task to a *different* engine/mind. Verbs `explore` / `review` / `write`. **Divergence:** Provenance paragraph reframed for re-broadcast (above); `type: command` already present upstream. Runtime dep: `uv tool install colleague-cli` + a reachable engine. |
140
140
 
141
141
  Downstream is empty by design — guildmaster is the first holder outside
142
142
  colleague. `guild teach --new --skill outsource --to <repos>` frames it as a
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "guild-cli"
3
- version = "0.19.1"
3
+ version = "0.19.3"
4
4
  description = "guildmaster — an agent and CLI that manages skills for the AgentCulture mesh."
5
5
  readme = "README.md"
6
6
  license = "Apache-2.0"
@@ -0,0 +1,165 @@
1
+ """Behavioural tests for ``configure-repo.sh``'s SONAR_TOKEN step (step 4).
2
+
3
+ The Python provisioning tests stub ``configure-repo.sh`` with an echo, so the
4
+ real secret-seeding logic has no coverage there. These tests run the *actual*
5
+ script in ``--apply`` mode against a fake ``gh`` on ``PATH`` — no network, no
6
+ real GitHub — and assert the contract that matters:
7
+
8
+ - seed the secret from the operator's exported ``$SONAR_TOKEN`` when the repo
9
+ has none (an *empty* secret means SonarCloud is silently skipped, since
10
+ ``tests.yml`` gates on ``env.SONAR_TOKEN != ''``);
11
+ - create it empty (and warn) only when ``$SONAR_TOKEN`` is not exported;
12
+ - never clobber a secret that already exists — the value in GitHub wins.
13
+
14
+ The token must reach ``gh`` on stdin, never on argv (the process table is
15
+ world-readable), so the fake records stdin and the tests assert on that.
16
+ """
17
+
18
+ from __future__ import annotations
19
+
20
+ import os
21
+ import subprocess
22
+ from pathlib import Path
23
+
24
+ REPO_ROOT = Path(__file__).resolve().parent.parent
25
+ CONFIGURE = REPO_ROOT / ".claude" / "skills" / "guild" / "scripts" / "configure-repo.sh"
26
+
27
+ FAKE_TOKEN = "s3cr3t-sonar-token-value"
28
+
29
+
30
+ def _install_fake_gh(tmp_path: Path, *, secret_present: bool, list_fails: bool = False) -> Path:
31
+ """Write a fake ``gh`` onto ``tmp_path`` and return the log path.
32
+
33
+ The fake stubs every ``gh`` call the apply path makes:
34
+ - ``secret list`` prints ``SONAR_TOKEN`` iff *secret_present* — or exits
35
+ non-zero (with a diagnostic on stderr) when *list_fails*, so the tests can
36
+ exercise the fail-closed path;
37
+ - ``secret set`` records BOTH its full argv (prefixed ``ARGV:``) and its
38
+ stdin (prefixed ``SET:``) to the log, so a test can prove the token
39
+ reaches ``gh`` on stdin and never on argv;
40
+ - ``api …/rulesets`` echoes the ruleset name so the script treats it as
41
+ already-present and skips the create (whose heredoc would read stdin);
42
+ - every other ``api`` call exits 0 silently.
43
+ """
44
+ log = tmp_path / "gh.log"
45
+ # Real `gh secret list` is TAB-separated `NAME<TAB>UPDATED[<TAB>VIS]` with no
46
+ # header. Emit real tabs (printf interprets `\t`) so the script's
47
+ # first-column `awk` extraction is exercised the way it runs in production.
48
+ if list_fails:
49
+ list_branch = ' echo "fake gh: HTTP 403: forbidden" >&2\n exit 1\n'
50
+ elif secret_present:
51
+ list_branch = ' printf "SONAR_TOKEN\\t2024-01-01T00:00:00Z\\tactions\\n"\n exit 0\n'
52
+ else:
53
+ list_branch = " exit 0\n"
54
+ gh = tmp_path / "gh"
55
+ gh.write_text(
56
+ "#!/usr/bin/env bash\n"
57
+ f"LOG={log!s}\n"
58
+ 'if [[ "$1" == "secret" && "$2" == "list" ]]; then\n'
59
+ f"{list_branch}"
60
+ "fi\n"
61
+ 'if [[ "$1" == "secret" && "$2" == "set" ]]; then\n'
62
+ ' printf "ARGV:[%s]\\n" "$*" >> "$LOG"\n'
63
+ ' printf "SET:[%s]\\n" "$(cat)" >> "$LOG"\n'
64
+ " exit 0\n"
65
+ "fi\n"
66
+ 'if [[ "$1" == "api" ]]; then\n'
67
+ ' for a in "$@"; do\n'
68
+ ' [[ "$a" == *rulesets ]] && { printf "Protect main\\n"; exit 0; }\n'
69
+ " done\n"
70
+ " exit 0\n"
71
+ "fi\n"
72
+ "exit 0\n"
73
+ )
74
+ gh.chmod(0o755)
75
+ return log
76
+
77
+
78
+ def _set_lines(log: Path) -> list[str]:
79
+ """The ``SET:[…]`` stdin lines recorded by the fake ``gh``."""
80
+ if not log.exists():
81
+ return []
82
+ return [ln for ln in log.read_text().splitlines() if ln.startswith("SET:")]
83
+
84
+
85
+ def _run(
86
+ tmp_path: Path, *, token: str | None, check: bool = True
87
+ ) -> subprocess.CompletedProcess[str]:
88
+ env = dict(os.environ)
89
+ env["PATH"] = f"{tmp_path}{os.pathsep}{env['PATH']}"
90
+ if token is None:
91
+ env.pop("SONAR_TOKEN", None)
92
+ else:
93
+ env["SONAR_TOKEN"] = token
94
+ return subprocess.run(
95
+ ["bash", str(CONFIGURE), "agentculture/fixture-repo", "--apply"],
96
+ capture_output=True,
97
+ text=True,
98
+ env=env,
99
+ check=check,
100
+ )
101
+
102
+
103
+ def test_seeds_secret_from_exported_token(tmp_path: Path) -> None:
104
+ """Token exported + repo has no secret → set it, from stdin."""
105
+ log = _install_fake_gh(tmp_path, secret_present=False)
106
+ result = _run(tmp_path, token=FAKE_TOKEN)
107
+
108
+ assert _set_lines(log) == [f"SET:[{FAKE_TOKEN}]"]
109
+ # The token must never appear in the visible command output (argv/logs).
110
+ assert FAKE_TOKEN not in result.stdout
111
+ assert FAKE_TOKEN not in result.stderr
112
+ assert "set secret 'SONAR_TOKEN' from the exported" in result.stdout
113
+
114
+
115
+ def test_token_reaches_gh_on_stdin_never_on_argv(tmp_path: Path) -> None:
116
+ """The token must be piped to `gh secret set`, never passed as an argument.
117
+
118
+ argv is world-readable via the process table, so leaking the token there
119
+ would defeat the point. The fake records every `secret set` argv line.
120
+ """
121
+ log = _install_fake_gh(tmp_path, secret_present=False)
122
+ _run(tmp_path, token=FAKE_TOKEN)
123
+
124
+ argv_lines = [ln for ln in log.read_text().splitlines() if ln.startswith("ARGV:")]
125
+ assert argv_lines, "expected a `gh secret set` invocation to be recorded"
126
+ for line in argv_lines:
127
+ assert FAKE_TOKEN not in line, f"token leaked onto argv: {line}"
128
+
129
+
130
+ def test_creates_empty_secret_and_warns_when_token_absent(tmp_path: Path) -> None:
131
+ """No exported token + no secret → create empty AND warn it will be skipped."""
132
+ log = _install_fake_gh(tmp_path, secret_present=False)
133
+ result = _run(tmp_path, token=None)
134
+
135
+ assert _set_lines(log) == ["SET:[]"]
136
+ assert "SonarCloud" in result.stderr
137
+ assert "SKIPPED" in result.stderr
138
+
139
+
140
+ def test_never_clobbers_an_existing_secret(tmp_path: Path) -> None:
141
+ """Secret already present → never call ``secret set``, even with a token."""
142
+ log = _install_fake_gh(tmp_path, secret_present=True)
143
+ result = _run(tmp_path, token=FAKE_TOKEN)
144
+
145
+ assert _set_lines(log) == [], "an already-present secret must never be overwritten"
146
+ assert "already set" in result.stdout
147
+
148
+
149
+ def test_fails_closed_when_secret_listing_errors(tmp_path: Path) -> None:
150
+ """If `gh secret list` fails, refuse to set — never risk clobbering blind."""
151
+ log = _install_fake_gh(tmp_path, secret_present=False, list_fails=True)
152
+ result = _run(tmp_path, token=FAKE_TOKEN, check=False)
153
+
154
+ assert result.returncode != 0, "a listing failure must abort, not fall through"
155
+ assert _set_lines(log) == [], "must not call `secret set` when presence is unknown"
156
+ assert "refusing to set" in result.stderr
157
+
158
+
159
+ def test_whitespace_only_token_is_treated_as_absent(tmp_path: Path) -> None:
160
+ """A blank/whitespace token is as useless as an empty one → empty + warn."""
161
+ log = _install_fake_gh(tmp_path, secret_present=False)
162
+ result = _run(tmp_path, token=" \t ")
163
+
164
+ assert _set_lines(log) == ["SET:[]"]
165
+ assert "SKIPPED" in result.stderr
@@ -179,7 +179,7 @@ wheels = [
179
179
 
180
180
  [[package]]
181
181
  name = "guild-cli"
182
- version = "0.19.1"
182
+ version = "0.19.3"
183
183
  source = { editable = "." }
184
184
  dependencies = [
185
185
  { name = "pyyaml" },
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes