Skip to content

Prophet21 Purchase Order Write-Back B0 Live Spike Report

Prophet21 Purchase Order Write-Back: B0 Live Spike Report

Section titled “Prophet21 Purchase Order Write-Back: B0 Live Spike Report”

Date of Live Execution: 2026-09-09
Target Environment: Approved Genfit Playground connection

Target Purchase Order: 1002430 (external_po_no=ORDERMATIC-DEMO, company_no=GENFIT, vendor_id=10290)
Design Reference: Unified Revision Workbench (§4.5, §8)


This report evaluates the B0 Hard Gate mandated by §4.5 of the Unified Revision Workbench specification:

“Before any P21 write code, prove in the Genfit sandbox: live header+line read by immutable identity, the PO update transaction and required fields, line-add/remove support, concurrency/version behavior, idempotent retry, and post-write verification. If any one is unavailable, canApply=false; the product ships read/diff/record/copy-summary and the operator keys P21 manually.”

Gate Verdict: NOT PASS (B0 Hard Gate Incomplete)

Section titled “Gate Verdict: NOT PASS (B0 Hard Gate Incomplete)”

As §4.5 wrote it, the B0 gate is all-or-nothing: one unavailable capability sets canApply=false for everything. Amended 2026-09-17 for the ASF pilot (debt/backlog/supplymatic-asf-phase-1-design.md, Plan amendments): B0 PASS is now recorded per write type on the partner’s own tenant — Acknowledged, acknowledged date, promised dates, quantity, unit price — and B3 proceeds for the passed types only, with line add, remove and cancel staying manual in P21. The verdict below is the all-or-nothing read against the Genfit sandbox and it stands for general P21 write-back. Automated ERP write-backs cannot be enabled because live verification revealed multiple critical gaps that make programmatic apply unsafe:

  1. Line Removal Unsupported (FAIL): Live testing against Prophet21 Transaction API proved that programmatic line deletion / cancellation is impossible via the API:
    • When submitting cancel_flag: ON alone, the API returned Status: Passed but performed a silent no-op (no state change; cancel_flag remained 'N').
    • When submitting delete_flag: ON, the API returned Status: Failed and aborted the transaction (Cannot delete this row.).
  2. Multi-Line Promised Dates Unsafe & Unproven (FAIL): In the Prophet21 UI Server WCF transaction schema, TABPAGE_18.extended_info is an unkeyed Form element (<Keys .../> is empty). It applies exclusively to the active/selected line. Emitting multiple extended-info forms provides no line binding, making multi-line delivery date updates structurally unbindable to distinct lines.
  3. Concurrency Non-Atomic (FAIL): Concurrency protection is client-side pre-read comparison only (expectedUpdatedAt compared to live modified timestamps). P21’s transaction API endpoint does not accept an optimistic locking version token or server-side rejection header. Furthermore, mixed-result reconciliation across multi-element transaction sets was not proven live.
  4. Tenant Boundary Gaps: Verified exclusively on Genfit Playground sandbox. Production customer tenants (ASF, P.F. Markey) have differing configurations/workflows and provide zero compatibility proof.

Per §4.5:

“If any one is unavailable, canApply=false; the product ships read/diff/record/copy-summary and the operator keys P21 manually.”

General Prophet21 purchase-order write-back remains NOT enabled. B0 is still NOT PASS, and no ASF/P.F. Markey compatibility is claimed.

For the explicitly approved Genfit Playground demo connection only, p21_purchase_order_update_v1 may enable a deliberately narrower operation:

  • exactly one existing active line;
  • quantity-only, with a positive finite target quantity;
  • immutable po_line_uid identity and item-id validation;
  • mandatory fresh pre-read and exact version-token match;
  • post-write verification of quantity, active-line identities/count, collateral quantities/prices/dates, and protected header fields;
  • no automatic retry after an ambiguous transport or transaction outcome.

Added, removed, cancelled, price, date, header, mixed, and multi-line changes remain 'recorded' for manual keying. purchaseOrderTarget.canApply exposes the capability. A decision is persisted 'approved' from eligibility alone (the mapped operation matches this narrow contract); the connection-scoped flag is returned as applyEnabled so the workbench withholds Apply while it is off, and execution fails closed in revision-apply.ts unless the flag is enabled. This is a temporary demo exception on the Genfit sandbox, and it is not a scoped B0 PASS: scoped PASS is recorded per write type against a design partner’s own P21 tenant (see the amendment in §1).


B0 Requirement Test Description Live P21 Result Status
1. Immutable Read Query p21_view_po_hdr & p21_view_po_line for po_no eq 1002430 Returned header po_hdr_uid: 2430, Line 1 po_line_uid: 36118, Line 2 po_line_uid: 36175. Required unquoted Edm.Decimal literal. PASS
2. Single-Line Update Mutate Line 1: unit_quantity: 100 -> 105, unit_price: 0.185 -> 0.190, expected_ship_date: 2026-10-15 -> 2026-10-16 Transaction API returned Status: Passed. Read-back from Data Services confirmed values updated and date_last_modified advanced to 2026-09-09T18:03:36.56. PASS
3. Line Addition Append Line 3: item_id: 108, unit_quantity: 5, unit_price: 4.62, dueDate: 2026-10-25 Transaction API returned Status: Passed. Read-back confirmed Line 3 created with new immutable UID 36205. PASS
4. Line Removal Attempt line cancellation/deletion on Line 3 via cancel_flag and delete_flag FAILED. Outcome A (cancel_flag alone) resulted in silent no-op (Passed, state unchanged). Outcome B (delete_flag) aborted (Failed). FAIL (Hard Gate Blocker)
5. Multi-Line Dates Update multiple lines with distinct promised delivery dates (expected_ship_date) Structurally unproven. TABPAGE_18.extended_info has empty keys (<Keys .../>) with no line identity binding. FAIL (Hard Gate Blocker)
6. Atomic Concurrency Test server-side optimistic locking against concurrent edits Client-side pre-read check only. Transaction endpoint lacks version token / atomic server-side reject. FAIL (Hard Gate Blocker)
7. Restoration Restore Line 1 back to original values: qty: 100, price: 0.185, date: 2026-10-15 Transaction API returned Status: Passed. Read-back verified exact restoration to baseline. PASS

When submitting a transaction targeting existing line_no: 3 with cancel_flag: ON:

<DataElement>
<Keys xmlns:a="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
<a:string>line_no</a:string>
</Keys>
<Name>TABPAGE_17.tp_17_dw_17</Name>
<Rows>
<Row>
<Edits>
<Edit><Name>line_no</Name><Value>3</Value></Edit>
<Edit><Name>cancel_flag</Name><Value>ON</Value></Edit>
</Edits>
</Row>
</Rows>
<Type>List</Type>
</DataElement>

P21 Response:

{
"Summary": "Transaction Passed",
"Results": {
"Transactions": [
{
"Status": "Passed",
"Messages": []
}
]
}
}

Post-Write Verification (p21_view_po_line):

{
"line_no": 3,
"po_line_uid": 36205,
"item_id": "108",
"cancel_flag": "N",
"delete_flag": "N",
"complete": "N"
}

Finding: The API returns Passed, but P21 silently ignores the cancel flag edit. No state change occurs.

Outcome B: Transaction Aborted (delete_flag: ON)

Section titled “Outcome B: Transaction Aborted (delete_flag: ON)”

When submitting a transaction with delete_flag: ON (or both cancel_flag: ON and delete_flag: ON):

<DataElement>
<Keys xmlns:a="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
<a:string>line_no</a:string>
</Keys>
<Name>TABPAGE_17.tp_17_dw_17</Name>
<Rows>
<Row>
<Edits>
<Edit><Name>line_no</Name><Value>3</Value></Edit>
<Edit><Name>cancel_flag</Name><Value>ON</Value></Edit>
<Edit><Name>delete_flag</Name><Value>ON</Value></Edit>
</Edits>
</Row>
</Rows>
<Type>List</Type>
</DataElement>

P21 Response:

{
"Summary": "Transaction Failed. Failed: 1, Succeeded: 0.",
"Results": {
"Transactions": [
{
"Status": "Failed",
"Messages": ["The transaction has been aborted.", "Cannot delete this row."]
}
]
}
}

Finding: The UI Server rejects row deletion on purchase orders.


In the WCF DataContract schema for PurchaseOrder, line-level expected delivery dates and expedite notes live on TABPAGE_18.extended_info:

<DataElement>
<Keys xmlns:a="http://schemas.microsoft.com/2003/10/Serialization/Arrays"/>
<Name>TABPAGE_18.extended_info</Name>
<Rows>
<Row>
<Edits>
<Edit><Name>expected_ship_date</Name><Value>2026-10-20</Value></Edit>
<Edit><Name>acknowledged</Name><Value>Y</Value></Edit>
<Edit><Name>acknowledged_date</Name><Value>2026-09-09</Value></Edit>
</Edits>
<RelativeDateEdits/>
</Row>
</Rows>
<Type>Form</Type>
</DataElement>

Critical Limitation: Notice <Keys .../> is empty. The extended_info DataElement schema has no line_no key. In P21, this form targets the active row of the line list. If a transaction includes updates to multiple lines with due dates, multiple TABPAGE_18.extended_info blocks cannot specify their line associations, creating a severe risk of date cross-contamination across lines.


  1. Narrow adapter capability: purchaseOrderTarget.canApply is true, but mapChangeSet/apply accept only one existing-line quantity mutation. Every broader change is blocked or recorded.
  2. Decision and execution gates: revision-decision.ts records 'approved' for a Prophet21 connection whose server-recomputed mapping is quantity-only, regardless of the flag; it returns the connection-scoped flag as applyEnabled so the workbench withholds Apply while it is off. revision-apply.ts checks the flag before claiming or writing.
  3. Service-level guards: Prophet21Service.updatePurchaseOrder independently rechecks the flag, requires the expected version token, rejects unusable POs and inactive/mismatched lines, and emits quantity plus line identity only.
  4. Verification and uncertainty: Success requires exact read-back of the target and unchanged collateral/header state. Transport errors and unexplained partial states are WRITE_OUTCOME_UNKNOWN; retry reconciliation always starts from a fresh read.
  5. Feature flag status: p21_purchase_order_update_v1 remains default-off and may be enabled only for the approved Genfit Playground connection during the demo/rehearsal window.