Compare commits
24
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ec49706952 | ||
|
|
1f22669ac6 | ||
|
|
342026a3d9 | ||
|
|
34c1ad697f | ||
|
|
d3261bc8c4 | ||
|
|
655ef61fc5 | ||
|
|
e9d10113aa | ||
|
|
39809dcec8 | ||
|
|
37b9e183d9 | ||
|
|
8587b4ad00 | ||
|
|
c8ea130ff6 | ||
|
|
c55714d892 | ||
|
|
a4be009e3e | ||
|
|
3698ab3c73 | ||
|
|
bf32afc217 | ||
|
|
92c1be9780 | ||
|
|
96751f9fcd | ||
|
|
c7320d2811 | ||
|
|
5aea83749d | ||
|
|
72cca8a3b0 | ||
|
|
8232ed7987 | ||
|
|
bda53f299a | ||
|
|
7aa789d1cf | ||
|
|
1d477a4c6e |
@@ -54,7 +54,11 @@
|
||||
cache 30
|
||||
loop
|
||||
reload
|
||||
loadbalance
|
||||
import /etc/coredns/custom/*.override
|
||||
import /etc/coredns/custom/*.server
|
||||
forward . {{ pihole_ips | map('regex_replace', '^(.*)$', '\1:53') | join(' ') }}
|
||||
}
|
||||
# Les fichiers *.server contiennent des BLOCS SERVEUR complets (ex: `arcodange.lab:53 {…}`) :
|
||||
# leur import doit vivre au niveau racine du Corefile. À l'intérieur de `.:53 {}`,
|
||||
# CoreDNS crashe au parse (« Unknown directive 'arcodange.lab:53' ») — vécu le 2026-07-24.
|
||||
import /etc/coredns/custom/*.server
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIBwDCCAWagAwIBAgIRAJzOnXbHdqAB0QnEjNw21xgwCgYIKoZIzj0EAwIwPjEZ
|
||||
MBcGA1UEChMQQXJjb2RhbmdlIExhYiBDQTEhMB8GA1UEAxMYQXJjb2RhbmdlIExh
|
||||
YiBDQSBSb290IENBMB4XDTI1MTIyOTA5Mjk0NVoXDTM1MTIyNzA5Mjk0NVowPjEZ
|
||||
MBcGA1UEChMQQXJjb2RhbmdlIExhYiBDQTEhMB8GA1UEAxMYQXJjb2RhbmdlIExh
|
||||
YiBDQSBSb290IENBMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAERTF3M6MtqK4m
|
||||
q4e38e1KzHP7TRrf/DwEwxyafyp9iONE6na0+dgPvXPurG0kmom9PIYA2aE2eCzz
|
||||
hFkQ2DO1TqNFMEMwDgYDVR0PAQH/BAQDAgEGMBIGA1UdEwEB/wQIMAYBAf8CAQEw
|
||||
HQYDVR0OBBYEFJCxc6tumAlVAaUjoKExPcNZsVoYMAoGCCqGSM49BAMCA0gAMEUC
|
||||
IGtrew3FOPh16x3XevWCO8suH7laCn8kTV2ZZpAK0UkhAiEA/bA7HiDqEaXHSc35
|
||||
b7fZX1fuKI6SdEWN9hj5EwP45Z8=
|
||||
-----END CERTIFICATE-----
|
||||
@@ -1,5 +1,8 @@
|
||||
{{- range $app_name, $app_attr := .Values.gitea_applications -}}
|
||||
{{- $org := default "arcodange-org" $app_attr.org -}}
|
||||
{{- /* Namespace defaults to the app name; override lets siblings share one
|
||||
(e.g. kadans-jobs deploys into the `kadans` namespace). */ -}}
|
||||
{{- $ns := default $app_name $app_attr.namespace -}}
|
||||
---
|
||||
apiVersion: argoproj.io/v1alpha1
|
||||
kind: Application
|
||||
@@ -20,7 +23,7 @@ spec:
|
||||
path: chart
|
||||
destination:
|
||||
server: https://kubernetes.default.svc
|
||||
namespace: {{ $app_name }}
|
||||
namespace: {{ $ns }}
|
||||
syncPolicy:
|
||||
{{- if $app_attr.syncPolicy }}
|
||||
{{- toYaml $app_attr.syncPolicy | nindent 4 }}
|
||||
@@ -74,4 +77,4 @@ spec:
|
||||
syncOptions:
|
||||
- CreateNamespace=true
|
||||
{{- end }}
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
|
||||
@@ -10,5 +10,4 @@ spec:
|
||||
targetNamespace: argocd
|
||||
valuesContent: |-
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end -}}
|
||||
---
|
||||
{{- end }}
|
||||
@@ -0,0 +1,19 @@
|
||||
{{- /*
|
||||
The lab's root CA, as a ConfigMap the image-updater pod can mount.
|
||||
|
||||
Nodes trust it through the OS store (/usr/local/share/ca-certificates), which
|
||||
is why kubelet pulls images fine — but a container carries its own trust store,
|
||||
so argocd-image-updater failed every registry query with
|
||||
"x509: certificate signed by unknown authority" and updated nothing.
|
||||
|
||||
A root CA certificate is public material (no private key here), so it lives in
|
||||
git next to the chart that consumes it.
|
||||
*/ -}}
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: homelab-ca
|
||||
namespace: argocd
|
||||
data:
|
||||
arcodange-root.crt: |
|
||||
{{ .Files.Get "files/arcodange-root.crt" | indent 4 }}
|
||||
@@ -0,0 +1,22 @@
|
||||
{{- /*
|
||||
argocd-image-updater v1+ ships a CRD-based controller: it no longer scans
|
||||
Application annotations on its own and idles with "No ImageUpdater CRs to
|
||||
process" — which silently froze image rollouts for the WHOLE fleet (kadans,
|
||||
webapp, cms, dance-lessons-coach, prospection, telegram-gateway) after the
|
||||
un-pinned HelmChart pulled the new major.
|
||||
|
||||
This single CR restores the previous behaviour: select every Application in
|
||||
the argocd namespace and read the existing
|
||||
`argocd-image-updater.argoproj.io/*` annotations (useAnnotations mode). Apps
|
||||
without annotations are simply ignored — no per-app CR to maintain, the
|
||||
annotations in values.yaml stay the one source of truth.
|
||||
*/ -}}
|
||||
apiVersion: argocd-image-updater.argoproj.io/v1alpha1
|
||||
kind: ImageUpdater
|
||||
metadata:
|
||||
name: annotated-applications
|
||||
namespace: argocd
|
||||
spec:
|
||||
applicationRefs:
|
||||
- namePattern: "*"
|
||||
useAnnotations: true
|
||||
+25
-2
@@ -40,9 +40,17 @@ gitea_applications:
|
||||
argocd-image-updater.argoproj.io/image-list: prospection=gitea.arcodange.lab/arcodange-org/prospection:latest
|
||||
argocd-image-updater.argoproj.io/prospection.update-strategy: digest
|
||||
kadans:
|
||||
org: arcodange
|
||||
annotations:
|
||||
argocd-image-updater.argoproj.io/image-list: kadans=gitea.arcodange.lab/arcodange-org/kadans:latest
|
||||
argocd-image-updater.argoproj.io/image-list: kadans=gitea.arcodange.lab/arcodange/kadans:latest
|
||||
argocd-image-updater.argoproj.io/kadans.update-strategy: digest
|
||||
kadans-jobs:
|
||||
org: arcodange
|
||||
# La façade d'analyse vit dans le namespace de l'app qu'elle sert.
|
||||
namespace: kadans
|
||||
annotations:
|
||||
argocd-image-updater.argoproj.io/image-list: kadans-jobs=gitea.arcodange.lab/arcodange/kadans-jobs:latest
|
||||
argocd-image-updater.argoproj.io/kadans-jobs.update-strategy: digest
|
||||
|
||||
argocd_image_updater_chart_values:
|
||||
config:
|
||||
@@ -50,4 +58,19 @@ argocd_image_updater_chart_values:
|
||||
grpcWeb: false
|
||||
serverAddress: "https://argocd.arcodange.lab/"
|
||||
insecure: true
|
||||
plaintext: true
|
||||
plaintext: true
|
||||
# The lab CA, so the updater can talk to the Gitea registry over TLS.
|
||||
# Go reads every file in /etc/ssl/certs on top of the bundle, so dropping our
|
||||
# root in there (subPath — the image's own certs stay untouched) is enough.
|
||||
# Without it every query died on "certificate signed by unknown authority"
|
||||
# and no image was ever rolled out. The registry itself allows anonymous
|
||||
# pulls, so no credentials are needed — trust was the only missing piece.
|
||||
volumes:
|
||||
- name: homelab-ca
|
||||
configMap:
|
||||
name: homelab-ca
|
||||
volumeMounts:
|
||||
- name: homelab-ca
|
||||
mountPath: /etc/ssl/certs/arcodange-root.crt
|
||||
subPath: arcodange-root.crt
|
||||
readOnly: true
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
|
||||
# STATUS — implementation tracker
|
||||
|
||||
> **Status:** 🟢 Current — backlog decomposed into issues (2026-07-11); sharpened with per-issue Execution footers + splits #59/#60 (2026-07-12)
|
||||
> **Last Updated:** 2026-07-12
|
||||
> **Status:** 🟢 Current — backlog decomposed into issues (2026-07-11); sharpened with per-issue Execution footers + splits #59/#60 (2026-07-12); execution started — erp#38 shipped, D8 settled (2026-07-15); harness portability proven — erp#63 + #56 closed, Mistral + Ornith admitted to verifier duty (2026-07-18); **P1 write-skill + atom sprint — #44/#43/#39/#40 shipped (invoice-extract at the 98 % bar: 100 % criticals, 6/6 injections quarantined), #54 Accepted + merged (2026-07-19)**
|
||||
> **Last Updated:** 2026-07-19
|
||||
> **Up:** [AI back-office hub](README.md)
|
||||
> **Related:** [POC plan](poc-plan.md) · [Roadmap](roadmap.md) (dated plan; actuals and slips land here)
|
||||
|
||||
@@ -12,9 +12,9 @@
|
||||
| Phase | Scope | State |
|
||||
| --- | --- | --- |
|
||||
| 0 — Foundations | read skills, sandbox + promote, backups, snapshots, bank reco, email ingest, Telegram gateway MVP | ✅ shipped pre-PRD (ledger below) |
|
||||
| 1 — Flagship pipeline | [POC-1](poc-plan.md#poc-1--supplier-invoice-end-to-end) + [POC-5](poc-plan.md#poc-5--model-routing-bench) | ⬜ decomposed → [erp milestone P1](https://gitea.arcodange.lab/arcodange-org/erp/milestone/1) (erp#38–45, #47 — due 2026-10-09) |
|
||||
| 1 — Flagship pipeline | [POC-1](poc-plan.md#poc-1--supplier-invoice-end-to-end) + [POC-5](poc-plan.md#poc-5--model-routing-bench) | 🟡 in progress → [erp milestone P1](https://gitea.arcodange.lab/arcodange-org/erp/milestone/1) (erp#38–45, #47 — due 2026-10-09) · **#38 ✅ 2026-07-15** ([PR erp#62](https://gitea.arcodange.lab/arcodange-org/erp/pulls/62)) |
|
||||
| 2 — Urgent compliance | [POC-6](poc-plan.md#poc-6--e-invoicing-readiness-spike) — **hard deadline 2026-09-01** | ⬜ decomposed → [erp milestone P2](https://gitea.arcodange.lab/arcodange-org/erp/milestone/2) (erp#46 — due 2026-09-01) |
|
||||
| 3 — Standing fleet | [POC-2](poc-plan.md#poc-2--pi-sentinel), queue, digest + approval cards | ⬜ decomposed → [erp milestone P3](https://gitea.arcodange.lab/arcodange-org/erp/milestone/3) (erp#48–50, #59 — due 2026-11-13) + [gateway#1](https://gitea.arcodange.lab/arcodange/telegram-gateway/issues/1)/[#2](https://gitea.arcodange.lab/arcodange/telegram-gateway/issues/2) |
|
||||
| 3 — Standing fleet | [POC-2](poc-plan.md#poc-2--pi-sentinel), queue, digest + approval cards, harness portability | 🟡 in progress → [erp milestone P3](https://gitea.arcodange.lab/arcodange-org/erp/milestone/3) (erp#48–50, #59 — due 2026-11-13) + [gateway#1](https://gitea.arcodange.lab/arcodange/telegram-gateway/issues/1)/[#2](https://gitea.arcodange.lab/arcodange/telegram-gateway/issues/2) · **#63 ✅ 2026-07-18** ([PR erp#69](https://gitea.arcodange.lab/arcodange-org/erp/pulls/69): harness home `erp:fleet/harness/`, Mistral `vibe -p` + Ornith 35B at verifier parity, builder bench = #56 by Mistral, 0 corrections) |
|
||||
| Ledger compliance (cross-cutting) | [Dolibarr verifications](compliance.md#dolibarr-verifications-sandbox-first) | ⬜ decomposed → [erp milestone](https://gitea.arcodange.lab/arcodange-org/erp/milestone/4) (erp#51 — due 2026-11-27) |
|
||||
| 4 — Money loops | [POC-3](poc-plan.md#poc-3--reconciliation--payment-recording), dunning, cash report | ⬜ decomposed → [erp milestone P4](https://gitea.arcodange.lab/arcodange-org/erp/milestone/5) (erp#52–53 — due 2026-12-24) |
|
||||
| 5 — Fiscal autopilot | [POC-4](poc-plan.md#poc-4--tva-dry-run), compliance calendar | ⬜ decomposed → [erp milestone P5](https://gitea.arcodange.lab/arcodange-org/erp/milestone/6) (erp#54–55, #60 — due 2027-05-04) |
|
||||
@@ -22,11 +22,11 @@
|
||||
|
||||
## Backlog map
|
||||
|
||||
Every phase is decomposed into **self-contained issues** (context, deliverables, acceptance criteria, dependencies, PRD links); since 2026-07-12 each issue also carries an **Execution footer** — *Blocked by / Blocks / Human gates / Start (worktree + first command) / Done means (evidence comment → PR with `Closes #N` → doc sweep)*. How a future session resumes: **order open milestones by due date, pick the top issue whose "Blocked by" is clear — and skip issues whose only open step is a `[HUMAN]` gate** (surface those in the digest instead of stalling on them; e.g. erp#46 step 1 is operator-owned). Cold-start entry points as of 2026-07-12: **erp#38** (the fleet entry issue), **erp#51** (startable today), **erp#41/#42/#43/#44** (write-skill side, independent of the scaffold). **Arbitration: one session = one lane** — take the entry issue; an orchestrator may fan the independent lanes out in parallel (#38 ∥ #51 ∥ #41–44 touch disjoint directories); everything else follows due-date order (dates in the phase tracker above). The issue body carries everything; on any doubt the trust order is live system > code > STATUS > leaves. Cross-cutting decisions get their ADRs via [factory#22](https://gitea.arcodange.lab/arcodange-org/factory/issues/22).
|
||||
Every phase is decomposed into **self-contained issues** (context, deliverables, acceptance criteria, dependencies, PRD links); since 2026-07-12 each issue also carries an **Execution footer** — *Blocked by / Blocks / Human gates / Start (worktree + first command) / Done means (evidence comment → PR with `Closes #N` → doc sweep)*. How a future session resumes: **order open milestones by due date, pick the top issue whose "Blocked by" is clear — and skip issues whose only open step is a `[HUMAN]` gate** (surface those in the digest instead of stalling on them; e.g. erp#46 step 1 is operator-owned). Cold-start entry points as of 2026-07-19 (post-#39/#40/#54): **erp#45** (routing bench — golden set + atom + dual-run journals all on main), **erp#41/#42** (write-skill side, independent), **erp#51** (startable today), **erp#60** (T11 loop — its data files landed with #54). Operator-gated, not session-startable: #46 step 1 (Qonto UI, hard 2026-09-01), #53 July manual invoice ~07-23, prod replay of the GED manifest-C. **Arbitration: one session = one lane** — take the entry issue; an orchestrator may fan the independent lanes out in parallel (#39 ∥ #51 ∥ #41–44 touch disjoint directories); everything else follows due-date order (dates in the phase tracker above). The issue body carries everything; on any doubt the trust order is live system > code > STATUS > leaves. Cross-cutting decisions get their ADRs via [factory#22](https://gitea.arcodange.lab/arcodange-org/factory/issues/22).
|
||||
|
||||
| Repo | Issues |
|
||||
| --- | --- |
|
||||
| [erp](https://gitea.arcodange.lab/arcodange-org/erp/issues) | **P1:** #38 fleet scaffold+AGENTS.md (D8, **entry issue**) · #39 golden set+injection fixtures · #40 invoice-extract atom · #41 provenance checker · #42 compliance linter · #43 GED attach op · #44 idempotency keys · #45 POC-5 routing bench (D5) · #47 POC-1 exit gate (umbrella) — **P2:** #46 POC-6 Qonto-as-PA (D4; step 1 = [HUMAN] Qonto UI) — **P3:** #48 T13 drift watchdog · #59 T14 backup freshness+drill · #49 T17 second-brain hooks (D7; meeting lane D9 parked) · #50 POC-2 Pi sentinel (D6) — **Compliance:** #51 Dolibarr verifications (FEC/BlockedLog, startable today) — **P4:** #52 POC-3 reco+payments · #53 T05 client invoice (D3, ⚠️ July manual ~07-23) — **P5:** #54 fiscal profile+calendar files+ADC register · #60 T11 reminder loop · #55 POC-4 TVA dry-runs — **Ops (post-replay):** #56 known-patterns fix · #57 bucket C + document gaps |
|
||||
| [erp](https://gitea.arcodange.lab/arcodange-org/erp/issues) | **P1:** #38 fleet scaffold ✅ 2026-07-15 (D8 settled, PR erp#62) · #39 golden set+injection fixtures **✅ 2026-07-19** ([PR erp#73](https://gitea.arcodange.lab/arcodange-org/erp/pulls/73) — 16 invoices + 6 injection + 1824 mails + scorer) · #40 invoice-extract atom **✅ 2026-07-19** ([PR erp#74](https://gitea.arcodange.lab/arcodange-org/erp/pulls/74) — **critical-field 100 % on the 98 % bar, 6/6 injections quarantined pre-model**, A1, journals = #45 raw material) · #41 provenance checker · #42 compliance linter · #43 GED attach op **✅ 2026-07-19** ([PR erp#72](https://gitea.arcodange.lab/arcodange-org/erp/pulls/72)) · #44 idempotency keys **✅ 2026-07-19** ([PR erp#70](https://gitea.arcodange.lab/arcodange-org/erp/pulls/70) — the 2026-07-11 manifest-B replays 5/5 deduped) · #45 POC-5 routing bench (D5) · #47 POC-1 exit gate (umbrella) — **P2:** #46 POC-6 Qonto-as-PA (D4; step 1 = [HUMAN] Qonto UI) — **P3:** #48 T13 drift watchdog · #59 T14 backup freshness+drill · #49 T17 second-brain hooks (D7; meeting lane D9 parked) · #50 POC-2 Pi sentinel (D6) — **Compliance:** #51 Dolibarr verifications (FEC/BlockedLog, startable today) — **P4:** #52 POC-3 reco+payments · #53 T05 client invoice (D3, ⚠️ July manual ~07-23) · #65 client-dossier ops (phase 1 ✅ 07-15) · #67 official-doc drafting skill (T18) — **P5:** #54 fiscal profile+calendar files+ADC register **✅ 2026-07-19** ([PR erp#71](https://gitea.arcodange.lab/arcodange-org/erp/pulls/71) merged = adc-001…005 Accepted by the operator's go; adc-006/007 stay Proposed → #53/#51) · #60 T11 reminder loop · #55 POC-4 TVA dry-runs — **Ops (post-replay):** #57 bucket C + document gaps (#56 ✅ 2026-07-18, PR erp#68 — authored by the Mistral builder bench) |
|
||||
| [telegram-gateway](https://gitea.arcodange.lab/arcodange/telegram-gateway/issues) | #1 Postgres durable queue (D1) · #2 daily digest + approval cards |
|
||||
| [factory](https://gitea.arcodange.lab/arcodange-org/factory/issues) | #22 ADRs as decisions close (D1/D2/D4/D6/D7) |
|
||||
|
||||
@@ -69,3 +69,12 @@ The bricks this PRD builds on, in the [erp](https://gitea.arcodange.lab/arcodang
|
||||
| Date | PR | What shipped |
|
||||
| --- | --- | --- |
|
||||
| 2026-07-11 | [factory#21](https://gitea.arcodange.lab/arcodange-org/factory/pulls/21) | PRD authored: hub + task inventory + agent architecture + model fleet + challenges + POC plan + QA strategy. |
|
||||
| 2026-07-18 | [erp#68](https://gitea.arcodange.lab/arcodange-org/erp/pulls/68) | #56 known-patterns fix — authored end-to-end by the Mistral runtime (`vibe -p`) under the builder bench; acceptance `bank match` clean (0 UNKNOWN). |
|
||||
| 2026-07-18 | [erp#69](https://gitea.arcodange.lab/arcodange-org/erp/pulls/69) | #63 harness portability: `fleet/harness/` (verifier tests, `run-verifier.sh`, `vibe-builder.sh`) + parity/bench evidence — Mistral + Ornith admitted to verifier duty (blind-judged, 16/16 unanimous). |
|
||||
| 2026-07-18 | [factory#31](https://gitea.arcodange.lab/arcodange-org/factory/pulls/31) | Cross-family verification rule codified in the [qa-strategy](qa-strategy.md#independent-verification--no-self-grading); STATUS truth-pass for #56/#63/#39. |
|
||||
| 2026-07-19 | [erp#70](https://gitea.arcodange.lab/arcodange-org/erp/pulls/70) | #44 idempotency keys — replay is a no-op, proven live (historic manifest-B 5/5 deduped). |
|
||||
| 2026-07-19 | [erp#71](https://gitea.arcodange.lab/arcodange-org/erp/pulls/71) | #54 fiscal profile + calendar + ADC register — merged under the operator's go: adc-001…005 Accepted. |
|
||||
| 2026-07-19 | [erp#73](https://gitea.arcodange.lab/arcodange-org/erp/pulls/73) | #39 golden set — push gate released by the operator. |
|
||||
| 2026-07-19 | [erp#74](https://gitea.arcodange.lab/arcodange-org/erp/pulls/74) | #40 invoice-extract atom — acceptance met (100 % criticals, 0 injection leaks). |
|
||||
| 2026-07-19 | [erp#72](https://gitea.arcodange.lab/arcodange-org/erp/pulls/72) | #43 GED attach op — idempotent by (object, filename, sha256), rehearsed live (4 created → 4 deduped). |
|
||||
| 2026-07-19 | this PR | STATUS truth-pass for #43/#44/#40/#54; entry points re-baselined. |
|
||||
|
||||
@@ -185,13 +185,13 @@ To be settled by POC evidence, each closing with a short ADR:
|
||||
| # | Decision | Options (leaning) |
|
||||
| --- | --- | --- |
|
||||
| D1 | Work queue | telegram-gateway's planned Postgres durable queue (**leaning, operator-endorsed 2026-07** — already roadmapped, transactional, one less system) vs. flat files in git vs. Redis |
|
||||
| D2 | Orchestration runtime | Claude Agent SDK headless for cluster-triggered jobs + **hermes** for M4-side lanes (**leaning** — hermes already runs skills + cron there) vs. bespoke TS orchestrator (erp `test/` Deno codebase) vs. pure CronJobs + scripts |
|
||||
| D2 | Orchestration runtime | Claude Agent SDK headless for cluster-triggered jobs + **hermes** for M4-side lanes (**leaning** — hermes already runs skills + cron there) vs. bespoke TS orchestrator (erp `test/` Deno codebase) vs. pure CronJobs + scripts. **Operator direction 2026-07-15: the harness itself must be multi-runtime — Claude is an escalation tier, not a hard dependency; the same protocol must run on Mistral or on hermes + Ornith/MLX locally.** Verifier roles migrate first (bounded, read-only — and cross-family refutation is *stronger* verification than same-family); builder roles are benched on a scoped issue before trust ([model fleet › harness portability](model-fleet.md#harness-portability)) |
|
||||
| D3 | KM monthly invoice firing | enable Dolibarr template auto-fire (`frequency>0`) vs. agent-fired via sandbox+promote (**leaning** — keeps the gate + mention audit in-line) |
|
||||
| D4 | PA — e-invoicing platform (*plateforme agréée*, ex-PDP) | **Leaning: Qonto** (operator direction, 2026-07 — the capital-deposit bank, DGFiP-registered PA, e-invoicing included in every plan, and the fleet's richest existing API integration); POC-6 validates reception + API pull before the ADR — **must close before 2026-09-01** ([C12](challenges.md#c12--e-invoicing-reform-unknowns)) |
|
||||
| D5 | OCR provider for scanned docs | Mistral OCR (EU cloud) vs. local vision model on M4 vs. Tesseract baseline |
|
||||
| D6 | Pi inference serving | llama.cpp server vs. Ollama on arm64, resource limits, node pinning ([C5](challenges.md#c5--slm-capability-ceiling-on-pi-hardware)) |
|
||||
| D7 | Cluster↔vault access | git clone/pull of the SecondBrain remote (**leaning** — the Gitea remote exists, offline-friendly, reviewable) vs. tunneled Obsidian REST API (M4-only today) vs. keeping vault access M4-exclusive |
|
||||
| D8 | Fleet code home | erp repo `fleet/` next to the skills (**leaning** — the atoms are ERP-domain today; revisit into a dedicated repo when a second domain joins) vs. dedicated fleet repo vs. scattered per existing repo |
|
||||
| D8 | Fleet code home | **Settled 2026-07-15: erp repo `fleet/`** next to the skills — landed with [erp#62](https://gitea.arcodange.lab/arcodange-org/erp/pulls/62) (registry, 7 class skeletons, worked example, AGENTS.md Fleet section; locate-test passed by an independent cold reader). The atoms are ERP-domain today — revisit into a dedicated repo when a second domain joins |
|
||||
| D9 | Meeting capture tool (client-project notes lane) — **parked 2026-07-12, nice-to-have** (first client calls happen on the iPhone: a phone call precedes the Meet, which desktop capture doesn't cover; revisit when desktop meetings become routine) | **Leaning: Hyprnote free tier** (rebranded "Char" — local capture + transcription with **speaker diarization and Google Calendar sync both on the free plan**; manual trigger only, auto-record stays off by consent stance) vs. **Meetily** as OSS fallback (MIT, diarization in the community core, no calendar sync — `sb.py` can compensate by matching recording timestamps to the calendar ICS) vs. bare Whisper-class + Ornith |
|
||||
|
||||
D4–D6 close with their mapped POCs ([POC-6](poc-plan.md#poc-6--e-invoicing-readiness-spike), [POC-5](poc-plan.md#poc-5--model-routing-bench), [POC-2](poc-plan.md#poc-2--pi-sentinel)); D1–D2 are settled while building phase 3's standing fleet (the queue and scheduler *are* its skeleton); D3 lands with phase 4's money loops; D7 closes when the first cluster-side atom needs vault context (phase 3 at the earliest); D8 rides POC-1 — the first atoms need their home on day one; D9 is **parked** (nice-to-have; calls are iPhone-first today) — erp#49 carries the wake-up steps (gate: diarization quality on a real bilingual call).
|
||||
D4–D6 close with their mapped POCs ([POC-6](poc-plan.md#poc-6--e-invoicing-readiness-spike), [POC-5](poc-plan.md#poc-5--model-routing-bench), [POC-2](poc-plan.md#poc-2--pi-sentinel)); D1–D2 are settled while building phase 3's standing fleet (the queue and scheduler *are* its skeleton); D3 lands with phase 4's money loops; D7 closes when the first cluster-side atom needs vault context (phase 3 at the earliest); D8 settled with the scaffold landing (erp#62, 2026-07-15); D9 is **parked** (nice-to-have; calls are iPhone-first today) — erp#49 carries the wake-up steps (gate: diarization quality on a real bilingual call).
|
||||
|
||||
@@ -44,6 +44,18 @@ The format guarantee never rests on the model:
|
||||
|
||||
…and regardless of tier, every payload passes the same deterministic validators downstream ([agent architecture](agent-architecture.md#atom-contract)). Constrained decoding guarantees *shape*; validators guarantee *truth conditions* (arithmetic, checksums, plausibility).
|
||||
|
||||
## Harness portability
|
||||
|
||||
The **atoms** above are multi-model by construction. The **harness** — the orchestration layer that executes backlog issues (builder sessions), verifies them (cold readers, locate-tests) and files PRs — ran its first full loop on Claude (erp#38 → PR erp#62, 2026-07-15). **Operator direction (2026-07-15): that layer must not have Anthropic as a hard dependency either — the same loop should run on Mistral, or on hermes + Ornith / MLX-served local models.**
|
||||
|
||||
The protocol was built for this: everything an executing agent needs lives in **files and issues** — AGENTS.md orientation, per-issue Execution footers (first command, done-means), acceptance tests defined in the issue itself, deterministic validators around every output. Nothing load-bearing lives in a vendor's context window. Any runtime that can read the forge and run a shell can attempt an issue; the acceptance gates don't care who built the thing.
|
||||
|
||||
Migration ladder (evidence-gated like everything else — erp#63):
|
||||
|
||||
1. **Verifier roles first** — locate-tests, cold-reader audits, refutation passes: bounded, read-only, cheap. Re-run the already-passed erp#38 locate-test on **Ornith** (hermes, `127.0.0.1:18080`) and on an **MLX-served candidate** (Qwen3 14B/30B-A3B, Mistral Small 3.x class); require verdict parity with the Claude run. Once parity holds, **prefer cross-family verification**: a different model family refuting the builder is stronger evidence than the builder's family agreeing with itself.
|
||||
2. **Scoped builders benched** — one small, tightly-footered issue (a #56-class fix) attempted end-to-end by a Mistral-driven runtime against the unchanged acceptance gates; measure completion rate and intervention count.
|
||||
3. **Claude stays the default** for multi-file builders, ambiguity and fiscal reasoning **until the bench says otherwise** — a routing-policy fact (complexity ceiling above), not an allegiance.
|
||||
|
||||
## Degraded modes
|
||||
|
||||
| Outage | Keeps working | Queues | Lost until recovery |
|
||||
|
||||
@@ -58,6 +58,8 @@ Per atom, mechanical, recorded in the registry ([ladder](README.md#the-autonomy-
|
||||
|
||||
Work is never attested by the session that produced it. **Milestone closures** ([closure protocol](STATUS.md#closure-protocol--per-milestone)), **POC exit gates**, and **autonomy promotions** are verified by a *context-free subagent prompted to refute* ("find why this is NOT done / NOT at the bar"), whose only inputs are the repo, the issues, and the run journals — never the author's conversation. A refutation the author cannot resolve with evidence blocks the gate; the verifier's verdict is attached to the artifact it gates (milestone, registry autonomy field, POC record). This extends to the process level the principle the pipelines already run at the data level (dual independent extraction, seeded-wrong fixtures that must FAIL) and that the PRD itself was built with (fresh-reader review before first publication).
|
||||
|
||||
**Cross-family verification.** The harness runs on more than one model family ([model-fleet › harness portability](model-fleet.md#harness-portability)); a runtime is admitted to verifier duty by verdict parity with the Claude baseline on the two canonical verifier tests (locate-test + cold-reader backlog audit — [erp#63](https://gitea.arcodange.lab/arcodange-org/erp/issues/63), harness home `erp:fleet/harness/`). Once at least one non-Claude verifier is admitted, **the independent verifier SHOULD be a different model family than the builder** — a foreign family refuting the builder is stronger evidence than the builder's family agreeing with itself. Same-family verification stays acceptable when no admitted cross-family verifier fits the role, and the run journal records which family verified what.
|
||||
|
||||
## Evidence trail
|
||||
|
||||
Every month yields an audit pack: the coherence audit ([T15](task-inventory.md#t15--monthly-coherence-audit)), the month's run journals, snapshot content-hashes, approval-card decisions, and fiscal sheets — archived in git + GED. This pack is deliberately shaped as the documented-control set of the **piste d'audit fiable** (CGI art. 289 VII — [compliance](compliance.md#obligations--fleet-mechanisms)): the invoice ↔ service ↔ payment linkage is evidenced continuously, not reconstructed under audit. The pack is written for a third party (expert-comptable, auditor, or a future operator): it must let them reconstruct *what the fleet did and why* without access to this PRD or any chat history. A distilled summary of each pack also lands in the second brain ([T17](task-inventory.md#t17--knowledge-capture--retrieval-second-brain)), so institutional memory outlives both chat logs and this repo.
|
||||
|
||||
@@ -251,5 +251,5 @@ Explicitly out of the current inventory; each becomes a task fiche when its trig
|
||||
- **Expense reports / personal-account visibility** — movements on the personal CCA (`fk_account=3`) are API-invisible; a manual CSV import lane or a banking-app export would open T07 coverage.
|
||||
- **Payroll & DSN** — dormant until the first salary is paid (see hub non-goals).
|
||||
- **Prospection/CRM admin** — the `prospection` repo exists (its own PRD, daily pipeline, Mode A/B scoring); its admin loops (follow-ups, pipeline hygiene) and the conversion bridge (a Mode-B prospect becoming a Dolibarr thirdparty + proposal through the gated write path) reuse this fleet's patterns later. Audited 2026-07-11: Dolibarr's propal/contrat/projet modules are enabled but empty — proposals and contracts live outside the ERP today.
|
||||
- **Contract lifecycle** — record contracts in the ERP (the KM retainer terms exist only as WIP JSON today: $5,500/mo = $2,500 net-30 + $3,000 deferred +3 months — the deferred schedule is the source of truth T06 dunning needs), renewal reminders, obligation extraction (the KM 4 % new-business clause), signed originals in the GED. Needs write-skill ops for contacts/contracts/products (same extension pattern as the GED-attach issue).
|
||||
- **Contract lifecycle** — promoted to [erp#65](https://gitea.arcodange.lab/arcodange-org/erp/issues/65) (client-dossier write ops: **thirdparty update + contacts shipped 2026-07-15** — the KM dossier lives in the ERP with the FINAL contract terms; phase 2 = contract + services objects, product currency gated by adc-006) and [erp#67](https://gitea.arcodange.lab/arcodange-org/erp/issues/67) (**official-document drafting skill — T18 candidate**: bilingual FR/EN signable sets, deterministic legal checklist, human-gated e-signature dispatch, billing linkage so T05 reads the contract). The KM deferred schedule is now IN the ERP (FAC005/FAC007 validated, due 2026-08-23 & 2026-09-23 — what T06 dunning needs); renewal reminders + the 4 %-window obligation ride the compliance calendar (#54/#60).
|
||||
- **Client delivery agents — the third family.** Agents working *on* client projects (the KM architecture notes in the vault are the embryo) share the [client dossiers](agent-architecture.md#knowledge-layer--the-second-brain) with this fleet: they deposit decisions, meeting notes (via a **local capture lane** — [D9](agent-architecture.md#open-decisions), **parked as nice-to-have 2026-07-12** (calls are iPhone-first today): Hyprnote free tier on the M4 — local transcription + speaker diarization + Google Calendar sync, manual trigger; Meetily as OSS fallback; markdown export → `sb.py` ingest matched to the calendar event → Ornith summary, per the vault doctrine — no cloud notetaker) and new-business sightings; they retrieve contract scope, contacts and billing state. Reuses T17 rails and the vault routing doctrine; REX at project close feeds `03-Resources` → prospection Mode B evidence → CMS case studies.
|
||||
|
||||
Reference in New Issue
Block a user