| #!/usr/bin/env node | ||
| // Single-source release-version synchronization: package.json.version is canonical. | ||
| // Propagates it to .claude-plugin/plugin.json and skills/dev-like/SKILL.md frontmatter | ||
| // metadata.version. Deliberately does NOT write .claude-plugin/marketplace.json โ Claude's | ||
| // plugin resolution precedence is plugin.json -> marketplace entry -> git SHA, so a | ||
| // marketplace-entry version would be a second, unnecessary source of truth. `--check` | ||
| // enforces that no such entry-level version exists. | ||
| // | ||
| // All target files are parsed and validated (structurally, before any write) up front, | ||
| // so malformed/ambiguous input fails loudly and no file is ever partially written. This | ||
| // is "plan fully, then write" ordering within a single process โ it is not a cross-file | ||
| // filesystem transaction, so a crash between two writes can still leave them inconsistent; | ||
| // re-running the tool (idempotent) recovers. | ||
| import { readFile, writeFile } from 'node:fs/promises'; | ||
| import { join, dirname } from 'node:path'; | ||
| import { fileURLToPath } from 'node:url'; | ||
| const DEFAULT_ROOT = join(dirname(fileURLToPath(import.meta.url)), '..'); | ||
| const PACKAGE_JSON = 'package.json'; | ||
| const PLUGIN_JSON = join('.claude-plugin', 'plugin.json'); | ||
| const MARKETPLACE_JSON = join('.claude-plugin', 'marketplace.json'); | ||
| const SKILL_MD = join('skills', 'dev-like', 'SKILL.md'); | ||
| // Canonical SemVer 2.0.0 regex, from https://semver.org/#is-there-a-suggested-regular-expression-regex-to-check-a-semver-string | ||
| const SEMVER_RE = | ||
| /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$/; | ||
| export function isValidSemver(value) { | ||
| return typeof value === 'string' && SEMVER_RE.test(value); | ||
| } | ||
| class SyncError extends Error {} | ||
| // Not a general JSON parser โ JSON.parse already provides structural validation. This is | ||
| // a minimal lexical scanner that counts how many times a key named `keyName` appears at | ||
| // object depth 1 (i.e. directly inside the root `{ }`), so we can detect duplicate | ||
| // top-level keys that JSON.parse silently collapses to their last occurrence. It respects | ||
| // JSON string/escape syntax and object/array nesting depth so key-like text inside string | ||
| // values or nested objects is never miscounted. | ||
| function countTopLevelObjectKeys(text, keyName) { | ||
| let depth = 0; | ||
| let inString = false; | ||
| let escaped = false; | ||
| let count = 0; | ||
| const keyRe = new RegExp(`^"${keyName}"\\s*:`); | ||
| for (let i = 0; i < text.length; i++) { | ||
| const ch = text[i]; | ||
| if (inString) { | ||
| if (escaped) { | ||
| escaped = false; | ||
| } else if (ch === '\\') { | ||
| escaped = true; | ||
| } else if (ch === '"') { | ||
| inString = false; | ||
| } | ||
| continue; | ||
| } | ||
| if (ch === '"') { | ||
| inString = true; | ||
| if (depth === 1 && keyRe.test(text.slice(i))) count++; | ||
| continue; | ||
| } | ||
| if (ch === '{' || ch === '[') depth++; | ||
| else if (ch === '}' || ch === ']') depth--; | ||
| } | ||
| return count; | ||
| } | ||
| async function readJson(root, rel) { | ||
| const full = join(root, rel); | ||
| let text; | ||
| try { | ||
| text = await readFile(full, 'utf8'); | ||
| } catch (err) { | ||
| throw new SyncError(`${rel}: cannot read (${err.message})`); | ||
| } | ||
| let json; | ||
| try { | ||
| json = JSON.parse(text); | ||
| } catch (err) { | ||
| throw new SyncError(`${rel}: invalid JSON (${err.message})`); | ||
| } | ||
| return { rel, full, text, json }; | ||
| } | ||
| function readPackageVersion(pkg) { | ||
| const version = pkg.json.version; | ||
| if (!isValidSemver(version)) { | ||
| throw new SyncError(`${pkg.rel}: missing or malformed "version" field`); | ||
| } | ||
| return version; | ||
| } | ||
| function planPluginJsonUpdate(pluginFile, targetVersion) { | ||
| const current = pluginFile.json.version; | ||
| if (!isValidSemver(current)) { | ||
| throw new SyncError(`${pluginFile.rel}: missing or malformed "version" field`); | ||
| } | ||
| // JSON.parse silently collapses duplicate top-level keys to the last occurrence, so an | ||
| // ambiguous manifest with two "version" keys could otherwise pass unnoticed (worse, if | ||
| // the last duplicate happens to already equal targetVersion, --check would pass too). | ||
| // Surface this as drift (like the marketplace invariant) rather than throwing | ||
| // immediately, so --check can report it without excepting. | ||
| const topLevelVersionKeys = countTopLevelObjectKeys(pluginFile.text, 'version'); | ||
| if (topLevelVersionKeys !== 1) { | ||
| return { | ||
| rel: pluginFile.rel, | ||
| full: pluginFile.full, | ||
| ambiguous: true, | ||
| message: `expected exactly one "version" field, found ${topLevelVersionKeys}`, | ||
| }; | ||
| } | ||
| if (current === targetVersion) return null; | ||
| // Update only the top-level "version" key structurally (not a regex line count, which | ||
| // can't distinguish top-level from nested "version" fields) and reserialize as | ||
| // deterministic 2-space JSON + trailing newline. This is a one-time formatting | ||
| // normalization of a tiny manifest โ simpler and safer than a custom tokenizer that | ||
| // preserves byte-for-byte formatting while still doing a structural edit. | ||
| const updated = { ...pluginFile.json, version: targetVersion }; | ||
| const newText = `${JSON.stringify(updated, null, 2)}\n`; | ||
| return { rel: pluginFile.rel, full: pluginFile.full, newText }; | ||
| } | ||
| function planSkillMdUpdate(skillPath, text, targetVersion) { | ||
| const fmMatch = text.match(/^---\n([\s\S]*?)\n---\n/); | ||
| if (!fmMatch) throw new SyncError(`${skillPath}: no YAML frontmatter found`); | ||
| const frontmatter = fmMatch[1]; | ||
| // Narrow frontmatter parse: locate `metadata:` block and require exactly one | ||
| // `version:` line within it (indented under metadata). | ||
| const lines = frontmatter.split('\n'); | ||
| const metadataIdx = lines.findIndex((l) => /^metadata:\s*$/.test(l)); | ||
| if (metadataIdx === -1) throw new SyncError(`${skillPath}: frontmatter missing "metadata:" block`); | ||
| // First pass: count ANY indented "version:" key within the metadata block, regardless | ||
| // of value formatting (double-quoted, single-quoted, or plain scalar), so a duplicate | ||
| // in any style is caught as ambiguous โ not just a duplicate double-quoted line. | ||
| const versionKeyRe = /^(\s+)version:\s*(.*)$/; | ||
| const versionLineIdxs = []; | ||
| for (let i = metadataIdx + 1; i < lines.length; i++) { | ||
| const line = lines[i]; | ||
| if (/^\S/.test(line)) break; // dedent = end of metadata block | ||
| if (versionKeyRe.test(line)) versionLineIdxs.push(i); | ||
| } | ||
| if (versionLineIdxs.length === 0) { | ||
| throw new SyncError(`${skillPath}: "metadata.version" field not found`); | ||
| } | ||
| if (versionLineIdxs.length > 1) { | ||
| throw new SyncError(`${skillPath}: multiple "metadata.version" fields found`); | ||
| } | ||
| const versionLineIdx = versionLineIdxs[0]; | ||
| const m = lines[versionLineIdx].match(/^(\s+)version:\s*"([^"]*)"\s*$/); | ||
| if (!m) { | ||
| throw new SyncError(`${skillPath}: "metadata.version" must be a double-quoted string`); | ||
| } | ||
| const versionValue = m[2]; | ||
| if (!isValidSemver(versionValue)) { | ||
| throw new SyncError(`${skillPath}: "metadata.version" is missing or malformed`); | ||
| } | ||
| if (versionValue === targetVersion) return null; | ||
| const indent = lines[versionLineIdx].match(/^(\s+)/)[1]; | ||
| lines[versionLineIdx] = `${indent}version: "${targetVersion}"`; | ||
| const newFrontmatter = lines.join('\n'); | ||
| const newText = text.slice(0, fmMatch.index) + `---\n${newFrontmatter}\n---\n` + text.slice(fmMatch.index + fmMatch[0].length); | ||
| return { rel: skillPath, newText }; | ||
| } | ||
| function checkMarketplaceHasNoVersion(marketplaceFile) { | ||
| const plugins = marketplaceFile.json.plugins; | ||
| if (!Array.isArray(plugins)) { | ||
| throw new SyncError(`${marketplaceFile.rel}: missing "plugins" array`); | ||
| } | ||
| const entries = plugins.filter((p) => p && p.name === 'dev-like'); | ||
| if (entries.length === 0) { | ||
| throw new SyncError(`${marketplaceFile.rel}: no "dev-like" plugin entry found`); | ||
| } | ||
| if (entries.length > 1) { | ||
| return { | ||
| path: marketplaceFile.rel, | ||
| message: `expected exactly one "dev-like" plugin entry, found ${entries.length}`, | ||
| }; | ||
| } | ||
| const [entry] = entries; | ||
| if (Object.prototype.hasOwnProperty.call(entry, 'version')) { | ||
| return { | ||
| path: marketplaceFile.rel, | ||
| message: | ||
| '"dev-like" plugin entry must not declare a "version" field ' + | ||
| '(canonical version comes from plugin.json; duplicating it here creates drift risk)', | ||
| }; | ||
| } | ||
| return null; | ||
| } | ||
| /** | ||
| * Synchronize (or check) release-version metadata across plugin.json and SKILL.md, | ||
| * treating package.json.version as canonical. Never writes marketplace.json. | ||
| * | ||
| * @param {{ root?: string, check?: boolean }} [opts] | ||
| * @returns {Promise<{ ok: boolean, drift: Array<{ path: string, message: string }>, written: string[] }>} | ||
| */ | ||
| export async function syncReleaseVersion({ root = DEFAULT_ROOT, check = false } = {}) { | ||
| const [pkg, pluginFile, marketplaceFile] = await Promise.all([ | ||
| readJson(root, PACKAGE_JSON), | ||
| readJson(root, PLUGIN_JSON), | ||
| readJson(root, MARKETPLACE_JSON), | ||
| ]); | ||
| const skillFull = join(root, SKILL_MD); | ||
| let skillText; | ||
| try { | ||
| skillText = await readFile(skillFull, 'utf8'); | ||
| } catch (err) { | ||
| throw new SyncError(`${SKILL_MD}: cannot read (${err.message})`); | ||
| } | ||
| const targetVersion = readPackageVersion(pkg); | ||
| const marketplaceDrift = checkMarketplaceHasNoVersion(marketplaceFile); | ||
| const pluginPlan = planPluginJsonUpdate(pluginFile, targetVersion); | ||
| const skillPlan = planSkillMdUpdate(SKILL_MD, skillText, targetVersion); | ||
| const drift = []; | ||
| if (marketplaceDrift) drift.push(marketplaceDrift); | ||
| if (pluginPlan?.ambiguous) drift.push({ path: pluginPlan.rel, message: pluginPlan.message }); | ||
| else if (pluginPlan) drift.push({ path: pluginPlan.rel, message: `version differs from package.json (${targetVersion})` }); | ||
| if (skillPlan) drift.push({ path: skillPlan.rel, message: `metadata.version differs from package.json (${targetVersion})` }); | ||
| if (check || drift.length === 0) { | ||
| return { ok: drift.length === 0, drift, written: [] }; | ||
| } | ||
| if (pluginPlan?.ambiguous) { | ||
| // Never write when plugin.json's top-level "version" key is ambiguous โ this is a | ||
| // design violation the tool must not "fix" by writing around it. | ||
| throw new SyncError(`${pluginPlan.rel}: ${pluginPlan.message}`); | ||
| } | ||
| if (marketplaceDrift) { | ||
| // Never write when the marketplace invariant is violated โ this is a design | ||
| // violation the tool must not "fix" by writing around it. | ||
| throw new SyncError(`${marketplaceDrift.path}: ${marketplaceDrift.message}`); | ||
| } | ||
| const written = []; | ||
| if (pluginPlan) { | ||
| await writeFile(pluginPlan.full, pluginPlan.newText, 'utf8'); | ||
| written.push(pluginPlan.rel); | ||
| } | ||
| if (skillPlan) { | ||
| await writeFile(skillFull, skillPlan.newText, 'utf8'); | ||
| written.push(skillPlan.rel); | ||
| } | ||
| return { ok: true, drift: [], written }; | ||
| } | ||
| function parseArgs(argv) { | ||
| const opts = { check: false, root: undefined }; | ||
| for (let i = 0; i < argv.length; i++) { | ||
| const arg = argv[i]; | ||
| if (arg === '--check') { | ||
| opts.check = true; | ||
| } else if (arg === '--root') { | ||
| const value = argv[i + 1]; | ||
| if (!value || value.startsWith('-')) throw new SyncError('--root requires a value'); | ||
| opts.root = value; | ||
| i++; | ||
| } else { | ||
| throw new SyncError(`unknown argument: ${arg}`); | ||
| } | ||
| } | ||
| return opts; | ||
| } | ||
| async function main() { | ||
| let opts; | ||
| try { | ||
| opts = parseArgs(process.argv.slice(2)); | ||
| } catch (err) { | ||
| console.error(`FAIL ${err.message}`); | ||
| process.exitCode = 1; | ||
| return; | ||
| } | ||
| try { | ||
| const result = await syncReleaseVersion(opts); | ||
| if (opts.check) { | ||
| if (result.ok) { | ||
| console.log('OK release-version metadata is in sync'); | ||
| } else { | ||
| for (const d of result.drift) console.error(`FAIL ${d.path}: ${d.message}`); | ||
| process.exitCode = 1; | ||
| } | ||
| } else { | ||
| if (result.written.length === 0) console.log('OK release-version metadata already in sync'); | ||
| else for (const w of result.written) console.log(` ok synced ${w}`); | ||
| } | ||
| } catch (err) { | ||
| console.error(`FAIL ${err.message}`); | ||
| process.exitCode = 1; | ||
| } | ||
| } | ||
| if (process.argv[1] === fileURLToPath(import.meta.url)) { | ||
| main(); | ||
| } |
+4
-4
| { | ||
| "name": "dev-like", | ||
| "version": "0.4.0", | ||
| "version": "0.4.1", | ||
| "description": "Profile a shop's engineering culture from public sources and install develop-like-<target> agent skills. /dev-like Every", | ||
@@ -41,8 +41,8 @@ "keywords": [ | ||
| "scripts": { | ||
| "validate": "node scripts/validate.mjs", | ||
| "validate": "node scripts/validate.mjs && node scripts/sync-release-version.mjs --check", | ||
| "eval:paired": "node evals/paired/run.mjs", | ||
| "test": "node --test tests/*.test.mjs && bun test tests/*.test.ts", | ||
| "prepublishOnly": "bun run validate && bun run test", | ||
| "version-changesets": "changeset version", | ||
| "publish-changesets": "changeset publish", | ||
| "version-changesets": "changeset version && node scripts/sync-release-version.mjs", | ||
| "publish-changesets": "node scripts/sync-release-version.mjs --check && changeset publish", | ||
| "alias-release": "bun run .github/scripts/alias-release.ts" | ||
@@ -49,0 +49,0 @@ }, |
+21
-8
@@ -1,11 +0,17 @@ | ||
| # dev-like | ||
| <p align="center"> | ||
| <img src=".github/readme-hero.png" alt="dev-like โ engineering-culture config profiles compiled into an installable agent skill" width="640"> | ||
| </p> | ||
| [](https://www.npmjs.com/package/dev-like) | ||
| [](https://github.com/marcusrbrown/dev-like/actions/workflows/ci.yaml) | ||
| [](https://github.com/marcusrbrown/dev-like/actions/workflows/link-check.yaml) | ||
| [](https://www.skills.sh/marcusrbrown/dev-like) | ||
| <h1 align="center">dev-like</h1> | ||
| > Steal the workflow, not the code. `/dev-like Every` and your agent develops like the | ||
| > shops you admire โ with receipts. | ||
| <p align="center"> | ||
| <i>Steal the workflow, not the code. <code>/dev-like Every</code> and your agent develops like the shops you admire โ with receipts.</i> | ||
| </p> | ||
| <p align="center"> | ||
| <a href="https://www.npmjs.com/package/dev-like"><img src="https://img.shields.io/npm/v/dev-like?style=for-the-badge&logo=npm&color=00d0c7&labelColor=13131c" alt="npm"></a> | ||
| <a href="https://github.com/marcusrbrown/dev-like/actions/workflows/ci.yaml"><img src="https://img.shields.io/github/actions/workflow/status/marcusrbrown/dev-like/ci.yaml?style=for-the-badge&logo=github&label=CI&color=00d0c7&labelColor=13131c" alt="CI"></a> | ||
| <a href="https://www.skills.sh/marcusrbrown/dev-like"><img src="https://img.shields.io/badge/skills.sh-npx%20skills%20add-00d0c7?style=for-the-badge&labelColor=13131c" alt="skills.sh"></a> | ||
| </p> | ||
| `dev-like` profiles a tech company or developer's engineering culture from **public sources | ||
@@ -49,3 +55,5 @@ only** (their shipped agent configs, linter configs, CI files, engineering blogs, talks) and | ||
| |------|------|--------------|-------| | ||
| | [`37signals`](registry/37signals/) | org | self-published | [develop-like-37signals](registry/37signals/skill/develop-like-37signals/) | | ||
| | [`every`](registry/every/) | org | self-published | [develop-like-every](registry/every/skill/develop-like-every/) | | ||
| | [`linear`](registry/linear/) | org | self-published | [develop-like-linear](registry/linear/skill/develop-like-linear/) | | ||
| | [`oxide`](registry/oxide/) | org | self-published | [develop-like-oxide](registry/oxide/skill/develop-like-oxide/) | | ||
@@ -77,6 +85,11 @@ | [`theo`](registry/theo/) | person | stated | generated on demand | | ||
| bun install | ||
| bun run validate # frontmatter + registry schema + index sync | ||
| bun run validate # frontmatter + registry schema + index sync + plugin/skill version lockstep | ||
| bun run test # generator, CLI install, link-collection suites | ||
| ``` | ||
| `bun run validate` also checks that `.claude-plugin/plugin.json` and the `dev-like` skill's | ||
| frontmatter `metadata.version` stay in lockstep with `package.json` (the canonical version). | ||
| The marketplace entry intentionally stays unversioned โ `plugin.json` is authoritative for | ||
| Claude's plugin resolution. If a check fails, `node scripts/sync-release-version.mjs` fixes it. | ||
| Plain node works too (`node scripts/validate.mjs`, `node --test tests/`) โ the package has | ||
@@ -83,0 +96,0 @@ zero runtime dependencies. Provenance links are re-checked weekly in CI; trigger evals and the |
@@ -24,16 +24,16 @@ # 37signals โ dev culture profile | ||
| Shaping (defining the problem, appetite, and rough solution) happens ahead of the cycle; | ||
| bets are placed at a betting table during cooldown, not pulled from a backlog โ "no backlogs" | ||
| is explicit doctrine [[Shape Up ch.8]](https://basecamp.com/shapeup/2.2-chapter-08). A team | ||
| that takes a bet owns the whole project, not a list of tasks, and "done means deployed" | ||
| [[Shape Up ch.10]](https://basecamp.com/shapeup/3.1-chapter-10). Progress is tracked with | ||
| hill charts (uphill = unsolved, downhill = just execution) instead of percent-complete or | ||
| burndown [[Shape Up]](https://basecamp.com/shapeup). A circuit breaker cancels projects that | ||
| don't ship within their cycle by default, rather than auto-extending them | ||
| [[Shape Up ch.8]](https://basecamp.com/shapeup/2.2-chapter-08). Cooldown is when bugs get | ||
| fixed, cycles get planned, and the next bets get made | ||
| Before the cycle, shape the problem, state the appetite, and sketch the rough solution. During | ||
| cooldown, place bets at a betting table; do not pull them from a backlog โ "no backlogs" is | ||
| explicit doctrine [[Shape Up ch.8]](https://basecamp.com/shapeup/2.2-chapter-08). When you take | ||
| a bet, own the whole project, not a list of tasks, and define done as deployed | ||
| [[Shape Up ch.10]](https://basecamp.com/shapeup/3.1-chapter-10). Track progress with hill | ||
| charts (uphill = unsolved, downhill = just execution), not percent-complete or burndown | ||
| [[Shape Up]](https://basecamp.com/shapeup). Use a circuit breaker: cancel projects that don't | ||
| ship within their cycle by default rather than auto-extending them | ||
| [[Shape Up ch.8]](https://basecamp.com/shapeup/2.2-chapter-08). During cooldown, fix bugs, plan | ||
| cycles, and make the next bets | ||
| [[how we work]](https://github.com/basecamp/handbook/blob/master/how-we-work.md). | ||
| QA is a two-person team running manual, guided exploratory testing against ~100-item | ||
| per-product checklists (not exhaustive test-case matrices), plus accessibility passes with | ||
| screen readers and a home-grown BackstopJS visual-regression suite | ||
| As a two-person QA team, run manual, guided exploratory testing against ~100-item | ||
| per-product checklists (not exhaustive test-case matrices), then run accessibility passes with | ||
| screen readers and the home-grown BackstopJS visual-regression suite | ||
| [[all about QA]](https://dev.37signals.com/all-about-qa/). | ||
@@ -40,0 +40,0 @@ |
@@ -5,16 +5,16 @@ # Workflow โ 37signals | ||
| Shaping (defining the problem, appetite, and rough solution) happens ahead of the cycle; | ||
| bets are placed at a betting table during cooldown, not pulled from a backlog โ "no backlogs" | ||
| is explicit doctrine [[Shape Up ch.8]](https://basecamp.com/shapeup/2.2-chapter-08). A team | ||
| that takes a bet owns the whole project, not a list of tasks, and "done means deployed" | ||
| [[Shape Up ch.10]](https://basecamp.com/shapeup/3.1-chapter-10). Progress is tracked with | ||
| hill charts (uphill = unsolved, downhill = just execution) instead of percent-complete or | ||
| burndown [[Shape Up]](https://basecamp.com/shapeup). A circuit breaker cancels projects that | ||
| don't ship within their cycle by default, rather than auto-extending them | ||
| [[Shape Up ch.8]](https://basecamp.com/shapeup/2.2-chapter-08). Cooldown is when bugs get | ||
| fixed, cycles get planned, and the next bets get made | ||
| Before the cycle, shape the problem, state the appetite, and sketch the rough solution. During | ||
| cooldown, place bets at a betting table; do not pull them from a backlog โ "no backlogs" is | ||
| explicit doctrine [[Shape Up ch.8]](https://basecamp.com/shapeup/2.2-chapter-08). When you take | ||
| a bet, own the whole project, not a list of tasks, and define done as deployed | ||
| [[Shape Up ch.10]](https://basecamp.com/shapeup/3.1-chapter-10). Track progress with hill | ||
| charts (uphill = unsolved, downhill = just execution), not percent-complete or burndown | ||
| [[Shape Up]](https://basecamp.com/shapeup). Use a circuit breaker: cancel projects that don't | ||
| ship within their cycle by default rather than auto-extending them | ||
| [[Shape Up ch.8]](https://basecamp.com/shapeup/2.2-chapter-08). During cooldown, fix bugs, plan | ||
| cycles, and make the next bets | ||
| [[how we work]](https://github.com/basecamp/handbook/blob/master/how-we-work.md). | ||
| QA is a two-person team running manual, guided exploratory testing against ~100-item | ||
| per-product checklists (not exhaustive test-case matrices), plus accessibility passes with | ||
| screen readers and a home-grown BackstopJS visual-regression suite | ||
| As a two-person QA team, run manual, guided exploratory testing against ~100-item | ||
| per-product checklists (not exhaustive test-case matrices), then run accessibility passes with | ||
| screen readers and the home-grown BackstopJS visual-regression suite | ||
| [[all about QA]](https://dev.37signals.com/all-about-qa/). |
@@ -42,16 +42,19 @@ --- | ||
| Shaping (defining the problem, appetite, and rough solution) happens ahead of the cycle; | ||
| bets are placed at a betting table during cooldown, not pulled from a backlog โ "no backlogs" | ||
| is explicit doctrine [[Shape Up ch.8]](https://basecamp.com/shapeup/2.2-chapter-08). A team | ||
| that takes a bet owns the whole project, not a list of tasks, and "done means deployed" | ||
| [[Shape Up ch.10]](https://basecamp.com/shapeup/3.1-chapter-10). Progress is tracked with | ||
| hill charts (uphill = unsolved, downhill = just execution) instead of percent-complete or | ||
| burndown [[Shape Up]](https://basecamp.com/shapeup). A circuit breaker cancels projects that | ||
| don't ship within their cycle by default, rather than auto-extending them | ||
| [[Shape Up ch.8]](https://basecamp.com/shapeup/2.2-chapter-08). Cooldown is when bugs get | ||
| fixed, cycles get planned, and the next bets get made | ||
| Execute these checkpoints before and during the task. Treat them as required actions, not | ||
| background description: | ||
| Before the cycle, shape the problem, state the appetite, and sketch the rough solution. During | ||
| cooldown, place bets at a betting table; do not pull them from a backlog โ "no backlogs" is | ||
| explicit doctrine [[Shape Up ch.8]](https://basecamp.com/shapeup/2.2-chapter-08). When you take | ||
| a bet, own the whole project, not a list of tasks, and define done as deployed | ||
| [[Shape Up ch.10]](https://basecamp.com/shapeup/3.1-chapter-10). Track progress with hill | ||
| charts (uphill = unsolved, downhill = just execution), not percent-complete or burndown | ||
| [[Shape Up]](https://basecamp.com/shapeup). Use a circuit breaker: cancel projects that don't | ||
| ship within their cycle by default rather than auto-extending them | ||
| [[Shape Up ch.8]](https://basecamp.com/shapeup/2.2-chapter-08). During cooldown, fix bugs, plan | ||
| cycles, and make the next bets | ||
| [[how we work]](https://github.com/basecamp/handbook/blob/master/how-we-work.md). | ||
| QA is a two-person team running manual, guided exploratory testing against ~100-item | ||
| per-product checklists (not exhaustive test-case matrices), plus accessibility passes with | ||
| screen readers and a home-grown BackstopJS visual-regression suite | ||
| As a two-person QA team, run manual, guided exploratory testing against ~100-item | ||
| per-product checklists (not exhaustive test-case matrices), then run accessibility passes with | ||
| screen readers and the home-grown BackstopJS visual-regression suite | ||
| [[all about QA]](https://dev.37signals.com/all-about-qa/). | ||
@@ -58,0 +61,0 @@ |
@@ -23,12 +23,11 @@ # Every โ dev culture profile | ||
| The CEP plugin ships a six-step loop: **brainstorm โ plan โ work โ simplify โ review โ | ||
| compound** [[CEP]](https://github.com/EveryInc/compound-engineering-plugin). Every's own guide | ||
| describes the core cycle in four beats โ **plan โ work โ review โ compound โ repeat** โ with | ||
| `simplify` being the extra gate the plugin inserts | ||
| [[guide]](https://every.to/guides/compound-engineering). The compound step (`/ce-compound`) | ||
| writes learnings to `docs/solutions/`, which ground the next loop โ knowledge accretes in the | ||
| repo, not in heads | ||
| Run the six-step loop: **brainstorm โ plan โ work โ simplify โ review โ compound** | ||
| [[CEP]](https://github.com/EveryInc/compound-engineering-plugin). Use the four-beat core cycle | ||
| โ **plan โ work โ review โ compound โ repeat** โ and keep `simplify` as the extra gate the | ||
| plugin inserts [[guide]](https://every.to/guides/compound-engineering). At the compound step | ||
| (`/ce-compound`), write learnings to `docs/solutions/` and use them to ground the next loop โ | ||
| make knowledge accrete in the repo, not in heads | ||
| [[ce-compound]](https://github.com/EveryInc/compound-engineering-plugin/blob/main/docs/skills/ce-compound.md). | ||
| Fully autonomous pipeline (`/lfg`): plan โ work โ review โ PR โ watch CI until green. Reviewer | ||
| personas live as skill-local prompt assets (29 skills, 0 standalone agents post-migration) | ||
| For the fully autonomous pipeline (`/lfg`), plan โ work โ review โ PR โ watch CI until green. | ||
| Keep reviewer personas as skill-local prompt assets (29 skills, 0 standalone agents post-migration) | ||
| [[CEP]](https://github.com/EveryInc/compound-engineering-plugin). | ||
@@ -35,0 +34,0 @@ |
@@ -5,12 +5,11 @@ # Workflow โ Every | ||
| The CEP plugin ships a six-step loop: **brainstorm โ plan โ work โ simplify โ review โ | ||
| compound** [[CEP]](https://github.com/EveryInc/compound-engineering-plugin). Every's own guide | ||
| describes the core cycle in four beats โ **plan โ work โ review โ compound โ repeat** โ with | ||
| `simplify` being the extra gate the plugin inserts | ||
| [[guide]](https://every.to/guides/compound-engineering). The compound step (`/ce-compound`) | ||
| writes learnings to `docs/solutions/`, which ground the next loop โ knowledge accretes in the | ||
| repo, not in heads | ||
| Run the six-step loop: **brainstorm โ plan โ work โ simplify โ review โ compound** | ||
| [[CEP]](https://github.com/EveryInc/compound-engineering-plugin). Use the four-beat core cycle | ||
| โ **plan โ work โ review โ compound โ repeat** โ and keep `simplify` as the extra gate the | ||
| plugin inserts [[guide]](https://every.to/guides/compound-engineering). At the compound step | ||
| (`/ce-compound`), write learnings to `docs/solutions/` and use them to ground the next loop โ | ||
| make knowledge accrete in the repo, not in heads | ||
| [[ce-compound]](https://github.com/EveryInc/compound-engineering-plugin/blob/main/docs/skills/ce-compound.md). | ||
| Fully autonomous pipeline (`/lfg`): plan โ work โ review โ PR โ watch CI until green. Reviewer | ||
| personas live as skill-local prompt assets (29 skills, 0 standalone agents post-migration) | ||
| For the fully autonomous pipeline (`/lfg`), plan โ work โ review โ PR โ watch CI until green. | ||
| Keep reviewer personas as skill-local prompt assets (29 skills, 0 standalone agents post-migration) | ||
| [[CEP]](https://github.com/EveryInc/compound-engineering-plugin). |
@@ -40,12 +40,14 @@ --- | ||
| The CEP plugin ships a six-step loop: **brainstorm โ plan โ work โ simplify โ review โ | ||
| compound** [[CEP]](https://github.com/EveryInc/compound-engineering-plugin). Every's own guide | ||
| describes the core cycle in four beats โ **plan โ work โ review โ compound โ repeat** โ with | ||
| `simplify` being the extra gate the plugin inserts | ||
| [[guide]](https://every.to/guides/compound-engineering). The compound step (`/ce-compound`) | ||
| writes learnings to `docs/solutions/`, which ground the next loop โ knowledge accretes in the | ||
| repo, not in heads | ||
| Execute these checkpoints before and during the task. Treat them as required actions, not | ||
| background description: | ||
| Run the six-step loop: **brainstorm โ plan โ work โ simplify โ review โ compound** | ||
| [[CEP]](https://github.com/EveryInc/compound-engineering-plugin). Use the four-beat core cycle | ||
| โ **plan โ work โ review โ compound โ repeat** โ and keep `simplify` as the extra gate the | ||
| plugin inserts [[guide]](https://every.to/guides/compound-engineering). At the compound step | ||
| (`/ce-compound`), write learnings to `docs/solutions/` and use them to ground the next loop โ | ||
| make knowledge accrete in the repo, not in heads | ||
| [[ce-compound]](https://github.com/EveryInc/compound-engineering-plugin/blob/main/docs/skills/ce-compound.md). | ||
| Fully autonomous pipeline (`/lfg`): plan โ work โ review โ PR โ watch CI until green. Reviewer | ||
| personas live as skill-local prompt assets (29 skills, 0 standalone agents post-migration) | ||
| For the fully autonomous pipeline (`/lfg`), plan โ work โ review โ PR โ watch CI until green. | ||
| Keep reviewer personas as skill-local prompt assets (29 skills, 0 standalone agents post-migration) | ||
| [[CEP]](https://github.com/EveryInc/compound-engineering-plugin). | ||
@@ -52,0 +54,0 @@ |
@@ -24,18 +24,18 @@ # Linear โ dev culture profile | ||
| Work runs in *n*-week cycles (2 weeks is typical), unfinished items roll forward | ||
| automatically rather than triggering scope negotiation, and a manageable backlog beats an | ||
| exhaustive one [[Method: introduction]](https://linear.app/method/introduction). Projects | ||
| (defined loosely as "multiple people, more than two weeks of work") are led by a rotating | ||
| project lead โ nobody is the permanent lead, and the rotation is deliberate so every engineer | ||
| learns to run one [[how we run projects]](https://linear.app/now/how-we-run-projects-at-linear). | ||
| Leads write concise 1-2 page specs covering why/what/how before building, post weekly project | ||
| updates, and use milestones to define "done" per release stage; the weekly product meeting is | ||
| built around demos rather than status reports | ||
| Run work in *n*-week cycles (2 weeks is typical). Roll unfinished items forward automatically | ||
| rather than triggering scope negotiation, and keep a manageable backlog instead of an | ||
| exhaustive one [[Method: introduction]](https://linear.app/method/introduction). For projects | ||
| (defined loosely as "multiple people, more than two weeks of work"), rotate the project lead; | ||
| do not make anyone permanent, and use the rotation to teach every engineer to run one | ||
| [[how we run projects]](https://linear.app/now/how-we-run-projects-at-linear). Before building, | ||
| write a concise 1-2 page spec covering why/what/how. Post weekly project updates and use | ||
| milestones to define "done" per release stage; build the weekly product meeting around demos, | ||
| not status reports | ||
| [[how we run projects]](https://linear.app/now/how-we-run-projects-at-linear). Planning is | ||
| continuous, not a scheduled batch process: incoming ideas and requests are triaged directly | ||
| into "candidate projects" as they arrive, so a quarter's planning session starts from an | ||
| continuous, not a scheduled batch process: triage incoming ideas and requests directly into | ||
| "candidate projects" as they arrive, so a quarter's planning session starts from an | ||
| already-vetted list instead of a blank page | ||
| [[continuous planning]](https://linear.app/now/continuous-planning-in-linear). Quality is a | ||
| weekly team habit, not a phase: every engineer ships at least one small, non-bug quality fix | ||
| each week and presents it at a dedicated Wednesday standup ("Quality Wednesdays") โ over | ||
| weekly team habit, not a phase: have every engineer ship at least one small, non-bug quality | ||
| fix each week and present it at a dedicated Wednesday standup ("Quality Wednesdays") โ over | ||
| 1,000 such fixes shipped in two years | ||
@@ -42,0 +42,0 @@ [[Quality Wednesdays]](https://linear.app/now/quality-wednesdays). |
@@ -5,19 +5,19 @@ # Workflow โ Linear | ||
| Work runs in *n*-week cycles (2 weeks is typical), unfinished items roll forward | ||
| automatically rather than triggering scope negotiation, and a manageable backlog beats an | ||
| exhaustive one [[Method: introduction]](https://linear.app/method/introduction). Projects | ||
| (defined loosely as "multiple people, more than two weeks of work") are led by a rotating | ||
| project lead โ nobody is the permanent lead, and the rotation is deliberate so every engineer | ||
| learns to run one [[how we run projects]](https://linear.app/now/how-we-run-projects-at-linear). | ||
| Leads write concise 1-2 page specs covering why/what/how before building, post weekly project | ||
| updates, and use milestones to define "done" per release stage; the weekly product meeting is | ||
| built around demos rather than status reports | ||
| Run work in *n*-week cycles (2 weeks is typical). Roll unfinished items forward automatically | ||
| rather than triggering scope negotiation, and keep a manageable backlog instead of an | ||
| exhaustive one [[Method: introduction]](https://linear.app/method/introduction). For projects | ||
| (defined loosely as "multiple people, more than two weeks of work"), rotate the project lead; | ||
| do not make anyone permanent, and use the rotation to teach every engineer to run one | ||
| [[how we run projects]](https://linear.app/now/how-we-run-projects-at-linear). Before building, | ||
| write a concise 1-2 page spec covering why/what/how. Post weekly project updates and use | ||
| milestones to define "done" per release stage; build the weekly product meeting around demos, | ||
| not status reports | ||
| [[how we run projects]](https://linear.app/now/how-we-run-projects-at-linear). Planning is | ||
| continuous, not a scheduled batch process: incoming ideas and requests are triaged directly | ||
| into "candidate projects" as they arrive, so a quarter's planning session starts from an | ||
| continuous, not a scheduled batch process: triage incoming ideas and requests directly into | ||
| "candidate projects" as they arrive, so a quarter's planning session starts from an | ||
| already-vetted list instead of a blank page | ||
| [[continuous planning]](https://linear.app/now/continuous-planning-in-linear). Quality is a | ||
| weekly team habit, not a phase: every engineer ships at least one small, non-bug quality fix | ||
| each week and presents it at a dedicated Wednesday standup ("Quality Wednesdays") โ over | ||
| weekly team habit, not a phase: have every engineer ship at least one small, non-bug quality | ||
| fix each week and present it at a dedicated Wednesday standup ("Quality Wednesdays") โ over | ||
| 1,000 such fixes shipped in two years | ||
| [[Quality Wednesdays]](https://linear.app/now/quality-wednesdays). |
@@ -42,18 +42,21 @@ --- | ||
| Work runs in *n*-week cycles (2 weeks is typical), unfinished items roll forward | ||
| automatically rather than triggering scope negotiation, and a manageable backlog beats an | ||
| exhaustive one [[Method: introduction]](https://linear.app/method/introduction). Projects | ||
| (defined loosely as "multiple people, more than two weeks of work") are led by a rotating | ||
| project lead โ nobody is the permanent lead, and the rotation is deliberate so every engineer | ||
| learns to run one [[how we run projects]](https://linear.app/now/how-we-run-projects-at-linear). | ||
| Leads write concise 1-2 page specs covering why/what/how before building, post weekly project | ||
| updates, and use milestones to define "done" per release stage; the weekly product meeting is | ||
| built around demos rather than status reports | ||
| Execute these checkpoints before and during the task. Treat them as required actions, not | ||
| background description: | ||
| Run work in *n*-week cycles (2 weeks is typical). Roll unfinished items forward automatically | ||
| rather than triggering scope negotiation, and keep a manageable backlog instead of an | ||
| exhaustive one [[Method: introduction]](https://linear.app/method/introduction). For projects | ||
| (defined loosely as "multiple people, more than two weeks of work"), rotate the project lead; | ||
| do not make anyone permanent, and use the rotation to teach every engineer to run one | ||
| [[how we run projects]](https://linear.app/now/how-we-run-projects-at-linear). Before building, | ||
| write a concise 1-2 page spec covering why/what/how. Post weekly project updates and use | ||
| milestones to define "done" per release stage; build the weekly product meeting around demos, | ||
| not status reports | ||
| [[how we run projects]](https://linear.app/now/how-we-run-projects-at-linear). Planning is | ||
| continuous, not a scheduled batch process: incoming ideas and requests are triaged directly | ||
| into "candidate projects" as they arrive, so a quarter's planning session starts from an | ||
| continuous, not a scheduled batch process: triage incoming ideas and requests directly into | ||
| "candidate projects" as they arrive, so a quarter's planning session starts from an | ||
| already-vetted list instead of a blank page | ||
| [[continuous planning]](https://linear.app/now/continuous-planning-in-linear). Quality is a | ||
| weekly team habit, not a phase: every engineer ships at least one small, non-bug quality fix | ||
| each week and presents it at a dedicated Wednesday standup ("Quality Wednesdays") โ over | ||
| weekly team habit, not a phase: have every engineer ship at least one small, non-bug quality | ||
| fix each week and present it at a dedicated Wednesday standup ("Quality Wednesdays") โ over | ||
| 1,000 such fixes shipped in two years | ||
@@ -60,0 +63,0 @@ [[Quality Wednesdays]](https://linear.app/now/quality-wednesdays). |
@@ -25,24 +25,28 @@ # Oxide โ dev culture profile | ||
| Decisions move through explicit RFD states โ prediscussion โ ideation โ discussion โ | ||
| published โ committed/abandoned โ with discussion happening in GitHub PRs | ||
| [[RFD 1]](https://rfd.shared.oxide.computer/rfd/0001). Engineering work itself has named | ||
| phases: scoping โ exploration โ prototyping โ determination โ development โ validation โ | ||
| stress โ production [[RFD 5]](https://rfd.shared.oxide.computer/rfd/0005). Decision values | ||
| are explicit and include both rigor *and* urgency โ analysis is not allowed to become | ||
| avoidance [[RFD 113]](https://rfd.shared.oxide.computer/rfd/0113). | ||
| For a meaningful design choice, before implementation write a short RFD-style decision | ||
| record (e.g. `RFD-topic-slug.md`) containing: the problem/decision, options considered, the | ||
| chosen approach with tradeoffs, and failure modes/validation โ this is a lightweight record | ||
| in the spirit of Oxide's RFD process, not a full formal RFD for every edit | ||
| [[RFD 1]](https://rfd.shared.oxide.computer/rfd/0001). Move it through explicit RFD states โ | ||
| prediscussion โ ideation โ discussion โ published โ committed/abandoned โ and discuss it in | ||
| GitHub PRs [[RFD 1]](https://rfd.shared.oxide.computer/rfd/0001). Name the engineering phase | ||
| before acting: scoping โ exploration โ prototyping โ determination โ development โ | ||
| validation โ stress โ production [[RFD 5]](https://rfd.shared.oxide.computer/rfd/0005). Apply | ||
| both rigor and urgency; do not let analysis become avoidance | ||
| [[RFD 113]](https://rfd.shared.oxide.computer/rfd/0113). | ||
| Day to day: remote-first with recorded meetings, no formalized performance review, no | ||
| engineering metrics, and a weekly Demo Friday โ show working things continuously | ||
| Work remote-first, record meetings, avoid formalized performance reviews and engineering | ||
| metrics, and show working things continuously at a weekly Demo Friday | ||
| [[engineering culture]](https://oxide.computer/blog/engineering-culture). Hardware teams | ||
| work distributed by investing in prototyping tooling; teams "don't need approval or | ||
| sign-off, we just go do what's right" | ||
| work distributed by investing in prototyping tooling; do not wait for approval or sign-off โ | ||
| "we just go do what's right" | ||
| [[remote hardware]](https://oxide.computer/blog/building-big-systems-with-remote-hardware-teams). | ||
| Baseline hygiene is non-negotiable: cargo check, clippy, rustfmt, nextest in the loop; CI | ||
| runs on buildomat, their first-party job orchestrator โ when the tool you need doesn't | ||
| exist, you build it [[omicron PR 10628]](https://github.com/oxidecomputer/omicron/pull/10628) | ||
| [[buildomat]](https://github.com/oxidecomputer/buildomat). Long-running control-plane | ||
| operations are modeled as observable, recoverable sagas rather than fire-and-forget scripts | ||
| Keep cargo check, clippy, rustfmt, and nextest in the loop; run CI on buildomat, and build | ||
| the tool you need when it does not exist | ||
| [[omicron PR 10628]](https://github.com/oxidecomputer/omicron/pull/10628) | ||
| [[buildomat]](https://github.com/oxidecomputer/buildomat). Model long-running control-plane | ||
| operations as observable, recoverable sagas rather than fire-and-forget scripts | ||
| [[RFD 107]](https://rfd.shared.oxide.computer/rfd/0107). Agent-era note: repos carry both | ||
| CLAUDE.md and AGENTS.md ("that covers all agent harnesses in wide use"), with nested, | ||
| generated, code-local agent instructions over one giant top-level file | ||
| CLAUDE.md and AGENTS.md ("that covers all agent harnesses in wide use"); keep agent | ||
| instructions nested, generated, and code-local rather than in one giant top-level file | ||
| [[omicron PR 10628]](https://github.com/oxidecomputer/omicron/pull/10628). | ||
@@ -49,0 +53,0 @@ |
@@ -5,24 +5,28 @@ # Workflow โ Oxide | ||
| Decisions move through explicit RFD states โ prediscussion โ ideation โ discussion โ | ||
| published โ committed/abandoned โ with discussion happening in GitHub PRs | ||
| [[RFD 1]](https://rfd.shared.oxide.computer/rfd/0001). Engineering work itself has named | ||
| phases: scoping โ exploration โ prototyping โ determination โ development โ validation โ | ||
| stress โ production [[RFD 5]](https://rfd.shared.oxide.computer/rfd/0005). Decision values | ||
| are explicit and include both rigor *and* urgency โ analysis is not allowed to become | ||
| avoidance [[RFD 113]](https://rfd.shared.oxide.computer/rfd/0113). | ||
| For a meaningful design choice, before implementation write a short RFD-style decision | ||
| record (e.g. `RFD-topic-slug.md`) containing: the problem/decision, options considered, the | ||
| chosen approach with tradeoffs, and failure modes/validation โ this is a lightweight record | ||
| in the spirit of Oxide's RFD process, not a full formal RFD for every edit | ||
| [[RFD 1]](https://rfd.shared.oxide.computer/rfd/0001). Move it through explicit RFD states โ | ||
| prediscussion โ ideation โ discussion โ published โ committed/abandoned โ and discuss it in | ||
| GitHub PRs [[RFD 1]](https://rfd.shared.oxide.computer/rfd/0001). Name the engineering phase | ||
| before acting: scoping โ exploration โ prototyping โ determination โ development โ | ||
| validation โ stress โ production [[RFD 5]](https://rfd.shared.oxide.computer/rfd/0005). Apply | ||
| both rigor and urgency; do not let analysis become avoidance | ||
| [[RFD 113]](https://rfd.shared.oxide.computer/rfd/0113). | ||
| Day to day: remote-first with recorded meetings, no formalized performance review, no | ||
| engineering metrics, and a weekly Demo Friday โ show working things continuously | ||
| Work remote-first, record meetings, avoid formalized performance reviews and engineering | ||
| metrics, and show working things continuously at a weekly Demo Friday | ||
| [[engineering culture]](https://oxide.computer/blog/engineering-culture). Hardware teams | ||
| work distributed by investing in prototyping tooling; teams "don't need approval or | ||
| sign-off, we just go do what's right" | ||
| work distributed by investing in prototyping tooling; do not wait for approval or sign-off โ | ||
| "we just go do what's right" | ||
| [[remote hardware]](https://oxide.computer/blog/building-big-systems-with-remote-hardware-teams). | ||
| Baseline hygiene is non-negotiable: cargo check, clippy, rustfmt, nextest in the loop; CI | ||
| runs on buildomat, their first-party job orchestrator โ when the tool you need doesn't | ||
| exist, you build it [[omicron PR 10628]](https://github.com/oxidecomputer/omicron/pull/10628) | ||
| [[buildomat]](https://github.com/oxidecomputer/buildomat). Long-running control-plane | ||
| operations are modeled as observable, recoverable sagas rather than fire-and-forget scripts | ||
| Keep cargo check, clippy, rustfmt, and nextest in the loop; run CI on buildomat, and build | ||
| the tool you need when it does not exist | ||
| [[omicron PR 10628]](https://github.com/oxidecomputer/omicron/pull/10628) | ||
| [[buildomat]](https://github.com/oxidecomputer/buildomat). Model long-running control-plane | ||
| operations as observable, recoverable sagas rather than fire-and-forget scripts | ||
| [[RFD 107]](https://rfd.shared.oxide.computer/rfd/0107). Agent-era note: repos carry both | ||
| CLAUDE.md and AGENTS.md ("that covers all agent harnesses in wide use"), with nested, | ||
| generated, code-local agent instructions over one giant top-level file | ||
| CLAUDE.md and AGENTS.md ("that covers all agent harnesses in wide use"); keep agent | ||
| instructions nested, generated, and code-local rather than in one giant top-level file | ||
| [[omicron PR 10628]](https://github.com/oxidecomputer/omicron/pull/10628). |
@@ -42,24 +42,31 @@ --- | ||
| Decisions move through explicit RFD states โ prediscussion โ ideation โ discussion โ | ||
| published โ committed/abandoned โ with discussion happening in GitHub PRs | ||
| [[RFD 1]](https://rfd.shared.oxide.computer/rfd/0001). Engineering work itself has named | ||
| phases: scoping โ exploration โ prototyping โ determination โ development โ validation โ | ||
| stress โ production [[RFD 5]](https://rfd.shared.oxide.computer/rfd/0005). Decision values | ||
| are explicit and include both rigor *and* urgency โ analysis is not allowed to become | ||
| avoidance [[RFD 113]](https://rfd.shared.oxide.computer/rfd/0113). | ||
| Execute these checkpoints before and during the task. Treat them as required actions, not | ||
| background description: | ||
| Day to day: remote-first with recorded meetings, no formalized performance review, no | ||
| engineering metrics, and a weekly Demo Friday โ show working things continuously | ||
| For a meaningful design choice, before implementation write a short RFD-style decision | ||
| record (e.g. `RFD-topic-slug.md`) containing: the problem/decision, options considered, the | ||
| chosen approach with tradeoffs, and failure modes/validation โ this is a lightweight record | ||
| in the spirit of Oxide's RFD process, not a full formal RFD for every edit | ||
| [[RFD 1]](https://rfd.shared.oxide.computer/rfd/0001). Move it through explicit RFD states โ | ||
| prediscussion โ ideation โ discussion โ published โ committed/abandoned โ and discuss it in | ||
| GitHub PRs [[RFD 1]](https://rfd.shared.oxide.computer/rfd/0001). Name the engineering phase | ||
| before acting: scoping โ exploration โ prototyping โ determination โ development โ | ||
| validation โ stress โ production [[RFD 5]](https://rfd.shared.oxide.computer/rfd/0005). Apply | ||
| both rigor and urgency; do not let analysis become avoidance | ||
| [[RFD 113]](https://rfd.shared.oxide.computer/rfd/0113). | ||
| Work remote-first, record meetings, avoid formalized performance reviews and engineering | ||
| metrics, and show working things continuously at a weekly Demo Friday | ||
| [[engineering culture]](https://oxide.computer/blog/engineering-culture). Hardware teams | ||
| work distributed by investing in prototyping tooling; teams "don't need approval or | ||
| sign-off, we just go do what's right" | ||
| work distributed by investing in prototyping tooling; do not wait for approval or sign-off โ | ||
| "we just go do what's right" | ||
| [[remote hardware]](https://oxide.computer/blog/building-big-systems-with-remote-hardware-teams). | ||
| Baseline hygiene is non-negotiable: cargo check, clippy, rustfmt, nextest in the loop; CI | ||
| runs on buildomat, their first-party job orchestrator โ when the tool you need doesn't | ||
| exist, you build it [[omicron PR 10628]](https://github.com/oxidecomputer/omicron/pull/10628) | ||
| [[buildomat]](https://github.com/oxidecomputer/buildomat). Long-running control-plane | ||
| operations are modeled as observable, recoverable sagas rather than fire-and-forget scripts | ||
| Keep cargo check, clippy, rustfmt, and nextest in the loop; run CI on buildomat, and build | ||
| the tool you need when it does not exist | ||
| [[omicron PR 10628]](https://github.com/oxidecomputer/omicron/pull/10628) | ||
| [[buildomat]](https://github.com/oxidecomputer/buildomat). Model long-running control-plane | ||
| operations as observable, recoverable sagas rather than fire-and-forget scripts | ||
| [[RFD 107]](https://rfd.shared.oxide.computer/rfd/0107). Agent-era note: repos carry both | ||
| CLAUDE.md and AGENTS.md ("that covers all agent harnesses in wide use"), with nested, | ||
| generated, code-local agent instructions over one giant top-level file | ||
| CLAUDE.md and AGENTS.md ("that covers all agent harnesses in wide use"); keep agent | ||
| instructions nested, generated, and code-local rather than in one giant top-level file | ||
| [[omicron PR 10628]](https://github.com/oxidecomputer/omicron/pull/10628). | ||
@@ -66,0 +73,0 @@ |
@@ -21,7 +21,7 @@ # Theo Browne (t3.gg) โ dev culture profile | ||
| "Bleed responsibly" โ reach for bleeding-edge tools only in reversible places where you can | ||
| "Bleed responsibly": reach for bleeding-edge tools only in reversible places where you can | ||
| afford the cost [[T3 intro]](https://create.t3.gg/en/introduction/). Optimize for delivery and | ||
| iteration, not architecture cosplay: speed of shipping, DX, and maintainability over ceremony | ||
| [[2023 tech]](https://t3.gg/blog/post/2023-tech). Build-your-own when unhappy with incumbents โ | ||
| Ping, UploadThing, and T3 Chat were all born that way | ||
| iteration, not architecture cosplay; prioritize speed of shipping, DX, and maintainability over ceremony | ||
| [[2023 tech]](https://t3.gg/blog/post/2023-tech). Build your own replacement when unhappy with | ||
| incumbents โ Ping, UploadThing, and T3 Chat were all born that way | ||
| [[t3dotgg]](https://github.com/t3dotgg). No further first-party detail on day-to-day process is | ||
@@ -28,0 +28,0 @@ currently sourced; treat this section as thin and directional rather than a documented |
@@ -5,9 +5,9 @@ # Workflow โ Theo Browne | ||
| "Bleed responsibly" โ reach for bleeding-edge tools only in reversible places where you can | ||
| "Bleed responsibly": reach for bleeding-edge tools only in reversible places where you can | ||
| afford the cost [[T3 intro]](https://create.t3.gg/en/introduction/). Optimize for delivery and | ||
| iteration, not architecture cosplay: speed of shipping, DX, and maintainability over ceremony | ||
| [[2023 tech]](https://t3.gg/blog/post/2023-tech). Build-your-own when unhappy with incumbents โ | ||
| Ping, UploadThing, and T3 Chat were all born that way | ||
| iteration, not architecture cosplay; prioritize speed of shipping, DX, and maintainability over ceremony | ||
| [[2023 tech]](https://t3.gg/blog/post/2023-tech). Build your own replacement when unhappy with | ||
| incumbents โ Ping, UploadThing, and T3 Chat were all born that way | ||
| [[t3dotgg]](https://github.com/t3dotgg). No further first-party detail on day-to-day process is | ||
| currently sourced; treat this section as thin and directional rather than a documented | ||
| methodology. |
@@ -46,7 +46,10 @@ --- | ||
| "Bleed responsibly" โ reach for bleeding-edge tools only in reversible places where you can | ||
| Execute these checkpoints before and during the task. Treat them as required actions, not | ||
| background description: | ||
| "Bleed responsibly": reach for bleeding-edge tools only in reversible places where you can | ||
| afford the cost [[T3 intro]](https://create.t3.gg/en/introduction/). Optimize for delivery and | ||
| iteration, not architecture cosplay: speed of shipping, DX, and maintainability over ceremony | ||
| [[2023 tech]](https://t3.gg/blog/post/2023-tech). Build-your-own when unhappy with incumbents โ | ||
| Ping, UploadThing, and T3 Chat were all born that way | ||
| iteration, not architecture cosplay; prioritize speed of shipping, DX, and maintainability over ceremony | ||
| [[2023 tech]](https://t3.gg/blog/post/2023-tech). Build your own replacement when unhappy with | ||
| incumbents โ Ping, UploadThing, and T3 Chat were all born that way | ||
| [[t3dotgg]](https://github.com/t3dotgg). No further first-party detail on day-to-day process is | ||
@@ -53,0 +56,0 @@ currently sourced; treat this section as thin and directional rather than a documented |
@@ -30,2 +30,5 @@ --- | ||
| Execute these checkpoints before and during the task. Treat them as required actions, not | ||
| background description: | ||
| {{workflowShape}} | ||
@@ -32,0 +35,0 @@ |
@@ -43,2 +43,8 @@ # Distilling: profile โ develop-like-<slug> skill | ||
| each with a `[source]` link. No source, no claim. | ||
| - Workflow steps as checkpointed imperatives the agent executes before and during the task, | ||
| not culture-summary prose (for example: "Before writing code: state the appetite in weeks | ||
| and list what you will NOT build this cycle"). Each step carries its `[source]` citation. | ||
| - If the profiled workflow expects an artifact before code (decision record, appetite/scope | ||
| list, plan, etc.), name that artifact explicitly, state its minimum required contents, and | ||
| require producing it before implementation โ not just describing the practice. | ||
| - Capture workflow *shape*, not prompt-pile trivia. Fidelity that degrades utility loses: | ||
@@ -45,0 +51,0 @@ distilled principles beat verbatim mimicry. |
@@ -13,3 +13,3 @@ --- | ||
| author: marcusrbrown | ||
| version: "0.1.0" | ||
| version: "0.4.1" | ||
| repository: https://github.com/marcusrbrown/dev-like | ||
@@ -16,0 +16,0 @@ --- |
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
153897
10.92%55
1.85%1172
31.54%102
14.61%6
20%