@vegastack/skills 0.2.0 → 0.3.0
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.
- package/README.md +1 -1
- package/dist/index.js +9 -9
- package/package.json +1 -1
- package/skill/arch-guardian/SKILL.md +27 -39
- package/skill/arch-guardian/agents/openai.yaml +2 -2
- package/skill/arch-guardian/assets/adr-template.md +10 -25
- package/skill/arch-guardian/assets/answers-example.json +8 -18
- package/skill/arch-guardian/assets/architecture-profile.json +10 -22
- package/skill/arch-guardian/assets/architecture-profile.schema.json +13 -195
- package/skill/arch-guardian/references/advisory-report.md +65 -0
- package/skill/arch-guardian/references/architecture/ai-cost.md +2 -0
- package/skill/arch-guardian/references/architecture/ai-data-boundaries.md +2 -0
- package/skill/arch-guardian/references/architecture/ai-evals.md +2 -0
- package/skill/arch-guardian/references/architecture/connectors-sandbox.md +2 -2
- package/skill/arch-guardian/references/architecture/delivery-operations.md +5 -5
- package/skill/arch-guardian/references/architecture/durable-execution.md +3 -1
- package/skill/arch-guardian/references/architecture/flutter.md +1 -1
- package/skill/arch-guardian/references/architecture/foundation.md +17 -19
- package/skill/arch-guardian/references/architecture/hosting-reliability.md +1 -1
- package/skill/arch-guardian/references/architecture/identity-tenancy.md +7 -7
- package/skill/arch-guardian/references/architecture/model-lifecycle.md +5 -3
- package/skill/arch-guardian/references/architecture/models-observability.md +1 -1
- package/skill/arch-guardian/references/architecture/security-privacy.md +9 -5
- package/skill/arch-guardian/references/architecture/topology-monorepo.md +1 -1
- package/skill/arch-guardian/references/architecture/web.md +1 -1
- package/skill/arch-guardian/references/foundation-compatibility.json +1 -1
- package/skill/arch-guardian/references/profile-governance.md +25 -39
- package/skill/arch-guardian/references/rule-model.json +2 -2
- package/skill/arch-guardian/references/workflows.md +15 -12
- package/skill/arch-guardian/refresh/REFRESH.md +9 -2
- package/skill/arch-guardian/refresh/sources.json +26 -14
- package/skill/arch-guardian/scripts/lib.mjs +1 -10
- package/skill/arch-guardian/scripts/profile-tool.mjs +43 -49
- package/skill/arch-guardian/scripts/refresh-evidence.mjs +43 -5
- package/skill/arch-guardian/scripts/validate-profile.mjs +20 -196
- package/skill/arch-guardian/scripts/verify-corpus.mjs +1 -13
- package/skill/skill-maintainer/refresh/REFRESH.md +1 -1
- package/skill-integrity.json +34 -35
- package/skill/arch-guardian/references/control-catalog.json +0 -55
- package/skill/arch-guardian/scripts/architecture-check.mjs +0 -323
package/README.md
CHANGED
|
@@ -11,7 +11,7 @@ npx @vegastack/skills add arch-guardian
|
|
|
11
11
|
|
|
12
12
|
| Skill | What it does |
|
|
13
13
|
|---|---|
|
|
14
|
-
| `arch-guardian` | Architecture advisor:
|
|
14
|
+
| `arch-guardian` | Architecture advisor: tier-scoped normative rules activated by declared capabilities, evidence-backed advisory reports, slim committed profile, source-freshness contract |
|
|
15
15
|
| `skill-maintainer` | Encodes the Agent Skills standards (Claude Code, Codex, Hermes, agentskills.io) for creating, updating, and releasing skills in a skills repo |
|
|
16
16
|
| `skillify` | Turns a feature or workflow into a complete skill conforming to the VegaStack skills contract, or audits an existing one |
|
|
17
17
|
|
package/dist/index.js
CHANGED
|
@@ -516,7 +516,7 @@ async function doctor(options) {
|
|
|
516
516
|
await assertNoSymlink(base, false);
|
|
517
517
|
let failed = false;
|
|
518
518
|
const profileCandidates = [join(base, ".vegastack", "architecture.json"), join(base, ".vegastack", "architecture.yaml")];
|
|
519
|
-
let
|
|
519
|
+
let foundProfilePath = null;
|
|
520
520
|
if (options.mode !== "global") {
|
|
521
521
|
let profile = null;
|
|
522
522
|
for (const candidate of profileCandidates)
|
|
@@ -524,14 +524,14 @@ async function doctor(options) {
|
|
|
524
524
|
profile = candidate;
|
|
525
525
|
break;
|
|
526
526
|
}
|
|
527
|
-
|
|
527
|
+
foundProfilePath = profile;
|
|
528
528
|
if (profile) {
|
|
529
529
|
if (profile.endsWith(".yaml"))
|
|
530
530
|
console.log(`notice: ${profile} uses the legacy .yaml name for a JSON document; rename to architecture.json`);
|
|
531
531
|
try {
|
|
532
532
|
const parsed = JSON.parse(await readFile(profile, "utf8"));
|
|
533
|
-
if (parsed.schemaVersion !==
|
|
534
|
-
throw new Error("required identity fields are absent or profile is not
|
|
533
|
+
if (parsed.schemaVersion !== 4 || !parsed.project?.name || !parsed.project?.tier || !Array.isArray(parsed.capabilities))
|
|
534
|
+
throw new Error("required identity fields are absent or profile is not schema v4 (run profile-tool.mjs migrate for v3 profiles)");
|
|
535
535
|
console.log(`ok architecture profile: ${profile}`);
|
|
536
536
|
} catch (error) {
|
|
537
537
|
console.log(`invalid architecture profile: ${profile} (${error.message})`);
|
|
@@ -564,7 +564,7 @@ async function doctor(options) {
|
|
|
564
564
|
console.log(`${result.status === "verified" ? "ok" : "invalid"} ${agent} ${skillName} installation${result.issues.length ? ` (${result.issues.join(", ")})` : ""}`);
|
|
565
565
|
if (result.status !== "verified")
|
|
566
566
|
failed = true;
|
|
567
|
-
const candidate = join(destination, "scripts", "
|
|
567
|
+
const candidate = join(destination, "scripts", "validate-profile.mjs");
|
|
568
568
|
if (await exists(candidate))
|
|
569
569
|
checkScripts.push(candidate);
|
|
570
570
|
}
|
|
@@ -574,12 +574,12 @@ async function doctor(options) {
|
|
|
574
574
|
failed = true;
|
|
575
575
|
}
|
|
576
576
|
const firstCheckScript = checkScripts[0];
|
|
577
|
-
if (options.mode !== "global" && firstCheckScript &&
|
|
578
|
-
const result = spawnSync(process.execPath, [firstCheckScript,
|
|
577
|
+
if (options.mode !== "global" && firstCheckScript && foundProfilePath && !failed) {
|
|
578
|
+
const result = spawnSync(process.execPath, [firstCheckScript, foundProfilePath], { encoding: "utf8" });
|
|
579
579
|
if (result.status === 0)
|
|
580
|
-
console.log("ok
|
|
580
|
+
console.log("ok profile validation");
|
|
581
581
|
else {
|
|
582
|
-
console.log(`invalid
|
|
582
|
+
console.log(`invalid profile: ${result.stdout.trim() || result.stderr.trim()}`);
|
|
583
583
|
failed = true;
|
|
584
584
|
}
|
|
585
585
|
}
|
package/package.json
CHANGED
|
@@ -1,35 +1,36 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: arch-guardian
|
|
3
|
-
description: Architecture advisor for VegaStack projects. Use when designing a new service or feature, reviewing architecture or a risky change (auth, tenancy, agents, jobs, connectors, data lifecycle, hosting), deciding between architectural options, writing
|
|
3
|
+
description: Architecture advisor for VegaStack projects. Use when designing a new service or feature, reviewing architecture or a risky change (auth, tenancy, agents, jobs, connectors, data lifecycle, hosting), deciding between architectural options, writing an ADR or a .vegastack/architecture.json profile, threat modeling, planning a migration, or checking dependency and source drift. Advises contextually by declared tier (prototype, production, enterprise) and enabled capabilities; recommends the smallest architecture that meets the requirement and produces evidence-backed advisory reports, never CI gates. Covers web-only, Flutter, agentic and non-agentic, single- and multi-tenant, internal, client, and package projects.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# VegaStack Architecture Guardian
|
|
7
7
|
|
|
8
|
-
Act as the project's
|
|
8
|
+
Act as the project's senior architecture advisor. Apply only enabled capabilities at the declared tier. Recommend; never gate. Never invent compliance or project facts. There is no exception machinery: a team that departs from a recommendation records the decision, and you keep reporting it honestly as accepted risk.
|
|
9
9
|
|
|
10
10
|
## Start every task
|
|
11
11
|
|
|
12
12
|
1. Identify the actual decision, its scope, and how expensive it is to reverse.
|
|
13
|
-
2.
|
|
14
|
-
3.
|
|
15
|
-
4.
|
|
16
|
-
5.
|
|
17
|
-
6.
|
|
18
|
-
7.
|
|
13
|
+
2. Read the profile (`.vegastack/architecture.json`) and repository evidence before asking questions. Keep read-only work read-only; never create a profile or artifact merely because it is absent.
|
|
14
|
+
3. Note the **tier** (`prototype` | `production` | `enterprise`) — it decides which concerns apply. If no profile exists, ask for the tier (or state the assumed one) before recommending.
|
|
15
|
+
4. Separate facts, constraints, assumptions, preferences, and recorded team decisions. Distinguish current, target, and migration state.
|
|
16
|
+
5. Ask at most three material questions at a time. If unanswered, proceed with bounded assumptions and the smallest architecture that meets stated requirements — every proposed moving service names the trigger that justifies it.
|
|
17
|
+
6. Read only the directly relevant references below. Use the committed profile, designs, and ADRs as architecture memory; never rely on hidden chat state.
|
|
18
|
+
7. Prioritize security/correctness, recovery, ownership, contracts, operability, delivery, then optional optimization. Make one primary recommendation and identify the rejected alternative.
|
|
19
19
|
|
|
20
20
|
Script invocations below write `<skill-dir>` as a placeholder: replace it with the absolute path of the directory containing this SKILL.md before running (no environment variable is set for you).
|
|
21
21
|
|
|
22
22
|
## Answer at the right size
|
|
23
23
|
|
|
24
|
-
- **Questions and explanations:** answer directly — the
|
|
25
|
-
- **Design reviews, ADRs, migration plans:** use the
|
|
24
|
+
- **Questions and explanations:** answer directly — the recommendation and at most one material risk. No section headers, no report.
|
|
25
|
+
- **Design reviews, ADRs, migration plans:** use the [advisory report contract](references/advisory-report.md): per-area grades (`sound`/`attention`/`at-risk`), severity-ranked findings (`critical`/`production-gate`/`enterprise-gate`/`consider`), each with cited evidence and its principle ID, plus questions and not-verified items. No finding without evidence; detection is never a claim of absence.
|
|
26
26
|
|
|
27
27
|
## Route progressively
|
|
28
28
|
|
|
29
29
|
| Need | Read |
|
|
30
30
|
|---|---|
|
|
31
|
-
| operating model,
|
|
32
|
-
| greenfield, brownfield,
|
|
31
|
+
| operating model, tiers, minimum viable architecture, profiles | [foundation](references/architecture/foundation.md), [profile and governance](references/profile-governance.md) |
|
|
32
|
+
| greenfield, brownfield, review, migration workflows | [adaptive workflows](references/workflows.md) |
|
|
33
|
+
| review output format and evidence recipes | [advisory report](references/advisory-report.md) |
|
|
33
34
|
| topology, deployables, packages, contracts | [topology and monorepo](references/architecture/topology-monorepo.md) |
|
|
34
35
|
| web/Next/OpenAPI/cache | [web](references/architecture/web.md) |
|
|
35
36
|
| Flutter/mobile | [Flutter](references/architecture/flutter.md) |
|
|
@@ -43,54 +44,41 @@ Script invocations below write `<skill-dir>` as a placeholder: replace it with t
|
|
|
43
44
|
| model spend, budgets, cost attribution | [AI cost](references/architecture/ai-cost.md) |
|
|
44
45
|
| realtime, notifications, channels | [realtime and channels](references/architecture/realtime-channels.md) |
|
|
45
46
|
| models, BYOK, telemetry, audit | [models and observability](references/architecture/models-observability.md) |
|
|
46
|
-
| security, privacy, threat model | [security and privacy](references/architecture/security-privacy.md) |
|
|
47
|
+
| security, privacy, secrets, threat model | [security and privacy](references/architecture/security-privacy.md) |
|
|
47
48
|
| hosting, Cloudflare/OpenNext, SLO/recovery | [hosting and reliability](references/architecture/hosting-reliability.md) |
|
|
48
49
|
| delivery, migration, verification | [delivery and operations](references/architecture/delivery-operations.md) |
|
|
49
50
|
| fragile boundary implementation | [golden patterns](references/golden-patterns.md) |
|
|
50
51
|
|
|
51
|
-
|
|
52
|
+
For current detail beyond a pinned claim, [refresh/sources.json](refresh/sources.json) is also the research index: fetch the affected source's `llms` or `docsIndex` URL (or use an available docs MCP). For design reviews and recommendations that lean on a **critical** source (`critical: true`), check freshness — `node <skill-dir>/scripts/refresh-evidence.mjs --topics <affected-topics>` when online, or report the claim as not verified when offline past its `thresholdDays`. Plain questions answer from the shipped snapshot with a one-line staleness caveat. Consult [foundation compatibility](references/foundation-compatibility.json) for version baselines.
|
|
52
53
|
|
|
53
54
|
## Execute the task-specific workflow
|
|
54
55
|
|
|
55
|
-
- **Greenfield:** Follow the adaptive intake in [workflows](references/workflows.md)
|
|
56
|
-
- **Brownfield/review:** Inspect instructions, manifests/locks, deployables,
|
|
57
|
-
- **ADR/design/threat/deploy:** Use the relevant asset only after write authorization
|
|
58
|
-
- **Continuous work:** Load only affected references
|
|
59
|
-
- **Source drift:** Follow [refresh/REFRESH.md](refresh/REFRESH.md). Refresh only affected topics
|
|
56
|
+
- **Greenfield:** Follow the adaptive intake in [workflows](references/workflows.md): interview (tier first), recommend one capability set and topology sized by minimum viable architecture, name immediate/deferred decisions and triggers, and offer a slim profile draft after confirmation.
|
|
57
|
+
- **Brownfield/review:** Inspect instructions, manifests/locks, deployables, schemas/migrations, auth, APIs, jobs, infra, ADRs, and runbooks before interviewing. Produce an advisory report; prefer controlled migration over rewrites.
|
|
58
|
+
- **ADR/design/threat/deploy:** Use the relevant asset only after write authorization; an ADR is a decision record, never a waiver.
|
|
59
|
+
- **Continuous work:** Load only affected references. Do not force absent capabilities or higher-tier concerns into scope.
|
|
60
|
+
- **Source drift:** Follow [refresh/REFRESH.md](refresh/REFRESH.md). Refresh only affected topics.
|
|
60
61
|
|
|
61
|
-
## Profiles
|
|
62
|
+
## Profiles and mutation safety
|
|
62
63
|
|
|
63
|
-
The committed profile lives at `.vegastack/architecture.json` (
|
|
64
|
+
The committed profile lives at `.vegastack/architecture.json` (schema v4, ~12 lines; legacy names are discovered with a deprecation notice). Inspect or draft without mutation:
|
|
64
65
|
|
|
65
66
|
```sh
|
|
66
67
|
node <skill-dir>/scripts/profile-tool.mjs inspect .
|
|
67
68
|
node <skill-dir>/scripts/profile-tool.mjs scaffold answers.json --dir .
|
|
69
|
+
node <skill-dir>/scripts/profile-tool.mjs migrate .vegastack/architecture.json --dir . # v3 -> v4 draft
|
|
68
70
|
```
|
|
69
71
|
|
|
70
|
-
`inspect` prints a compact summary;
|
|
71
|
-
|
|
72
|
-
Write only after explicit authorization; writes are atomic, refuse symlinks, stay inside `--dir`, and require `--force` to replace differing content:
|
|
73
|
-
|
|
74
|
-
```sh
|
|
75
|
-
node <skill-dir>/scripts/profile-tool.mjs scaffold answers.json --dir . --write
|
|
76
|
-
node <skill-dir>/scripts/profile-tool.mjs migrate-v2 .vegastack/architecture.yaml --dir .
|
|
77
|
-
```
|
|
78
|
-
|
|
79
|
-
Validate and review (prefer `--summary` in conversation; `--json` is for CI):
|
|
72
|
+
`inspect` prints a compact summary; `--json` for the full draft. The answers format is documented by example in `<skill-dir>/assets/answers-example.json`. Write only after explicit authorization; writes are atomic, refuse symlinks, stay inside `--dir`, and require `--force` to replace differing content (`--write` to apply). Validate with:
|
|
80
73
|
|
|
81
74
|
```sh
|
|
82
75
|
node <skill-dir>/scripts/validate-profile.mjs .vegastack/architecture.json
|
|
83
|
-
node <skill-dir>/scripts/architecture-check.mjs . --summary
|
|
84
76
|
```
|
|
85
77
|
|
|
86
|
-
`architecture-check` exit codes: 0 = no FAIL findings, 1 = FAIL findings present, 2 = tool/usage error. A non-zero exit is a review result, not a crash. Paths can be excluded deliberately via a `.guardianignore` file (path prefixes, one per line). Symlinks, agent-skill trees, and generated/bundled files (very large or very long-line files) are skipped automatically and reported in one `NOT VERIFIED` finding.
|
|
87
|
-
|
|
88
|
-
Interpret outcomes exactly: `PASS` satisfies the recommendation; `FAIL` violates it without a valid exception; `EXCEPTED` is active project-owner accepted risk and remains visibly noncompliant although CI may pass; `NOT VERIFIED` records reason, risk, owner, and next action. Invalid, expired, or mismatched exceptions fail. Continue to recommend rejection when accepted risk remains unsafe.
|
|
89
|
-
|
|
90
78
|
## Guardrails
|
|
91
79
|
|
|
92
|
-
-
|
|
93
|
-
-
|
|
94
|
-
-
|
|
80
|
+
- Tiers gate concerns, never tools. Never require a tool when only the invariant matters: the mechanism (platform secret store vs OpenBao, cron vs pg-boss, in-process loop vs EVE at prototype) is chosen by named triggers and recorded per project.
|
|
81
|
+
- Never require SQL/RLS, Better Auth, Flutter, EVE, pg-boss, sandbox, connectors, enterprise identity, realtime, notifications, or knowledge when their activation condition is absent — and never surface enterprise-tier concerns as defects to a prototype/production project; report them as that tier's gate.
|
|
82
|
+
- Challenge proposals and defaults when evidence warrants. Choose the smallest architecture meeting current requirements and measured objectives.
|
|
95
83
|
- Never mutate a repository for an explanation or read-only review. Draft first and ask before writing.
|
|
96
84
|
- Never create paid/cloud resources or claim live recovery, isolation, failover, credential-backed, or provider tests ran unless they actually ran.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
interface:
|
|
2
2
|
display_name: "VegaStack Architecture Guardian"
|
|
3
|
-
short_description: "
|
|
4
|
-
default_prompt: "Use $arch-guardian to make one scoped architecture recommendation for this project without assuming absent capabilities."
|
|
3
|
+
short_description: "Tier-aware architecture advisor for VegaStack projects"
|
|
4
|
+
default_prompt: "Use $arch-guardian to make one scoped architecture recommendation for this project at its declared tier, without assuming absent capabilities or requiring tools whose triggers are unmet."
|
|
@@ -1,15 +1,12 @@
|
|
|
1
1
|
# ADR-NNN: Decision title
|
|
2
2
|
|
|
3
|
+
An ADR is an optional decision record for consequential architecture choices — including deliberate departures from a guardian recommendation. Nothing gates on it; it exists so future readers know the decision was deliberate, who owns it, and when to revisit it.
|
|
4
|
+
|
|
3
5
|
- Status: proposed | accepted | superseded | rejected
|
|
4
6
|
- Date: YYYY-MM-DD
|
|
5
|
-
-
|
|
6
|
-
-
|
|
7
|
-
-
|
|
8
|
-
- Control-IDs: comma-separated exact checker/manual control IDs, or `all` for a rule-level exception that omits the profile controls list
|
|
9
|
-
- Exception-ID: profile exception ID or `none`
|
|
10
|
-
- Foundation-Deviation-Acknowledged: true | false
|
|
11
|
-
- Review-Date: YYYY-MM-DD | none
|
|
12
|
-
- Review-Event: concrete event | none
|
|
7
|
+
- Owner: accountable person
|
|
8
|
+
- Related-Principles: canonical rule IDs this decision touches, or `none`
|
|
9
|
+
- Revisit: YYYY-MM-DD or a concrete event, or `none`
|
|
13
10
|
|
|
14
11
|
## Context and facts
|
|
15
12
|
|
|
@@ -17,24 +14,12 @@ Separate observed facts, constraints, assumptions, preferences and prior accepte
|
|
|
17
14
|
|
|
18
15
|
## Decision and rationale
|
|
19
16
|
|
|
20
|
-
State the primary decision, ownership, boundaries and why it fits. State the rejected alternative and reason.
|
|
21
|
-
|
|
22
|
-
## Risks and accepted deviation
|
|
23
|
-
|
|
24
|
-
Describe each risk, who accepts it, affected paths/tenants/data, and why the foundation recommendation remains unmet.
|
|
25
|
-
|
|
26
|
-
## Compensating controls
|
|
27
|
-
|
|
28
|
-
Map preventive, detective and recovery controls to each risk. Do not claim an untested control works.
|
|
29
|
-
|
|
30
|
-
## Verification
|
|
31
|
-
|
|
32
|
-
List static sentinels, declared controls, reproduced tests, and `NOT VERIFIED` environment behavior with reason, risk, owner and next action.
|
|
17
|
+
State the primary decision, ownership, boundaries and why it fits. State the rejected alternative and the reason — including, for any new moving service, the trigger that justifies it.
|
|
33
18
|
|
|
34
|
-
##
|
|
19
|
+
## Risks
|
|
35
20
|
|
|
36
|
-
Describe
|
|
21
|
+
Describe each accepted risk, who accepts it, and what is affected. If this departs from a guardian recommendation, say so plainly; the guardian will keep reporting it as accepted risk in reviews.
|
|
37
22
|
|
|
38
|
-
##
|
|
23
|
+
## Verification and rollback
|
|
39
24
|
|
|
40
|
-
|
|
25
|
+
What evidence supports the decision (label unverified claims honestly), how it would be rolled back or migrated away from, and any irreversible steps.
|
|
@@ -1,20 +1,10 @@
|
|
|
1
1
|
{
|
|
2
|
-
"
|
|
3
|
-
"
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
"
|
|
7
|
-
"
|
|
8
|
-
"
|
|
9
|
-
|
|
10
|
-
"sandbox": { "status": "disabled", "ownership": "not-applicable" },
|
|
11
|
-
"connectors": { "status": "disabled", "ownership": "not-applicable" },
|
|
12
|
-
"knowledge": { "status": "disabled", "ownership": "not-applicable" },
|
|
13
|
-
"modelRouting": { "status": "disabled", "ownership": "not-applicable" },
|
|
14
|
-
"enterpriseIdentity": { "status": "disabled", "ownership": "not-applicable" },
|
|
15
|
-
"realtime": { "status": "disabled", "ownership": "not-applicable" },
|
|
16
|
-
"notifications": { "status": "disabled", "ownership": "not-applicable" },
|
|
17
|
-
"secrets": { "status": "enabled", "ownership": "owned", "versions": { "openbao": "2.3.2" }, "placement": "external-service", "sourceRoots": ["infra/secrets"], "controls": { "provider": "openbao" } }
|
|
18
|
-
},
|
|
19
|
-
"exceptions": []
|
|
2
|
+
"project": { "name": "example-product", "kind": "saas", "tier": "production", "tenancy": "multi-tenant-shared-schema" },
|
|
3
|
+
"hosting": "cloudflare-opennext",
|
|
4
|
+
"capabilities": ["web", "jobs"],
|
|
5
|
+
"notes": [
|
|
6
|
+
"Better Auth is the identity library",
|
|
7
|
+
"PostgreSQL is the system of record; RLS forced on tenant tables",
|
|
8
|
+
"Secrets live in the platform's managed secret store (trigger review before enterprise tier)"
|
|
9
|
+
]
|
|
20
10
|
}
|
|
@@ -1,25 +1,13 @@
|
|
|
1
1
|
{
|
|
2
|
-
"schemaVersion":
|
|
3
|
-
"
|
|
4
|
-
"
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
"
|
|
8
|
-
"
|
|
2
|
+
"schemaVersion": 4,
|
|
3
|
+
"foundationVersion": "0.4.0",
|
|
4
|
+
"project": {
|
|
5
|
+
"name": "REQUIRED-CONFIRMED-PROJECT-NAME",
|
|
6
|
+
"kind": "REQUIRED-CONFIRMED-KIND",
|
|
7
|
+
"tier": "REQUIRED-CONFIRMED-TIER",
|
|
8
|
+
"tenancy": "REQUIRED-CONFIRMED-TENANCY"
|
|
9
9
|
},
|
|
10
|
-
"
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
"agents": { "status": "disabled", "ownership": "not-applicable" },
|
|
14
|
-
"jobs": { "status": "disabled", "ownership": "not-applicable" },
|
|
15
|
-
"sandbox": { "status": "disabled", "ownership": "not-applicable" },
|
|
16
|
-
"connectors": { "status": "disabled", "ownership": "not-applicable" },
|
|
17
|
-
"knowledge": { "status": "disabled", "ownership": "not-applicable" },
|
|
18
|
-
"modelRouting": { "status": "disabled", "ownership": "not-applicable" },
|
|
19
|
-
"enterpriseIdentity": { "status": "disabled", "ownership": "not-applicable" },
|
|
20
|
-
"realtime": { "status": "disabled", "ownership": "not-applicable" },
|
|
21
|
-
"notifications": { "status": "disabled", "ownership": "not-applicable" },
|
|
22
|
-
"secrets": { "status": "disabled", "ownership": "not-applicable" }
|
|
23
|
-
},
|
|
24
|
-
"exceptions": []
|
|
10
|
+
"hosting": "REQUIRED-CONFIRMED-HOSTING",
|
|
11
|
+
"capabilities": [],
|
|
12
|
+
"notes": []
|
|
25
13
|
}
|
|
@@ -1,213 +1,31 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
3
|
"$id": "https://raw.githubusercontent.com/vegastack/vegastack-skills/main/skills/arch-guardian/assets/architecture-profile.schema.json",
|
|
4
|
-
"title": "VegaStack Architecture Profile
|
|
4
|
+
"title": "VegaStack Architecture Profile v4",
|
|
5
|
+
"description": "Slim advisor memory: confirmed project facts, the declared tier, and the enabled capability list. Versions are read from lockfiles and manifests at advice time, never duplicated here.",
|
|
5
6
|
"type": "object",
|
|
6
7
|
"additionalProperties": false,
|
|
7
|
-
"required": ["schemaVersion", "
|
|
8
|
-
"$defs": {
|
|
9
|
-
"exactVersion": { "type": "string", "pattern": "^[0-9]+\\.[0-9]+(?:\\.[0-9]+)?(?:-[0-9A-Za-z.-]+)?(?:\\+[0-9A-Za-z.-]+)?$" },
|
|
10
|
-
"relativePath": { "type": "string", "minLength": 1, "pattern": "^(?!/)(?!.*(?:^|/)\\.\\.(?:/|$))(?!.*\\\\).+$" },
|
|
11
|
-
"nonEmptyStrings": { "type": "array", "minItems": 1, "uniqueItems": true, "items": { "type": "string", "minLength": 1 } },
|
|
12
|
-
"serviceContract": {
|
|
13
|
-
"type": "object",
|
|
14
|
-
"additionalProperties": false,
|
|
15
|
-
"required": ["ownerService", "contract", "version", "tenantSecurityBoundary", "identityAudience", "dataResidency", "sloRecovery", "incidentOwner", "compatibility", "migrationExit"],
|
|
16
|
-
"properties": {
|
|
17
|
-
"ownerService": { "type": "string", "minLength": 1 },
|
|
18
|
-
"contract": { "type": "string", "minLength": 1 },
|
|
19
|
-
"version": { "$ref": "#/$defs/exactVersion" },
|
|
20
|
-
"tenantSecurityBoundary": { "type": "string", "minLength": 1 },
|
|
21
|
-
"identityAudience": { "type": "string", "minLength": 1 },
|
|
22
|
-
"dataResidency": { "type": "string", "minLength": 1 },
|
|
23
|
-
"sloRecovery": { "type": "string", "minLength": 1 },
|
|
24
|
-
"incidentOwner": { "type": "string", "minLength": 1 },
|
|
25
|
-
"compatibility": { "type": "string", "minLength": 1 },
|
|
26
|
-
"migrationExit": { "type": "string", "minLength": 1 }
|
|
27
|
-
}
|
|
28
|
-
},
|
|
29
|
-
"removal": {
|
|
30
|
-
"type": "object",
|
|
31
|
-
"additionalProperties": false,
|
|
32
|
-
"required": ["durableData", "credentials", "queues", "contracts", "owner", "verification", "rollback"],
|
|
33
|
-
"properties": {
|
|
34
|
-
"durableData": { "type": "string", "minLength": 1 },
|
|
35
|
-
"credentials": { "type": "string", "minLength": 1 },
|
|
36
|
-
"queues": { "type": "string", "minLength": 1 },
|
|
37
|
-
"contracts": { "type": "string", "minLength": 1 },
|
|
38
|
-
"owner": { "type": "string", "minLength": 1 },
|
|
39
|
-
"verification": { "type": "string", "minLength": 1 },
|
|
40
|
-
"rollback": { "type": "string", "minLength": 1 }
|
|
41
|
-
}
|
|
42
|
-
},
|
|
43
|
-
"capability": {
|
|
44
|
-
"type": "object",
|
|
45
|
-
"additionalProperties": false,
|
|
46
|
-
"required": ["status", "ownership"],
|
|
47
|
-
"properties": {
|
|
48
|
-
"status": { "enum": ["enabled", "disabled"] },
|
|
49
|
-
"ownership": { "enum": ["owned", "shared-managed", "external-managed", "not-applicable"] },
|
|
50
|
-
"versions": {
|
|
51
|
-
"type": "object",
|
|
52
|
-
"minProperties": 1,
|
|
53
|
-
"propertyNames": { "pattern": "^[A-Za-z][A-Za-z0-9]*$" },
|
|
54
|
-
"additionalProperties": { "$ref": "#/$defs/exactVersion" }
|
|
55
|
-
},
|
|
56
|
-
"placement": { "type": "string", "minLength": 1 },
|
|
57
|
-
"sourceRoots": { "type": "array", "minItems": 1, "uniqueItems": true, "items": { "$ref": "#/$defs/relativePath" } },
|
|
58
|
-
"contract": { "$ref": "#/$defs/serviceContract" },
|
|
59
|
-
"controls": { "type": "object", "additionalProperties": { "type": ["string", "boolean", "number", "array"], "items": { "type": "string" } } },
|
|
60
|
-
"transitionFrom": { "enum": ["enabled", "disabled"] },
|
|
61
|
-
"removal": { "$ref": "#/$defs/removal" }
|
|
62
|
-
},
|
|
63
|
-
"allOf": [
|
|
64
|
-
{
|
|
65
|
-
"if": { "properties": { "status": { "const": "enabled" } }, "required": ["status"] },
|
|
66
|
-
"then": { "required": ["versions", "placement"], "properties": { "ownership": { "enum": ["owned", "shared-managed", "external-managed"] } } }
|
|
67
|
-
},
|
|
68
|
-
{
|
|
69
|
-
"if": { "properties": { "status": { "const": "disabled" } }, "required": ["status"] },
|
|
70
|
-
"then": { "properties": { "ownership": { "const": "not-applicable" } } }
|
|
71
|
-
},
|
|
72
|
-
{
|
|
73
|
-
"if": { "properties": { "status": { "const": "enabled" }, "ownership": { "const": "owned" } }, "required": ["status", "ownership"] },
|
|
74
|
-
"then": { "required": ["sourceRoots"] }
|
|
75
|
-
},
|
|
76
|
-
{
|
|
77
|
-
"if": { "properties": { "ownership": { "enum": ["shared-managed", "external-managed"] } }, "required": ["ownership"] },
|
|
78
|
-
"then": { "required": ["contract"], "not": { "required": ["sourceRoots"] } }
|
|
79
|
-
},
|
|
80
|
-
{
|
|
81
|
-
"if": { "properties": { "status": { "const": "disabled" }, "transitionFrom": { "const": "enabled" } }, "required": ["status", "transitionFrom"] },
|
|
82
|
-
"then": { "required": ["removal"] }
|
|
83
|
-
}
|
|
84
|
-
]
|
|
85
|
-
},
|
|
86
|
-
"exception": {
|
|
87
|
-
"type": "object",
|
|
88
|
-
"additionalProperties": false,
|
|
89
|
-
"required": ["id", "ruleId", "paths", "adr", "projectOwner", "status", "verificationType", "rationale", "decision", "risks", "compensatingControls", "verification", "rollbackOrMigration", "review", "foundationDeviationAcknowledged"],
|
|
90
|
-
"properties": {
|
|
91
|
-
"id": { "type": "string", "pattern": "^EXC-[0-9]{3,}$" },
|
|
92
|
-
"ruleId": { "type": "string", "pattern": "^[A-Z]+-[0-9]{3}$" },
|
|
93
|
-
"controls": { "$ref": "#/$defs/nonEmptyStrings" },
|
|
94
|
-
"paths": { "type": "array", "minItems": 1, "uniqueItems": true, "items": { "$ref": "#/$defs/relativePath" } },
|
|
95
|
-
"adr": { "$ref": "#/$defs/relativePath" },
|
|
96
|
-
"projectOwner": { "type": "string", "minLength": 1 },
|
|
97
|
-
"status": { "enum": ["active", "withdrawn"] },
|
|
98
|
-
"verificationType": { "enum": ["static-sentinel", "manual-qualification"] },
|
|
99
|
-
"rationale": { "type": "string", "minLength": 1 },
|
|
100
|
-
"decision": { "type": "string", "minLength": 1 },
|
|
101
|
-
"risks": { "$ref": "#/$defs/nonEmptyStrings" },
|
|
102
|
-
"compensatingControls": { "$ref": "#/$defs/nonEmptyStrings" },
|
|
103
|
-
"verification": { "$ref": "#/$defs/nonEmptyStrings" },
|
|
104
|
-
"rollbackOrMigration": { "type": "string", "minLength": 1 },
|
|
105
|
-
"review": {
|
|
106
|
-
"oneOf": [
|
|
107
|
-
{ "type": "object", "additionalProperties": false, "required": ["date"], "properties": { "date": { "type": "string", "format": "date" } } },
|
|
108
|
-
{ "type": "object", "additionalProperties": false, "required": ["event"], "properties": { "event": { "type": "string", "minLength": 1 } } }
|
|
109
|
-
]
|
|
110
|
-
},
|
|
111
|
-
"foundationDeviationAcknowledged": { "const": true }
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
},
|
|
8
|
+
"required": ["schemaVersion", "project", "hosting", "capabilities"],
|
|
115
9
|
"properties": {
|
|
116
|
-
"schemaVersion": { "const":
|
|
117
|
-
"
|
|
118
|
-
"foundation": {
|
|
119
|
-
"type": "object",
|
|
120
|
-
"additionalProperties": false,
|
|
121
|
-
"required": ["version", "baseline", "adoption"],
|
|
122
|
-
"properties": {
|
|
123
|
-
"version": { "const": "0.3.0" },
|
|
124
|
-
"baseline": { "type": "string", "minLength": 1 },
|
|
125
|
-
"adoption": { "enum": ["supported", "candidate", "deprecated"] }
|
|
126
|
-
}
|
|
127
|
-
},
|
|
10
|
+
"schemaVersion": { "const": 4 },
|
|
11
|
+
"foundationVersion": { "type": "string", "minLength": 1 },
|
|
128
12
|
"project": {
|
|
129
13
|
"type": "object",
|
|
130
14
|
"additionalProperties": false,
|
|
131
|
-
"required": ["name", "kind", "
|
|
15
|
+
"required": ["name", "kind", "tier", "tenancy"],
|
|
132
16
|
"properties": {
|
|
133
17
|
"name": { "type": "string", "minLength": 1 },
|
|
134
|
-
"kind": { "enum": ["saas
|
|
135
|
-
"
|
|
136
|
-
"access": { "enum": ["public", "authenticated", "internal", "mixed"] },
|
|
18
|
+
"kind": { "enum": ["saas", "internal-tool", "client-site", "api", "package"] },
|
|
19
|
+
"tier": { "enum": ["prototype", "production", "enterprise"] },
|
|
137
20
|
"tenancy": { "enum": ["none", "single-tenant", "multi-tenant-shared-schema", "multi-tenant-isolated"] }
|
|
138
21
|
}
|
|
139
22
|
},
|
|
140
|
-
"
|
|
141
|
-
"type": "object",
|
|
142
|
-
"additionalProperties": false,
|
|
143
|
-
"required": ["production", "localDevelopment"],
|
|
144
|
-
"properties": {
|
|
145
|
-
"production": {
|
|
146
|
-
"type": "object",
|
|
147
|
-
"additionalProperties": false,
|
|
148
|
-
"required": ["hosting"],
|
|
149
|
-
"properties": { "hosting": { "enum": ["self-hosted", "vercel", "cloudflare-opennext", "external", "none"] }, "region": { "type": "string", "minLength": 1 } }
|
|
150
|
-
},
|
|
151
|
-
"localDevelopment": {
|
|
152
|
-
"type": "object",
|
|
153
|
-
"additionalProperties": false,
|
|
154
|
-
"required": ["trusted", "allowances"],
|
|
155
|
-
"properties": { "trusted": { "const": true }, "allowances": { "type": "array", "uniqueItems": true, "items": { "enum": ["local-workflow-world", "local-secrets", "local-unsandboxed-code", "single-process"] } } }
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
},
|
|
23
|
+
"hosting": { "enum": ["self-hosted", "vercel", "cloudflare-opennext", "external", "none"] },
|
|
159
24
|
"capabilities": {
|
|
160
|
-
"type": "
|
|
161
|
-
"
|
|
162
|
-
"
|
|
163
|
-
"properties": {
|
|
164
|
-
"webControlPlane": { "$ref": "#/$defs/capability" },
|
|
165
|
-
"flutter": { "$ref": "#/$defs/capability" },
|
|
166
|
-
"agents": { "$ref": "#/$defs/capability" },
|
|
167
|
-
"jobs": { "$ref": "#/$defs/capability" },
|
|
168
|
-
"sandbox": { "$ref": "#/$defs/capability" },
|
|
169
|
-
"connectors": { "$ref": "#/$defs/capability" },
|
|
170
|
-
"knowledge": { "$ref": "#/$defs/capability" },
|
|
171
|
-
"modelRouting": { "$ref": "#/$defs/capability" },
|
|
172
|
-
"enterpriseIdentity": { "$ref": "#/$defs/capability" },
|
|
173
|
-
"realtime": { "$ref": "#/$defs/capability" },
|
|
174
|
-
"notifications": { "$ref": "#/$defs/capability" },
|
|
175
|
-
"secrets": { "$ref": "#/$defs/capability" }
|
|
176
|
-
}
|
|
177
|
-
},
|
|
178
|
-
"data": {
|
|
179
|
-
"type": "object",
|
|
180
|
-
"additionalProperties": false,
|
|
181
|
-
"required": ["classes"],
|
|
182
|
-
"properties": {
|
|
183
|
-
"classes": {
|
|
184
|
-
"type": "array",
|
|
185
|
-
"minItems": 1,
|
|
186
|
-
"items": {
|
|
187
|
-
"type": "object",
|
|
188
|
-
"additionalProperties": false,
|
|
189
|
-
"required": ["name"],
|
|
190
|
-
"properties": {
|
|
191
|
-
"name": { "enum": ["public", "internal", "confidential", "restricted"] },
|
|
192
|
-
"residency": { "type": "string", "minLength": 1 },
|
|
193
|
-
"retention": { "type": "string", "minLength": 1 },
|
|
194
|
-
"owner": { "type": "string", "minLength": 1 }
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
},
|
|
200
|
-
"objectives": {
|
|
201
|
-
"type": "object",
|
|
202
|
-
"additionalProperties": false,
|
|
203
|
-
"properties": {
|
|
204
|
-
"availability": { "type": "string", "minLength": 1 },
|
|
205
|
-
"latency": { "type": "string", "minLength": 1 },
|
|
206
|
-
"rpoMinutes": { "type": "number", "minimum": 0 },
|
|
207
|
-
"rtoMinutes": { "type": "number", "minimum": 0 }
|
|
208
|
-
},
|
|
209
|
-
"minProperties": 1
|
|
25
|
+
"type": "array",
|
|
26
|
+
"uniqueItems": true,
|
|
27
|
+
"items": { "enum": ["web", "flutter", "agents", "jobs", "sandbox", "connectors", "knowledge", "models", "realtime", "notifications", "enterprise-identity"] }
|
|
210
28
|
},
|
|
211
|
-
"
|
|
29
|
+
"notes": { "type": "array", "items": { "type": "string", "minLength": 1 } }
|
|
212
30
|
}
|
|
213
31
|
}
|