agentleFS
hyparamhyparam/hypaware/AGENTS.md

hypaware

AGENTS.md16 starsChanged 3 months agoMITView on GitHub

HypAware is the active codebase. Prefer files under src/, hypaware-core/, bin/, and root test/. The old collectivus/ donor tree is not part of this repo; do not assume its tests, package scripts, or agent notes are available unless a task explicitly provides that context. Make the smallest change that fixes the problem. When a bigger change looks right, land the small one and defer the rest. File a GitHub issue autonomously only when the follow-up is concrete, consequential, and clearly…

  • Installs packages
  • 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,439 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 repository8 other files it gives its agents.

The file

Show its rules and text

We split this AGENTS.md into the rules it gives an agent

25 rules. About 1 is common, 9 are distinctive, and 15 are very specific to this project.

  • ≈1

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈9

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 15

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    No new runtime dependencies: Use the standard library and the code already here.

    line 16
  2. Distinctive:

    Add one only when the task calls for it, and a rejected one stays rejected.

    line 20
  3. Very specific:

    Read before you change: Before modifying a subsystem, read the LLP tagged with its Systems value (e.g.

    line 45
  4. Very specific:

    Annotate non-obvious decisions: When you implement or change code that realizes a documented, non-obvious design decision, add an …

    line 47
  5. Very specific:

    Keep refs honest: When you touch annotated code, check the referenced section still applies.

    line 54
  6. Very specific:

    Living docs: Update the LLP when the design changes: land the doc edit in the same commit as the code.

    line 56
  7. Very specific:

    No em dashes (the U+2014 character) anywhere: code, comments, JSDoc, strings, or docs.

    line 82
  8. Distinctive:

    No raw NUL bytes (U+0000) in tracked text.

    line 85
  9. Very specific:

    Never use inline import('...') types.

    line 91
  10. Very specific:

    Do not use @typedef in JSDoc.

    line 93
  11. Very specific:

    Run npm test for the active traditional test suite.

    line 110
  12. Distinctive:

    Add traditional tests for deterministic logic: config parsing and validation, manifest validation, daemon install rendering, path helpers, …

    line 112
  13. Very specific:

    Use npm run smoke -- <flow> for the existing hermetic smoke flows under hypaware-core/smoke/flows.

    line 115
  14. Very specific:

    Do not treat the hermetic smokes as the only release gate.

    line 117
  15. Very specific:

    Use scripts/sandbox/hyp-sandbox to exercise install methods (npx, npm install -g, hyp init, hyp join/leave, attach, daemon install) without …

    line 120
  16. Distinctive:

    Keep two tiers distinct:

    line 131
  17. Distinctive:

    When adding or changing workflows, make the app observable enough that failures identify the broken step rather than only returning a …

    line 139
  18. Very specific:

    Prefer structured attributes such as component, operation, status, error_kind, plugin names, dataset names, and sink/source ids.

    line 146
  19. Distinctive:

    Verify both external behavior and emitted telemetry.

    line 148
  20. Common:

    Keep dev telemetry local and secret-safe.

    line 151
  21. Very specific:

    After a smoke failure, inspect the run-specific logs/spans/metrics before changing code.

    line 154
  22. Distinctive:

    Read a file (or the region you will change) before your first Edit to it in a session, and re-read it before retrying any failed Edit.

    line 187
  23. Distinctive:

    If the same Edit fails twice, stop retrying: re-read, rebuild the edit from the current content, or fall back to Write.

    line 190
  24. Very specific:

    Run before tagging a new HypAware release:

    line 228
  25. Very specific:

    If the release changes what bounds an automatic import (backfill.window_days, backfill.sweep_cron, or the window the scheduled sweep …

    line 276

≈ “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.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
AGENTS.md

Repository Guidance

HypAware is the active codebase. Prefer files under src/, hypaware-core/, bin/, and root test/. The old collectivus/ donor tree is not part of this repo; do not assume its tests, package scripts, or agent notes are available unless a task explicitly provides that context.

Adding things

Make the smallest change that fixes the problem. When a bigger change looks right, land the small one and defer the rest. File a GitHub issue autonomously only when the follow-up is concrete, consequential, and clearly outside the current task. Do not file issues for speculative improvements, minor cleanup, or observations that are adequately captured in the PR description.

  • No new runtime dependencies. Use the standard library and the code already here. If nothing here can do the job, keep the fix small and apply the same follow-up threshold above.
  • Do not invent columns, config keys, or schema fields. Reuse or derive. Add one only when the task calls for it, and a rejected one stays rejected.
  • Reuse before you add a file, helper, wrapper, or abstraction, unless the existing one is the wrong home for it.
  • Stop when tests pass. Note unasked-for docs, cleanups, or adjacent fixes in the PR description; do not land them.

Performance

Performance is a product requirement. Keep CPU work and memory use economical and bounded, especially in hot paths, per-record work, and long-running processes. Every code review must include an explicit CPU and memory pass over the changed code and affected paths. Call out avoidable allocation, repeated work, unbounded growth, busy loops, and behavior that worsens with data volume or uptime; state explicitly when the review finds no CPU or memory concern.

Design docs (LLP)

Design rationale lives in numbered LLP documents under llp/, following Linked Literate Programming. Start at llp/0000-hypaware.explainer.md for the subsystem map, and LLP 0002 for what actually shipped in V1.

  • Most changes need no LLP. Bug fixes, null handling, tests, renames, behavior-preserving refactors, and version bumps get none. Write one when a real design decision is made or changed, not as a record of a fix.
  • Read before you change. Before modifying a subsystem, read the LLP tagged with its Systems value (e.g. Sources, Sinks, Plugins, Config).
  • Annotate non-obvious decisions. When you implement or change code that realizes a documented, non-obvious design decision, add an annotation: // @ref LLP NNNN#anchor: short gloss (with an optional relation before the colon: [implements], [constrained-by], [tests], e.g. // @ref LLP NNNN#anchor [implements]: short gloss). Attach it directly above the construct; a blank line breaks attachment. Don't annotate mechanically; a ref must tell you something the code and filename don't.
  • Keep refs honest. When you touch annotated code, check the referenced section still applies; update or remove the @ref if not.
  • Living docs. Update the LLP when the design changes: land the doc edit in the same commit as the code. Mark retired docs Superseded or move them to llp/tombstones/ with Status: Tombstoned; don't leave stale guidance.
  • Accepted docs are settled. Once an LLP is Accepted or Active, do not edit what it settled. Change the design by extending it (a new LLP, noted on the old doc's Extended-by: line) or by replacing it with a new LLP and marking the old one Superseded. Mechanical edits are still fine: typos, broken links, status changes, and renumbering that does not change meaning (LLP 0156).
  • Tooling lives in-repo under .claude/skills/ (so every clone has it): /ref-check [path] validates @refs; /ref-story <file> shows a file's rationale-order view; /llp-create <title> scaffolds a new doc; /llp-list surveys the corpus; /llp-grill stress-tests a plan against the LLP corpus before you write code.
  • A new number comes from node scripts/llp-numbers.js next, after a git fetch --prune. Numbers are minted on every branch at once, so the tree you have checked out is not the corpus: three branches each read max(llp/) + 1 and each got the same answer (issue #907). The same script gates it: check in the cross-branch-numbers CI job, which fetches every branch first, and in npm test wherever the clone carries them (a shallow or single-branch checkout skips it and says so). survey shows every collision across every ref.

Code Style

  • JavaScript, no semicolons.
  • No em dashes (the U+2014 character) anywhere: code, comments, JSDoc, strings, or docs. In prose, use the punctuation the sentence wants (a comma, colon, parentheses, or a sentence split); in runtime strings, prefer -.
  • No raw NUL bytes (U+0000) in tracked text. grep classifies a file holding one as binary and silently skips it, so the file drops out of every text search with no error to say so. When a string genuinely needs a NUL (a dedup-key separator, say), write the escape \0: it yields the same value and keeps the bytes on disk searchable.
  • Types are defined in JSDoc comments, not TypeScript.
  • Never use inline import('...') types. Declare type imports at the top of the file with @import JSDoc comments, then reference the bare names.
  • Do not use @typedef in JSDoc. Define shared types as interfaces in .d.ts files and import them via @import.
  • Type-import specifiers are repo-root-anchored .js paths. Inside src/, write @import { Foo } from '../../src/core/types.js' (route up to the repo root, then back down through src/..., with a .js extension), not from './types.d.ts'. The published declaration build (npm run build:types, tsconfig.build.json, rootDir: src to outDir: types) emits .d.ts into a parallel types/ tree; a root-anchored specifier resolves identically from both src/<P>/x.js and the generated types/<P>/x.d.ts, so consumers of the published package get real types instead of any. A bare ./types.d.ts resolves in src but dangles in types/. Imports of the root kernel contract (hypaware-plugin-kernel-types.js) and hypaware-core/... already reach the root, so they only need the .js extension. This is the icebird-style no-copy convention.

Development Checks

  • Run npm test for the active traditional test suite. It is intentionally scoped to root test/**/*.test.js.
  • Add traditional tests for deterministic logic: config parsing and validation, manifest validation, daemon install rendering, path helpers, TOML transforms, OTLP flatteners, sink scheduling, and similar local contracts.
  • Use npm run smoke -- <flow> for the existing hermetic smoke flows under hypaware-core/smoke/flows.
  • Do not treat the hermetic smokes as the only release gate. They run with a temp HYP_HOME and HYP_DEV_TELEMETRY=1, which is useful for deterministic regression checks but does not prove installed-daemon behavior.
  • Use scripts/sandbox/hyp-sandbox to exercise install methods (npx, npm install -g, hyp init, hyp join/leave, attach, daemon install) without touching your own install. It redirects HOME, HYP_HOME, and the npm global prefix into a throwaway root, and puts mock launchctl / security / systemctl first on PATH so those calls never reach your real launchd domain or login keychain (both are per-uid, so a temp HOME alone does not sandbox them). See scripts/sandbox/README.md.

Smoke Test Model

Keep two tiers distinct:

  1. Traditional tests: fast, deterministic, and broad over edge cases.
  2. Hermetic smokes: narrow complete workflows in a temp install, good for PR confidence and plugin/kernel wiring checks.

Log-Driven Development

When adding or changing workflows, make the app observable enough that failures identify the broken step rather than only returning a nonzero exit code.

  • Give every smoke a stable DEV_RUN_ID, smoke_name, and smoke_step.
  • Emit structured logs/spans/metrics around entrypoints, lifecycle transitions, external calls, retries, validation decisions, source/sink starts, and error paths.
  • Prefer structured attributes such as component, operation, status, error_kind, plugin names, dataset names, and sink/source ids.
  • Verify both external behavior and emitted telemetry. A smoke should assert the user-visible result and the internal signal that proves the intended path ran.
  • Keep dev telemetry local and secret-safe. Do not record credentials, raw prompts, private customer data, or hidden reasoning. Use hashes or short redacted excerpts when payload identity matters.
  • After a smoke failure, inspect the run-specific logs/spans/metrics before changing code. Fix from evidence, then rerun the same smoke.

Useful commands:

npm test
npm run smoke -- core_boot_noop
npm run smoke -- gateway_codex_capture
npm run smoke -- daemon_foreground_start_stop

Session hygiene

  • Close working sessions at the end of the day. Before closing a session you intend to continue, ask the agent for a continuation summary: open questions, key file paths, decisions made, and the next step. Start the next day's session from that summary instead of reopening the old session.
  • A session reopened on a later day re-reads its entire history on every exchange. If a session has crossed a day boundary and its history no longer informs the current step, start fresh.
  • Long autonomous runs (loops, overnight workflows) are exempt: they manage their own context.

Edit rules

  • Skill descriptions control discovery. Agents use the SKILL.md description to decide whether to load the skill at all. Preserve existing trigger examples and routing requirements when reorganizing or shortening skills; changes to the body cannot compensate for lost discovery. Treat description rewrites as behavior changes, and do not claim routing is preserved from static checks alone: verify it in fresh sessions or explicitly report it as unverified.
  • Read a file (or the region you will change) before your first Edit to it in a session, and re-read it before retrying any failed Edit; the failure usually means the file changed underneath you (a formatter or another agent).
  • If the same Edit fails twice, stop retrying: re-read, rebuild the edit from the current content, or fall back to Write.

Repository layout

src/
  core/                 # the kernel
    observability/      # tracer, logger, meter, attrs, span helpers
    manifest.js
    dep_graph.js
    registry/           # capabilities, commands, datasets, sources, sinks
    runtime/            # paths, activation, loader, daemon runtime
    cache/              # intrinsic Iceberg-backed cache
    cli/                # dispatch, walkthrough, core_commands
    config/             # v2 schema, validator
    daemon/             # platform installers (launchd / systemd) + lifecycle
    otlp/               # shared OTLP http/json listener machinery
    plugin_install/     # resolver, fetch, lock, update_check
    sinks/              # cron driver + encoder utility
hypaware-core/
  smoke/                # `hyp dev smoke <name>` flows
  plugins-workspace/
    ai-gateway/         # @hypaware/ai-gateway
    otel/               # @hypaware/otel
    local-fs/           # @hypaware/local-fs
    format-parquet/     # @hypaware/format-parquet
    format-jsonl/       # @hypaware/format-jsonl
    claude/             # @hypaware/claude
    codex/              # @hypaware/codex
    central/            # @hypaware/central (bundled, opt-in via `hyp join`)
    gascity/            # @hypaware/gascity (bundled, opt-in)
bin/
  hypaware.js           # CLI entrypoint (bound to both `hypaware` and `hyp`)

Release checklist

Run before tagging a new HypAware release:

npm test                  # if a test script is present
npm run typecheck         # if a typecheck script is present
npm pack --dry-run        # verify the published file set

Re-run the smoke battery and confirm every one is green:

hyp dev smoke package_bin_boot
hyp dev smoke cli_bundled_plugins_activated
hyp dev smoke daemon_foreground_start_stop
hyp dev smoke daemon_install_render
hyp dev smoke walkthrough_picker_to_first_query
hyp dev smoke client_attach_idempotent
hyp dev smoke gateway_claude_capture
hyp dev smoke gateway_codex_capture
hyp dev smoke claude_telemetry_capture
hyp dev smoke hypignore_capture_drop
hyp dev smoke local_only_export_withhold
hyp dev smoke source_optout_export_withhold
hyp dev smoke github_local_only_withhold
hyp dev smoke opencode_capture
hyp dev smoke cursor_capture
hyp dev smoke pi_capture
hyp dev smoke github_local_capture
hyp dev smoke otel_loopback_capture
hyp dev smoke local_parquet_export
hyp dev smoke query_grep_roundtrip
hyp dev smoke status_diagnostics

Finally, exercise the manual gate end-to-end on at least one macOS host and one Linux host:

npm pack
npx ./hypaware-*.tgz
hypaware status
hypaware daemon restart
hypaware query sql "select count(*) from ai_gateway_messages"
hypaware query sql "select count(*) from traces"
hypaware query sql "select count(*) from logs"
hypaware daemon uninstall

If the release changes what bounds an automatic import (backfill.window_days, backfill.sweep_cron, or the window the scheduled sweep resolves), say so in the release notes and name every adapter the change reaches. The bounding is cross-plugin, and one such bound is already in force: as of v1.31.0 a provider's positive backfill.window_days narrows its scheduled recovery sweep as well as its join-time import (LLP 0359 #sweep-context), OpenClaw's Lane B transcript sweep included, so a window an operator set only to keep the first import small also caps every later recovery. Nothing is removed from disk, and widening or dropping the window lets the next sweep take the older history.

<!-- neutral:llp-conventions -->

LLP conventions

Design rationale lives in numbered LLP documents under llp/, driven by neutral.

  • Immutable docs; change is a new request. An Accepted/Active LLP is a record, not a worksheet: do not edit what it decided or required. To change intent, mint a new request (rfc/spec/issue) that @refs what it supersedes, and append a Superseded-by:/Extended-by: LLP NNNN forward-ref to the applicable parts of the old doc. Trivial editorial fixes (typos, links, forward-refs) are fine; Drafts are still editable.
<!-- /neutral:llp-conventions -->

Download now (ZIP)

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
What did you use it for? e.g. Reviewing pull requests in a Rails app

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.