use-cases.md #2

  • //
  • p4sudo/
  • dev/
  • doc/
  • use-cases.md
  • Markdown
  • View
  • Commits
  • Open Download .zip Download (12 KB)

P4Sudo — Use Cases


Use Case 001: Bootstrap Black Belt INFO.md on PPN

Overview

When a new customer is onboarded to the Perforce Black Belt consulting subscription program, a standard INFO.md file must be created from a template and submitted to the PPN (Perforce Partner Network) P4 server in a customer-specific depot path. A corresponding row must also be added to a shared customer index file.

This is a technically complex operation requiring P4 super access (creating depots and streams), but the person initiating it is typically a non-technical program manager. P4Sudo exposes this as a single web-form interaction backed by a script that handles all P4 operations transparently.

Server: PPN (ssl:50.18.77.74:1670 / ssl:ppn.perforce.com:1670) Command name: mkblackbelt Command type: site-defined script Invocation: p4 sudo mkblackbelt <CustomerTag> [options]


Authorization

Who Access
Black Belt program managers Authorized to run mkblackbelt via web UI
P4 administrators Can run all p4 sudo commands

This command runs exclusively via the web UI; CLI invocation is for admin/debug use only.


Workflow

The command executes the following steps in order. Any abort leaves the ephemeral workspace in place (to aid debugging) and logs a detailed error.

1. Validate inputs
2. Fetch INFO.md template from PPN
3. Provision //<CustomerTag> stream depot (idempotent)
4. Provision //<CustomerTag>/main stream (idempotent)
5. Create ephemeral workspace for //<CustomerTag>/main
6. Instantiate INFO.md from template (text substitution)
7. Submit INFO.md to //<CustomerTag>/main/BlackBelt/INFO.md
8. Delete ephemeral workspace (only on success)
9. Update CustomerIndex.md via persistent BlackBelt workspace

Step-by-step detail

Step 1 — Validate inputs

  • All required fields present and non-empty
  • CustomerTag matches pattern: alphanumeric, any case, no spaces, no special characters, must not start with a digit
  • Dates in YYYY/MM/DD format
  • Abort with descriptive error on any validation failure

Step 2 — Fetch template

  • p4 print -q -o <tmpfile> //BlackBelt/main/docs/INFO.md.template
  • Abort if file cannot be fetched (log P4 error output)
  • No workspace needed for this step

Step 3 — Provision depot

  • Check: p4 depots -e <CustomerTag> — if exists, skip creation and continue
  • If not: p4 depot -i to create a stream depot named <CustomerTag>
  • Abort if creation fails

Step 4 — Provision stream

  • Check: p4 streams -e //<CustomerTag>/main — if exists, skip and continue
  • If not: p4 stream -i to create //<CustomerTag>/main as a mainline stream
  • Abort if creation fails

Step 5 — Create ephemeral workspace

  • Name: p4sudo-mkblackbelt-<CustomerTag>-<timestamp>
  • Root: a temp directory (e.g. /tmp/p4sudo-mkblackbelt-<CustomerTag>-<timestamp>)
  • Stream: //<CustomerTag>/main
  • Owner: p4sudo-svc
  • On success of step 8: delete workspace and temp directory
  • On abort: leave workspace and temp directory in place for debugging

Step 6 — Instantiate INFO.md

  • Perform token substitutions on the fetched template (see Substitution Tokens section below)
  • Write result to <workspace_root>/BlackBelt/INFO.md

Step 7 — Submit INFO.md

  • p4 -c <ephemeral_workspace> add <workspace_root>/BlackBelt/INFO.md
  • p4 -c <ephemeral_workspace> submit -d "Bootstrap Black Belt INFO.md for <CustomerTag>"
  • Abort if add or submit fails

Step 8 — Delete ephemeral workspace (only on success)

  • p4 client -d <ephemeral_workspace_name>
  • Remove temp directory

Step 9 — Update CustomerIndex.md

  • Uses persistent workspace mapped to //BlackBelt/main
  • p4 -c <blackbelt_persistent_workspace> sync //BlackBelt/main/Customers/CustomerIndex.md
  • p4 -c <blackbelt_persistent_workspace> edit //BlackBelt/main/Customers/CustomerIndex.md
  • Insert new row in the Active Customers table (see Row Format below)
  • p4 -c <blackbelt_persistent_workspace> submit -d "Add <CustomerTag> to Black Belt Customer Index"
  • Abort if any step fails

Template and Substitution Tokens

Template location on PPN: //BlackBelt/main/docs/INFO.md.template

Token Field Notes
__EDITME_CUSTOMER_TAG__ CustomerTag Used in multiple places
__EDITME_SALESFORCE_LINK__ Salesforce URL Full URL
__EDITME_YYYY_MM_DD__ Activation date Date INFO.md is created (auto-set to today)
__EDITME_LICENSED_USERS__ Licensed user count Integer
__EDITME_BACKGROUND_USERS__ Background user count Integer
__EDITME_PROGRAM_START_DATE__ Program start date YYYY/MM/DD
__EDITME_PROGRAM_END_DATE__ Program end date YYYY/MM/DD
__EDITME_CONTACT_1_NAME__ Customer contact 1 name
__EDITME_CONTACT_1_EMAIL__ Customer contact 1 email
__EDITME_CONTACT_1_ROLE_AND_NOTES__ Customer contact 1 role
__EDITME_CONTACT_2_NAME__ Customer contact 2 name Optional
__EDITME_CONTACT_2_EMAIL__ Customer contact 2 email Optional
__EDITME_CONTACT_2_ROLE_AND_NOTES__ Customer contact 2 role Optional
__EDITME_P4_PRIMARY_NAME__ P4 primary contact name
__EDITME_P4_PRIMARY_EMAIL__ P4 primary contact email
__EDITME_P4_PRIMARY_ROLE_AND_NOTES__ P4 primary contact role
__EDITME_P4_SECONDARY_NAME__ P4 secondary contact name Optional
__EDITME_P4_SECONDARY_EMAIL__ P4 secondary contact email
__EDITME_P4_SECONDARY_ROLE_AND_NOTES__ P4 secondary contact role
__EDITME_P4_EXTRA_1_NAME__ P4 extra contact 1 name Optional
__EDITME_P4_EXTRA_1_EMAIL__ P4 extra contact 1 email Optional
__EDITME_P4_EXTRA_1_ROLE_AND_NOTES__ P4 extra contact 1 role Optional
__EDITME_P4_EXTRA_2_NAME__ P4 extra contact 2 name Optional
__EDITME_P4_EXTRA_2_EMAIL__ P4 extra contact 2 email Optional
__EDITME_P4_EXTRA_2_ROLE_AND_NOTES__ P4 extra contact 2 role Optional
__EDITME_YY_MM_DD__ History entry date Auto-set to today (YY/MM/DD format)

Note: Virginia Tong <vtong@perforce.com> appears as a hard-coded P4 staff contact in the template (Program Management role). No substitution needed for that row.


CustomerIndex.md Row Format

File location on PPN: //BlackBelt/main/Customers/CustomerIndex.md

New rows are appended to the Active Customers table. The link uses the P4 Code Review (Swarm) URL format:

| [<CustomerTag>](https://ppn.perforce.com/files/<CustomerTag>/main/BlackBelt/INFO.md) | Active | <StartDate> | <EndDate> | <Tier> | <Comms> | <Notes> |
Column Source
Customer CustomerTag (linked to Swarm URL)
Status Always Active for new entries
Start Program Start Date (YYYY/MM/DD)
End Program End Date (YYYY/MM/DD)
Tier User input (Standard / Enterprise / Essential)
Comms User input (e.g. Slack #ext-<channel>)
Notes User input (optional free text)

Web UI Form Fields

The web form presents the following inputs. Fields marked Required must be filled before submission; Optional fields may be left blank (tokens for those fields will be replaced with an empty string in the generated INFO.md, pending manual cleanup).

Customer Identity

Field Type Required Notes
Customer Tag word Yes Alphanumeric, no spaces, no leading digit. Becomes P4 depot name
Salesforce Link url Yes Full Salesforce opportunity/account URL
Tier select Yes Options: Standard, Enterprise, Essential
Comms Channel line Yes e.g. Slack #ext-acme-perforce-bb
Notes line No Free text for CustomerIndex Notes column

Program Dates

Field Type Required Notes
Program Start Date date Yes YYYY/MM/DD
Program End Date date Yes YYYY/MM/DD
Licensed Users integer Yes
Background Users integer Yes

Activation date (__EDITME_YYYY_MM_DD__) and history date (__EDITME_YY_MM_DD__) are set automatically to today.

Customer Contacts

Field Type Required Notes
Contact 1 Name line Yes
Contact 1 Email email Yes
Contact 1 Role/Notes line Yes
Contact 2 Name line No
Contact 2 Email email No
Contact 2 Role/Notes line No

P4 Staff Contacts

Field Type Required Notes
P4 Primary Name line Yes
P4 Primary Email email Yes
P4 Primary Role/Notes line Yes
P4 Secondary Name line No
P4 Secondary Email email No
P4 Secondary Role/Notes line No
P4 Extra Contact 1 Name line No
P4 Extra Contact 1 Email email No
P4 Extra Contact 1 Role/Notes line No
P4 Extra Contact 2 Name line No
P4 Extra Contact 2 Email email No
P4 Extra Contact 2 Role/Notes line No

Design Implications

This use case reveals that the INI-style p4sudo.cfg format (designed for simple commands with a handful of scalar arguments) is not sufficient to describe a command with:

  • Grouped / composite fields (a contact = name + email + role)
  • Typed fields (date, url, email, integer, select)
  • Optional vs. required fields
  • Auto-populated fields (today's date)
  • Multiple repeatable groups (several contacts)

Recommended approach: Keep p4sudo.cfg for command registration (type, script path, description, authorization rules). Add a separate per-command UI definition file in a structured format (YAML or JSON) that describes the web form. The [commands] entry in p4sudo.cfg gains one new key: <cmd>.ui_def = /p4/common/site/p4sudo/commands/<cmd>.ui.yaml

This keeps the INI config simple and human-editable while allowing rich form definitions for complex commands.

Example p4sudo.cfg addition:

mkblackbelt.type        = script
mkblackbelt.script      = /p4/common/site/p4sudo/commands/mkblackbelt.sh
mkblackbelt.description = Bootstrap a new Black Belt customer on PPN.
mkblackbelt.usage       = p4 sudo mkblackbelt <CustomerTag> [options]
mkblackbelt.ui_def      = /p4/common/site/p4sudo/commands/mkblackbelt.ui.yaml

The mkblackbelt.ui.yaml file defines the full form structure with field types, labels, groupings, required/optional, and default values.


Open Questions — Resolved

Q1. Optional contact token handling Keep the row in the table even when a field is empty. Empty optional tokens are substituted with an empty string; no rows are removed. Required vs. optional field designation lives in mkblackbelt.ui.yaml (not in code), so it can be adjusted without a script change.

Q2. CustomerTag validation No automated validation for now — manual input only. Future integration with Perforce1 (internal Salesforce) is anticipated but not yet accessible. CustomerTag values may intentionally differ from Salesforce names (e.g. FGS vs. Friendly Greeting System) for depot-naming compatibility.

Q3. Persistent BlackBelt workspace The p4sudo-svc account requires a persistent workspace mapped to //BlackBelt/main on PPN. Suggested name: p4sudo-svc.blackbelt. The workspace root must be a directory on the production server machine. This workspace is pre-created as part of P4Sudo deployment on PPN and documented in the Admin Guide. It cannot be created by the script itself.

Q4. Conflict handling for CustomerIndex.md Concurrent runs are unlikely but worth protecting against. The script performs a sync-edit-submit cycle on CustomerIndex.md and retries once on a submit conflict (re-sync, re-apply the row addition, re-submit). If the retry also fails, abort with a clear error.

Q5. Date token format Resolved: template updated by Tom Tyler (2026-04-06) to use __EDITME_YYYY_MM_DD__ throughout. Both occurrences (line 9 "Active as of" and line 45 history entry) use the same token and are set to today's date at run time.

Q6. Swarm URL format https://ppn.perforce.com/files/<CustomerTag>/main/BlackBelt/INFO.md is confirmed correct and stable. (The product has been rebranded from "Helix Swarm" to "P4 Code Review" but the URL is unaffected.)


Use case captured from session with Tom Tyler, 2026-04-06. Open questions resolved 2026-04-06.

# P4Sudo — Use Cases

---

## Use Case 001: Bootstrap Black Belt INFO.md on PPN

### Overview

When a new customer is onboarded to the Perforce **Black Belt** consulting
subscription program, a standard `INFO.md` file must be created from a
template and submitted to the PPN (Perforce Partner Network) P4 server in a
customer-specific depot path. A corresponding row must also be added to a
shared customer index file.

This is a technically complex operation requiring P4 super access (creating
depots and streams), but the person initiating it is typically a non-technical
program manager. P4Sudo exposes this as a single web-form interaction backed
by a script that handles all P4 operations transparently.

**Server:** PPN (`ssl:50.18.77.74:1670` / `ssl:ppn.perforce.com:1670`)
**Command name:** `mkblackbelt`
**Command type:** site-defined script
**Invocation:** `p4 sudo mkblackbelt <CustomerTag> [options]`

---

### Authorization

| Who | Access |
|-----|--------|
| Black Belt program managers | Authorized to run `mkblackbelt` via web UI |
| P4 administrators | Can run all `p4 sudo` commands |

This command runs exclusively via the web UI; CLI invocation is for admin/debug
use only.

---

### Workflow

The command executes the following steps in order. Any abort leaves the
ephemeral workspace in place (to aid debugging) and logs a detailed error.

```
1. Validate inputs
2. Fetch INFO.md template from PPN
3. Provision //<CustomerTag> stream depot (idempotent)
4. Provision //<CustomerTag>/main stream (idempotent)
5. Create ephemeral workspace for //<CustomerTag>/main
6. Instantiate INFO.md from template (text substitution)
7. Submit INFO.md to //<CustomerTag>/main/BlackBelt/INFO.md
8. Delete ephemeral workspace (only on success)
9. Update CustomerIndex.md via persistent BlackBelt workspace
```

#### Step-by-step detail

**Step 1 — Validate inputs**
- All required fields present and non-empty
- CustomerTag matches pattern: alphanumeric, any case, no spaces, no special
  characters, must not start with a digit
- Dates in YYYY/MM/DD format
- Abort with descriptive error on any validation failure

**Step 2 — Fetch template**
- `p4 print -q -o <tmpfile> //BlackBelt/main/docs/INFO.md.template`
- Abort if file cannot be fetched (log P4 error output)
- No workspace needed for this step

**Step 3 — Provision depot**
- Check: `p4 depots -e <CustomerTag>` — if exists, skip creation and continue
- If not: `p4 depot -i` to create a stream depot named `<CustomerTag>`
- Abort if creation fails

**Step 4 — Provision stream**
- Check: `p4 streams -e //<CustomerTag>/main` — if exists, skip and continue
- If not: `p4 stream -i` to create `//<CustomerTag>/main` as a mainline stream
- Abort if creation fails

**Step 5 — Create ephemeral workspace**
- Name: `p4sudo-mkblackbelt-<CustomerTag>-<timestamp>`
- Root: a temp directory (e.g. `/tmp/p4sudo-mkblackbelt-<CustomerTag>-<timestamp>`)
- Stream: `//<CustomerTag>/main`
- Owner: `p4sudo-svc`
- On success of step 8: delete workspace and temp directory
- On abort: leave workspace and temp directory in place for debugging

**Step 6 — Instantiate INFO.md**
- Perform token substitutions on the fetched template (see Substitution Tokens
  section below)
- Write result to `<workspace_root>/BlackBelt/INFO.md`

**Step 7 — Submit INFO.md**
- `p4 -c <ephemeral_workspace> add <workspace_root>/BlackBelt/INFO.md`
- `p4 -c <ephemeral_workspace> submit -d "Bootstrap Black Belt INFO.md for <CustomerTag>"`
- Abort if add or submit fails

**Step 8 — Delete ephemeral workspace** *(only on success)*
- `p4 client -d <ephemeral_workspace_name>`
- Remove temp directory

**Step 9 — Update CustomerIndex.md**
- Uses persistent workspace mapped to `//BlackBelt/main`
- `p4 -c <blackbelt_persistent_workspace> sync //BlackBelt/main/Customers/CustomerIndex.md`
- `p4 -c <blackbelt_persistent_workspace> edit //BlackBelt/main/Customers/CustomerIndex.md`
- Insert new row in the **Active Customers** table (see Row Format below)
- `p4 -c <blackbelt_persistent_workspace> submit -d "Add <CustomerTag> to Black Belt Customer Index"`
- Abort if any step fails

---

### Template and Substitution Tokens

**Template location on PPN:** `//BlackBelt/main/docs/INFO.md.template`

| Token | Field | Notes |
|-------|-------|-------|
| `__EDITME_CUSTOMER_TAG__` | CustomerTag | Used in multiple places |
| `__EDITME_SALESFORCE_LINK__` | Salesforce URL | Full URL |
| `__EDITME_YYYY_MM_DD__` | Activation date | Date INFO.md is created (auto-set to today) |
| `__EDITME_LICENSED_USERS__` | Licensed user count | Integer |
| `__EDITME_BACKGROUND_USERS__` | Background user count | Integer |
| `__EDITME_PROGRAM_START_DATE__` | Program start date | YYYY/MM/DD |
| `__EDITME_PROGRAM_END_DATE__` | Program end date | YYYY/MM/DD |
| `__EDITME_CONTACT_1_NAME__` | Customer contact 1 name | |
| `__EDITME_CONTACT_1_EMAIL__` | Customer contact 1 email | |
| `__EDITME_CONTACT_1_ROLE_AND_NOTES__` | Customer contact 1 role | |
| `__EDITME_CONTACT_2_NAME__` | Customer contact 2 name | Optional |
| `__EDITME_CONTACT_2_EMAIL__` | Customer contact 2 email | Optional |
| `__EDITME_CONTACT_2_ROLE_AND_NOTES__` | Customer contact 2 role | Optional |
| `__EDITME_P4_PRIMARY_NAME__` | P4 primary contact name | |
| `__EDITME_P4_PRIMARY_EMAIL__` | P4 primary contact email | |
| `__EDITME_P4_PRIMARY_ROLE_AND_NOTES__` | P4 primary contact role | |
| `__EDITME_P4_SECONDARY_NAME__` | P4 secondary contact name | Optional |
| `__EDITME_P4_SECONDARY_EMAIL__` | P4 secondary contact email | |
| `__EDITME_P4_SECONDARY_ROLE_AND_NOTES__` | P4 secondary contact role | |
| `__EDITME_P4_EXTRA_1_NAME__` | P4 extra contact 1 name | Optional |
| `__EDITME_P4_EXTRA_1_EMAIL__` | P4 extra contact 1 email | Optional |
| `__EDITME_P4_EXTRA_1_ROLE_AND_NOTES__` | P4 extra contact 1 role | Optional |
| `__EDITME_P4_EXTRA_2_NAME__` | P4 extra contact 2 name | Optional |
| `__EDITME_P4_EXTRA_2_EMAIL__` | P4 extra contact 2 email | Optional |
| `__EDITME_P4_EXTRA_2_ROLE_AND_NOTES__` | P4 extra contact 2 role | Optional |
| `__EDITME_YY_MM_DD__` | History entry date | Auto-set to today (YY/MM/DD format) |

**Note:** Virginia Tong `<vtong@perforce.com>` appears as a hard-coded P4
staff contact in the template (Program Management role). No substitution needed
for that row.

---

### CustomerIndex.md Row Format

**File location on PPN:** `//BlackBelt/main/Customers/CustomerIndex.md`

New rows are appended to the **Active Customers** table. The link uses the P4
Code Review (Swarm) URL format:

```markdown
| [<CustomerTag>](https://ppn.perforce.com/files/<CustomerTag>/main/BlackBelt/INFO.md) | Active | <StartDate> | <EndDate> | <Tier> | <Comms> | <Notes> |
```

| Column | Source |
|--------|--------|
| Customer | CustomerTag (linked to Swarm URL) |
| Status | Always `Active` for new entries |
| Start | Program Start Date (YYYY/MM/DD) |
| End | Program End Date (YYYY/MM/DD) |
| Tier | User input (Standard / Enterprise / Essential) |
| Comms | User input (e.g. `Slack #ext-<channel>`) |
| Notes | User input (optional free text) |

---

### Web UI Form Fields

The web form presents the following inputs. Fields marked **Required** must be
filled before submission; **Optional** fields may be left blank (tokens for
those fields will be replaced with an empty string in the generated INFO.md,
pending manual cleanup).

#### Customer Identity

| Field | Type | Required | Notes |
|-------|------|----------|-------|
| Customer Tag | `word` | Yes | Alphanumeric, no spaces, no leading digit. Becomes P4 depot name |
| Salesforce Link | `url` | Yes | Full Salesforce opportunity/account URL |
| Tier | `select` | Yes | Options: Standard, Enterprise, Essential |
| Comms Channel | `line` | Yes | e.g. `Slack #ext-acme-perforce-bb` |
| Notes | `line` | No | Free text for CustomerIndex Notes column |

#### Program Dates

| Field | Type | Required | Notes |
|-------|------|----------|-------|
| Program Start Date | `date` | Yes | YYYY/MM/DD |
| Program End Date | `date` | Yes | YYYY/MM/DD |
| Licensed Users | `integer` | Yes | |
| Background Users | `integer` | Yes | |

*Activation date (`__EDITME_YYYY_MM_DD__`) and history date (`__EDITME_YY_MM_DD__`) are set automatically to today.*

#### Customer Contacts

| Field | Type | Required | Notes |
|-------|------|----------|-------|
| Contact 1 Name | `line` | Yes | |
| Contact 1 Email | `email` | Yes | |
| Contact 1 Role/Notes | `line` | Yes | |
| Contact 2 Name | `line` | No | |
| Contact 2 Email | `email` | No | |
| Contact 2 Role/Notes | `line` | No | |

#### P4 Staff Contacts

| Field | Type | Required | Notes |
|-------|------|----------|-------|
| P4 Primary Name | `line` | Yes | |
| P4 Primary Email | `email` | Yes | |
| P4 Primary Role/Notes | `line` | Yes | |
| P4 Secondary Name | `line` | No | |
| P4 Secondary Email | `email` | No | |
| P4 Secondary Role/Notes | `line` | No | |
| P4 Extra Contact 1 Name | `line` | No | |
| P4 Extra Contact 1 Email | `email` | No | |
| P4 Extra Contact 1 Role/Notes | `line` | No | |
| P4 Extra Contact 2 Name | `line` | No | |
| P4 Extra Contact 2 Email | `email` | No | |
| P4 Extra Contact 2 Role/Notes | `line` | No | |

---

### Design Implications

This use case reveals that the INI-style `p4sudo.cfg` format (designed for
simple commands with a handful of scalar arguments) is not sufficient to
describe a command with:
- Grouped / composite fields (a contact = name + email + role)
- Typed fields (date, url, email, integer, select)
- Optional vs. required fields
- Auto-populated fields (today's date)
- Multiple repeatable groups (several contacts)

**Recommended approach:** Keep `p4sudo.cfg` for command *registration* (type,
script path, description, authorization rules). Add a separate per-command
**UI definition file** in a structured format (YAML or JSON) that describes
the web form. The `[commands]` entry in `p4sudo.cfg` gains one new key:
`<cmd>.ui_def = /p4/common/site/p4sudo/commands/<cmd>.ui.yaml`

This keeps the INI config simple and human-editable while allowing rich form
definitions for complex commands.

Example `p4sudo.cfg` addition:
```ini
mkblackbelt.type        = script
mkblackbelt.script      = /p4/common/site/p4sudo/commands/mkblackbelt.sh
mkblackbelt.description = Bootstrap a new Black Belt customer on PPN.
mkblackbelt.usage       = p4 sudo mkblackbelt <CustomerTag> [options]
mkblackbelt.ui_def      = /p4/common/site/p4sudo/commands/mkblackbelt.ui.yaml
```

The `mkblackbelt.ui.yaml` file defines the full form structure with field
types, labels, groupings, required/optional, and default values.

---

### Open Questions — Resolved

**Q1. Optional contact token handling**
Keep the row in the table even when a field is empty. Empty optional tokens
are substituted with an empty string; no rows are removed. Required vs.
optional field designation lives in `mkblackbelt.ui.yaml` (not in code),
so it can be adjusted without a script change.

**Q2. CustomerTag validation**
No automated validation for now — manual input only. Future integration
with Perforce1 (internal Salesforce) is anticipated but not yet accessible.
CustomerTag values may intentionally differ from Salesforce names (e.g.
`FGS` vs. `Friendly Greeting System`) for depot-naming compatibility.

**Q3. Persistent BlackBelt workspace**
The `p4sudo-svc` account requires a persistent workspace mapped to
`//BlackBelt/main` on PPN. Suggested name: `p4sudo-svc.blackbelt`.
The workspace root must be a directory on the production server machine.
This workspace is pre-created as part of P4Sudo deployment on PPN and
documented in the Admin Guide. It cannot be created by the script itself.

**Q4. Conflict handling for CustomerIndex.md**
Concurrent runs are unlikely but worth protecting against. The script
performs a sync-edit-submit cycle on `CustomerIndex.md` and retries once
on a submit conflict (re-sync, re-apply the row addition, re-submit).
If the retry also fails, abort with a clear error.

**Q5. Date token format**
Resolved: template updated by Tom Tyler (2026-04-06) to use
`__EDITME_YYYY_MM_DD__` throughout. Both occurrences (line 9 "Active as of"
and line 45 history entry) use the same token and are set to today's date
at run time.

**Q6. Swarm URL format**
`https://ppn.perforce.com/files/<CustomerTag>/main/BlackBelt/INFO.md` is
confirmed correct and stable. (The product has been rebranded from
"Helix Swarm" to "P4 Code Review" but the URL is unaffected.)

---

*Use case captured from session with Tom Tyler, 2026-04-06.*
*Open questions resolved 2026-04-06.*
# Change User Description Committed
#2 32528 bot_Claude_Anthropic Design: resolve UC-001 open questions; add mkblackbelt.ui.yaml

Update use-cases.md with answers to open questions Q1-Q6.
Add mkblackbelt.ui.yaml: YAML web form definition for mkblackbelt.
Update p4sudo.cfg.example with mkblackbelt command entry.
Key decisions: required/optional fields live in YAML UI definition;
empty optional tokens substituted as empty string (row kept);
CustomerTag validation deferred; conflict retry on CustomerIndex.

#review-32529 @robert_cowham @tom_tyler
#1 32526 bot_Claude_Anthropic Add use-cases.md: Bootstrap Black Belt INFO.md on PPN (UC-001)

Captures the first concrete P4Sudo use case in full detail:
workflow steps, template token inventory, CustomerIndex row
format, web UI field definitions, and design implications.

Key finding: p4sudo.cfg INI format needs a companion per-command
UI definition file (YAML) for complex multi-field web forms.

#review-32527 @robert_cowham @tom_tyler