diff --git a/components/engine/engine-intent/src/main/resources/intent-assistant-guide.md b/components/engine/engine-intent/src/main/resources/intent-assistant-guide.md
index da04dacd5dc..1afc7ebdecc 100644
--- a/components/engine/engine-intent/src/main/resources/intent-assistant-guide.md
+++ b/components/engine/engine-intent/src/main/resources/intent-assistant-guide.md
@@ -97,6 +97,8 @@ composition is opt-in.
- `major: false` - keep the field off the entity list table (it is still shown in forms and the
record details pane). Defaults to `true` (every field is a list column). Use it to declutter the list
of wide/secondary fields (e.g. `uuid`, long notes).
+- `aggregate: true` - include this numeric field in a document's **totals footer** (the sum across the
+ line items is shown under the items table). Use it on money / quantity columns of a `DocumentItem`.
- `readOnly: true` - the field is not editable in generated forms; it renders in the read-only details
block (Label: Value) above the action buttons. Use it for system/workflow-managed fields like a
`status` driven by the process. (`ProcessId`, the audit columns and `uuid` fields are flagged
@@ -422,8 +424,9 @@ entities:
(a `DocumentItem`/`*Item` child, or a single composition child). Prefer `function` over the legacy
`*Item` naming and the `documentTitle`/`kind: setting` flags (still accepted); `documentStatus` was
renamed and is now REJECTED with a migration message - use `function: EntityStatus` on the status relation.
-Reserved values for upcoming templates (e.g. `Calendar`) are recognised but rejected with a clear
-"not yet available" message until the template ships.
+`Calendar` is **available** (see the **views** section below). The values `Board` / `Gantt` /
+`Timeline` are reserved for upcoming templates and are recognised but rejected with a clear
+"not yet available" message until those templates ship.
**`documentItemsLayout: chat` - render the items as a conversation thread.** On a document master, set
`documentItemsLayout: chat` to render its line-items child as a chat thread (message bubbles + a
@@ -455,6 +458,59 @@ author vs the logged-in user.
- { name: Case, kind: manyToOne, to: Case, composition: true, required: true }
```
+### views - calendar, range, and slots
+
+**Use when:** an entity's records read better on a time surface than in a table - appointments,
+bookings, day allocations, anything keyed by a date. Set `view:` on the entity (or `function: Calendar`,
+the role alias for `view: calendar`) and add the matching config block. The generated REST controller
+and form are reused unchanged; only the presentation differs.
+
+- **`view: calendar`** (or `function: Calendar`) + a `calendar:` block renders the records as events on
+ the Harmonia calendar. **`view: range`** uses the same block for start/end spans.
+ ```yaml
+ - name: Appointment
+ view: calendar # or function: Calendar
+ fields:
+ - { name: id, type: integer, primaryKey: true, generated: true }
+ - { name: at, type: timestamp }
+ - { name: until, type: timestamp }
+ - { name: title, type: string, length: 200 }
+ relations:
+ - { name: Status, kind: manyToOne, to: AppointmentStatus, function: EntityStatus }
+ calendar:
+ start: at # date/datetime field placed on the timeline (REQUIRED)
+ end: until # optional end field for multi-hour / multi-day events
+ title: title # field or to-one relation labelling the event pill (default: the name/title)
+ color: Status # field or to-one relation the event colour is keyed by (categorical)
+ scope: # optional: a to-one relation to filter/prefill by (see below)
+ initialView: month # month (default) | week | day
+ ```
+ When the calendar entity is a **composition child**, it renders as an embedded calendar in its
+ master's detail pane instead of a standalone page. A `scope:` to-one relation filters the events to
+ the parent whose id arrives as `?=` and prefills that FK on create - so e.g. a timesheet's
+ day allocations show only that timesheet's entries.
+
+- **`view: slots`** + a `slots:` block renders an appointment/booking picker (a 3-day grid of
+ selectable time slots); a free slot opens the create form prefilled with the chosen date + time.
+ ```yaml
+ - name: Booking
+ view: slots
+ fields:
+ - { name: id, type: integer, primaryKey: true, generated: true }
+ - { name: at, type: timestamp }
+ slots:
+ start: at # the datetime field a picked slot writes to (REQUIRED)
+ open: "08:00" # first slot of the day (default 08:00)
+ close: "18:00" # exclusive end of the day (default 18:00)
+ step: 30 # slot length in minutes (default 30)
+ disabledDays: [0, 6] # weekdays always closed (0 = Sunday .. 6 = Saturday)
+ ```
+
+**Rules:** `view` is one of `calendar` / `range` / `slots`. `calendar.start` (calendar/range) and
+`slots.start` (slots) are required and must name a declared `date`/`timestamp` field; `calendar.end`
+likewise when set; `calendar.title`/`color` must be a declared field or relation; `calendar.scope` a
+declared to-one relation. `function: Calendar` cannot be combined with a different `view:`.
+
### processes - workflows and approvals
**Use when:** a record needs a multi-step flow - approvals, hand-offs, branching, or automated steps.
@@ -475,6 +531,12 @@ the literal `end`. The `trigger` fires on exactly one lifecycle event of a decla
`onCreate`, `onUpdate` or `onDelete` - and may carry a `when` guard so the process starts only when the
guard holds, e.g. `trigger: { onUpdate: Loan, when: "status == 'OVERDUE'" }`.
+**Assignees.** A `userTask`'s `assignee` is normally a role / candidate-group name (e.g. `manager`).
+Use the literal **`assignee: personal`** to route the task to the **record owner's** Inbox instead -
+the task lands with whoever owns the triggering record. This requires the trigger entity to declare a
+`personal:` relation (see *Personal surfaces*), which is how the owner is resolved; the parser rejects
+`assignee: personal` when there is no personal relation to resolve the owner from.
+
**Approve/Reject on a user task = branch on the chosen `action`.** A task form's button (e.g. Approve,
Reject) completes the task with an `action` variable; put a `decision` immediately after the task that
tests it. Continue on approve, branch to a cancel-and-end on reject - or loop the reject branch back to
@@ -923,10 +985,35 @@ schedules:
Period: now
```
+**Per-matched-row child rows (`generate.children`).** A scheduled `generate` may also fan out into
+**child rows** via a `children:` list. Each entry names a `to` target and its `parent`, and a `forEach`
+that iterates either another entity (`forEach: { entity: , match: { ... } }`) or the working days of
+the period (`forEach: { days: workingDays }`), writing one child per iteration (`map` / `defaults` /
+`dayField` as usual; nesting is capped at two levels). Use it for "create a monthly timesheet per active
+employee, with a day row per working day" style recurring generation.
+
+```yaml
+schedules:
+ - name: monthlyTimesheets
+ cron: "0 0 1 1 * ?"
+ entity: Employee
+ where: [ { field: status, op: eq, value: ACTIVE } ]
+ generate:
+ to: EmployeeTimesheet
+ map: { Employee: id }
+ defaults: { Period: now }
+ children:
+ - to: EmployeeDayAllocation
+ parent: EmployeeTimesheet
+ forEach: { days: workingDays } # one child per working day of the period
+ dayField: day
+```
+
**Rules:** unique name, a `cron`, a declared `entity`, `where` operators from the allowed list, and
**exactly one** of `notify` (valid recipient) / `generate` (a declared/cross-model `to`, a `map` over
-the row's fields/to-one relations). Composition-item cloning is **not** available on a schedule (it
-needs a selected document) - use an on-demand `generates` action for document-to-document cloning.
+the row's fields/to-one relations, optional `children`). Composition-item cloning via `items:` is
+**not** available on a schedule (it needs a selected document) - use an on-demand `generates` action
+for document-to-document cloning, or `generate.children` for the fan-out shape above.
### integrations - outbound HTTP on a data change
@@ -1047,6 +1134,16 @@ payment's unallocated balance; entity writes go only through the generated repos
| notification `channel` | `email` |
| schedule `where` `op` | `eq`, `ne`, `gt`, `ge`, `lt`, `le`, `like` |
| integration `method` | `GET`, `POST`, `PUT`, `PATCH`, `DELETE` |
+| entity `function` | `Document`, `DocumentItem`, `Master`, `Detail`, `List`, `Setting`, `Calendar` (reserved-and-rejected: `Board`, `Gantt`, `Timeline`) |
+| field `function` | `DocumentTitle` |
+| relation `function` | `EntityStatus` |
+| entity `view` | `calendar`, `range`, `slots` |
+| report `kind` | `balance` |
+| report `chart` | `bar`, `line`, `pie`, `doughnut`, `polarArea`, `radar` |
+| report `widget.kind` | `count`, `value`, `list` |
+| custom `widgets` `kind` | `kpi`, `page` |
+| rollup `op` | `count` (default), `sum` |
+| expansion `unit` | `day`, `week`, `month` |
## Mapping requests to capabilities (quick reference)