arcane-cli 0.33.9 → 0.34.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -72,7 +72,7 @@ Arcane separates framework-level decisions from org-specific ones using two pref
|
|
|
72
72
|
2. Confirms no collision with other entities
|
|
73
73
|
3. Identifies any docs, scripts, or prompts that reference the old name
|
|
74
74
|
|
|
75
|
-
This check was added after [[
|
|
75
|
+
This check was added after [[docs/rcas/RCA-001-naming-collision|RCA-001]] discovered that ADR-061 named a product without checking whether the ops repo already used that name. **Enforcement: explicitly advisory prose (ARC-023) — no script or spell gate verifies that an ADR introducing a new name actually contains a "Naming impact" section or performed its three checks; `spell-scry` can run the grep-and-collision check manually, but nothing requires it before such an ADR is written.**
|
|
76
76
|
|
|
77
77
|
### Tier 2: Companion Detail Docs
|
|
78
78
|
|
|
@@ -38,7 +38,7 @@ An RCA is **recommended** (but optional) for:
|
|
|
38
38
|
|
|
39
39
|
## RCA Template
|
|
40
40
|
|
|
41
|
-
**Every RCA follows this structure. Artifacts are stored in `
|
|
41
|
+
**Every RCA follows this structure. Artifacts are stored in `docs/rcas/` with the filename `RCA-NNN-short-slug.md` (sequential numbering, matching the related ADR when applicable). Enforcement: explicitly advisory prose (ARC-023) — no script validates RCA filenames, sequential numbering, or template structure.**
|
|
42
42
|
|
|
43
43
|
```markdown
|
|
44
44
|
---
|
|
@@ -104,7 +104,7 @@ Bullet points — what the team now knows that it didn't before.
|
|
|
104
104
|
### 1. Initiate
|
|
105
105
|
|
|
106
106
|
When a trigger condition is met:
|
|
107
|
-
- Create the RCA artifact file in `
|
|
107
|
+
- Create the RCA artifact file in `docs/rcas/`
|
|
108
108
|
- Fill in the Incident Summary and Timeline sections
|
|
109
109
|
- Record the ADR that establishes the RCA (if applicable)
|
|
110
110
|
|
|
@@ -147,13 +147,13 @@ RCAs do not have formal severity levels. The trigger conditions above determine
|
|
|
147
147
|
## Artifact Location
|
|
148
148
|
|
|
149
149
|
```
|
|
150
|
-
|
|
150
|
+
docs/
|
|
151
151
|
rcas/
|
|
152
152
|
RCA-001-naming-collision.md
|
|
153
153
|
RCA-002-...
|
|
154
154
|
```
|
|
155
155
|
|
|
156
|
-
**Why `governance/rcas/`?** RCAs are governance artifacts (process improvement
|
|
156
|
+
**Why `docs/rcas/`, not `governance/rcas/`?** RCAs are project/domain documents (a record of what happened in *this* repository), not a framework-managed standard — [[portable-bootstrap#where-documents-live|portable-bootstrap.md's "Where Documents Live"]] reserves `.arcane/governance/` for framework-managed standards and explicitly forbids a duplicate root `governance/` tree; `docs/` is the same explicit-descriptive-path convention it names for project/domain documents. RCAs remain governance artifacts in *purpose* (process improvement, not a journal or a decision) — they complement ADRs by explaining *how a decision failed* rather than *what was decided* — just not in *filesystem location*. Enforcement: explicitly advisory prose (ARC-023) — no script checks that an RCA file actually lives under `docs/rcas/` rather than elsewhere.
|
|
157
157
|
|
|
158
158
|
## Maintenance
|
|
159
159
|
|
package/dist/index.js
CHANGED
|
@@ -4817,6 +4817,9 @@ async function runDoctor(targetDir, options = {}, assetsDir) {
|
|
|
4817
4817
|
}
|
|
4818
4818
|
}
|
|
4819
4819
|
|
|
4820
|
+
// src/commands/ward.ts
|
|
4821
|
+
import { readFile as readFile11 } from "fs/promises";
|
|
4822
|
+
|
|
4820
4823
|
// src/modules/ward.ts
|
|
4821
4824
|
import { readdir as readdir6, readFile as readFile10 } from "fs/promises";
|
|
4822
4825
|
import { join as join13, relative as relative2 } from "path";
|
|
@@ -4942,8 +4945,24 @@ function parseTerms(raw) {
|
|
|
4942
4945
|
if (!raw) return [];
|
|
4943
4946
|
return raw.split(",").map((t) => t.trim()).filter(Boolean);
|
|
4944
4947
|
}
|
|
4948
|
+
function parseTermsFileContent(raw) {
|
|
4949
|
+
return raw.split(/[,\r\n]+/).map((t) => t.trim()).filter(Boolean);
|
|
4950
|
+
}
|
|
4951
|
+
async function readTermsFile(filePath) {
|
|
4952
|
+
try {
|
|
4953
|
+
return parseTermsFileContent(await readFile11(filePath, "utf8"));
|
|
4954
|
+
} catch (error) {
|
|
4955
|
+
console.warn(
|
|
4956
|
+
`\u26A0 arcane: could not read --terms-file "${filePath}": ${error.message}`
|
|
4957
|
+
);
|
|
4958
|
+
return [];
|
|
4959
|
+
}
|
|
4960
|
+
}
|
|
4945
4961
|
async function runWardCli(targetDir, options = {}, exclusions = []) {
|
|
4946
|
-
const terms =
|
|
4962
|
+
const terms = [
|
|
4963
|
+
...parseTerms(options.terms),
|
|
4964
|
+
...options.termsFile ? await readTermsFile(options.termsFile) : []
|
|
4965
|
+
];
|
|
4947
4966
|
const report = await runWard(targetDir, { terms, exclusions });
|
|
4948
4967
|
console.log("\nspell ward \u2014 scanning for leaked identifiers\n");
|
|
4949
4968
|
const leaks = report.findings.filter((f) => f.category === "leak");
|
|
@@ -5154,6 +5173,9 @@ program.command("doctor").description("Check your environment for Arcane prerequ
|
|
|
5154
5173
|
program.command("ward").description("Scan the repo for leaked identifiers -- third-party trademarks and the operator's own personal identifiers alike (T18)").option(
|
|
5155
5174
|
"--terms <terms>",
|
|
5156
5175
|
"Comma-separated denylist terms, in addition to the built-in vendor-identifier list. Seed this from your OWN identity too, not just org/venture names -- usernames, machine names, and personal handles leak the same way a private venture name does (I1)"
|
|
5176
|
+
).option(
|
|
5177
|
+
"--terms-file <path>",
|
|
5178
|
+
"Read denylist terms from a file instead of --terms, to avoid shell-history exposure (ARC-041). Same comma/newline-separated format as ARCANE_ORG_TOKENS."
|
|
5157
5179
|
).option("--gate", "Exit non-zero if any leak is found (for CI)").action(async (opts) => {
|
|
5158
5180
|
await runWardCli(process.cwd(), opts);
|
|
5159
5181
|
});
|