Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
89 changes: 89 additions & 0 deletions .github/workflows/pages.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
name: GitHub Pages

on:
pull_request:
push:
branches:
- main
workflow_dispatch:

permissions:
contents: read

concurrency:
group: pages-${{ github.ref }}
cancel-in-progress: true

env:
NODE_VERSION: "24.4.1"
PNPM_VERSION: "11.9.0"
RUST_TOOLCHAIN: "1.88.0"

jobs:
validate:
runs-on: ubuntu-24.04
defaults:
run:
shell: bash
working-directory: site
steps:
- name: Check out Pages source
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
path: site

- name: Check out canonical agentctl source
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
repository: opensourceops/agentctl
path: agentctl

- name: Install pinned Node.js
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version: ${{ env.NODE_VERSION }}
cache: pnpm
cache-dependency-path: site/pnpm-lock.yaml

- name: Install pinned Rust and pnpm
run: |
set -euo pipefail
rustup toolchain install "$RUST_TOOLCHAIN" --profile minimal --component rustfmt
rustup default "$RUST_TOOLCHAIN"
corepack enable
corepack prepare "pnpm@$PNPM_VERSION" --activate

- name: Install site dependencies and browser
run: |
pnpm install --frozen-lockfile
pnpm exec playwright install --with-deps chromium

- name: Verify canonical docs and final site artifact
env:
AGENTCTL_REPO: ${{ github.workspace }}/agentctl
run: pnpm verify:agentctl

- name: Configure GitHub Pages
if: github.event_name != 'pull_request'
uses: actions/configure-pages@45bfe0192ca1faeb007ade9deae92b16b8254a0d # v6.0.0

- name: Upload complete Pages artifact
if: github.event_name != 'pull_request'
uses: actions/upload-pages-artifact@fc324d3547104276b827a68afc52ff2a11cc49c9 # v5.0.0
with:
path: site/_site

deploy:
if: github.event_name != 'pull_request'
needs: validate
runs-on: ubuntu-24.04
permissions:
pages: write
id-token: write
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- name: Deploy GitHub Pages
id: deployment
uses: actions/deploy-pages@cd2ce8fcbc39b97be8ca5fce6e763baed58fa128 # v5.0.0
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
node_modules/
dist-agentctl/
_site/
.astro/
playwright-report/
test-results/
.agentctl-docs-server.json
15 changes: 15 additions & 0 deletions .markdownlint-cli2.jsonc
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"config": {
"MD013": false,
"MD012": false,
"MD024": { "siblings_only": true },
"MD033": false,
"MD041": false,
"MD046": false
},
"ignores": [
"node_modules/**",
"dist-agentctl/**",
"_site/**"
]
}
39 changes: 38 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,38 @@
# opensourceops.github.io
# OpenSourceOps GitHub Pages

This repository builds the organization root site and the public `agentctl` documentation at `/agentctl/`. Technical content is canonical in `opensourceops/agentctl`; a deterministic manifest imports it into an Astro and Starlight presentation layer.

## Prerequisites

- Node.js 22 or newer
- pnpm 11.9.0 through Corepack
- Rust 1.88.0 and Cargo
- Playwright Chromium for the full browser gate
- local checkouts of this repository and `agentctl`

Set `AGENTCTL_REPO` when the agentctl checkout is not in a documented sibling location.

## Local development

```text
corepack enable
pnpm install
pnpm exec playwright install chromium
AGENTCTL_REPO=/path/to/agentctl pnpm docs:sync
pnpm dev:agentctl
```

The development URL is `http://localhost:4321/agentctl/`. The development server makes no provider request, but dependency installation can use the package registry.

## Build and verify

```text
AGENTCTL_REPO=/path/to/agentctl pnpm build
AGENTCTL_REPO=/path/to/agentctl pnpm verify:agentctl
```

`pnpm build` writes the complete Pages artifact to `_site`; serve that directory at its root and open `/agentctl/`. `pnpm verify:agentctl` is the canonical cross-repository gate. It runs `cargo xtask docs-verify`, synchronizes canonical content, checks writing, spelling, links, anchors, Mermaid, search, and generated freshness, builds the final artifact, then runs responsive Playwright and axe checks.

Common failures are a missing `AGENTCTL_REPO`, stale generated source or CLI references, a missing Playwright browser, or another process using port 4173. No verification command needs a provider API key.

See [deployment settings](docs/DEPLOYMENT.md) and the [documentation execution ledger](docs/execution/AGENTCTL_DOCS_STATUS.md).
175 changes: 175 additions & 0 deletions astro.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
import { defineConfig } from 'astro/config';
import starlight from '@astrojs/starlight';
import mermaid from 'astro-mermaid';

const github = 'https://github.com/opensourceops/agentctl';

export default defineConfig({
site: 'https://opensourceops.github.io',
base: '/agentctl/',
outDir: './dist-agentctl',
integrations: [
mermaid({
autoTheme: true,
enableLog: false,
mermaidConfig: {
securityLevel: 'strict',
flowchart: { curve: 'linear', htmlLabels: false },
},
}),
starlight({
title: 'agentctl',
description:
'Declarative workflows for deterministic automation and bounded agent reasoning, with explicit policy and durable local state.',
tagline: 'Deterministic workflows. Bounded agents. Durable evidence.',
favicon: '/favicon.png',
social: [{ icon: 'github', label: 'agentctl on GitHub', href: github }],
editLink: { baseUrl: `${github}/edit/main/` },
lastUpdated: false,
pagination: true,
pagefind: true,
credits: false,
customCss: ['./src/styles/custom.css'],
components: {
Header: './src/components/Header.astro',
Footer: './src/components/Footer.astro',
},
head: [
{ tag: 'meta', attrs: { name: 'theme-color', content: '#0f766e' } },
{ tag: 'meta', attrs: { property: 'og:site_name', content: 'agentctl documentation' } },
{ tag: 'meta', attrs: { property: 'og:type', content: 'website' } },
{ tag: 'meta', attrs: { name: 'twitter:card', content: 'summary_large_image' } },
{ tag: 'meta', attrs: { property: 'og:image', content: 'https://opensourceops.github.io/agentctl/og.png' } },
{ tag: 'meta', attrs: { name: 'twitter:image', content: 'https://opensourceops.github.io/agentctl/og.png' } },
{
tag: 'script',
attrs: { type: 'application/ld+json' },
content: JSON.stringify({
'@context': 'https://schema.org',
'@type': 'WebSite',
name: 'agentctl documentation',
url: 'https://opensourceops.github.io/agentctl/',
}),
},
],
sidebar: [
{
label: 'Start here',
items: [
{ slug: 'overview', label: 'Overview', badge: 'v1alpha1' },
{ slug: 'why-agentctl', label: 'Why agentctl' },
{ slug: 'concepts/product', label: 'Product definition' },
{ slug: 'getting-started/installation', label: 'Installation' },
{ slug: 'getting-started', label: 'Getting started' },
{ slug: 'getting-started/first-agent', label: 'First agent workflow' },
{ slug: 'learning-paths', label: 'Learning paths' },
{ slug: 'deployment-model', label: 'Choose a deployment model' },
],
},
{
label: 'Learn the workflow model',
items: [
{ slug: 'concepts/workflow-model', label: 'Workflow document' },
{ slug: 'guides/workflow-authoring', label: 'Author workflows' },
{ slug: 'concepts/tools', label: 'Actions, tools, and effects' },
{ slug: 'concepts/policies', label: 'Policies and approvals' },
{ slug: 'concepts/memory', label: 'Memory' },
{ slug: 'concepts/packs', label: 'Packs' },
],
},
{
label: 'Run workflows',
items: [
{ slug: 'guides/local-operation', label: 'Local operation' },
{ slug: 'durable-execution', label: 'Resume, replay, retry, and fork' },
{ slug: 'operations/scheduled', label: 'Scheduled execution' },
],
},
{
label: 'Operate agentctl',
items: [
{ slug: 'guides/container', label: 'Container' },
{ slug: 'guides/ci-cd', label: 'CI/CD and Kubernetes' },
{ slug: 'observability', label: 'Logs and observability' },
{ slug: 'reference/database', label: 'State, locking, and retention' },
],
},
{
label: 'Providers and protocols',
items: [
{ slug: 'providers', label: 'Provider overview' },
{ slug: 'reference/capabilities', label: 'Capability matrices' },
{ slug: 'providers/mcp', label: 'MCP' },
{ slug: 'providers/a2a', label: 'A2A' },
{ slug: 'reference/environment', label: 'Authentication and environment' },
],
},
{
label: 'Security',
items: [
{ slug: 'security', label: 'Security model' },
{ slug: 'security/threat-model', label: 'Threat model' },
{ slug: 'concepts/policies', label: 'Filesystem, process, and network policy' },
{ slug: 'reference/limitations', label: 'Known limitations' },
],
},
{
label: 'Examples and use cases',
items: [
{ slug: 'examples', label: 'Examples overview' },
{ slug: 'examples/repository-audit', label: 'Repository audit' },
{ slug: 'examples/release-readiness', label: 'Release readiness' },
{ slug: 'examples/scheduled-review', label: 'Scheduled review' },
{ slug: 'examples/ci-quality-gate', label: 'CI quality gate' },
{ slug: 'examples/approval-gated', label: 'Approval-gated action' },
{ slug: 'examples/recorded-replay', label: 'Recorded replay' },
{ slug: 'examples/provider-portability', label: 'Provider portability' },
],
},
{
label: 'Troubleshooting',
items: [{ slug: 'troubleshooting', label: 'Problem-solving guide' }],
},
{
label: 'Reference',
items: [
{ slug: 'reference/cli', label: 'CLI reference' },
{ slug: 'reference/yaml', label: 'YAML reference' },
{ slug: 'reference/output', label: 'Output and exit codes' },
{ slug: 'reference/environment', label: 'Environment and default paths' },
{ slug: 'reference/capabilities', label: 'Provider and tool matrices' },
{ slug: 'reference/database', label: 'Database and migrations' },
{ slug: 'reference/terminology', label: 'Terminology' },
{ slug: 'reference/compatibility', label: 'Compatibility' },
{ slug: 'reference/migration', label: 'Migrate from TypeScript' },
{ slug: 'reference/limitations', label: 'Limitations' },
],
},
{
label: 'Architecture',
items: [
{ slug: 'architecture', label: 'Architecture overview' },
{ slug: 'architecture/diagrams', label: 'Architecture diagrams' },
{
label: 'Design decisions',
items: ['architecture/decisions/0001', 'architecture/decisions/0002', 'architecture/decisions/0003', 'architecture/decisions/0004', 'architecture/decisions/0005', 'architecture/decisions/0006', 'architecture/decisions/0007'],
},
],
},
{
label: 'Contributing',
items: [
{ slug: 'contributing', label: 'Contributor guide' },
{ slug: 'contributing/developer-guide', label: 'Developer guide' },
{ slug: 'contributing/testing', label: 'Build and test' },
{ slug: 'contributing/add-action', label: 'Add an action or tool' },
{ slug: 'contributing/add-provider', label: 'Add a provider' },
{ slug: 'contributing/add-migration', label: 'Add a migration' },
{ slug: 'contributing/documentation', label: 'Write documentation' },
{ slug: 'contributing/release', label: 'Release process' },
],
},
],
}),
],
});
25 changes: 25 additions & 0 deletions cspell.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"version": "0.2",
"language": "en",
"useGitignore": true,
"ignorePaths": [
"pnpm-lock.yaml",
"docs/execution/**",
"src/content/docs/_generated/reference/cli.md",
"public/downloads/workflow.schema.json"
],
"words": [
"agentctl", "OpenSourceOps", "Starlight", "Astro", "Pagefind", "Playwright",
"Anthropic", "Gemini", "OpenAI", "A2A", "MCP", "SQLite", "JSONL", "OCI",
"Kubernetes", "CronJob", "systemd", "runbook", "allowlist", "allowlists",
"idempotency", "idempotent", "toolchain", "checkpoints", "subprocess",
"worktree", "rustls", "Clippy", "Rustfmt", "CycloneDX", "Gitleaks", "Trivy",
"Cargo", "SHA", "v1alpha1", "tmpfs", "noexec", "nosuid", "runAsNonRoot",
"fsGroup", "backoffLimit", "concurrencyPolicy", "apiVersion", "prev", "frontmatter",
"astrojs", "basenames", "checkpointed", "checksummed", "Containerfile", "distroless",
"effectful", "exfiltration", "inspectable", "ledgered", "lockfiles", "misexecutes",
"msvc", "noninteractive", "nonroot", "oneshot", "proptest", "rustdoc", "sandboxing",
"schedulable", "Streamable", "subpaths", "TOCTOU", "transactionally", "uncheckpointed",
"unpushed", "xtask", "MSRV", "nojekyll", "accDescr"
]
}
19 changes: 19 additions & 0 deletions docs/DEPLOYMENT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# GitHub Pages deployment

The workflow in `.github/workflows/pages.yml` validates pull requests and deploys only from `main` or a manual dispatch. It checks out both repositories, runs the credential-free canonical and site gates, assembles `_site`, verifies `agentctl/index.html`, and uses GitHub's current Pages artifact deployment actions.

## Required repository settings after merge

1. Open the `opensourceops/opensourceops.github.io` repository settings.
2. Under **Pages**, set **Source** to **GitHub Actions**.
3. Keep the public custom domain empty unless OpenSourceOps intentionally adds one later.
4. Under **Actions**, allow GitHub-owned actions. No provider secret is required.
5. Protect `main` according to the organization's normal policy and require the `validate` job if desired.
6. Run the workflow manually once, or merge a validated change to `main`.
7. Confirm the deployment environment reports `https://opensourceops.github.io/` and verify `https://opensourceops.github.io/agentctl/` separately.

Do not configure Pages to deploy from a branch directory. The workflow uploads the complete `_site` artifact, including the organization root, `.nojekyll`, and the `agentctl/` subdirectory.

## Security model

Pull requests receive read-only repository permission and never reach the deployment job. The deployment job alone receives `pages: write` and `id-token: write`. The workflow does not read provider credentials or repository secrets. All action references are immutable commit SHAs with release annotations.
20 changes: 20 additions & 0 deletions docs/execution/AGENTCTL_DOCS_CONTENT_MATRIX.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# agentctl documentation content matrix

| User question | Persona | Public page | Canonical source | Working example | Verification | Status |
| --- | --- | --- | --- | --- | --- | --- |
| What is agentctl and why use it? | evaluator | homepage, overview, why agentctl | `docs/PRODUCT.md` | `examples/acceptance/mock-tool` | site copy review, example gate | complete |
| How do I install it? | new user | installation | `docs/guides/INSTALLATION.md` | `examples/v1/hello.yaml` | source install smoke | complete |
| How do I finish a first run? | new user | getting started | `docs/guides/GETTING_STARTED.md` | `examples/v1/hello.yaml` | clean-directory run | complete |
| How do I try an agent without a key? | new user | first agent workflow | `docs/guides/FIRST_AGENT_WORKFLOW.md` | `examples/acceptance/mock-tool` | clean-directory fake-provider run | complete |
| How does workflow YAML fit together? | workflow author | workflow authoring, YAML reference | `docs/DSL.md`, `docs/reference/YAML.md` | `examples/v1/dataflow.yaml` | check and plan | complete |
| How do I run and recover locally? | operator | local operation, durable execution | `docs/OPERATIONS.md`, `docs/DURABLE_EXECUTION.md` | `examples/v1/crash-resume.yaml` | runtime and acceptance tests | complete |
| How do I use a container? | platform engineer | container | `docs/CONTAINER.md` | acceptance mock tool | locally executed container acceptance | complete |
| How do I use CI or Kubernetes? | platform engineer | CI/CD | `docs/guides/CI_CD.md`, `docs/CONTAINER.md` | checked snippets | syntax and documentation review | complete |
| How should I schedule runs? | operator | scheduled execution | `docs/OPERATIONS.md` | cron, systemd, CronJob | documentation review | complete |
| Which provider can do what? | workflow author | providers | `docs/PROVIDERS.md` | `examples/v1/*-live.yaml` | mock protocol and opt-in live gates | complete |
| How do MCP and A2A behave? | integrator | protocols | `docs/MCP.md`, `docs/A2A.md` | `examples/v1/mcp.yaml`, `a2a.yaml` | local mock servers | complete |
| What is persisted and why? | operator | stateful architecture | `docs/DURABLE_EXECUTION.md`, `docs/MEMORY.md` | crash/resume and memory examples | store/runtime tests | complete |
| How do I diagnose a failed run? | operator | troubleshooting, observability | `docs/guides/TROUBLESHOOTING.md`, `docs/OBSERVABILITY.md` | failure fixtures | exit and inspection tests | complete |
| What are the security boundaries? | security reviewer | security, threat model | `docs/SECURITY.md`, `docs/THREAT_MODEL.md` | policy denial and approval | security and policy tests | complete |
| How do I add runtime behavior? | contributor | developer guides | `docs/development/*` | focused Rust tests | cargo tests and docs gate | complete |
| What is not supported? | evaluator | limitations and compatibility | `docs/LIMITATIONS.md`, `docs/COMPATIBILITY.md` | capability failure | negative contract tests | complete |
Loading
Loading