generated from coulomb/repo-seed
Implement post-triage operational hardening
This commit is contained in:
@@ -101,17 +101,58 @@ A Rule's action block specifies:
|
||||
|
||||
```yaml
|
||||
action:
|
||||
task_template: tasks/{template-slug}.md # required
|
||||
target_repo: event.attributes.repo_slug # expression — attribute access only
|
||||
priority: high # high | medium | low | literal
|
||||
labels: ["onboarding", "security"] # literal list
|
||||
due_in_days: 7 # optional, integer literal
|
||||
task_template: "Run SBOM rescan for {context.repo.repo_slug}"
|
||||
target_repo: context.repo.repo_slug
|
||||
priority: medium
|
||||
labels: ["sbom", "security", "{context.repo.repo_slug}"]
|
||||
due_in_days: 7
|
||||
```
|
||||
|
||||
`target_repo` and similar fields accept simple attribute access expressions
|
||||
(no boolean logic — just path traversal). This allows dynamic routing to the
|
||||
correct issue-core instance without arbitrary expression evaluation in action
|
||||
fields.
|
||||
`action.task_template` is the emitted task title template. It is not a path to a
|
||||
repo-local file. Older design notes and the legacy `tasks/*.md` directory use
|
||||
"task template" for materialized task-body templates; that is a separate legacy
|
||||
surface. To avoid surprise, new rule actions should treat `task_template` as
|
||||
`title_template` semantics until the field can be renamed in a schema-breaking
|
||||
revision.
|
||||
|
||||
Action fields accept two deterministic rendering forms:
|
||||
|
||||
- Whole-field paths: if the whole string is a path like
|
||||
`context.repo.repo_slug` or `event.attributes.repo_slug`, the rendered value
|
||||
keeps the original scalar/list/object shape from that path. This is the
|
||||
correct form for `target_repo` and other fields that should not become prose.
|
||||
- Scalar placeholders: strings may include `{context.foo}` or `{event.foo}`
|
||||
placeholders. Each placeholder must resolve to a scalar. Lists and objects are
|
||||
rejected rather than stringified, which prevents accidental JSON blobs or
|
||||
untrusted text from being embedded into task titles.
|
||||
|
||||
Unsafe action cases are rejected:
|
||||
|
||||
- Any action path outside `context.*` or `event.*`.
|
||||
- Any path containing calls, indexing, arithmetic, filters, or boolean logic.
|
||||
- Placeholder values that resolve to lists or objects.
|
||||
- `for_each` values that are not a whole-field `context.*` or `event.*` path to
|
||||
a list.
|
||||
- `bind_as` names that are not simple identifiers.
|
||||
|
||||
Per-item rule expansion is explicit:
|
||||
|
||||
```yaml
|
||||
for_each: context.repos.repos
|
||||
bind_as: repo
|
||||
condition: 'context.repo.sbom_age_days > 30'
|
||||
action:
|
||||
task_template: Run SBOM rescan for {context.repo.repo_slug}
|
||||
target_repo: context.repo.repo_slug
|
||||
priority: medium
|
||||
labels: ["sbom", "security", "automated"]
|
||||
```
|
||||
|
||||
The weekly SBOM staleness definition is the canonical pattern. The State Hub
|
||||
bulk resolver exposes all repository entries at `context.repos.repos`, the rule
|
||||
binds each item as `context.repo`, and the strict staleness definition is
|
||||
`context.repo.sbom_age_days > 30`. Thirty days exactly is not stale; thirty-one
|
||||
days is stale.
|
||||
|
||||
#### Evaluation semantics
|
||||
|
||||
|
||||
Reference in New Issue
Block a user