Skip to content

Dogfood round 2: report ${...} parse columns correctly; name JS/Python string equivalents - #261

Merged
b-macker merged 1 commit into
masterfrom
claude/naab-inadmissible-action-prevention-4cmn1m
Sep 28, 2026
Merged

b-macker merged 1 commit into
masterfrom
claude/naab-inadmissible-action-prevention-4cmn1m

Conversation

@b-macker

Copy link
Copy Markdown
Owner

Summary

Two diagnostics fixes from repo-sentinel round 2 (the dogfooding project):

  • Interpolation parse errors (a regression from Literal ${ in strings, one interpolation splitter, errors that teach #258). When a string not on line 1 contains ${...} that isn't valid NAAb, the "Parser said" line printed Parse error at line 2, column 11. The line was the file line, but the column was a position inside ${...}, so the pair pointed nowhere real.
  • string.slice suggested split(). The "did you mean" suggestion is chosen by edit distance, so it picked split. Names people and LLMs commonly reach for from JavaScript and Python now point at the NAAb equivalent, with an example.

Round 2 also confirmed that all six round-1 findings are fixed on the current build (F-001 to F-006).

Changes

  • include/naab/string_interpolation.h: formatInterpolationError rewrites the inner parse position to "at character N of the expression" whatever line it reports.
  • src/stdlib/string_impl.cpp: synonym hints for:
    • slice/substr → substring. The end index is exclusive, like slice.
    • includes → contains.
    • padStart/rjust → pad_left, and padEnd/ljust → pad_right.
    • trimStart/trimEnd/trimLeft/trimRight → trim.
    • replaceAll → replace, which already replaces every occurrence.
    • Each mapping was checked against actual behaviour first.
  • tests/parser/test_dogfood_hints.sh: 7 new checks.

Test Plan

  • test_dogfood_hints.sh passes 17/17.
    • Against the previous build, all 6 new checks fail and the control (S-00, string.substring still works) passes.
    • My first draft of the S checks passed S-01 on the old build, because "substring" also appeared in the old message's "Available:" list. They now match the suggestion text itself.
  • test_string_interp_escape.sh passes 25/25.
  • test_error_msg_leaks.sh passes 874/874.

🤖 Generated with Claude Code

https://claude.ai/code/session_01ELUfjXZvx8kzXo1UJjrAhC


Generated by Claude Code

…n string equivalents

From repo-sentinel round 2.

- Interpolation parse errors (regression from #258): the evaluators shift the
  inner tokens to the string's file line so runtime errors point at the right
  line, which moved the inner parse error off "line 1" -- and the rewrite to
  "character N of the expression" only matched "line 1". Any string not on
  line 1 printed "Parser said: Parse error at line 2, column 11": a file line
  paired with an offset inside ${...}. The rewrite now matches any line.
- string.slice suggested split() (edit distance). slice/substr, includes,
  padStart/padEnd/rjust/ljust, trimStart/trimEnd, replaceAll now name the
  NAAb equivalent with an example. Each mapping checked against behaviour:
  substring's end is exclusive like slice's, replace already replaces all.

tests/parser/test_dogfood_hints.sh: +7 arms (I-01, S-00..S-05). Against the
old binary all 6 non-control arms fail; the first draft of the S arms passed
S-01 on the old build because "substring" also appeared in the old message's
"Available:" list, so they now match the suggestion itself.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ELUfjXZvx8kzXo1UJjrAhC
@github-actions

Copy link
Copy Markdown

NAAb Governance Report

Metric Count
Files checked 16
Passed 16
Failed 0

All governance checks passed!

Generated by NAAb Governance Engine v4.0

@b-macker
b-macker marked this pull request as ready for review September 28, 2026 09:29
@b-macker
b-macker merged commit 9b31c89 into master Sep 28, 2026
23 checks passed
@b-macker
b-macker deleted the claude/naab-inadmissible-action-prevention-4cmn1m branch September 28, 2026 09:29
b-macker added a commit that referenced this pull request Sep 28, 2026
…de passed through process.run (#262)

* One implementation of string slice/substring/replace; fix a tree-walker hang

Dogfood round 3 reported string.slice "not fixed" (it ran a build without
#261), but checking it found that s.slice(...) worked as a METHOD while
string.slice(...) did not exist -- and that the method forms disagreed
between engines. Four copies (VM method dispatch, two tree-walker method
paths, the string module); measured on "hello" / "a-b-c":

  s.replace("-", "+")   VM a+b-c (first only)   tree-walker a+b+c
  s.substring(3, 1)     VM ""                   tree-walker "lo" (wrapped size_t)
  s.slice(-3)           VM llo                  tree-walker hello (aliased to substring)

and "ab".replace("", "+") hung the tree-walker: find("") matches at every
position, so it inserted forever with growing memory. --timeout cannot stop
it (the loop never returns to the interpreter), and the REST API runs the
tree-walker. The VM gave "+ab".

The module functions agreed with each other in every case, so they are the
reference: include/naab/string_ops.h holds substring, slice (JavaScript
semantics) and replaceAll (empty pattern = unchanged), and all four sites
call it. string.slice(s, start[, end]) is added as a module function.

Tests: tests/differential/corpus/string_methods.naab (the corpus only had
module-form string probes, which is why none of this surfaced) and
test_dogfood_hints.sh S-06 (string.slice) and E-01 (the hang, both engines,
10s limit). Against the previous build S-06 and E-01 fail in both engines,
E-01/tree-walk by being killed at 10s.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ELUfjXZvx8kzXo1UJjrAhC

* Check inline interpreter code passed through process.run

process.run("python3", ["-c", code]) is a <<python>> block by another name,
but it skipped every code check the block and codegen.run() get. Found
dogfooding repo-sentinel: a size helper that swallowed every error
(`except Exception: return 0`) and reported every C++ file as 0 bytes. The
project's own no_incomplete_logic (HARD) blocks that code as a block and in
codegen.run(); through process.run it ran silently.

process.run now recognises python/pypy -c, node -e/-p/--eval/--print,
ruby -e, perl -e/-E, php -r and sh/bash/dash/zsh/ksh -c (through a directory
prefix, .exe, a version suffix, and clustered short flags) and passes the
code to checkPolyglotBlock(). A script file is not inline code and is not
scanned; only the outer interpreter is recognised.

Test: tests/security/test_process_run_inline_gate.sh, 14/14 on both engines;
the prior build fails exactly PI-01 and PI-03 on each. The python -c and
sh -c calls in living-script{,_v2,_extended} and hivemind{,_governed} run
unchanged under their own configs on both builds.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ELUfjXZvx8kzXo1UJjrAhC

* Register test_process_run_inline_gate.sh in run-all-tests.sh

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ELUfjXZvx8kzXo1UJjrAhC

---------

Co-authored-by: Claude <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants