Skip to content

feat: establish the maintained fork with English docs and BOM consistency CI - #4

Open
ramereth wants to merge 13 commits into
mainfrom
osl-docs
Open

feat: establish the maintained fork with English docs and BOM consistency CI#4
ramereth wants to merge 13 commits into
mainfrom
osl-docs

Conversation

@ramereth

Copy link
Copy Markdown
Member

Turns this from a clone of upstream into something OSL can maintain.

Two findings that would cost money

  1. R5 disagrees between the files. 27k in both BOMs, both centroid files
    and the rendered schematic; 72k in all three layouts. It sets the MP1584
    enable divider, so that's an input under-voltage lockout of ~7.0 V versus
    ~3.6 V — the difference between the board starting at the advertised 5 V and
    not starting. Can only be settled by measuring a physical board (R5 is 27k in the BOMs and 72k in the layouts #1).
  2. control2.*, the final layout, was never exported for assembly. No BOM,
    no XY, and the Gerber zips predate it. Anything ordered from this repo today
    comes from a stale export (control2 (final layout) has no BOM/XY/Gerber export #2).

Also filed: no design files exist for V1.1, which is the revision actually
sold (#3).

BOM consistency CI

tools/check_bom.py parses Element[] records out of a .pcb and cross-checks
refdes, value and footprint against the matching BOM and XY exports. Pure stdlib,
no EDA tooling — it stays fast and can't break when pcb-rnd changes. It finds
the R5 drift independently in all four export files.

Findings in tools/known_bom_issues.txt are reported but don't fail, so CI blocks
on new drift while R5 stays open. Deleting an entry re-enables enforcement.

English documentation

All Chinese translated — README, prototype sketch comments, the link.txt cable
table, the 编号 BOM column. No schematic, layout, footprint, BOM value or
centroid data touched.

AGENTS.md is a full hardware reference derived from the layout's embedded
NetList(): MCU pin map, connector pinouts, power tree, the back-to-back MOSFET
output switch, and how the DS18B20 ROM code becomes the serial number, MAC and
hostname. doc/ has the vendor pages translated with images mirrored locally.

The README also now states plainly that the firmware is not in this repo
the sketch here is an abandoned prototype, and the shipped firmware is in
osuosl/proc.

Review notes

  • master was renamed to main; upstream is still master, so syncing is
    git merge upstream/master.
  • This PR is the first CI run.

ramereth and others added 7 commits July 25, 2026 16:27
Everything upstream is written in Chinese and the design rationale is
spread across the vendor's website rather than the repo. This adds the
English working notes OSU OSL needs to maintain the boards it runs.

AGENTS.md covers:
  - the hardware reference (MCU pin map, connectors, power tree, the
    back-to-back MOSFET output switch, the DS18B20-derived device
    identity), derived from the NetList() block in control2.pcb
  - which revision is which: control2.* is the final layout here, and
    the published board is V1.1, for which no design files exist
  - translations of README.md and the full commit log
  - hardware-side issues found while reading the files, including an
    R5 value that disagrees between the BOMs (27k) and the layout
    (72k), which moves the input UVLO between ~7.0V and ~3.6V

doc/ carries full English translations of the vendor pages, with the
images mirrored locally so they survive the site going away:
  - node-914  hardware installation manual
  - node-953  motherboard COM header
  - node-954  V1.1 board render

Note the firmware in control/control.ino is an abandoned prototype;
the shipped firmware lives in the proc repository.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Signed-off-by: Lance Albertson <lance@osuosl.org>
Everything upstream is written in Chinese, which makes the hardware
design hard for OSU OSL to work with. This translates the text that
lives in the repository itself:

  - README.md, the product description
  - control/control.ino, the comments in the prototype sketch
  - link.txt, the serial cable pin mapping table headers, and the
    ground row (地 -> GND)
  - the 编号 column header in control_bom.csv and control1_bom.csv,
    which holds the JLCPCB part number

Comments and prose only -- no schematic, layout, footprint, BOM value
or pick-and-place data is touched, and control/control.ino is a dead
prototype that nothing builds.

Kept as one isolated commit so it can be replayed or dropped in one
operation when rebasing on upstream, which remains Chinese.

The README's claim of "up to 32 temperature probes" is translated as
written; the shipped firmware supports 10. See AGENTS.md section 8.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Signed-off-by: Lance Albertson <lance@osuosl.org>
The BOM and pick-and-place CSVs are exported from the layout by hand and
then edited by hand, so they drift from it. That has already happened: R5
is 27k in both BOMs, both centroid files and the rendered schematic, but
72k in all three layouts. R5 sets the MP1584 enable divider, so those two
values put the input under-voltage lockout at roughly 7.0V and 3.6V
respectively -- the difference between the board starting at the 5V the
README advertises and not starting at all.

tools/check_bom.py parses the Element[] records out of a .pcb and
cross-checks refdes, value and footprint against the matching BOM and XY
exports. Pure stdlib and no EDA tooling, deliberately: it stays fast and
cannot break when pcb-rnd or lepton-eda change.

It also warns that control2.pcb, the final layout here, has no BOM or XY
export at all, so anything sent to a fab today would come from a stale one.

Findings listed in tools/known_bom_issues.txt are reported but do not fail
the run, so CI blocks on new drift while the R5 question -- which can only
be settled by measuring a physical board -- stays open. Deleting an entry
is what turns enforcement back on for that part.

CI also checks that relative links in markdown resolve, which is the other
way this repository rots.

Refs: #1, #2

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Signed-off-by: Lance Albertson <lance@osuosl.org>
The README was upstream's product blurb, translated, and it overstated the
hardware: it claimed support for 32 temperature probes where the shipped
firmware supports 10.

README.md now leads with the two things that would actually cost someone
money -- that control2.* was never exported for assembly, and that R5
disagrees between the BOMs and the layouts -- along with a parts summary,
the revision table, and how to open the design files with Debian's pcb-rnd
and lepton-eda rather than building upstream's forks.

It also states plainly that the firmware is not in this repository. The
sketch here is an abandoned prototype; the shipped firmware is in
osuosl/proc.

CONTRIBUTING.md covers the sign-off requirement, the fork PR-base trap,
merge-don't-rebase, and the rule that matters most for EDA files: a GUI
round-trip rewrites the entire file, so keep diffs reviewable and never
regenerate the Gerber zips, which are the record of what was fabricated.
It also explains the known-issue baseline, and that entries are meant to be
deleted rather than accumulated.

AGENTS.md now maps its hardware findings to the GitHub issues that own the
state.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Signed-off-by: Lance Albertson <lance@osuosl.org>
The docs linked to the sibling repository with relative paths such as
../proc/AGENTS.md. Those resolve only in a workspace where both repos sit
next to each other, which is how they were written and checked. Anyone who
clones this repository on its own gets ~25 broken links.

The link checker added in the previous commit caught this on its first CI
run, which is roughly the ideal outcome for a check like that.

Cross-repo and out-of-tree targets are now absolute URLs. Links within a
repository stay relative, so they keep working on a branch or a fork.

Also drops the two references to the workspace-level overview, which is not
published anywhere, and replaces them with the relevant facts inline.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Signed-off-by: Lance Albertson <lance@osuosl.org>
Mirrors the setup in osuosl/proc so both repositories release the same way.

  release-please-config.json      simple release type, tuned changelog sections
  .release-please-manifest.json   pinned to 0.0.0
  version.txt                     release-please owned
  .github/workflows/
    release-please.yml            maintains the release PR, tags, publishes
    pr-title.yml                  rejects unconventional PR titles

One difference worth stating explicitly, and it is documented in
CONTRIBUTING.md and CHANGELOG.md: a release in this repository is a
snapshot of the design and its documentation, not a fabricated board
revision. Board revisions are control.*, control1.*, control2.* and the
unpublished V1.1. Conflating the two would be actively misleading, since
"v1.2.0" says nothing about which PCB is actually in the rack.

The commit type guidance is adjusted to match: most work here is docs or
fix, feat is reserved for changes to the design itself, and a breaking
change means one that would make an already-fabricated board incorrect.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Signed-off-by: Lance Albertson <lance@osuosl.org>
Only commits after 5bf428b, the last upstream commit, are ours to release.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Signed-off-by: Lance Albertson <lance@osuosl.org>
@ramereth ramereth changed the title Establish the maintained fork: English docs, hardware reference, BOM consistency CI feat: establish the maintained fork with English docs and BOM consistency CI Jul 26, 2026
We are not squash-merging, so the PR title never becomes a commit on main
and linting it checks nothing that matters. Every individual commit is what
lands, what release-please parses, and what the changelog is built from.

Replaces pr-title.yml with commits.yml, which walks every non-merge commit
in the PR and requires a conventional subject and a Signed-off-by trailer.
It also rejects a capitalised subject or a trailing period, so release notes
read consistently.

The failure mode this guards against is quiet: a non-conventional subject
does not break the release, the change just silently never appears in the
changelog.

CONTRIBUTING.md gains a Merging section stating the rule and the reason --
squashing would collapse a branch's distinct fixes into one changelog line
and discard the individual sign-offs.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Signed-off-by: Lance Albertson <lance@osuosl.org>
ramereth and others added 5 commits July 26, 2026 16:54
Weekly, and grouped: one PR covering every action rather than one PR per
action. Majors are in the group too, so a breaking bump shows up as a red
CI run on that PR instead of arriving silently later.

Two integration details that would otherwise bite:

  - Dependabot commits are prefixed "ci(deps):" via commit-message.prefix.
    Without that they would not be conventional, and every Dependabot PR
    would fail the commit lint added in the previous commit.
  - Dependabot has no DCO option, so commits.yml now exempts bot authors
    from the sign-off requirement. They are not exempt from the format
    check: if the prefix is ever dropped from dependabot.yml, CI catches
    it. The same exemption covers release-please's own
    "chore(main): release X" commit.

github-actions is the only ecosystem that applies. There is none for
arduino-cli, so the core and library pins stay manual, which is documented
in CONTRIBUTING.md along with why: this firmware sits at ~95% of flash, and
a toolchain bump can push it over the ceiling or change generated code. It
wants a human reading the size delta, not an automerge.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Signed-off-by: Lance Albertson <lance@osuosl.org>
Dependabot was prefixing its commits "ci(deps):". That was enough to pass
the commit lint, but "ci" is visible in changelog-sections here on purpose,
because a toolchain change is often the whole point of a release in this
repository. So action bumps would have shown up in release notes that are
read by someone deciding whether to reflash a board.

Switch the prefix to "chore(deps):", which fixes both halves:

  - release-please's default versioning strategy bumps only for feat, fix
    and breaking changes, so a chore commit cannot cause a release on its
    own. Merging a Dependabot PR no longer mints a firmware version.
  - chore is already hidden in changelog-sections, so the bumps stay out of
    the notes while remaining in git history where they belong.

It still has to be a conventional prefix at all, or every Dependabot PR
would fail the commit check -- that part is unchanged, and the check still
catches the prefix being removed.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Signed-off-by: Lance Albertson <lance@osuosl.org>
main is protected: changes go through a PR, all status checks must pass,
force pushes and deletions are blocked, and conversations must be resolved.

Two settings are deliberately off, and both would look like mistakes without
an explanation, so they are written down:

  - Linear history is NOT required. Requiring it would reject the merge
    commits we switched to so release-please sees individual commits.
  - Approvals are NOT required (0). Requiring one would stop a solo
    maintainer landing a fix, which matters when the thing being fixed is
    the out-of-band access to a machine that is already down.

Admin enforcement is also off, for a specific reason: release-please's PR
is created with GITHUB_TOKEN, and a token-created PR does not trigger
workflows, so its required checks never report and it shows as blocked
forever. Admin bypass makes the release mergeable today; the proper fix is
a fine-grained PAT or App token passed to the action, which is documented
so nobody has to rediscover why the first release would not merge.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Signed-off-by: Lance Albertson <lance@osuosl.org>
Every commit on this branch is a fix, documentation or CI, so
release-please would compute a patch bump and cut 0.0.1. 0.1.0 better
describes what this is: the point where the hardware design became
documented in English, cross-checked by CI, and maintained by OSL.

1.0.0 is left for when the open questions are settled -- R5 measured on a
physical board, control2 exported for assembly, and the V1.1 design either
obtained or reconstructed. Until then the repository does not fully
describe the boards in the rack, and the version should not pretend
otherwise.

The override applies to this release only; the next version is computed
normally.

Release-As: 0.1.0
Signed-off-by: Lance Albertson <lance@osuosl.org>
The action now reads secrets.RELEASE_PLEASE_TOKEN and falls back to
github.token when it is unset, so this changes nothing until the secret
exists and needs no coordination to land.

Why it matters: a PR created with GITHUB_TOKEN does not trigger workflows,
so release-please's PR gets no CI runs, its required checks never report,
and branch protection shows it as blocked. Admin enforcement is currently
off to work around that. With a real token the release PR runs CI like any
other and the bypass can be turned back on.

CONTRIBUTING.md gains the full procedure: which permissions the token needs
(contents and pull-requests, read and write, nothing else), how to store it
once at the org for both repos, the command to re-enable admin enforcement
afterwards, and the caveat that a user PAT makes release PRs appear authored
by that user.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Signed-off-by: Lance Albertson <lance@osuosl.org>
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.

1 participant