feat(write-skill): chronology guard + explicit production opt-in #78

Merged
arcodange merged 1 commits from arcodange/prod-apply into main 2026-07-26 01:26:41 +02:00
Owner

Two guards, both from real incidents in this session.

1. Chronology (CGI art. 289). Dolibarr assigns the number at validation, in creation order — so issuing a document dated before the last one already issued gives a higher number to an earlier date. The July plan walked straight into it: the M3 deferred part is due 2026-10-23 and must be issued at D-60 (24/08) to stay under the L.441-10 I ceiling, while the M4 fixed part is dated 23/08. Issue them in the wrong order and the numbering breaks.

invoice-create.sh now reads the last issued document of the same kind and refuses an earlier date, with ARCO_ALLOW_BACKDATE=I-UNDERSTAND-THIS-BREAKS-CHRONOLOGY as a loud, documented override. Verified: refuses a 01/07 invoice against FAC008 (23/07), accepts 23/08.

2. Production opt-in. The sandbox-only guard from #75 had no way to express a deliberate production run — so any prod work meant bypassing it entirely, which is how guards die. Production now requires both ARCO_ALLOW_PRODUCTION=<exact host> and ARCO_PROD_CONFIRM=I-UNDERSTAND-THIS-WRITES-PROD, and prints a banner before acting. Also fixes a misleading (sandbox verified) log that printed even when the target was production.

grantAgentRight.ts joins the repo (it was never committed in #75) and gains --revoke, so a temporarily elevated right can be handed back — used today to attach a payment in production, revoked immediately after.

Note for a follow-up: the production ai_agent already holds create/modify on invoices and thirdparties, and delete on proposals — while AGENTS.md, ADR-0003 and the SKILL.md files all state that production is read-only for agents. The documented posture and the real one disagree; that needs a decision (align the rights, or correct the doctrine).

🤖 Generated with Claude Code

https://claude.ai/code/session_01VRShc4QhLLU73FLHx9vskh

Two guards, both from real incidents in this session. **1. Chronology (CGI art. 289).** Dolibarr assigns the number at validation, in creation order — so issuing a document dated *before* the last one already issued gives a **higher number to an earlier date**. The July plan walked straight into it: the M3 deferred part is due 2026-10-23 and must be issued at D-60 (**24/08**) to stay under the L.441-10 I ceiling, while the M4 fixed part is dated **23/08**. Issue them in the wrong order and the numbering breaks. `invoice-create.sh` now reads the last issued document of the same kind and refuses an earlier date, with `ARCO_ALLOW_BACKDATE=I-UNDERSTAND-THIS-BREAKS-CHRONOLOGY` as a loud, documented override. Verified: refuses a 01/07 invoice against FAC008 (23/07), accepts 23/08. **2. Production opt-in.** The sandbox-only guard from #75 had no way to express a *deliberate* production run — so any prod work meant bypassing it entirely, which is how guards die. Production now requires **both** `ARCO_ALLOW_PRODUCTION=<exact host>` and `ARCO_PROD_CONFIRM=I-UNDERSTAND-THIS-WRITES-PROD`, and prints a banner before acting. Also fixes a misleading `(sandbox verified)` log that printed even when the target was production. `grantAgentRight.ts` joins the repo (it was never committed in #75) and gains `--revoke`, so a temporarily elevated right can be handed back — used today to attach a payment in production, revoked immediately after. **Note for a follow-up:** the production `ai_agent` already holds create/modify on invoices and thirdparties, and delete on proposals — while `AGENTS.md`, ADR-0003 and the SKILL.md files all state that production is read-only for agents. The documented posture and the real one disagree; that needs a decision (align the rights, or correct the doctrine). 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01VRShc4QhLLU73FLHx9vskh
arcodange added 1 commit 2026-07-26 01:26:29 +02:00
Two guards, both from real incidents in the same session.

1. invoice-create.sh — chronology (CGI art. 289). Dolibarr assigns the number at
   validation, in creation order, so issuing a document dated BEFORE the last one
   already issued gives a higher number to an earlier date. The July plan walked
   straight into it: the M3 deferred part is due 2026-10-23 and must be issued at
   D-60 (24/08) to stay under the L.441-10 I ceiling, while the M4 fixed part is
   dated 23/08 — issue them in the wrong order and the numbering breaks. The
   guard reads the last issued document of the same kind and refuses an earlier
   date, with ARCO_ALLOW_BACKDATE as a loud, documented override.
   Verified: refuses a 01/07 invoice against FAC008 (23/07), accepts 23/08.

2. test/scripts/guard.ts — production opt-in. The sandbox-only guard had no way
   to express a deliberate production run, so any prod work meant bypassing it
   entirely (which is how guards die). Production now requires BOTH
   ARCO_ALLOW_PRODUCTION=<exact host> and
   ARCO_PROD_CONFIRM=I-UNDERSTAND-THIS-WRITES-PROD, and prints a banner. Nothing
   reaches prod by inheriting an ambient variable.
   Also fixes a misleading "(sandbox verified)" log that printed even on prod.

grantAgentRight.ts joins the repo (it was never committed) and gains --revoke,
so a temporarily elevated right can be handed back — used today to attach a
payment in production and revoked immediately after.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
Claude-Session: https://claude.ai/code/session_01VRShc4QhLLU73FLHx9vskh
arcodange merged commit 937bcfc8da into main 2026-07-26 01:26:41 +02:00
arcodange deleted branch arcodange/prod-apply 2026-07-26 01:26:42 +02:00
Sign in to join this conversation.
No Reviewers
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: arcodange-org/erp#78