Add Field Notes section#432
Merged
Merged
Conversation
A second blog instance at /field-notes for dense, dated engineering notes — distinct from the docs-plugin Changelog. Includes: - @docusaurus/plugin-content-blog instance with id 'field-notes', RSS+Atom+JSON feeds, no left sidebar - Swizzled BlogPostItems renders a single-column list (title, dek from `description` frontmatter, monospace meta line with indigo hashtag tags, hairline dividers) - TestedAgainst component for the per-note "Tested against: Avocado X / JetPack Y / boards" badge - Field-notes layout fills the width that the left-nav would occupy on other tabs; right-hand TOC kept and restyled subtle - Geist + Geist Mono fonts and indigo accent, all scoped to .plugin-id-field-notes so other tabs (Product Docs, Hardware, Developer Reference, Changelog) are unchanged - Notepad icon in the navbar - _template.mdx, authors.yml, CONTRIBUTING.md, and a worked example (2026-06-30-power-pull-orin-nx) included Editorial frontmatter (`hn_title`, `poster`, `lift_for_blog`, `promote_to_track`) lives in the source for greppability but never renders to HTML. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Contributor
There was a problem hiding this comment.
Pull request overview
Adds a new Docusaurus blog instance (“Field Notes”) under /field-notes, with custom list rendering and scoped styling to create a dense, single-column engineering-notes stream distinct from the existing docs/changelog areas.
Changes:
- Adds a new
@docusaurus/plugin-content-bloginstance (id: 'field-notes') with feeds and a new navbar entry. - Swizzles
BlogPostItemsto render a custom single-column index/tag/author/archive list with dek + meta + hashtag tags. - Introduces a
TestedAgainstcomponent plus Field Notes–scoped typography/layout styling and example content/templates.
Reviewed changes
Copilot reviewed 10 out of 10 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| src/src/theme/BlogPostItems/index.js | Swizzled blog list renderer for Field Notes (custom row rendering). |
| src/src/theme/BlogPostItems/styles.module.css | Styles for the Field Notes single-column post list. |
| src/src/components/TestedAgainst/index.jsx | New badge component for “Tested against” metadata. |
| src/src/components/TestedAgainst/styles.module.css | Styling for the TestedAgainst badge. |
| src/src/css/custom.css | Adds Field Notes navbar icon + scoped Field Notes layout/typography/TOC styling. |
| src/docusaurus.config.js | Registers the new blog plugin instance, navbar link, and Geist font includes. |
| src/field-notes/CONTRIBUTING.md | Contributor guidance for Field Notes notes/frontmatter conventions. |
| src/field-notes/authors.yml | Adds Field Notes author map. |
| src/field-notes/_template.mdx | New note template for Field Notes entries. |
| src/field-notes/2026-06-30-power-pull-orin-nx.mdx | Adds an initial worked example note entry. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+34
to
+35
| grep -l "^hn_title:" field-notes/*.mdx | ||
| grep -l "^promote_to_track: \"[^\"]" field-notes/*.mdx |
…uide Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Drafted note on running the Avocado Desktop preview end-to-end on a Raspberry Pi 5 from macOS. Contains [ENGINEER: ...] placeholders for versions, command output, the agent diff, and the honest "what fought me" section to be filled in after a real run. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copilot stopped reviewing on behalf of
bbrock25 due to an error
June 16, 2026 11:09
Justin built Avocado Desktop — this note documents his own lightning demo, not a third-party engineer's first run. Reworked TL;DR, the "Why I built it" section, "Where it still fights me", and "Where this is going" so the voice matches. Embedded the YouTube lightning demo at the top with a responsive 16:9 iframe. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The OTA note was dated 2026-06-30 (future-dated relative to today's 2026-06-16 rpi5 draft) which pushed the newer post below it on the index. Backdated to 2026-06-15 — descending date order now puts new posts at the top of the list, the standard blog convention. Renamed the file in the prior commit so the YYYY-MM-DD filename matches the new frontmatter date and the post URL. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The inner author .row in the post header carried bootstrap's default margin-left: -16px (it normally compensates for col padding). I'd zeroed the col padding for the field-notes layout but not the row's negative margin, so the author name sat 16px left of the h1. Zeroed the row's horizontal margins. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Comment on lines
+2
to
+6
| title: "Pulling the power 200 times mid-OTA on an Orin NX" | ||
| description: "200 scripted power cuts at random points during an A/B OTA update. Zero bricks at steady state — and the two early failures weren't where we expected." | ||
| date: 2026-06-15 | ||
| authors: [jschneck] | ||
| tags: [ota, rollback, jetson, orin-nx] |
Two related issues at narrow widths: - The outer .row carried bootstrap's default -16px horizontal margin, which canceled the container's 16px padding and left the article hugging the viewport edge on mobile. Zeroed the row's margins so the container's padding becomes the visible side margin. - The right-hand TOC was stacking below the article at <=996px (taking full width with the article above it). Replaced the stacking behavior with display: none — it's a summary nav, not load-bearing on mobile. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Replaced the Yocto-tax framing with the angle Justin actually wants to lead with: native USB provisioning on macOS, no Linux VM and no passthrough. New title, description, tags (rpi5/provisioning/macos/usb/ preview), and a rewritten body that puts the USB-from-a-Mac problem first and the Avocado Desktop mechanism second. Demo video embed and TestedAgainst badge preserved at the top. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
| --- | ||
| title: "Provisioning a Raspberry Pi from macOS natively, no Linux VM and no USB passthrough" | ||
| description: "Flashing embedded boards from a Mac usually means a Linux VM and fragile USB passthrough. The Avocado Desktop preview provisions a Raspberry Pi 5 natively from macOS, so there is no VM to babysit and no passthrough to drop." | ||
| date: 2026-06-16 |
Comment on lines
+1
to
+4
| --- | ||
| title: "Pulling the power 200 times mid-OTA on an Orin NX" | ||
| description: "200 scripted power cuts at random points during an A/B OTA update. Zero bricks at steady state — and the two early failures weren't where we expected." | ||
| date: 2026-06-15 |
Field-note draft based on the Seeding the var partition advanced guide. Leads with the offline-first-boot angle — a device booting on a factory floor or behind a firewall can't reach a registry, so Avocado bakes the container image cache into the writable /var at build time (temporary dockerd inside the SDK container, data-root pointed at the var staging area). Includes the var_files exclusion pattern that keeps Docker storage out of the read-only .raw. Date 2026-06-17 puts it on top of the index; tagged [var, docker, offline-first, build, provisioning]. [ENGINEER: ...] placeholders cover real boot logs, timing, and the "what didn't work" section. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Field Notes is now hidden from the public site until a visitor lands on any URL with ?preview=1. The flag persists in sessionStorage for the rest of the tab session; ?preview=0 clears it. Four moving parts: 1. Inline <head> script (docusaurus.config.js headTags) — runs synchronously before paint; if the URL is under /field-notes and the flag isn't in URL or sessionStorage, replaces location with /. Visitors without the flag never see a flash of content. 2. clientModule fieldNotesGate.js — same flag logic, but sets html[data-show-field-notes="1"] so CSS can show the navbar link. Uses a data attribute, not a class, because react-helmet-async rewrites the root className on every render and would wipe a class. 3. postBuild plugin field-notes-preview-gate — injects <meta name="robots" content="noindex,nofollow"> into every /field-notes HTML page so crawlers that don't run the JS redirect still get the no-index signal. 4. build.sh — deletes the RSS/Atom/JSON feed files after docusaurus build finishes (postBuild hooks across plugins run concurrently, so the plugin can't reliably catch the blog plugin's own postBuild writes; the build script can). robots.txt with Disallow: /field-notes added as a third layer. To launch publicly: remove the inline head script, the clientModule, the preview-gate plugin, the rm line in build.sh, and the Disallow in robots.txt. The CSS gate is fine to keep but pointless without the attribute being set. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Comment on lines
+1
to
+5
| --- | ||
| title: "Pulling the power 200 times mid-OTA on an Orin NX" | ||
| description: "200 scripted power cuts at random points during an A/B OTA update. Zero bricks at steady state — and the two early failures weren't where we expected." | ||
| date: 2026-06-15 | ||
| authors: [jschneck] |
The Heroicons document-text path occupies y=2.25..20.625 in a 0..24 viewBox — the cut top-right corner pulls the artwork's visual mass up ~0.5 SVG units, so the icon sat noticeably higher than the other navbar icons. Added transform='translate(0 0.5)' on the path inside the mask-image data URI so the icon renders centered. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Field-note draft from the nvidia-deepstream reference. Leads with the HN-worthy angle: a five-model DeepStream pipeline on Jetson Orin Nano that boots to a live dashboard in ~15s instead of the canonical 10-12min first-boot TensorRT compile. The mechanism: pre-built engines committed per-target into prebuilt-engines/<target>/<model>/, staged into the sysext at build time, and refreshed via OTA with a size-compare invalidation in the preflight script (sysext authoritative, /var as cache). Walks through what's running (PeopleNet, NvDCF, MoveNet, YOLOX-BHH, MediaPipe Hand Landmark) and lists candidate failure modes Justin can pick from for the "what didn't work" section. Dated 2026-06-18 to sort on top of the index. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
| --- | ||
| title: "Pulling the power 200 times mid-OTA on an Orin NX" | ||
| description: "200 scripted power cuts at random points during an A/B OTA update. Zero bricks at steady state — and the two early failures weren't where we expected." | ||
| date: 2026-06-15 |
CI failures: - Run prettier --write across the field-notes set (10 files). - Replace raw <h2> with <Heading as="h2"> in the swizzled BlogPostItems so the @docusaurus/prefer-docusaurus-heading lint passes. Real bugs flagged by the auto-reviewer: - TestedAgainst: guard the "·" separator so it only appears between rendered parts (was producing "Tested against: · Board" when only boards were passed) and return null when nothing is set. - BlogPostItems.ReadingTime: use a nullish check instead of !minutes so 0-minute posts still render "1 min read" rather than disappearing. - Scope --field-notes-accent to .plugin-id-field-notes (and the dark-theme override) so the variable stays inside Field Notes and doesn't leak into other tabs as a global :root custom property. - preview-gate plugin's injectNoindex now replaces any existing robots meta tag (e.g. an index,follow one another plugin might emit) rather than skipping the file. - robots.txt: drop the Disallow: /field-notes line. With the noindex meta + sync redirect already in place, Disallow only prevents crawlers from seeing the noindex (URLs can still surface from external links). Allow crawling, let noindex win. - YouTube iframe: add loading="lazy" and referrerPolicy="strict-origin-when-cross-origin" to match the existing pattern in src/src/components/solutions/ValueProposition.tsx. Misleading documentation: - Fixed the comment above the preview-gate plugin registration that claimed it deletes feed files — feed deletion happens in build.sh. - CONTRIBUTING.md grep snippets now consistently assume the reader is inside src/field-notes/, matching the cp instruction above. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
nicksinas
previously approved these changes
Jun 17, 2026
Copilot kept flagging notes with [ENGINEER: ...] placeholders as "should be marked draft: true." That suggestion doesn't fit our workflow: draft: true would also exclude the post from the gated preview build, which is the entire review surface. CONTRIBUTING.md now has a "Drafts and the [ENGINEER: ...] convention" section explaining how the gate, the placeholders, and the review loop fit together — and why we deliberately don't use draft: true. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Comment on lines
+18
to
+31
| const params = new URLSearchParams(window.location.search) | ||
| const param = params.get('preview') | ||
| if (param === '1') { | ||
| window.sessionStorage.setItem(FLAG_KEY, '1') | ||
| return true | ||
| } | ||
| if (param === '0') { | ||
| window.sessionStorage.removeItem(FLAG_KEY) | ||
| return false | ||
| } | ||
| return window.sessionStorage.getItem(FLAG_KEY) === '1' | ||
| } catch (e) { | ||
| return false | ||
| } |
Comment on lines
+245
to
+258
| try { | ||
| var params = new URLSearchParams(window.location.search); | ||
| var flag = params.get('preview'); | ||
| if (flag === '1') { | ||
| window.sessionStorage.setItem('peridio:fn-preview', '1'); | ||
| return; | ||
| } | ||
| if (flag === '0') { | ||
| window.sessionStorage.removeItem('peridio:fn-preview'); | ||
| } else if (window.sessionStorage.getItem('peridio:fn-preview') === '1') { | ||
| return; | ||
| } | ||
| } catch (e) { /* sessionStorage unavailable — fall through to redirect */ } | ||
| window.location.replace('/'); |
|
|
||
| ```bash | ||
| grep -l "^hn_title:" *.mdx | ||
| grep -l "^promote_to_track: \"[^\"]" *.mdx |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds a Field Notes section at
/field-notes— a second blog instance for dense, dated engineering notes that are distinct from the docs-plugin Changelog. Field Notes is the source-of-truth stream; strong notes get repurposed into marketing posts downstream.The section ships gated behind
?preview=1: visitors without the flag are synchronously redirected to/before paint, all field-notes pages carry<meta name="robots" content="noindex,nofollow">, and RSS/Atom/JSON feeds are dropped from the production build. Reviewers opendocs.peridio.com/field-notes?preview=1to see the section; the public site behaves as if it doesn't exist.@docusaurus/plugin-content-bloginstance (id: 'field-notes') withblogSidebarCount: 0and feeds configuredBlogPostItemsrenders a single-column list: title, dek fromdescriptionfrontmatter, monospace meta line (date · author · reading time) with indigo#hashtagtags, hairline dividersTestedAgainstcomponent for the per-note "Tested against: Avocado / JetPack / boards" badge.plugin-id-field-notes— other tabs (Product Docs, Hardware, Developer Reference, Changelog) are visually unchanged_template.mdx,authors.yml,CONTRIBUTING.md(including the[ENGINEER: ...]draft convention), and four draft notes (2026-06-15-power-pull-orin-nx,2026-06-16-rpi5-from-macos,2026-06-17-pre-seeded-docker-cache,2026-06-18-jetson-deepstream-15s-boot)Editorial frontmatter (
hn_title,poster,lift_for_blog,promote_to_track) lives in the source for greppability but never renders to HTML.To launch publicly
Remove (in this order):
src/plugins/field-notes-preview-gate/(the noindex injector)src/src/clientModules/fieldNotesGate.js(the body-class clientModule)<head>redirect script insrc/docusaurus.config.jsheadTagsrm -f build/field-notes/*.{xml,json}line insrc/scripts/build.sh.navbar__link[href="/field-notes"] { display: none }) insrc/src/css/custom.cssCONTRIBUTING.md's "Drafts and the
[ENGINEER: ...]convention" section explains why notes ship with placeholders — they're the conversation surface for the review pass before the engineer fills in measured values.Test plan
npm run buildpasses/field-noteswith?preview=1: title + dek + monospace meta + indigo hashtags, hairline dividers, full-width/field-noteswithout flag: redirects to/synchronously, no flash?preview=1(data attribute, not class — survives Helmet rerenders)/field-notes/2026/06/16/rpi5-from-macos?preview=1renders the embedded demo video, theTestedAgainstbadge, and the "FIELD NOTES" eyebrow; no left sidebar; right-hand TOC visible#4f46e5light /#818cf8dark, scoped to.plugin-id-field-notes)/field-notes/tags/{ota,rollback,jetson,orin-nx,rpi5,...}render under the gate/field-notes/authors/jschneckrenders under the gate/field-notes/**carries<meta name="robots" content="noindex,nofollow">; other tabs do notbuild/field-notes/rss.xml,atom.xml,feed.jsondeleted bybuild.shhn_title,poster,lift_for_blog,promote_to_track) not in any rendered HTML🤖 Generated with Claude Code