Commit graph

15 commits

Author SHA1 Message Date
thiagonogueira
217e7f4042
feat(skills): let skill owners yank a published version (#866)
Some checks are pending
Deploy Docs / build (push) Waiting to run
Deploy Docs / Deploy (push) Blocked by required conditions
Security / Dependency Review (push) Waiting to run
Security / CodeQL (java-kotlin) (push) Waiting to run
Security / CodeQL (python) (push) Waiting to run
Security / CodeQL (javascript-typescript) (push) Waiting to run
* feat(auth): expose skill lifecycle routes to API tokens

With an API token, v0.2.19 can remove a whole skill (DELETE
/api/v1/skills/{ns}/{slug} with skill:delete) but cannot archive or
unarchive a skill, nor delete a single draft/rejected version. Those
three routes are opened by AUTHORIZATION_POLICIES (authenticated
fallback) yet have no entry in API_TOKEN_POLICIES, so a bearer request
falls through to "unsupported" and is rejected with 403.

That contradicts the contract written above SESSION_ONLY_ROUTES in
RouteSecurityPolicyRegistry: bearer tokens are rejected on exactly the
listed session-only routes and nowhere else, and anything else the
authorization list opens must be reachable with a token holding the
required scope.

Add API-token policies for both the /api/v1 and /api/web prefixes that
SkillLifecycleController serves:

- POST .../skills/{ns}/{slug}/archive and .../unarchive require
  skill:publish. They are owner-level operations, gated by the same
  assertCanManageLifecycle check as publishing, so they sit at the same
  scope tier.
- DELETE .../skills/{ns}/{slug}/versions/{version} requires
  skill:delete, matching the existing whole-skill delete.

Whole-skill DELETE on /api/web stays session-only as documented; the
new version-delete pattern does not overlap it. No scope allow-list
exists outside the registry (TokenController and ApiTokenScopeService
accept any scope string), so no other change is needed for tokens to
carry these scopes.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DdnYX4jTS3JwMMP9JCGxzU

* feat(skills): let skill owners yank a published version

Yanking a published version is only available through
POST /api/v1/admin/skills/versions/{versionId}/yank, which is
session-only (SESSION_ONLY_ROUTES covers /api/v1/admin/**) and requires
SKILL_ADMIN or SUPER_ADMIN. A skill owner therefore cannot pull a
broken release themselves, neither from the web surface nor from a
script holding an API token.

In package registries yank is an act of the publisher: `cargo yank`
and PyPI's "yank release" are performed by the package owner, not by a
registry admin, because the goal is to stop new installs of a bad
release while keeping the artifact available for lock files. SkillHub
already lets owners archive, unarchive, rerelease and delete draft
versions through SkillLifecycleController under the
assertCanManageLifecycle rule (owner, or namespace ADMIN/OWNER); yank
belongs on the same surface with the same rule.

Changes:

- SkillGovernanceService: add an owner-checked yankVersion(skill,
  version, actor, roles, ip, ua, reason) that runs
  assertCanManageLifecycle and then the same yank logic as the admin
  variant, now shared in yankVersionInternal. The admin entry point is
  unchanged for AdminSkillController.
- SkillLifecycleAppService / GovernanceWorkflowAppService: resolve
  skill and version by namespace/slug/version, delegate to the new
  domain method, and return SkillLifecycleMutationResponse with action
  YANK and the resulting version status. The YANK_SKILL_VERSION audit
  record and SkillVersionYankedEvent are emitted by the domain service
  exactly as for the admin path.
- SkillLifecycleController: POST /{namespace}/{slug}/versions/{version}/yank
  on both /api/v1/skills and /api/web/skills, optional body
  AdminSkillActionRequest (reason).
- RouteSecurityPolicyRegistry: require skill:yank for the new route on
  both prefixes, so tokens can reach it as the SESSION_ONLY_ROUTES
  comment promises for every route the authorization list opens. The
  admin yank stays session-only. No allow-list of scopes exists outside
  the registry; the docs' scope enumeration is updated to include
  skill:yank.
- Tests: RouteSecurityPolicyRegistryTest (scope required on both
  prefixes, admin route still closed), SkillGovernanceServiceTest
  (owner and namespace ADMIN allowed, MEMBER forbidden, unpublished
  rejected), SkillLifecycleControllerTest (envelope with and without
  body).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DdnYX4jTS3JwMMP9JCGxzU

* fix(auth): complete API token lifecycle access

Signed-off-by: XiaoSeS <87064762+XiaoSeS@users.noreply.github.com>

* fix(skills): align owner lifecycle token access

Signed-off-by: XiaoSeS <87064762+XiaoSeS@users.noreply.github.com>

---------

Signed-off-by: XiaoSeS <87064762+XiaoSeS@users.noreply.github.com>
Co-authored-by: Thiago Nascimento Nogueira <thiago.nascimento.nogueira@emeal.nttdata.com>
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
Co-authored-by: XiaoSeS <87064762+XiaoSeS@users.noreply.github.com>
2026-09-17 18:48:05 +08:00
XiaoSeS
45d341f144
feat(review): add skill comments and user feedback (#793)
* feat(review): add skill review domain model

Signed-off-by: XiaoSeS <87064762+XiaoSeS@users.noreply.github.com>

* feat(review): expose skill reviews in API and UI

Signed-off-by: XiaoSeS <87064762+XiaoSeS@users.noreply.github.com>

* fix(review): preserve moderation under concurrent edits

Signed-off-by: XiaoSeS <87064762+XiaoSeS@users.noreply.github.com>

* fix(review): scope concurrent write conflicts

Signed-off-by: XiaoSeS <87064762+XiaoSeS@users.noreply.github.com>

* fix(review): restore web build compatibility

Signed-off-by: XiaoSeS <87064762+XiaoSeS@users.noreply.github.com>

* fix(review): keep author cleanup available

Signed-off-by: XiaoSeS <87064762+XiaoSeS@users.noreply.github.com>

* fix(review): preserve author cleanup access

Signed-off-by: XiaoSeS <87064762+XiaoSeS@users.noreply.github.com>

* fix(review): require review score contract

Signed-off-by: XiaoSeS <87064762+XiaoSeS@users.noreply.github.com>

* test(review): strengthen failure and concurrency coverage

Signed-off-by: XiaoSeS <87064762+XiaoSeS@users.noreply.github.com>

* test(review): tighten persistence assertions

Signed-off-by: XiaoSeS <87064762+XiaoSeS@users.noreply.github.com>

* test(review): disambiguate repository ports

Signed-off-by: XiaoSeS <87064762+XiaoSeS@users.noreply.github.com>

* fix(review): enable request validation

Signed-off-by: XiaoSeS <87064762+XiaoSeS@users.noreply.github.com>

* test(review): align validation and postgres coverage

Signed-off-by: XiaoSeS <87064762+XiaoSeS@users.noreply.github.com>

* test(namespace): verify invalid batch has no side effects

Signed-off-by: XiaoSeS <87064762+XiaoSeS@users.noreply.github.com>

* test(web): align accessibility and plural assertions

Signed-off-by: XiaoSeS <87064762+XiaoSeS@users.noreply.github.com>

* test(i18n): require complete plural references

Signed-off-by: XiaoSeS <87064762+XiaoSeS@users.noreply.github.com>

* fix(review): wrap editor actions on mobile

Signed-off-by: XiaoSeS <87064762+XiaoSeS@users.noreply.github.com>

* fix(review): wrap long mobile labels

Signed-off-by: XiaoSeS <87064762+XiaoSeS@users.noreply.github.com>

* fix(review): disable edits for archived skills

Signed-off-by: XiaoSeS <87064762+XiaoSeS@users.noreply.github.com>

* fix(review): enforce archived mutation guard

Signed-off-by: XiaoSeS <87064762+XiaoSeS@users.noreply.github.com>

---------

Signed-off-by: XiaoSeS <87064762+XiaoSeS@users.noreply.github.com>
2026-09-02 11:15:52 +08:00
dongmucat
3a254d7524 fix(auth): guard SUPER_ADMIN role mutations
Signed-off-by: dongmucat <1127093059@qq.com>
2026-07-01 16:23:45 +08:00
vsxd
2868c10467 refactor(app): slim portal controllers and sync backend findings 2026-03-20 10:09:03 +08:00
Xudong Sun
4aa3d29599 refactor: skill lifecycle projection and docs (#78)
* Refactor skill lifecycle projection and docs

* Improve owner lifecycle visibility on skill detail

* Track download counts per skill version
2026-03-18 13:39:22 +08:00
tww
bd83f91648 cli fix 2026-03-15 20:34:36 +08:00
yun-zhi-ztl
14328868ae docs: align roadmap with current review flow 2026-03-15 16:16:33 +08:00
yun-zhi-ztl
bf62b340ab fix: change api/v1/cli to api/v1 2026-03-14 20:35:50 +08:00
vsxd
ac352314f7 Add extensible auth compatibility layer for private SSO 2026-03-13 18:00:22 +08:00
vsxd
3682a4646b Auto-publish skills submitted by super admins 2026-03-13 15:36:56 +08:00
vsxd
9d7282221c docs: update specs, plans, and design documents for Phase 2-4 2026-03-12 17:46:41 +08:00
vsxd
95c8c31561 feat(domain): complete Phase 1 entity fields for Namespace and NamespaceMember 2026-03-12 01:51:57 +08:00
vsxd
27b7a4dad1 feat: project ini and docs updates 2026-03-11 22:47:05 +08:00
vsxd
dfa66bbfbe docs: rename project to skillhub 2026-03-11 20:34:09 +08:00
vsxd
db64bef098 docs: project's documents 2026-03-11 20:24:01 +08:00