diff --git a/deps/apiinfo.go b/deps/apiinfo.go
index 789f2e89f..75b786d63 100644
--- a/deps/apiinfo.go
+++ b/deps/apiinfo.go
@@ -7,6 +7,7 @@ import (
 	"math/rand"
 	"net/http"
 	"reflect"
+	"strings"
 	"sync"
 	"time"
 
@@ -71,11 +72,13 @@ func GetFullNodeAPIV1Curio(ctx *cli.Context, ainfoCfg []string) (api.Chain, json
 		}
 
 		// Compare with binary's network using BuildTypeString()
-		if string(networkName) != build.BuildTypeString()[1:] {
-			clog.Warnf("Network mismatch for node %s: binary built for %s but node is on %s",
-				head.addr, build.BuildTypeString()[1:], networkName)
-			closer()
-			continue
+		if !(strings.HasPrefix(string(networkName), "test") || strings.HasPrefix(string(networkName), "local")) {
+			if string(networkName) != build.BuildTypeString()[1:] {
+				clog.Warnf("Network mismatch for node %s: binary built for %s but node is on %s",
+					head.addr, build.BuildTypeString()[1:], networkName)
+				closer()
+				continue
+			}
 		}
 
 		fullNodes = append(fullNodes, v1api)
diff --git a/web/api/webrpc/storage_stats.go b/web/api/webrpc/storage_stats.go
index 6a43bed88..82b45da3a 100644
--- a/web/api/webrpc/storage_stats.go
+++ b/web/api/webrpc/storage_stats.go
@@ -8,6 +8,7 @@ import (
 
 	"github.com/samber/lo"
 	"github.com/snadrus/must"
+	"golang.org/x/xerrors"
 
 	"github.com/filecoin-project/go-address"
 
@@ -80,7 +81,7 @@ func (a *WebRPC) StorageUseStats(ctx context.Context) ([]StorageUseStats, error)
 	return stats, nil
 }
 
-type StorageGCMarks struct {
+type StorageGCMark struct {
 	Actor     int64  `db:"sp_id"`
 	SectorNum int64  `db:"sector_num"`
 	FileType  int64  `db:"sector_filetype"`
@@ -102,16 +103,70 @@ type StorageGCMarks struct {
 	Miner string
 }
 
-func (a *WebRPC) StorageGCMarks(ctx context.Context) ([]*StorageGCMarks, error) {
-	var marks []*StorageGCMarks
-	err := a.deps.DB.Select(ctx, &marks, `
-		SELECT m.sp_id, m.sector_num, m.sector_filetype, m.storage_id, m.created_at, m.approved, m.approved_at, sl.can_seal, sl.can_store, sl.urls
-			FROM storage_removal_marks m LEFT JOIN storage_path sl ON m.storage_id = sl.storage_id
-			ORDER BY created_at DESC`)
+type StorageGCMarks struct {
+	Marks []*StorageGCMark
+	Total int
+}
+
+func (a *WebRPC) StorageGCMarks(ctx context.Context, miner *string, sectorNum *int64, limit int, offset int) (*StorageGCMarks, error) {
+	var spID *int64
+	if miner != nil {
+		maddr, err := address.NewFromString(*miner)
+		if err != nil {
+			return nil, err
+		}
+		sp_id, err := address.IDFromAddress(maddr)
+		if err != nil {
+			return nil, err
+		}
+		tspid := int64(sp_id)
+		spID = &tspid
+	}
+
+	if sectorNum != nil && *sectorNum < 0 {
+		return nil, xerrors.Errorf("invalid sector_num: %d", *sectorNum)
+	}
+
+	var marks []*StorageGCMark
+	var total int
+
+	// Get the total count of rows
+	err := a.deps.DB.QueryRow(ctx, `SELECT 
+    											COUNT(*) 
+											FROM storage_removal_marks 
+											WHERE 
+											     ($1::BIGINT IS NULL OR sp_id = $1) 
+											  AND ($2::BIGINT IS NULL OR sector_num = $2)`, spID, sectorNum).Scan(&total)
 	if err != nil {
-		return nil, err
+		return nil, xerrors.Errorf("querying storage removal marks: %w", err)
 	}
 
+	err = a.deps.DB.Select(ctx, &marks, `
+								SELECT 
+								    m.sp_id, 
+								    m.sector_num, 
+								    m.sector_filetype, 
+								    m.storage_id, 
+								    m.created_at, 
+								    m.approved, 
+								    m.approved_at, 
+								    sl.can_seal, 
+								    sl.can_store, 
+								    sl.urls
+								FROM storage_removal_marks m 
+								    LEFT JOIN storage_path sl ON m.storage_id = sl.storage_id
+								WHERE 
+								    ($1::BIGINT IS NULL OR m.sp_id = $1)
+    								AND ($2::BIGINT IS NULL OR m.sector_num = $2) 
+								ORDER BY created_at 
+								DESC LIMIT $3 
+								OFFSET $4`, spID, sectorNum, limit, offset)
+	if err != nil {
+		return nil, xerrors.Errorf("querying storage removal marks: %w", err)
+	}
+
+	minerMap := make(map[int64]address.Address)
+
 	for i, m := range marks {
 		marks[i].TypeName = storiface.SectorFileType(m.FileType).String()
 
@@ -129,14 +184,21 @@ func (a *WebRPC) StorageGCMarks(ctx context.Context) ([]*StorageGCMarks, error)
 			return must.One(url.Parse(u)).Host
 		})
 		marks[i].Urls = strings.Join(us, ", ")
-		maddr, err := address.NewIDAddress(uint64(marks[i].Actor))
-		if err != nil {
-			return nil, err
+		maddr, ok := minerMap[marks[i].Actor]
+		if !ok {
+			maddr, err = address.NewIDAddress(uint64(marks[i].Actor))
+			if err != nil {
+				return nil, err
+			}
+			minerMap[marks[i].Actor] = maddr
 		}
 		marks[i].Miner = maddr.String()
 	}
 
-	return marks, nil
+	return &StorageGCMarks{
+		Marks: marks,
+		Total: total,
+	}, nil
 }
 
 func (a *WebRPC) StorageGCApprove(ctx context.Context, actor int64, sectorNum int64, fileType int64, storageID string) error {
diff --git a/web/static/gc/gc-marks.mjs b/web/static/gc/gc-marks.mjs
index 3fe9d3827..5523e0072 100644
--- a/web/static/gc/gc-marks.mjs
+++ b/web/static/gc/gc-marks.mjs
@@ -3,29 +3,117 @@ import RPCCall from '/lib/jsonrpc.mjs';
 
 class StorageGCStats extends LitElement {
     static properties = {
-        data: { type: Array }
+        data: { type: Array },
+        pageSize: { type: Number },
+        currentPage: { type: Number },
+        totalPages: { type: Number },
+        totalCount: { type: Number },
+        miner: { type: String },
+        sectorNum: { type: Number },
     };
 
     constructor() {
         super();
         this.data = [];
-        this.loadData();
+        this.pageSize = 50; // Default number of rows per page
+        this.currentPage = 1;
+        this.totalPages = 0;
+        this.totalCount = 0;
+        this.miner = null; // Default: No Miner filter
+        this.sectorNum = null; // Default: No Sector Number filter
+        this.loadData(); // Load initial data for page 1
     }
 
-    async loadData() {
-        this.data = await RPCCall('StorageGCMarks');
+    async loadData(page = 1) {
+        const offset = (page - 1) * this.pageSize;
+
+        // Fetch data from the backend with limit, offset, and optional filters
+        const response = await RPCCall('StorageGCMarks', [
+            this.miner, // Include Miner filter if set
+            this.sectorNum, // Include Sector Number filter if set
+            this.pageSize,
+            offset,
+        ]);
+
+        this.data = response.Marks || []; // Data for the current page
+        this.totalCount = response.Total || 0; // Total rows matching the filters
+        this.totalPages = Math.ceil(this.totalCount / this.pageSize); // Calculate total pages
+        this.currentPage = page; // Update the current page
         this.requestUpdate();
     }
 
     async approveEntry(entry) {
         await RPCCall('StorageGCApprove', [entry.Actor, entry.SectorNum, entry.FileType, entry.StorageID]);
+        this.loadData(this.currentPage); // Reload current page
+    }
+
+    updateFilters(event) {
+        const { name, value } = event.target;
+        if (name === 'miner') {
+            this.miner = value ? value.trim() : null; // Trim spaces for miner ID
+        } else if (name === 'sectorNum') {
+            this.sectorNum = value ? Number(value) : null; // Convert sectorNum to a number
+        }
+    }
+
+    applyFilters() {
+        this.currentPage = 1; // Reset to page 1 when filters are applied
         this.loadData();
     }
 
+    renderFilters() {
+        return html`
+            <div class="filter-container mb-3">
+                <label for="miner">Miner:</label>
+                <input
+                        id="miner"
+                        name="miner"
+                        type="text"
+                        @input="${this.updateFilters}"
+                        placeholder="Enter Miner ID"
+                >
+
+                <label for="sectorNum">Sector Number:</label>
+                <input
+                        id="sectorNum"
+                        name="sectorNum"
+                        type="number"
+                        @input="${this.updateFilters}"
+                        placeholder="Enter Sector Number"
+                >
+                <p></p>
+                <button @click="${this.applyFilters}" class="btn btn-primary">Apply Filters</button>
+            </div>
+        `;
+    }
+
+    renderPagination() {
+        return html`
+            <nav>
+                <ul class="pagination">
+                    <li class="page-item ${this.currentPage === 1 ? 'disabled' : ''}">
+                        <button class="page-link" @click="${() => this.loadData(this.currentPage - 1)}">Previous</button>
+                    </li>
+                    <li class="page-item disabled">
+                        <span class="page-link">
+                            Page ${this.currentPage} of ${this.totalPages}
+                        </span>
+                    </li>
+                    <li class="page-item ${this.currentPage === this.totalPages ? 'disabled' : ''}">
+                        <button class="page-link" @click="${() => this.loadData(this.currentPage + 1)}">Next</button>
+                    </li>
+                </ul>
+            </nav>
+        `;
+    }
+
     render() {
         return html`
             <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
             <link rel="stylesheet" href="/ux/main.css" onload="document.body.style.visibility = 'initial'">
+            <p></p>
+            ${this.renderFilters()}
+            <p></p>
             <table class="table table-dark">
                 <thead>
                 <tr>
@@ -44,26 +132,22 @@ class StorageGCStats extends LitElement {
                         <td>${entry.Miner}</td>
                         <td>${entry.SectorNum}</td>
                         <td>
-                            <div>
-                                ${entry.StorageID}
-                            </div>
-                            <div>
-                                ${entry.Urls}
-                            </div>
+                            <div>${entry.StorageID}</div>
+                            <div>${entry.Urls}</div>
                         </td>
                         <td>${entry.PathType}</td>
                         <td>${entry.TypeName}</td>
                         <td>${entry.CreatedAt}</td>
                         <td>
-                            ${entry.Approved ?
-            "Yes " + entry.ApprovedAt :
-            html`No <button @click="${() => this.approveEntry(entry)}" class="btn btn-primary btn-sm">Approve</button>`
-        }
+                            ${entry.Approved
+                                    ? `Yes ${entry.ApprovedAt}`
+                                    : html`No <button @click="${() => this.approveEntry(entry)}" class="btn btn-primary btn-sm">Approve</button>`}
                         </td>
                     </tr>
-                    `)}
+                `)}
                 </tbody>
             </table>
+            ${this.renderPagination()}
         `;
     }
 }
@@ -76,7 +160,7 @@ class ApproveAllButton extends LitElement {
 
     constructor() {
         super();
-        this.unapprove = false; // default is false, meaning "Approve All"
+        this.unapprove = false; // Default is "Approve All"
     }
 
     async handleClick() {
@@ -98,4 +182,4 @@ class ApproveAllButton extends LitElement {
         `;
     }
 }
-customElements.define('approve-all-button', ApproveAllButton);
\ No newline at end of file
+customElements.define('approve-all-button', ApproveAllButton);
diff --git a/web/static/pages/pipeline_porep/pipeline-porep-sectors.mjs b/web/static/pages/pipeline_porep/pipeline-porep-sectors.mjs
index 3a878ce02..50547da64 100644
--- a/web/static/pages/pipeline_porep/pipeline-porep-sectors.mjs
+++ b/web/static/pages/pipeline_porep/pipeline-porep-sectors.mjs
@@ -382,6 +382,7 @@ export function renderSectorState(name, rowspan, sector, task, after, started) {
     // 1) "waiting for precommit"
     if (
         name === 'PComm Msg' &&
+        sector.AfterSynthetic &&
         sector.PreCommitReadyAt &&
         !sector.AfterPrecommitMsg &&
         !sector.TaskPrecommitMsg