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:
1 parent
a3cdef909b
commit
1df339f4ec
6 files changed
+60
-77
No files matched your search
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
Reference in new issue
Block a user