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)
1. Executive Summary
Section titled “1. Executive Summary”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:
- 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: ONalone, the API returnedStatus: Passedbut performed a silent no-op (no state change;cancel_flagremained'N'). - When submitting
delete_flag: ON, the API returnedStatus: Failedand aborted the transaction (Cannot delete this row.).
- When submitting
- Multi-Line Promised Dates Unsafe & Unproven (FAIL): In the Prophet21 UI Server WCF transaction schema,
TABPAGE_18.extended_infois 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. - Concurrency Non-Atomic (FAIL): Concurrency protection is client-side pre-read comparison only (
expectedUpdatedAtcompared 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. - 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.
Architectural Resolution
Section titled “Architectural Resolution”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_uididentity 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).
2. Live Verification Test Matrix
Section titled “2. Live Verification Test Matrix”| 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 |
3. Raw Evidence & Sanitized Payloads
Section titled “3. Raw Evidence & Sanitized Payloads”3.1 Line Removal: Dual Failure Modes
Section titled “3.1 Line Removal: Dual Failure Modes”Outcome A: Silent No-Op (cancel_flag: ON)
Section titled “Outcome A: Silent No-Op (cancel_flag: ON)”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.
3.2 Unkeyed Multi-Line Extended Info
Section titled “3.2 Unkeyed Multi-Line Extended Info”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.
4. Code & Architecture Impact
Section titled “4. Code & Architecture Impact”- Narrow adapter capability:
purchaseOrderTarget.canApplyis true, butmapChangeSet/applyaccept only one existing-line quantity mutation. Every broader change is blocked or recorded. - Decision and execution gates:
revision-decision.tsrecords'approved'for a Prophet21 connection whose server-recomputed mapping is quantity-only, regardless of the flag; it returns the connection-scoped flag asapplyEnabledso the workbench withholds Apply while it is off.revision-apply.tschecks the flag before claiming or writing. - Service-level guards:
Prophet21Service.updatePurchaseOrderindependently rechecks the flag, requires the expected version token, rejects unusable POs and inactive/mismatched lines, and emits quantity plus line identity only. - 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. - Feature flag status:
p21_purchase_order_update_v1remains default-off and may be enabled only for the approved Genfit Playground connection during the demo/rehearsal window.