This is the repository's authoritative AI operating policy. Skills may supply workflows, but may not override it.
- If a required local tool is missing from
PATH, stop and ask the owner to install it. Do not install or substitute tools without approval. .lua,.js,.gsh, and interpreted.gowork does not require a standalone runtime. Use./gopherbot syntaxand./gopherbot script; seeaidocs/TESTING_CURRENT.md.
Before proposing or changing code:
- Read
aidocs/README.mdandaidocs/COMPONENT_MAP.md. - Read only the decision docs relevant to the task.
- Inspect the current source and tests; docs intentionally do not duplicate source-level control flow or API inventories.
For changes involving startup/configuration, connectors, routing, identity,
authorization, privacy, privilege separation, task execution, root defaults,
or cross-protocol compatibility, also read aidocs/STARTUP_FLOW.md,
aidocs/EXECUTION_SECURITY_MODEL.md, and aidocs/TESTING_CURRENT.md.
Before such a cross-cutting change, share an Impact Surface Report covering: affected subsystems, preserved/redefined invariants, startup/concurrency and compatibility risks, validation, and documentation. Do not implement until the report is shared unless the owner explicitly waives it.
- Startup and configuration precedence are deterministic and explicit.
- Connectors own transport behavior and accurate message context. The engine owns routing, business policy, authorization, elevation, and secret scope.
- Canonical username is the security identity across protocols. Never infer identity equivalence from display names or transport IDs.
- A primary connector failure is fatal; secondary connector failures are isolated. Preserve message order within each connector.
- Installed extension defaults are authoritative. Custom robot config should remain delta-only unless intentionally redefining behavior.
- Unprivileged extensions may receive secrets only through configuration explicitly attached to that extension or its authorized brain namespace. Never expose provider registries, parameter sets, or broad secret-bearing configuration through generic extension methods.
IgnoreUsersandIgnoreUnlistedUsersare pre-pipeline gates. Keep them before worker creation;IgnoreUsersmatching is case-insensitive.- Trust a connector-supplied canonical username for policy only when
ValidatedUser=true. - Connectors are authoritative for
DirectMessage,HiddenMessage, andSelfMessage; engine/plugins must not rewrite that context. - Private-command policy is engine-owned and runs before plugin logic.
Say/Replypreserve the triggering context; they do not implicitly make a response private. Sensitive responses must require private invocation or useDirect(). Bot-initiated per-user secrets must useSendUserMessage.
- Admin authority has exactly two sources: configured
AdminUsers, orautomaticTask=true. Automatic tasks are administrator-configured schedules and queue triggers; future user-scheduled work must use a separate model. - Security order is admin → private-context checks → authorizer → elevator. Admins bypass the authorizer; elevation is additional assurance after authorization.
Task.Usersis a whitelist whose empty value permits all users.- Auth/elevator plugins must explicitly return
robot.Success;robot.Normalis a mechanism failure. - Pipeline elevation persists once achieved. Do not reset it mid-pipeline.
- Compiled-in Go extensions are trusted, privileged, in-process engine code. File-backed extensions execute in child processes.
- The parent retains all policy, identity, authorization, and secret authority. Child interpreters receive only resolved, scoped parameters through the RPC boundary.
- There are no normal mid-process privilege transitions. A file-backed child commits once, before extension code, to the invoking robot UID or the setuid unprivileged UID.
- Privsep is UID-only. GID and supplementary groups are inherited and are not a security boundary.
- Pipeline privilege is fixed from its starter. Never add a privileged task/job/plugin to an unprivileged pipeline or weaken that gate.
Privsep activates only on a setuid binary and has no normal automated test.
Changes to privsep or its call sites require manual validation: build; install
owned by nobody (or platform equivalent) with setuid set and setgid clear; run
as a non-root robot user; verify the PRIVSEP - UID-only privilege separation initialized log includes the expected daemon and unprivileged UIDs; then clear
setuid and restore normal ownership.
Follow aidocs/V3_COMPATIBILITY_CONTRACT.md. Before the first public v3
release, configuration, extension APIs, and operational behavior may change
when the change is intentional, bounded, and fully synchronized across source,
defaults, skeleton, tests, user docs, migration guidance, and material
Changelog entries. Preserve username-security invariants and brain data where
feasible; publish the stricter public compatibility contract at the v3 release
boundary.
For every change to Gopherbot source, installed defaults, robot.skel/,
shipped extensions, deployment assets, or user-visible CLI behavior, inspect
docs/ and decide whether the user documentation is affected. Update affected
user documentation in the same logical change. When no user-doc update is
needed, report that the documentation impact was reviewed. Co-location exists
so source behavior and its user documentation evolve together.
When behavior changes, update the decision document that explains why:
- startup/config precedence:
aidocs/STARTUP_FLOW.md - routing/pipelines/schedules/queues:
aidocs/PIPELINE_LIFECYCLE.md,aidocs/SCHEDULER_FLOW.md, oraidocs/JobQueues.md - connector identity or transport semantics:
aidocs/CONNECTOR_CONTRACT.mdand the connector-specific doc - execution/security:
aidocs/EXECUTION_SECURITY_MODEL.md - extension runtime/API:
aidocs/INTERPRETERS.mdoraidocs/EXTENSION_API.md - migration:
aidocs/V3_COMPATIBILITY_CONTRACT.md, rootUPGRADING-v3.md, and correspondingconf//robot.skel/defaults - test mechanics:
aidocs/TESTING_CURRENT.md
Only Clu, Floyd, and Bishop are public robot-instance names. Generated or
edited documentation may mention those names. Treat every other
robot-instance name as private: do not reproduce it from source, configuration,
examples, logs, or connected workspaces. Use neutral placeholders such as
acme-bot or example-robot instead.
GOALS_v3.md is the human roadmap. aidocs/TODO.md contains only unresolved
AI follow-ups. Active project coordination may live temporarily under
aidocs/projects/; each active project must maintain a resumable status file
named STATUS.md with the current phase, completed work, exact next owner/action,
validation state, and recommended model/reasoning effort. Update it at every
human/AI handoff and remove the project records when the project is complete.
Historical slice reports belong in Git history, not aidocs/.
Any documentation or AI-instruction change must pass
helpers/check-docs-hygiene.sh.
Changes under docs/ must also pass mdbook build docs.
- Keep one logical change per branch unless the owner says otherwise.
- Preserve behavior unless the task explicitly redefines it; document migration for intentional changes.
- Revalidate affected invariants and run focused tests before broader tests.
- Rebuild with
makeafter core engine or connector-runtime code changes.
When integration coverage applies:
- Build helpers with
make mcp integration-buildwhen needed. - Use the MCP
run_integration_suitetool for a specific suite/selector with live output disabled. - Start with the compact result; inspect
result.json,runner.log, orrobot.logonly as needed. - Classify each failure as a regression or an intentional change with stale expectations before editing assertions.
- Report the exact issue for each of 1–3 changed tests; group larger updates.