---
title: "Teacher Activation Workflow"
url: https://docs.growamal.com/en/guides/teacher-activation/
language: en
---

# Teacher Activation Workflow

The Teacher Activation Workflow (WP-TAW) is a **17-step guided state machine** that walks a teacher
from seeing a bundle recommendation all the way through plan review and exit. It is a pure
orchestration layer: it adds no new decision logic, only coordinates the already-built bundle,
cluster, and monitoring engines.

The workflow follows the principle stated in V-12: **the system proposes, the teacher decides**.
Every consequential action requires an explicit teacher choice.

## The six named UI surfaces

| Surface | Purpose |
|---|---|
| **Recommendations Panel** | Shows the class's active bundle recommendations (one per student) derived from the profile engine |
| **Smart Grouping Panel** | Previews which students can be clustered together (same bundle, anchor skill, scaffold tier, delivery mode) |
| **Scaffold Distribution Preview** | Shows the Level\_1 / Level\_2 / Level\_3 breakdown across a cluster before the teacher commits |
| **Activation Review** | Per-member confirmation step; teacher may apply per-member adjustments (OVR\_\* rules) before finalising |
| **Activation Confirmation** | Final commit; triggers bulk activation through the existing cluster write path |
| **Plan Review & Exit** | The ongoing surface the teacher returns to for monitoring status, alert resolution, and plan continuation or exit |

## The 17-step state machine (TAW_01..TAW_17)

The single-writer paths (review and exit) acquire an advisory lock per `(org, bundleAssignment)`; distinct assignments never block each other. The bulk-activate path delegates the full transaction to the cluster writer, which holds its own per-`(org, class)` lock. Each step is executed by delegating to the relevant shipped writer. No new write path is introduced by this module; the five single-write-path lint rules (`bundle-assignment`, `cluster-result`, `monitoring`, and related) remain green.

**Step grouping (canonical STEP\_STAGE map):**

1. **Review phase (TAW\_01..03):** load recommendations, check guardrails, surface the recommendation panel.
2. **Grouping phase (TAW\_04..06):** compute clusters, present scaffold distribution preview, let teacher adjust membership.
3. **Activation phase (TAW\_07..12):** activation review, per-member OVR confirmation, then either a bundle commit (TAW\_11 bulk / TAW\_12 individual) or a non-bundle routing record (TAW\_12). See the two activation outcomes below.
4. **Monitoring phase (TAW\_13..14):** plan status read, acute-alert surface.
5. **Decision phase (TAW\_15..17):** TAW\_15 acute-regression alert resolution, TAW\_16 plan-status transition, TAW\_17 exit.

## Draft persistence

A `workflow_draft` row (one per `(org, teacher, class)`) is the only mutable table the workflow
owns. It has a **7-day TTL** (soft-expire via `last_write_wins` upsert). All audit history lives in
`teacher_action_log` and `bundle_assignment_history.triggeringWorkflowStep`, never in the draft.

## The three guardrail flows

> **Warning:** These guardrails are enforced at the workflow boundary and cannot be bypassed by any override code.

| Guardrail | Trigger | System response |
|---|---|---|
| **Insufficient Evidence** | A student's recommendation carries `do_not_decide_yet` | Activation is blocked (409); the student is routed to the "needs more data" bucket and excluded from any cluster |
| **Acute Regression** | An open `acute_regression_alert` exists for a student | The teacher must resolve the alert first (`/api/workflow/review`): dismiss with a context flag, or escalate for a tier-review nomination. The plan status is **never auto-changed** (GSR-02) |
| **DATA\_INCOMPLETE** | The cluster engine has excluded the student via QA\_003 | The student is deferred; activation proceeds for the remaining cluster members |

## Override codes and context flags

When a teacher modifies a recommendation, the reason must come from the **9-code OverrideCodeCatalog**; no
free text is ever accepted. The applicable scope is enforced at the API level (`SCOPE_MISMATCH` → 400
when a bundle-exit code is used on a non-exit path, etc.).

Context flags use the closed `ContextFlagId` dictionary (7 allowed codes: `CTX_SESSION_INTERRUPTED`,
`CTX_TECHNICAL_ISSUE`, `CTX_AUDIO_PROBLEM`, `CTX_GROUP_NOT_COMPLETED`, `CTX_STUDENT_ABSENT`,
`CTX_NEEDED_REPETITION`, `CTX_PAPER_CHECK_ADMIN`). A context flag is recorded in `context_flag_log`
only; it is never stored on the alert row itself.

Any deviation from the recommended scaffold tier requires `confirmed: true` in the request body, or
the server returns 409 `CONFIRMATION_REQUIRED`.

## Two activation outcomes (R12 Tier-D, D-015)

`POST /api/workflow/activate` now resolves to one of two outcomes depending on the
recommendation's object type. This replaces the retired `NO_BUNDLE_SYSTEM_GUARD`
bundle path: non-bundle recommendations no longer create a placeholder assignment.

| Outcome | When | What is written | Response shape |
|---|---|---|---|
| `kind="activated"` | The recommendation is a real `INTERVENTION` / `COMPOSITE` bundle (`recommended_bundle_id` non-null) | One `bundle_assignment` + scaffold rows | `bundleId` + `activated[]`, `routing: null` |
| `kind="routed"` | The recommendation is a **non-bundle object** (`recommended_bundle_id` NULL) | **No** `bundle_assignment`, **no** scaffold; the controlled routing/action code is appended to `teacher_action_log` (`actionType='individual_routing'`, `workflowStep` TAW_12) | `routing: { studentId, objectType, routingOutcome }`, `bundleId: null`, `activated: []` |

Both outcomes return HTTP 200. The routed outcome carries only controlled
`BundleObjectType` + routing/action codes — never free text.

## RTI tier

The workflow **never writes an RTI tier**. Tier escalation/de-escalation is owned by the separate RTI
module. The workflow's escalation path opens a `TeacherReviewRequest` nomination only; the formal
`TierReviewRequest` and `applyDecision()` write live in the RTI engine.

## API endpoints (7)

All routes require teacher authentication and are ClassTeacher-scoped.

| Method | Path | Purpose |
|---|---|---|
| `GET` | `/api/workflow/steps` | Load the 17 step definitions (version-pinned) |
| `GET` | `/api/workflow/recommendations/:classId` | Fetch class recommendations (the Recommendations Panel feed) |
| `GET` | `/api/workflow/draft/:teacherId/:classId` | Resume an in-progress draft |
| `POST` | `/api/workflow/save-draft` | Persist draft state (7-day TTL upsert) |
| `POST` | `/api/workflow/activate` | Commit activation — either a bundle assignment (`kind="activated"`) or a non-bundle routing record (`kind="routed"`); see "Two activation outcomes" above |
| `POST` | `/api/workflow/review` | Resolve an acute-regression alert (dismiss or escalate) |
| `POST` | `/api/workflow/exit` | Exit / close the plan |

For full request/response shapes see the [API Reference](https://docs.growamal.com/en/api-reference/).

## Related guides

- [Intervention Bundles](https://docs.growamal.com/en/guides/intervention-bundles/): how bundles are structured (anchor + supporting threads + asset bridge)
- [Smart Clustering](https://docs.growamal.com/en/guides/smart-clustering/): how the 5-key cluster identity is computed
- [Progress Monitoring](https://docs.growamal.com/en/guides/progress-monitoring/): the monitoring status the Plan Review surface reads
- [Language Safety](https://docs.growamal.com/en/guides/language-safety/): why context flags replace free-text teacher notes
