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:
- 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")
- 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
(e.g., "need performance benchmarks to choose between X and Y")
- 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).
2. **State the blocking condition** (`deferred(scope)`) or
**investigation target** (`deferred(unclear)`) — what specific thing
would unblock this? Be concrete: "blocked on: alknet-agent crate spec
exists" or "investigation: work through 2+ example outbound-dial use
cases (hub→worker, worker→hub) to see how verifier-selection +
provider + connector compose."
would unblock this? Be concrete: "blocked on: alkgit-admin crate spec
exists" or "investigation: work through 2+ example git-over-ssh use
cases (clone and push) to see how identity + repo resolution +
pkt-line session compose."
3. **State the impacts** — what does this block downstream? Be
specific: "blocks the first hub deployment because the hub dials
workers" not "blocks the hub crate." This is the triage signal that
specific: "blocks the http endpoint because receive-pack needs
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,
the deferral needs to be addressed soon; if it's a future feature,
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
deferral's urgency is invisible and triage is guesswork.
- Is it specific? "Blocks the first hub deployment because the hub
dials workers" is useful. "Blocks the hub crate" is boilerplate.
- Is it specific? "Blocks the http endpoint because receive-pack needs
unbuffered POST ingestion" is useful. "Blocks the http crate" is
boilerplate.
- Does it match the priority? A `deferred(unclear)` with high priority
but a vague impacts field ("blocks future features") is a mismatch —
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:
- No comments in code (per project convention)
- Error handling uses `anyhow::Result` (application) / `thiserror` (library) — no
panics in library code
- Feature flags are used correctly (`tls`, `iroh`, `acme`) — base crate compiles
lean
- Error handling uses `thiserror` for library error types — no panics in
library code, no `unwrap()`/`expect()` outside tests
- Feature flags are used correctly (`sha256`, `acme`) — base crates compile
lean; default features stay minimal
- Public API is well-documented with `///` doc comments where appropriate
- Module structure follows Rust conventions (`mod.rs`, `lib.rs`)
- 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
3. **Key references** — Which source files and architecture docs to read
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
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}}
@@ -204,13 +205,14 @@ Your task: {{task}}
7. Push: git push origin $(git branch --show-current)
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
- No comments in code
- anyhow::Result for application errors, thiserror for library error types
- Feature flags for transports (tls, iroh, acme)
- thiserror for library error types; no panics in library code
- Feature flags for optional surface (sha256, acme)
- Async via tokio runtime
- No panics in library code
- gitoxide (gix) for git storage/wire primitives; never shell out to git
```
### 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
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 (`///`, `//!`)
are fine and expected on public API.
1. **No comments in code** — Per project convention. Doc comments (`///`,
`//!`) are fine and expected on public API.
2. **Error handling** — `thiserror` for library error types. No panics in
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
operation does not cascade to other operations.
3. **`tokio` is the async runtime** — all I/O is async. Use `tokio::sync`
primitives (`oneshot`, `mpsc`) for request correlation and subscription
channels; `parking_lot` for short-held internal locks (`PendingRequestMap`).
4. **No secret material on the wire** — `call.requested`/`call.responded`
payloads and `OperationContext.metadata` carry no private keys, API keys, or
decrypted credentials. Outbound credentials flow through `Capabilities`
injected at the assembly layer → `HandlerRegistration.capabilities` →
`OperationContext.capabilities` → handler.
5. **No-env-vars invariant** — no handler reads outbound credentials from any
source other than `OperationContext.capabilities`. This is a spec-level
invariant, not a runtime convention.
6. **`OperationEnv` must remain a trait** — the trait-based design enables
registry layering (session overlays, connection overlays, peer-keyed
composition). Do not make it concrete or hardcode the global registry.
7. **Wire formats are stable** — `EventEnvelope` (`{ type, id, payload }` +
length-prefixed JSON framing) and the channels 8-byte chunk header
(`[channel_id:u32 BE][length:u32 BE][payload]`) are one-way doors. New event
types may be added; existing shapes must not change.
8. **Producer/consumer, not server/client** — both sides of a call or channels
connection can initiate. Use "producer"/"consumer" or "accept side"/"connect
side," not "server"/"client."
9. **Vendored core types** — `Connection`, `ProtocolHandler`, `BiStream`,
`BidiStreamSource`, `AuthContext`, `IdentityProvider`, `Identity`,
`AuthToken`, `Capabilities`, `OwnershipProvider`, `HandlerError`,
`StreamError` live in this crate. Do not add a separate `alkcore` dependency.
Keep them lean (no TLS, no transport coupling, no endpoint/accept-loop).
10. **BAST documents for wire formats** — every binary wire format carries a
BAST (Binary Abstract Syntax Tree) document as its machine-readable spec
(e.g. the channels chunk header's `docs/architecture/chunk-header.bast.json`,
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.
`RwLock`/`Mutex`, use `unwrap_or_else(|e| e.into_inner())` so a panic in
one operation does not cascade to other operations.
3. **`tokio` is the async runtime** — all I/O is async. Do not introduce
blocking I/O on the async path. Use `tokio::sync` primitives (`oneshot`,
`mpsc`) for correlation and subscription channels; `parking_lot` for
short-held internal locks.
4. **No secret material on the wire or in plaintext at rest** — outbound
credentials flow through `Capabilities` injected at the assembly layer;
stored credentials live in alkvault, metadata stores hold references.
5. **No-env-vars invariant** — no handler reads outbound credentials from
any source other than `OperationContext.capabilities`. This is a
spec-level invariant, not a runtime convention.
6. **Wire formats are stable one-way doors** — once published, an existing
wire format shape must not change (see AGENTS.md and the architecture
ADRs for the current list per crate).
7. **Visible-surface = authorized-surface** — use alkcall's model:
`AccessControl` on every op; `Visibility::Internal` ops are never
wire-callable. No unauthenticated endpoints unless a repo is explicitly
public.
8. **gitoxide for git primitives** — storage and pkt-line come from gix
crates; never shell out to the `git` binary in the serving path; never
copy code from MPL-2.0-licensed reference projects (see
`docs/research/reference-policy.md`).
9. **Feature flags** — optional surface is feature-gated (`sha256`,
`acme`); base crates compile lean. Verify both `cargo test` (default)
and `cargo test --all-features` pass if features are added.
10. **Naming conventions** — Rust standard: `snake_case` for
functions/variables/modules, `PascalCase` for types/traits,
`SCREAMING_SNAKE_CASE` for constants.
11. **Module structure** — one module per file under `src/`, re-exported
from `src/lib.rs`. Public API surface is `lib.rs` re-exports.
## Key Principles
+1 -1
View File
@@ -2,7 +2,7 @@
## 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:
- **OpenCode CLI** as the agent execution environment