Project Scoping

Course Schedule

"Plans are worthless, but planning is everything."
-- Dwight D. Eisenhower


For bullet-point highlights of the spec, see the lecture slides.

NOTE: the spec remains the single source of truth: in case of any discrepancies between the slides and the spec, please follow what is written in the spec.

Using EGM to Scope Project

When interacting with the LLM, always stress to the LLM that it must generate NO CODE and must use PLAIN ENGLISH, minimal jargon. Make this prompt from Dave Rensin’s Elephant-Goldfish Model article part of your task description:

“I do not want you to create code. We are not going to create code. Resist your impulse to create code. Instead, we are going to have a design discussion. I am about to describe a feature. I want you to ask me clarifying questions and challenge my assumptions. Do not just accept what I say”.

Rensin, Elephants, Goldfish and the New Golden Age of Software Engineering, Medium, Apr. 27, 2026.

Notes:

Phase 1: Stakeholder Discovery & Requirement Gathering (Peanuts and Hay)

Elephant: Feed the Elephant the stakeholder interview transcripts or videos, the final proposal summary, and the project proposal slide deck. Ask the Elephant to list all pain points mentioned in the interviews that are related to the value proposition identified in the project proposal slide deck, in order of frequency and importance, to create [Exhibit E-A]. Additionally, ask it to list all features related to the value proposition the interviewees desire, in order of preference, to create [Exhibit E-B].

Goldfish 1: Feed Goldfish 1 the same three input documents. Instruct it to act as a senior product manager and review Exhibits E-A and E-B to provide critiques on the identifications of pain points and desires related to the value proposition, generating [Exhibits G-A and G-B]. If these critiques are substantial, feed them back to the original Elephant for another iteration. Repeat this process, using a new Goldfish for each cycle, until the critiques are minor, resulting in [updated Exhibits E-A and E-B].

Growing the Elephant and the Goldfish Protocol:

Elephant: Provide the updated Exhibits E-A and E-B, along with the three levels of functionality from your slide deck, to the Elephant. Ask it to generate mobile app ideas that use deeply embedded AI to address all listed pain points and provide all benefits related to the value prosition, satisfying the functional levels, which becomes [Exhibit E-C]. Follow Rensin’s advice to engage in a back-and-forth conversation, arguing with the AI and having it interrogate your assumptions. “Simply asking the AI, ‘Why do you think that?’ is your best friend.” Every time the AI starts being sycophantic, tell it, “You are not being helpful. Your highest and best use is to challenge my thinking.”

Goldfish 2: Ask a new Goldfish, acting as a staff software engineer, to review Exhibits E-A, E-B, and E-C, and to explain what Exhibit E-C is trying to accomplish. If it cannot explain the project based solely on these documents, add the missing context to Exhibit E-C and repeat the process to protect against low-quality output. This yields an [updated Exhibit E-C].

Goldfish 3: Ask another Goldfish to act as a senior product manager and critique Exhibit E-C, producing [Exhibit G-C]. Pass this critique back to the Elephant for revision, repeating with a new Goldfish each time until the feedback is minor. This establishes the final list of features as [Exhibit E-D].

Phase 2: Sizing the Elephant (Algorithmic Scoping)

To maintain a reasonable scope, we size the project by measuring architectural friction. We map stakeholder demands to structural system components using graph theory.

Definitions

Elephant (Data Extraction):

Provide the Elephant with the updated Exhibits E-A through E-D. Instruct it to act as a deterministic data parser using the provided definitions and execute the following steps:

  1. Group the pain points from Exhibit E-A into isolated, start-to-finish user workflows (Story Arcs).
  2. Assign the Story Arc addressing the most frequent pain point a weight of 100, and scale the remaining arcs from 1 to 99 based on their rank in Exhibit E-A.
  3. Identify the absolute minimum set of Rigorous Features (excluding standard CRUD operations and UI screens) required for each Story Arc.

Instruct the Elephant to output the results solely as a Python dictionary formatted as {"Arc Name": {"weight": 85, "features": {"node1", "node2"}}} without any additional conversational text or mathematical analysis.

The Python Sandbox (Execution):

Copy the dictionary output from the Elephant into the Python script below, set your target capacity, and run it.

# algorithmic_scoping.py

# --- Configuration ---  
# Target Capacity (T): The ideal number of rigorous features.   
# Set between 3 and 5 depending on your team size and backend tech stack.  
TARGET_CAPACITY = 3  

# Copy the Python dictionary output generated by the Elephant  
# and paste it exactly here, replacing the empty dictionary.  
arcs = {  
    # Paste LLM output here. Required format:  
    # "Story Arc name": {"weight": 85, "features": {"pivotal_node_X", "rigorous_feature_5"}},  
}

''' Example:  
arcs = {  
    "Arc A: Patient Intake Workflow": {  
        "weight": 85,   
        "features": {"auth_state", "camera_api", "db_patient_join"}  
    },  
    "Arc B: Quick Vitals Sync": {  
        "weight": 40,   
        "features": {"bluetooth_stream", "db_patient_join"}  
    },  
    "Arc C: Multi-Provider Chat": {  
        "weight": 95,   
        "features": {"websocket_async", "auth_state", "push_notifications", "db_chat"}  
    },  
    "Arc D: Export Lab Report": {  
        "weight": 60,   
        "features": {"pdf_transform", "email_api", "db_patient_join"}  
    }  
}  
'''

print(f"Target Capacity (T): {TARGET_CAPACITY} Rigorous Features\n")

if not arcs:  
    print("Error: You must populate the 'arcs' dictionary with the Elephant's output.")  
    exit()

# --- Step 1: Constraint Optimization ---  
scored_arcs = {}  
for name, data in arcs.items():  
    W = data["weight"]  
    R = len(data["features"])  
    score = W / (1 + abs(R - TARGET_CAPACITY)) # Target-Proximity Penalty  
    scored_arcs[name] = {"score": score, "weight": W, "features": set(data["features"])}

# Sort descending by score to generate the Top 3 Base Scopes  
sorted_arcs = sorted(scored_arcs.items(), key=lambda item: item[1]["score"], reverse=True)  
top_3_bases = sorted_arcs[:3]

print("=== Top 3 Base Scopes ===")  
for name, data in top_3_bases:  
    print(f"- {name}: Score {data['score']:.1f} (Weight {data['weight']}, Nodes: {len(data['features'])})")  
    print(f"  Features: {data['features']}n")

# --- Step 2: Greedy Expansion (Pivotal Node Analysis / Bipartite Projection) ---  
# Generate stretch goals using the Greedy Approximation Algorithm for the Weighted Maximum Coverage Problem  
print("=== STRETCH GOAL EXPANSIONS ===")  
for base_name, base_data in top_3_bases:  
    """  
    For each of the top three base arcs, calculate the missing Pivotal delta of all remaining unselected Story Arcs.   
    When evaluating stretch goals for a specific base arch, explicitly include the other two top base arcs in the candidate pool.  
    """  
    print(f"\nEvaluating expansions for: [{base_name}]")  
      
    # --- Stretch Goal 1 ---  
    base_features = set(base_data["features"])  
    remaining_arcs = {k: v for k, v in arcs.items() if k != base_name}  
      
    best_sg1_name = None  
    best_sg1_metric = -1  
    best_sg1_new_features = set()

    # Treat the project as a bipartite graph connecting Story Arcs to Pivotal Nodes.  
    for name, data in remaining_arcs.items():  
        # Perform a local bipartite projection to find the nearest neighbor.  
        new_features = set(data["features"]) - base_features  
        cost = len(new_features)  
          
        # Maximize new value, minimize net-new required features.  
        # Add 0.1 to cost to prevent division by zero if features are fully shared.  
        leverage_metric = data["weight"] / (cost + 0.1)   
          
        if leverage_metric > best_sg1_metric:  
            best_sg1_metric = leverage_metric  
            best_sg1_name = name  
            best_sg1_new_features = new_features

    if best_sg1_name:  
        print(f"  Stretch Goal 1: {best_sg1_name}")  
        if len(best_sg1_new_features) == 0:  
            print("    Cost: 0 net-new nodes (100% architectural overlap)")  
        else:  
            print(f"    Cost: {len(best_sg1_new_features)} net-new nodes -> {best_sg1_new_features}")

        # --- Stretch Goal 2 ---  
        # Repeat the greedy expansion, assuming Stretch Goal 1's nodes are integrated.  
        updated_base_features = base_features | best_sg1_new_features  
        remaining_arcs_sg2 = {k: v for k, v in remaining_arcs.items() if k != best_sg1_name}

        best_sg2_name = None  
        best_sg2_metric = -1  
        best_sg2_new_features = set()

        for name, data in remaining_arcs_sg2.items():  
            new_features = set(data["features"]) - updated_base_features  
            cost = len(new_features)  
            leverage_metric = data["weight"] / (cost + 0.1)

            if leverage_metric > best_sg2_metric:  
                best_sg2_metric = leverage_metric  
                best_sg2_name = name  
                best_sg2_new_features = new_features

        if best_sg2_name:  
            print(f"  Stretch Goal 2: {best_sg2_name}")  
            if len(best_sg2_new_features) == 0:  
                print("    Cost: 0 net-new nodes (100% architectural overlap with Base + SG1)")  
            else:  
                print(f"    Cost: {len(best_sg2_new_features)} net-new nodes -> {best_sg2_new_features}")

Once you have inserted your Story Arcs to the arcs variable in the script above, run it with:

laptop$ python algorithmic_scoping.py

Phase 3: Goldfish Verification (Architectural Review)

Goldfish 4 (Base Scope Verification):
Take the output of the Python script to use as [Exhibit E-E]. Provide this to a Goldfish acting as a senior systems architect. Ask it to evaluate the Pivotal Node classifications for the top three arcs, ensuring they meet the definition of Rigorous Features rather than basic CRUD operations. Have it identify if any required nodes or external dependencies were missed, generating [Exhibit G-D]. Return this feedback to the Elephant, re-running the script as needed until the components are structurally sound, yielding an [updated Exhibit E-E].

Goldfish 5 (Expansion Verification):
Take the stretch goal expansions from the Python script, representing [Exhibit E-F] (Stretch Goal 1) and [Exhibit E-G] (Stretch Goal 2). Ask a Goldfish acting as a lead engineering manager to review the architectural leverage of these expansions and check if Stretch Goal 1 and 2 introduce cascading failure risks to the base scope’s state management, generating [Exhibit G-E]. Iterate with the Elephant until you settle on a safe expansion pathway to [finalize Exhibits E-F and E-G].

Phase 4: Team Pitch (In-Person Selection)

You now possess three optimized project scopes with clear expansion pathways. Review the updated Exhibit E-E with your team and select a base scope to build. During the in-person meeting, you will pitch this choice, defending it using the validated architectural nodes and stakeholder value data. If your chosen base scope is still too light, we will consider having you build one of its stretch goals instead.

Next time, we’ll continue the process to use the Elephant-Goldfish model to create your Story Map.

What to Submit

Submit to Canvas a single file named EGMScoping.pdf containing:

  1. Your Top 3 Base Scopes and the two Stretch Goals of each: the full Exhibits E-E, E-F, E-G. We will use these in the 1-1 Team Pitch.
  2. A one-page audit table (structured with columns for Exhibit Name, Key Criticisms Identified, Adjustment Made, and Final Outcome).
  3. A one-page summary of each Exhibit, from E-A to E-G and G-A to G-E, so a total of 14 pages, placed in interleaved chronological order.

Prepared by Sugih Jamin Last updated: September 27th, 2026

Acknowledgments: I have used Gemini 3.1 Pro and 3.6+ to prepare this document. All structural concepts, technical details, and final editorial decisions remain entirely my responsibility. I thank Dave Rensin for his careful read of the document and suggestions that improve both the process and the student experience.