DinoStack
AGENTS.md14 starsChanged 12 days agoApache-2.0View on GitHub
A portable package of the agentic engineering protocol for AI-assisted software development. It provides a structured delegation model, risk classification, adversarial review loops, code quality gates, git workflow conventions, and named agent definitions.
- Pipes a download into a shell
- Reads credentials
- Deletes or force-pushes
- Commits and pushes
Where files are headingNew AGENTS.md files have more rules about keeping secrets out of the code, and fewer about code style.
Of the AGENTS.md files we read, the 31,843 first seen in the last six months, against the older ones: the kind of rule that gained most share, and the kind that lost most. About files like this in general, not this one, and an estimate, since a kind is a pattern in the words.
In this repository17 other files it gives its agents.
- bin/AGENTS.mdAGENTS.md
- .codex/AGENTS.mdAGENTS.md
- .github/workflows/AGENTS.mdAGENTS.md
- hooks/AGENTS.mdAGENTS.md
- .kimi/AGENTS.mdAGENTS.md
- CLAUDE.mdCLAUDE.md
- .github/copilot-instructions.mdCopilot instructions
- .cursor/rules/agent-methodology.mdcCursor rule
- .cursor/rules/code-standards.mdcCursor rule
- .cursor/rules/conventions.mdcCursor rule
- .cursor/rules/frontmatter/agent-methodology.yamlCursor rule
- .cursor/rules/frontmatter/code-standards.yamlCursor rule
- .cursor/rules/frontmatter/conventions.yamlCursor rule
- dinostackSkill
- contentSkill
- dinostackSkill
- dinostackSkill
The file
We split this AGENTS.md into the rules it gives an agent
6 rules. About 0 are common, 1 is distinctive, and 5 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈1
Distinctive · estimate
This author's own choices. Worth a look.
5
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 17
No enforcement hook may deny conductor Read/Grep/Glob to force delegation, and none may gate on inferred session capability - flat …
- Very specific: line 60
Update local main: bin/ds-base-sync <this-checkout-path> main (run from this repo's own checkout, since it's both ticket repo and tool …
- Very specific: line 74
After any content/SKILL.md change, run .claude/build.sh to regenerate its SKILL.md copy (.pi/build.sh belongs to the catch-up chore).
- Very specific: line 79
Verify DCO author/sign-off with lowercase git log --format=%ae (raw) - uppercase %aE and git show both APPLY .mailmap, which can show a …
- Distinctive: line 89
After an isolation-worktree engineer commits, the main checkout's view of that branch ref can lag behind the worktree's own HEAD.
- Very specific: line 107
Never include "mode": "opt-in" in doc or adapter example JSON unless demonstrating opt-in activation - it silently disables the methodology …
≈ “Common” is an estimate: at least 1 in 5 of the 40,246 AGENTS.md files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
dinostack
A portable package of the agentic engineering protocol for AI-assisted software development. It provides a structured delegation model, risk classification, adversarial review loops, code quality gates, git workflow conventions, and named agent definitions.
Decisions
- Methodology source-of-truth:
content/sections/01-*.md-12-*.md(12 sections;06-capability-preflight.mdadded by P2, renumbering 06-11 to 07-12). Editcontent/sections/for any methodology change -content/rules/agent-methodology.mdno longer exists. scripts/build-methodology.shis the canonical assembly script; it also supports--corpus minimal|medium|full(DS-204, defaultfullwith no flag - byte-identical to the pre-DS-204 output). Only.claude/and.gemini/corpus-qualify their build: each invokes it TWICE per build - once plain/--corpus fullfor a full-corpus sibling file, once with--corpus minimal --full-text-name <sibling-basename>for the skill's trigger-loaded embed - so their skill bodies default to the minimal corpus while a full-corpus fallback stays reachable via a generated "Deferred at this corpus" pointer block..kimi/and.copilot/(generating.github/skills/) were flipped the same way and then HELD BACK in the same DS-204 round (runtime QA came back INCONCLUSIVE for both - no drivable runtime on the verification host) - both invoke it plain, full corpus, unconditionally, same as.codex/build.sh(bash "$REPO_DIR/scripts/build-methodology.sh", unaffected by DS-204) and every other adapter..cursor/build.shdiffers in output structure and skips it..claude/install.shmanages~/.claude/CLAUDE.mdvia amanaged_contentPython string fromcontent/templates/claude-managed-content.md(lean Skill Loading table). DS-143: the 3 @-import lines (METHODOLOGY.md,code-standards.md,conventions.md) drop when the skill symlink resolves (SKILL_LINK_OK) - methodology loads via/dinostackinstead, embedded verbatim into.claude/skills/dinostack/SKILL.mdby.claude/build.sh. Broken symlink: install.sh keeps imports and warns. Re-run install.sh after template changes.bootstrap.sh(repo root, PR #109) is the publiccurl | bashinstaller: clones to$(pwd)/DinoStack(overrideAE_DEST_DIR), writes the resolved path to~/.agentic/agentic-engineering-config.json(repo_dir)./ds-update-agentic-engineeringreadsrepo_dirat runtime (git-rev-parse validated, falls back to~/DinoStack).skill_auto_loadopt-in enforcement (PR #97):hooks/skill-auto-load-check.shwired per adapter - Claude/Codex: UserPromptSubmit; Gemini: BeforeAgent. Kimi's SessionStart nudge is an independent reimplementation, not a consumer of this file - a repo-wide grep forskill-auto-load-checkreturns no.kimihit. OpenCode:session.createdplugin (.opencode/plugins/session-context.ts). Cursor: no hook (loaded via .mdc). All install scripts use read-modify-write for config updates - bare overwrite destroys existing keys. OpenCode reads~/.config/opencode/agentic-engineering.json; all other adapters read~/.claude/agentic-engineering.json. DS-218 added an applicability filter: the hook fires whenskill_auto_load=trueand the turn's prompt looks like a software-development request, or when the prompt cannot be determined (fail-open) (seehooks/AGENTS.mdfor the fail-open contract).- FE/QA methodology (P0+P1+P2) shipped 2026-05-28 in 14 PRs (#137-#140, #142-#145, #149-#154).
qa_criteria.methodenum is now 7 values:browser,api,runtime-required,visual_conformance,accessibility,perceptual_diff,motion. Capability preflight default isblockingas of P2 (9 agents populated; skeptic + orchestration-planner are deliberate no-ops). Canonical new reference docs:content/references/capability-preflight.mdandcontent/references/frontend-discipline.md(7 sections + 8 Skeptic finding categories). Motion scenarios require Playwright (CDPEmulation.setEmulatedMedia); agent-browser cannot execute them. Storybook 6 ships URL format detection only; full SB6 framework adapter procedure improvements are deferred. - Project-level identity override:
ds-identity --scope projectwrites<repo>/.agentic/identity.yml. Effective identity resolves 4-tier confirmation-first: project-confirmed > global-confirmed > project-provisional > global-provisional > none. Gitignored per-developer. Resolver:bin/ds-identity+hooks/stop-context.js(5 regression tests inbin/tests/test_agentic_identity.py). - Telemetry-commit-on-PR:
commit_telemetrytoggle in.agentic/config.json(default true) makes/ds-implement-ticketPhase 8 commit.agentic/session-log/<dev>.jsonlas a separate commit when identity is confirmed (!.agentic/session-log/carve-out in.gitignore). Path-aware PR-checkout resolution + HEAD-branch soft-fail guard prevents wrong-branch commits. Eventual-consistency: a session's own line lands in the NEXT ticket's Phase 8 commit; non-/ds-implement-ticketPRs are not covered. - Progressive-disclosure kernel split (PR #340): the always-on methodology body keeps only the governance kernel inline; trigger-only detail lives in
content/references/**, reached by read-on-trigger pointers.content/references/design-goals.mdGoal 4 (three-question partition test) is canonical for inline-vs-defer. Sections 03/05/06/11 are NOT split - their reference files are supplements, not full copies. .agentic/tasks.jsonlownership is defined bybin/tests/fold_model.py(DS-108, #521), not prose; ordering is arrival-order only. Gates:test_fold_invariants.py,test_tasks_jsonl_fold.sh.- Host-harness instruction conflicts (#530,
d6b61e7b; DS-132 generalized one collision to four): kernel rule incontent/sections/02-delegation.md; catalog + delegation-suppression rule incontent/references/delegation-detail.md§Harness-Injected Instruction Conflicts. - No enforcement hook may deny conductor Read/Grep/Glob to force delegation, and none may gate on inferred session capability - flat prohibitions (#530):
hooks/AGENTS.md§No gating on inferred session capability. evals/is git-untracked (decision #203), stays that way pending explicit re-tracking; invisible (not merely ignored) inside an isolation worktree. Seeevals/AGENTS.md.- Post-merge local base-branch sync (#540, DS-121):
bin/ds-base-sync, called unconditionally at/ds-implement-ticketPhase 12 - NOT nested underauto_merge_on_ci_green(defaults false).divergedrequires BOTHbehind>0ANDahead>0; ahead-only isn't divergence. Taxonomy/recovery:content/references/base-branch-sync.md. - Hooks-snapshot dogfooding-gap closure (DS-54 follow-up): a merged hook fix stays dormant on this machine until an installer re-syncs the snapshot - the SessionStart nudge only fires at a brand-new session's first tool call, never mid-session or at merge time. Three mechanisms now close it:
bin/ds-doctor'scheck_hooks_snapshot_stalenesscheck (on-demand;--fixcallssync_hooks_snapshot, the identical call every adapterinstall.shalready makes unconditionally;half_appliedis NOT reported resolved by that sync alone - it only refreshes snapshot content, never an adapter's own hook config, so--fixonhalf_appliedreports it unfixable with an actionable "re-run that adapter's install.sh" message; a nonzero exit from the classifier is a WARN, never a silent OK);bin/ds-base-sync's non-blocking advisory note after every invocation (the one guaranteed post-merge trigger point, since Phase 12 calls it unconditionally; read-only, never mutates); andbin/ds-update's_hooks_snapshot_divergedcheck, which forces the adapter-install loop on itsold_head==new_headearly-return path when the live hooks/ source hash diverges from the snapshot's stored hash - closing the case where an operator manuallygit pulled a hooks change before runningds-update, leaving no diff for the normal rebuild-trigger logic to see (scripts/update.js, the interactive updater, has no direct equivalent on this path - it relies transitively on its own unconditionalrunDoctor()call instead). None of the three can auto-rewire a live session's hooks from a passive trigger - only an explicit--fixor an adapterinstall.shrun ever callssync_hooks_snapshot(the DS-54 invariant). All three hashing call sites (the sync writer, the SessionStart classifier, andds-update's divergence check) call the SOLEhooks_source_pathsfunction inscripts/lib/hooks-snapshot.sh- never a hand-copied path list. Friction cost: any operator with uncommitted localhooks/edits gets the full adapter-install loop forced on everyds-update"already up to date" run (the live hash differs from the last sync by construction) - expected, not a bug. Full detail:hooks/AGENTS.md§Downstream consumers "Merged is not live". Adapter asymmetry:.cursor/install.shand.opencode/install.shsymlink hook config directly into the checkout instead of snapshotting it, so those two harnesses have no dormancy gap at all - Claude Code (the primary harness), Codex, Gemini, and Kimi are the ones subject to it. - Resident-set budget ratchet (DS-68 redo, #532; redefined DS-143):
scripts/check-resident-budget.shmeasures only the post-manifest body ofcontent/templates/claude-managed-content.md(the Skill Loading table - the sole content resident every session after DS-143 stopped~/.claude/CLAUDE.md@-importing METHODOLOGY.md/conventions.md/code-standards.md). Workflow.github/workflows/resident-budget.yml; suitebin/tests/test_check_resident_budget.sh. Required onmain(ruleset14778332, 15 checks). THRESHOLD ratchets downward - lower it in the same PR as any deliberate shrink; runbash scripts/check-resident-budget.shfor the live figure, never trust a cited pair. Separate gatescripts/check-skill-embed-budget.sh(suitebin/tests/test_check_skill_embed_budget.sh) guards generated.claude/skills/dinostack/SKILL.mdthree ways: FLOOR (catches regression to pointer-only skill); CEILING (safety boundary on verified-safe injection size, not a tidiness budget - DS-45 found its own arithmetic is 1.1x a 2026-08-07 build-size snapshot (126,509 B, 598 B below the injection-confirmed 127,107 B figure), not 1.1x the injection-verified figure it claims to protect; the 2026-08-19 raise to 145,000 B was an explicit operator decision to unblock work, not a new measurement - see the CEILING constant's own comment); an embed-completeness check (DS-143 follow-up) pinningEXPECTED_SECTION_COUNT/EXPECTED_RULES_COUNTagainstcontent/sections/[0-9][0-9]-*.mdandcontent/rules/*.md(excludingmodule-manifest.md) - bump the matching constant in the same commit as any source add/remove/renumber.check-skill-embed-budgetis required onmaintoo (count moved 15->16 when this job was promoted, and 16->15 whencheck-codex-skill-syncwas dropped on 2026-10-31). DS-45 sweep RUN 2026-09-03 viascripts/skill-embed-sweep-harness.sh+docs/skill-embed-injection-sweep.md: headlessclaude -pprobes confirmed intact injection (tail canary,declared_total_bytes, and an exactpad_block_sha256match) at 140,000 / 145,000 / 150,000 / 160,000 B, so CEILING's current value (145,000 B) is now a genuinely verified-safe injection size - this result says nothing about whether raising CEILING is warranted; do not raise it on the basis of this sweep. Raising it remains a separate operator decision requiring its own new swept confirmation, exactly as before this sweep was run. - Root
MEMORY.mdis untracked (DS-129), same rationale as/decisions.md/.agentic/*: methodology self-improvement scratch, not shippable.MEMORY-archive.mdis deleted, the archive pattern retired (DS-130) - an archived entry stops being enforced once it leaves the always-loaded file. Fresh clones and worktree-isolated engineers have noMEMORY.md; put facts an engineer needs inAGENTS.mdor the spawn brief. - Command file size ratchet:
scripts/check-command-file-budget.shmeasures the raw on-disk byte size ofcontent/commands/ds-implement-ticket.mddirectly (wc -c, no build step) - closing the gap left bycheck-resident-budget.sh, which deliberately measures only the assembled resident set and never sees command files at all. That file grew from 233,942 B to 363,761 B in about two weeks with zero shrink commits before this gate existed. Workflow.github/workflows/command-file-budget.yml, regression suitebin/tests/test_check_command_file_budget.sh. THRESHOLD_BYTES has been raised five times since gate creation (DS-188, DS-170 rounds 2-4, DS-244) and lowered since; its live value is deliberately not recorded here (run the script) - it is meant to fire on sustained growth, not the next paragraph. Sharesscripts/lib/budget-gate.shwith the other budget gates (grep -rln '^source .*lib/budget-gate.sh' scripts/*.shfinds the current set), but not identically: every gate sourcing that library callsbudget_repo_dir/budget_file_bytes, while onlycheck-resident-budget.shcalls the exit-callingbudget_reportwrapper - this gate calls the underlyingbudget_evaldirectly instead (see the DS-182 paragraph below for why);check-skill-embed-budget.shcalls neither, hand-rolling its own OK-path tail (see the DS-182 paragraph below for why). Advisory, not required: it is deliberately NOT added to themainruleset's required-checks list - promoting it to a blocking check is a separate operator decision - but the job itself is NOTcontinue-on-error: it fails (goes red, with a::error::annotation) on overage like any other check. THRESHOLD_BYTES ratchets downward over time - lower it in the same PR as any deliberate compression of the file; never raise it to accommodate un-triaged growth, and never trust a cited figure - runbash scripts/check-command-file-budget.shfor the live number. - Command arg-substitution gate (DS-192):
scripts/check-command-arg-substitution.pyfails CI when a bare$0-$9/$ARGUMENTStoken reappears inside an executable (bare/bash/sh/shell/zsh) fence anywhere undercontent/commands/**- the harness's slash-command literal-text argument substitution silently corrupts awk field-selector syntax at any such site before the model ever reads the instruction. Workflow.github/workflows/command-arg-substitution.yml(non-required, scan-only - no regenerate-then-diff step, since that would flipcontent/commands/ds-implement-ticket.md's provenance underscripts/gate-provenance.sh's D1 rule); regression suitesbin/tests/test_check_command_arg_substitution.sh(the six named reddening mutations) andbin/tests/test_arg_substitution_field_rewrites.sh(old-form/new-form byte-identity on representative fixtures). Fixed 12 sites at ticket creation; each converted to whichever substitution-safe form fit its construct (dynamic-field awk, a pure-bash scan, or a non-$Ncomment wording). - Per-PR delta axis on the two shared/merge-order-sensitive budget gates (DS-182):
budget_report's pre-DS-182 shape (prints OK/OVER BUDGET andexits itself) is unchanged for its one remaining original caller,check-resident-budget.sh(byte-unchanged; it gained no git axis at all) -scripts/lib/budget-gate.shsplit its body into a non-exitingbudget_eval(returns 0/1) plus a thinbudget_reportwrapper (if budget_eval "$@"; then exit 0; else exit 1; fi). New library functionsbudget_base_resolve <repo_dir> [base_branch](resolvesorigin/<branch>then<branch>against-C <repo_dir>, defaultmain; returns 1 and prints nothing when git/a work tree/a resolvable ref is unavailable - takesrepo_direxplicitly, same asbudget_delta, so both always resolve against the caller's repo root rather than the process's own cwd),budget_delta(signed byte delta of a path between a base ref and the working tree; returns 2 and prints nothing when the path is absent at base - never conflated with a delta equal to the path's own full size), andbudget_burn_line(one informational line, ALWAYS returns 0 and ALWAYS prints something - a distinct "burn: SKIPPED (...)" line, never a blank line, when git/a base ref/the base commit date is unavailable). Two different uses on the two gates that needed a git axis:check-command-file-budget.sh(hand-authored file - a PR's diff to it is that PR's own doing) gained a hard-failing per-PRDELTA_LIMIT_BYTES(32,936 B, re-derived asceil(max_observed_delta * 1.1)from the 43 first-parent non-creation commits touching the file,max_observed_delta = 29,941 Bat commitd644217c; fires 0/43 on the history it was derived from) - it callsbudget_evaldirectly (notbudget_report), since a delta breach is recorded (delta_over=1) rather than exiting immediately, so theTHRESHOLD_BYTESbudget_evalreport still runs and prints even when both axes are over budget in the same run; the delta context is reported viabudget_eval's existing extra-context slot solines[-1]of stdout (whatbin/ds-evaluate's_collect_budget_gatesreads as the gate's summary) stays theheadroom:line.check-skill-embed-budget.sh(a GENERATED artifact - its size on any branch reflects upstreamcontent/**churn as much as that PR's own diff, the exact "merge order decides pass/fail" failure mode DS-182 exists to close, per KNW-20260818-001) gained only the informationalbudget_burn_line(a B/day burn RATE,"burn: <B_per_day> B/day over <D> d - <N> d to limit", not a raw delta -<D>is the whole-day span since the resolved base ref's own commit date, floored at 1;<N>= headroom / burn rate, omitted when the rate is <= 0), no hard delta limit. Its OK-path tail is hand-rolled directly in the gate script rather than routed throughbudget_eval, becausebin/ds-evaluate's summary consumer depends on the exact pre-DS-182 wording (ceiling:/headroom to ceiling:), whichbudget_eval's sharedthreshold:/headroom:labels cannot express; the burn line is computed once before the FLOOR/CEILING checks and printed on all three exit paths (OK, BELOW FLOOR, ABOVE CEILING), not only the OK path. Both workflow files neededfetch-depth: 0added to the relevant checkout step(s) (command-file-budget.yml's single job;resident-budget.yml'scheck-skill-embed-budgetjob only -check-resident-budget's checkout is deliberately untouched, since that gate gained no git axis at all) ororigin/mainis unreachable on a default shallow checkout and the git axis silently degrades to its SKIPPED variant on every CI run. All three git-based functions degrade gracefully (never a hard failure) when git is absent orrepo_dirisn't a git work tree - verified against every per-gate test suite (grep -rl budget-gate.sh bin/tests/test_check_*.shfinds the current set -test_budget_gate_lib.shis a sibling library-level suite outside this set and does build a realgit initfixture for its own DS-182 scenarios), which have always built their scratch fixtures with zerogit initat all. Deciding which axis a NEW budget-gate target needs (a hard per-PRDELTA_LIMIT_BYTESfor an AUTHORED/hand-edited target, vs. an informationalbudget_burn_linefor a DERIVED/generated one) is not a fresh judgment call each time: runbash scripts/gate-provenance.sh <repo-relative-path>first - it classifies the target asAUTHOREDorDERIVEDagainst the real CI workflows and manifest headers and cites which rule fired. DS-183/184/185/186 (any future budget-gate axis work) should run it before assigning an axis, not re-derive the classification by hand. - Dependency-advisory gate:
scripts/check-npm-audit.shaudits BOTH lockfiles (package-lock.json,scripts/package-lock.json) and fails only on advisories with a non-breaking fix available. The predicate is actionability, NOT severity, and NOTfixAvailabletruthiness: npm reportsfixAvailableas a truthy object even when its only remedy is a semver-major change, often a downgrade of a parent package, for an advisory with no patched version at all, so a severity or truthiness predicate would keepmainred on advisories nobody can fix (example, measured 2026-11-06, not a live count: every advisory inscripts/proposed such a fix, e.g. a@marp-team/marp-cli@0.12.1downgrade flaggedisSemVerMajor: true). The discriminator isisSemVerMajor !== true; a breaking-only fix is an operator call, reported on every run but never a failure.npm auditresolves from the lockfile with NOnode_modulespresent, so the gate needs no install step (~0.5 s per manifest). Job:npm-auditin.github/workflows/codeql.yml(placed there for the weeklyschedule- the failure class is drift, not diff; see.github/workflows/AGENTS.md); the job installs a pinned npm 11 release before auditing (see the step incodeql.yml), because npm 10.9.9 and 11.3.0 report a non-breakingfixAvailableon@eslint/config-arraywhere none exists. Regression suitebin/tests/test_check_npm_audit.shdrives the predicate through--classifywith fixtures, since live output changes whenever the upstream advisory DB does. Advisory, not required - deliberately off themainruleset's required-checks list, same precedent ascheck-command-file-budgetandcheck-slide-overflow, but the job is NOTcontinue-on-errorand goes red on an actionable advisory. Covered byscripts/check-local.sh(whose preflight requiresnpm); it is the only covered gate needing NETWORK, which no preflight can require, so it splits on${CI}- loud SKIPPED locally, hard red in CI. It can never go green in CI having asserted nothing, but a green LOCALcheck-local.shrun is not proof the audit ran; read the gate's own output. Precedence when manifests disagree: an actionable advisory DETECTED in one manifest outranks another manifest failing to audit, and is reported as exit 1 (naming the unaudited manifest too) rather than discarded in favour of a skip. Retirement is keyed to an observable, not to.github/dependabot.yml- that file already configures npm updates for both directories, and security alerts are governed separately from version-update scope. The test: next time the gate goes red, check whether an update PR proposing that same fix was already open BEFORE it fired. That test is only valid on an advisory whose remediating package is NOT covered by anignore:rule, because anignorerule suppresses security updates as well as version updates..github/dependabot.ymlignores@marp-team/*on/scripts, so for any advisory that remediates through@marp-team/*the test is guaranteed to answer "no PR was open" by deliberate config choice rather than by the automation failing - answering the retirement question on it would keep the gate alive on evidence that could never have come out any other way. If the gate has only ever gone red on ignored packages, the test has not been run yet. - CI trigger policy (2026-09-03): workflows are PR-only by default; the post-merge run is CONSOLIDATED, not deleted. Do NOT re-add
push: branches: [main]to an individual workflow, and do NOT delete.github/workflows/verify-merged-tree.ymlon the theory that strict required checks make it redundant - that theory is false here. Ruleset14778332setsstrict_required_status_checks_policy: trueBUT also carriesbypass_actors: [{RepositoryRole admin, bypass_mode: always}], andgh pr merge --admin --squashis the normal unattended-agent merge path, so a behind-base PR can merge without being brought up to date. Measured over the 25 most recent first-parent merges by comparing each squash commit's tree object to its PR head commit's tree object: 19 matched, 6 did NOT (#850, #854, #855, #856, #857, #860 - 24%; #850 differed across 46 files).verify-merged-tree.yml(push:main + workflow_dispatch) runs a ~10sneeds-full-rungate comparing those two trees and skipping the suite when they match. Its fail-open behavior is TWO-AXIS: inside the script, AND at the job boundary, where all 10 suite jobs guard onif: ${{ !cancelled() && (needs.needs-full-run.result != 'success' || needs.needs-full-run.outputs.run_full == 'true') }}(merged-codex-skill-syncaddsinputs.all_harnesses &&after!cancelled(), so it runs only on anall_harnessesdispatch) - a bareif: needs.<job>.outputs.<x> == 'true'gets GitHub's implicitsuccess()and would SKIP the suite when the gate FAILS, inverting the contract exactly when the gate is least trustworthy. Never simplify that expression: the${{ }}wrapper is mandatory (a bare leading!opens a YAML tag and is a scanner error), and!cancelled()is preferred overalways()so an operator cancel does not start all 10 jobs. Two runner-semantics traps that bit this workflow and generalize: (1) GitHub runs arun:block asbash -e {0}unless the step setsshell:, so error-fallthrough branches written on a "no errexit" assumption are DEAD - the gate step setsshell: bash {0}deliberately, and any harness testing arun:block must read the step's ownshell:key rather than assumingbash -c; (2)git rev-parse <bad-ref>prints its argument to STDOUT and exits 128, so an emptiness test on its output never fires - use--verify.push: mainis NOT only merges:changelog-publish.ymlpushesCHANGELOG.md+docs/changelog.htmldaily with a PAT (CHANGELOG_PUSH_TOKEN- a PAT DOES trigger workflows) and no PR, so the gate has a secondrun_full=falsepath for no-PR pushes whose<sha>^ <sha>diff is a subset of a two-entryUNTESTED_SAFE_PATHSallowlist of files no check reads; keep it tiny, it retires when changelog-publish opens a PR instead. The cheap way to keeprun_full=falsethe norm for merges isgh pr update-branch --rebasebefore an--adminmerge (works as of local gh 2.100). A separate 0-catches-in-600-runs/31-merges measurement is evidence that ~19 duplicate runs per merge was the wrong shape, NOT that the post-merge run is unnecessary.codeql.yml,gitleaks.yml,scorecard.ymlkeeppush: main.bin-tests.ymlstill has its own push trigger: when that is dropped, its three jobs MUST be added toverify-merged-tree.ymlin the same change. Canonical policy:.github/workflows/AGENTS.md. - Claude Code first (operator ruling 2026-10-30/31): a methodology PR regenerates and checks only
.claude(bash .claude/build.sh); the other 10 adapters plus the.github/*Copilot surfaces catch up later in an on-demand chore PR, never in each PR. One switch,DS_ALL_HARNESSES=1, turns the non-Claude set back on everywhere:hooks/pre-commit(all builds, staging, and the Codex skill-sync gate),scripts/check-local.sh,.claude/install.sh's.cursorbuild, the tests that read or rebuild non-Claude output (bin/tests/harness_scope.pyfor pytest,[ "${DS_ALL_HARNESSES:-}" = 1 ]in shell,process.env.DS_ALL_HARNESSES === '1'in the hook JS tests), and CI, where it is set for any PR whose branch starts withchore/adapter-catch-up(adapter-sync.yml,bin-tests.yml,hooks-tests.yml,codex-skill-sync.yml) and byverify-merged-tree.yml'sall_harnessesdispatch input (which also adds itself tomerged-codex-skill-sync's job-levelif:, after!cancelled()).check-codex-skill-syncleft the required set (15 required checks) and runs only on PRs touching the Codex skill pipeline (paths:) or on dispatch; nothing was deleted. Between catch-upsmaincarries stale non-Claude artifacts: outside the switch the non-Claude installers skip their build and install the committed files, sods-updatekeeps working (Kimi still builds its gitignored per-command skills via.kimi/build.sh --untracked-only), and.codex/install.shonly warns that its source is stale or its staged build failed. The catch-up procedure is in CONTRIBUTING.md "Non-Claude harnesses (catch-up chore)".
Tools
- GitHub operations: use
ghCLI, not GitHub MCP gh pr createrequires an authenticatedghsession (gh auth status) - rungh auth loginif needed.rm -rfis blocked by Claude Code permissions here; remove files individually:rm <file>thenrmdir <dir>bin/ds-memory- lightweight retrieval tool for querying.agentic/events.jsonl,MEMORY.md,.agentic/context.mdon demand.bin/ds-base-sync- fast-forwards the local base branch after a merge without a checkout; the only way to move a local branch ref outside an explicit checkout+pull.- Force-push (
--force,-f,--force-with-lease) is blanket-denied by the harness permission layer for subagents AND the conductor; chat authorization doesn't clear it. Push to a NEW branch name instead of rebasing a branch with an open PR. bin/ds-tracker- manages the project-local gitignored.agentic/tracker.ymloverlay (init/set/show/path/resolve). Applied after the four-stepAGENTS.mdtracker chain: overlay is sole source (_source: "overlay") whenAGENTS.mddeclares no tracker or a different one; merges field-by-field (_source: "merged") only when both declare the same tracker. Refuses git-tracked paths;--force-unignoredoverrides.- The Graphify PyPI package is genuinely named
graphifyy(double-y); CLI/skill command staygraphify- verified against upstream README, do not "fix" it. git checkout <sha> -- <path>inside a worktree resurrects files a later commit deleted (adds files present at<sha>, doesn't replay deletions). When basing a step on a non-maincommit this way,git rmanything it deleted and gate on an exactgit ls-filesset.
Deploy
- The docs site (docs.dinostack.ai) auto-deploys on push to
mainvia Vercel git integration (~3 min); verify withcurl -sI https://docs.dinostack.ai/<path> | grep last-modified. There is no manual deploy step; do NOT runvercel --prodfrom a local CLI unless its authenticated scope demonstrably contains thedinostack-docsproject (a mis-linked deploy once caused a live 404). dinostack-docsVercel project's Root Directory isdocs/, so Vercel readsdocs/vercel.json- repo-rootvercel.jsonis ignored for redirects/rewrites/headers (once caused a live install-URL redirect to silently 404). Put Vercel redirect/rewrite/header changes indocs/vercel.json.
Conventions
- Base branch:
mainis the sole integration branch for this repo. Declaration:BASE_BRANCH: main. - Workflow for all implementation work (non-Trivial risk):
git fetch originto ensure latestmain.- Spawn subagent Workers using
isolation: "worktree"with worktrees branched fromorigin/main. Worktree path:.agentic/worktrees/<branch-name>. - Worker implements, runs quality gates (lint, typecheck, tests), commits.
- Push branch to origin:
git push -u origin <branch-name>. - Open PR against
mainviagh pr create. - Once CI/CD checks pass, auto-merge:
gh pr merge --squash --delete-branch. - Clean up: retire or hold each carrier at completion (
ds-retire-carrier,content/references/worktree-lifecycle.md§Carrier lifecycle by purpose). Session-start prune + branch-prune remain as backstops. - Update local main:
bin/ds-base-sync <this-checkout-path> main(run from this repo's own checkout, since it's both ticket repo and tool source) - fast-forwards localmainwithout a checkout. Fall back togit checkout main && git pull --ff-only origin mainonly whenbin/ds-base-syncis not present at that path.
- Steps 6-8 are automatic - never pause for merge approval when CI is green.
mainenforces strict required status checks: a PR whose base has moved must be rebased and re-run before merge - GitHub does not re-run workflows on base movement. Sync withgh pr update-branch --rebase; the default (merge) update produces an unsigned commit that fails the DCO check.- Failed CI is a hard stop - investigate before proceeding.
- Conductor never edits shippable artifacts directly, even Trivial one-liners - delegate to a worktree-isolated
engineerfromorigin/main; conductor may only edit exempt artifacts (.agentic/, conductor-direct prints/decisions/resolver execution). Classifier:content/rules/conventions.md§Git Workflow. - Superseding an open PR: close + rebase, never bundle (
content/rules/conventions.md§Git Workflow). - Sequential isolation:worktree spawns: the worktree is cleaned up between them, so later Workers fall back to the main tree - tell them explicitly. Round-N rework mechanic:
content/rules/conventions.md§Git Workflow,content/references/worktree-lifecycle.md§Round-N rework mechanic. (DS-123) - Parallel engineer spawn briefs must say "branch your worktree from current
origin/main, NOT a local checkout that may include not-yet-merged sibling units" - worktree branch leaks are the most common cross-unit contamination class. - Multi-unit PR assembly:
mainrequires DCO Signed-off-by on every commit. Conductorgit merge --no-ffis unsigned - cherry-pick each engineer's signed commit (no merge commits) orgit merge --signoff. Never force-push to fix;gh pr merge --admin --squashdiscards merge commits anyway. - Pre-commit builds and stages the
.claudegenerated files (.claude/commands/*.md,.claude/skills/dinostack/{METHODOLOGY,SKILL}.md; every adapter's,.codex/agents/*.tomlincluded, only underDS_ALL_HARNESSES=1) only in the primary checkout with a stagedcontent/change - inside a linked worktree the hook exits early before any build or staging runs. Since an agent is always in a worktree, runbash .claude/build.shand stage its output manually after anycontent/edit. - A green
bin/tests/run is not the gate set - the requiredhooks-js-testscheck pins methodology prose byte-for-byte and lives outsidebin/tests/, so it is entirely possible to have a greenpytest bin/tests/and a red PR. There is now a single literal command for the locally-runnable part of the set:bash scripts/check-local.sh(exit 0 every covered gate passed, 1 a gate failed, 2 toolchain preflight failed - see CONTRIBUTING.md "Local toolchain"). Its coverage is deliberately partial and it says so: three gates are excluded on cost (the full Codex skill suite, the slides build plus overflow checks, and the gitleaks full-history scan), and every run ends with aNOT RUN LOCALLY (run in CI)block naming them and their exact commands. A green run means the covered set passed, never that CI will be green - read that block. The hooks JS set is derived, never hand-counted:list_hooks_js_testsinscripts/lib/ci-test-discovery.shtranscribes thehooks-js-testsjob's own loop (globhooks/tests/test-*.jsminus thecase-arm quarantine into the separatewrap-lock-testsjob), pinned against a fresh inline re-derivation bybin/tests/test_ci_test_discovery.sh. That exclusion is not a local exemption:check-local.shruns the two excluded files as its ownwrap-lock-testsgate, andbin/tests/test_check_local.shbreaks each in turn to prove it. Do not infer membership from a filename -test-wrap-lock-abandoned.js,test-wrap-lock-session-id.js, andtest-wrap-lock-verdict.jsall run inhooks-js-tests, notwrap-lock-tests. Two of those prose-pinning tests aretest-wrap-md-partA-parity.js(asserts/ds-wrapretains its whole-flow lock) andtest-wrap-context-format-golden.js(sha256-pinscontent/references/wrap-context-format.mdfrom its NORMATIVE marker to EOF). - Docs-currency pass is mandatory before any work is declared complete and before its PR merges - ticket work or ad-hoc, regardless of which paths changed. Enumerate the surfaces the diff touched, then verify and update any related documentation that now states something stale; land doc updates in the SAME PR as the work. Candidate doc surfaces to check:
docs/index.html,docs/slides/*.md(plus rebuilt.htmlviabash scripts/build-slides.sh),README.md,CONTRIBUTING.md,content/SKILL.md, and the relevantAGENTS.mdsections. This generalizes thecontent/-triggered bullet below: that bullet's trigger stays mandatory forcontent/edits specifically, while this pass applies to all work. Skeptic tiering percontent/references/doc-sync-obligation.md. - Any change to
content/rules/,content/references/,content/agents/,content/commands/, orcontent/sections/MUST also updatedocs/index.htmland any affecteddocs/slides/*.md(then runbash scripts/build-slides.shand commit the regenerated.html- do not hand-edit the.html; upgrading marp is an intentional same-PR action: bumpscripts/package.json+ regeneratescripts/package-lock.json+ rebuild) in the same PR; additionally, any now-stale count, list, or reference inREADME.md,CONTRIBUTING.md, orcontent/SKILL.mdis in-scope for the same PR. Public-facing intent debt is the worst kind. The canonical trigger predicate and tiered Skeptic classification for this obligation live incontent/references/doc-sync-obligation.md; Skeptic reports missing docs sync as Minor (Blocking-minor:when a public-facing doc actively misleads). Grep the decks by hand:check-slides-synconly compares each.mdagainst a fresh render, so an assertion that is stale in both the.mdand its.htmlpasses the gate. - Any new interactive prompt in
.claude/install.shMUST useae_confirm()(reads/dev/ttywhen available, defaults "no"). Never bareread -p- it aborts underset -euo pipefail+ piped stdin (thecurl | bashpath). - After any
content/SKILL.mdchange, run.claude/build.shto regenerate its SKILL.md copy (.pi/build.shbelongs to the catch-up chore). Pre-commit does not auto-stage these. - Mutation-testing a
content/spec assertion requiresbash .claude/build.sh(bash scripts/build-all.shfor an assertion that reads non-Claude copies, run underDS_ALL_HARNESSES=1) BEFORE running the test - mutatingcontent/alone trips the byte-identity assertion and falsely confirms a semantic assertion caught the change. codex-skill-syncCI validates exactly 4 generated native skills under.codex/skills/. It is advisory and runs on PRs touching.codex/**or its generator scripts, and on workflow_dispatch (Claude Code first, above). After changing a canonical input in the catch-up chore:python3 scripts/codex-skills.py inventory --repo . > .codex/skill-compatibility.yml, then.codex/build.sh- never hand-edit generated skill files. That redirect truncates the file to 0 bytes before Python runs, so an aborted run (e.g. aSkillError) leaves it empty on disk -git checkout -- .codex/skill-compatibility.ymlrestores it. Prefer a temp-file +mvon success, or check exit status first.REPO_DIRis distinct fromREPO:REPOis the ticket's own project checkout,REPO_DIRis the dinostack install wherebin/-tools live. Resolve viascripts/lib/repo-dir.sh(resolve_repo_dir):repo_dirfrom~/.agentic/agentic-engineering-config.jsonwhen valid, else~/DinoStack.bin/ds-resolve-worktreeandbin/ds-base-syncboth depend on it.- Any local adapter-drift check must copy its pathspecs verbatim from the two drift steps in
.github/workflows/adapter-sync.yml:Fail on adapter drift(-- .claude, always) andFail on non-Claude adapter drift(the other 10 adapter dirs PLUS.github/copilot-instructions.md,.github/agents,.github/prompts,.github/instructions,.github/hooks,.github/skills; only underDS_ALL_HARNESSES=1).scripts/build-all.sh'sADAPTERSarray omits those six;git diff --exit-codesilently exits 0 on a nonexistent pathspec. (.github/skillsadded DS-186.) Both pathspecs have TWO in-repo consumers,adapter-sync.ymlandverify-merged-tree.yml; the duplication is deliberate (extracting it into a composite action would move the assertion out of a workflow file and stopgate-provenance.sh's D1 rule classifying the adapter dirs as DERIVED) and is kept honest by a step in the latter'smerged-adapter-syncjob asserting each pair of copies is byte-identical. - Verify DCO author/sign-off with lowercase
git log --format=%ae(raw) - uppercase%aEandgit showboth APPLY.mailmap, which can show a mismatched author email on a correctly signed commit. - Build commits with porcelain
git commit -s, nevergit commit-tree- the plumbing command takes no-s(fails DCO) and skips pre-commit hooks entirely. - A new module isn't done until something in
content/invokes it - shipping uncalled and passing review is the default failure. Assert wiring explicitly, ascheck_prose_wiring()inbin/tests/test_worktree_lifecycle_spec.shdoes. docs/planning/is gitignored - a worktree-isolated engineer branched fromorigin/maincannot read a plan there. Restate any obligation in the spawn brief; never keep the same binding prose in both (a fix to one copy drifts silently).- No CI gate checks for em dashes, so scope the check to your own diff, never the whole file:
git diff --cached -U0 | grep '^+.*—'(staged) orgit diff -U0 origin/main...HEAD | grep '^+.*—'(branch). A whole-file grep is useless here - 1 em dash pre-exists onmainin the resident files (content/rules/code-standards.md0,content/sections/04-risk-classification.md1) and will match on every run. That count is the baseline: leave those alone, and treat any added line that matches as a defect to fix before committing - except the two in this bullet's own grep patterns, which are the literal search target and must not be "fixed" (doing so silently breaks both commands). - A shell gate whose assertions are guarded by
command -v <tool>must hard-fail under${CI}rather than skip, or the job goes green asserting nothing.bin/tests/test_check_resident_budget.sh:155-156is the pattern;.github/workflows/bin-tests.yml:57-58installs zsh so the guard never fires in CI. A silently-skipped assertion is indistinguishable from a pass in the job log. - Editing the
mainruleset requires the adminghaccount - a non-admin token's read of ruleset14778332can returnbypass_actorsempty when the admin read returns an actor. Treat any unfetched-as-adminbypass_actorsas unverified, not empty - a PUT built from it can wipe the entry. Back up the full ruleset JSON before any PUT and diff field-by-field after. - Session knowledge belongs in root
MEMORY.md- untracked by design (DS-129), sole-copy risk accepted; a worktree-isolated engineer branched fromorigin/maincannot see it, and neither can a fresh clone. Never end a session holding uncommittedMEMORY.mdedits with content that exists nowhere else - confirm sole-copy status withgit log --all -S "<phrase>"plusgit stash list(--alldoes not coverrefs/stash) before letting the session end. TrackedAGENTS.mdfiles must never accumulate uncommitted session-end edits; any change to them is a normal reviewed PR like any other shippable file, never a session-end commit obligation. - An
isolation:"worktree"engineer spawn with a named branch can leak that branch into the conductor's own checkout and switch its HEAD (once corruptedmain). After every worktree-isolated spawn, verify the conductor's own checkout is still on its expected branch (git branch --show-current+git status+git diff --stat) before committing anything from it. - Isolation worktrees always branch from
mainHEAD, never from a named feature branch. A continuation fix for an existing feature branch can't be briefed as "branch fromorigin/<feature>" - it silently starts from main instead; cherry-pick or push the commit directly onto the existing branch's remote tip instead. - After an isolation-worktree engineer commits, the main checkout's view of that branch ref can lag behind the worktree's own HEAD. Push the explicit commit SHA (
git push origin <sha>:refs/heads/<branch>), not the branch name, orgh pr createcan reject a stale-base push. - An adapter-rebuild/baseline-regen commit (or one built from a stale local snapshot) can silently revert unrelated files with CI green - once reverted 51 files from three merged PRs; PR #390/#432 (DS-47) similarly reverted unrelated list items/counts/cross-refs. Verify a "regenerate generated artifacts" commit's diff touches only the intended paths; diff a PR's base..tip for unrelated hunks before merge/rebase; spot-check a key new symbol lands on
mainafter a multi-PR feature, not just "merged." .claude/install.shhas a zsh variable conflict: a local variable namedstatusis read-only in zsh. Avoidstatusas a variable name in zsh-specific code; run affected blocks in a bash subshell for mixed-shell compatibility.- Empty-array expansion under
set -u: use${ARR[@]+"${ARR[@]}"}with the outer expansion unquoted. Figures are argc, measured 2026-09-24 by placing the expansion between two literal arguments and having the callee report$#, written as unset/empty/two-element for /bin/bash 3.2.57 | bash 5.3.9 | zsh 5.9, so 2 means the expansion added nothing and 3 means it added one empty word. Safe form${ARR[@]+"${ARR[@]}"}: 2/2/4 | 2/2/4 | 2/2/4, and a spaced element stays one word."${ARR[@]:-}": 3/3/4 | 3/3/4 | 3/3/4."${ARR[@]-}": 3/3/4 | 3/3/4 | 3/2/4. Either-form can therefore add an empty positional where you wanted nothing, breaking any consumer that rejects one:bin/ds-cleanup-worktreesexits 2. Bare"${ARR[@]}": abort/abort/4 | 2/2/4 | abort/2/4. Outer-quoting the safe form is wrong under zsh:"${ARR[@]+"${ARR[@]}"}"is 2/2/4 | 2/2/4 | 3/3/4. A[[ ${#ARR[@]} -gt 0 ]]pre-guard is equally sound and is what most sites here use. Pin such a construct by executing the shipped block against an argc stub (check_step2_age_passthrough_argv,bin/tests/test_worktree_lifecycle_spec.sh), never by grepping its spelling. DS-189 recorded the wrong remedy in untracked rootMEMORY.md, never in this file; DS-252 corrected it. - When
origin/mainadvances mid-session, a diff against the neworigin/maincan make an unrelated, already-merged PR's files look reverted - a diff-base artifact, not a real one. Diagnose by comparing your commit's parent toorigin/main; fix by rebasing onto current main and re-running any generator the new commits may have changed. - Checking for duplicate in-flight work only at spawn time misses collisions starting (or merging) mid-run - two live sessions once independently fixed the same three tickets. Check open PRs and the shared checkout's
git statusbefore spawning, and re-check for a superseding merge right before opening a PR (a dirtymergeStateStatuson a fresh PR is the after-the-fact symptom). When superseded, stand down and cite the superseding PR rather than racing a rebase. - Four git lessons: (1) flip a gitignored file to tracked via an additive negation (
!.agentic/<file>), never remove the ignore rule; (2) a negation cannot re-include a file whose parent directory is excluded (.agentic/,/.agentic/, bare.agenticdefeat!.agentic/qa.md) - only glob forms (/.agentic/*,**/.agentic/**) work; (3) matching is last-match-wins - a negation only overrides an umbrella above it (bin/agentic-migrateonce appended umbrellas at EOF and killed every carve-out, fixed #527); (4)git diff --quiet <ref> -- <path>exits 0 for a path never committed to<ref>("unchanged", not "new") - pair withgit cat-file -e <ref>:<path>(fixed #534). Green CI per-PR doesn't guaranteemain's end state under concurrent sessions - assert withgit ls-files/git check-ignore. - Merging to
mainneeds exactly 1 code-owner approval, not 3 (verified against the live ruleset:required_approving_review_count: 1; CODEOWNERS designates* @tysonhummelas sole owner).--adminis still required forgh pr mergewhen the PR is authored by @tysonhummel (GitHub disallows self-approval), or no@tysonhummelreviewer is present - the normal unattended-agent case. Confirmed merging #483-#486; an approval-required failure on--adminmeans the bypass actor was removed from the ruleset and needs re-adding in GitHub's UI. - The live Claude Code harness auto-locks every
isolation:"worktree"worktree at creation. Directory:.claude/worktrees/agent-<agentId>(NOTworktree-agent-<id>- that's the branch name); branch:worktree-agent-<agentId>;git worktree list --porcelainshowslocked claude agent agent-<agentId> (pid <pid> ...). Non-forcegit worktree removerefuses it (remove -f -fneeded) independent of any methodology-level lock. Match cleanup detection on the branch-name pattern, not the directory-path substring. - Work in an isolation worktree can silently absolutize the
.claude/skills/dinostack/{agents,commands,references,rules}symlinks to that worktree's path - the symlink still resolves on the breaking machine, socheck-adapter-syncmisses it and a merged absolutized symlink breaks the skill for every other clone.scripts/check-symlinks-relative.sh(adapter-sync.yml) gates this in CI; before staging, checkgit status --shortfor those four paths, restore withgit restore --staged --worktree; audit a landed commit withgit ls-tree -r <sha> .claude/skills/dinostack | awk '$1=="120000"{print $4}'thengit cat-file -p <sha>:<path>(leading/= broken). Recurs on every build inside an isolation worktree - re-check before every stage. (DS-96, DS-104) - Moving inline prose into
content/references/*-detail.mdcreates two silent hazards, neither producing a conflict marker: (1) the original site drifts after extraction as later commits keep patching it while the copy diverges; (2) the extracted block can arrive already wrong, since a verbatim move preserves whatever it asserted and reviewers read the move as a no-op (DS-68's move carried a stale byte figure; PR #420). Re-verify every count/path/figure against live state in the same PR - "verbatim" is a diff property, not a correctness one. - A verification step piped through BSD
xargs -I{}can assert nothing and still pass: real paths exceed-I's ~255-byte budget, soxargsreturns rc=1 and emits nothing, leaving the comparator comparing empty to empty.2>/dev/nullon a comparison step compounds this into a false pass. - Adapter/methodology build discipline:
content/is single-sourced into all adapter dirs; a methodology PR runsbash .claude/build.shthengit diff --exit-code -- .claude, and the other 10 adapters catch up in the on-demand chore (Claude Code first, above).content/sections/**changes also needscripts/.methodology-baseline.sha256regenerated (bash scripts/check-methodology-drift.sh --regenerate).check-adapter-synctests the merge result, not your branch - rebase ontoorigin/mainand rebuild first. - Repo checkout convention:
DinoStack; Most adapters use skill name and directorydinostack(.claude/skills/dinostack/, etc.). Codex usesdinostack-codexplusdinostack-codex-{brief,wrap,implement-ticket}in the shared~/.agents/skills/namespace to avoid overriding Gemini payloads; its installer migrates only exact-owned old-name symlinks. Config FILENAMES/activation markers did NOT rename:~/.claude/agentic-engineering.json,~/.agentic/agentic-engineering-config.json,agentic-engineering: opt-in/opt-out/-profile:/-preset:markers (live in consumer repos we don't control). Slash commands use/ds-*;bin/agentic-*CLI names unaffected. (DS-26) - Some
content/source files are hardlinked (not copied) into their adapter destinations, and this is inconsistent across files - check the mechanism, not a fixed list, which goes stale: grep the targetbuild.shforhardlink_from_content(, a bareln(no-s), oros.link(- any adapter build whose script calls one of these against acontent/source genuinely hardlinks it (same inode, mutates in place on acontent/edit) rather than copying it. A hand-typed snapshot of which scripts/counts this resolves to has repeatedly gone stale here (DS-90 Unit 5 review) - do not restore one. A rebuild (bash .claude/build.sh, orbash scripts/build-all.shin the catch-up chore) is still required after anycontent/edit regardless of hardlink status, since a fresh git worktree checkout breaks all hardlink relationships (git does not track hardlinks - every worktree gets independent inodes) until rebuilt. (DS-78, DS-90) - Adapter dirs contain hand-authored sources
build.shdoes NOT regenerate (.codex/.copilot/.cursor/.gemini/.githubhook files,.opencode/plugins/session-context.ts) - check manually after any adapter source edit or cross-adapter pattern change. (DS-26) - Bulk sweeps over
evals/must exclude git worktrees (evals/.worktrees/wt-*are pinned at historical commits) to avoid dirtying checkouts. (DS-26) - On a GLM (or any non-Claude-backed) session, spawning a methodology subagent fails immediately - every agent's
model:frontmatter is a Claude alias and the Agent tool'smodelenum is Claude-only. Don't attempt Worker/Skeptic delegation; go conductor-direct with mechanical verification, or switch to a Claude model first. - Never include
"mode": "opt-in"in doc or adapter example JSON unless demonstrating opt-in activation - it silently disables the methodology on repos without anagentic-engineering: opt-inmarker. Show only the field being demonstrated (e.g.{ "profile": "relaxed" }) or use"mode": "opt-out". - Marp dark-theme reskin gotchas (theme leaks, table/code-syntax fixes): see
docs/slides/AGENTS.md. - Slide overflow gate (DS-203):
scripts/check-slide-overflow.sh(check-slide-overflowjob inslides-sync.yml) is wired advisory-only - deliberately NOT on themainruleset's required-checks list, matching the command-file-budget gate's precedent, but the job itself is a real red job on overage, notcontinue-on-error.scripts/slide-overflow-baseline.jsonis membership-only (deck basename -> positional section ids, no px values) - after any edit that inserts, removes, or reorders slides in a debt-carrying deck, re-runnode scripts/check-slide-overflow.js --dump-overflows, diff, and commit the updated baseline in the same PR; never hand-typed. The live figure is not hand-typed here either - runjq '[.[] | length] | add' scripts/slide-overflow-baseline.jsonfor the current pre-existing overflow count. The sole load-bearing determinism mechanism is a fresh headless-Chrome browser context per deck (a reused page converges on wrong values, measured). Known residual: a hypothetical future deck relying only on system fonts (no@font-faceat all) would trip the font fail-closed predicate's "no font face reached loaded status" axis even though nothing is actually broken - update the predicate if that ever happens. - A shell check written as
cmd 2>/dev/null | head -N || echo 'no records'can never report its negative case:||binds tohead, which exits 0 on empty input, so the fallback is unreachable. Same vacuous-pass family as thecommand -vguard and the em-dash check. Test the branch you expect to fire by making it fire on purpose. - When a methodology sentence is found to be false, prefer DELETION over a narrowed rewrite, and check first whether anything is load-bearing on it. A narrowed rewrite reads as the careful option but re-asserts the same shape of claim against the same unverified surface: DS-150's replacement for "Subagents do not have hooks." was itself false. Both original sentences were load-bearing for nothing and deletion was the correct fix. Corollary: a claim removed from
content/is not gone until itsdocs/slides/*.mdcopy is grepped by hand -check-slides-synccompares each deck against a fresh render and passes when the.mdand.htmlare stale in agreement. - Read
docs/overview/vision.mdbefore designing any change to this repo's own methodology surface (content/**,hooks/**,bin/**,scripts/**, adapter dirs) and name the pillars that cut against the proposal, not only the ones that support it. Nothing enforces this mechanically: no hook, no CI gate, andcheck-vision-alignmentinspects PR-body prose only and never opens the file. Several agent contracts and commands require the same read within their own scope - that is not a reason to skip it here.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

