docs: adapt SDD process + agent specs for alkgit

- sdd_process.md: alkcall -> alkgit
- coordinator: spawn prompt targets alkgit, constraints point at AGENTS.md
- implementation-specialist: conventions rewritten for the git-server
  workspace (replaces alkcall-specific vendored-types/BAST/abort items)
- code-reviewer: thiserror (no anyhow), sha256/acme feature flags
- architect/architecture-reviewer: examples de-alknetted

Verified: none needed (markdown only)
This commit is contained in:
glm-5.3-flash committed 2026-09-19 15:36:24 +00:00
1 parent a3cdef909b
commit 1df339f4ec
6 files changed
+60 -77

No files matched your search

+9 -8
View File
@@ -326,10 +326,10 @@ result, a concrete use case to arrive.
A decision should be `deferred(scope)` when: A decision should be `deferred(scope)` when:
- The use case isn't concrete (e.g., "we don't know what the agent crate - The use case isn't concrete (e.g., "we don't know what the admin API
will need from the call protocol") will need from the call protocol")
- The options depend on something that doesn't exist yet (e.g., - The options depend on something that doesn't exist yet (e.g.,
"depends on the alknet-http crate spec") "depends on the alkgit-http streaming adapter shape")
- The trade-off requires data that can only come from implementation - The trade-off requires data that can only come from implementation
(e.g., "need performance benchmarks to choose between X and Y") (e.g., "need performance benchmarks to choose between X and Y")
- The decision is genuinely not needed for the current scope (e.g., "the - The decision is genuinely not needed for the current scope (e.g., "the
@@ -373,13 +373,14 @@ A decision should be `deferred(unclear)` when:
(implies it's decided). (implies it's decided).
2. **State the blocking condition** (`deferred(scope)`) or 2. **State the blocking condition** (`deferred(scope)`) or
**investigation target** (`deferred(unclear)`) — what specific thing **investigation target** (`deferred(unclear)`) — what specific thing
would unblock this? Be concrete: "blocked on: alknet-agent crate spec would unblock this? Be concrete: "blocked on: alkgit-admin crate spec
exists" or "investigation: work through 2+ example outbound-dial use exists" or "investigation: work through 2+ example git-over-ssh use
cases (hub→worker, worker→hub) to see how verifier-selection + cases (clone and push) to see how identity + repo resolution +
provider + connector compose." pkt-line session compose."
3. **State the impacts** — what does this block downstream? Be 3. **State the impacts** — what does this block downstream? Be
specific: "blocks the first hub deployment because the hub dials specific: "blocks the http endpoint because receive-pack needs
workers" not "blocks the hub crate." This is the triage signal that unbuffered POST ingestion" not "blocks the http crate." This is the
triage signal that
makes the deferral's urgency visible. If the impact is significant, makes the deferral's urgency visible. If the impact is significant,
the deferral needs to be addressed soon; if it's a future feature, the deferral needs to be addressed soon; if it's a future feature,
it can wait. it can wait.
+3 -2
View File
@@ -158,8 +158,9 @@ blocks downstream. Check:
- Is the impacts field present? Absence is a warning — without it, the - Is the impacts field present? Absence is a warning — without it, the
deferral's urgency is invisible and triage is guesswork. deferral's urgency is invisible and triage is guesswork.
- Is it specific? "Blocks the first hub deployment because the hub - Is it specific? "Blocks the http endpoint because receive-pack needs
dials workers" is useful. "Blocks the hub crate" is boilerplate. unbuffered POST ingestion" is useful. "Blocks the http crate" is
boilerplate.
- Does it match the priority? A `deferred(unclear)` with high priority - Does it match the priority? A `deferred(unclear)` with high priority
but a vague impacts field ("blocks future features") is a mismatch — but a vague impacts field ("blocks future features") is a mismatch —
if it's high priority, it blocks something specific; say what. if it's high priority, it blocks something specific; say what.
+4 -4
View File
@@ -111,10 +111,10 @@ cargo fmt --check # Format check
For this project, also verify: For this project, also verify:
- No comments in code (per project convention) - No comments in code (per project convention)
- Error handling uses `anyhow::Result` (application) / `thiserror` (library) — no - Error handling uses `thiserror` for library error types — no panics in
panics in library code library code, no `unwrap()`/`expect()` outside tests
- Feature flags are used correctly (`tls`, `iroh`, `acme`) — base crate compiles - Feature flags are used correctly (`sha256`, `acme`) — base crates compile
lean lean; default features stay minimal
- Public API is well-documented with `///` doc comments where appropriate - Public API is well-documented with `///` doc comments where appropriate
- Module structure follows Rust conventions (`mod.rs`, `lib.rs`) - Module structure follows Rust conventions (`mod.rs`, `lib.rs`)
- No unnecessary `unwrap()` or `expect()` in library code - No unnecessary `unwrap()` or `expect()` in library code
+8 -6
View File
@@ -185,13 +185,14 @@ also include:
main may have advanced since their worktree was created main may have advanced since their worktree was created
3. **Key references** — Which source files and architecture docs to read 3. **Key references** — Which source files and architecture docs to read
4. **Project constraints** — Important rules from the repo (no comments, 4. **Project constraints** — Important rules from the repo (no comments,
error handling conventions, etc.) error handling conventions, etc.). Point at `AGENTS.md` at the repo root —
it is the authoritative list; don't duplicate the whole list here.
5. **Done signal** — Use `worktree({action: "notify", ...})` when complete 5. **Done signal** — Use `worktree({action: "notify", ...})` when complete
Example prompt template: Example prompt template:
``` ```
You are an implementation specialist for the @alkdev/alknet project. You are an implementation specialist for the @alkdev/alkgit project.
Your task: {{task}} Your task: {{task}}
@@ -204,13 +205,14 @@ Your task: {{task}}
7. Push: git push origin $(git branch --show-current) 7. Push: git push origin $(git branch --show-current)
8. Notify: worktree({action: "notify", args: {message: "Task completed: {{task}}. <brief summary>", level: "info"}}) 8. Notify: worktree({action: "notify", args: {message: "Task completed: {{task}}. <brief summary>", level: "info"}})
Key project constraints (@alkdev/alknet): Key project constraints (@alkdev/alkgit):
- Rust workspace: crates/alkgit-core, -transport, -http, -ssh, alkgitd
- Rust: use cargo build, cargo clippy, cargo fmt, cargo test - Rust: use cargo build, cargo clippy, cargo fmt, cargo test
- No comments in code - No comments in code
- anyhow::Result for application errors, thiserror for library error types - thiserror for library error types; no panics in library code
- Feature flags for transports (tls, iroh, acme) - Feature flags for optional surface (sha256, acme)
- Async via tokio runtime - Async via tokio runtime
- No panics in library code - gitoxide (gix) for git storage/wire primitives; never shell out to git
``` ```
### Partial Generation Spawning ### Partial Generation Spawning
+35 -56
View File
@@ -207,65 +207,44 @@ This is especially important for complex tasks that span many file operations.
## Project Conventions ## Project Conventions
Read `AGENTS.md` at project root for full details. Key rules: Read `AGENTS.md` at project root for the full authoritative list. Key
rules (summary — AGENTS.md wins on any conflict):
1. **No comments in code** — Per project convention. Doc comments (`///`, `//!`) 1. **No comments in code** — Per project convention. Doc comments (`///`,
are fine and expected on public API. `//!`) are fine and expected on public API.
2. **Error handling** — `thiserror` for library error types. No panics in 2. **Error handling** — `thiserror` for library error types. No panics in
library code. No `unwrap()` or `expect()` outside tests. For poisoned library code. No `unwrap()` or `expect()` outside tests. For poisoned
`RwLock`/`Mutex`, use `unwrap_or_else(|e| e.into_inner())` so a panic in one `RwLock`/`Mutex`, use `unwrap_or_else(|e| e.into_inner())` so a panic in
operation does not cascade to other operations. one operation does not cascade to other operations.
3. **`tokio` is the async runtime** — all I/O is async. Use `tokio::sync` 3. **`tokio` is the async runtime** — all I/O is async. Do not introduce
primitives (`oneshot`, `mpsc`) for request correlation and subscription blocking I/O on the async path. Use `tokio::sync` primitives (`oneshot`,
channels; `parking_lot` for short-held internal locks (`PendingRequestMap`). `mpsc`) for correlation and subscription channels; `parking_lot` for
4. **No secret material on the wire** — `call.requested`/`call.responded` short-held internal locks.
payloads and `OperationContext.metadata` carry no private keys, API keys, or 4. **No secret material on the wire or in plaintext at rest** — outbound
decrypted credentials. Outbound credentials flow through `Capabilities` credentials flow through `Capabilities` injected at the assembly layer;
injected at the assembly layer → `HandlerRegistration.capabilities` → stored credentials live in alkvault, metadata stores hold references.
`OperationContext.capabilities` → handler. 5. **No-env-vars invariant** — no handler reads outbound credentials from
5. **No-env-vars invariant** — no handler reads outbound credentials from any any source other than `OperationContext.capabilities`. This is a
source other than `OperationContext.capabilities`. This is a spec-level spec-level invariant, not a runtime convention.
invariant, not a runtime convention. 6. **Wire formats are stable one-way doors** — once published, an existing
6. **`OperationEnv` must remain a trait** — the trait-based design enables wire format shape must not change (see AGENTS.md and the architecture
registry layering (session overlays, connection overlays, peer-keyed ADRs for the current list per crate).
composition). Do not make it concrete or hardcode the global registry. 7. **Visible-surface = authorized-surface** — use alkcall's model:
7. **Wire formats are stable** — `EventEnvelope` (`{ type, id, payload }` + `AccessControl` on every op; `Visibility::Internal` ops are never
length-prefixed JSON framing) and the channels 8-byte chunk header wire-callable. No unauthenticated endpoints unless a repo is explicitly
(`[channel_id:u32 BE][length:u32 BE][payload]`) are one-way doors. New event public.
types may be added; existing shapes must not change. 8. **gitoxide for git primitives** — storage and pkt-line come from gix
8. **Producer/consumer, not server/client** — both sides of a call or channels crates; never shell out to the `git` binary in the serving path; never
connection can initiate. Use "producer"/"consumer" or "accept side"/"connect copy code from MPL-2.0-licensed reference projects (see
side," not "server"/"client." `docs/research/reference-policy.md`).
9. **Vendored core types** — `Connection`, `ProtocolHandler`, `BiStream`, 9. **Feature flags** — optional surface is feature-gated (`sha256`,
`BidiStreamSource`, `AuthContext`, `IdentityProvider`, `Identity`, `acme`); base crates compile lean. Verify both `cargo test` (default)
`AuthToken`, `Capabilities`, `OwnershipProvider`, `HandlerError`, and `cargo test --all-features` pass if features are added.
`StreamError` live in this crate. Do not add a separate `alkcore` dependency. 10. **Naming conventions** — Rust standard: `snake_case` for
Keep them lean (no TLS, no transport coupling, no endpoint/accept-loop). functions/variables/modules, `PascalCase` for types/traits,
10. **BAST documents for wire formats** — every binary wire format carries a `SCREAMING_SNAKE_CASE` for constants.
BAST (Binary Abstract Syntax Tree) document as its machine-readable spec 11. **Module structure** — one module per file under `src/`, re-exported
(e.g. the channels chunk header's `docs/architecture/chunk-header.bast.json`, from `src/lib.rs`. Public API surface is `lib.rs` re-exports.
embedded as `CHUNK_HEADER_BAST`). BAST is plain JSON — no dependency
required to author or consume it. The `alktype` crate compiles BAST into
readers/writers/validators; future codegen derives language-specific
implementations. Trivial or hot-path formats (chunk header, tty framing)
stay hand-rolled with the BAST doc as the contract; complex formats (sftp)
use the alktype engine or codegen. Do not roll your own offset map or
validator for complex formats.
11. **Feature flags** — transports may be feature-gated if the need arises. The
base crate should compile lean (no `quinn`, no `iroh` unless the feature is
on). Verify both `cargo test` (default) and `cargo test --all-features` pass
if features are added.
12. **Abort cascades to descendants** — `call.aborted` for a parent cascades to
all non-terminal descendants. Default `abort-dependents`;
`continue-running` opt-in. The composing handler decides the child's policy,
not the wire caller.
13. **Peer authorization via `AccessControl`** — a remote peer's call is
authorized by `AccessControl::check(peer_identity)`. No `remote_safe` flag,
no `trusted_peer` bypass. `Visibility::Internal` ops are never wire-callable.
14. **Naming conventions** — Rust standard: `snake_case` for functions/variables/
modules, `PascalCase` for types/traits, `SCREAMING_SNAKE_CASE` for constants.
15. **Module structure** — one module per file under `src/`, re-exported from
`src/lib.rs`. Public API surface is `lib.rs` re-exports.
## Key Principles ## Key Principles
+1 -1
View File
@@ -2,7 +2,7 @@
## Overview ## Overview
This document defines the SDD process for the @alkdev/alkcall package. It This document defines the SDD process for the @alkdev/alkgit project. It
leverages: leverages:
- **OpenCode CLI** as the agent execution environment - **OpenCode CLI** as the agent execution environment