Git Repository Structure and Resource Validation Rules
1. Configuration Goal
Prepare a compliant Git repository so that administrators can preview, import, and sync Skill, Work, Connector, and App resources from Git into Resource Hub.
A Git repository must satisfy two layers of requirements:
- The Manifest under
.workbench/correctly declares the resources; - The resource directories, definition files, and file snapshots referenced by the Manifest comply with Resource Hub validation rules.
2. Repository Directory Design
The Git repository root must provide a .workbench/ directory for declaring the resources that Resource Hub can read. .workbench/ contains only Manifest metadata; do not put passwords, Tokens, caches, runtime state, or other sensitive information there.
The currently supported repository structure is:
.workbench/
skills.json
works.json
connectors.json
apps.json
skills/
<skill-key>/
SKILL.md
works/
<work-key>/
<member>/
SKILL.md
connectors/
<connector-key>/
<member>/
SKILL.md
apps/
<app-key>/
manifest.yaml
<member>/
SKILL.mdDirectory naming rules:
- Every resource directory under
skills/must haveSKILL.mdat its root; - Each resource under
works/is organized by first-level member directories, with the member definition at<member>/SKILL.md; - Each resource under
connectors/is organized by first-level member directories, with the member definition at<member>/SKILL.md; - Each resource under
apps/must contain a rootmanifest.yamland at least one first-level member definition at<member>/SKILL.md; - Actual directory names and resource keys must exactly match the
pathin the Manifest; - The Manifest declares only the resource list; it does not contain resource content.
3. Manifest Design
Each resource type uses one Manifest file:
| Resource type | Manifest path | Manifest array field | Resource directory prefix |
|---|---|---|---|
| Skill | .workbench/skills.json | skills | skills/ |
| Work | .workbench/works.json | works | works/ |
| Connector | .workbench/connectors.json | connectors | connectors/ |
| App | .workbench/apps.json | apps | apps/ |
The repository's Access scope must match the corresponding array field. The App business resource type is app; its Git type and Access scope are both apps.
Every Manifest item must contain three fields: key, name, and path. Example:
{
"skills": [
{
"key": "code-review",
"name": "Code Review",
"path": "skills/code-review"
}
]
}Work and Connector use their corresponding array fields and directory prefixes:
{
"works": [
{
"key": "software-delivery",
"name": "Software Delivery",
"path": "works/software-delivery"
}
]
}{
"connectors": [
{
"key": "lark-plugin",
"name": "Lark Plugin",
"path": "connectors/lark-plugin"
}
]
}App example:
{
"apps": [
{
"key": "library",
"name": "Library",
"path": "apps/library"
}
]
}The names and keys above are structural examples only; they are not fixed values for a customer environment. The Manifest root must contain the corresponding array field. The works array must not be empty; skills, connectors, and apps may be empty arrays.
4. Manifest Field Validation
4.1 Basic Fields
Every Manifest item must satisfy:
- The item is an object;
key,name, andpathare non-empty strings after trimming leading and trailing whitespace;keyvalues within one Manifest are not duplicated; values that differ only in case are also duplicates;pathexactly equals the resource directory prefix pluskey;pathpoints to an actual directory in the target commit.
The corresponding values are:
| Manifest | Example key | path must be |
|---|---|---|
skills | code-review | skills/code-review |
works | software-delivery | works/software-delivery |
connectors | lark-plugin | connectors/lark-plugin |
apps | library | apps/library |
Extra root and item fields are accepted, but extra item fields are not included in the resource-list response. Git Manifest parsing does not additionally require kebab-case keys; exact path matching and subsequent resource validation still apply.
4.2 Path Safety
Manifest path values are trimmed and backslashes are converted to / before comparison and use. Use / when authoring paths and follow these rules:
- Use repository-relative paths;
- Not start with
/; - Not be absolute paths;
- Not contain a path segment whose value is
..; - Not point inside
.workbench/; - Not contain empty path segments, such as
a//b; - Consistently use
/as the path separator; - Resolve to a location that remains inside the resource directory and cannot escape to another directory.
Manifest paths may point only to directories, not directly to individual files.
Resource file-tree validation also rejects duplicate paths, requires each parent node to exist as a directory, prohibits file content on directory nodes, and prevents moving a directory into itself or a descendant.
5. Resource Directory Validation by Type
5.1 Skill
.workbench/
skills.json
skills/
<skill-key>/
SKILL.md
user_preferences.md
references/
checklist.mdGit list preview checks that the directory and root SKILL.md exist without parsing frontmatter. Import and publication also validate definition content.
Validation requirements:
- The Manifest item's
pathmust beskills/<key>; - The resource directory must exist;
SKILL.mdmust exist at the resource root;- At publication time,
SKILL.mdmust be a non-empty text file; SKILL.mdmust contain parseable YAML frontmatter;nameanddescriptionin the frontmatter must be strings, anddescriptionmust not be empty;- After trimming leading and trailing whitespace,
namemust be 1 to 100 characters long; it cannot be.or.., or contain/, a backslash, or ASCII control characters.
After an optional BOM is removed, SKILL.md must start with --- and contain a closing YAML delimiter followed by a newline. Duplicate name / description fields or invalid YAML cause writes to fail. Kebab-case names are not required. When the root definition is created, uploaded, edited, or moved through Resource Hub, its frontmatter name is synchronized to the current resource name.
A standalone Skill root may include a lowercase user_preferences.md. It stores only durable preferences explicitly confirmed by the user and remains an empty template when none exist. This supporting file is not required by Resource Hub definition validation, and the backend does not parse it as a Skill definition.
5.2 Work
.workbench/
works.json
works/
<work-key>/
plan/
SKILL.md
implement/
SKILL.md
verify/
SKILL.mdValidation requirements:
- The Manifest item's
pathmust beworks/<key>; - The Work root cannot contain a root-level
SKILL.md; - At least one first-level member definition
<member>/SKILL.mdmust exist; - The member definition's relative path must have exactly two segments, such as
plan/SKILL.md; group/plan/SKILL.mddoes not count as a first-level member definition;- Every recognized member
SKILL.mdmust contain parseable YAML frontmatter and a non-emptydescription; - After trimming leading and trailing whitespace, a member name must be non-empty and no longer than 100 characters; it cannot be
.or.., or contain/, a backslash, or ASCII control characters; - Member names must be unique by exact string within the Work; case differences are not treated as duplicates at this step.
List preview checks the first-level definition structure and does not require every first-level directory to contain SKILL.md. Import and publication also validate definition content. A root WORK.md may exist as an ordinary file but cannot replace member SKILL.md files.
5.3 Connector
.workbench/
connectors.json
connectors/
<connector-key>/
lark-approval/
SKILL.md
lark-calendar/
SKILL.md
lark-shared/
SKILL.mdValidation requirements:
- The Manifest item's
pathmust beconnectors/<key>; - The Connector root cannot contain a root-level
SKILL.md; - At least one first-level member definition
<member>/SKILL.mdmust exist; - The member definition's relative path must have exactly two segments;
- A root-level
README.md, ordinary documentation files, andreferences/inside member directories may exist; - Every recognized member
SKILL.mdmust contain parseable YAML frontmatter and a non-emptydescription; - Member names must satisfy the safety rules and be unique by exact string within the Connector.
The Connector's capabilities, authorization, and runtime contract should be guaranteed by the Connector resource's own authoring rules. Git repository validation first confirms that the Manifest, directories, and member Skill definitions have the correct structure.
A root SKILL.md together with member Skills is also invalid. Compatibility reading of historical root-only Connectors does not apply to new Git previews, imports, or republication. A root CONNECTOR.md may exist as an ordinary file, but the backend does not use it to validate authentication settings or runtime contracts.
5.4 App
.workbench/
apps.json
apps/
library/
manifest.yaml
library-query/
SKILL.md
library-update/
SKILL.mdValidation requirements:
- The Manifest item's
pathmust beapps/<key>, and the repository'sAccess scopemust beapps; - Git list and snapshot validation require a root
manifest.yamland at least one first-level<member>/SKILL.md; file names and hierarchy are case-sensitive; - List preview checks file presence without parsing the YAML in
manifest.yamlor member frontmatter; creating a draft from Git and publishing also validate member definition content; - A root
SKILL.md,skills/<member>/SKILL.md, or a deeper definition cannot satisfy the first-level member requirement for Git Apps; - Publication of non-Git App drafts and historical packages also recognizes the compatible
skills/<member>/SKILL.mdstructure, but new Git Apps should use first-level members; - Member names must follow the safety rules above and be unique by exact string; kebab-case is not required;
- Each recognized member definition must be UTF-8 text no larger than 1,000,000 bytes, contain no NUL byte, and have parseable frontmatter with a non-empty string
description; itsnameis normalized to the member directory name when the snapshot is saved.
App draft operations do not allow direct deletion of recognized member SKILL.md files. After updating a Git App package, commit and push it, then Pull the corresponding branch to update the server cache.
6. Git Read and Validation Order
When Resource Hub reads a resource from a Git repository, it checks in this order:
- Confirm that the signed-in user has administrator permission and the repository connection exists;
- Confirm that the requested resource type exactly matches the repository's
Access scope; - Select the branch by priority: the branch explicitly requested, the repository
Default branch, then the remoteHEAD; - Read the persistent cached snapshot from the target branch's most recent successful Pull; preview is unavailable without a usable snapshot;
- Read the corresponding
.workbench/*.jsonManifest from that cached Commit; - Validate Manifest JSON, array fields, item fields, key uniqueness, and resource paths;
- Validate the resource directory and type-specific definition-file structure; reading a specific snapshot also validates the file tree, file count, and sizes;
- Return the previewable resource list, branch, and commit information.
A successful Git fetch does not mean that Resource validation succeeds. The repository can be accessible while still being invalid as a Resource Hub source if its Manifest, paths, or resource directories do not meet the requirements.
Creating a repository connection triggers its first Pull. Administrators must Pull manually to refresh the cache afterward. Preview and subsequent Git sync read the cache instead of contacting the remote on every operation.
7. Resource Snapshot Limits
When reading resource snapshots during the first import and later synchronization, all of the following limits apply:
| Limit | Maximum |
|---|---|
| Files in one resource | 1000 |
| Individual file size | 100 MiB |
| Total size of all files in one resource | 500 MiB |
| File size eligible for online text reading | 1,000,000 bytes |
File encoding rules:
- Files no larger than 1,000,000 bytes that are valid UTF-8 and contain no NUL byte can be read as text;
- Other content within the individual-file limit is retained as Base64 binary;
SKILL.mdfiles used for Skill-definition validation must be valid UTF-8 text files.
8. First Import and Subsequent Sync Validation
8.1 First Import
When selecting Import from Git in Resource Hub:
- Select a Git repository that matches the resource type and confirm that the target branch has been Pulled successfully;
- Confirm the selected branch and cached preview Commit;
- Check
key,name,path, and the resource directory in the Manifest; - Confirm that file count, individual-file size, and total size meet the limits;
- The Commit used for the first import must match the Commit confirmed during preview;
- Provide the resource name and draft name during creation, with an optional description; a resource draft is created after validation passes.
For the first import, expectedCommitSha must match the current cached Commit. If another Pull changes the cached Commit after preview, preview again. New remote commits do not automatically change the cache before a Pull.
Resource and draft names must be non-empty after trimming and no longer than 100 characters; descriptions allow up to 2000 characters. Draft names are unique without regard to case within one resource, and the resource type cannot change after creation.
8.2 Subsequent Git Sync
When executing Sync from Git in the resource's Git Settings:
- Pull the target branch first; sync reads the cached Commit from that branch's most recent successful Pull;
- It confirms that both the resource key and normalized resource path match the current Manifest item; key matching is case-sensitive;
- It confirms that the resource directory and type-specific structure remain valid;
- After validation passes, it creates a new Named Draft;
- Existing drafts and published versions remain unchanged.
If the Manifest deletes or renames the current resource item, the system does not silently import from the old path. Correct the repository structure first, then preview or sync again.
8.3 Validation Before Publication
After import or sync creates a draft, publication must separately pass these checks:
- The resource and draft exist, and the draft belongs to the resource and has not been deleted;
- The version is non-empty after trimming, no longer than 100 characters, and unique within the resource; SemVer is not required. The optional version description allows up to 500 characters;
expectedRevisionis the current draft revision, expressed as a positive integer string of 1 to 19 digits; reread the draft after a concurrent change;- Every recognized Skill definition has parseable frontmatter and a non-empty string
description, and meets the structure and naming rules for its resource type.
Trim version values and reject empty input before submission; do not rely on the server to reject whitespace-only versions.
Publication creates an immutable version snapshot. A standalone Skill's name is normalized to the resource name; Work, Connector, and App members use the member directory name. This publication normalization does not modify the draft. Successful preview or draft creation does not mean the resource has been published.
9. Common Validation Problems
| Symptom | Resolution |
|---|---|
| Corresponding Manifest not found | Confirm that the target branch contains .workbench/skills.json, .workbench/works.json, .workbench/connectors.json, or .workbench/apps.json for the resource type and has been Pulled. |
| Invalid Manifest JSON | Check JSON syntax and confirm that the corresponding array field exists and is an array. |
| Item field validation fails | Check that key, name, and path are non-empty strings after trimming whitespace, and confirm that keys are unique. |
| Resource directory not found | Check that path exactly equals the resource directory prefix plus key, and confirm that the target path is a directory. |
| Resource type mismatch | Confirm that the Git repository's Access scope matches the resource type selected in Resource Hub. |
| Skill validation fails | Confirm that a non-empty SKILL.md exists at the resource root, with parseable frontmatter and a non-empty description. |
| Work validation fails | Confirm that the root has no root-level SKILL.md and contains at least one first-level <member>/SKILL.md. |
| Connector validation fails | Confirm that the root has no root-level SKILL.md and contains at least one first-level <member>/SKILL.md. |
| App validation fails | Confirm Access scope=apps, path=apps/<key>, a root manifest.yaml, and at least one first-level member definition; skills/<member>/SKILL.md alone does not pass Git validation. |
| Old content remains after a push | Pull the target branch manually, then preview or sync again; those operations do not themselves refresh the remote cache. |
resource_manifest_invalid | Check JSON, array fields, items, duplicate keys, paths, and definition structure in order; this combined error does not identify the specific failing check. |
create_package_invalid | The Git App snapshot was read, but member definitions failed creation validation; use response details to correct frontmatter or descriptions. |
draft_conflict / version_exists | Reread the draft revision before publishing again, or choose a version not already used within the resource. |
| Preview Commit has changed | Run the Git preview again and use the new Commit for the first import. |
| Snapshot exceeds size limits | Reduce the file count, split oversized files, or split the resource before committing again. |
10. Git Repository Self-checklist
Before handing the repository to Resource Hub, confirm each item:
-
Access scopematches the target resource type; -
.workbench/<type>.jsonis on the branch actually being read; - The Manifest is valid JSON, its corresponding field is an array, and a
worksarray is non-empty; - Every item has non-empty
key,name, andpathvalues after trimming whitespace; - No case-insensitive duplicate
keyexists within one Manifest; -
pathis exactlyskills/<key>,works/<key>,connectors/<key>, orapps/<key>; -
pathis an existing directory and contains no absolute path,.., or empty path segment; - The Skill resource root contains
SKILL.md; - Work and Connector roots have no root-level
SKILL.mdand contain at least one first-level member Skill; - A Git App has a root
manifest.yamland at least one first-level<member>/SKILL.md; - Work, Connector, and App member names satisfy safety rules and are unique by exact string;
- Frontmatter is parseable and
descriptionis non-empty in every recognized Skill definition file; - File count, individual-file size, and total size are within snapshot limits;
- The Commit used for the first import matches the preview result;
- The target branch has been Pulled, and preview and sync use the intended cached Commit;
- Before later synchronization, confirm that the resource key and path still match the Manifest;
- The publication version is valid and unique, and
expectedRevisionmatches the current draft; -
.workbench/and resource files contain no passwords, Tokens, private keys, or other sensitive information.
11. Completion Criteria
- The Git repository directory follows the
.workbench/, resource-directory, and member-directory conventions; - The corresponding Manifest is committed to the target branch, and JSON, field, and path validation pass;
- Resource Hub can read the resource list and display a preview Commit;
- Type-specific resource directories and
SKILL.mddefinitions pass validation; - File count, file size, total size, and encoding meet snapshot limits;
- The first import or a subsequent sync can generate a resource draft;
- Subsequent synchronization does not overwrite existing drafts or published versions;
- If publication is required, definition content, version, and draft revision validation pass, and a version has been created;
- The repository contains no authentication credentials or other sensitive information.