Skip to content

feat(licence): the licensed-identity row on aikey status and aikey doctor - #27

Open
damonleelcx wants to merge 3 commits into
develop-v1.0.5from
feat/licensed-identity-cli
Open

feat(licence): the licensed-identity row on aikey status and aikey doctor#27
damonleelcx wants to merge 3 commits into
develop-v1.0.5from
feat/licensed-identity-cli

Conversation

@damonleelcx

Copy link
Copy Markdown

What

src/license_identity.rs — the CLI half of 需求变更 2026-08-18, which makes aikey status and aikey doctor two of the four surfaces that must render the licensed identity byte-identically.

Design notes

  • One renderer. No surface composes its own string; the literals are bound to named constants that a cross-repo fence in aikey-license-core/crossrepo compares against the Go authority and the TypeScript client.
  • 🔴 The resting state is SILENT. An open-source Personal user runs aikey status with no licence for the life of the install, so a warning there would train everyone to ignore warnings — taking the error-state warning with it. Only the error state warns.
  • 🔴 404 is the unlicensed answer, not a failure: design D9 means a Personal control plane mounts no /v1/license/identity at all. Every other failure — 500, unreachable, 200 with no company name — is the error row. Collapsing those would report a Production server whose control plane is down as an unlicensed Personal install, which is the most expensive way to be wrong here.

Verification

  • 16/16 in license_identity
  • A new cross-language fence (TestAnAbsentLicensingRouteIsTheUnlicensedAnswerInEveryLanguage, in aikey-license-core) compares this 404 mapping against the TypeScript client. Both arms drilled red — flipping either language's arm to the error state fails it — then restored.
  • cargo fmt --check clean (the release gate runs it).

Note for the reviewer

This branch also carries one commit that is not part of this work and was simply unpushed on develop-v1.0.5 locally:

  • b7f4464 fix(trust-local): verify macOS stop actually stayed stopped

Related: aikeylabs/aikey-license-core#4, aikeylabs/aikey-control-master#36

Damon and others added 3 commits August 15, 2026 05:15
🔴 AUTHORSHIP: the code in this commit was written in a prior session on
2026-08-14 and left uncommitted and unformatted in the working tree. This
session applied `rustfmt` to it (proven whitespace-only: the token stream
ignoring whitespace is byte-identical before and after) and verified it —
`cargo fmt --check` clean, full suite 2600+ tests, 0 failures. Nothing about
its behaviour was designed or changed here.

It is committed rather than left dirty because release.sh's Step 2 `fmt-check`
fence refuses the tree, and a package built for a paying customer must come
from a committed tree — otherwise the customer runs bits that exist in no
commit and nobody can reproduce.

macOS "stop" used to be `launchctl kill TERM`, which signals the process but
leaves the job loaded, so KeepAlive respawned it seconds later while we printed
"stop succeeded" over the top. The check asks launchd's own job state rather
than /healthz, because a healthz probe cannot tell "stopped" from "restarting"
— the PyInstaller binary needs ~20s to self-extract before it binds.

Guarded `#[cfg(target_os = "macos")]`; Linux and Windows paths are untouched.

Bugfix: workflow/CI/bugfix/20260814-trust-local-stop-does-not-stop-macos.md
(that doc is still untracked in the workflow repo — it belongs with this change)
… doctor`

需求变更 2026-08-18 makes the CLI two of the four surfaces that must
render the licensed identity byte-identically. license_identity.rs is the
one renderer for all of them; no surface composes its own string.

🔴 The resting state is SILENT. An open-source Personal user runs `aikey
status` with no licence for the life of the install, so a warning there
would train everyone to ignore warnings — taking the error-state warning
with it. Only the error state warns.

404 from the identity route is the unlicensed answer (design D9: a
Personal control plane mounts no such route), and every other failure —
500, unreachable, 200 with no company name — is the error row. Collapsing
those would report a Production server whose control plane is down as an
unlicensed Personal install, which is the most expensive way to be wrong
here. All three are asserted, and a new cross-language fence in
aikey-license-core/crossrepo now compares the mapping against the
TypeScript client.

16/16 in license_identity.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
release.sh Step 2 runs `cargo fmt --check`, so unformatted source stops
the whole cut. No behaviour change; the cross-language identity fence in
aikey-license-core still passes, which is the point of matching on the
declaration rather than on a line's exact shape.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant