Skills Development Tracker

L3
ModelContextProtocolNotionOnline Resume

Create a comprehensive skills audit system with development tracking for skills below 70% proficiency.

Created by Xiangyan Liu
2025-07-27
Database ManipulationCross Reference LinkingConditional FilteringData AggregationTemplate PopulationVisual 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
OpenAI
gpt-5-medium
4
/4
860.5s
16.8
254,802
39,406
294,208
OpenAI
gpt-5-high
3
/4
1648.1s
16.8
330,343
72,590
402,933
OpenAI
gpt-5-low
3
/4
586.1s
13.5
262,421
36,262
298,683
Z.ai
glm-4-5
2
/4
256.1s
26.8
638,636
6,214
644,849
OpenAI
o3
2
/4
189.4s
17.0
236,359
11,180
247,539
Claude
claude-sonnet-4-high
1
/4
256.3s
24.5
1,962,999
5,545
1,968,544
DeepSeek
deepseek-chat
1
/4
244.1s
19.0
403,799
2,437
406,236
Qwen
qwen-3-coder-plus
1
/4
128.3s
28.5
937,637
4,086
941,722
Claude
claude-opus-4-1
0
/1
--
247.4s
19.0
622,238
4,324
626,562
Claude
claude-sonnet-4
0
/4
221.7s
25.3
689,009
5,706
694,715
Claude
claude-sonnet-4-low
0
/4
335.7s
23.8
2,299,554
5,185
2,304,739
Gemini
gemini-2-5-flash
0
/4
19.1s
2.3
19,006
2,269
21,275
Gemini
gemini-2-5-pro
0
/4
55.9s
4.5
66,857
4,295
71,153
OpenAI
gpt-4-1
0
/4
40.0s
9.3
89,649
1,089
90,738
OpenAI
gpt-4-1-mini
0
/4
69.9s
15.8
249,798
1,923
251,721
OpenAI
gpt-4-1-nano
0
/4
20.9s
8.5
125,095
382
125,477
OpenAI
gpt-5-mini-high
0
/4
502.6s
24.8
1,804,917
30,655
1,835,572
OpenAI
gpt-5-mini-low
0
/4
47.7s
7.5
69,054
3,667
72,721
OpenAI
gpt-5-mini-medium
0
/4
251.2s
23.5
935,511
19,017
954,528
OpenAI
gpt-5-nano-high
0
/4
399.9s
7.0
233,980
82,750
316,730
OpenAI
gpt-5-nano-low
0
/4
79.9s
5.8
38,024
14,501
52,525
OpenAI
gpt-5-nano-medium
0
/4
190.1s
5.0
113,015
37,807
150,821
OpenAI
gpt-oss-120b
0
/4
28.0s
4.0
21,738
842
22,580
Grok
grok-4
0
/4
527.1s
34.3
1,250,483
15,641
1,266,124
Grok
grok-code-fast-1
0
/4
115.6s
27.8
554,670
9,344
568,645
MoonshotAI
kimi-k2-0711
0
/4
181.8s
27.3
583,372
3,467
586,839
MoonshotAI
kimi-k2-0905
0
/4
1385.0s
58.3
2,134,012
18,505
2,152,517
OpenAI
o4-mini
0
/4
310.3s
12.0
79,612
23,004
102,615
Qwen
qwen-3-max
0
/4
904.1s
100.0
3,361,014
24,282
3,385,297

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

Create a comprehensive skills audit system by performing the following tasks:

Task Requirements:

  1. Create a new database named "Skills Development Tracker" as a child database in the main resume page with the following properties:

    • Name (title property)
    • Current Skill (relation to Skills database)
    • Current Proficiency (rollup from related skill's "Skill Level" property)
    • Target Proficiency (number property with format "percent")
    • Gap (formula: Target Proficiency - Current Proficiency)
    • Learning Resources (rich text property)
    • Progress Notes (rich text property)
  2. Populate the Skills Development Tracker database with entries for all skills that have a proficiency level below 70% (0.7):

    • For each qualifying skill, create an entry with:
      • Name: "[Skill Name] Development Plan"
      • Link to the corresponding skill in Skills database
      • Target Proficiency: Set to Current + 25% (capped at 95%)
      • Learning Resources: "Online courses and practice projects"
      • Progress Notes: "Initial assessment completed"
  3. Create a callout block immediately after the Skills section (after the Skills database) with:

    • Background color: blue_background
    • Icon: 🎯 (target emoji)
    • Content: "Focus Areas: [3 skills with lowest current proficiency]"


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 Skills Development Tracker database and callout block were created correctly.
    """
    page_id = None
    if main_id:
        found_id, object_type = notion_utils.find_page_or_database_by_id(
            notion, main_id
        )
        if found_id and object_type == "page":
            page_id = found_id

    if not page_id:
        page_id = notion_utils.find_page(notion, "New Online Resume")
    if not page_id:
        print("Error: Page 'New Online Resume' not found.", file=sys.stderr)
        return False

    # Step 1: Verify Skills Development Tracker database exists
    tracker_db_id = notion_utils.find_database_in_block(
        notion, page_id, "Skills Development Tracker"
    )
    if not tracker_db_id:
        print(
            "Error: Database 'Skills Development Tracker' not found.", file=sys.stderr
        )
        return False

    # Step 2: Verify database schema
    try:
        db_info = notion.databases.retrieve(database_id=tracker_db_id)
        properties = db_info.get("properties", {})

        # Check required properties
        required_props = {
            "Name": "title",
            "Current Skill": "relation",
            "Current Proficiency": "rollup",
            "Target Proficiency": "number",
            "Gap": "formula",
            "Learning Resources": "rich_text",
            "Progress Notes": "rich_text",
        }

        for prop_name, expected_type in required_props.items():
            if prop_name not in properties:
                print(
                    f"Error: Property '{prop_name}' not found in database.",
                    file=sys.stderr,
                )
                return False
            if properties[prop_name]["type"] != expected_type:
                print(
                    f"Error: Property '{prop_name}' has incorrect type. Expected '{expected_type}', got '{properties[prop_name]['type']}'.",
                    file=sys.stderr,
                )
                return False

        # Verify Target Proficiency is percent format
        if (
            properties["Target Proficiency"].get("number", {}).get("format")
            != "percent"
        ):
            print(
                "Error: Target Proficiency should have 'percent' format.",
                file=sys.stderr,
            )
            return False

    except Exception as e:
        print(f"Error retrieving database info: {e}", file=sys.stderr)
        return False

    # Step 3: Get Skills database to check entries
    skills_db_id = notion_utils.find_database_in_block(notion, page_id, "Skills")
    if not skills_db_id:
        print("Error: Skills database not found.", file=sys.stderr)
        return False

    # Get all skills with proficiency < 70%
    skills_below_70 = []
    try:
        skills_results = notion.databases.query(database_id=skills_db_id).get(
            "results", []
        )
        for skill in skills_results:
            skill_level = (
                skill.get("properties", {}).get("Skill Level", {}).get("number", 1.0)
            )
            if skill_level < 0.7:
                skill_name = (
                    skill.get("properties", {}).get("Skill", {}).get("title", [])
                )
                if skill_name:
                    skill_name_text = skill_name[0].get("text", {}).get("content", "")
                    skills_below_70.append(
                        {
                            "name": skill_name_text,
                            "id": skill["id"],
                            "level": skill_level,
                        }
                    )
    except Exception as e:
        print(f"Error querying Skills database: {e}", file=sys.stderr)
        return False

    if not skills_below_70:
        print("Warning: No skills found with proficiency below 70%.", file=sys.stderr)
        # This might be OK if all skills are above 70%

    # Step 4: Verify entries in Skills Development Tracker
    try:
        tracker_results = notion.databases.query(database_id=tracker_db_id).get(
            "results", []
        )

        # Check that we have entries for skills below 70%
        if len(skills_below_70) > 0 and len(tracker_results) == 0:
            print(
                "Error: No entries found in Skills Development Tracker database.",
                file=sys.stderr,
            )
            return False

        # Verify each entry
        for entry in tracker_results:
            props = entry.get("properties", {})

            # Check name format
            name_prop = props.get("Name", {}).get("title", [])
            if not name_prop:
                print("Error: Entry missing Name property.", file=sys.stderr)
                return False
            name_text = name_prop[0].get("text", {}).get("content", "")
            if not name_text.endswith(" Development Plan"):
                print(
                    f"Error: Entry name '{name_text}' doesn't follow expected format.",
                    file=sys.stderr,
                )
                return False

            # Check relation to Skills database
            skill_relation = props.get("Current Skill", {}).get("relation", [])
            if not skill_relation:
                print(
                    f"Error: Entry '{name_text}' missing Current Skill relation.",
                    file=sys.stderr,
                )
                return False

            # Check Target Proficiency (should be set)
            target_prof = props.get("Target Proficiency", {}).get("number")
            if target_prof is None:
                print(
                    f"Error: Entry '{name_text}' missing Target Proficiency.",
                    file=sys.stderr,
                )
                return False

            # Check Learning Resources
            learning_resources = props.get("Learning Resources", {}).get(
                "rich_text", []
            )
            if not learning_resources:
                print(
                    f"Error: Entry '{name_text}' missing Learning Resources.",
                    file=sys.stderr,
                )
                return False

            # Check Progress Notes
            progress_notes = props.get("Progress Notes", {}).get("rich_text", [])
            if not progress_notes:
                print(
                    f"Error: Entry '{name_text}' missing Progress Notes.",
                    file=sys.stderr,
                )
                return False

    except Exception as e:
        print(f"Error querying Skills Development Tracker: {e}", file=sys.stderr)
        return False

    # Step 5: Verify callout block exists after Skills section
    all_blocks = notion_utils.get_all_blocks_recursively(notion, page_id)

    # Find Skills database block
    skills_db_block_index = None
    for i, block in enumerate(all_blocks):
        if (
            block.get("type") == "child_database"
            and block.get("child_database", {}).get("title") == "Skills"
        ):
            skills_db_block_index = i
            break

    if skills_db_block_index is None:
        print("Error: Could not find Skills database block.", file=sys.stderr)
        return False

    # Look for callout block after Skills database
    callout_found = False
    block = all_blocks[skills_db_block_index + 1]
    if block.get("type") == "callout":
        callout_data = block.get("callout", {})

        # Check background color
        if callout_data.get("color") != "blue_background":
            print("Error: Could not find callout block with blue background.")
            return False

        # Check icon
        icon = callout_data.get("icon", {})
        if icon.get("type") != "emoji" or icon.get("emoji") != "🎯":
            print("Error: Could not find callout block with 🎯 emoji.")
            return False

        # Check content starts with "Focus Areas:"
        rich_text = callout_data.get("rich_text", [])
        if rich_text:
            content = rich_text[0].get("text", {}).get("content", "")
            if (
                content.startswith("Focus Areas:")
                and "CSS + Basic JS" in content
                and "Webflow" in content
                and "Rive" in content
            ):
                callout_found = True
                print(f"Success: Found callout block with content: {content}")
            else:
                print("Error: Could not find callout block with required text content.")
                return False

    if not callout_found:
        print(
            "Error: Could not find callout block with Focus Areas after Skills section.",
            file=sys.stderr,
        )
        return False

    print(
        "Success: Skills Development Tracker database and callout block verified successfully."
    )
    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()