Hedronite Lesson · Polyglot-Dev / V · Thu 2026-10-08 · V row #8 (Duha 3 of 4)

Make one local change to V 0.5.2: a termios doc typo, ./vnew, the covering tests, and a PR draft · Copy the Tree · Find Every Copy · Test What Covers It · Draft, Do Not Open

Copy the tree. Find every copy. Test what covers it. Draft, do not open.

Lesson Class: Duha (V dual-seat · learn-first · contributor-aware · watch-not-adopt)
Focus: Copy the Tree · Find Every Copy · Test What Covers It · Draft, Do Not Open
Done-criteria: one tiny local edit (11 platform files, one word); fmt -verify; covering tests run; PR title + body drafted; nothing opened upstream
Grounding: vlang/v 0.5.2 (7647ce1) CONTRIBUTING + AGENTS.md + TESTS.md + vlib/term/termios; live duplicate check labelled as live
Note: Lab Mac, macOS 27.0.1 arm64 · ./vnew 4.89 s · termios 1 passed · vlib/term 8 passed · branch fix_termios_dependent_typo · push disabled · V_C_ERROR_BUG_REPORT_DISABLED=1 · Nix Beat B skipped · late fire
Find Every Copy
One doc line, eleven platform files. Fix all of them or name the ones you leave.
Test What Covers It
Nearest test, then vlib/term. Without a tty the termios test compares zeros.
Draft, Do Not Open
module: change commit, behavior change none, tests run, paths. Push URLs dead; no fork.
Copy the tree. Find every copy. Test what covers it. Draft, do not open.

Copy the tree. Find every copy. Test what covers it. Draft, do not open.

§I. Frame

Duha V session 3 of 4 (syllabus row #8), Thu 2026-10-08. Learn-first, contributor-aware, watch-not-adopt. Yesterday read the ladder and named step 2, a doc fix, as the cheapest first PR. Today makes one: a single wrong word in a public doc comment, fixed on a local branch, formatted, tested, committed, and written up as a PR that nobody opens. Every cite is vlang/v at tag 0.5.2 (commit 7647ce1). Two checks against the live tracker and master are marked as live.

Safety note. V 0.5.2 uploads a report to bugs.vlang.io on every C compile error by default. Each report carries up to 40 V source lines on each side of the failing line, the C context around the error, and the build options. v help build-c documents this; docs.md does not. The lab script's first command is export V_C_ERROR_BUG_REPORT_DISABLED=1, and every V lab does the same.

§II. Four techniques

  1. Copy the Tree. Work in a private copy of the built checkout. Yesterday's build stays clean for every other lab.
  2. Find Every Copy. A doc line in a platform module exists once per platform. Grep before you edit, and edit all of them or say why not.
  3. Test What Covers It. Run the nearest test, then one ring out, then read what the test proves.
  4. Draft, Do Not Open. Write the PR title and body the repo asks for, with the push path cut.

§III. The repo's own rules for agents

The 0.5.2 tree carries an AGENTS.md, 726 lines, "Written for AI coding agents; useful for humans too." It sharpens CONTRIBUTING in three places that matter today.

That table chose the change. If the typo sits in builtin, then the rules ask for a compiler rebuild before any test; thus a first PR goes to a leaf module.

§IV. Pick the change

A grep of vlib doc comments for common misspellings turned up retuns in builtin (core) and platform dependant in term.termios. "Dependant" is the noun, a person who depends on someone; the adjective is "dependent". The termios line sits on pub fn invert, so v doc prints it.

Find Every Copy (named technique). The grep found the same sentence in eleven files, one per platform: android, darwin, default, dragonfly, freebsd, linux, netbsd, openbsd, qnx, solaris, windows. The compiler picks one file per OS, so fixing only termios_darwin.c.v would fix the docs on a Mac and nowhere else. Two more hits stay out of scope and the PR says so: vlib/builtin/utf8.c.v:21 (core module, own commit) and vlib/v2_toberemoved/types/types.v:474 (slated for removal).

Before writing anything, two live checks (2026-10-08 11:32 ET, read-only): master still has the typo in termios_darwin.c.v, and a GitHub search of vlang/v issues and PRs for "dependant" returns 11 results, none about termios.

§V. Branch, edit, format

Copy the Tree (named technique). The lab copied the Duha #6 build (~/src/vlang-duha6/v, 180 MB with ./v, vc, and thirdparty/) to ~/src/vlang-duha8/v. V finds vlib beside its own binary, so the copy's ./v compiles the copy's vlib. Then:

  1. Both remotes (origin and V_REPO) point at https://github.com/vlang/v. Their push URLs were set to no-push://disabled-for-lesson. There is no pullrequest remote.
  2. ./v -o ./vnew cmd/v took real 4.89 s. ./vnew version printed V 0.5.2 7647ce1. /vnew is in .gitignore.
  3. git switch -c fix_termios_dependent_typo, the branch-name style of CONTRIBUTING step 5 (fix_alabala).
  4. One sed across the eleven files. git diff --stat: 11 files, 11 insertions, 11 deletions.
  5. ./vnew fmt -verify on each touched file: exit 0, eleven times. No Markdown changed, so v check-md had nothing to check.

§VI. Test What Covers It

Test What Covers It (named technique). The module has one test file, termios_test.c.v.

RunResult
./vnew test vlib/term/termios/, over ssh (fd 0 not a tty)1 passed, exit 0
same, under a pty via script -q /dev/null1 passed, exit 0
VTEST_HIDE_OK=1 ./vnew test vlib/term/8 passed, 8 total, real 0.71 s
./vnew doc -comments term.termios"invert is a platform dependent way to bitwise NOT (~) TcFlag ..."

Read the test before trusting the green. test_termios calls tcgetattr(0, ...) and tcsetattr(0, ...) and never checks a return code. A small probe (lab/probe/probe.v) printed what fd 0 gives, first over plain ssh, then under the pty:

tcgetattr(0) returned -1, c_lflag=0
tcgetattr(0) returned 0, c_lflag=1483

Without a terminal every call fails, every struct stays zero, and each assert compares zero with zero. The test passes either way, and it proves something only under a pty. That does not touch today's change (a comment), but it tells you which green to believe when the change is code.

Reading the module turned up one more thing. set_state(fd int, new_state Termios) ends in tcsetattr(0, C.TCSANOW, mut x): the fd argument is never used. It is the same on master, and a search for "termios set_state" finds no issue. It is a candidate for a reproduce-and-report issue (ladder step 5), not for this PR.

v test-all was not run. TESTS.md asks for it before a PR, AGENTS.md says to ask first, and its last step installs a module from the network. The PR body says so, in the "Not run" form AGENTS.md asks for.

§VII. Draft, Do Not Open

Draft, Do Not Open (named technique). The commit follows the CONTRIBUTING example's module: change form (math: add a new function copysign):

e7f7582 term.termios: fix 'dependant' typo in the invert() doc comment

It was committed with a lab identity (lab@the lab Mac.local) and exported as lab/0001-term.termios-fix-dependant-typo.patch. The full PR text is in PR-DRAFT.md beside this lesson. Its shape:

The real workflow continues with CONTRIBUTING step 6, git push pullrequest, and step 7, the web UI. This lesson stops before step 6. A real PR would also rebase on master first, because the checkout is the depth-1 tag commit.

§VIII. Lab

  1. Export V_C_ERROR_BUG_REPORT_DISABLED=1. Copy the 0.5.2 build; set both push URLs to a dead value; build ./vnew.
  2. Grep for platform dependant; count the termios files (11).
  3. Branch, edit, git diff --stat, fmt -verify each file.
  4. v test vlib/term/termios/ with and without a pty; build and run the probe both ways; v test vlib/term/.
  5. v doc -comments term.termios; commit on the branch; git format-patch -1.
  6. Confirm the Duha #6 checkout still shows 0 status lines.

Evidence: lab/lab.sh, lab/lab.log, lab/0001-term.termios-fix-dependant-typo.patch, lab/probe/probe.v, lab/upstream-check-2026-10-08.log, and PR-DRAFT.md.

§IX. Common mistakes

  1. Fixing the file for your own OS and missing the other ten.
  2. Running ./v self or rebuilding over ./v. AGENTS.md says build ./vnew.
  3. Taking a green termios run over ssh as proof. Without a tty the test compares zeros.
  4. Editing the shared build that other labs use instead of a copy.
  5. Leaving a push URL live in a lesson checkout.
  6. Running V labs without V_C_ERROR_BUG_REPORT_DISABLED=1.

§X. Contributor-path takeaway

A first PR is small on purpose. Pick a leaf module so the decision table asks for one test file, grep for every copy, and let fmt -verify and the nearest test speak before you write a word of the body. Then read the test you leaned on: today it passed without a terminal and checked nothing. Write the body in the repo's own format (behavior change, tests run, paths) and keep the push for a fork you own.

This is learn-first contributor practice. It is not Hedronite product adoption. Nothing was pushed, no fork exists, and no upstream issue or PR was opened.

Related: ·

Copy the tree. Find every copy. Test what covers it. Draft, do not open.