Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions CHECKSUMS.sha256
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,12 @@ b31852babf88042b36b2a9a454c455fb951dcfa9f811f775fd1ea9e610bce0b1 skills/create-
23923c0ea8f56c77f01abe963e68d309a2f079c53fc09213bcfc1ff51633aa1d skills/create-issue/SKILL.md
866d306a90b463347590a630b3573ad828991a96bcbf33b784a21a0ccd2dbf36 skills/create-pr/SKILL.md
8a251d54806d6535da7fdb0266db13b674500f501bb31e30519d1672d062c202 skills/create-workflow/SKILL.md
fb4e6ed3c68a4b359fcd295d66df5e7cb9aa72da35a3085ce4bcd811930f838f skills/create-workflow/SPEC.md
b0262cac2f45d5b6457dbe59f489a1966f2a23640079906f915ea610f6bcef35 skills/create-workflow/reference/authoring-guide.md
4cc0698aff7e7bc4f45457dee8e7b5e8e766a4017660433a0196d8d1d2d6383e skills/create-workflow/SPEC.md
e0e77bb415742f89ec1c5400dd14dd10bc6bd3076efa6e676989390cb79da491 skills/create-workflow/reference/authoring-guide.md
01d1c1db089b6cbaa0dccc8261ceb78fb1e72f1d6d614ff3cd9fb1de221f44b4 skills/create-workflow/reference/examples/inline-review-fix.yaml
69ce44fb0d52850271e3985b2303bfeead79d5ed56489f6ad9ad0d1c07ff4b67 skills/create-workflow/reference/examples/pr-review-and-triage.yaml
02727c4d7d1f680e32d77d0490122f271e0745a0cfc5552a31651e577db0433b skills/create-workflow/reference/examples/review-fix-loop.yaml
3b787a8af9d64f36c2927635238c0101c8bd3d39a9cb92e7cf45017fb2cd22f0 skills/create-workflow/reference/v1/workflow.schema.json
052f89d482166035db9fc1a9db7f9874d6bc4b09ea9df4e76941d4ed2dad5215 skills/create-workflow/reference/v1/workflow.schema.json
f62ed9de9e44dc6895dcffe07dfdba4ec0499cee9b55a6638847123eb48377a5 skills/create-workflow/reference/workflow.schema.json
c81d4549a8cfb7800d293313cda4b67ef6696cdda33753eb7cd7df51e8279b83 skills/create-workflow/validate.mjs
0d86680003d1aa448c7ab511f668e14409bb02ffd19c6b45379424d14185a8f7 skills/design-review/SKILL.md
Expand Down
20 changes: 20 additions & 0 deletions evals/results.md
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,26 @@ Pending (human): run the scenario in a fresh agent session against a public
repository pull request and verify that the generated draft grounds every claim
in the selected commit.

## create-workflow commandless chat trigger schema sync — 2026-08-22

Method: synchronized the bundled v1 trigger definitions and authoring guidance
with source commit `748107cc025bfaab890a4e37161c8e29a64c3c20`, then ran the
deterministic schema-equivalence, trigger-contract, example, and public-skill
checks.

| Criterion | Result |
|---|---|
| Validation keywords are equivalent to the source schema after removing `description` annotations | PASS |
| Command chat trigger without `chats` remains valid | PASS |
| Commandless chat trigger with a non-empty `chats` allowlist is valid | PASS |
| Commandless chat trigger with missing or empty `chats` is rejected | PASS |
| All bundled workflow examples pass schema and static DAG validation | PASS |
| Public skill checks and checksum manifest pass | PASS |

Verdict: PASS — the portable bundle documents and validates both exact-command
and allowlisted commandless chat triggers without exposing source-only release
annotations.

## public eight-skill launch catalog — 2026-07-13

Method: ran `./scripts/validate-skills.sh` over the full eleven-skill repository,
Expand Down
4 changes: 3 additions & 1 deletion skills/create-workflow/SPEC.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ create-workflow/
reference/
authoring-guide.md
workflow.schema.json
v1/
workflow.schema.json
examples/
inline-review-fix.yaml
pr-review-and-triage.yaml
Expand Down Expand Up @@ -51,4 +53,4 @@ When the public workflow schema changes:

| Bundle | Source | Source commit | Released | Normalized SHA-256 |
|---|---|---|---|---|
| `reference/v1/workflow.schema.json` | `aictrl-dev/aictrl/schemas/workflow/v1/workflow.schema.json` | `58dd5b2d5182b94dae638b212aa329b83aec5704` | 2026-07-15 | `82b1b1b5a4bb4a36068760b540b8ccc7211e088d7c4e80c5941935c69adc3872` |
| `reference/v1/workflow.schema.json` | `aictrl-dev/aictrl/schemas/workflow/v1/workflow.schema.json` | `748107cc025bfaab890a4e37161c8e29a64c3c20` | 2026-08-20 | `322cc471d1e0a5d9380bd368638710d3e2f694466f9548a719a067f52a038a6e` |
15 changes: 13 additions & 2 deletions skills/create-workflow/reference/authoring-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -400,6 +400,15 @@ triggers:
prompt:
from: message
field: text

# Fire for ordinary non-command messages from an explicit Telegram chat:
- type: chat-message
provider: telegram
chats: [123456789] # required and non-empty when command is omitted
inputs:
prompt:
from: message
field: text
```

- `label`, `comment`, `pr-ready`, and `pr-opened` require `on: pull-request`.
Expand All @@ -408,8 +417,10 @@ triggers:
- For GitHub triggers, `inputs` maps workflow parameter names to JSONPath
expressions (each must start with `$`) evaluated against the webhook payload;
max 20 entries.
- `chat-message` has no `on` field. Its required fields are `provider` and
`command`; `command` must be an exact, case-sensitive slash command. Its
- `chat-message` has no `on` field. `provider` is required. When present,
`command` must be an exact, case-sensitive slash command; a command trigger may
omit `chats` to accept any chat. When `command` is omitted, the trigger matches
ordinary non-command messages and requires a non-empty `chats` allowlist. Its
`inputs` values are `{ from, field }` mappings, where `from` is `message`,
`channel_post`, or `interaction`, and `field` is a dot-path rather than JSONPath.
Telegram has runtime support; Slack and Discord definitions can be stored but
Expand Down
17 changes: 13 additions & 4 deletions skills/create-workflow/reference/v1/workflow.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -208,9 +208,18 @@
},
"chatMessageTrigger": {
"type": "object",
"required": ["type", "provider", "command"],
"required": ["type", "provider"],
"additionalProperties": false,
"description": "Fires the workflow when a supported chat provider receives a message whose first token equals command. This trigger is not pull-request scoped and has no on field. Its inputs map workflow parameter names to chat-source and field-path objects instead of JSONPath strings.",
"description": "Fires the workflow from a supported chat provider. With command, the first token must exactly match that slash command. Without command, ordinary non-command messages must come from the required non-empty chats allowlist. This trigger is not pull-request scoped and has no on field. Its inputs map workflow parameter names to chat-source and field-path objects instead of JSONPath strings.",
"allOf": [
{
"if": { "not": { "required": ["command"] } },
"then": {
"required": ["chats"],
"properties": { "chats": { "minItems": 1 } }
}
}
],
"properties": {
"type": { "const": "chat-message" },
"provider": {
Expand All @@ -222,11 +231,11 @@
"minLength": 2,
"maxLength": 64,
"pattern": "^/[A-Za-z0-9][A-Za-z0-9_-]*$",
"description": "Slash command that fires this trigger when it is the first whitespace-delimited token of a chat message (e.g. `/run-review`). Same grammar as the comment trigger; matched exactly and case-sensitively."
"description": "Optional slash command that fires this trigger when it is the first whitespace-delimited token of a chat message (e.g. `/run-review`). Omit it to match ordinary non-command messages; a commandless trigger must declare at least one chats entry. Same grammar as the comment trigger; matched exactly and case-sensitively."
},
"chats": {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Empty chats allowlist passes when command present.

🤖 Fix with your agent
Fix this code review finding (aictrl-dev/skills PR #28, skills/create-workflow/reference/v1/workflow.schema.json:236-241):

Problem: Empty chats allowlist passes when command present
Detail: The new allOf/then branch enforces minItems:1 on chats only for commandless triggers; a command trigger with chats: [] still validates. An empty allowlist semantically means the trigger can match no chat (docs say "omit it to fire for any chat", not "set it empty"), yielding a silently dead trigger that passes schema validation. The gap predates this PR (chats never had minItems), but this PR adds the minItems machinery and leaves the empty-array case unconstrained in the command branch. Note: the bundle mirrors the upstream source schema (aictrl-dev/aictrl/schemas/workflow/v1), so the durable fix belongs upstream, then re-synced here.
Suggested fix: If the empty-allowlist semantics are unintended, add "minItems": 1 to the base chats property (next to maxItems: 100) in the source schema aictrl-dev/aictrl/schemas/workflow/v1/workflow.schema.json, so chats: [] is rejected in both branches (the then-branch then only needs required: ["chats"]), and re-sync the bundle. If empty-means-any is intended, document it in the chats description instead.

Implement the fix on the PR head branch and add a regression test that fails before the fix and passes after.
Why this matters

The new allOf/then branch enforces minItems:1 on chats only for commandless triggers; a command trigger with chats: [] still validates. An empty allowlist semantically means the trigger can match no chat (docs say "omit it to fire for any chat", not "set it empty"), yielding a silently dead trigger that passes schema validation. The gap predates this PR (chats never had minItems), but this PR adds the minItems machinery and leaves the empty-array case unconstrained in the command branch. Note: the bundle mirrors the upstream source schema (aictrl-dev/aictrl/schemas/workflow/v1), so the durable fix belongs upstream, then re-synced here.

        "chats": {
          "type": "array",
          "description": "Optional allowlist of chat/channel ids this trigger fires for. Ints (Telegram) or strings (Slack/Discord) are stored as text. Command triggers may omit it to fire for any chat; commandless triggers require at least one entry. Max 100 entries.",
          "items": { "type": ["string", "integer"] },
          "maxItems": 100
        },

"type": "array",
"description": "Optional allowlist of chat/channel ids this trigger fires for. Ints (Telegram) or strings (Slack/Discord) stored as text. Omit to fire for any chat. Max 100 entries.",
"description": "Optional allowlist of chat/channel ids this trigger fires for. Ints (Telegram) or strings (Slack/Discord) are stored as text. Command triggers may omit it to fire for any chat; commandless triggers require at least one entry. Max 100 entries.",
"items": { "type": ["string", "integer"] },
"maxItems": 100
},
Expand Down
Loading