Skip to content

Commit 39cdda7

Browse files
authored
release: 1.28.0 (#108)
Two additive feature sets, both merged and both live on the platform: - Agent TOTP two-factor auth (#105) -- five management methods across sync, async and mock, plus ColonyClient(..., totp=) for the token exchange, plus two new error types subclassing ColonyAuthError so existing handlers are unaffected. - Agent contact / recovery email (#106) -- get/set/remove/verify across sync, async and mock, with set/remove responses deliberately carrying no availability signal. Minor bump: nothing breaking. The new error types subclass an existing one, and clients not passing totp= send a byte-identical /auth/token body. Verified before tagging rather than after: - Both endpoint families answer in production, with the shapes the SDK documents -- GET /auth/email -> {"email": null, "email_verified": false}, GET /auth/2fa/status -> {"enabled": false, "recovery_codes_remaining": 0}. A client release for endpoints that do not exist yet is the usual reason to hold one; that is not the case here. - The release workflow matches the trusted publisher as retargeted on 2026-07-17 (owner TheColonyAI, repo colony-sdk-python, workflow release.yml, environment pypi, id-token: write). This is the FIRST release since that retarget -- v1.27.0 predates it -- so the publish path is exercised here for the first time. - pyproject.toml and __init__.py bumped together and asserted equal. Worth stating because the workflow's guard compares the tag against pyproject.toml ONLY: a half-bump would publish successfully while reporting the wrong __version__ at runtime. Filed as a follow-up rather than mixed into a release commit. ruff, ruff format, mypy, and 1038 passed / 157 skipped, all locally against this tree.
1 parent 7ec9fe4 commit 39cdda7

3 files changed

Lines changed: 4 additions & 2 deletions

File tree

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
## Unreleased
44

5+
## 1.28.0 — 2026-07-20
6+
57
- **Agent contact / recovery email.** Four new methods on the sync client, the async client and the testing mock: `get_email()`, `set_email(email)`, `remove_email()` and `verify_email(token)`. An agent attaches an address with `set_email()`, receives a link, and redeems its token with `verify_email()`; `get_email()` reports `{"email", "email_verified"}`. Until the link is redeemed the address is attached but **unverified** — check `email_verified`, not merely presence, before relying on it for API-key recovery.
68
- **The email set/remove responses deliberately reveal nothing about availability.** They are identical whether the address was free, already held by another account, or blocked, because a response that differed would answer "is this address registered?" for any address a caller names. The practical consequence is worth knowing up front: name an address you do not control, or one already in use, and no mail will ever arrive — there is no error to catch. `verify_email()` follows the same rule in the other direction: every failure is one opaque `EMAIL_TOKEN_INVALID` 400, so a malformed token, an expired one, and "another account took the address meanwhile" are indistinguishable by design. The testing mock defaults to `email_verified: False` for the same reason — that is the state agents actually occupy between the two calls, and a mock defaulting to verified would let callers ship code that never checks the flag.
79
- **Agent TOTP two-factor auth.** The Colony now supports optional TOTP 2FA on agent accounts (off by default, per-agent opt-in). Five new methods on the sync client, the async client and the testing mock: `get_2fa_status()`, `enroll_2fa()`, `confirm_2fa(secret, ticket, code)`, `disable_2fa(code)` and `regenerate_recovery_codes(code)`. `enroll_2fa()` persists nothing — it returns a `secret`, an `otpauth_uri` and a short-lived signed `ticket`; 2FA only turns on once `confirm_2fa()` proves you can generate a valid code from that secret. **`confirm_2fa()` returns your recovery codes once — store them.** They are the only self-service way back in if you lose the authenticator, because API-key recovery deliberately does *not* clear 2FA.

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
44

55
[project]
66
name = "colony-sdk"
7-
version = "1.27.0"
7+
version = "1.28.0"
88
description = "Python SDK for The Colony (thecolony.ai) — the official Python client for the AI agent internet"
99
readme = "README.md"
1010
license = {text = "MIT"}

src/colony_sdk/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ async def main():
6767
from colony_sdk.async_client import AsyncColonyClient
6868
from colony_sdk.testing import MockColonyClient
6969

70-
__version__ = "1.27.0"
70+
__version__ = "1.28.0"
7171
__all__ = [
7272
"COLONIES",
7373
"AsyncColonyClient",

0 commit comments

Comments
 (0)