Goga
An open platform for building AI-SDLC.
AI can already write code. The next problem is engineering the process around it.
Goga turns engineering processes into reusable software. Define them as pipelines, package capabilities as tools, use any CLI agent at any stage — and share the whole methodology across projects.
A full Specification-Driven Development (SDD) cycle ships in the box — it can run interactively with a human in the loop or autonomously as a harness.
Three pillars
⚙ PipelinesA declarative scenario of stages an agent walks through to deliver work, with |
🧩 ToolsPluggable capability packages. Any open-source tool or in-house methodology is packaged as |
📋 SDDThe reference cycle shipped in the box: CODEMANIFEST contracts as the source of truth, an agent workflow from |
AI development without a framework collapses into uncoordinated agent runs — the cycle cannot be reproduced, there are no managed approval checkpoints, and the methodology is locked into a single tool. goga is the framework: the process is declared, agents are interchangeable, methodologies are composable.
Languages
| Python |
JavaScript |
Kotlin |
Swift |
Go |
Agents
| Claude |
Codex |
OpenCode |
Cursor |
Qwen |
Documentation · Getting Started · Pipelines · Tools · Configuration
Install
pipx install goga
goga build and goga pipeline launch a Docker container, so Docker must be installed and accessible on your host:
docker info
Before each launch they also verify that the host goga version and the image's goga version agree at the (major, minor) level — set GOGA_SKIP_VERSION_CHECK=1 to skip the check, and run goga --version to print the installed host version.
Connect goga to your agent
goga connect <agent>
To upgrade goga later and re-sync all connected agents, use:
goga upgrade
To stay within your current version line while upgrading, use goga upgrade --patch (latest patch of the installed minor line) or goga upgrade --minor (latest release of the installed major line). See goga upgrade for the full surface.
Quick start
Start a new project from scratch and ship your first piece of work end-to-end.
1. Initialize the project — the interactive wizard sets up .goga/config.yml, language conventions, and (optionally) a Dockerfile:
goga init
You can also start from a copier template (goga init <template-url>, optionally pinned with #ref or --ref), and later migrate a scaffolded project with goga init --upgrade. Installed tools can be invited into the wizard with goga init -t <tool-name> (repeatable) — the tool then contributes its own questions and its config files under .goga/tools/<tool>/. See goga init for the full surface.
2. Open your agent — launch the agent you connected via goga connect (e.g., Claude Code) in the project directory. All goga-<command> skills are now available.
3. Run a pipeline — pick one of the shipped cycles and let goga walk the agent through its stages, pausing at every communication checkpoint for your input. The container mounts nothing automatically: give it access to your agent credentials yourself — a read-only volume token in the docker.run list of ~/.goga/config.yml, or the agent's API-key env var with -e (see Credentials in the container):
goga pipeline refinement # product definition: define → discover → specify → review
goga pipeline development # the development cycle: prototype-architecture → … → accept
goga pipeline bugfix # root-cause analysis and defect resolution
goga pipeline patch # refactoring or minimal change with a plan
goga pipeline review # scoped review of code, contracts, docs, then lint/format/tests
goga pipeline sync # sync specifications & tests with the code after changes
Each pipeline is a flat YAML file describing the stages; layer project-specific behavior on top via an optional workflow file (per-stage agent, additional skills, prompt context, loop expansion, auto-approval, manual stage launch, stage skipping, note buttons, new stages, project-memory participation).
4. Drive the cycle by hand (optional) — if you want explicit control over each step instead of running a full pipeline, formulate the task and step through each command manually:
/goga:specify <what you want to create>
specify → prototype → apply → design → plan → goga build → change → accept
The slash-command form /goga:<command> works in agents that consume the goga command bundle — currently claude, opencode, and qwen (see goga connect). Codex and cursor do not register commands; in those agents invoke the skill directly: goga-specify (Codex uses the $ prefix — $goga-specify). Reviews are optional at every stage.
5. Inspect the result — once apply has produced cells on disk, view the cell hierarchy:
goga schema
Pipelines
A pipeline is a declarative scenario of stages an agent walks through to deliver a piece of work — specify, review, prototype, apply, design, plan, build, change, accept. A pipeline-file does not depend on any concrete agent: claude, codex, qwen, opencode, or any other installed wrapper can execute it. Stages with communication: true pause the run and ask for human input; without it they run autonomously.
A pipeline-file is a flat YAML document with a header and a list of stages:
name: Feature
description: End-to-end feature development
---
- name: specify
title: "Create the task from a user specification"
communication: true
prompt: |
Save the task file as `.goga/history/<year>/<topic>/task.md`
(`<year>` = current year, `YYYY`; `<topic>` = lowercase kebab-case slug
of the current git branch name; create the directory lazily)
skills:
- goga-specify
- name: prototype
title: "Task-based architecture development"
communication: true
skills:
- goga-prototype
- name: accept-result
title: "Contracts & coverage audit"
communication: true
skills:
- goga-accept
Six definitions ship with goga:
| Pipeline | Purpose |
|---|---|
development |
End-to-end development lifecycle: architecture, design, plan, accept |
refinement |
Product definition and task refinement: define, discover, specify |
bugfix |
Root-cause analysis and resolution for a defect |
patch |
Refactoring or minimal change with a formalized plan |
review |
Scoped review of code, contracts, docs, then lint/format/tests |
sync |
Sync specifications and tests with the implementation |
Pipelines are resolved from <cwd>/.goga/pipelines/ (project) and ~/.goga/pipelines/ (user); the project source wins on name conflicts.
goga pipeline development # run the development cycle (opens with prototype-architecture)
goga pipeline development -t feat/x # first switch to the branch hosting this work, then run
goga pipeline refinement -s discover # shorter run: skip technical discovery
goga pipeline development -p 4 # cap parallelism (subject to the pipeline's dependency rules)
goga pipeline development --clean # wipe persistent state for a fresh run
Inspect pipelines without running anything:
goga pipeline --list # available pipeline names
goga pipeline --list --info # every pipeline with its description
goga pipeline development --info # the pipeline card: stages in execution order
goga pipeline development --info -s prototype-architecture # the card with a stage excluded — the composition the run would execute
A running pipeline executes inside a Docker container, where its flows, run-state, and logs are written to a persistent host directory and survive across runs of the same pipeline on the same project and branch — so an interrupted run can be resumed.
Workflows — configure and extend a pipeline
A workflow-file (.goga/workflows/<name>.yml) configures and extends a compiled pipeline at run time, without touching the pipeline-file. Eight levers, each with a short example.
agent — hire a different agent per stage. Authoring on codex, reviews on claude, no pipeline duplication:
stages:
prototype-architecture:
agent: codex
architecture-review:
agent: claude
plan-review:
agent: claude
loop — repeat a stage N times as chained copies. Multiple review passes with increasing depth:
stages:
plan-review:
loop: 2 # → plan-review-1 → plan-review-2, each depending on the previous
approve — auto-approve a stage. Three modes (auto / plan / dialog) drive two independent effects — suppression of interactive and emission of auto_approve:
stages:
accept-result:
approve: auto # the stage will not prompt the user and will self-approve
manual — hold a stage for manual launch. manual: true compiles the stage with auto_run: false — the run pauses when it reaches the stage and continues only after you launch it; manual: false cancels a trigger: manual authored in the stage body:
stages:
accept-result:
manual: true # the pipeline pauses before accept-result until launched manually
skills — add skills to a stage. Merged with the pipeline stage's own skills (pipeline-first, deduplicated by value):
stages:
prototype-architecture:
skills: [goga-tool-acme-explore, goga-tool-acme-propose]
prompt — context, not command. To make a workflow prompt carry actual requirements, use labeled blocks (Requirements: / Constraints:); free-form prose is interpreted as background:
stages:
specify:
prompt: |
Task formalization process.
Requirements:
- Examine all link connections between cells carefully.
- Do not write code examples in the task.
Constraints:
- Do not build architecture in the task.
notes — attach note buttons to a stage. A map of note name → prompt text, compiled verbatim into the stage's buttons field:
stages:
plan-review:
notes:
fix: Fix the failure and continue
memory — wire stages into project memory. A top-level block plus per-stage instructions; the block is emitted only when at least one stage participates:
memory:
method: reflect # or: alignment
max_rules: 40
stages:
prototype-architecture:
reflect: # which memory file the stage reflects into
file: shared.md
Additionally: skip: true removes a stage with transparent reconnection of dependents, and extend: adds brand-new stages with before/after positioning (a new stage's own launch mode is authored in its body via trigger: manual). Names under stages: must name stages of the target pipeline — specify exists only in refinement, prototype-architecture only in development; brand-new stages come via extend:. The full model is in the Workflows documentation. Workflow memory requires afm 0.5.60+ (the shipped image carries it).
Run with a workflow:
goga pipeline development # auto-match: .goga/workflows/development.yml if present
goga pipeline development --workflow custom # explicit
goga pipeline development --no-workflow # disable workflow application entirely
Read the full functional model in the Pipelines section of the docs.
Build
goga build is a separate service that materializes a plan into code. Pipelines produce plans; Build executes them — and neither side is a special case of the other. A plan is handed to a ralph-loop running inside an isolated Docker container, which reads the plan, executes each task in sequence (declaration → contract tests → implementation → interface verification → logic tests → debugging → contract re-verification → lint → review → approval), and writes the implementation into the project tree. CODEMANIFEST files stay read-only throughout — the contract is the source of truth, the build produces code that satisfies it.
goga build .goga/history/<year>/<topic>/plan.md
The host side assembles the environment and launches the container; the in-container process then guards its environment, prepares the loop's working directory, and runs the loop with the plan as input. The launcher adds no credential mounts — mount the agent's credential file read-only yourself via the docker.run list of ~/.goga/config.yml, or pass its API-key env var with -e, so the agent executing the plan runs with your live credentials (see Credentials in the container).
Customize the run with the usual flags:
goga build plan.md --update # refresh the image first (build from config dockerfile, else pull)
goga build plan.md --clean # wipe persistent loop state for a fresh run
goga build plan.md -e ENV_VAR=value # forward an extra env var into the container
goga build plan.md --skip-review # run tasks only, skip the review phase
The build configuration in .goga/config.yml is two-part: the build root carries the tasks-pass settings (agent, env, iteration and session knobs), and its review sub-block carries the review-pass settings. A run with review on is always two passes — a tasks pass on the root agent's wrapper, then a review pass on the review agent's wrapper (review.agent inherits build.agent when unset); --skip-review or review.skip: true collapses the cycle to the tasks pass alone, and a failed tasks pass skips the review. The review pass is configured through the sub-block:
- Hand review to a different agent (
review.agent: codexruns the review pass on the codex wrapper; unset inheritsbuild.agent); - Skip it by default (
review.skip: true—--no-skip-reviewforces the full cycle); - Select the reviewer composition (
review.roles: [quality, testing]); - Layer environment variables onto the review pass alone (
review.env: {ANTHROPIC_MODEL: reviewer}— the variables overlay the container environment for the review subprocess only; the tasks pass never sees them, the review env never inherits the root env, and the values never reach logs or dry-run output); - Bound the review diff to an explicit base (
review.base_ref: origin/main— a branch name or commit hash that overrides ralphex's default-branch detection;--base-refon the command line wins); - Pick the review strategy (
review.strategy: full | medium | short, defaultmedium—mediumdisables the external reviewer;fullkeeps it;shortruns the external review alone, on the additional agent's wrapper); - Set a finalize prompt (
review.finalize: |— a user-authored final review prompt materialized into ralphex's finalize step); - Stop the external review after N unchanged rounds (
review.additional.patience: 3, or--review-patience).
Before the first pass a validation gate runs: tools subscribed to build/validate_build read the resolved run facts and may veto the run (see Tools below). After a successful run the plan file itself moves to completed/ inside its own topic directory (.goga/history/<year>/<topic>/completed/).
A running build executes inside a Docker container, where its run-state and logs are written to a persistent host directory and survive across runs of the same project on the same branch — so an interrupted build can be resumed. Pass --clean (or -c) to wipe that state before launch for a fresh run. After the build, test the implementation manually.
See goga build for the full CLI reference, configuration, and exit codes.
Tools
A tool is a pluggable capability package. Any open-source tool or in-house methodology is packaged as a Python package under the goga_tool_ prefix and becomes part of the goga ecosystem: its skills land in a shared catalog at ~/.goga/skills/, its pipeline-files install at ~/.goga/pipelines/ with a namespace prefix, and everything lives side by side, addressed uniformly.
Installing a tool
Tools are distributed as Python packages under the goga-tool- prefix. goga install targets the running interpreter's pip directly and re-syncs every already-connected agent after a successful pip — the new tool's skills and pipelines appear in ~/.goga/ and in each agent's symlink tree immediately:
# Install one tool, latest version
goga install <tool-name>
# Install a pinned or ranged version (four-form grammar)
goga install <tool-name> --version 1.0.x
# Install every tool declared under tools: in .goga/config.yml in one pip call
goga install
# Install a tool from a local source directory (no PyPI lookup)
goga install --local <path>
# Same, naming the tool whose post-install hook runs
goga install --local <path>:<tool-name>
After a successful pip, goga install runs each freshly installed tool's optional post-install hook (a callable install in its facade — skipped quietly when absent), then re-syncs every already-connected agent automatically. Connect a new agent at any time:
goga connect <agent>
Pass goga install --no-connect to opt out of the post-install agent re-sync (CI/Docker escape-hatch; the post-install hooks still run). Pass goga install --sudo for system-Python installs requiring root.
See goga install for the full version-grammar rules and single/bulk/empty/local semantics.
Removing a tool
goga uninstall removes exactly one tool package from the running interpreter's pip. It asks for confirmation first — Enter removes (the default is Y), n cancels:
# Remove one tool (interactive confirmation, Enter = yes)
goga uninstall <tool-name>
# Skip the confirmation — the scripted/CI form
goga uninstall <tool-name> --yes
goga uninstall <tool-name> -y
# Remove from a system-Python install requiring root
goga uninstall <tool-name> --sudo
# Remove and re-sync another user's goga installation
goga uninstall <tool-name> --user alice
After a successful pip uninstall, every connected agent is re-synced: the removed tool's skills and pipelines disappear from ~/.goga/ and from each agent's symlink tree. A tool removed by hand with plain pip leaves those artifacts behind until the next re-sync.
See goga uninstall for the full confirmation, sudo/user, and exit-code semantics.
Using a tool
Via CLI:
goga tool <name> [args...]
Via agent skill:
Invoke the /goga:tool <name> command (or goga-tool skill) in your agent session. The slash-command form works in claude, opencode, qwen; in Codex and cursor, invoke the skill directly — goga-tool (Codex: $goga-tool).
Packaging your own tool
Minimal layout, illustrated by a tool named acme that ships four subcommands — explore, propose, apply, archive — and one pipeline-file:
goga_tool_acme/
├── __init__.py # main(argv: list[str]) — CLI entry; optional install()/register_hooks()
├── skills/
│ ├── acme/
│ │ └── SKILL.md # goga-tool-acme — the entry point
│ ├── acme-explore/
│ │ └── SKILL.md # goga-tool-acme-explore
│ ├── acme-propose/
│ │ └── SKILL.md # goga-tool-acme-propose
│ ├── acme-apply/
│ │ └── SKILL.md # goga-tool-acme-apply
│ └── acme-archive/
│ └── SKILL.md # goga-tool-acme-archive
└── pipelines/
└── spec.yml # → ~/.goga/pipelines/acme:spec.yml
A valid tool must:
- Be named with the
goga_tool_prefix (PyPI publication undergoga-tool-) - Contain the entry-point skill
skills/<tool-name>/SKILL.md—goga connectskips the whole package with a warning when it is missing (every skill directory carries aSKILL.md) - Expose a
main(argv: list[str])function for CLI execution - A
pipelines/directory is optional; when present, its flat*.ymlfiles are copied into~/.goga/pipelines/atgoga connecttime, namespaced as<tool>:<name>.yml
A tool may additionally expose an install(user: str | None = None) callable in its facade package: goga install calls it after a successful pip, passing the initiating user (SUDO_USER when goga itself runs under sudo, else the current OS user) only when the parameter is declared keyword-capable. A missing or non-callable install is skipped quietly.
A tool may also expose a register_hooks(hooks) callable to extend goga domains with its own hooks. Today the hook zones are:
- statuses — the topic status scale registration (
register_statuses); - onboarding — the onboarding session (
declare_session/amend_config, reached viagoga init -t <tool>); - topics — the nine topic-lifecycle checkpoints: two content amendments and seven notifications (see Topics — Hooks);
- pipeline — the three checkpoints: the workflow amendment
amend_workflowand the two run notificationsrun_created/run_completed(see Pipelines — Hooks); - build — the five checkpoints: the validation gate
validate_build, delivered before the first pass with the resolved run facts, plus the four run notificationsbuild_started,pass_started,pass_completed,build_completed(see Build — Hooks); - config — the config amendment checkpoint
config/amend_config, delivered at the project-config load moment of every host-side config-consuming command (pipeline,lint,contract,installbulk,config,build,topics,usages status/sync) and delivered a second time in-container by the run form ofgoga pipelineand bygoga build— the in-container delivery feeds the run parameters (pipeline.agent/pipeline.env,build.*) and fails the run cleanly (exit 1) on a hard hook failure (see Configuration — Hooks); - schema — the cell-amendment checkpoint
schema/amend_cell, delivered at the generation moment of the project map (goga schema), and the validation gateschema/validate_schema, an observe-and-veto pass over the final assembled tree delivered after the tools overlay and before serialization (see Schema — Hooks); - contract — the contract-amendment checkpoint
contract/amend_contract, delivered at the comparison moment of every requested cell (goga contract— tools read the comparison facts of each cell and contribute per-type facts onto thetoolsarea of the JSON output; see Contract — Hooks); - usages — the four run-level moments
usages/sync_started,usages/sync_completed,usages/status_started,usages/status_completed— all soft notifications wrappinggoga usages syncandgoga usages status(see Usages — Hooks).
goga calls register_hooks when a command first reaches a hook checkpoint of the run, or when you inspect the registry with goga hooks; commands that use no hooks never call it:
def register_hooks(hooks):
hooks.subscribe("statuses", "register_statuses", "published", register_published)
def register_published(context):
context.register("published", "mkdocs/published.md", after="planned")
The hook receives the delivered status registry through context — read and call freely, attribute assignment is blocked. The name is shown qualified as <tool>.<name> (here mkdocs.published); the tool identity is the package name with the goga_tool_ prefix dropped and underscores turned into hyphens, so goga_tool_hello_world registers hello-world.*. The filepath is relative to the topic directory (nested paths allowed), and before=/after= anchor the entry to an existing scale entry — at least one anchor is required, both define a range. Built-in entries are immutable. A bad registration — an unknown anchor, an invalid range, or a crashed hook — is skipped with a warning on stderr and never aborts the command; only a package that fails to import is fatal. That skip-with-a-warning rule covers the soft actions; the platform's hard actions are pipeline/amend_workflow, build/validate_build, config/amend_config, schema/amend_cell, schema/validate_schema, and contract/amend_contract — a hook of the first that raises (or contributes a malformed document) aborts goga pipeline before any launch with a clean error naming the hook, the tool, and the action; the build gate instead lets every subscribed tool's hooks run to completion, collects their context.veto(reason) calls (a raising hook counts as its tool's veto, with the crash reason), and merges all vetoes into one error that stops goga build before any pass; the config amendment stops the command at the first failing tool with the same clean error (a structurally malformed contribution — an unknown path, a non-leaf address, a wrong-typed value — is treated identically, and the tool's whole contribution is discarded); the schema cell amendment stops goga schema at the first failing tool the same way — a crashed hook or a contribution not representable in the node's JSON map — its error naming the tool, the action, and the failing cell path, with no partial map printed; the schema validation gate runs like the build gate — every subscribed tool's hooks run to completion, one veto per tool (context.veto(reason); a crash counts as that tool's veto), merged into one error that stops goga schema before any output, nothing on stdout; the contract amendment stops goga contract at the first failing tool the same way — a crashed hook, a structurally malformed contribution, or a contribution addressing a type the cell does not declare — with the same clean error naming the hook, the tool, the action, and the failing cell path, and no partial JSON printed. Run goga hooks to inspect what is registered. The removed register_topic_statuses(statuses) callback is no longer called — a package still carrying it loses its statuses silently after the update.
After publication, install into any project:
goga install acme
goga pipeline acme:spec # namespaced pipeline from the tool
The subcommands become ordinary agent skills — goga-tool-acme-explore, goga-tool-acme-propose, goga-tool-acme-apply, goga-tool-acme-archive — that can be invoked directly (/goga:tool acme explore, goga-tool-acme-explore, or $goga-tool-acme-explore in Codex) or merged into any stage of any pipeline via skills: in a workflow-file. The acme cycle explore → propose → apply → archive can be run end-to-end through acme:spec, woven stage-by-stage into the SDD cycle, or composed into a custom pipeline where goga-tool-acme-propose runs next to goga-prototype.
The entry point may optionally declare a keyword-capable ast parameter to receive the project AST (loaded lazily from the current project root, only when declared). It may likewise declare a keyword-capable config parameter to receive the tool's raw YAML config from .goga/tools/<tool>/config.yml (an absent file delivers None). A tool that declares neither keeps the minimal main(argv) form and the AST is never built. See goga tool for the entry-point forms and opt-in rules.
Skill naming
When goga connect installs a tool, the prefix goga-tool-<tool-name>- is added to every skill and the result lives centrally under ~/.goga/skills/:
In package (skills/) |
After goga connect (~/.goga/skills/) |
|---|---|
mkdocs/SKILL.md |
goga-tool-mkdocs |
mkdocs-discovery/SKILL.md |
goga-tool-mkdocs-discovery |
mkdocs-writer/SKILL.md |
goga-tool-mkdocs-writer |
Rules:
- Use lowercase with hyphens as separators
- The entry-point skill directory is named exactly
<tool-name>— it becomes the skill invoked by/goga:tool <name>(orgoga-tool/$goga-toolin agents without slash-command support). It is required: a package withoutskills/<tool-name>/SKILL.mdis skipped bygoga connectwith a warning. - Name sub-skills descriptively using the
<tool-name>-<purpose>pattern (e.g.,mkdocs-discovery,mkdocs-validator)
Pipeline namespacing
Tool pipelines are namespaced on install. A file <name>.yml in a tool's pipelines/ directory is copied into ~/.goga/pipelines/ as <tool>:<name>.yml, where <tool> is the package name with the goga_tool_ prefix dropped and underscores normalized to hyphens (goga_tool_hello_world → hello-world):
| Source | Destination in ~/.goga/pipelines/ |
Addressable as |
|---|---|---|
Internal goga source (goga/assets/pipelines/) |
development.yml (un-prefixed) |
goga pipeline development |
Tool package goga_tool_acme/pipelines/deploy.yml |
acme:deploy.yml |
goga pipeline acme:deploy |
Namespacing structurally prevents collisions — between a tool pipeline and an internal-source pipeline, and between two tools shipping the same name. See Shipped Pipelines for the full installation algorithm.
Read the full Tools model in the Tools section of the docs.
SDD — the reference cycle
Out of the box, goga ships a full Specification-Driven Development (SDD) cycle. This is the three pillars in action: a pipeline-file describes the stages, tools supply skills, and CODEMANIFEST is the contract language used inside the stages. Use the cycle as is, extend it through workflows, or replace it with your own methodology built from tools and pipelines.
Contracts as the source of truth
A cell is a directory that encapsulates a distinct responsibility domain with a well-defined API boundary. Each cell contains a CODEMANIFEST file describing its contract and an optional .usages/ directory with documentation for API consumers.
cell/
├── CODEMANIFEST # YAML DSL describing the API contract
└── .usages/*.md # Practices for working with the cell
The rule of thumb is one responsibility zone — one cell. A new cell is born when logic can be decoupled, owns distinct data models, must be reused, or can be stated in a single phrase without "and".
Sharing specs across projects
Cell .usages/ practices can be shared through git: declare a dependency in .goga/config.yml and run goga usages sync — usage files from the source repository sync into .goga/usages/<group>/<dep>/, ready to be referenced by Usages in any CODEMANIFEST.
Anatomy of a contract
A CODEMANIFEST consists of three sections separated by ---:
- Header —
Imports(types and usages from other cells),Usages(named practices),Annotations(global directives) - Body — entities and routines that form the cell's public API
- Footer —
Author,CreatedAt,Description
Cells expose three kinds of types:
- Entity types — objects with state and behavior (services, configurations, data models): properties + methods
- Routine types — single operations (transformers, factories, validators, parsers): no state
- Embedded types — re-exports of imported types:
->ExternalService
Specialization is expressed with the :: mutation syntax. The DSL stays language-agnostic — BaseEntity::ExtendedEntity may be realized through inheritance, composition, an adapter, or an interface implementation in the target language.
Example
Imports:
- Types:
- AnotherCellType
From: path/to/another_cell
Usages:
conventions: .goga/usages/conventions.md
Annotations: |
Use `conventions` when writing code.
---
"ParseInput(input: string) -> data:List<byte>":
location: parser.py
annotations: |
Parses raw input into a byte buffer.
`input`: raw request payload
"HTTPServer(name: String)":
location: server.py
properties:
"host -> String": |
Bind address for incoming connections.
methods:
"handleRequest(req: Request) -> resp:Response": |
Dispatches a single HTTP request.
Algorithm:
1. Parse input from `req` with `ParseInput`
2. Filter result by some logic
3. Save filtered result in `resp`
4. Return `resp` object
---
Author: Goga
CreatedAt: 01/01/26
Description: |
HTTP entry point cell.
Extending the cycle
The SDD cycle is not monolithic — every part of it is extensible through the same workflow mechanisms described in the Pipelines section, applied to the shipped development pipeline.
Add an external skill to a stage. prototype-architecture gains an extra skill from the acme tool alongside goga-prototype:
# .goga/workflows/development.yml
stages:
prototype-architecture:
skills: [goga-tool-acme-explore]
Swap an SDD stage for an external equivalent. On architecture-review, switch to codex and run goga-tool-acme-explore against the spec; on apply-architecture, loop twice and pair goga-apply with goga-tool-acme-apply:
stages:
architecture-review:
agent: codex
skills: [goga-tool-acme-explore]
apply-architecture:
loop: 2
skills: [goga-tool-acme-apply]
Insert new stages from a tool's arsenal. Between plan-review and commit-changes, run goga-tool-acme-explore to walk the spec; after accept-result, run goga-tool-acme-archive to archive the delivered spec snapshot:
extend:
spec-explore:
after: [plan-review]
before: [commit-changes]
title: Spec exploration
skills: [goga-tool-acme-explore]
prompt: |
Walk the current spec before architecture work begins.
spec-archive:
after: [accept-result]
title: Archive spec
skills: [goga-tool-acme-archive]
prompt: |
Archive the delivered spec snapshot.
Run a stage for two passes. plan-review with loop: 2 runs two sequential passes with increasing depth:
stages:
plan-review:
loop: 2
Finish autonomously. accept-result with approve: auto suppresses the user prompt and self-approves:
stages:
accept-result:
approve: auto
These are not special "SDD extension points" — they are exactly the same workflow mechanisms from the Pipelines section, applied to the SDD cycle. Combining tools and workflows, SDD can be compressed to specify → accept for prototypes or expanded with threat-modelling, security review, and compliance gates for production. Read the full functional model in the Workflows section of the docs.
Topics
Work is organized as topics — one directory per piece of work under .goga/history/<year>/<topic>/, each usually living on its own git branch. The goga topics command group manages them:
goga topics board # the board: one entry per topic of the year with its own branch
goga topics board --remote # same board over remote-tracking refs
goga topics board --info # the board with the todo column (the todo summary of todo.md)
goga topics board --per-host # the audit view: one row per topic and hosting branch
goga topics board --json # the machine-readable board (pretty-printed JSON, either view)
goga topics board --host feat/x --host main # keep only the topics hosted by the named branches
goga topics board --topic feat-x --topic feat-y # keep only the named topics (repeatable, composes with --host)
goga topics create feat/x --from-current # fresh work off the current HEAD: the branch verbatim + its topic committed, you stay on your branch
goga topics create feat/x --from-current -t "Payment retry" # same; the todo becomes the branch's todo.md commit (status: todo)
printf 'Payment retry.\n' | goga topics create feat/x --from-current --todo # same; the piped stdin is the todo (value-less --todo), no publication ask
goga topics create feat/x --from-current -s # same, but switch to the fresh branch; on a terminal the todo entry opens in your `$EDITOR`
goga topics create feat/x --from-current -p -t "Payment retry" # same as the default, plus pushed to origin
goga topics switch feat-x # onto the branch hosting that work (branch, slug, or prefix)
goga topics switch feat-x --todo # same, then edit the topic's todo.md in your `$EDITOR`
goga topics update feat-x # bring the topic up to its base (merge/rebase per topics.update.strategy), checkout-free
goga topics update --publish # update the current topic, then push the refreshed branch (rebase pushes under a lease)
goga topics publish feat-x # deliver an existing topic branch to origin (pushed / up-to-date / remote-ahead; a diverged twin is a clean error)
goga topics propagate feat-x # deliver the finished topic into its base and push it — one confirmation (--yes skips)
goga topics delete feat-x # delete the branch, its origin twin, and the directory
goga topics clear # delete every merged topic of the year (base: --base-ref or topics.base_ref), one confirmation
goga topics --year 2025 board # the board of an explicit year
Every create needs a base: --base-ref, or topics.base_ref in .goga/config.yml, or the current HEAD under --from-current. The default creation quarantines the topic into the branch — one commit carrying the topic's todo.md on top of the base — while you stay on your branch; the todo is required there. -t/--todo carries three states: a value is the todo itself, the value-less form takes it from the piped stdin (read fully once, strictly UTF-8, verbatim; piped content without the declaration is a clean error), and with nothing given a terminal opens the external editor for the todo. Once a todo is resolved the command asks on a terminal whether to publish — never when the todo came from the pipe; without a terminal the no-switch creation is a clean error while -s succeeds with no todo. -s/--switch checks out the fresh branch instead — the topic directory and todo.md land in the working copy uncommitted, and the todo is optional. --publish/-p is the fast mode: it builds the branch off the resolved base with a single todo.md commit and pushes it to origin without switching — your working copy, index, and HEAD stay untouched, and a failed push rolls the branch back. See goga topics.
The exchange pair works against the same topics.base_ref base (--base-ref beats it). goga topics update brings a topic up to its base under topics.update.strategy (merge, rebase, ff-else-merge, ff-else-rebase) — another topic updates fully checkout-free while you stay on your branch, the current one updates in place behind a read-only pre-flight, and every conflict is a clean error pointing at manual git before anything mutates. goga topics publish delivers an existing topic branch to origin as an operation of its own — an omitted identifier addresses the current topic, no confirmation, no force or lease ever, no configuration keys; one targeted fetch of the branch's own origin twin, then one of three success kinds (pushed — the twin is created or fast-forwarded from behind, up-to-date, remote-ahead), one stdout line naming the kind, and exit 0 on all three (a diverged twin — neither contains the other — is a clean error naming both tips). goga topics propagate delivers a finished topic into its base (topics.propagate.strategy: merge, ff, squash) and pushes it — the push is inherent — after exactly one confirmation naming the topic, the base, and the push; a base the remote moved concurrently gets one retry cycle, and a base that already carries the topic is the idempotent nothing-to-do success. The exchange pair needs git >= 2.40.
A clear takes the same topics.base_ref base — --base-ref beats it, and there is no current-HEAD rung — and removes every own-branched topic of the year the base's tree already carries (the merged work), each with its branch, its origin twin, and its directory; a topic without its own branch is silently skipped — it is history. An empty scope is one line and exit 0.
The board is a four-column table — topic, branch, hosts, statuses, plus the todo and delivery columns under --info (the delivery cell shows the topic's divergence against the configured topics.base_ref: base, up-to-date, propagated, or need-update) — one entry per topic that still has its own branch, with * marking the current branch and the hosts column listing every branch carrying the topic's history (a local branch absorbing its remote twin). Each topic carries its maximal statuses in scale order: empty → todo → defined → discovered → backlog → prototyped → designed → planned → done, deepening as todo.md, prd.md, adr.md, task.md, arch.md, design.md, plan.md, and completed/plan.md land. A topic can carry several statuses at once (goga history status prints them; -s filters by any of them).
Topics no branch hosts anymore are orphans — goga history prune --dry-run lists the orphans of a year, and goga history -y <year> prune deletes them (the year is the group's -y/--year option, given once before the subcommand; irreversibly: the history tree is not in git).
To resume work inside a pipeline, pass the identifier to the run — goga pipeline development -t feat/x switches to the hosting branch first (creating a local branch from its remote-tracking ref when needed) and is an idempotent no-op when you are already on it; adding --todo opens the topic's todo.md in your editor after the switch. Fresh work is better started with goga topics create — it takes an explicit base, todo, and publication; a pipeline -t creates from the current HEAD when nothing hosts the identifier.
Documentation
Full documentation is available at qarium.github.io/goga.
Contributing
After cloning, enable the local git hooks once:
make install-hooks
This installs two-layer protection against Co-Authored-By: trailers (project policy: no co-authorship in git history):
- commit-msg — blocks the commit at creation time.
- pre-push — blocks the push if any new commit being pushed contains the trailer (catches cases where the commit-msg hook was bypassed with
--no-verifyor not installed).
Bypass in rare intentional cases with git commit --no-verify / git push --no-verify.
Metadata
Release files for goga 2.0.3
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| goga-2.0.3.tar.gz | 3.2 MB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| goga-2.0.3-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 4.4 MB
Release files / goga-2.0.3.tar.gz
| Download URL | goga-2.0.3.tar.gz |
|---|---|
| Size | 3.2 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
2569db35cd55ac07775bd1d232faadb6a1db9115f529e0fde96bc174cd9ef22f
|
|
BLAKE2b-256 checksum How to use checksums |
7d9e2d5cb55537874430f2864548f8a252e98238472d7936cb49ce1ca124ef5e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Release files / goga-2.0.3-py3-none-any.whl
| Download URL | goga-2.0.3-py3-none-any.whl |
|---|---|
| Size | 1.2 MB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
ede80f3d12e163fb93cf7fa82319a65ae45477437259c370e73e14fd8f0aca96
|
|
BLAKE2b-256 checksum How to use checksums |
cdb46bc125f1bfa5d0664dda20ae614bd317a74d9d54e5667a41aa2c34816452
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|