FactoryWager Wiki

AGENTS.md

AI agent entrypoint for the FactoryWager monorepo (~/Projects).

Git remotes: originproject-R-score (this monorepo). cascade → private nested product cascade-mover-v3 (git remote only — do not default-push there). Runtime identity: lib/github-repository-ref.ts (owner/name/host/remote — not REPO_URL); parts SSOT in CANONICAL_REMOTES.

Remote SSH: Reasonix remote hosts live in ~/.reasonix/config.toml under [remote]. Active: factorywager-staging (internal.staging, ~/.ssh/id_ed25519, workspace ~/Projects). cloudflare-pages (API-based, no SSH — deploy via bash scripts/cloudflare-pages-deploy.sh). Cascade Mover host is placeholder (uncomment when IP known). Tunnel: scripts/cloudflared-reasonix.ymlreasonix.factory-wager.com. CLI: reasonix remote test/connect/list. First-time bootstrap: bun run remote:setup. Reasonix binary: /Applications/Reasonix.app/Contents/MacOS/reasonix.

Cloudflare MCP (.mcp.json): cloudflare (account/API) · cloudflare-docs (search) · cloudflare-bindings (Workers bindings) · cloudflare-builds (Workers Builds CI — not Pages deploy history) · cloudflare-observability (logs/metrics). Token: CLOUDFLARE_API_TOKEN in ~/.reasonix/.env. Pages project pins: bun run cloudflare:env. Token scope probe (bun run cloudflare:env:validate) proves harness operational confidence — not MCP runtime authorization (dashboard token policy only). Not a TOC/partner desk: Soft Balance, rails, MessageLog, phones, and package Telegram stay in toc-ops-repo (ct); Pages exposes the baked board at /portal/toc/ · docs/harness/tenants/toc-ops.md.

Canonical docs

Role Doc
This file (agent entry) AGENTS.md
Full agent guide docs/AGENTS.md (aligned to this entry + UNIFIED / WIRE_BOUNDARY)
Harness JIT index docs/harness/README.md (when NFR unresolved → one owner)
Authority / lanes docs/harness/AUTHORITY.md
Repository review (JIT) docs/harness/REVIEW.md
Proof / install journey docs/harness/PROOF.md · bun run proof:install
Docs index docs/README.md
Human hub README.md
Workspace map STRUCTURE.md
Coding standards .custom-instructions.md · docs/DEVELOPMENT-STANDARDS.md
Bun install policy docs/UNIFIED.md
Import boundaries docs/IMPORT_BOUNDARIES.md
Wire boundary (parse once) docs/WIRE_BOUNDARY.md
Portal foundation (static UI) docs/portal-foundation.md · bun run verify:portal:static · serve:public:hot
TOC Ops portal board (fixture) docs/harness/tenants/toc-ops.md · /portal/toc/ · bun run ops:seed:toc · bun test tests/toc-ops-fixture.test.ts
Ops loop throughput docs/harness/tenants/ops-loop-throughput.md · bun run ops:loop:baseline / ops:loop:post / ops:outbox:requeue · claim ops-loop-throughput
Factory Telegram docs/harness/tenants/telegram-factory.md · bun run telegram:verify · telegram:ops:consume · lib/telegram/
Platform routing (local vs Pages) docs/platform-routing.md · bun run check:routes · bun run verify:pages-edge
Bun native capabilities docs/BUN_NATIVE_CAPABILITIES.md (WebView, markdown.ansi, Terminal/PTY, Bun.Image, cron, UDP)
Bun token/catalog operate docs/BUN_DOCS_OPERATE.md (bun run docs:refresh)
TokenRef (interior) / BunToken (export) lib/docs/token-ref.ts · lib/docs/bun-token.ts
Projects triage projects/README.md
Path SSOT (code) lib/docs/repo-docs.ts
Cloudflare / R2 / Pages config/r2-env.ts · bun run cloudflare:env / :assert / :assert-apex / :assert-live / :validate · cloudflare:preflight · cloudflare:deploy:verify · docs/harness/tenants/cloudflare-pages.md
Harness thesis lopopolo/harness-engineering

Communication precision

Do not append an unrequested caveat, counterargument, or moralizing endcap to a sharp claim merely to demonstrate balance. If a boundary condition changes the truth of the claim, put it in the mechanism or scope the claim correctly. If it does not, cut it. Accuracy belongs in the argument; model self-protection does not.

Terminology (harness): prefer artifact over codebase for what is maintained, delivered, or proven; use repository / source tree for the git tree. Domain-valued strings use brands, not bare string, after the boundary — see .custom-instructions.md and lopopolo/harness-engineering.

Branded IDs are mandatory (agents)

Do not declare domain IDs as bare string. This is enforced by pre-commit (--staged --strict has no baseline — new code always fails). Bare id: string / _id: string is also flagged; suppress only with an explicit // brand-ok decision — the detector no longer auto-suppresses opaque primary keys.

Wrong Right
sessionId: string sessionId: SessionId + asSessionId / trySessionId / parseSessionId
userId?: string userId?: UserId
function f(accountId: string) function f(accountId: AccountId)
id: string (opaque DTO PK) id: string; // brand-ok — opaque entity primary key
'' as AccountId never — use try* or throw
bun tools/brand-catalog.ts SessionId   # which constructor + mint authority
bun run check:brands                   # repo-wide (baseline may grandfather legacy only)
bun tools/branded-id-check.ts --staged --strict   # what pre-commit runs on your diff

Import brands from lib/types/branded.ts. Map: lib/types/branded/README.md. Manifest: lib/types/brand-manifest.json. Skill: .agents/skills/branded-ids/. Intentional opaque passthrough only: // brand-ok on that line.

Wire boundary (parse once)

Full map: docs/WIRE_BOUNDARY.md — what is edge vs interior, path/name allowlists, suppressions.

Interior (default) Boundary only
Domain types / brands unknown fun args
No re-decode decodeUnknownSync / decodeUnknown*
Trusted SessionId, structs parse* / is* / type guards

Operating rules

Bun install policy (machine + workspace): docs/UNIFIED.md

Machine Bun policy (summary)

Machine SSOT is ~/.bunfig.toml (linker = "isolated", globalStore = true, frozenLockfile = true, minimumReleaseAge = 259200, absolute [install.cache].dir); env in ~/.config/shell/bun.sh (BUN_INSTALL, NO_PROXYno BUN_INSTALL_GLOBAL_STORE); PATH in ~/.config/shell/path.sh. Full component table: docs/UNIFIED.md.

Bun API references (required for agents)

Before using an unfamiliar Bun API, resolve its canonical doc instead of guessing the signature:

bun tools/bun-doc-refs.ts suggest "Bun.secrets"   # → catalog DOC + SHIP/FIX/BLOG/NOTE when known
bun tools/bun-doc-refs.ts url "Bun.stringWidth"   # → canonical URL
bun tools/bun-docs-catalog.ts get Bun.WebView     # full catalog entry
bun run docs:catalog:export                       # compact TSV for agents

Commands: url list suggest (catalog → canonical map → index) · catalog · check/annotate (find/insert @see refs) · audit (map anchors vs index) · deepcheck (repo links vs index) · validate (HTTP links) · integrity (4-layer proof; --fix self-heals taxonomy aliases, --fix-dry previews) · status (includes tier-A coverage) · schedule (Bun.cron daemon; --once for single runs) · export (hierarchical llms-full.txt)

Operate loop (RSS → reference index → scrape → catalog → integrity): docs/BUN_DOCS_OPERATE.md · bun run docs:refresh · strict tracked-token gate: bun run verify:docs-coverage:save

Rules:

Branded ID types (harness)

Mandatory for agents. Domain *Id values are never bare string after the boundary (see section above).

Stable import: lib/types/branded.ts · Domains: lib/types/branded/{session,identity,documents,security,deployment,audit,operations}.ts · Manifest: lib/types/brand-manifest.json · Agent map: lib/types/branded/README.md

Each domain module repeats the same pattern: type + as* + try* + parse* + *_BRAND_SPECS. Agents learn the invariant from structure.

Tier Use
asXId Required string → brand or throw
tryXId Optional → brand or undefined (never empty forge)
parseXId Wire unknown → brand or throw

Mint authority is documented per brand in the manifest (system-internal · user-input · wire-input). Optional audit: BRAND_PROVENANCE=1.

bun tools/brand-catalog.ts                       # JIT brand discovery (domain|BrandName)
bun run check:brands                             # actionable unbranded IDs (manifest-driven + baseline)
bun run check:brands:types                       # tsc proof: SessionId ≠ UserId
bun run check:brands:all                         # manifest + smart + types
bun tools/brand-manifest.ts                      # regenerate institutional record
bun tools/brand-manifest.ts --check              # fail if manifest stale (pre-commit)
bun tools/branded-id-check.ts --write-baseline   # only when expanding detector (owners)

Skill: .agents/skills/branded-ids/ · Type proof: tests/branded-types.test-d.ts

Console depth (output verbosity)

Object-inspection depth is controlled project-wide via lib/console-depth.ts (wrapper over Bun.inspect / .table / .custom). Precedence: --console-depth=N flag > BUN_CONSOLE_DEPTH env (set in root .env) > default 4. Prefer wrapper helpers (inspect / logDepth / logTable / inspectCustom) over raw console.log(obj) / console.table; forward to children with depthArgs() / withConsoleDepth(). Hashing wrapper: lib/security/index.ts SecurityUtils (claim security-hash-boundaries). Full wrapper inventory: docs/harness/PROOF.md · BUN_NATIVE_WRAPPERS · bun run harness:status. Note: Bun’s runtime does not read BUN_CONSOLE_DEPTH itself and util.inspect.defaultOptions.depth is a no-op in Bun — only bun --console-depth=N and Bun.inspect({depth}) work.

Kind References
Repo claim console-depth-boundaries · wrapper lib/console-depth.ts · tests/console-depth.test.ts · tools/benchmarks/console-depth-perf.ts · wrappers map PROOF.md · hash wrapper security-hash-boundaries
Bun runtime/console · runtime/utils (inspect · .table · .custom · stringWidth) · hashing
Other external bun-types pin