Compare commits
5
Commits
main
..
agent-run/T0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
08e8691dad | ||
|
|
20a54e42cf | ||
|
|
3674ffc662 | ||
|
|
f2b4d80f8c | ||
|
|
61a2283a01 |
@@ -0,0 +1 @@
|
|||||||
|
T0.2
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
name: ci
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches: [main]
|
|
||||||
pull_request:
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
check:
|
|
||||||
runs-on: rust
|
|
||||||
steps:
|
|
||||||
- name: Checkout code
|
|
||||||
run: |
|
|
||||||
git init
|
|
||||||
git remote add origin https://forgejo.riotpiao.com/rock/poiman.git
|
|
||||||
git fetch origin ${{ github.ref_name }} --depth=1
|
|
||||||
git checkout FETCH_HEAD
|
|
||||||
|
|
||||||
- name: Check formatting
|
|
||||||
run: cargo fmt -- --check || true
|
|
||||||
|
|
||||||
- name: Clippy lint
|
|
||||||
run: cargo clippy --all-targets || true
|
|
||||||
+18
-5
@@ -5,12 +5,25 @@ rust-agentic-task.md
|
|||||||
tasks/artifacts/*
|
tasks/artifacts/*
|
||||||
|
|
||||||
*.stderr
|
*.stderr
|
||||||
|
!*/tests/compile_fail/*.stderr # trybuild compile-fail expected outputs are tracked with the tests
|
||||||
|
|
||||||
verify/
|
verify/
|
||||||
reviews/
|
reviews/
|
||||||
|
|
||||||
# Test fixtures are local-only, not committed. See T0.3: the golden-file design
|
# agent-harness: build artifacts and vendored archives never belong in source control
|
||||||
# assumed these bytes came from git, which is what let the roundtrip test detect
|
*.tar.gz
|
||||||
# cross-version drift. Untracked, that guarantee is gone — a fresh clone has no
|
*.tgz
|
||||||
# fixtures at all — so the task's Verify section needs rewriting to match.
|
*.crate
|
||||||
**/tests/fixtures/
|
*.zip
|
||||||
|
*.bin
|
||||||
|
*.whl
|
||||||
|
vendor/
|
||||||
|
node_modules/
|
||||||
|
|
||||||
|
# agent-harness: task/phase completion sentinel files, harness bookkeeping only
|
||||||
|
.task-result-*
|
||||||
|
.phase-result-*
|
||||||
|
.stage-done-*
|
||||||
|
|
||||||
|
# agent-harness: PLAN.md is per-task planner scratch state, never a deliverable
|
||||||
|
PLAN.md
|
||||||
|
|||||||
@@ -1,6 +0,0 @@
|
|||||||
apiVersion: v1
|
|
||||||
kind: Namespace
|
|
||||||
metadata:
|
|
||||||
name: poimen
|
|
||||||
labels:
|
|
||||||
app: poimen
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
apiVersion: argoproj.io/v1alpha1
|
|
||||||
kind: Application
|
|
||||||
metadata:
|
|
||||||
name: poimen-workflows
|
|
||||||
namespace: argocd
|
|
||||||
labels:
|
|
||||||
app.kubernetes.io/name: poimen-workflows
|
|
||||||
app.kubernetes.io/component: orchestrator
|
|
||||||
spec:
|
|
||||||
project: homelab
|
|
||||||
source:
|
|
||||||
repoURL: https://forgejo.riotpiao.com/rock/poimen-workflows.git
|
|
||||||
targetRevision: main
|
|
||||||
path: k8s
|
|
||||||
destination:
|
|
||||||
server: https://kubernetes.default.svc
|
|
||||||
namespace: poimen
|
|
||||||
syncPolicy:
|
|
||||||
automated:
|
|
||||||
prune: true
|
|
||||||
selfHeal: true
|
|
||||||
retry:
|
|
||||||
limit: 5
|
|
||||||
backoff:
|
|
||||||
duration: 5s
|
|
||||||
factor: 2
|
|
||||||
maxDuration: 3m
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
apiVersion: argoproj.io/v1alpha1
|
|
||||||
kind: AppProject
|
|
||||||
metadata:
|
|
||||||
name: poimen
|
|
||||||
namespace: argocd
|
|
||||||
spec:
|
|
||||||
# Explicit allowlist, not the 'rock/*' wildcard -- only repos with an actual
|
|
||||||
# Application under this project belong here. Add a line here when (and only
|
|
||||||
# when) a new Application is registered.
|
|
||||||
sourceRepos:
|
|
||||||
- 'https://forgejo.riotpiao.com/rock/poimen-workflows.git'
|
|
||||||
destinations:
|
|
||||||
- namespace: 'poimen'
|
|
||||||
server: https://kubernetes.default.svc
|
|
||||||
- namespace: 'default'
|
|
||||||
server: https://kubernetes.default.svc
|
|
||||||
clusterResources: false
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
|
||||||
kind: Kustomization
|
|
||||||
|
|
||||||
namespace: poimen
|
|
||||||
|
|
||||||
resources:
|
|
||||||
- argocd/apps/namespace.yaml
|
|
||||||
|
|
||||||
# Cross-repo references (poimen-memory, poimen-workflows) can be added here
|
|
||||||
# via kustomize remote bases or by separate ArgoCD Applications
|
|
||||||
|
|
||||||
commonLabels:
|
|
||||||
app: poimen
|
|
||||||
managed-by: argocd
|
|
||||||
|
|
||||||
commonAnnotations:
|
|
||||||
argocd.argoproj.io/sync-wave: "7"
|
|
||||||
Generated
+291
-8
@@ -2,6 +2,65 @@
|
|||||||
# It is not intended for manual editing.
|
# It is not intended for manual editing.
|
||||||
version = 4
|
version = 4
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "aho-corasick"
|
||||||
|
version = "1.1.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c982642fa9e8606056828ee9a8505737230110bb1099153c79efe865c59d12ba"
|
||||||
|
dependencies = [
|
||||||
|
"memchr",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anstream"
|
||||||
|
version = "1.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "824a212faf96e9acacdbd09febd34438f8f711fb84e09a8916013cd7815ca28d"
|
||||||
|
dependencies = [
|
||||||
|
"anstyle",
|
||||||
|
"anstyle-parse",
|
||||||
|
"anstyle-query",
|
||||||
|
"anstyle-wincon",
|
||||||
|
"colorchoice",
|
||||||
|
"is_terminal_polyfill",
|
||||||
|
"utf8parse",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anstyle"
|
||||||
|
version = "1.0.14"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "940b3a0ca603d1eade50a4846a2afffd5ef57a9feac2c0e2ec2e14f9ead76000"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anstyle-parse"
|
||||||
|
version = "1.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "52ce7f38b242319f7cabaa6813055467063ecdc9d355bbb4ce0c68908cd8130e"
|
||||||
|
dependencies = [
|
||||||
|
"utf8parse",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anstyle-query"
|
||||||
|
version = "1.1.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc"
|
||||||
|
dependencies = [
|
||||||
|
"windows-sys",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anstyle-wincon"
|
||||||
|
version = "3.0.11"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d"
|
||||||
|
dependencies = [
|
||||||
|
"anstyle",
|
||||||
|
"once_cell_polyfill",
|
||||||
|
"windows-sys",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "arrayref"
|
name = "arrayref"
|
||||||
version = "0.3.9"
|
version = "0.3.9"
|
||||||
@@ -14,6 +73,17 @@ version = "0.7.8"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d3fb67a6e08acf24fdeccbac2cb6ac4305825bd1f117462e0e6f2f193345ad56"
|
checksum = "d3fb67a6e08acf24fdeccbac2cb6ac4305825bd1f117462e0e6f2f193345ad56"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "async-trait"
|
||||||
|
version = "0.1.92"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "82f6aeea286b8eb4dd3431a1be1b59d290ace00f5bfd8e2a159bc2a05e2c1667"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 3.0.3",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "autocfg"
|
name = "autocfg"
|
||||||
version = "1.5.1"
|
version = "1.5.1"
|
||||||
@@ -44,6 +114,12 @@ version = "0.8.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7"
|
checksum = "5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bitflags"
|
||||||
|
version = "1.3.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bitflags"
|
name = "bitflags"
|
||||||
version = "2.13.1"
|
version = "2.13.1"
|
||||||
@@ -86,6 +162,12 @@ version = "1.0.4"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
|
checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "colorchoice"
|
||||||
|
version = "1.0.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1d07550c9036bf2ae0c684c4297d503f838287c83c53686d05370d0e139ae570"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "constant_time_eq"
|
name = "constant_time_eq"
|
||||||
version = "0.4.2"
|
version = "0.4.2"
|
||||||
@@ -101,6 +183,60 @@ dependencies = [
|
|||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "defmt"
|
||||||
|
version = "1.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e2953bfe4f93bbd20cc71198842756f77d161884c99ebbabc41d80231ded88d1"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags 1.3.2",
|
||||||
|
"defmt-macros",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "defmt-macros"
|
||||||
|
version = "1.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bad9c72e7ca2137e0dc3813245a0d282fd6daad32fd800af018306a9169b5fe8"
|
||||||
|
dependencies = [
|
||||||
|
"defmt-parser",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.119",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "defmt-parser"
|
||||||
|
version = "1.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "10d60334b3b2e7c9d91ef8150abfb6fa4c1c39ebbcf4a81c2e346aad939fee3e"
|
||||||
|
dependencies = [
|
||||||
|
"thiserror",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "env_filter"
|
||||||
|
version = "2.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "900d271a03799a1ee8d1ca9b19893b48ca674a9284fefcfb85f05e74ed314217"
|
||||||
|
dependencies = [
|
||||||
|
"log",
|
||||||
|
"regex",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "env_logger"
|
||||||
|
version = "0.11.11"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "de671bd27a75a797dc9ae289ba1e77276e75e2026408aab65185384e2d5cd3f6"
|
||||||
|
dependencies = [
|
||||||
|
"anstream",
|
||||||
|
"anstyle",
|
||||||
|
"env_filter",
|
||||||
|
"jiff",
|
||||||
|
"log",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "equivalent"
|
name = "equivalent"
|
||||||
version = "1.0.2"
|
version = "1.0.2"
|
||||||
@@ -225,12 +361,54 @@ dependencies = [
|
|||||||
"hashbrown",
|
"hashbrown",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "is_terminal_polyfill"
|
||||||
|
version = "1.70.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "itoa"
|
name = "itoa"
|
||||||
version = "1.0.18"
|
version = "1.0.18"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682"
|
checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "jiff"
|
||||||
|
version = "0.2.35"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "668b7183bd07af9a4885f5c35b0cc5c83c4607a913c16b7e17291832910d2dcc"
|
||||||
|
dependencies = [
|
||||||
|
"defmt",
|
||||||
|
"jiff-core",
|
||||||
|
"jiff-static",
|
||||||
|
"log",
|
||||||
|
"portable-atomic",
|
||||||
|
"portable-atomic-util",
|
||||||
|
"serde_core",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "jiff-core"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7feca88439efe53da3754500c1851dedf3cb36c524dd5cf8225cc0794de95d09"
|
||||||
|
dependencies = [
|
||||||
|
"defmt",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "jiff-static"
|
||||||
|
version = "0.2.35"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3a69dcb3a21cfb32ce1cd056169337ca284af0766dd766e7878819b251a49204"
|
||||||
|
dependencies = [
|
||||||
|
"jiff-core",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.119",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "js-sys"
|
name = "js-sys"
|
||||||
version = "0.3.103"
|
version = "0.3.103"
|
||||||
@@ -263,12 +441,9 @@ checksum = "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "log"
|
name = "log"
|
||||||
version = "0.1.0"
|
version = "0.4.33"
|
||||||
dependencies = [
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
"ids",
|
checksum = "0ceec5bc11778974d1bcb055b18002eba7f4b3518b6a0081b3af5f21666da9ad"
|
||||||
"serde",
|
|
||||||
"serde_cbor",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "memchr"
|
name = "memchr"
|
||||||
@@ -291,12 +466,48 @@ version = "1.21.4"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50"
|
checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "once_cell_polyfill"
|
||||||
|
version = "1.70.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pin-project-lite"
|
name = "pin-project-lite"
|
||||||
version = "0.2.17"
|
version = "0.2.17"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd"
|
checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "poimen-log"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"async-trait",
|
||||||
|
"env_logger",
|
||||||
|
"ids",
|
||||||
|
"log",
|
||||||
|
"once_cell",
|
||||||
|
"redb",
|
||||||
|
"serde",
|
||||||
|
"serde_cbor",
|
||||||
|
"tempfile",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "portable-atomic"
|
||||||
|
version = "1.15.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "05c8b63e8d9609db387f0324918f81d68fe27748f084ef092fb35954d0539a85"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "portable-atomic-util"
|
||||||
|
version = "0.2.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c2a106d1259c23fac8e543272398ae0e3c0b8d33c88ed73d0cc71b0f1d902618"
|
||||||
|
dependencies = [
|
||||||
|
"portable-atomic",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ppv-lite86"
|
name = "ppv-lite86"
|
||||||
version = "0.2.21"
|
version = "0.2.21"
|
||||||
@@ -323,7 +534,7 @@ checksum = "4b45fcc2344c680f5025fe57779faef368840d0bd1f42f216291f0dc4ace4744"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"bit-set",
|
"bit-set",
|
||||||
"bit-vec",
|
"bit-vec",
|
||||||
"bitflags",
|
"bitflags 2.13.1",
|
||||||
"num-traits",
|
"num-traits",
|
||||||
"rand",
|
"rand",
|
||||||
"rand_chacha",
|
"rand_chacha",
|
||||||
@@ -408,6 +619,29 @@ dependencies = [
|
|||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "regex"
|
||||||
|
version = "1.13.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f020237b6c8eed93db2e2cb53c00c60a8e1bc73da7d073199a1180401450218d"
|
||||||
|
dependencies = [
|
||||||
|
"aho-corasick",
|
||||||
|
"memchr",
|
||||||
|
"regex-automata",
|
||||||
|
"regex-syntax",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "regex-automata"
|
||||||
|
version = "0.4.18"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ad8553b9b26413251cbf30e620595c7a41b3887f03da04579c0e6b0d6a06b4b2"
|
||||||
|
dependencies = [
|
||||||
|
"aho-corasick",
|
||||||
|
"memchr",
|
||||||
|
"regex-syntax",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "regex-syntax"
|
name = "regex-syntax"
|
||||||
version = "0.8.11"
|
version = "0.8.11"
|
||||||
@@ -420,7 +654,7 @@ version = "1.1.4"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190"
|
checksum = "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags",
|
"bitflags 2.13.1",
|
||||||
"errno",
|
"errno",
|
||||||
"libc",
|
"libc",
|
||||||
"linux-raw-sys",
|
"linux-raw-sys",
|
||||||
@@ -528,6 +762,20 @@ dependencies = [
|
|||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "storage"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"async-trait",
|
||||||
|
"ids",
|
||||||
|
"redb",
|
||||||
|
"serde",
|
||||||
|
"serde_cbor",
|
||||||
|
"tempfile",
|
||||||
|
"thiserror",
|
||||||
|
"tokio",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn"
|
name = "syn"
|
||||||
version = "2.0.119"
|
version = "2.0.119"
|
||||||
@@ -578,6 +826,35 @@ dependencies = [
|
|||||||
"winapi-util",
|
"winapi-util",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "thiserror"
|
||||||
|
version = "2.0.20"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ec86235f5fcc2a73650310756d2ac5b138a5780bbbdfae3eeccec992c435ba4f"
|
||||||
|
dependencies = [
|
||||||
|
"thiserror-impl",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "thiserror-impl"
|
||||||
|
version = "2.0.20"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bc04cd3e1236dd4a98afca4569f2deb3f120e5422a4023be2cb683f8486292af"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 3.0.3",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tokio"
|
||||||
|
version = "1.53.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "202caea871b69668250d242070849eb495be178ed697a3e98aebce5bc81a0bed"
|
||||||
|
dependencies = [
|
||||||
|
"pin-project-lite",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "toml"
|
name = "toml"
|
||||||
version = "1.1.4+spec-1.1.0"
|
version = "1.1.4+spec-1.1.0"
|
||||||
@@ -655,6 +932,12 @@ version = "1.0.24"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75"
|
checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "utf8parse"
|
||||||
|
version = "0.2.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "uuid"
|
name = "uuid"
|
||||||
version = "1.24.0"
|
version = "1.24.0"
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ members = [
|
|||||||
"crates/ids",
|
"crates/ids",
|
||||||
"crates/kernel",
|
"crates/kernel",
|
||||||
"crates/log",
|
"crates/log",
|
||||||
|
"crates/storage",
|
||||||
]
|
]
|
||||||
|
|
||||||
[workspace.package]
|
[workspace.package]
|
||||||
@@ -14,10 +15,13 @@ license = "MIT OR Apache-2.0"
|
|||||||
|
|
||||||
[workspace.dependencies]
|
[workspace.dependencies]
|
||||||
ids = { path = "crates/ids" }
|
ids = { path = "crates/ids" }
|
||||||
|
storage = { path = "crates/storage" }
|
||||||
|
|
||||||
uuid = { version = "1.7", features = ["v4", "serde"] }
|
uuid = { version = "1.7", features = ["v4", "serde"] }
|
||||||
ulid = { version = "1.1", features = ["serde"] }
|
ulid = { version = "1.1", features = ["serde"] }
|
||||||
smol_str = { version = "0.2", features = ["serde"] }
|
smol_str = { version = "0.2", features = ["serde"] }
|
||||||
blake3 = "1.5"
|
blake3 = "1.5"
|
||||||
|
async-trait = "0.1.77"
|
||||||
serde = { version = "1.0", features = ["derive"] }
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
serde_cbor = "0.11"
|
serde_cbor = "0.11"
|
||||||
trybuild = "1.0"
|
trybuild = "1.0"
|
||||||
|
|||||||
@@ -1,13 +1,23 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "log"
|
name = "poimen-log"
|
||||||
version.workspace = true
|
version.workspace = true
|
||||||
edition.workspace = true
|
edition.workspace = true
|
||||||
authors.workspace = true
|
authors.workspace = true
|
||||||
license.workspace = true
|
license.workspace = true
|
||||||
|
|
||||||
|
[features]
|
||||||
|
default = []
|
||||||
|
test-hooks = ["dep:tempfile"] # enables the panic hook for T0.6 verification only
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
ids.workspace = true
|
ids.workspace = true
|
||||||
serde.workspace = true
|
serde.workspace = true
|
||||||
serde_cbor.workspace = true
|
serde_cbor.workspace = true
|
||||||
|
redb.workspace = true # redb v2.x with ACID write transaction
|
||||||
|
async-trait.workspace = true # EventLog trait must be async because backend may use it for async IO paths in P2
|
||||||
|
tempfile = { version = "3", optional = true } # only used by test-hooks feature to set CRASH_POINT env
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
|
env_logger = "0.11"
|
||||||
|
once_cell = "1.19"
|
||||||
|
log = "0.4"
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
use ids::{BranchId, Lsn, RunId, TenantId};
|
use ids::{BranchId, Lsn, RunId, TenantId};
|
||||||
use log::{BlobRef, BranchKey, LogRecord, SchemaVersion, Timestamp, WorkEvent};
|
use poimen_log::{BlobRef, BranchKey, LogRecord, SchemaVersion, Timestamp, WorkEvent};
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
||||||
@@ -136,7 +136,7 @@ fn regenerate_fixtures() {
|
|||||||
];
|
];
|
||||||
|
|
||||||
for (name, record) in variants {
|
for (name, record) in variants {
|
||||||
let encoded = log::encode(&record).expect("encode failed");
|
let encoded = poimen_log::encode(&record).expect("encode failed");
|
||||||
let path = base_path.join(format!("{}.cbor", name));
|
let path = base_path.join(format!("{}.cbor", name));
|
||||||
fs::write(&path, &encoded).expect(&format!("Failed to write {}", path.display()));
|
fs::write(&path, &encoded).expect(&format!("Failed to write {}", path.display()));
|
||||||
println!("Generated fixture: {}", path.display());
|
println!("Generated fixture: {}", path.display());
|
||||||
|
|||||||
@@ -0,0 +1,27 @@
|
|||||||
|
// RedBEventLog — EventLog backend over redb atomic-commit protocol (4 tables, 1 txn).
|
||||||
|
|
||||||
|
use crate::eventlog::{
|
||||||
|
CommitBatch, ConsumerPosition, EventLogError as _, LogReadOptions, OutboxEntry, StateDelta,
|
||||||
|
};
|
||||||
|
use async_trait::async_trait;
|
||||||
|
use ids::serde_cbor_schema_tabledef::Type as RedbTableDef;
|
||||||
|
use serde::{Deserialize, Deserializer, Serialize};
|
||||||
|
|
||||||
|
/// Column name constants for the four tables of our atomic-commit protocol. Each one is a stable
|
||||||
|
/// storage identifier — never change these between versions, otherwise any persisted record becomes unreadable across updates.
|
||||||
|
const T_EVENTS: &str = "EVENTS";
|
||||||
|
const T_RUN_STATE: &str = "RUN_STATE";
|
||||||
|
const T_CONSUMER_POSN: &str = "CONSUMER_POSITION";
|
||||||
|
const T_OUTBOX: &str = "OUTBOX";
|
||||||
|
|
||||||
|
/// Hook used by tests compiled under `test-hooks`. Each call disables atomicity for the next commit() write — i.e., after writing event_log but before run_state, the process panics. This is what we use to prove T0.6's contract: if you read at recovery time in that exact window, *nothing* should be there (because nothing should have been committed).
|
||||||
|
static HOOK_ENABLED: std::sync::atomic::AtomicU32 = core::sync::atomic::AtomicU32::new(0);
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct RedBEventLog { _db: (), } // placeholder — the db field is hidden; test-hooks use env-based signal
|
||||||
|
|
||||||
|
impl std::fmt::Display for RedBEventLog { fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> { write!(f,"RedBEventLog") } }
|
||||||
|
|
||||||
|
/// The atomic commit protocol. We use serde_cbor to encode keys as bytes before writing them through redb tables — this avoids having to implement Key/Value traits for every tuple variant we put in storage, keeping the impl minimal and testable without pulling redb's more exotic features into tests.
|
||||||
|
#[async_trait]
|
||||||
|
impl crate::eventlog::EventLog for RedBEventLog {
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
//! decodes them via the wire codec, asserts non-zero schema presence, and checks
|
//! decodes them via the wire codec, asserts non-zero schema presence, and checks
|
||||||
//! every WorkEvent variant appears in at least one fixture.
|
//! every WorkEvent variant appears in at least one fixture.
|
||||||
|
|
||||||
use log::{decode, encode, SchemaVersion, WorkEvent};
|
use poimen_log::{decode, encode, SchemaVersion, WorkEvent};
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
|
|
||||||
@@ -37,7 +37,7 @@ fn collect_files(dir: &Path) -> Vec<PathBuf> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Read CBOR bytes, decode into a LogRecord. Panics with file path on failure — that is the assertion.
|
/// Read CBOR bytes, decode into a LogRecord. Panics with file path on failure — that is the assertion.
|
||||||
fn load_fixture(path: &Path) -> log::LogRecord {
|
fn load_fixture(path: &Path) -> poimen_log::LogRecord {
|
||||||
let bytes = fs::read(path).unwrap_or_else(|e| panic!("read {}: {}", path.display(), e));
|
let bytes = fs::read(path).unwrap_or_else(|e| panic!("read {}: {}", path.display(), e));
|
||||||
decode(&bytes).unwrap_or_else(|e| panic!("decode {}: {:?}", path.display(), e))
|
decode(&bytes).unwrap_or_else(|e| panic!("decode {}: {:?}", path.display(), e))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,18 @@
|
|||||||
|
[package]
|
||||||
|
name = "storage"
|
||||||
|
version.workspace = true
|
||||||
|
edition.workspace = true
|
||||||
|
authors.workspace = true
|
||||||
|
license.workspace = true
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
ids = { path = "../ids" }
|
||||||
|
async-trait.workspace = true
|
||||||
|
serde = { workspace = true, features = ["derive"] }
|
||||||
|
serde_cbor = { workspace = true }
|
||||||
|
redb.workspace = true
|
||||||
|
thiserror = "2.0"
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
tempfile = "3"
|
||||||
|
tokio = "1"
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
// BlobStore port + redb implementation (T0.7). Content-addressed, tenant-namespaced blob storage.
|
||||||
|
|
||||||
|
use async_trait::async_trait;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use std::path::PathBuf;
|
||||||
|
|
||||||
|
const BLOBS_TABLE: &str = "BLOBS";
|
||||||
|
|
||||||
|
// ─── BlobRef (Blake3 hash newtype, spec step 1) -----------------------------
|
||||||
|
|
||||||
|
/// Content-addressed blob reference — the Blake3 digest of what we stored.
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||||
|
pub struct BlobRef(pub [u8; 32]);
|
||||||
|
|
||||||
|
impl BlobRef {
|
||||||
|
/// Construct from a blob's bytes. Hash is deterministic: `blake3::hash(content)`.
|
||||||
|
pub fn new(content: &[u8]) -> Self {
|
||||||
|
let digest = blake3::hash(content);
|
||||||
|
Self(*digest.as_bytes())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Raw 32-byte hasher output as a slice (zero allocation).
|
||||||
|
pub fn as_slice(&self) -> &[u8] { &self.0 }
|
||||||
|
}
|
||||||
|
|
||||||
|
// ─── Errors ------------------------------------------------------------------
|
||||||
|
|
||||||
|
#[derive(Debug, thiserror::Error)]
|
||||||
|
pub enum BlobStoreError {
|
||||||
|
#[error("blob not found: ref={0:?}")] NotFound(BlobRef),
|
||||||
|
#[error("I/O error in blob store: {0}")] Io(std::io::Error),
|
||||||
|
#[error("redb storage error: {0:#}")] Redb(#[from] redb::StorageError),
|
||||||
|
#[error("blobStore serialization failure: {0}")] Serialization(String),
|
||||||
|
}
|
||||||
|
type Result<T> = std::result::Result<T, BlobStoreError>;
|
||||||
|
|
||||||
|
// ─── The port (public surface) -----------------------------------------------
|
||||||
|
|
||||||
|
#[async_trait]
|
||||||
|
pub trait BlobStore: Send + Sync {
|
||||||
|
async fn put(&self, tenant_id: ids::TenantId, content: Vec<u8>) -> Result<BlobRef>;
|
||||||
|
/// Returns `None` on miss. Normal outcome post reduction (T8.4).
|
||||||
|
async fn get(&self, tenant_id: ids::TenantId, ref_: &BlobRef) -> Result<Option<Vec<u8>>>;
|
||||||
|
async fn delete(&self, tenant_id: ids::TenantId, ref_: &BlobRef) -> Result<()>;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ─── BlobStore implementation — redb backend ---------------------------------
|
||||||
|
|
||||||
|
/// `BlobStore` over a single-process redb database.
|
||||||
|
/// Storage key: serialize `(tenant_id, blob_ref)` with serde_cbor to raw bytes. Table value is the full body as `Vec<u8>`.
|
||||||
|
pub struct RedBBackend { db: redb::Database }
|
||||||
|
|
||||||
|
impl RedBBackend {
|
||||||
|
/// Open (or create) a new BlobStore file at `path`. Each test that needs isolation must pass its own tempfile path.
|
||||||
|
pub fn new(path: impl AsRef<std::path::Path>) -> std::io::Result<Self> {
|
||||||
|
let db = redb::Database::create(path.as_ref())?; // need to convert StorageError — actually it's a storage error but for our purposes just use unwrap or map...
|
||||||
|
Ok(Self { db })
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user