---
title: "Field Classification Contract"
slug: field-classification-contract
section: Globus Core
status: stable
description: "The metadata every Workflow Studio field must carry so Globus can deterministically route values to the right table and the right partner surface."
last-updated: 2026-10-07
---

# Field Classification Contract

The metadata every Workflow Studio field must carry so Globus can deterministically route values to the right table and the right partner surface. Spec only — no code changes here.

> **Capture is identical; classification must not be**
>
> Workflow Studio captures both biographical applicant attributes and program-specific application answers through the same step → snapshot mechanism. Today the difference is decided implicitly by hardcoded knowledge inside biographicalSync. Every new field a program admin adds is therefore a coin flip — sometimes it ends up on applicants and surfaces correctly, sometimes it stays in the snapshot and silently disappears from SEVIS, partner portals, and host cards. This contract makes the classification a property of the field itself, declared at authoring time. Audience visibility is not a per-field decision — it is set once at the step level (see Step Scope) and the platform's hard-coded PII registry always masks a fixed set of sensitive field types regardless. See the canonical Applicant vs Application Data boundary for what each scope means downstream.

## Problem: Capture Is Identical, Classification Is Invisible

A Workflow Studio step writes the values it collects into portal_step_snapshots keyed by the step's step_key. There is no field-level metadata on the step that says “this value belongs to the person, not to this attempt” or “a partner needs to see this on the placement card.” The boundary documented on the Applicant vs Application Data page is correct as a snapshot of the system today, but nothing in the authoring path keeps it correct tomorrow when a new field is added.

The silent-failure path

- A program admin adds a new identity-bound field to a Workflow Studio step (e.g. a second passport for dual-nationals).
- The field is captured into the snapshot row for the application.
- biographicalSync doesn't know about the new step_key, so it doesn't promote the value to the applicants row.
- The SEVIS payload, the partner applicant detail view, and the host placement card all read from the promoted columns and see nothing.
- No error is raised. No warning is shown. The data is captured but invisible to every downstream consumer.
## The Contract: Required Field Metadata

### Metadata Shape

Every field a Workflow Studio step captures (form input, upload, structured answer) must carry the following metadata as part of its step definition. This is the schema the future authoring UI must elicit and the future biographicalSync rewrite must read.

| Key | Type | Required? | Purpose |
| --- | --- | --- | --- |
| key | type | | purpose |

_(row above is a template, repeated for each data row)_

The surfaces slot is intentionally a placeholder on this page. The per-surface enumeration and the contract for how each surface renders the field live in the sibling Dynamic Field Surface Spec task. This contract requires the slot to exist on every field; the sibling task fills it in.

Per-field redaction is intentionally not in this metadata shape. Audience visibility is set on the step (see Step Scope) and the always-mask list lives in the platform PII registry — neither is a per-field choice the program admin makes.

### scope vs core (and why both)

scope

Decides where the value is stored.

- &bull; applicant — promoted onto the applicants row, reused across every attempt.
- &bull; application — stays in the per-attempt snapshot.
core

Decides whether other systems are allowed to depend on it.

- &bull; true — part of the contract. Stable name, breaking changes require a step revision.
- &bull; false — free-form snapshot data; downstream systems must not bind to it.
> **Both axes are needed**
>
> An applicant-scope field is not automatically core (e.g. a free-form “preferred nickname” on the person — promoted across attempts, but no other system cares). An application-scope field can be core (e.g. applications.status — per-attempt, but every consumer depends on it). The two axes describe orthogonal facts.

## Step Scope (Audience)

Every Workflow Studio step carries a single data scope dropdown that picks the audience allowed to see the data the step collects. Every field in the step inherits that audience. There is no per-field redaction toggle, no per-field partner_visibility predicate, no per-field hidden / masked enum — the dropdown is the only audience knob a program admin sets, and the shared projectForAudience(record, audience) projector consumes it directly.

| Value | Audience the projector serves |
| --- | --- |
| labelvalue | description |

_(row above is a template, repeated for each data row)_

The dropdown is set per step, not per field, because the audience for a step's collected data is almost always uniform — a "Recruiter intake" step's fields all go to the recruiter, a "Background check review" step's fields all stay with staff. Forcing the program admin to set audience on every individual field was the authoring nightmare this design replaces. If a single step needs to mix audiences, split it into two steps.

## Platform PII Registry

A small, fixed list of always-masked field types maintained by the platform team — not by program admins. The shared projector consults the registry on every read and applies the registry's masking format regardless of the step's data scope. The registry is the second half of the visibility contract: step scope decides who sees the step at all; the PII registry decides what is masked even for audiences that can see it.

| Field type | Masking format on non-staff surfaces |
| --- | --- |
| field | masking |

_(row above is a template, repeated for each data row)_

> **Governance**
>
> The registry is platform-team-owned and lives in the Globus codebase, not in any per-program configuration. Adding or removing entries requires a platform engineering change and a documented decision; program admins cannot opt fields in or out. The detailed schema (where in the code the registry is declared, how the projector matches a field against it, the masking-format primitives) is owned by the new Platform PII Registry ticket in P1: Foundation Hardening — this section is the contract; that ticket is the implementation.

## Decision Tree for Authoring

When a program admin adds a field to a step in Workflow Studio, the authoring UI should walk them through these questions in order. The first two map directly to the rule of thumb already documented on the Applicant vs Application boundary page.

## Worked Examples

Three fields a Workflow Studio admin might add today, classified end-to-end.

## Decision Record — Why We Dropped Field-Level Redaction

The previous design required every field on every step to declare a per-field redaction policy (e.g. none / masked / hidden_from_partners / hidden_from_hosts) plus an optional partner_visibility predicate. In a single program with hundreds of fields, that was hundreds of independent decisions a program admin had to make and keep correct over time. Forgetting one — or picking the wrong default — was silent: data leaked or vanished without any error.

We replaced it with two pieces that together preserve the same security guarantee with one decision per step instead of one decision per field:

- Step-level data scope — one dropdown per step picks the audience. Every field in the step inherits it.
- Platform PII registry — a fixed, hard-coded list of always-masked field types maintained by the platform team. The projector always masks these regardless of the step's audience.
What we kept: the shared projectForAudience projector, the build-time guard that catches direct field reads bypassing the projector, and the field surfaces contract (where each field appears in each portal). What we dropped: the per-field redaction enum and the per-field partner_visibility predicate. Implementation is tracked in Asana ticket 1214212456520951 (response projector) and the new Platform PII Registry ticket in P1: Foundation Hardening.

## Baseline Audit

What exists today — captured here so the gap between the contract and reality is concrete. No fixes are made on this page; remediation is tracked as follow-ups.

### Authoring UI (Workflow Studio)

### Runtime (biographicalSync)

### Reported Gaps (No Fixes)

| # | Gap | Layer | Severity |
| --- | --- | --- | --- |
| n | gap | | sev |

_(row above is a template, repeated for each data row)_

## Related Pages

Applicant vs Application Data

Defines the scope boundary this contract enforces at the field level. Use it for the rule-of-thumb questions in the decision tree above.

Workflow Studio &rarr; Step Key Governance

Step keys are the only stable identifier today. Field classification metadata is the missing companion that turns the key into a routing decision.

Workflow Studio Help

In-app help for program admins. Once the authoring UI is updated, classification authoring guidance lives there.

Glossary

Canonical definitions for Field Scope, Core Field, Field Surface, Snapshot Field.

Ecosystem MCP Sync

This contract was synced to the AAG ecosystem MCP coordination server when the page shipped (heartbeat + sync-status posted against /api/mcp/heartbeat and /api/mcp/sync-status) so the Partner Portal, GLOBUS Hub, and other ecosystem portals are aware of the new field metadata schema, the new glossary terms, and the gaps list. Subsequent edits to this page must repeat the sync per the mcp-sync skill.
