Skip to main content
Wecode integrates with Moss (Measure of Software Similarity) to detect code plagiarism and measure similarity between submissions.

What is Moss?

Moss is a service developed by Stanford University that compares program source code files to identify similar code segments. It’s language-independent and can detect similarities even when code has been modified.

Configuration

Before using Moss, you need to configure your Moss User ID:
  1. Navigate to the Moss page for any assignment: /moss/{assignment_id}
  2. Enter your Moss User ID in the configuration form
  3. Click “Update” to save the configuration
You need to register for a free Moss account to obtain a User ID. Visit Stanford Moss to request an account.
The configuration updates the moss script with your user ID:
$moss_original = trim( file_get_contents(rtrim(Setting::get('tester_path'), '/').'/moss_original') );
$moss_path = rtrim(Setting::get('tester_path'), '/').'/moss';
file_put_contents($moss_path, str_replace('MOSS_USER_ID', $userid, $moss_original));

Running Detection

To run plagiarism detection on an assignment:
  1. Go to /moss/{assignment_id}
  2. Click the “Detect” button
  3. Wait for Moss to process the submissions

Detection Process

The detection process:
moss_controller.php:76
private function _detect($assignment_id = FALSE)
{
    if ($assignment_id === FALSE)
        abort(404);

    $lang = Language::all();

    $assignments_path = rtrim(Setting::get('assignments_root'), '/');
    $tester_path = rtrim(Setting::get('tester_path'), '/');
    shell_exec("chmod +x {$tester_path}/moss");
    $items = Submission::get_final_submissions($assignment_id);
    $groups = array();
    foreach ($items as $item) {
        if (!isset($groups[$item->problem_id]))
            $groups[$item->problem_id] = array($item);
        else
            array_push($groups[$item->problem_id], $item);
    }
    foreach ($groups as $problem_id => $group) {
        $list = '';
        $assignment_path = $assignments_path."/assignment_{$assignment_id}";
        foreach ($group as $item){
            $list .= "problem_{$problem_id}/{$item->username}/{$item->file_name}." .(string)Language::find($item->language_id)->extension . " ";
        }

        shell_exec("list='$list'; cd $assignment_path; $tester_path/moss \$list > problem_{$problem_id}/moss_link.txt  2>&1 &");
        shell_exec("cd $assignment_path/problem_{$problem_id}; touch moss_running");

    }
    
    Assignment::where('id', $assignment_id)->update(['moss_update' => date('Y-m-d H:i:s')]);
}

What Happens During Detection

  1. Grouping: Submissions are grouped by problem
  2. File Collection: Final submissions for each user are collected
  3. Moss Execution: The Moss script is run on all submissions for each problem
  4. Background Processing: Detection runs in the background using shell execution
  5. Status Tracking: A moss_running file is created to indicate processing

Viewing Results

After detection completes:

Status Indicators

  • Moss Link: If detection is complete, a URL to the Moss results page is displayed
  • Processing: “submission submitted to moss, awaiting response, please be patience”
  • Not Run: No link displayed if detection hasn’t been run

Result Display Logic

moss_controller.php:37
foreach ($assignment->problems as $key => $problem){
    $moss_problems[$problem->id]['problem'] = $problem;
    $path = Submission::get_path('', $assignment_id, $problem->id) .'/' ;
    if (file_exists($path . "moss_link.txt") && file_get_contents($path . "moss_link.txt") != ''){
        $moss_problems[$problem->id]['moss'] = shell_exec("tail -n1 $path/moss_link.txt");
        shell_exec("rm $path/moss_running");
    } else if (file_exists($path . "moss_running")){
        $moss_problems[$problem->id]['moss'] = "submission submitted to moss, awaiting respone, please be patience";
    } else {
        $moss_problems[$problem->id]['moss'] = NULL;
    }
}

Routes

Available Moss routes:
  • GET /moss/{id} - View Moss page for an assignment
  • POST /moss/update/{id} - Update Moss configuration
  • POST /moss/detect/{id} - Run plagiarism detection

Permissions

Only admins and head instructors can access Moss features. Other users will receive a 403 Forbidden error.

Best Practices

  1. Run After Deadline: Run Moss detection after the assignment deadline when all submissions are in
  2. Per-Problem Analysis: Results are generated separately for each problem in an assignment
  3. Final Submissions Only: Only final (best-scoring) submissions are analyzed
  4. Review Results: Always manually review Moss results - similar code doesn’t always mean plagiarism

Troubleshooting

Moss Not Responding

If the status shows “awaiting response” for a long time:
  1. Check if the moss_running file exists in the problem directory
  2. Check if the Moss service is available
  3. Verify your Moss User ID is correct
  4. Check server logs for errors

Invalid Moss User ID

If detection fails:
  1. Verify you’ve registered for a Moss account
  2. Check that your User ID is correctly entered
  3. Ensure the moss script has execute permissions

Build docs developers (and LLMs) love