{
  "from" : "7.6.1.3",
  "to" : "9.2",
  "export" : "examples/customer-upgrade/export",
  "assessedAt" : "2026-11-08T00:00:36Z",
  "runId" : "5a249250012e4f6bb012088dac6d3e394b1332cdd787bfcc2357e571c9582efe",
  "engine" : {
    "version" : "0.13.0",
    "appliedRules" : [ {
      "id" : "assessment.evidence-resolution@2",
      "sha256" : "3a20d215946902ddfb9edc2d6dcaed35463d5441ed3455e90bf04563899148a3",
      "scope" : "static binding context; runtime behaviour not asserted; unresolved hops remain unchecked",
      "applications" : [ "assessment.evidence-resolution@2 | assessment -> source parity, conditional constraints and product ownership" ]
    } ],
    "packVersion" : "2026.09"
  },
  "supplied" : [ "dictionary", "code", "presentation" ],
  "customer" : "Kestrel Energy",
  "estateExported" : "2026-09-10",
  "disclosure" : "Demonstration package. Kestrel Energy is fictional: the dictionary export, the Java, the automation script and the screen assessed here are synthetic customer inputs. The 7.6.1.3 and 9.2 dictionaries, the Oil & Gas add-on columns, IBM's upgrade scripts and the psdi API index they are assessed against are real.",
  "notSupplied" : [ {
    "surface" : "object-structures",
    "reason" : "the integration framework was not exported for this engagement, so no object-structure schemas were available to check. `mxh assess` now reads them when supplied: point the manifest's object-structures surface at a directory of the customer's own exported OSLC `/oslc/jsonschemas/<os>` responses (or an OpenAPI document) and every field one publishes outside the code-scanned objects is compared against the target dictionary the same way a plain attribute is"
  }, {
    "surface" : "launch-points",
    "reason" : "the automation scripts were exported as source only, so SCRIPTLAUNCHPOINT and LAUNCHPOINTVARS were not taken and what fires each script was not checked — only what it does. `mxh assess` now reads them when supplied: point the manifest's launch-points surface at the customer's own export of those two tables and every object and column a trigger binds to, plus every variable bound to a bare attribute, is compared against the target dictionary the same way a plain attribute is"
  }, {
    "surface" : "java-inventory",
    "reason" : "no JAR inventory was taken for this engagement, so only the Java under src/java is scanned for psdi references. `mxh assess` now reads compiled JARs too when supplied: point the manifest's java-jars surface at the customisation's lib directory (or a WAR's WEB-INF/lib) and every class file's constant pool is checked for removed psdi signatures the same way source is — no execution, no classloading"
  } ],
  "objectsAssessed" : 4,
  "filesScanned" : 3,
  "coverage" : {
    "objectsInventoried" : 4,
    "objectsCompared" : 4,
    "objectsChanged" : 4,
    "objectsReferenced" : 2,
    "referencesTiedBy" : {
      "object hint" : 10
    },
    "referencesUntied" : 14,
    "presentationUnresolved" : [ {
      "site" : "examples/customer-upgrade/src/screens/wotrack.xml <textbox id=k8 dataattribute=KEWELLHEAD.KEPLATFORM>",
      "binding" : "KEWELLHEAD.KEPLATFORM",
      "hop" : "WORKORDER.KEWELLHEAD",
      "reason" : "unknown-relationship"
    } ]
  },
  "findings" : [ {
    "grade" : "BLOCKING",
    "kind" : "class-removed",
    "confidence" : "A2",
    "reach" : "cited",
    "object" : "psdi.iface.jms.ErrorQueueNotfCronTask",
    "message" : "psdi.iface.jms.ErrorQueueNotfCronTask no longer exists in 9.1 and your code references it",
    "evidence" : "IBM's API at 9.1",
    "owner" : "Customisation developer",
    "requiredAction" : "Replace the reference. The type does not exist at the target, so the customisation will not compile; find the supported equivalent or remove the dependency.",
    "closureTest" : "The customisation compiles against the target's `businessobjects.jar` with no unresolved import.",
    "sites" : [ "examples/customer-upgrade/src/java/com/kestrel/maximo/PermitGate.java:8" ],
    "disposition" : {
      "proposed" : "REPLACE",
      "rationale" : "The type or member is gone at the target (A2). What references it has to point at what the target ships for the same purpose."
    }
  }, {
    "grade" : "REVIEW",
    "kind" : "screen-field-local-extension",
    "confidence" : "B2",
    "reach" : "cited",
    "object" : "ASSET",
    "attribute" : "KEINSPECTIONCLASS",
    "message" : "ASSET.KEINSPECTIONCLASS is bound on a screen through WORKORDER.ASSET → ASSET, and it is your own column: in your export, not in IBM's shipped dictionary at either release. The stock 9.2 dictionary not carrying it is expected — an in-place upgrade carries your own columns forward — so this is not a release removal and the screen is not known to be broken. Confirm the column is present on the upgraded system before cutover; if it is, the binding is unaffected. At least one hop was read from the 9.2 relationship graph mxh ships rather than from your own MAXRELATIONSHIP rows, so which object the field lands on is our assumption about your install — confirm the relationship too.",
    "evidence" : "not present in IBM's shipped dictionary at either release; bound by the screen, followed through the 9.2 relationship graph mxh ships",
    "owner" : "Application Designer / configuration",
    "requiredAction" : "Confirm the column on the upgraded system, then leave the screen alone. The field is your own column, which an in-place upgrade carries forward; the stock target dictionary not listing it is expected, not a broken binding. If the column is not there after the upgrade, re-apply it — a database change — before the screen is opened.",
    "closureTest" : "`select 1 from maxattribute where objectname = <object> and attributename = <attribute>` on the upgraded system returns a row, and the screen renders with the field populated.",
    "sites" : [ "examples/customer-upgrade/src/screens/wotrack.xml" ],
    "disposition" : {
      "proposed" : "RETAIN",
      "rationale" : "Your own column or object: in your export, not in IBM's dictionary at either release. An in-place upgrade carries it forward; confirm it on the upgraded system."
    }
  }, {
    "grade" : "REVIEW",
    "kind" : "attribute-removed",
    "confidence" : "A1",
    "reach" : "referenced",
    "object" : "ASSET",
    "attribute" : "PLUSSGEOJSON",
    "message" : "ASSET.PLUSSGEOJSON is removed on the path to 9.2 (no reference found in the code supplied)",
    "evidence" : "IBM upgrade script, 9.0",
    "owner" : "Customisation developer",
    "requiredAction" : "Change every cited site before cutover. The column is gone at the target: a read throws and a write fails.",
    "closureTest" : "`select 1 from maxattribute where objectname = <object> and attributename = <attribute>` on the target returns no row, and no cited site references it.",
    "sites" : [ ],
    "disposition" : {
      "proposed" : "INVESTIGATE",
      "rationale" : "The removal is stated by IBM's own evidence (A1) but no supplied line was seen to depend on it. Confirm nothing outside the supplied surfaces does."
    }
  }, {
    "grade" : "REVIEW",
    "kind" : "attribute-removed",
    "confidence" : "A1",
    "reach" : "referenced",
    "object" : "WORKORDER",
    "attribute" : "PLUSSGEOJSON",
    "message" : "WORKORDER.PLUSSGEOJSON is removed on the path to 9.2 (no reference found in the code supplied)",
    "evidence" : "IBM upgrade script, 9.0",
    "owner" : "Customisation developer",
    "requiredAction" : "Change every cited site before cutover. The column is gone at the target: a read throws and a write fails.",
    "closureTest" : "`select 1 from maxattribute where objectname = <object> and attributename = <attribute>` on the target returns no row, and no cited site references it.",
    "sites" : [ ],
    "disposition" : {
      "proposed" : "INVESTIGATE",
      "rationale" : "The removal is stated by IBM's own evidence (A1) but no supplied line was seen to depend on it. Confirm nothing outside the supplied surfaces does."
    }
  }, {
    "grade" : "REVIEW",
    "kind" : "method-removed",
    "confidence" : "A2",
    "reach" : "cited",
    "object" : "psdi.app.person.Person",
    "attribute" : "getAvailableHours(Ljava/util/Date;Lpsdi/app/person/PersonCalRemote;Lpsdi/app/common/AvailCalc;)D",
    "message" : "psdi.app.person.Person.getAvailableHours(Ljava/util/Date;Lpsdi/app/person/PersonCalRemote;Lpsdi/app/common/AvailCalc;)D is gone in 8.7; you reference the class — check the call",
    "evidence" : "IBM's API at 8.7",
    "owner" : "Customisation developer",
    "requiredAction" : "Check each cited site. The class survives but this member does not, so a call compiles today and fails at the target.",
    "closureTest" : "The customisation compiles against the target's `businessobjects.jar`, and the cited lines either no longer call the member or call its replacement.",
    "sites" : [ "examples/customer-upgrade/src/java/com/kestrel/maximo/PermitGate.java:9" ],
    "disposition" : {
      "proposed" : "REPLACE",
      "rationale" : "The type or member is gone at the target (A2). What references it has to point at what the target ships for the same purpose."
    }
  }, {
    "grade" : "REVIEW",
    "kind" : "method-removed",
    "confidence" : "A2",
    "reach" : "cited",
    "object" : "psdi.app.person.Person",
    "attribute" : "getAvailableMbo(Ljava/util/Date;Lpsdi/app/person/PersonCalRemote;Lpsdi/app/common/AvailCalc;)Lpsdi/mbo/MboRemote;",
    "message" : "psdi.app.person.Person.getAvailableMbo(Ljava/util/Date;Lpsdi/app/person/PersonCalRemote;Lpsdi/app/common/AvailCalc;)Lpsdi/mbo/MboRemote; is gone in 8.7; you reference the class — check the call",
    "evidence" : "IBM's API at 8.7",
    "owner" : "Customisation developer",
    "requiredAction" : "Check each cited site. The class survives but this member does not, so a call compiles today and fails at the target.",
    "closureTest" : "The customisation compiles against the target's `businessobjects.jar`, and the cited lines either no longer call the member or call its replacement.",
    "sites" : [ "examples/customer-upgrade/src/java/com/kestrel/maximo/PermitGate.java:9" ],
    "disposition" : {
      "proposed" : "REPLACE",
      "rationale" : "The type or member is gone at the target (A2). What references it has to point at what the target ships for the same purpose."
    }
  }, {
    "grade" : "REVIEW",
    "kind" : "method-removed",
    "confidence" : "A2",
    "reach" : "cited",
    "object" : "psdi.app.person.Person",
    "attribute" : "getAvailableMboList(Ljava/util/Date;Lpsdi/app/person/PersonCalRemote;Lpsdi/app/common/AvailCalc;)Ljava/util/List;",
    "message" : "psdi.app.person.Person.getAvailableMboList(Ljava/util/Date;Lpsdi/app/person/PersonCalRemote;Lpsdi/app/common/AvailCalc;)Ljava/util/List; is gone in 8.7; you reference the class — check the call",
    "evidence" : "IBM's API at 8.7",
    "owner" : "Customisation developer",
    "requiredAction" : "Check each cited site. The class survives but this member does not, so a call compiles today and fails at the target.",
    "closureTest" : "The customisation compiles against the target's `businessobjects.jar`, and the cited lines either no longer call the member or call its replacement.",
    "sites" : [ "examples/customer-upgrade/src/java/com/kestrel/maximo/PermitGate.java:9" ],
    "disposition" : {
      "proposed" : "REPLACE",
      "rationale" : "The type or member is gone at the target (A2). What references it has to point at what the target ships for the same purpose."
    }
  }, {
    "grade" : "ENVIRONMENT",
    "kind" : "local-extension",
    "confidence" : "B2",
    "reach" : "cited",
    "object" : "ASSET",
    "attribute" : "KECORROSIONLOOP",
    "message" : "ASSET.KECORROSIONLOOP is not part of IBM's own 7.6.1.3 dictionary either — it is your own field, not something the release removes. Decide whether to carry it forward to 9.2. Your code reads or writes it.",
    "evidence" : "not present in IBM's shipped 7.6.1.3 dictionary",
    "owner" : "Database / migration",
    "requiredAction" : "Decide whether to carry it forward. It is your own field, not part of IBM's dictionary at either release, so its absence at the target is not release evidence — re-applying it is a database change, not a code change.",
    "closureTest" : "Either the attribute exists on the target with the type, length and required flag your code expects, or every cited site has been changed to stop using it. One or the other, recorded.",
    "sites" : [ "examples/customer-upgrade/src/screens/wotrack.xml:24" ],
    "disposition" : {
      "proposed" : "RETAIN",
      "rationale" : "Your own column or object: in your export, not in IBM's dictionary at either release. An in-place upgrade carries it forward; confirm it on the upgraded system."
    }
  }, {
    "grade" : "ENVIRONMENT",
    "kind" : "local-extension",
    "confidence" : "B2",
    "reach" : "cited",
    "object" : "ASSET",
    "attribute" : "KEINSPECTIONCLASS",
    "message" : "ASSET.KEINSPECTIONCLASS is not part of IBM's own 7.6.1.3 dictionary either — it is your own field, not something the release removes. Decide whether to carry it forward to 9.2. Your code reads or writes it.",
    "evidence" : "not present in IBM's shipped 7.6.1.3 dictionary",
    "owner" : "Database / migration",
    "requiredAction" : "Decide whether to carry it forward. It is your own field, not part of IBM's dictionary at either release, so its absence at the target is not release evidence — re-applying it is a database change, not a code change.",
    "closureTest" : "Either the attribute exists on the target with the type, length and required flag your code expects, or every cited site has been changed to stop using it. One or the other, recorded.",
    "sites" : [ "examples/customer-upgrade/src/screens/wotrack.xml:25" ],
    "disposition" : {
      "proposed" : "RETAIN",
      "rationale" : "Your own column or object: in your export, not in IBM's dictionary at either release. An in-place upgrade carries it forward; confirm it on the upgraded system."
    }
  }, {
    "grade" : "ENVIRONMENT",
    "kind" : "local-extension",
    "confidence" : "B2",
    "reach" : "inventory",
    "object" : "FAILUREREPORT",
    "attribute" : "KEROOTCAUSECODE",
    "message" : "FAILUREREPORT.KEROOTCAUSECODE is not part of IBM's own 7.6.1.3 dictionary either — it is your own field, not something the release removes. Decide whether to carry it forward to 9.2.",
    "evidence" : "not present in IBM's shipped 7.6.1.3 dictionary",
    "owner" : "Database / migration",
    "requiredAction" : "Decide whether to carry it forward. It is your own field, not part of IBM's dictionary at either release, so its absence at the target is not release evidence — re-applying it is a database change, not a code change.",
    "closureTest" : "Either the attribute exists on the target with the type, length and required flag your code expects, or every cited site has been changed to stop using it. One or the other, recorded.",
    "sites" : [ ],
    "disposition" : {
      "proposed" : "RETAIN",
      "rationale" : "Your own column or object: in your export, not in IBM's dictionary at either release. An in-place upgrade carries it forward; confirm it on the upgraded system."
    }
  }, {
    "grade" : "ENVIRONMENT",
    "kind" : "local-extension",
    "confidence" : "B2",
    "reach" : "inventory",
    "object" : "LOCATIONS",
    "attribute" : "KEPLATFORM",
    "message" : "LOCATIONS.KEPLATFORM is not part of IBM's own 7.6.1.3 dictionary either — it is your own field, not something the release removes. Decide whether to carry it forward to 9.2.",
    "evidence" : "not present in IBM's shipped 7.6.1.3 dictionary",
    "owner" : "Database / migration",
    "requiredAction" : "Decide whether to carry it forward. It is your own field, not part of IBM's dictionary at either release, so its absence at the target is not release evidence — re-applying it is a database change, not a code change.",
    "closureTest" : "Either the attribute exists on the target with the type, length and required flag your code expects, or every cited site has been changed to stop using it. One or the other, recorded.",
    "sites" : [ ],
    "disposition" : {
      "proposed" : "RETAIN",
      "rationale" : "Your own column or object: in your export, not in IBM's dictionary at either release. An in-place upgrade carries it forward; confirm it on the upgraded system."
    }
  }, {
    "grade" : "ENVIRONMENT",
    "kind" : "local-extension",
    "confidence" : "B2",
    "reach" : "cited",
    "object" : "WORKORDER",
    "attribute" : "KEFLARINGHOURS",
    "message" : "WORKORDER.KEFLARINGHOURS is not part of IBM's own 7.6.1.3 dictionary either — it is your own field, not something the release removes. Decide whether to carry it forward to 9.2. Your code reads or writes it.",
    "evidence" : "not present in IBM's shipped 7.6.1.3 dictionary",
    "owner" : "Database / migration",
    "requiredAction" : "Decide whether to carry it forward. It is your own field, not part of IBM's dictionary at either release, so its absence at the target is not release evidence — re-applying it is a database change, not a code change.",
    "closureTest" : "Either the attribute exists on the target with the type, length and required flag your code expects, or every cited site has been changed to stop using it. One or the other, recorded.",
    "sites" : [ "examples/customer-upgrade/src/screens/wotrack.xml:15" ],
    "disposition" : {
      "proposed" : "RETAIN",
      "rationale" : "Your own column or object: in your export, not in IBM's dictionary at either release. An in-place upgrade carries it forward; confirm it on the upgraded system."
    }
  }, {
    "grade" : "ENVIRONMENT",
    "kind" : "local-extension",
    "confidence" : "B2",
    "reach" : "cited",
    "object" : "WORKORDER",
    "attribute" : "KEPERMITSTATUS",
    "message" : "WORKORDER.KEPERMITSTATUS is not part of IBM's own 7.6.1.3 dictionary either — it is your own field, not something the release removes. Decide whether to carry it forward to 9.2. Your code reads or writes it.",
    "evidence" : "not present in IBM's shipped 7.6.1.3 dictionary",
    "owner" : "Database / migration",
    "requiredAction" : "Decide whether to carry it forward. It is your own field, not part of IBM's dictionary at either release, so its absence at the target is not release evidence — re-applying it is a database change, not a code change.",
    "closureTest" : "Either the attribute exists on the target with the type, length and required flag your code expects, or every cited site has been changed to stop using it. One or the other, recorded.",
    "sites" : [ "examples/customer-upgrade/src/screens/wotrack.xml:14" ],
    "disposition" : {
      "proposed" : "RETAIN",
      "rationale" : "Your own column or object: in your export, not in IBM's dictionary at either release. An in-place upgrade carries it forward; confirm it on the upgraded system."
    }
  }, {
    "grade" : "ENVIRONMENT",
    "kind" : "local-extension",
    "confidence" : "B2",
    "reach" : "cited",
    "object" : "WORKORDER",
    "attribute" : "KESHUTDOWNREF",
    "message" : "WORKORDER.KESHUTDOWNREF is not part of IBM's own 7.6.1.3 dictionary either — it is your own field, not something the release removes. Decide whether to carry it forward to 9.2. Your code reads or writes it.",
    "evidence" : "not present in IBM's shipped 7.6.1.3 dictionary",
    "owner" : "Database / migration",
    "requiredAction" : "Decide whether to carry it forward. It is your own field, not part of IBM's dictionary at either release, so its absence at the target is not release evidence — re-applying it is a database change, not a code change.",
    "closureTest" : "Either the attribute exists on the target with the type, length and required flag your code expects, or every cited site has been changed to stop using it. One or the other, recorded.",
    "sites" : [ "examples/customer-upgrade/src/screens/wotrack.xml:13" ],
    "disposition" : {
      "proposed" : "RETAIN",
      "rationale" : "Your own column or object: in your export, not in IBM's dictionary at either release. An in-place upgrade carries it forward; confirm it on the upgraded system."
    }
  }, {
    "grade" : "ENVIRONMENT",
    "kind" : "local-extension",
    "confidence" : "B2",
    "reach" : "cited",
    "object" : "WORKORDER",
    "attribute" : "KEWELLID",
    "message" : "WORKORDER.KEWELLID is not part of IBM's own 7.6.1.3 dictionary either — it is your own field, not something the release removes. Decide whether to carry it forward to 9.2. Your code reads or writes it.",
    "evidence" : "not present in IBM's shipped 7.6.1.3 dictionary",
    "owner" : "Database / migration",
    "requiredAction" : "Decide whether to carry it forward. It is your own field, not part of IBM's dictionary at either release, so its absence at the target is not release evidence — re-applying it is a database change, not a code change.",
    "closureTest" : "Either the attribute exists on the target with the type, length and required flag your code expects, or every cited site has been changed to stop using it. One or the other, recorded.",
    "sites" : [ "examples/customer-upgrade/src/screens/wotrack.xml:12" ],
    "disposition" : {
      "proposed" : "RETAIN",
      "rationale" : "Your own column or object: in your export, not in IBM's dictionary at either release. An in-place upgrade carries it forward; confirm it on the upgraded system."
    }
  }, {
    "grade" : "REVIEW",
    "kind" : "type-changed",
    "confidence" : "B2",
    "reach" : "referenced",
    "object" : "ASSET",
    "attribute" : "ASSETHEALTH",
    "message" : "ASSET.ASSETHEALTH type INTEGER → DECIMAL. Check stored values and consumers for case, rounding and conversion effects. A type difference alone does not establish a failure. No line of the supplied code reads or writes it, so nothing you own is known to break; anything outside the supplied code that carries it — an integration, a report — is what to check. The same column carries this change on 2 tables: ASSET, LOCATIONS.",
    "evidence" : "dictionary 7.6.1.3 vs 9.2",
    "owner" : "Customisation developer",
    "requiredAction" : "Validate existing values and every cited consumer against the new type, including case, rounding, range and truth semantics. A metadata difference alone does not establish a failing operation.",
    "closureTest" : "Each cited site has been read against the new type and either changed or recorded as unaffected, with the reason.",
    "sites" : [ ],
    "disposition" : {
      "proposed" : "INVESTIGATE",
      "rationale" : "The column still exists with a different definition. Whether a cited site cares is a judgement about the code, not a fact in the dictionary."
    }
  }, {
    "grade" : "REVIEW",
    "kind" : "scale-changed",
    "confidence" : "B2",
    "reach" : "referenced",
    "object" : "ASSET",
    "attribute" : "ASSETHEALTH",
    "message" : "ASSET.ASSETHEALTH scale 0 → 2 The same column carries this change on 2 tables: ASSET, LOCATIONS.",
    "evidence" : "dictionary 7.6.1.3 vs 9.2",
    "owner" : "Customisation developer",
    "requiredAction" : "Check arithmetic and rounding at every cited site, and any total that has to reconcile.",
    "closureTest" : "A worked example at the new scale reconciles against the same example at the old one, or the difference is accepted and recorded.",
    "sites" : [ ],
    "disposition" : {
      "proposed" : "INVESTIGATE",
      "rationale" : "The column still exists with a different definition. Whether a cited site cares is a judgement about the code, not a fact in the dictionary."
    }
  }, {
    "grade" : "REVIEW",
    "kind" : "type-changed",
    "confidence" : "B1",
    "reach" : "referenced",
    "object" : "ASSET",
    "attribute" : "GEOMETRY",
    "message" : "ASSET.GEOMETRY type BLOB → CLOB. Check stored values and consumers for case, rounding and conversion effects. A type difference alone does not establish a failure. No line of the supplied code reads or writes it, so nothing you own is known to break; anything outside the supplied code that carries it — an integration, a report — is what to check. The same column carries this change on 3 tables: ASSET, LOCATIONS, WORKORDER.",
    "evidence" : "dictionary 7.6.1.3 vs 9.2, corroborated by IBM's upgrade script, 9.0",
    "owner" : "Customisation developer",
    "requiredAction" : "Validate existing values and every cited consumer against the new type, including case, rounding, range and truth semantics. A metadata difference alone does not establish a failing operation.",
    "closureTest" : "Each cited site has been read against the new type and either changed or recorded as unaffected, with the reason.",
    "sites" : [ ],
    "disposition" : {
      "proposed" : "INVESTIGATE",
      "rationale" : "The column still exists with a different definition. Whether a cited site cares is a judgement about the code, not a fact in the dictionary."
    }
  }, {
    "grade" : "REVIEW",
    "kind" : "persistence-changed",
    "confidence" : "B1",
    "reach" : "referenced",
    "object" : "ASSET",
    "attribute" : "GEOMETRY",
    "message" : "ASSET.GEOMETRY persistent true → false The same column carries this change on 3 tables: ASSET, LOCATIONS, WORKORDER.",
    "evidence" : "dictionary 7.6.1.3 vs 9.2, corroborated by IBM's upgrade script, 9.0",
    "owner" : "Customisation developer",
    "requiredAction" : "A non-persistent attribute is not in the table. Anything that queries, indexes, reports on or joins to it stops working, even though reading it through the MBO still does.",
    "closureTest" : "No SQL, report or integration references the attribute as a column on the target.",
    "sites" : [ ],
    "disposition" : {
      "proposed" : "INVESTIGATE",
      "rationale" : "The column still exists with a different definition. Whether a cited site cares is a judgement about the code, not a fact in the dictionary."
    }
  }, {
    "grade" : "REVIEW",
    "kind" : "persistence-changed",
    "confidence" : "B2",
    "reach" : "referenced",
    "object" : "ASSET",
    "attribute" : "METHODNAME",
    "message" : "ASSET.METHODNAME persistent false → true The same column carries this change on 2 tables: ASSET, LOCATIONS.",
    "evidence" : "dictionary 7.6.1.3 vs 9.2",
    "owner" : "Customisation developer",
    "requiredAction" : "A non-persistent attribute is not in the table. Anything that queries, indexes, reports on or joins to it stops working, even though reading it through the MBO still does.",
    "closureTest" : "No SQL, report or integration references the attribute as a column on the target.",
    "sites" : [ ],
    "disposition" : {
      "proposed" : "INVESTIGATE",
      "rationale" : "The column still exists with a different definition. Whether a cited site cares is a judgement about the code, not a fact in the dictionary."
    }
  }, {
    "grade" : "REVIEW",
    "kind" : "type-changed",
    "confidence" : "B2",
    "reach" : "inventory",
    "object" : "LOCATIONS",
    "attribute" : "HEALTH",
    "message" : "LOCATIONS.HEALTH type INTEGER → DECIMAL. Check stored values and consumers for case, rounding and conversion effects. A type difference alone does not establish a failure. No line of the supplied code reads or writes it, so nothing you own is known to break; anything outside the supplied code that carries it — an integration, a report — is what to check.",
    "evidence" : "dictionary 7.6.1.3 vs 9.2",
    "owner" : "Customisation developer",
    "requiredAction" : "Validate existing values and every cited consumer against the new type, including case, rounding, range and truth semantics. A metadata difference alone does not establish a failing operation.",
    "closureTest" : "Each cited site has been read against the new type and either changed or recorded as unaffected, with the reason.",
    "sites" : [ ],
    "disposition" : {
      "proposed" : "INVESTIGATE",
      "rationale" : "The column still exists with a different definition. Whether a cited site cares is a judgement about the code, not a fact in the dictionary."
    }
  }, {
    "grade" : "REVIEW",
    "kind" : "scale-changed",
    "confidence" : "B2",
    "reach" : "inventory",
    "object" : "LOCATIONS",
    "attribute" : "HEALTH",
    "message" : "LOCATIONS.HEALTH scale 0 → 2",
    "evidence" : "dictionary 7.6.1.3 vs 9.2",
    "owner" : "Customisation developer",
    "requiredAction" : "Check arithmetic and rounding at every cited site, and any total that has to reconcile.",
    "closureTest" : "A worked example at the new scale reconciles against the same example at the old one, or the difference is accepted and recorded.",
    "sites" : [ ],
    "disposition" : {
      "proposed" : "INVESTIGATE",
      "rationale" : "The column still exists with a different definition. Whether a cited site cares is a judgement about the code, not a fact in the dictionary."
    }
  } ],
  "notAssessed" : [ "14 attribute reference(s) in the supplied code could not be tied to an object, so they were NOT checked: the file names no object (no launch point for the script, no `mboname`/`objectName`, no `mxh:object=` comment). Supply the SCRIPTLAUNCHPOINT export so each script's object is known, or add a `# mxh:object=<OBJECT>` line to the file. First sites: examples/customer-upgrade/src/java/com/kestrel/maximo/PermitGate.java:23, examples/customer-upgrade/src/java/com/kestrel/maximo/PermitGate.java:24, examples/customer-upgrade/src/java/com/kestrel/maximo/PermitGate.java:33, examples/customer-upgrade/src/java/com/kestrel/maximo/PermitGate.java:41, examples/customer-upgrade/src/scripts/KESHUTDOWN.py:8, examples/customer-upgrade/src/scripts/KESHUTDOWN.py:9, examples/customer-upgrade/src/scripts/KESHUTDOWN.py:10, examples/customer-upgrade/src/scripts/KESHUTDOWN.py:12.", "1 screen field(s) run through a relationship path that was followed using the 9.2 relationship graph mxh ships, because your own MAXRELATIONSHIP export does not define the hop. Their attributes were checked against the 9.2 dictionary the same way every other field was, but which object each one lands on is IBM's out-of-the-box answer rather than yours — Application Designer lets a relationship be redefined, and a redefined hop lands somewhere else. Findings from those paths carry evidence class B2 and are graded for review; a clean result on them is weaker than a clean result on a path your own rows answered. `mxh import-dd` against your full MAXRELATIONSHIP extract settles it.", "1 screen field(s) run through a relationship this run could not follow, so they were not checked: WORKORDER.KEWELLHEAD. Neither your own MAXRELATIONSHIP export nor the 9.2 relationship graph mxh ships defines a relationship of that name on that object. An export scoped to some objects does not carry every relationship, so this is missing evidence rather than a broken screen — it is not reported as a finding.", "No automation-script launch points were supplied, so what fires each script was not checked — only what the script does. A script whose code has not changed still breaks when the column its launch point binds to is gone at the target, and no code scan can see that. Export `SCRIPTLAUNCHPOINT` and `LAUNCHPOINTVARS` and point the manifest's `launch-points` surface at them.", "No configuration export was supplied, so your own escalations, cron task instances, actions, workflow conditions, communication templates, domain values and property values were NOT checked. An escalation whose condition names a column the target dropped does not fail at import; it fails on its first run, in a log. Export `ESCALATION`, `ESCREFPOINT`, `CRONTASKDEF`, `CRONTASKINSTANCE`, `ACTION`, `WFPROCESS`, `WFCONDITION`, `COMMTEMPLATE`, `MAXDOMAIN`, `SYNONYMDOMAIN`, `ALNDOMAIN` and `MAXPROP` as JSON and point the manifest's `configuration` surface at them.", "No security export was supplied, so **who** each finding above affects was not assessed — only what it breaks. Security-group grants and restrictions are a customer's own rather than IBM's, so nothing shipped can answer it: a restriction pointing at a column the target dropped stops applying silently, and rows it was hiding become visible with nothing in any log to say so. Export `MAXGROUP`, `APPLICATIONAUTH`, `SECURITYRESTRICT` and group membership **as counts** (`SELECT groupname, COUNT(*) ... GROUP BY groupname` over active users — never user ids) and point the manifest's `security` surface at them.", "Shipped configuration is compared — action, application, commtemplate, crontask, doctype, endpoint, escalation, intobject, kpi, property, report, restriction, securitygroup, sigoption, workflow — and a difference becomes a finding where the supplied code names it. Configuration reached only from the database (an escalation whose action row points at a class, a report the code never names) is not seen by a code scan, and neither are security-group grants or menu placement, which are a customer's own rather than IBM's. Those come in from the customer's own configuration export, the same way `--export` brings their dictionary in.", "`object-structures` was declared not supplied by Kestrel Energy — the integration framework was not exported for this engagement, so no object-structure schemas were available to check. `mxh assess` now reads them when supplied: point the manifest's object-structures surface at a directory of the customer's own exported OSLC `/oslc/jsonschemas/<os>` responses (or an OpenAPI document) and every field one publishes outside the code-scanned objects is compared against the target dictionary the same way a plain attribute is.", "`launch-points` was declared not supplied by Kestrel Energy — the automation scripts were exported as source only, so SCRIPTLAUNCHPOINT and LAUNCHPOINTVARS were not taken and what fires each script was not checked — only what it does. `mxh assess` now reads them when supplied: point the manifest's launch-points surface at the customer's own export of those two tables and every object and column a trigger binds to, plus every variable bound to a bare attribute, is compared against the target dictionary the same way a plain attribute is.", "`java-inventory` was declared not supplied by Kestrel Energy — no JAR inventory was taken for this engagement, so only the Java under src/java is scanned for psdi references. `mxh assess` now reads compiled JARs too when supplied: point the manifest's java-jars surface at the customisation's lib directory (or a WAR's WEB-INF/lib) and every class file's constant pool is checked for removed psdi signatures the same way source is — no execution, no classloading.", "Dictionary differences that need no work, so not raised: 2 where IBM's own 7.6.1.3 definition already matches 9.2 (the difference is your customisation, and an in-place upgrade carries it), 54 where 9.2 only relaxes the column (longer, or a type that accepts more), so every existing value and consumer still fits, and 0 fields of yours that 9.2 defines identically.", "5 of your own columns bound on your screens are already listed as local extensions; the upgrade carries the column and the binding, so the screens raise nothing further for them.", "1 control property set on your screens is defined by neither the 7.6.1.1 nor the 9.2 release, so the screens ignore them today and will on 9.2. Not raised as findings.", "8 IBM objects and columns removed on the path to 9.2 are used by nothing you supplied, so the upgrade drops them with no work on your side; if you keep rows in any of them, export those rows before cutover: FAILUREREPORT.EXCEPTIONDATE, FAILUREREPORT.EXCEPTIONREASON, FAILUREREPORT.EXCEPTIONREFERENCE, FAILUREREPORT.IMMEDIATEACTION, FAILUREREPORT.QUALITYIMPACT, FAILUREREPORT.READYTOUSEAFTERCORRECTION, FAILUREREPORT.USEDAFTEROVERDUE, LOCATIONS.PLUSSGEOJSON." ],
  "route" : {
    "from" : {
      "release" : "7.6.1.3",
      "dictionary" : "your export at examples/customer-upgrade/export (4 objects)",
      "stock" : "mxh's shipped evidence at 7.6.1.3",
      "solutionsApplied" : [ "oilandgas" ],
      "scopeSignals" : "No product marker was established from the supplied surfaces."
    },
    "to" : {
      "release" : "9.2",
      "dictionary" : "mxh's shipped 9.2 dictionary (1866 objects)",
      "packVersion" : "2026.09",
      "signed" : true,
      "identity" : "tUhAdETgAGVf3pHW2pD3BQwY7y0k6K/q1koc429yr1nD5ha+mKxkPSub3b/9xJIIZwBsn2xQi+N5hqAhH8HOAw=="
    },
    "evidenceChain" : [ {
      "release" : "7.6.7.1",
      "evidence" : "IBM upgrade scripts (7 object(s) touched)",
      "dictionary" : false
    }, {
      "release" : "7.6.7.2",
      "evidence" : "IBM upgrade scripts (11 object(s) touched)",
      "dictionary" : false
    }, {
      "release" : "7.6.7.3",
      "evidence" : "IBM upgrade scripts (25 object(s) touched)",
      "dictionary" : false
    }, {
      "release" : "7.6.8",
      "evidence" : "IBM upgrade scripts (33 object(s) touched)",
      "dictionary" : false
    }, {
      "release" : "7.6.8.1",
      "evidence" : "IBM upgrade scripts (3 object(s) touched)",
      "dictionary" : false
    }, {
      "release" : "7.6.8.2",
      "evidence" : "IBM upgrade scripts (18 object(s) touched)",
      "dictionary" : false
    }, {
      "release" : "8.5",
      "evidence" : "IBM upgrade scripts (69 object(s) touched)",
      "dictionary" : false
    }, {
      "release" : "8.6",
      "evidence" : "IBM upgrade scripts (13 object(s) touched)",
      "dictionary" : false
    }, {
      "release" : "8.7",
      "evidence" : "IBM upgrade scripts (38 object(s) touched)",
      "dictionary" : false
    }, {
      "release" : "8.9",
      "evidence" : "IBM upgrade scripts (34 object(s) touched)",
      "dictionary" : false
    }, {
      "release" : "9.0",
      "evidence" : "IBM upgrade scripts (107 object(s) touched)",
      "dictionary" : true
    }, {
      "release" : "9.1",
      "evidence" : "IBM upgrade scripts (128 object(s) touched)",
      "dictionary" : true
    }, {
      "release" : "9.2",
      "evidence" : "IBM upgrade scripts (147 object(s) touched)",
      "dictionary" : true
    } ],
    "preconditions" : [ {
      "item" : "Source release 7.6.1.3",
      "status" : "7.6.1.3 is one of the three classic levels the Manage upgrade accepts (7.6.0.10, 7.6.1.2, 7.6.1.3). The system's own level is not in the package.",
      "next" : "Export MAXVARS (varname, varvalue) into the configuration directory; MAXUPG is then checked against the declared release here.",
      "evidence" : "none supplied: configuration/maxvars.json"
    }, {
      "item" : "Integrity Checker on the source database",
      "status" : "Run IBM's Integrity Checker on the source database before cutover; its log is not in the package.",
      "next" : "Supply the checker's log as configuration/integrity-checker.log; its error and warning lines are then counted here.",
      "evidence" : "none supplied: configuration/integrity-checker.log"
    }, {
      "item" : "Customisation deployment",
      "status" : "Supply the deployed customisation JAR (or its lib directory) as java-jars; every class the findings cite is then checked for presence in what is deployed.",
      "next" : "Take businessobjects customisations from the deployed lib directory, not from a developer's build, so the check is against what runs.",
      "evidence" : "none supplied: java-jars"
    }, {
      "item" : "Platform, database and licensing",
      "status" : "Confirm the target's OpenShift, database and AppPoint prerequisites with the platform team. No table a Maximo export carries states them, so the package cannot.",
      "next" : "Record the confirmation in the work package that carries cutover; nothing in this assessment moves with it.",
      "evidence" : "not an export: no artefact establishes it"
    }, {
      "item" : "Industry solutions at the target",
      "status" : "oilandgas applied to both sides of the comparison; the source's installed products are not in the package. No product marker was established from the supplied surfaces.",
      "next" : "Read applications/maximo/properties/product/*.xml on the source server into configuration/products.json; the installed add-ons and their levels are then compared with what the manifest declares.",
      "evidence" : "none supplied: configuration/products.json"
    } ]
  },
  "decisions" : {
    "proposed" : {
      "CHANGE" : 0,
      "INVESTIGATE" : 9,
      "REPLACE" : 4,
      "RETAIN" : 9,
      "RETIRE" : 0
    },
    "reviewed" : {
      "CHANGE" : 0,
      "INVESTIGATE" : 0,
      "REPLACE" : 0,
      "RETAIN" : 0,
      "RETIRE" : 0
    },
    "decided" : 0,
    "agreeingWithProposal" : 0,
    "differingFromProposal" : 0,
    "undecided" : 22,
    "unmatched" : [ ]
  },
  "workPackages" : [ {
    "id" : "WP-ee4980cc",
    "owner" : "Customisation developer",
    "subject" : "Class removed",
    "firstAction" : "Replace the reference. The type does not exist at the target, so the customisation will not compile; find the supported equivalent or remove the dependency.",
    "blocking" : 1,
    "review" : 0,
    "environment" : 0,
    "decided" : 0,
    "findings" : [ "class-removed|psdi.iface.jms.ErrorQueueNotfCronTask|" ],
    "acceptance" : [ "The customisation compiles against the target's `businessobjects.jar` with no unresolved import." ],
    "proposed" : {
      "REPLACE" : 1
    }
  }, {
    "id" : "WP-cf44bbb5",
    "owner" : "Customisation developer",
    "subject" : "Validate changed datatypes against actual usage",
    "firstAction" : "Validate existing values and every cited consumer against the new type, including case, rounding, range and truth semantics. A metadata difference alone does not establish a failing operation.",
    "blocking" : 0,
    "review" : 3,
    "environment" : 0,
    "decided" : 0,
    "findings" : [ "type-changed|ASSET|ASSETHEALTH", "type-changed|ASSET|GEOMETRY", "type-changed|LOCATIONS|HEALTH" ],
    "acceptance" : [ "Each cited site has been read against the new type and either changed or recorded as unaffected, with the reason." ],
    "proposed" : {
      "INVESTIGATE" : 3
    }
  }, {
    "id" : "WP-395a9c9b",
    "owner" : "Customisation developer",
    "subject" : "Method removed",
    "firstAction" : "Check each cited site. The class survives but this member does not, so a call compiles today and fails at the target.",
    "blocking" : 0,
    "review" : 3,
    "environment" : 0,
    "decided" : 0,
    "findings" : [ "method-removed|psdi.app.person.Person|getAvailableHours(Ljava/util/Date;Lpsdi/app/person/PersonCalRemote;Lpsdi/app/common/AvailCalc;)D", "method-removed|psdi.app.person.Person|getAvailableMbo(Ljava/util/Date;Lpsdi/app/person/PersonCalRemote;Lpsdi/app/common/AvailCalc;)Lpsdi/mbo/MboRemote;", "method-removed|psdi.app.person.Person|getAvailableMboList(Ljava/util/Date;Lpsdi/app/person/PersonCalRemote;Lpsdi/app/common/AvailCalc;)Ljava/util/List;" ],
    "acceptance" : [ "The customisation compiles against the target's `businessobjects.jar`, and the cited lines either no longer call the member or call its replacement." ],
    "proposed" : {
      "REPLACE" : 3
    }
  }, {
    "id" : "WP-232873dd",
    "owner" : "Customisation developer",
    "subject" : "Attribute removed",
    "firstAction" : "Change every cited site before cutover. The column is gone at the target: a read throws and a write fails.",
    "blocking" : 0,
    "review" : 2,
    "environment" : 0,
    "decided" : 0,
    "findings" : [ "attribute-removed|ASSET|PLUSSGEOJSON", "attribute-removed|WORKORDER|PLUSSGEOJSON" ],
    "acceptance" : [ "`select 1 from maxattribute where objectname = <object> and attributename = <attribute>` on the target returns no row, and no cited site references it." ],
    "proposed" : {
      "INVESTIGATE" : 2
    }
  }, {
    "id" : "WP-15e67888",
    "owner" : "Customisation developer",
    "subject" : "Persistence changed",
    "firstAction" : "A non-persistent attribute is not in the table. Anything that queries, indexes, reports on or joins to it stops working, even though reading it through the MBO still does.",
    "blocking" : 0,
    "review" : 2,
    "environment" : 0,
    "decided" : 0,
    "findings" : [ "persistence-changed|ASSET|GEOMETRY", "persistence-changed|ASSET|METHODNAME" ],
    "acceptance" : [ "No SQL, report or integration references the attribute as a column on the target." ],
    "proposed" : {
      "INVESTIGATE" : 2
    }
  }, {
    "id" : "WP-1683a233",
    "owner" : "Customisation developer",
    "subject" : "Scale changed",
    "firstAction" : "Check arithmetic and rounding at every cited site, and any total that has to reconcile.",
    "blocking" : 0,
    "review" : 2,
    "environment" : 0,
    "decided" : 0,
    "findings" : [ "scale-changed|ASSET|ASSETHEALTH", "scale-changed|LOCATIONS|HEALTH" ],
    "acceptance" : [ "A worked example at the new scale reconciles against the same example at the old one, or the difference is accepted and recorded." ],
    "proposed" : {
      "INVESTIGATE" : 2
    }
  }, {
    "id" : "WP-253434f3",
    "owner" : "Application Designer / configuration",
    "subject" : "Screen field local extension",
    "firstAction" : "Confirm the column on the upgraded system, then leave the screen alone. The field is your own column, which an in-place upgrade carries forward; the stock target dictionary not listing it is expected, not a broken binding. If the column is not there after the upgrade, re-apply it — a database change — before the screen is opened.",
    "blocking" : 0,
    "review" : 1,
    "environment" : 0,
    "decided" : 0,
    "findings" : [ "screen-field-local-extension|ASSET|KEINSPECTIONCLASS" ],
    "acceptance" : [ "`select 1 from maxattribute where objectname = <object> and attributename = <attribute>` on the upgraded system returns a row, and the screen renders with the field populated." ],
    "proposed" : {
      "RETAIN" : 1
    }
  }, {
    "id" : "WP-1af3c60d",
    "owner" : "Database / migration",
    "subject" : "Local extension",
    "firstAction" : "Decide whether to carry it forward. It is your own field, not part of IBM's dictionary at either release, so its absence at the target is not release evidence — re-applying it is a database change, not a code change.",
    "blocking" : 0,
    "review" : 0,
    "environment" : 8,
    "decided" : 0,
    "findings" : [ "local-extension|ASSET|KECORROSIONLOOP", "local-extension|ASSET|KEINSPECTIONCLASS", "local-extension|FAILUREREPORT|KEROOTCAUSECODE", "local-extension|LOCATIONS|KEPLATFORM", "local-extension|WORKORDER|KEFLARINGHOURS", "local-extension|WORKORDER|KEPERMITSTATUS", "local-extension|WORKORDER|KESHUTDOWNREF", "local-extension|WORKORDER|KEWELLID" ],
    "acceptance" : [ "Either the attribute exists on the target with the type, length and required flag your code expects, or every cited site has been changed to stop using it. One or the other, recorded." ],
    "proposed" : {
      "RETAIN" : 8
    }
  } ],
  "dependencies" : [ {
    "object" : "ASSET",
    "findings" : 9,
    "dependents" : {
      "screens" : [ "examples/customer-upgrade/src/screens/wotrack.xml" ]
    }
  }, {
    "object" : "FAILUREREPORT",
    "findings" : 1,
    "dependents" : { }
  }, {
    "object" : "LOCATIONS",
    "findings" : 3,
    "dependents" : { }
  }, {
    "object" : "WORKORDER",
    "findings" : 5,
    "dependents" : {
      "screens" : [ "examples/customer-upgrade/src/screens/wotrack.xml" ]
    }
  } ],
  "readiness" : {
    "model" : "assessment.readiness@1",
    "runtimeAcceptance" : "pending",
    "counts" : {
      "BLOCKING" : 1,
      "VALIDATION" : 12,
      "ENVIRONMENT" : 8,
      "INFORMATIONAL" : 1
    },
    "rows" : [ {
      "findingIndex" : 0,
      "category" : "BLOCKING",
      "workPackage" : "WP-ee4980cc"
    }, {
      "findingIndex" : 1,
      "category" : "VALIDATION",
      "workPackage" : "WP-253434f3"
    }, {
      "findingIndex" : 2,
      "category" : "VALIDATION",
      "workPackage" : "WP-232873dd"
    }, {
      "findingIndex" : 3,
      "category" : "VALIDATION",
      "workPackage" : "WP-232873dd"
    }, {
      "findingIndex" : 4,
      "category" : "VALIDATION",
      "workPackage" : "WP-395a9c9b"
    }, {
      "findingIndex" : 5,
      "category" : "VALIDATION",
      "workPackage" : "WP-395a9c9b"
    }, {
      "findingIndex" : 6,
      "category" : "VALIDATION",
      "workPackage" : "WP-395a9c9b"
    }, {
      "findingIndex" : 7,
      "category" : "ENVIRONMENT",
      "workPackage" : "WP-1af3c60d"
    }, {
      "findingIndex" : 8,
      "category" : "ENVIRONMENT",
      "workPackage" : "WP-1af3c60d"
    }, {
      "findingIndex" : 9,
      "category" : "ENVIRONMENT",
      "workPackage" : "WP-1af3c60d"
    }, {
      "findingIndex" : 10,
      "category" : "ENVIRONMENT",
      "workPackage" : "WP-1af3c60d"
    }, {
      "findingIndex" : 11,
      "category" : "ENVIRONMENT",
      "workPackage" : "WP-1af3c60d"
    }, {
      "findingIndex" : 12,
      "category" : "ENVIRONMENT",
      "workPackage" : "WP-1af3c60d"
    }, {
      "findingIndex" : 13,
      "category" : "ENVIRONMENT",
      "workPackage" : "WP-1af3c60d"
    }, {
      "findingIndex" : 14,
      "category" : "ENVIRONMENT",
      "workPackage" : "WP-1af3c60d"
    }, {
      "findingIndex" : 15,
      "category" : "VALIDATION",
      "workPackage" : "WP-cf44bbb5"
    }, {
      "findingIndex" : 16,
      "category" : "VALIDATION",
      "workPackage" : "WP-1683a233"
    }, {
      "findingIndex" : 17,
      "category" : "VALIDATION",
      "workPackage" : "WP-cf44bbb5"
    }, {
      "findingIndex" : 18,
      "category" : "VALIDATION",
      "workPackage" : "WP-15e67888"
    }, {
      "findingIndex" : 19,
      "category" : "VALIDATION",
      "workPackage" : "WP-15e67888"
    }, {
      "findingIndex" : 20,
      "category" : "VALIDATION",
      "workPackage" : "WP-cf44bbb5"
    }, {
      "findingIndex" : 21,
      "category" : "INFORMATIONAL",
      "workPackage" : "WP-1683a233"
    } ],
    "families" : [ {
      "id" : "WP-ee4980cc",
      "family" : "class-removed",
      "title" : "Class removed",
      "category" : "BLOCKING",
      "owner" : "Customisation developer",
      "action" : "Replace the reference. The type does not exist at the target, so the customisation will not compile; find the supported equivalent or remove the dependency.",
      "closure" : "The customisation compiles against the target's `businessobjects.jar` with no unresolved import.",
      "findingIndexes" : [ 0 ],
      "subjects" : [ "psdi.iface.jms.ErrorQueueNotfCronTask" ],
      "findingCount" : 1
    }, {
      "id" : "WP-cf44bbb5",
      "family" : "data-types",
      "title" : "Validate changed datatypes against actual usage",
      "category" : "VALIDATION",
      "owner" : "Customisation developer",
      "action" : "Validate existing values and every cited consumer against the new type, including case, rounding, range and truth semantics. A metadata difference alone does not establish a failing operation.",
      "closure" : "Each cited site has been read against the new type and either changed or recorded as unaffected, with the reason.",
      "findingIndexes" : [ 15, 17, 20 ],
      "subjects" : [ "ASSET.ASSETHEALTH", "ASSET.GEOMETRY", "LOCATIONS.HEALTH" ],
      "findingCount" : 3
    }, {
      "id" : "WP-395a9c9b",
      "family" : "method-removed",
      "title" : "Method removed",
      "category" : "VALIDATION",
      "owner" : "Customisation developer",
      "action" : "Check each cited site. The class survives but this member does not, so a call compiles today and fails at the target.",
      "closure" : "The customisation compiles against the target's `businessobjects.jar`, and the cited lines either no longer call the member or call its replacement.",
      "findingIndexes" : [ 4, 5, 6 ],
      "subjects" : [ "psdi.app.person.Person.getAvailableHours(Ljava/util/Date;Lpsdi/app/person/PersonCalRemote;Lpsdi/app/common/AvailCalc;)D", "psdi.app.person.Person.getAvailableMbo(Ljava/util/Date;Lpsdi/app/person/PersonCalRemote;Lpsdi/app/common/AvailCalc;)Lpsdi/mbo/MboRemote;", "psdi.app.person.Person.getAvailableMboList(Ljava/util/Date;Lpsdi/app/person/PersonCalRemote;Lpsdi/app/common/AvailCalc;)Ljava/util/List;" ],
      "findingCount" : 3
    }, {
      "id" : "WP-232873dd",
      "family" : "attribute-removed",
      "title" : "Attribute removed",
      "category" : "VALIDATION",
      "owner" : "Customisation developer",
      "action" : "Change every cited site before cutover. The column is gone at the target: a read throws and a write fails.",
      "closure" : "`select 1 from maxattribute where objectname = <object> and attributename = <attribute>` on the target returns no row, and no cited site references it.",
      "findingIndexes" : [ 2, 3 ],
      "subjects" : [ "ASSET.PLUSSGEOJSON", "WORKORDER.PLUSSGEOJSON" ],
      "findingCount" : 2
    }, {
      "id" : "WP-15e67888",
      "family" : "persistence-changed",
      "title" : "Persistence changed",
      "category" : "VALIDATION",
      "owner" : "Customisation developer",
      "action" : "A non-persistent attribute is not in the table. Anything that queries, indexes, reports on or joins to it stops working, even though reading it through the MBO still does.",
      "closure" : "No SQL, report or integration references the attribute as a column on the target.",
      "findingIndexes" : [ 18, 19 ],
      "subjects" : [ "ASSET.GEOMETRY", "ASSET.METHODNAME" ],
      "findingCount" : 2
    }, {
      "id" : "WP-1683a233",
      "family" : "scale-changed",
      "title" : "Scale changed",
      "category" : "VALIDATION",
      "owner" : "Customisation developer",
      "action" : "Check arithmetic and rounding at every cited site, and any total that has to reconcile.",
      "closure" : "A worked example at the new scale reconciles against the same example at the old one, or the difference is accepted and recorded.",
      "findingIndexes" : [ 16, 21 ],
      "subjects" : [ "ASSET.ASSETHEALTH", "LOCATIONS.HEALTH" ],
      "findingCount" : 2
    }, {
      "id" : "WP-253434f3",
      "family" : "screen-field-local-extension",
      "title" : "Screen field local extension",
      "category" : "VALIDATION",
      "owner" : "Application Designer / configuration",
      "action" : "Confirm the column on the upgraded system, then leave the screen alone. The field is your own column, which an in-place upgrade carries forward; the stock target dictionary not listing it is expected, not a broken binding. If the column is not there after the upgrade, re-apply it — a database change — before the screen is opened.",
      "closure" : "`select 1 from maxattribute where objectname = <object> and attributename = <attribute>` on the upgraded system returns a row, and the screen renders with the field populated.",
      "findingIndexes" : [ 1 ],
      "subjects" : [ "ASSET.KEINSPECTIONCLASS" ],
      "findingCount" : 1
    }, {
      "id" : "WP-1af3c60d",
      "family" : "local-extension",
      "title" : "Local extension",
      "category" : "ENVIRONMENT",
      "owner" : "Database / migration",
      "action" : "Decide whether to carry it forward. It is your own field, not part of IBM's dictionary at either release, so its absence at the target is not release evidence — re-applying it is a database change, not a code change.",
      "closure" : "Either the attribute exists on the target with the type, length and required flag your code expects, or every cited site has been changed to stop using it. One or the other, recorded.",
      "findingIndexes" : [ 7, 8, 9, 10, 11, 12, 13, 14 ],
      "subjects" : [ "ASSET.KECORROSIONLOOP", "ASSET.KEINSPECTIONCLASS", "FAILUREREPORT.KEROOTCAUSECODE", "LOCATIONS.KEPLATFORM", "WORKORDER.KEFLARINGHOURS", "WORKORDER.KEPERMITSTATUS", "WORKORDER.KESHUTDOWNREF", "WORKORDER.KEWELLID" ],
      "findingCount" : 8
    } ],
    "findings" : 22,
    "workPackages" : 8,
    "blockingWorkPackages" : 1,
    "validationWorkPackages" : 6,
    "environmentWorkPackages" : 1,
    "informationalWorkPackages" : 0,
    "recommendation" : "Proceed with upgrade planning; resolve the named incompatible dependencies before retaining those functions at cutover."
  }
}
