Section Organization

L3
ModelContextProtocolNotionStandard Operating Procedure

Reorganize the Standard Operating Procedure page by swapping sections and creating a column layout.

Created by Xiangyan Liu
2025-08-11
Content OrganizationCross Reference LinkingVisual Formatting

Model Ranking

Click on the dots to view the trajectory of each task run
Model
Run Results
Pass@4
Pass^4
Avg Time
Avg Turns
Input Tokens
Output Tokens
Total Tokens
Claude
claude-opus-4-1
0
/1
--
361.2s
24.0
501,656
4,149
505,805
Claude
claude-sonnet-4
0
/4
276.6s
29.5
1,030,648
5,655
1,036,303
Claude
claude-sonnet-4-high
0
/4
218.6s
27.5
854,038
5,232
859,270
Claude
claude-sonnet-4-low
0
/4
221.6s
28.5
904,607
5,025
909,632
DeepSeek
deepseek-chat
0
/4
395.2s
32.3
890,762
3,772
894,534
Gemini
gemini-2-5-flash
0
/4
48.3s
1.3
13,242
5,264
18,505
Gemini
gemini-2-5-pro
0
/4
45.6s
2.3
21,579
3,132
24,711
Z.ai
glm-4-5
0
/4
199.6s
25.5
516,302
4,551
520,853
OpenAI
gpt-4-1
0
/4
63.1s
12.0
169,273
2,138
171,411
OpenAI
gpt-4-1-mini
0
/4
97.0s
19.0
308,014
2,729
310,743
OpenAI
gpt-4-1-nano
0
/4
11.2s
3.3
18,027
218
18,244
OpenAI
gpt-5-high
0
/4
989.4s
7.8
219,502
50,355
269,857
OpenAI
gpt-5-low
0
/4
841.6s
14.0
394,219
42,222
436,441
OpenAI
gpt-5-medium
0
/4
1327.4s
20.8
782,093
66,509
848,602
OpenAI
gpt-5-mini-high
0
/4
1878.0s
27.0
1,658,334
186,179
1,844,513
OpenAI
gpt-5-mini-low
0
/4
40.4s
4.3
22,412
2,607
25,019
OpenAI
gpt-5-mini-medium
0
/4
251.1s
15.3
355,712
22,361
378,073
OpenAI
gpt-5-nano-high
0
/4
183.8s
3.5
22,876
36,760
59,635
OpenAI
gpt-5-nano-low
0
/4
31.6s
1.8
6,953
4,861
11,813
OpenAI
gpt-5-nano-medium
0
/4
48.9s
2.5
13,175
9,512
22,687
OpenAI
gpt-oss-120b
0
/4
75.3s
7.5
135,149
4,778
139,927
Grok
grok-4
0
/4
438.2s
16.8
455,694
18,470
474,164
Grok
grok-code-fast-1
0
/4
316.8s
17.3
404,906
14,010
422,767
MoonshotAI
kimi-k2-0711
0
/4
169.3s
25.8
498,974
2,941
501,915
MoonshotAI
kimi-k2-0905
0
/4
531.9s
52.3
1,511,630
5,366
1,516,996
OpenAI
o3
0
/4
254.3s
5.8
50,228
19,188
69,416
OpenAI
o4-mini
0
/4
85.5s
3.0
16,402
6,526
22,928
Qwen
qwen-3-coder-plus
0
/4
232.9s
50.0
2,173,329
6,355
2,179,683
Qwen
qwen-3-max
0
/4
200.9s
35.3
1,008,813
3,388
1,012,201

Task State

Notion Workspace
This task is executed based on this Notion workspace
This workspace is cloned from notion official template marketplace.View Original Template

Instruction

Task: Reorganize Standard Operating Procedure Page Sections

Objective

Modify the structure of the Standard Operating Procedure page in Notion by reorganizing sections through swapping and creating a column layout.

Requirements

Step 1: Swap Sections

  • Navigate to the Standard Operating Procedure page
  • Swap the positions of the "Terminologies" and "Roles & responsibilities" sections
  • Preserve all content within each section exactly as is
  • Maintain the original formatting and structure of each section

Step 2: Create Column Layout

  • After swapping, arrange the "Tools" section and the section immediately below it ("Terminologies") into a 2-column layout
  • Position the "Tools" section in the left column
  • Position the "Terminologies" section in the right column
  • In the "Tools" column, add links to the Notion and Figma pages using appropriate reference blocks
  • Preserve the original child pages from the "Tools" section in a toggle block placed below the column layout, with the toggle titled "original pages"


Verify

*.py
Python
import sys
from notion_client import Client
from tasks.utils import notion_utils

def verify(notion: Client, main_id: str = None) -> bool:
    """
    Verifies that the Standard Operating Procedure page has been reorganized correctly.
    """
    # Step 1: Find the Standard Operating Procedure page
    if main_id:
        found_id, object_type = notion_utils.find_page_or_database_by_id(notion, main_id)
        if not found_id or object_type != 'page':
            print("Error: Standard Operating Procedure page not found.", file=sys.stderr)
            return False
    else:
        # Try to find the page by searching
        found_id = notion_utils.find_page(notion, "Standard Operating Procedure")
        if not found_id:
            print("Error: Standard Operating Procedure page not found.", file=sys.stderr)
            return False
    
    print(f"Found Standard Operating Procedure page: {found_id}")
    
    # Get all blocks from the page
    all_blocks = notion_utils.get_all_blocks_recursively(notion, found_id)
    print(f"Found {len(all_blocks)} blocks")
    
    print("Starting verification...")
    
    # Step 2: Verify the structure and section order
    print("2. Checking page structure and section order...")
    
    # Expected structure after the initial content and dividers
    # We'll look for main sections by their headings
    roles_index = None
    tools_column_index = None
    toggle_index = None
    procedure_index = None
    
    for i, block in enumerate(all_blocks):
        if block.get("type") == "heading_2":
            heading_text = ""
            rich_text = block.get("heading_2", {}).get("rich_text", [])
            if rich_text:
                heading_text = rich_text[0].get("text", {}).get("content", "")
            
            if heading_text == "Roles & responsibilities":
                roles_index = i
                print(f"✓ Found 'Roles & responsibilities' section at index {i}")
            elif heading_text == "Procedure":
                procedure_index = i
                print(f"✓ Found 'Procedure' section at index {i}")
    
    # Check for column_list (containing Tools and Terminologies)
    for i, block in enumerate(all_blocks):
        if block.get("type") == "column_list":
            # Check if this is the right column_list (should be after Roles & responsibilities)
            if roles_index and i > roles_index:
                tools_column_index = i
                print(f"✓ Found column_list at index {i}")
                break
    
    # Check for toggle block with "original pages"
    for i, block in enumerate(all_blocks):
        if block.get("type") == "toggle":
            toggle_text = ""
            rich_text = block.get("toggle", {}).get("rich_text", [])
            if rich_text:
                toggle_text = rich_text[0].get("text", {}).get("content", "")
            
            if toggle_text.lower() == "original pages":
                toggle_index = i
                print(f"✓ Found 'original pages' toggle at index {i}")
                break
    
    # Step 3: Verify section order
    print("3. Verifying section order...")
    
    if roles_index is None:
        print("Error: 'Roles & responsibilities' section not found.", file=sys.stderr)
        return False
    
    if tools_column_index is None:
        print("Error: Column layout not found.", file=sys.stderr)
        return False
    
    if toggle_index is None:
        print("Error: 'original pages' toggle not found.", file=sys.stderr)
        return False
    
    if procedure_index is None:
        print("Error: 'Procedure' section not found.", file=sys.stderr)
        return False
    
    # Verify order: Roles & responsibilities < column_list < toggle < Procedure
    if not (roles_index < tools_column_index < toggle_index < procedure_index):
        print("Error: Sections are not in the correct order.", file=sys.stderr)
        print(f"  Expected order: Roles & responsibilities ({roles_index}) < column_list ({tools_column_index}) < toggle ({toggle_index}) < Procedure ({procedure_index})", file=sys.stderr)
        return False
    
    print("✓ Sections are in the correct order")
    
    # Step 4: Verify column_list structure
    print("4. Verifying column layout structure...")
    
    column_list_block = all_blocks[tools_column_index]
    column_list_id = column_list_block.get("id")
    
    # Get direct children of column_list (should be columns only)
    try:
        column_response = notion.blocks.children.list(block_id=column_list_id)
        column_children = column_response.get("results", [])
    except Exception as e:
        print(f"Error getting column children: {e}", file=sys.stderr)
        return False
    
    if len(column_children) < 2:
        print(f"Error: Column list should have at least 2 columns, found {len(column_children)}.", file=sys.stderr)
        return False
    
    # Verify left column (Tools)
    left_column = column_children[0]
    if left_column.get("type") != "column":
        print("Error: First child of column_list should be a column.", file=sys.stderr)
        return False
    
    left_column_id = left_column.get("id")
    left_column_blocks = notion_utils.get_all_blocks_recursively(notion, left_column_id)
    
    # Check for Tools heading and link_to_page blocks in left column
    tools_heading_found = False
    link_to_page_count = 0
    for block in left_column_blocks:
        if block.get("type") == "heading_2":
            heading_text = block.get("heading_2", {}).get("rich_text", [{}])[0].get("text", {}).get("content", "")
            if heading_text == "Tools":
                tools_heading_found = True
                print("✓ Found 'Tools' heading in left column")
        elif block.get("type") == "link_to_page":
            link_to_page_count += 1
    
    if not tools_heading_found:
        print("Error: 'Tools' heading not found in left column.", file=sys.stderr)
        return False
    
    # Check for link_to_page blocks in Tools column
    if link_to_page_count < 2:
        print(f"Error: Tools column should have at least 2 link_to_page blocks, found {link_to_page_count}.", file=sys.stderr)
        return False
    
    print(f"✓ Found {link_to_page_count} link_to_page blocks in Tools column")
    
    # Verify right column (Terminologies)
    right_column = column_children[1]
    if right_column.get("type") != "column":
        print("Error: Second child of column_list should be a column.", file=sys.stderr)
        return False
    
    right_column_id = right_column.get("id")
    right_column_blocks = notion_utils.get_all_blocks_recursively(notion, right_column_id)
    
    # Check for Terminologies heading in right column
    terminologies_heading_found = False
    for block in right_column_blocks:
        if block.get("type") == "heading_2":
            heading_text = block.get("heading_2", {}).get("rich_text", [{}])[0].get("text", {}).get("content", "")
            if heading_text == "Terminologies":
                terminologies_heading_found = True
                print("✓ Found 'Terminologies' heading in right column")
                break
    
    if not terminologies_heading_found:
        print("Error: 'Terminologies' heading not found in right column.", file=sys.stderr)
        return False
    
    # Step 5: Verify toggle block content
    print("5. Verifying toggle block content...")
    
    toggle_block = all_blocks[toggle_index]
    toggle_id = toggle_block.get("id")
    
    # Get direct children of toggle
    try:
        toggle_response = notion.blocks.children.list(block_id=toggle_id)
        toggle_children = toggle_response.get("results", [])
    except Exception as e:
        print(f"Error getting toggle children: {e}", file=sys.stderr)
        return False
    
    # Check for child_page blocks (Notion and Figma)
    notion_page_found = False
    figma_page_found = False
    
    for block in toggle_children:
        if block.get("type") == "child_page":
            title = block.get("child_page", {}).get("title", "")
            if title == "Notion":
                notion_page_found = True
                print("✓ Found 'Notion' child page in toggle")
            elif title == "Figma":
                figma_page_found = True
                print("✓ Found 'Figma' child page in toggle")
    
    if not notion_page_found:
        print("Error: 'Notion' child page not found in toggle block.", file=sys.stderr)
        return False
    
    if not figma_page_found:
        print("Error: 'Figma' child page not found in toggle block.", file=sys.stderr)
        return False
    
    # Step 6: Verify that original sections no longer exist at top level
    print("6. Verifying original sections have been removed from top level...")
    
    # Check that there's no standalone "Terminologies" heading before "Roles & responsibilities"
    for i in range(0, roles_index if roles_index else len(all_blocks)):
        block = all_blocks[i]
        if block.get("type") == "heading_2":
            heading_text = block.get("heading_2", {}).get("rich_text", [{}])[0].get("text", {}).get("content", "")
            if heading_text == "Terminologies":
                print("Error: 'Terminologies' section found before 'Roles & responsibilities'.", file=sys.stderr)
                return False
    
    # Check that there's no standalone "Tools" heading outside the column
    tools_outside_column = False
    for i, block in enumerate(all_blocks):
        if i == tools_column_index:
            continue  # Skip the column_list itself
        if block.get("type") == "heading_2":
            heading_text = block.get("heading_2", {}).get("rich_text", [{}])[0].get("text", {}).get("content", "")
            if heading_text == "Tools" and i != tools_column_index:
                # Check if this is NOT inside the column
                parent_id = block.get("parent", {}).get("block_id")
                if parent_id != left_column_id:
                    tools_outside_column = True
                    break
    
    if tools_outside_column:
        print("Error: Standalone 'Tools' section found outside column layout.", file=sys.stderr)
        return False
    
    print("✓ Original sections have been properly reorganized")
    
    # Step 7: Final summary
    print("\n7. Final verification summary:")
    print("✓ 'Roles & responsibilities' and 'Terminologies' sections have been swapped")
    print("✓ 'Tools' and 'Terminologies' are in a 2-column layout")
    print("✓ Links to Notion and Figma pages are in the Tools column")
    print("✓ Original child pages are preserved in 'original pages' toggle")
    print("✓ Page structure is correct")
    
    print("\n✅ All verification checks passed!")
    return True

def main():
    """
    Executes the verification process and exits with a status code.
    """
    notion = notion_utils.get_notion_client()
    main_id = sys.argv[1] if len(sys.argv) > 1 else None
    if verify(notion, main_id):
        sys.exit(0)
    else:
        sys.exit(1)

if __name__ == "__main__":
    main()