a small build system with a focus on speed
This report summarizes scanner evidence for ninja-build/ninja, a C++ project with 13,297 GitHub stars. SynthScan examined 12,206 lines of code across 79 source files, recording 161 pattern matches distributed across 11 syntactic categories. The legacy adjusted pattern signal is 16.6 (Elevated pattern signal); it is not an authorship estimate.
Use the findings to ask whether maintainers can explain intent, verify dependencies, simplify unnecessary scaffolding, and focus review effort. Risk Payload v1 adds ownership, supply-chain, over-engineering, and review-effort vectors when available. These are prompts for human verification, not probabilities, security findings, or measured maintenance costs.
Use each vector to guide manual verification of the underlying findings.
Can maintainers explain intent, assumptions, and trade-offs? 144 finding(s).
Are imports declared and package/API names verified? 9 finding(s).
Are wrappers, guards, and repeated structures necessary? 49 finding(s).
Which changes need focused human review? 161 finding(s).
This chart tracks the legacy adjusted pattern score across scan runs. Changes can reflect source changes, scan coverage, or detector/scoring versions; they do not measure AI adoption or prove that a team refactored code. Compare runs only when their scoring versions are compatible. The dashed line tracks the raw pattern-hit count.
Groups findings by configured severity weight. Severity is not a confidence estimate, security rating, or proof that a package is missing. Verify imports against the project's manifests and inspect each finding in its local design context.
This horizontal bar chart shows where configured pattern scores accumulate across directories. Treat the bars as locations to inspect, not as evidence of authorship or code quality. Use the file-level findings to decide whether a directory needs a focused ownership, dependency, complexity, or review check.
The scanner identified 161 distinct pattern matches across 11 syntactic categories. Each entry below represents a discrete location in the source code where the engine recorded a detector match to inspect in context. Expand any category row to inspect the individual file paths, line numbers, code snippets, and the lexical context (CODE, COMMENT, or STRING) in which each match was detected.
Reading the findings table: The Severity column indicates the configured finding weight (CRITICAL / HIGH / MEDIUM / LOW). The Context column identifies whether the match occurred inside executable code, an inline comment, or a string literal — legacy comment-context matches receive a ×1.5 score weight. The ⚡ bolt icon marks clustered matches: three or more patterns within a 10-line window, each receiving an additional ×1.5 density multiplier under the legacy scoring model.
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | configure.py | 1 | #!/usr/bin/env python3 | COMMENT |
| LOW | misc/ninja_syntax_test.py | 1 | #!/usr/bin/env python3 | COMMENT |
| LOW | misc/measure.py | 1 | #!/usr/bin/env python3 | COMMENT |
| LOW | misc/jobserver_test.py | 1 | #!/usr/bin/env python3 | COMMENT |
| LOW | misc/ninja_syntax.py | 1 | #!/usr/bin/python | COMMENT |
| LOW | misc/jobserver_test_helper.py | 1 | #!/usr/bin/env python3 | COMMENT |
| LOW | misc/jobserver_pool.py | 1 | #!/usr/bin/env python3 | COMMENT |
| LOW | misc/jobserver_pool.py | 41 | # | COMMENT |
| LOW | misc/output_test.py | 21 | default_env.pop('NINJA_STATUS', None) | COMMENT |
| LOW | misc/output_test.py | 41 | # [ '\r', 'FOO\x1b[K\r', 'BAR\x1b[K\r', 'ZOO\x1b[K\r\n' ] | COMMENT |
| LOW | misc/oss-fuzz/build.sh | 1 | #!/bin/bash -eu | COMMENT |
| LOW | src/browse.py | 1 | #!/usr/bin/env python3 | COMMENT |
| LOW | src/browse.py | 41 | except ImportError: | COMMENT |
| LOW | src/edit_distance.h | 1 | // Copyright 2011 Google Inc. All Rights Reserved. | COMMENT |
| LOW | src/graphviz.h | 1 | // Copyright 2011 Google Inc. All Rights Reserved. | COMMENT |
| LOW | src/manifest_parser.h | 1 | // Copyright 2011 Google Inc. All Rights Reserved. | COMMENT |
| LOW | src/version.h | 1 | // Copyright 2013 Google Inc. All Rights Reserved. | COMMENT |
| LOW | src/status.h | 1 | // Copyright 2016 Google Inc. All Rights Reserved. | COMMENT |
| LOW | src/jobserver_pool.h | 1 | // Copyright 2025 Google Inc. All Rights Reserved. | COMMENT |
| LOW | src/jobserver_pool.h | 21 | COMMENT | |
| LOW | src/build_log.h | 1 | // Copyright 2011 Google Inc. All Rights Reserved. | COMMENT |
| LOW | src/build_log.h | 21 | #include <string> | COMMENT |
| LOW | src/hash_map.h | 1 | // Copyright 2011 Google Inc. All Rights Reserved. | COMMENT |
| LOW | src/dyndep_parser.h | 1 | // Copyright 2015 Google Inc. All Rights Reserved. | COMMENT |
| LOW | src/includes_normalize.h | 1 | // Copyright 2012 Google Inc. All Rights Reserved. | COMMENT |
| LOW | src/clean.h | 1 | // Copyright 2011 Google Inc. All Rights Reserved. | COMMENT |
| LOW | src/clean.h | 41 | int CleanTarget(const char* target); | COMMENT |
| LOW | src/dyndep.h | 1 | // Copyright 2015 Google Inc. All Rights Reserved. | COMMENT |
| LOW | src/exit_status.h | 1 | // Copyright 2011 Google Inc. All Rights Reserved. | COMMENT |
| LOW | src/build.h | 1 | // Copyright 2011 Google Inc. All Rights Reserved. | COMMENT |
| LOW | src/build.h | 121 | /// Update plan with knowledge that the given node is up to date. | COMMENT |
| LOW | src/parser.h | 1 | // Copyright 2018 Google Inc. All Rights Reserved. | COMMENT |
| LOW | src/clparser.h | 1 | // Copyright 2015 Google Inc. All Rights Reserved. | COMMENT |
| LOW | src/clparser.h | 21 | /// Visual Studio's cl.exe requires some massaging to work with Ninja; | COMMENT |
| LOW | src/command_collector.h | 1 | // Copyright 2024 Google Inc. All Rights Reserved. | COMMENT |
| LOW | src/command_collector.h | 21 | COMMENT | |
| LOW | src/depfile_parser.h | 1 | // Copyright 2011 Google Inc. All Rights Reserved. | COMMENT |
| LOW | src/build_result.h | 1 | // Copyright 2026 Google Inc. All Rights Reserved. | COMMENT |
| LOW | src/elide_middle.h | 1 | // Copyright 2024 Google Inc. All Rights Reserved. | COMMENT |
| LOW | src/elide_middle.h | 21 | /// Elide the given string @a str with '...' in the middle if the length | COMMENT |
| LOW | src/test.h | 1 | // Copyright 2011 Google Inc. All Rights Reserved. | COMMENT |
| LOW | src/inline.sh | 1 | #!/bin/sh | COMMENT |
| LOW | src/missing_deps.h | 1 | // Copyright 2019 Google Inc. All Rights Reserved. | COMMENT |
| LOW | src/string_piece.h | 1 | // Copyright 2011 Google Inc. All Rights Reserved. | COMMENT |
| LOW | src/eval_env.h | 1 | // Copyright 2011 Google Inc. All Rights Reserved. | COMMENT |
| LOW | src/graph.h | 1 | // Copyright 2011 Google Inc. All Rights Reserved. | COMMENT |
| LOW | src/graph.h | 481 | /// from the result, but are followed by the dependency walk. | COMMENT |
| LOW | src/status_printer.h | 1 | // Copyright 2016 Google Inc. All Rights Reserved. | COMMENT |
| LOW | src/msvc_helper.h | 1 | // Copyright 2011 Google Inc. All Rights Reserved. | COMMENT |
| LOW | src/deps_log.h | 1 | // Copyright 2012 Google Inc. All Rights Reserved. | COMMENT |
| LOW | src/deps_log.h | 21 | #include <stdio.h> | COMMENT |
| LOW | src/deps_log.h | 41 | /// help guide the design space. The total text in the files sums to | COMMENT |
| LOW | src/gen_doxygen_mainpage.sh | 1 | #!/bin/sh | COMMENT |
| LOW | src/string_piece_util.h | 1 | // Copyright 2017 Google Inc. All Rights Reserved. | COMMENT |
| LOW | src/json.h | 1 | // Copyright 2021 Google Inc. All Rights Reserved. | COMMENT |
| LOW | src/load_status.h | 1 | // Copyright 2019 Google Inc. All Rights Reserved. | COMMENT |
| LOW | src/util.h | 1 | // Copyright 2011 Google Inc. All Rights Reserved. | COMMENT |
| LOW | src/util.h | 21 | #include <stdint.h> | COMMENT |
| LOW | src/util.h | 41 | COMMENT | |
| LOW | src/util.h | 101 | /// @return the load average of the machine. A negative value is returned | COMMENT |
| 34 more matches not shown… | ||||
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| HIGH | misc/output_test.py | 175 | command = sleep $delay && echo $out | STRING |
| HIGH⚡ | misc/output_test.py | 363 | command = touch $out && echo "$out: extra" > $depfile | CODE |
| HIGH⚡ | misc/output_test.py | 370 | [1/1] touch somewhere/out && echo "somewhere/out: extra" > somewhere_else/out.d | CODE |
| HIGH⚡ | misc/output_test.py | 423 | build out3 : cat out2 out1 | implicit || order_only | CODE |
| HIGH | misc/output_test.py | 635 | build out: touch || dd | CODE |
| HIGH | misc/output_test.py | 687 | build stamp-1: touch || dd-1 | STRING |
| HIGH | misc/output_test.py | 689 | build stamp-2: touch || dd-2 | STRING |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| HIGH | configure.py | 257 | except OSError: | CODE |
| HIGH | configure.py | 384 | except Exception: | CODE |
| HIGH | misc/ci.py | 43 | except UnicodeError: | CODE |
| HIGH | misc/write_fake_manifests.py | 220 | except OSError: | CODE |
| HIGH | misc/write_fake_manifests.py | 161 | except OSError: | CODE |
| HIGH | src/browse.py | 101 | except StopIteration: | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | misc/ninja_syntax_test.py | 55 | def test_short_words_indented(self) -> None: | CODE |
| LOW | misc/ninja_syntax_test.py | 67 | def test_few_long_words_indented(self) -> None: | STRING |
| LOW⚡ | misc/ninja_syntax_test.py | 101 | def test_embedded_dollar_dollar(self) -> None: | STRING |
| LOW⚡ | misc/ninja_syntax_test.py | 110 | def test_two_embedded_dollar_dollars(self) -> None: | STRING |
| LOW⚡ | misc/ninja_syntax_test.py | 119 | def test_leading_dollar_dollar(self) -> None: | STRING |
| LOW⚡ | misc/ninja_syntax_test.py | 128 | def test_trailing_dollar_dollar(self) -> None: | STRING |
| LOW | misc/ninja_syntax_test.py | 146 | def test_leading_ninja_variable_is_kept(self) -> None: | STRING |
| LOW | misc/ninja_syntax_test.py | 158 | def test_escapes_spaces_in_paths(self) -> None: | STRING |
| LOW | misc/ninja_syntax_test.py | 163 | def test_escapes_each_path_in_a_list(self) -> None: | STRING |
| LOW | misc/ninja_syntax_test.py | 196 | def test_dollar_in_build_paths(self) -> None: | STRING |
| LOW | misc/ninja_syntax_test.py | 200 | def test_ninja_variable_prefix_in_build_paths(self) -> None: | STRING |
| LOW | misc/jobserver_test.py | 159 | def generate_double_build_plan( | STRING |
| LOW | misc/jobserver_test.py | 198 | def get_spans_for_multiple_builds(build_dirs: T.List[str], command_counts: T.List[int]) -> T.List[T.Tuple[int, int]]: | STRING |
| LOW | misc/jobserver_test.py | 224 | def compute_max_overlapped_spans(build_dir: str, command_count: int) -> int: | STRING |
| LOW | misc/jobserver_test.py | 333 | def test_jobserver_client_with_posix_fifo(self): | STRING |
| LOW | misc/jobserver_test.py | 337 | def test_jobserver_client_with_posix_pipe(self): | STRING |
| LOW | misc/jobserver_test.py | 352 | def run_ninja_with_jobserver_pipe(args): | STRING |
| LOW | misc/jobserver_test.py | 376 | def test_jobserver_client_with_posix_fifo_token_efficiency(self): | STRING |
| LOW | misc/jobserver_test.py | 455 | def test_jobserver_pool_mode_with_flag(self): | STRING |
| LOW | misc/jobserver_test.py | 517 | def test_jobserver_pool_mode_ignored_with_existing_pool(self): | STRING |
| LOW | misc/jobserver_test.py | 529 | def test_jobserver_pool_mode_with_variable(self): | STRING |
| LOW | misc/ninja_syntax.py | 161 | def _count_dollars_before_index(self, s: str, i: int) -> int: | CODE |
| LOW⚡ | misc/output_test.py | 360 | def test_depfile_directory_creation(self) -> None: | STRING |
| LOW⚡ | misc/output_test.py | 380 | def test_ninja_status_default(self) -> None: | STRING |
| LOW⚡ | misc/output_test.py | 395 | def test_status_flag_without_description(self) -> None: | STRING |
| LOW⚡ | misc/output_test.py | 401 | def test_status_flag_description_placement(self) -> None: | STRING |
| LOW⚡ | misc/output_test.py | 407 | def test_status_flag_unknown_variable(self) -> None: | STRING |
| LOW⚡ | misc/output_test.py | 413 | def test_entering_directory_on_stdout(self) -> None: | STRING |
| LOW | tests/compdb/test_compdb_validation.py | 45 | def test_compdb_excludes_validation_edge(self): | CODE |
| LOW | tests/compdb/test_compdb_validation.py | 63 | def test_compdb_with_rule_filter_excludes_validation(self): | STRING |
| LOW | tests/compdb/test_compdb_validation.py | 79 | def test_compdb_keeps_non_validation_edge(self): | STRING |
| LOW | tests/compdb/test_compdb_validation.py | 97 | def test_compdb_targets_excludes_validation_edge(self): | STRING |
| LOW | tests/compdb/test_compdb_validation.py | 113 | def test_compdb_mixed_validation_and_input(self): | STRING |
| LOW | tests/builddir_target/test_builddir_target.py | 48 | def test_exact_match_takes_priority(self): | CODE |
| LOW | tests/builddir_target/test_builddir_target.py | 75 | def test_no_builddir_no_fallback(self): | CODE |
| LOW | tests/builddir_target/test_builddir_target.py | 89 | def test_fallback_with_subdirectory(self): | CODE |
| LOW | tests/builddir_target/test_builddir_target.py | 105 | def test_fallback_miss_still_errors(self): | CODE |
| LOW | tests/restat/test_restat_builddir.py | 30 | def test_restat_with_builddir(self): | CODE |
| LOW | src/browse.py | 166 | class RequestHandler(httpserver.BaseHTTPRequestHandler): | STRING |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | configure.py | 39 | CODE | |
| LOW | misc/ninja_syntax.py | 170 | CODE | |
| LOW | misc/jobserver_pool_test.py | 24 | CODE | |
| LOW | misc/jobserver_pool.py | 240 | CODE | |
| LOW | src/browse.py | 69 | CODE | |
| LOW | src/browse.py | 134 | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| MEDIUM | tests/restat/test_restat_builddir.py | 33 | # Create a simple build.ninja file with builddir | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | configure.py | 384 | except Exception: | CODE |
| LOW | misc/ci.py | 22 | except Exception: | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | misc/ninja_syntax.py | 67 | CODE | |
| LOW | tests/builddir_target/test_builddir_target.py | 30 | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | misc/jobserver_pool_test.py | 10 | CODE | |
| LOW | misc/jobserver_pool.py | 60 | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | misc/jobserver_test.py | 33 | # Set this to True to debug command invocations. | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | misc/ninja_syntax.py | 187 | # No such space; just use the first unescaped space we can find. | COMMENT |