F1: Read-only Git document access¶
F1 adds the smallest repository-read surface needed by a continuity client. It does not copy a repository into HeyAira and it does not create a GitHub App, push code, open pull requests, or change deployment infrastructure.
Contract¶
The authenticated project is the tenant boundary. A local administrator first links a GitHub repository and allowlists a document at one immutable commit:
heyaira-admin add-document-source \
--project-id <project-id> \
--github-owner h8v6 \
--github-repository heyaira \
--document-role runtime \
--path docs/CONTINUITY_PROTOCOL.md \
--commit-sha <40-character-commit-sha>
The command stores only repository identity, role, path, commit SHA, and a fragment limit. It is an administrator operation; there is no model-facing write operation for changing the allowlist.
runtime_bootstrap_get() returns the authenticated project's active pinned
references. The response contains source_id, repository identity, role,
path, commit SHA, and limits. If no active runtime source exists, it returns
runtime_unconfigured.
git_document_get(source_id, start_byte?, max_bytes?, cursor?) reads one
allowlisted source. The server resolves the source from the authenticated
project and calls the fixed GitHub Contents API host with the pinned commit
SHA. The model cannot supply an arbitrary repository URL, branch, or path.
The response contains the UTF-8 content fragment, byte range, full-file
SHA-256, fragment SHA-256, and an opaque next_cursor when more content is
available. A cursor is signed and bound to the project, principal, source,
commit, path, offset, and expiry. Each continuation re-checks authorization
and re-reads GitHub; F1 has no cache.
Limits and failure behavior¶
documents:readis a separate OAuth scope; existing OAuth grants are not silently expanded.- Legacy static project tokens retain only their historical memory/task
permissions. They do not receive
documents:read; a document read needs an explicit OAuth grant containing that scope. - Only ordinary UTF-8 files are accepted. Directories, symlinks, gitlinks, invalid UTF-8, path traversal, and non-UTF-8 byte ranges are rejected.
- A file is limited to 1 MB and a response fragment to 64 KB.
- A full 40-character commit SHA is required; branch and tag names are not accepted by the F1 registry.
- The GitHub Contents JSON response is bounded to 1,500,000 bytes before JSON
parsing. This leaves room for base64 and JSON overhead around a valid 1 MB
decoded file while bounding responses without or with a false
Content-Length. Redirects are rejected rather than followed. - Provider failures are returned as stable codes such as
provider_not_found,provider_forbidden,provider_unavailable, orprovider_unconfigured; credentials and response bodies are never logged.
The provider follows GitHub's repository contents read contract and uses a
read-only injected credential. GitHub documents the path and ref inputs
and the Contents read permission in its repository contents API
documentation.
Installation-token acquisition is a separate future deployment concern; this
local F1 only provides the adapter seam and synthetic tests.
What F1 does not claim¶
F1 does not provide a HeyAira state snapshot, event sourcing, background routing, thread wake-up, GitHub App installation, or public GitHub access. The tests use an injected synthetic provider and therefore are not evidence of a public GitHub deployment. Production credential wiring and external verification remain a later, explicitly authorized stage.
Local verification¶
.venv/bin/pytest
The document tests exercise allowlist-shaped source records, UTF-8-safe fragments, signed cursor binding, object/encoding/limit failures, and the fixed-host GitHub adapter. They do not contact GitHub and do not require a production token.
The full MCP-to-document path is covered by an opt-in integration test. Point
HEYAIRA_F1_E2E_DATABASE_URL at a newly created isolated PostgreSQL database
before running it; the test starts a local MCP server, inserts synthetic
project/OAuth/allowlist state, uses a synthetic Git provider, verifies
bootstrap and continuation, revokes the source between reads, and confirms a
legacy token is denied before the provider is called:
HEYAIRA_F1_E2E_DATABASE_URL=postgresql://... \
.venv/bin/pytest -q tests/test_f1_mcp_e2e.py