Use Absl Log in g3 code rather than BMCWEB_LOG

In g3, we mainly rely on absl logs, keeping the same convention

Also a lot of these logs should not be logged ALWAYS.

PiperOrigin-RevId: 781729044
Change-Id: Iedc087534599c10eae1a236556688a23cd8c4b96
diff --git a/g3/managed_store.cpp b/g3/managed_store.cpp
index b19b951..85f4dcf 100644
--- a/g3/managed_store.cpp
+++ b/g3/managed_store.cpp
@@ -583,7 +583,7 @@
             std::chrono::duration_cast<std::chrono::milliseconds>(
                 clockNow() - valueType->lastRefreshAt)
                 .count());
-        BMCWEB_LOG_ALWAYS << "MAX AGE AT THIS POINT: " << age_in_ms;
+        LOG(INFO) << "MAX AGE AT THIS POINT: " << age_in_ms;
         std::move(callback)(valueType->errorCode,
                             valueType->managedProperty.value(), age_in_ms);
       });
@@ -628,7 +628,7 @@
     const std::string& match_expression,
     ecclesia::EventSourceId event_source_id) {
   if (match_expression.empty()) {
-    BMCWEB_LOG_ALWAYS
+    LOG(WARNING)
         << "D-Bus match expression is empty. Invalid call to subscribe!";
     return;
   }
@@ -636,7 +636,7 @@
   if (requestContext.eventSourceIds == nullptr ||
       requestContext.request_type ==
           ManagedObjectStoreContext::RequestType::kQuery) {
-    BMCWEB_LOG_ALWAYS << "eventSourceIds is null. Invalid call to subscribe!";
+    LOG(WARNING) << "eventSourceIds is null. Invalid call to subscribe!";
     return;
   }
 
@@ -649,12 +649,12 @@
           ManagedObjectStoreContext::RequestType::kCancelSubscription) {
         // Erase the monitor
         signal_monitors_.erase(find_monitor);
-        BMCWEB_LOG_ALWAYS << "Erased D-Bus monitor for id: "
+        LOG(WARNING) << "Erased D-Bus monitor for id: "
                           << event_source_id.ToString();
         return;
       }
 
-      BMCWEB_LOG_ALWAYS << "D-Bus monitor already created for id: "
+      LOG(WARNING) << "D-Bus monitor already created for id: "
                         << event_source_id.ToString();
 
       // Record monitor id regardless of an existing subscription since
@@ -671,23 +671,23 @@
         sdbusplus::bus::match_t>(
         *system_bus_, match_expression,
         [event_source_id, this](sdbusplus::message_t&) {
-          BMCWEB_LOG_ALWAYS
+          LOG(INFO)
               << "Received dbus signal. Notifying Subscription service now!";
           auto status =
               subscription_service_->Notify(event_source_id, absl::OkStatus());
           if (status.ok()) {
-            BMCWEB_LOG_ALWAYS << "Notified successfully!";
+            LOG(INFO) << "Notified successfully!";
             return;
           }
-          BMCWEB_LOG_ALWAYS << "Error while sending notification: " << status;
+          LOG(WARNING) << "Error while sending notification: " << status;
           if (status.code() == absl::StatusCode::kNotFound) {
             absl::MutexLock lock(&signal_monitor_mutex_);
             signal_monitors_.erase(event_source_id);
-            BMCWEB_LOG_ALWAYS << "Erased D-Bus monitor for id: "
+            LOG(INFO) << "Erased D-Bus monitor for id: "
                               << event_source_id.ToString();
           }
         });
-    BMCWEB_LOG_ALWAYS << "D-Bus monitor created. Event Source id: "
+    LOG(INFO) << "D-Bus monitor created. Event Source id: "
                       << event_source_id.ToString();
   });
 
@@ -1025,7 +1025,7 @@
       cached_object->lastUsedAges->pop_front();
     }
 
-    BMCWEB_LOG_ALWAYS << "Object found in store. " << " Key: " << key_id
+    LOG(INFO) << "Object found in store. " << " Key: " << key_id
                       << " CurrentAge: "
                       << clockDurationMilliseconds(current_age)
                       << " Context: " << requestContext.toString()
@@ -1042,7 +1042,7 @@
 
     // Evict the object from store as it has become stale.
     if (is_object_stale) {
-      BMCWEB_LOG_ALWAYS << "Object has become stale! "
+      LOG(INFO) << "Object has become stale! "
                         << " service: " << keyType.serviceName
                         << " path: " << keyType.objectPath.str
                         << " interface: " << keyType.interface << " property: "
diff --git a/tlbmc/g3doc/debug/sensor_debug_guide.md b/tlbmc/g3doc/debug/sensor_debug_guide.md
new file mode 100644
index 0000000..00f03c8
--- /dev/null
+++ b/tlbmc/g3doc/debug/sensor_debug_guide.md
@@ -0,0 +1,209 @@
+# Sensor Debug Guide
+
+go/tlbmc-sensor-debug
+
+<!--*
+# Document freshness: For more information, see go/fresh-source.
+freshness: { owner: 'tlbmc-dev' reviewed: '2025-07-08' }
+*-->
+
+By default, tlBMC store will fail to create when sensor creation fails. Note
+that with traditional dbus-sensors daemons, sensor creation failures are silent
+and will only result in the objects not being created. This results in partial
+data being reported and hides missing sensors in the redfish tree unless they
+are directly queried by a client. tlBMC's behavior allows for verification that
+all TlbmcOwned sensors declared in Entity Manager Config files are successfully
+created and served by tlBMC.
+
+You can verify that tlBMC has failed to initialize by querying the tlBMC root,
+which may result in the following output:
+
+```
+root@HOSTNAME:~# curl localhost/redfish/tlbmc
+{
+  "error": {
+    "@Message.ExtendedInfo": [
+      {
+        "@odata.type": "#Message.v1_1_1.Message",
+        "Message": "The requested resource of type  named 'tlbmc' was not found.",
+        "MessageArgs": [
+          "",
+          "tlbmc"
+        ],
+        "MessageId": "Base.1.13.0.ResourceNotFound",
+        "MessageSeverity": "Critical",
+        "Resolution": "Provide a valid resource identifier and resubmit the request."
+      }
+    ],
+    "code": "Base.1.13.0.ResourceNotFound",
+    "message": "The requested resource of type  named 'tlbmc' was not found."
+  }
+}
+```
+
+This output indicates that tlBMC is currently disabled and will result in a
+fallback to traditional bmcweb. Note that sensor readings may not be present in
+this case if `SkipDbusRead` is configured in EM config files per sensor. This
+guide will describe some common methods for how to debug which sensors fail to
+be created in this situation.
+
+[TOC]
+
+## Check tlBMC Store Creation Failure Logs
+
+To verify that tlBMC has failed during creation of a sensor, we can check the
+bmcweb logs. To check logs, use the following command and expect similar output:
+
+```
+root@HOSTNAME:~# journalctl -u bmcweb | grep -i tlbmc
+...
+Jul 06 09:09:54 {HOSTNAME} bmcweb[1955026]: E0706 09:09:54.072554 1955026 webserver_main_setup.hpp:232] Cannot create tlBMC store!! Error: INTERNAL: Failed to find hwmon under /sys/bus/i2c/devices/i2c-1/1-001a - Disabling tlBMC
+```
+
+This log indicates a failure to create a sensor object in tlBMC, likely due to a
+failure to initialize a sensor which may indicate a real hardware failure.
+
+To find additional information about the exact sensor that is failing, you can
+utilize the bus and address information derived from the log at
+`/sys/bus/i2c/devices/i2c-{BUS}/{BUS}-00{ADDRESS}`. By checking the EM config
+files associated with this platform, you can find the sensor configuration
+associated with the given bus/address. Verifying that the bus/address is correct
+for the intended sensor is an important first step for debug.
+
+## Verify hwmon File Presence and Value
+
+Checking that the expected hwmon file is present on the machine is necessary to
+verify that sensor readings are working as intended. To do so, use the following
+commands and you should expect to see similar output:
+
+```
+root@HOSTNAME:~# ls /sys/bus/i2c/devices/i2c-{BUS}/{BUS}-00{ADDRESS}
+driver     hwmon      modalias   name       of_node    pec        subsystem  uevent
+```
+
+Failure to find the hwmon directory shown above could indicate a larger issue,
+such as a real hardware failure (see below).
+
+If the hwmon directory is present, you can verify the intended value of the
+sensor by checking the following:
+
+```
+root@HOSTNAME:~# ls /sys/bus/i2c/devices/i2c-{BUS}/{BUS}-00{ADDRESS}/hwmon/hwmon{*}/
+curr1_crit         curr3_input        in1_label          in3_lcrit_alarm    power2_label       temp2_crit_alarm
+curr1_crit_alarm   curr3_label        in1_lcrit          in4_crit           power3_input       temp2_input
+curr1_input        curr3_max          in1_lcrit_alarm    in4_crit_alarm     power3_label       temp2_lcrit
+curr1_label        curr3_max_alarm    in1_max            in4_input          power4_input       temp2_lcrit_alarm
+curr1_max          curr4_crit         in1_max_alarm      in4_label          power4_label       temp2_max
+curr1_max_alarm    curr4_crit_alarm   in1_min            in4_lcrit          subsystem          temp2_max_alarm
+curr2_crit         curr4_input        in1_min_alarm      in4_lcrit_alarm    temp1_crit         temp3_crit
+curr2_crit_alarm   curr4_label        in2_input          name               temp1_crit_alarm   temp3_crit_alarm
+curr2_input        curr4_max          in2_label          of_node            temp1_input        temp3_input
+curr2_label        curr4_max_alarm    in3_crit           power1_alarm       temp1_lcrit        temp3_lcrit
+curr2_max          device             in3_crit_alarm     power1_input       temp1_lcrit_alarm  temp3_lcrit_alarm
+curr2_max_alarm    in1_crit           in3_input          power1_label       temp1_max          temp3_max
+curr3_crit         in1_crit_alarm     in3_label          power2_alarm       temp1_max_alarm    temp3_max_alarm
+curr3_crit_alarm   in1_input          in3_lcrit          power2_input       temp2_crit         uevent
+```
+
+To find the file that corresponds to the sensor you are interested in, you can
+`cat` the value of the `{sensor_type}{*}_label` files to find one that matches
+the label in the EM config. For instance, if the sensor name in the EM config is
+`vout1_Name`, the value `vout1` will be present in one of `in1_label`,
+`in2_label`, `in3_label`, or `in4_label`. The sensor reading will be in the
+corresponding `in{*}_input` file. Verify that this is a well-formed sensor
+reading value as expected.
+
+## Enable allow_sensor_creation_failure in tlBMC Configuration
+
+The method described above has the disadvantage of only being able to diagnose a
+single sensor at a time. tlBMC conveniently provides an option to configure
+bypassing sensor creation failures while still providing useful information for
+debugging. We provide a setting in the tlBMC central configuration to
+`allow_sensor_creation_failure`.
+
+This setting allows tlBMC store to be created regardless of sensor creation
+failures. Valid sensors will still be served by tlBMC and debug information can
+be obtained from tlBMC debug paths such as:
+
+```
+root@HOSTNAME:~# curl localhost/redfish/tlbmc/AllSensors
+{
+...
+"error": {
+    "@Message.ExtendedInfo": [
+      {
+        "@odata.type": "#Message.v1_1_1.Message",
+        "Message": "Sensor temperature_{SENSOR_NAME} is not ready in tlBMC Store: Failed to read from input device: No such device or address; input device path: /sys/bus/i2c/devices/i2c-{BUS}/{BUS}-00{ADDRESS}/hwmon/hwmon{*}/temp{*}_input",
+        "MessageId": "Base.1.13.0.InternalError"
+      },
+      {
+        "@odata.type": "#Message.v1_1_1.Message",
+        "Message": "Sensor voltage_{SENSOR_NAME} is not ready in tlBMC Store: Read data can't be converted to a number: Invalid argument",
+        "MessageId": "Base.1.13.0.InternalError"
+      },
+      ...
+    ],
+    "code": "Base.1.8.GeneralError",
+    "message": "A general error has occurred. See Resolution for information on how to resolve the error."
+  }
+}
+```
+
+All sensor creation errors encountered during tlBMC store creation are combined
+in the AllSensors response following the
+[Redfish error message spec](https://redfish.dmtf.org/schemas/DSP0266_1.19.0.html#error-responses).
+
+To enable the `allow_sensor_creation_failure` feature, a change must be made
+similar to:
+https://gbmc-private-review.git.corp.google.com/c/meta-google-private/+/35823.
+Add/modify the entry corresponding with the desired platform to include:
+
+```
+sensor_collector_module { enabled: true allow_sensor_creation_failure: true }
+```
+
+Build and flash a bmcweb binary including this change to have the central config
+take effect.
+
+## Verify Real Hardware Failures
+
+For additional information to diagnose sensor failures, it may be helpful to
+check logs using `dmesg`. Consider using the following command and look for logs
+similar to the following:
+
+```
+root@HOSTNAME:~# dmesg | grep "Failed to register"
+[   92.520183] i2c i2c-{BUS}: Failed to register i2c client {DRIVER} at 0x{ADDRESS} (-16)
+```
+
+This indicates a failure to set up the device which could indicate a real
+failure or the device could have been occupied by another script or service
+during boot.
+
+Potential *short term* solutions in this case could be to:
+
+-   Manually bind the device using:
+
+    ```
+    root@HOSTNAME:~# echo "{BUS}-00{ADDRESS}" >
+    /sys/bus/i2c/drivers/{DRIVER}/bind
+    ```
+
+    If the device was temporarily occupied during boot, this may correctly set
+    up the device.
+
+-   Powercycle the machine: rebooting has fixed sensor instantiation in some
+    cases
+
+    If either approach above is used, a bug should still be filed and the issue
+    should be reproduced. This flakiness in sensor creation could mask
+    underlying problems e.g. b/428930642.
+
+Note: In some cases, it may be expected to see some `Failed to register i2c
+client` logs, for instance in the case of having sensors configured in the EM
+config for second-source boards. These sensors may be expected to fail to create
+if the FRU on the machine does not correspond with the second-source FRU. Also
+note that expected dmesg error logs are only possible when these sensors are not
+supported by tlBMC. If tlBMC were to support the second source board sensors, a
+separate config would have to be made to logically separate these sensors and
+probe accordingly.
diff --git a/tlbmc/g3doc/general/redfish_resource_ownership_model.md b/tlbmc/g3doc/general/redfish_resource_ownership_model.md
new file mode 100644
index 0000000..eff23fe
--- /dev/null
+++ b/tlbmc/g3doc/general/redfish_resource_ownership_model.md
@@ -0,0 +1,364 @@
+# tlBMC Redfish Resource Ownership Model
+
+go/tlbmc-redfish-resource-ownership
+
+<!--*
+# Document freshness: For more information, see go/fresh-source.
+freshness: { owner: 'tlbmc-dev' reviewed: '2025-05-13' }
+*-->
+
+[TOC]
+
+Note: This is an evolving document and definitions may shift as the scope of
+tlBMC increases.
+
+tlBMC ownership of a redfish resource happens when a redfish URL is sent to the
+tlBMC app rather than the traditional gBMCweb app. As described in
+go/tlbmc-smart-routing, an incoming redfish query may be routed to traditional
+bmcweb or to the tlBMC app depending on if the resource is "owned" by tlBMC,
+this is called smart routing. In the case of tlBMC ownership, a query being sent
+to tlBMC means that tlBMC is providing the query response based on the internal
+representation of the requested object after tlBMC has parsed the EM config.
+There are no dbus calls being made or interactions with other daemons to return
+this response.
+
+There are three possible models for a redfish resource to be "owned" by tlBMC
+today. This document describes the extent to which tlBMC may have ownership over
+a resource.
+
+## Fully Owned
+
+### Chassis
+
+Chassis resources onboarded to tlBMC are detected and fully owned. In this case,
+FRUs are detected by tlBMC over I2C scan and the Redfish response is provided by
+the tlBMC backend. Every part of the Chassis response comes from tlBMC,
+including Fru info received from the eeprom of the device and links to
+associated Chassis, Cables, Processors, or Drives which are configured in the EM
+config.
+
+An example can be seen from this config:
+
+```json
+{
+  "Name": "foo",
+  "ProbeV2": {
+    "IpmiFru": {
+      "BOARD_PRODUCT_NAME": "Foo"
+    }
+  },
+  "ResourceType": "RESOURCE_TYPE_BOARD",
+  "Exposes":[
+    {
+      "Name": "Foo Downstream Port",
+      "Label": "PE0",
+      "Type": "PortDownstream"
+    },
+    {
+      "Type": "MAX31725",
+      "Bus": 1,
+      "Address": "0x4c",
+      "Name": "max31725_0",
+      "Name1": "max31725_1",
+      "TlbmcOwned":true
+    }
+  ],
+  "Asset": {
+    "Manufacturer": "$BOARD_MANUFACTURER",
+    "Model": "$BOARD_PRODUCT_NAME",
+    "PartNumber": "$BOARD_PART_NUMBER",
+    "SerialNumber": "$BOARD_SERIAL_NUMBER"
+  }
+}
+```
+
+The above config might produce the following redfish response, which contains
+fields fully populated by tlBMC, requiring no additional dbus calls or
+interactions with other daemons.
+
+```json
+{
+  "@odata.id": "/redfish/v1/Chassis/Foo",
+  "@odata.type": "#Chassis.v1_17_0.Chassis",
+  "Assembly": {
+    "@odata.id": "/redfish/v1/Chassis/Foo/Assembly"
+  },
+  "Certificates": {
+    "@odata.id": "/redfish/v1/Chassis/Foo/Certificates"
+  },
+  "ChassisType": "Module",
+  "Drives": {
+    "@odata.id": "/redfish/v1/Chassis/Foo/Drives"
+  },
+  "EnvironmentMetrics": {
+    "@odata.id": "/redfish/v1/Chassis/Foo/EnvironmentMetrics"
+  },
+  "Id": "Foo",
+  "Links": {
+    "ComputerSystems": [
+      {
+        "@odata.id": "/redfish/v1/Systems/system"
+      }
+    ],
+    "Contains": {
+      "@odata.id": "/redfish/v1/Chassis/Bar"
+    },
+    "ManagedBy": [
+      {
+        "@odata.id": "/redfish/v1/Managers/bmc"
+      }
+    ]
+  },
+  "Manufacturer": "Foo_Manufacturer",
+  "Memory": {
+    "@odata.id": "/redfish/v1/Systems/system/Memory"
+  },
+  "Model": "Foo_Model",
+  "Name": "Foo",
+  "PCIeDevices": {
+    "@odata.id": "/redfish/v1/Systems/system/PCIeDevices"
+  },
+  "PCIeSlots": {
+    "@odata.id": "/redfish/v1/Chassis/Foo/PCIeSlots"
+  },
+  "PartNumber": "1111111-11",
+  "Power": {
+    "@odata.id": "/redfish/v1/Chassis/Foo/Power"
+  },
+  "PowerState": "On",
+  "PowerSubsystem": {
+    "@odata.id": "/redfish/v1/Chassis/Foo/PowerSubsystem"
+  },
+  "Sensors": {
+    "@odata.id": "/redfish/v1/Chassis/Foo/Sensors"
+  },
+  "SerialNumber": "AAAAA-11111111",
+  "Status": {
+    "Health": "OK",
+    "HealthRollup": "OK",
+    "State": "Enabled"
+  },
+  "Thermal": {
+    "@odata.id": "/redfish/v1/Chassis/Foo/Thermal"
+  },
+  "ThermalSubsystem": {
+    "@odata.id": "/redfish/v1/Chassis/Foo/ThermalSubsystem"
+  },
+  "TrustedComponents": {
+    "@odata.id": "/redfish/v1/Chassis/Foo/TrustedComponents"
+  }
+}
+```
+
+### Sensors
+
+Sensors supported by tlBMC are fully owned. Sensor configurations are parsed
+from EM configs and readings are polled directly from hwmon files. There are no
+dbus calls being made to supply sensor readings in tlBMC.
+
+Note: Since tlBMC does not support all sensor types yet (only Hwmon Temp, PSU,
+and I2CFan sensors for now), tlBMC does not own sensor collection. The response
+at `/redfish/v1/Chassis/{ChassisId}/Sensors` is routed to bmcweb but a query for
+individual sensor will be routed to tlBMC if supported.
+
+An example can be seen from this config:
+
+```json
+"Exposes": [
+  {
+    "Name": "foo_external_sensor",
+    "Units": "Watts",
+    "MinValue": 6500,
+    "MaxValue": 7500,
+    "Type": "ExternalSensor"
+  },
+  {
+    "Name": "foo_psu_sensor",
+    "Address": "0x44",
+    "Bus": "11",
+    "Labels": [
+      "vout1",
+      "vout2",
+      "vout3",
+      "vout4"
+    ],
+    "vout1_Name": "foo_psu_sensor_0",
+    "vout2_Name": "foo_psu_sensor_1",
+    "vout3_Name": "foo_psu_sensor_2",
+    "vout4_Name": "foo_psu_sensor_3",
+    "Type": "ADM1266",
+    "TlbmcOwned": true
+  },
+  ...
+]
+```
+
+Since the `foo_psu_sensor` has the field `"TlbmcOwned"` and is of the supported
+type `ADM1266`, the response when any of these individual sensors is queried
+will be provided by tlBMC.
+
+## Linked Resources Not Owned
+
+For some configurations, tlBMC may detect and own the Chassis resource, but
+there may be resources configured in the EM config file that are not owned by
+tlBMC.
+
+Since the scope of tlBMC is limited to only the Chassis path at the moment it is
+possible for some Chassis to not own the resources linked in its "Links", even
+when configured in the EM config. When these properties are queried, the
+response will be populated from the traditional bmcweb path.
+
+These associated resources that are linked in response but not yet owned by
+tlBMC include:
+
+-   Storages
+-   Processors
+-   Cables
+
+An example can be seen in this config:
+
+```json
+# Assume there are two other Chassis EM configs connecting to the ports
+# Assume there is another Cable EM config with CableUpstreamConnection to Foo Cable Downstream
+{
+...
+  "Exposes": [
+    {
+      "Label": "IO0",
+      "Name": "foo Port 1",
+      "Type": "PortDownstream",
+      "User": "tlbmc"
+    },
+    {
+      "Label": "IO1",
+      "Name": "foo Port 2",
+      "Type": "PortDownstream",
+      "User": "tlbmc"
+    },
+    {
+      "Name": "Foo Cable Downstream",
+      "CableId": "foo_cable",
+      "Type": "CableDownstreamConnection",
+      "User": "tlbmc"
+    },
+    ...
+    {
+      "Name": "cpu0",
+      "Type": "Processor",
+      "User": "tlbmc"
+    },
+    {
+      "Name": "cpu1",
+      "Type": "Processor",
+      "User": "tlbmc"
+    },
+  ],
+  ...
+  "Storage":
+  {
+    "Id": "foo_storage",
+    "User": "tlbmc"
+  }
+...
+}
+```
+
+A snippet of the `Links` field resulting from querying this chassis is provided
+below. This has been annotated to show the resources that are tlBMC owned and
+not. As seen from the EM config above, several fields are configured for tlBMC
+to produce these links but tlBMC does not have ownership of the resource paths
+when queried.
+
+<pre><code class="lang-json">
+  {
+  ...
+  "Links": {
+    "Cables": [
+      {
+        "@odata.id": <del>"/redfish/v1/Cables/foo_cable"</del>
+      }
+    ],
+    "Cables@odata.count": 1,
+    "ComputerSystems": [
+      {
+        "@odata.id": "/redfish/v1/Systems/system"
+      }
+    ],
+    "Contains": [
+      {
+        "@odata.id":<ins>"/redfish/v1/Chassis/bar"</ins>
+      },
+      {
+        "@odata.id":<ins>"/redfish/v1/Chassis/baz"</ins>
+      }
+    ],
+    "Contains@odata.count": 2,
+    "ManagedBy": [
+      {
+        "@odata.id": "/redfish/v1/Managers/bmc"
+      }
+    ],
+    "Processors": [
+      {
+        "@odata.id": <del>"/redfish/v1/Systems/system/Processors/cpu0"</del>
+      },
+      {
+        "@odata.id":<del> "/redfish/v1/Systems/system/Processors/cpu1"</del>
+      }
+    ],
+    "Processors@odata.count": 2,
+    "Storage": [
+      {
+        "@odata.id": <del>"/redfish/v1/Systems/system/Storage/foo_storage"</del>
+      }
+    ],
+    "Storage@odata.count": 1
+  },
+  ...
+}
+</code></pre>
+
+## FRUs Not Detected by tlBMC but Modeled
+
+For some configurations, tlBMC does not detect the existence of the resource but
+may model it. tlBMC would have a TRUE probe for the resource i.e. Cables. In
+this case, the existence of the cable is implied by the successful detection of
+the surrounding Chassis resource and will be populated in the Cables Links of
+the associated Chassis.
+
+Here, tlBMC does not own the resource and querying the `/redfish/v1/Cables` path
+will return the traditional bmcweb response. tlBMC properties in this case exist
+only to correctly populate the associations (Links) to the `/redfish/v1/Cables`
+path in the associated resources that tlBMC does own i.e. upstream and
+downstream chassis to the cable. This is necessary for tlBMC to correctly fully
+own Chassis. In the future, when tlBMC fully owns these resources, the probe
+will become a real probe.
+
+An example can be seen from this cable config:
+
+```json
+{
+  "Exposes": [
+    {
+      "Name": "Foo Cable Downstream",
+      "CableId": "FooCable",
+      "Type": "CableUpstreamConnection",
+      "User": "tlbmc"
+    },
+    {
+      "Name": "Foo Cable Upstream",
+      "CableId": "FooCable",
+      "Type": "CableDownstreamConnection",
+      "User": "tlbmc"
+    }
+  ],
+  "Name": "NcsiCable",
+  "ProbeV2": "TRUE",
+  "ResourceType": "RESOURCE_TYPE_CABLE",
+  "Type": "Cable",
+}
+```
+
+Although tlBMC fields are required in this EM config to create the correct
+relationships when queried, tlBMC does not own `/redfish/v1/Cables/FooCable` and
+this will be served from traditional Bmcweb.