Green · worked reach study

Choose notification channels for maximum reach.

This tutorial exposes the full TURF contract: what each option means, who answers, the exact binary questions, the respondent-by-item incidence matrix, every candidate combination, and the tie-breaking rule.

1. State what “reach” means

green init --type turf \
  --description "Channels customers would accept for time-sensitive subscription delivery updates"
green next

A respondent is reached by a portfolio when they select at least one item in it. Here an item is a notification channel, and “selected” means the customer says that channel would appeal to them for these updates.

2. Define respondent-facing option labels

green item add channels email sms push in_app \
  --label email="Email delivery updates" \
  --label sms="SMS text delivery updates" \
  --label push="Mobile push notifications" \
  --label in_app="In-app delivery inbox"
green item list channels
green validate
Show identity versus display
stable item_id  respondent-facing label
email           Email delivery updates
sms             SMS text delivery updates
push            Mobile push notifications
in_app          In-app delivery inbox

Stable IDs drive imported rows and portfolio sets. Labels define what respondents see. The project description supplies the common use case, so “email” is never fielded without context.

3. Define respondents—there is no implicit panel

green agent-list create panel
green agent add panel --id mobile_first \
  --persona "Mobile-first customer who keeps push notifications enabled" \
  --trait primary_device=phone
green agent add panel --id inbox_manager \
  --persona "Customer who organizes purchases and receipts through email" \
  --trait email_use=high
green agent add panel --id privacy_cautious \
  --persona "Privacy-conscious customer who limits lock-screen notifications" \
  --trait notification_tolerance=low
green agent add panel --id text_reliant \
  --persona "Customer who relies on text messages for urgent logistics" \
  --trait sms_use=high
green agent-list show panel

These four records become four EDSL agents exactly as written. They demonstrate package construction; they do not constitute a representative customer sample.

4. Build and inspect the binary Survey

green field build --job-name reach --agent-list panel
ep inspect jobs.ep
ep inspect agent_list.ep
ep surveys questions survey.ep
Show actual question structure
turf_email · multiple_choice
  Study context: Channels customers would accept for time-sensitive
                 subscription delivery updates

  Option: Email delivery updates

  Would this option appeal to you?
  Options: Yes, No

turf_in_app … Option: In-app delivery inbox
turf_push   … Option: Mobile push notifications
turf_sms    … Option: SMS text delivery updates

question-map.json maps each question back to its item ID. Four options create four calls per model respondent.

5. Review, then choose administration

ep jobs cost jobs.ep --model gpt-5.4-mini
green plan field --job-name reach
Show fielding arithmetic
4 agents × 4 binary questions = 16 external model calls
requires approval: true
expected output: results.ep
# Model path—only after explicit approval
ep run jobs.ep --model gpt-5.4-mini --output results.ep

# Human path
ep humanize preview --survey survey.ep
ep humanize create --survey survey.ep \
  --schema humanize-schema.json --name "Delivery update channels"

6. Normalize to respondent-item incidence

green data import-edsl results.ep \
  --job-name reach --name field_run_1
green data quality field_run_1
Show normalized rows
respondent_id,item_id,selected
mobile_first,email,true
mobile_first,sms,false
mobile_first,push,true
mobile_first,in_app,false

One row is one respondent-item decision. TURF does not use how many selected items a person has as reach; it uses whether a portfolio contains at least one of them.

7. Reproduce the checked-in fixture

green data import-turf examples/turf/responses.csv --name channel_use
green data quality channel_use
green report turf channel_use --max-items 2
Show the binary incidence matrix
respondent  email  sms  push  in_app
r1           1     0     1      0
r2           1     1     0      0
r3           0     1     1      0
r4           0     0     1      1
r5           1     0     0      1
r6           0     1     0      1

The six-respondent fixture reproduces analysis locally. It is not output from the four illustrative agents and is not a population estimate.

8. See the set calculation

Reached(S) = union of respondents selecting any item in set S
Reach rate = |Reached(S)| / number of respondents
Show all one- and two-item outcomes
portfolio       reached  reach rate
email              3       50.0%
sms                3       50.0%
push               3       50.0%
in_app             3       50.0%

email + in_app     5       83.3%
email + push       5       83.3%
email + sms        5       83.3%
in_app + push      5       83.3%
in_app + sms       5       83.3%
push + sms         5       83.3%

Every pair ties in this deliberately symmetric fixture. Green sorts by reach, then smaller set size, then item IDs; therefore email + in_app is the deterministic first row, not a uniquely superior portfolio. The other ties remain in solutions.

9. Understand the search boundary

--max-items 2 enumerates every nonempty combination of size one or two. With four items that is 4 + 6 = 10 portfolios. Larger candidate sets grow combinatorially, and Green currently returns the first 25 sorted solutions in the report payload.

number of evaluated sets through size k
= C(n,1) + C(n,2) + … + C(n,k)

10. Save the decision artifact

green report save --name channel_portfolio \
  --kind turf --input channel_use --max-items 2
green report list
green validate --require-report turf
Show saved interpretation
best returned set  email + in_app
people reached     5 of 6
reach rate         83.3%
equally reaching two-item alternatives  5

The saved JSON retains all returned solutions and provenance. A deployment decision should also consider channel cost, fatigue, deliverability, and legal constraints; unweighted TURF optimizes reach alone.