AgentSkillsCN

synnovator

通过基于文件的 YAML+Markdown 引擎,管理 Synnovator 平台数据——涵盖 7 种内容类型(分类、文章、资源、规则、用户、群组、互动)以及 9 种关系类型。数据存储于 PROJECT_DIR/.synnovator/ 目录下。适用于对平台内容执行 CRUD 操作、管理活动与赛事、团队、文章、用户互动(点赞/评论/评分),或开展用户旅程测试。任何涉及 Synnovator 平台数据的操作、用户旅程模拟,或内容管理相关请求,均可触发此功能。

SKILL.md
--- frontmatter
name: synnovator
description: >
  Manage Synnovator platform data: 7 content types (category, post, resource, rule, user, group, interaction)
  and 9 relationship types via a file-based YAML+Markdown engine. Data stored in PROJECT_DIR/.synnovator/.
  Use when performing CRUD operations on platform content, managing activities/competitions, teams,
  posts, user interactions (likes/comments/ratings), or testing user journeys.
  Trigger: any request involving Synnovator platform data, user journey simulation, or content management.

Synnovator

File-based data engine for the Synnovator platform. All records are .md files with YAML frontmatter + Markdown body, stored under PROJECT_DIR/.synnovator/.

Quick Start

bash
# Initialize data directory
uv run python .claude/skills/synnovator/scripts/engine.py --init

# CRUD operations
uv run python .claude/skills/synnovator/scripts/engine.py [--user USER_ID] COMMAND TYPE [OPTIONS]

Commands: create, read, update, delete

Data Model

7 content types stored as .md files in .synnovator/<type>/:

  • category - Activities/competitions (YAML + Markdown body)
  • post - User posts with tags (YAML + Markdown body)
  • resource - File attachments (YAML frontmatter only)
  • rule - Activity rules with scoring criteria (YAML + Markdown body)
  • user - User accounts (YAML frontmatter only)
  • group - Teams/groups (YAML frontmatter only)
  • interaction - Likes, comments, ratings (YAML frontmatter only). Target info is stored in target_interaction relation, not on the interaction itself.

9 relationship types stored in .synnovator/relations/<type>/:

  • category_rule - Activity-to-rule bindings
  • category_post - Activity-to-post submissions
  • category_group - Team activity registration
  • category_category - Activity association (stage / track / prerequisite)
  • post_post - Post references/embeds/replies
  • post_resource - Post-to-attachment links
  • group_user - Group membership (with approval workflow)
  • user_user - User follow/block relationships
  • target_interaction - Content-to-interaction bindings

See references/schema.md for complete field definitions.

Content CRUD

Create

bash
engine.py [--user UID] create <type> --data '<json>' [--body 'markdown content']

Auto-generates: id, created_at, updated_at, deleted_at. Sets created_by from --user.

Read

bash
engine.py read <type> --id <record_id>           # Single record
engine.py read <type> --filters '<json>'          # Filtered list
engine.py read <type> --include-deleted           # Include soft-deleted

Update

bash
engine.py update <type> --id <record_id> --data '<json>'

For tags: "+tagname" appends, "-tagname" removes. Body: "_body": "new markdown".

Delete

bash
engine.py delete <type> --id <record_id>          # Soft delete (default)
engine.py delete <type> --id <record_id> --hard    # Hard delete

Cascades: deleting a post removes its relations and soft-deletes linked interactions.

Relation CRUD

bash
engine.py create <rel_type> --data '<json>'                        # Create
engine.py read <rel_type> --filters '<json>'                       # Read
engine.py update <rel_type> --filters '<json>' --data '<json>'     # Update
engine.py delete <rel_type> --filters '<json>'                     # Delete (hard)

Use _ or : separator: category_rule or category:rule.

Key Behaviors

  • Soft delete: Sets deleted_at, record stays on disk. Default for content types.
  • Hard delete: Removes file. Default for relations.
  • Cache stats: like_count, comment_count, average_rating on posts are read-only — auto-recalculated when target_interaction relations are created/deleted. Manual updates to these fields are silently ignored.
  • Two-step interactions: Creating an interaction requires: (1) create interaction for the record, (2) create target_interaction to link it to a target. Cache updates, duplicate-like checks, and target validation happen at step 2.
  • Group approval: require_approval=true sets join status to pending; owner approves via UPDATE group_user.
  • Uniqueness: Enforced for user (username), (email); like (user, target) at target_interaction creation; relation duplicates; user-per-category-per-group (a user can only belong to one group per category); user_user (source_user_id, target_user_id, relation_type); category_category (source_category_id, target_category_id).
  • Self-reference prevention: user_user and category_category cannot reference the same entity as both source and target.
  • Block enforcement: If user B blocks user A, A cannot follow B.
  • Circular dependency detection: category_category with stage or prerequisite relation types prevents cycles (A→B→C→A).
  • Prerequisite enforcement: Creating a category_group registration checks that all prerequisite categories (via category_category prerequisite) are closed.
  • Cascades: Deleting content cascades to relations and interactions per the schema spec. Notably:
    • Deleting a group cascades to both group_user and category_group relations.
    • Deleting a user cascades to group_user and user_user relations and soft-deletes all user interactions.
    • Deleting a category cascades to category_rule, category_post, category_group, and category_category relations and soft-deletes linked interactions.

Rule Enforcement

Rules linked to a category via category_rule are automatically enforced via a hook system. Rules support two definition styles: fixed fields (backward-compatible shorthand) and declarative checks (extensible condition-action pairs). All rules must pass (AND logic); any single violation rejects the operation.

Hook Points

OperationPhaseValidations
create category_postpreTime window, max submissions, submission format, min team size, resource requirements, entry prerequisites
create category_postpostPost-submission actions (notifications, etc.)
create group_userpreMax team size (checked against all categories the group is registered for)
create group_userpostPost-join actions
create category_groupprePrerequisite categories closed, entry conditions (team/proposal existence)
create category_grouppostPost-registration actions
update post.statuspreallow_public / require_review path enforcement
update post.statuspostPost-status-change actions
update category.statusprePre-closure validation
update category.statuspostClosure actions: disqualification flagging, ranking computation, certificate awarding

Phases

  • pre: Runs before the operation. on_fail: deny blocks the operation. on_fail: warn allows with warning. on_fail: flag marks but allows.
  • post: Runs after a successful operation. Never blocks. Used for compute/award/notify actions.

Validation Chain

code
category_post:   category → category_rule → rule.checks[trigger=create_relation(category_post)]
group_user:      group → category_group → category → category_rule → rule.checks[trigger=create_relation(group_user)]
category_group:  category → category_category(prerequisite) + category_rule → rule.checks[trigger=create_relation(category_group)]
post.status:     post → category_post → category → category_rule → rule.checks[trigger=update_content(post.status)]
category.status: category → category_rule → rule.checks[trigger=update_content(category.status)]

Fixed Fields as Syntactic Sugar

Fixed fields on Rule (max_submissions, min_team_size, submission_format, etc.) are automatically expanded into equivalent checks entries by the engine. User-defined checks are appended after expanded entries.

Fixed FieldExpands To
submission_start / submission_deadlinetime_window check on create_relation(category_post) pre
max_submissionscount check on create_relation(category_post) pre
submission_formatresource_format check on create_relation(category_post) pre
min_team_sizecount check on create_relation(category_post) pre
max_team_sizecount check on create_relation(group_user) pre
allow_public / require_reviewfield_match check on update_content(post.status) pre

Condition Types

TypeDescription
time_windowCurrent time within [start, end]
countEntity/relation count satisfies op + value
existsEntity/relation exists (or must not exist)
field_matchEntity field matches a predicate
resource_formatPost resources match allowed formats
resource_requiredPost has minimum required resources
unique_per_scopeUniqueness within a scope
aggregateAggregated value (count/sum/avg) meets threshold

Action Types (post phase only)

ActionDescription
flag_disqualifiedMark entities that fail post-closure checks
compute_rankingCalculate rankings from average_rating
award_certificateAuto-create certificate resources and posts per rank range
notifySend notifications (reserved, not yet implemented)

Behavior

  • No rules linked → no constraints, operation proceeds normally.
  • Rule field absent → that constraint is skipped (e.g., no submission_deadline means no time limit).
  • Violation (pre) → operation rejected with error: Rule '<name>': <reason>.
  • Violation (post) → action executes (flag/compute/award), does not rollback.
  • Posts not linked to any category are unconstrained (rules only apply through category_post).

See docs/rule-engine.md for the full specification.

File Format

Each record is a .md file:

markdown
---
name: 2025 AI Hackathon
type: competition
status: published
id: cat_abc123
created_by: user_alice
created_at: '2025-01-01T00:00:00Z'
---

## Activity Description

Markdown content here.

Testing

Tests are organized as modular files under scripts/tests/, one per test-case spec in specs/testcases/.

bash
# Run all tests
uv run python .claude/skills/synnovator/scripts/tests/run_all.py

# Run specific test files by number
uv run python .claude/skills/synnovator/scripts/tests/run_all.py 3 4 11

# Run a single test file directly
uv run python .claude/skills/synnovator/scripts/tests/test_11_user_journeys.py

Test File Map

#FileTC PrefixCoverage
1test_01_user.pyTC-USER-*User CRUD
2test_02_category.pyTC-CAT-*Category CRUD
3test_03_rule.pyTC-RULE-*Rule CRUD + enforcement
4test_04_group.pyTC-GRP-*Group CRUD + approval
5test_05_post.pyTC-POST-*Post CRUD + visibility
6test_06_resource.pyTC-RES-*Resource CRUD
7test_07_interaction.pyTC-IACT-*Interaction CRUD
8test_08_relations.pyTC-REL-*All 9 relation types
9test_09_cascade_delete.pyTC-DEL-*Cascade delete
10test_10_permissions.pyTC-PERM-*Access control
11test_11_user_journeys.pyTC-JOUR-*Integration (sequential)
12test_12_resource_transfer.pyTC-TRANSFER-*Resource transfer
13test_13_user_follow.pyTC-FRIEND-*Follow/block
14test_14_category_association.pyTC-STAGE/TRACK/PREREQ/CATREL-*Category associations
15test_15_entry_rules.pyTC-ENTRY-*Entry preconditions
16test_16_closure_rules.pyTC-CLOSE-*Closure rules
17test_17_rule_engine.pyTC-ENGINE-*Rule engine conditions/actions

Each file uses isolated data directories for parallel-safe execution. Shared fixtures are in scripts/tests/base.py.

See references/endpoints.md for detailed API examples. See references/schema.md for complete field and enum definitions.

Documentation Sync

This skill's data model is the implementation of the canonical specs in docs/ and specs/. When modifying the skill's schema, engine logic, or data model, must sync the following docs:

Skill fileCanonical docsSync what
references/schema.mddocs/data-types.md, docs/relationships.mdField definitions, enums, required fields, relation schemas
scripts/engine.py (CRUD logic)docs/crud-operations.md, specs/data-integrity.mdCRUD operations, cascade strategies, uniqueness constraints
scripts/engine.py (cache)specs/cache-strategy.mdCache stats triggers, read-only enforcement
scripts/tests/test_11_user_journeys.pydocs/user-journeys.mdUser journey steps, data operation sequences
scripts/tests/test_*.pyspecs/testcases/*.mdTest cases aligned 1:1 with spec numbering

Checklist when updating the skill:

  1. Update skill code (engine.py) and tests (scripts/tests/test_*.py)
  2. Update skill reference docs (references/schema.md, references/endpoints.md)
  3. Update canonical docs (docs/data-types.md, docs/relationships.md, docs/crud-operations.md, docs/user-journeys.md)
  4. Run uv run python .claude/skills/synnovator/scripts/tests/run_all.py to verify