@maadb/core 0.0.1 → 0.7.10-rc.3
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/LICENSE +21 -0
- package/README.md +371 -3
- package/dist/architect.d.ts +2 -0
- package/dist/architect.d.ts.map +1 -0
- package/dist/architect.js +273 -0
- package/dist/architect.js.map +1 -0
- package/dist/auth/resolve.d.ts +36 -0
- package/dist/auth/resolve.d.ts.map +1 -0
- package/dist/auth/resolve.js +77 -0
- package/dist/auth/resolve.js.map +1 -0
- package/dist/auth/token-store.d.ts +82 -0
- package/dist/auth/token-store.d.ts.map +1 -0
- package/dist/auth/token-store.js +464 -0
- package/dist/auth/token-store.js.map +1 -0
- package/dist/auth/types.d.ts +75 -0
- package/dist/auth/types.d.ts.map +1 -0
- package/dist/auth/types.js +15 -0
- package/dist/auth/types.js.map +1 -0
- package/dist/backend/adapter.d.ts +57 -0
- package/dist/backend/adapter.d.ts.map +1 -0
- package/dist/backend/adapter.js +6 -0
- package/dist/backend/adapter.js.map +1 -0
- package/dist/backend/index.d.ts +3 -0
- package/dist/backend/index.d.ts.map +1 -0
- package/dist/backend/index.js +2 -0
- package/dist/backend/index.js.map +1 -0
- package/dist/backend/sqlite/index.d.ts +63 -0
- package/dist/backend/sqlite/index.d.ts.map +1 -0
- package/dist/backend/sqlite/index.js +521 -0
- package/dist/backend/sqlite/index.js.map +1 -0
- package/dist/backend/sqlite/schema.d.ts +2 -0
- package/dist/backend/sqlite/schema.d.ts.map +1 -0
- package/dist/backend/sqlite/schema.js +88 -0
- package/dist/backend/sqlite/schema.js.map +1 -0
- package/dist/claude-md.d.ts +2 -0
- package/dist/claude-md.d.ts.map +1 -0
- package/dist/claude-md.js +97 -0
- package/dist/claude-md.js.map +1 -0
- package/dist/cli/commands/audit.d.ts +4 -0
- package/dist/cli/commands/audit.d.ts.map +1 -0
- package/dist/cli/commands/audit.js +39 -0
- package/dist/cli/commands/audit.js.map +1 -0
- package/dist/cli/commands/auth.d.ts +8 -0
- package/dist/cli/commands/auth.d.ts.map +1 -0
- package/dist/cli/commands/auth.js +242 -0
- package/dist/cli/commands/auth.js.map +1 -0
- package/dist/cli/commands/discover.d.ts +5 -0
- package/dist/cli/commands/discover.d.ts.map +1 -0
- package/dist/cli/commands/discover.js +48 -0
- package/dist/cli/commands/discover.js.map +1 -0
- package/dist/cli/commands/maintain.d.ts +6 -0
- package/dist/cli/commands/maintain.d.ts.map +1 -0
- package/dist/cli/commands/maintain.js +168 -0
- package/dist/cli/commands/maintain.js.map +1 -0
- package/dist/cli/commands/read.d.ts +7 -0
- package/dist/cli/commands/read.d.ts.map +1 -0
- package/dist/cli/commands/read.js +139 -0
- package/dist/cli/commands/read.js.map +1 -0
- package/dist/cli/commands/write.d.ts +4 -0
- package/dist/cli/commands/write.d.ts.map +1 -0
- package/dist/cli/commands/write.js +99 -0
- package/dist/cli/commands/write.js.map +1 -0
- package/dist/cli/helpers.d.ts +8 -0
- package/dist/cli/helpers.d.ts.map +1 -0
- package/dist/cli/helpers.js +17 -0
- package/dist/cli/helpers.js.map +1 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +296 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +7 -0
- package/dist/cli.js.map +1 -0
- package/dist/engine/audit.d.ts +15 -0
- package/dist/engine/audit.d.ts.map +1 -0
- package/dist/engine/audit.js +42 -0
- package/dist/engine/audit.js.map +1 -0
- package/dist/engine/backup.d.ts +9 -0
- package/dist/engine/backup.d.ts.map +1 -0
- package/dist/engine/backup.js +100 -0
- package/dist/engine/backup.js.map +1 -0
- package/dist/engine/composites.d.ts +6 -0
- package/dist/engine/composites.d.ts.map +1 -0
- package/dist/engine/composites.js +102 -0
- package/dist/engine/composites.js.map +1 -0
- package/dist/engine/context.d.ts +47 -0
- package/dist/engine/context.d.ts.map +1 -0
- package/dist/engine/context.js +55 -0
- package/dist/engine/context.js.map +1 -0
- package/dist/engine/docid-safe.d.ts +8 -0
- package/dist/engine/docid-safe.d.ts.map +1 -0
- package/dist/engine/docid-safe.js +0 -0
- package/dist/engine/docid-safe.js.map +1 -0
- package/dist/engine/helpers.d.ts +8 -0
- package/dist/engine/helpers.d.ts.map +1 -0
- package/dist/engine/helpers.js +102 -0
- package/dist/engine/helpers.js.map +1 -0
- package/dist/engine/index.d.ts +215 -0
- package/dist/engine/index.d.ts.map +1 -0
- package/dist/engine/index.js +494 -0
- package/dist/engine/index.js.map +1 -0
- package/dist/engine/indexing.d.ts +14 -0
- package/dist/engine/indexing.d.ts.map +1 -0
- package/dist/engine/indexing.js +225 -0
- package/dist/engine/indexing.js.map +1 -0
- package/dist/engine/journal.d.ts +32 -0
- package/dist/engine/journal.d.ts.map +1 -0
- package/dist/engine/journal.js +111 -0
- package/dist/engine/journal.js.map +1 -0
- package/dist/engine/logger.d.ts +19 -0
- package/dist/engine/logger.d.ts.map +1 -0
- package/dist/engine/logger.js +40 -0
- package/dist/engine/logger.js.map +1 -0
- package/dist/engine/maintenance.d.ts +15 -0
- package/dist/engine/maintenance.d.ts.map +1 -0
- package/dist/engine/maintenance.js +87 -0
- package/dist/engine/maintenance.js.map +1 -0
- package/dist/engine/mutex.d.ts +24 -0
- package/dist/engine/mutex.d.ts.map +1 -0
- package/dist/engine/mutex.js +50 -0
- package/dist/engine/mutex.js.map +1 -0
- package/dist/engine/pathguard.d.ts +16 -0
- package/dist/engine/pathguard.d.ts.map +1 -0
- package/dist/engine/pathguard.js +41 -0
- package/dist/engine/pathguard.js.map +1 -0
- package/dist/engine/reads.d.ts +25 -0
- package/dist/engine/reads.d.ts.map +1 -0
- package/dist/engine/reads.js +904 -0
- package/dist/engine/reads.js.map +1 -0
- package/dist/engine/types.d.ts +396 -0
- package/dist/engine/types.d.ts.map +1 -0
- package/dist/engine/types.js +5 -0
- package/dist/engine/types.js.map +1 -0
- package/dist/engine/writes.d.ts +10 -0
- package/dist/engine/writes.d.ts.map +1 -0
- package/dist/engine/writes.js +606 -0
- package/dist/engine/writes.js.map +1 -0
- package/dist/engine.d.ts +3 -0
- package/dist/engine.d.ts.map +1 -0
- package/dist/engine.js +6 -0
- package/dist/engine.js.map +1 -0
- package/dist/errors.d.ts +20 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +17 -0
- package/dist/errors.js.map +1 -0
- package/dist/extractor/fields.d.ts +3 -0
- package/dist/extractor/fields.d.ts.map +1 -0
- package/dist/extractor/fields.js +58 -0
- package/dist/extractor/fields.js.map +1 -0
- package/dist/extractor/index.d.ts +7 -0
- package/dist/extractor/index.d.ts.map +1 -0
- package/dist/extractor/index.js +22 -0
- package/dist/extractor/index.js.map +1 -0
- package/dist/extractor/normalizers.d.ts +22 -0
- package/dist/extractor/normalizers.d.ts.map +1 -0
- package/dist/extractor/normalizers.js +250 -0
- package/dist/extractor/normalizers.js.map +1 -0
- package/dist/extractor/objects.d.ts +3 -0
- package/dist/extractor/objects.d.ts.map +1 -0
- package/dist/extractor/objects.js +33 -0
- package/dist/extractor/objects.js.map +1 -0
- package/dist/extractor/relationships.d.ts +3 -0
- package/dist/extractor/relationships.d.ts.map +1 -0
- package/dist/extractor/relationships.js +58 -0
- package/dist/extractor/relationships.js.map +1 -0
- package/dist/git/commit.d.ts +63 -0
- package/dist/git/commit.d.ts.map +1 -0
- package/dist/git/commit.js +161 -0
- package/dist/git/commit.js.map +1 -0
- package/dist/git/diff.d.ts +4 -0
- package/dist/git/diff.d.ts.map +1 -0
- package/dist/git/diff.js +56 -0
- package/dist/git/diff.js.map +1 -0
- package/dist/git/index.d.ts +63 -0
- package/dist/git/index.d.ts.map +1 -0
- package/dist/git/index.js +151 -0
- package/dist/git/index.js.map +1 -0
- package/dist/git/log.d.ts +13 -0
- package/dist/git/log.d.ts.map +1 -0
- package/dist/git/log.js +116 -0
- package/dist/git/log.js.map +1 -0
- package/dist/git/snapshot.d.ts +4 -0
- package/dist/git/snapshot.d.ts.map +1 -0
- package/dist/git/snapshot.js +65 -0
- package/dist/git/snapshot.js.map +1 -0
- package/dist/instance/config.d.ts +19 -0
- package/dist/instance/config.d.ts.map +1 -0
- package/dist/instance/config.js +107 -0
- package/dist/instance/config.js.map +1 -0
- package/dist/instance/pool.d.ts +138 -0
- package/dist/instance/pool.d.ts.map +1 -0
- package/dist/instance/pool.js +335 -0
- package/dist/instance/pool.js.map +1 -0
- package/dist/instance/session.d.ts +140 -0
- package/dist/instance/session.d.ts.map +1 -0
- package/dist/instance/session.js +267 -0
- package/dist/instance/session.js.map +1 -0
- package/dist/logging.d.ts +108 -0
- package/dist/logging.d.ts.map +1 -0
- package/dist/logging.js +120 -0
- package/dist/logging.js.map +1 -0
- package/dist/maad-md.d.ts +11 -0
- package/dist/maad-md.d.ts.map +1 -0
- package/dist/maad-md.js +252 -0
- package/dist/maad-md.js.map +1 -0
- package/dist/mcp/bulk-cap.d.ts +10 -0
- package/dist/mcp/bulk-cap.d.ts.map +1 -0
- package/dist/mcp/bulk-cap.js +37 -0
- package/dist/mcp/bulk-cap.js.map +1 -0
- package/dist/mcp/config.d.ts +18 -0
- package/dist/mcp/config.d.ts.map +1 -0
- package/dist/mcp/config.js +20 -0
- package/dist/mcp/config.js.map +1 -0
- package/dist/mcp/ctx.d.ts +17 -0
- package/dist/mcp/ctx.d.ts.map +1 -0
- package/dist/mcp/ctx.js +7 -0
- package/dist/mcp/ctx.js.map +1 -0
- package/dist/mcp/guardrails.d.ts +42 -0
- package/dist/mcp/guardrails.d.ts.map +1 -0
- package/dist/mcp/guardrails.js +58 -0
- package/dist/mcp/guardrails.js.map +1 -0
- package/dist/mcp/idempotency.d.ts +69 -0
- package/dist/mcp/idempotency.d.ts.map +1 -0
- package/dist/mcp/idempotency.js +168 -0
- package/dist/mcp/idempotency.js.map +1 -0
- package/dist/mcp/instance-reload.d.ts +23 -0
- package/dist/mcp/instance-reload.d.ts.map +1 -0
- package/dist/mcp/instance-reload.js +126 -0
- package/dist/mcp/instance-reload.js.map +1 -0
- package/dist/mcp/kinds.d.ts +22 -0
- package/dist/mcp/kinds.d.ts.map +1 -0
- package/dist/mcp/kinds.js +112 -0
- package/dist/mcp/kinds.js.map +1 -0
- package/dist/mcp/lifecycle.d.ts +8 -0
- package/dist/mcp/lifecycle.d.ts.map +1 -0
- package/dist/mcp/lifecycle.js +65 -0
- package/dist/mcp/lifecycle.js.map +1 -0
- package/dist/mcp/memory-pressure.d.ts +37 -0
- package/dist/mcp/memory-pressure.d.ts.map +1 -0
- package/dist/mcp/memory-pressure.js +179 -0
- package/dist/mcp/memory-pressure.js.map +1 -0
- package/dist/mcp/notifications.d.ts +87 -0
- package/dist/mcp/notifications.d.ts.map +1 -0
- package/dist/mcp/notifications.js +154 -0
- package/dist/mcp/notifications.js.map +1 -0
- package/dist/mcp/query-depth.d.ts +28 -0
- package/dist/mcp/query-depth.d.ts.map +1 -0
- package/dist/mcp/query-depth.js +43 -0
- package/dist/mcp/query-depth.js.map +1 -0
- package/dist/mcp/rate-limit.d.ts +60 -0
- package/dist/mcp/rate-limit.d.ts.map +1 -0
- package/dist/mcp/rate-limit.js +203 -0
- package/dist/mcp/rate-limit.js.map +1 -0
- package/dist/mcp/reload-signal.d.ts +13 -0
- package/dist/mcp/reload-signal.d.ts.map +1 -0
- package/dist/mcp/reload-signal.js +68 -0
- package/dist/mcp/reload-signal.js.map +1 -0
- package/dist/mcp/response.d.ts +109 -0
- package/dist/mcp/response.d.ts.map +1 -0
- package/dist/mcp/response.js +132 -0
- package/dist/mcp/response.js.map +1 -0
- package/dist/mcp/roles.d.ts +7 -0
- package/dist/mcp/roles.d.ts.map +1 -0
- package/dist/mcp/roles.js +57 -0
- package/dist/mcp/roles.js.map +1 -0
- package/dist/mcp/server.d.ts +33 -0
- package/dist/mcp/server.d.ts.map +1 -0
- package/dist/mcp/server.js +252 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/mcp/shutdown.d.ts +32 -0
- package/dist/mcp/shutdown.d.ts.map +1 -0
- package/dist/mcp/shutdown.js +130 -0
- package/dist/mcp/shutdown.js.map +1 -0
- package/dist/mcp/tools/audit.d.ts +4 -0
- package/dist/mcp/tools/audit.d.ts.map +1 -0
- package/dist/mcp/tools/audit.js +45 -0
- package/dist/mcp/tools/audit.js.map +1 -0
- package/dist/mcp/tools/auth.d.ts +4 -0
- package/dist/mcp/tools/auth.d.ts.map +1 -0
- package/dist/mcp/tools/auth.js +181 -0
- package/dist/mcp/tools/auth.js.map +1 -0
- package/dist/mcp/tools/backup.d.ts +4 -0
- package/dist/mcp/tools/backup.d.ts.map +1 -0
- package/dist/mcp/tools/backup.js +52 -0
- package/dist/mcp/tools/backup.js.map +1 -0
- package/dist/mcp/tools/discover.d.ts +4 -0
- package/dist/mcp/tools/discover.d.ts.map +1 -0
- package/dist/mcp/tools/discover.js +83 -0
- package/dist/mcp/tools/discover.js.map +1 -0
- package/dist/mcp/tools/instance.d.ts +15 -0
- package/dist/mcp/tools/instance.d.ts.map +1 -0
- package/dist/mcp/tools/instance.js +207 -0
- package/dist/mcp/tools/instance.js.map +1 -0
- package/dist/mcp/tools/maintain.d.ts +4 -0
- package/dist/mcp/tools/maintain.d.ts.map +1 -0
- package/dist/mcp/tools/maintain.js +123 -0
- package/dist/mcp/tools/maintain.js.map +1 -0
- package/dist/mcp/tools/read.d.ts +4 -0
- package/dist/mcp/tools/read.d.ts.map +1 -0
- package/dist/mcp/tools/read.js +304 -0
- package/dist/mcp/tools/read.js.map +1 -0
- package/dist/mcp/tools/write.d.ts +4 -0
- package/dist/mcp/tools/write.d.ts.map +1 -0
- package/dist/mcp/tools/write.js +342 -0
- package/dist/mcp/tools/write.js.map +1 -0
- package/dist/mcp/transport/auth.d.ts +41 -0
- package/dist/mcp/transport/auth.d.ts.map +1 -0
- package/dist/mcp/transport/auth.js +115 -0
- package/dist/mcp/transport/auth.js.map +1 -0
- package/dist/mcp/transport/http.d.ts +62 -0
- package/dist/mcp/transport/http.d.ts.map +1 -0
- package/dist/mcp/transport/http.js +357 -0
- package/dist/mcp/transport/http.js.map +1 -0
- package/dist/mcp/transport/pin.d.ts +15 -0
- package/dist/mcp/transport/pin.d.ts.map +1 -0
- package/dist/mcp/transport/pin.js +71 -0
- package/dist/mcp/transport/pin.js.map +1 -0
- package/dist/mcp/transport/telemetry.d.ts +79 -0
- package/dist/mcp/transport/telemetry.d.ts.map +1 -0
- package/dist/mcp/transport/telemetry.js +97 -0
- package/dist/mcp/transport/telemetry.js.map +1 -0
- package/dist/mcp/with-session.d.ts +26 -0
- package/dist/mcp/with-session.d.ts.map +1 -0
- package/dist/mcp/with-session.js +275 -0
- package/dist/mcp/with-session.js.map +1 -0
- package/dist/parser/annotations.d.ts +3 -0
- package/dist/parser/annotations.d.ts.map +1 -0
- package/dist/parser/annotations.js +41 -0
- package/dist/parser/annotations.js.map +1 -0
- package/dist/parser/blocks.d.ts +3 -0
- package/dist/parser/blocks.d.ts.map +1 -0
- package/dist/parser/blocks.js +101 -0
- package/dist/parser/blocks.js.map +1 -0
- package/dist/parser/frontmatter.d.ts +9 -0
- package/dist/parser/frontmatter.d.ts.map +1 -0
- package/dist/parser/frontmatter.js +33 -0
- package/dist/parser/frontmatter.js.map +1 -0
- package/dist/parser/index.d.ts +11 -0
- package/dist/parser/index.d.ts.map +1 -0
- package/dist/parser/index.js +54 -0
- package/dist/parser/index.js.map +1 -0
- package/dist/parser/matter.d.ts +3 -0
- package/dist/parser/matter.d.ts.map +1 -0
- package/dist/parser/matter.js +32 -0
- package/dist/parser/matter.js.map +1 -0
- package/dist/parser/tags.d.ts +3 -0
- package/dist/parser/tags.d.ts.map +1 -0
- package/dist/parser/tags.js +32 -0
- package/dist/parser/tags.js.map +1 -0
- package/dist/parser/verbatim.d.ts +4 -0
- package/dist/parser/verbatim.d.ts.map +1 -0
- package/dist/parser/verbatim.js +121 -0
- package/dist/parser/verbatim.js.map +1 -0
- package/dist/parser/yaml-profile.d.ts +4 -0
- package/dist/parser/yaml-profile.d.ts.map +1 -0
- package/dist/parser/yaml-profile.js +73 -0
- package/dist/parser/yaml-profile.js.map +1 -0
- package/dist/registry/index.d.ts +2 -0
- package/dist/registry/index.d.ts.map +1 -0
- package/dist/registry/index.js +2 -0
- package/dist/registry/index.js.map +1 -0
- package/dist/registry/loader.d.ts +4 -0
- package/dist/registry/loader.d.ts.map +1 -0
- package/dist/registry/loader.js +147 -0
- package/dist/registry/loader.js.map +1 -0
- package/dist/registry/types.d.ts +2 -0
- package/dist/registry/types.d.ts.map +1 -0
- package/dist/registry/types.js +5 -0
- package/dist/registry/types.js.map +1 -0
- package/dist/scanner.d.ts +57 -0
- package/dist/scanner.d.ts.map +1 -0
- package/dist/scanner.js +223 -0
- package/dist/scanner.js.map +1 -0
- package/dist/schema/index.d.ts +3 -0
- package/dist/schema/index.d.ts.map +1 -0
- package/dist/schema/index.js +3 -0
- package/dist/schema/index.js.map +1 -0
- package/dist/schema/loader.d.ts +4 -0
- package/dist/schema/loader.d.ts.map +1 -0
- package/dist/schema/loader.js +303 -0
- package/dist/schema/loader.js.map +1 -0
- package/dist/schema/precision.d.ts +6 -0
- package/dist/schema/precision.d.ts.map +1 -0
- package/dist/schema/precision.js +59 -0
- package/dist/schema/precision.js.map +1 -0
- package/dist/schema/validator.d.ts +21 -0
- package/dist/schema/validator.d.ts.map +1 -0
- package/dist/schema/validator.js +200 -0
- package/dist/schema/validator.js.map +1 -0
- package/dist/schema-md.d.ts +8 -0
- package/dist/schema-md.d.ts.map +1 -0
- package/dist/schema-md.js +98 -0
- package/dist/schema-md.js.map +1 -0
- package/dist/skill-files.d.ts +3 -0
- package/dist/skill-files.d.ts.map +1 -0
- package/dist/skill-files.js +362 -0
- package/dist/skill-files.js.map +1 -0
- package/dist/skills-scaffold.d.ts +10 -0
- package/dist/skills-scaffold.d.ts.map +1 -0
- package/dist/skills-scaffold.js +52 -0
- package/dist/skills-scaffold.js.map +1 -0
- package/dist/types.d.ts +309 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +111 -0
- package/dist/types.js.map +1 -0
- package/dist/writer/index.d.ts +7 -0
- package/dist/writer/index.d.ts.map +1 -0
- package/dist/writer/index.js +32 -0
- package/dist/writer/index.js.map +1 -0
- package/dist/writer/serializer.d.ts +4 -0
- package/dist/writer/serializer.d.ts.map +1 -0
- package/dist/writer/serializer.js +103 -0
- package/dist/writer/serializer.js.map +1 -0
- package/dist/writer/template.d.ts +3 -0
- package/dist/writer/template.d.ts.map +1 -0
- package/dist/writer/template.js +27 -0
- package/dist/writer/template.js.map +1 -0
- package/package.json +59 -7
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
// ============================================================================
|
|
2
|
+
// Architect Skill File — generated on init
|
|
3
|
+
// The MAAD Architect role: designs and deploys databases from requirements.
|
|
4
|
+
// Operates autonomously, agent-to-agent, or interactively.
|
|
5
|
+
// ============================================================================
|
|
6
|
+
export function generateArchitectSkill() {
|
|
7
|
+
return `# MAAD Architect
|
|
8
|
+
|
|
9
|
+
## Role
|
|
10
|
+
|
|
11
|
+
You are the MAAD Architect. Your job is to design, deploy, and maintain MAAD database instances. You receive requirements — from another agent, a system spec, or a human — and produce a working database.
|
|
12
|
+
|
|
13
|
+
You use MAAD MCP tools for all operations. You do not use shell commands.
|
|
14
|
+
|
|
15
|
+
## Operating Modes
|
|
16
|
+
|
|
17
|
+
Read the input and decide:
|
|
18
|
+
|
|
19
|
+
| Input quality | Mode | Behavior |
|
|
20
|
+
|---------------|------|----------|
|
|
21
|
+
| Full spec (types, fields, relationships defined) | **Autonomous** | Build immediately. Report when done. |
|
|
22
|
+
| Partial spec (business type + some requirements) | **Targeted questions** | Ask 2-5 specific questions to fill gaps, then build. |
|
|
23
|
+
| Vague request ("I need a CRM") | **Structured discovery** | Run discovery interview, propose structure, confirm, then build. |
|
|
24
|
+
|
|
25
|
+
Default to the most autonomous mode the input supports. Do not ask questions you can answer from domain knowledge.
|
|
26
|
+
|
|
27
|
+
## Discovery Interview
|
|
28
|
+
|
|
29
|
+
When you need more information, ask about the business — not about databases. The requester may be a human or another agent. Either way, ask in business terms.
|
|
30
|
+
|
|
31
|
+
**Round 1 — What is this?**
|
|
32
|
+
- What kind of business or operation?
|
|
33
|
+
- What is the core activity? (selling, servicing, managing cases, treating patients, etc.)
|
|
34
|
+
- Approximate scale? (employees, customers, transactions per day/month)
|
|
35
|
+
|
|
36
|
+
**Round 2 — What do you track?** (only ask what Round 1 didn't answer)
|
|
37
|
+
- Who are the main entities? (customers, patients, clients, members, etc.)
|
|
38
|
+
- What happens repeatedly? (orders, visits, jobs, sessions, etc.)
|
|
39
|
+
- What needs to be looked up later? (history, billing, communications, etc.)
|
|
40
|
+
|
|
41
|
+
**Round 3 — Relationships and special needs** (only if unclear)
|
|
42
|
+
- What connects to what? (customer has orders, case has notes, etc.)
|
|
43
|
+
- Any status workflows? (open → in progress → closed, etc.)
|
|
44
|
+
- Any compliance or audit requirements?
|
|
45
|
+
|
|
46
|
+
Stop asking when you have enough to design. Three rounds maximum.
|
|
47
|
+
|
|
48
|
+
## Domain Knowledge
|
|
49
|
+
|
|
50
|
+
Use these patterns to fill gaps without asking. When the requester says a business type, you already know the common structure.
|
|
51
|
+
|
|
52
|
+
### Service businesses (plumbing, HVAC, electrical, landscaping, cleaning)
|
|
53
|
+
- **Customers**: name, address, phone, email, type (residential/commercial), since date. Master.
|
|
54
|
+
- **Technicians/Staff**: name, phone, certifications, hire date, specialties. Master.
|
|
55
|
+
- **Jobs/Work Orders**: customer ref, technician ref, service type, scheduled date, status, location, amount. Master (individually tracked).
|
|
56
|
+
- **Job Notes/Updates**: append to job file. Dispatch updates, technician field notes, completion notes. Transaction.
|
|
57
|
+
- **Invoices**: customer ref, job ref, amount, status, due date, paid date. Master if <5K/yr, transaction if more.
|
|
58
|
+
- **Service Types/Catalog**: name, base rate, category, duration estimate. Master (small, stable).
|
|
59
|
+
- **Parts/Inventory**: name, SKU, cost, supplier, quantity. Master.
|
|
60
|
+
- Typical: 500-2000 customers, 2000-10000 jobs/yr, 5-50 staff.
|
|
61
|
+
|
|
62
|
+
### Professional services (legal, consulting, accounting, agencies)
|
|
63
|
+
- **Clients**: company name, industry, primary contact, since date, status. Master.
|
|
64
|
+
- **Contacts**: name, email, phone, role, client ref. Master.
|
|
65
|
+
- **Cases/Projects/Engagements**: client ref, type, status, assigned staff, opened/closed dates. Master.
|
|
66
|
+
- **Notes/Activity Log**: append to case/project file. Meetings, calls, filings, research. Transaction.
|
|
67
|
+
- **Billing/Time Entries**: append to case file or separate. Hours, rate, description, date. Transaction.
|
|
68
|
+
- **Documents/Filings**: per case, tracked as records with metadata. Master if individually referenced.
|
|
69
|
+
- Typical: 50-500 clients, 100-2000 cases/yr, 5-50 staff.
|
|
70
|
+
|
|
71
|
+
### Retail / E-commerce
|
|
72
|
+
- **Customers**: name, email, phone, address, tier, since date. Master.
|
|
73
|
+
- **Products**: name, SKU, price, category, supplier, stock. Master.
|
|
74
|
+
- **Orders**: customer ref, date, status, total, items. Master (individually tracked).
|
|
75
|
+
- **Order Items**: append to order or separate line items. Transaction if high volume.
|
|
76
|
+
- **Inventory Log**: append to product file. Stock changes, restocks, adjustments. Transaction.
|
|
77
|
+
- Typical: 1000-100000 customers, 5000-500000 orders/yr.
|
|
78
|
+
|
|
79
|
+
### Healthcare / Clinical
|
|
80
|
+
- **Patients**: name, DOB, contact, insurance, primary provider. Master.
|
|
81
|
+
- **Providers/Staff**: name, credentials, specialty, department. Master.
|
|
82
|
+
- **Visits/Encounters**: patient ref, provider ref, date, type, notes. Master if individually tracked.
|
|
83
|
+
- **Clinical Notes**: append to patient file or visit file. Transaction.
|
|
84
|
+
- **Prescriptions**: patient ref, medication, dosage, provider, date. Master or transaction depending on volume.
|
|
85
|
+
- **Billing**: patient ref, visit ref, codes, amount, status. Master.
|
|
86
|
+
- Typical: 500-50000 patients, 2000-100000 visits/yr.
|
|
87
|
+
|
|
88
|
+
### General rules (apply to all domains)
|
|
89
|
+
- Entities with names/identities = master (customers, staff, products, cases)
|
|
90
|
+
- Entries that accumulate over time under a parent = transaction (notes, logs, events)
|
|
91
|
+
- If >1000 records/year → transaction pattern (append to parent file)
|
|
92
|
+
- If <1000 records/year → master pattern (one file per record)
|
|
93
|
+
- Status fields are almost always enums
|
|
94
|
+
- Date fields: declare \`store_precision\` for the minimum precision the schema expects (\`year\` / \`month\` / \`day\` / \`hour\` / \`minute\` / \`second\` / \`millisecond\`). Default \`on_coarser: warn\` surfaces drift without blocking the write; \`error\` opts into strict rejection. \`display_precision\` is a consumer-side rendering hint; the engine never enforces it. Pick per field meaning: identity dates (birthdays, since_date) = \`day\`; event timestamps (opened_at, logged_at) = \`second\` or \`millisecond\`. See \`_skills/schema-guide.md\` for the full contract.
|
|
95
|
+
- Money fields use amount type ("1250.00 USD")
|
|
96
|
+
- Cross-entity links use ref type with target
|
|
97
|
+
- Writes return \`_meta.warnings[]\` when values trip soft-validation (precision drift, etc.). Surface these to the caller instead of silently ignoring — agents should self-correct on warnings, not just on errors.
|
|
98
|
+
|
|
99
|
+
### Example schema shape (current DSL)
|
|
100
|
+
|
|
101
|
+
A typical modern schema file (\`_schema/case.v1.yaml\`):
|
|
102
|
+
|
|
103
|
+
\`\`\`yaml
|
|
104
|
+
type: case
|
|
105
|
+
version: 1
|
|
106
|
+
required: [doc_id, title, client, status]
|
|
107
|
+
fields:
|
|
108
|
+
title:
|
|
109
|
+
type: string
|
|
110
|
+
index: true
|
|
111
|
+
client:
|
|
112
|
+
type: ref
|
|
113
|
+
target: client
|
|
114
|
+
index: true
|
|
115
|
+
status:
|
|
116
|
+
type: enum
|
|
117
|
+
values: [open, pending, closed]
|
|
118
|
+
index: true
|
|
119
|
+
opened_at:
|
|
120
|
+
type: date
|
|
121
|
+
store_precision: day # contract minimum for this field
|
|
122
|
+
on_coarser: warn # default; 'error' to reject coarser writes
|
|
123
|
+
display_precision: day
|
|
124
|
+
index: true
|
|
125
|
+
resolved_at:
|
|
126
|
+
type: date
|
|
127
|
+
store_precision: second # events captured at event-moment granularity
|
|
128
|
+
display_precision: minute # UIs drop seconds on render
|
|
129
|
+
template:
|
|
130
|
+
headings:
|
|
131
|
+
- { level: 1, text: "{{title}}", id: summary }
|
|
132
|
+
- { level: 2, text: Timeline, id: timeline }
|
|
133
|
+
- { level: 2, text: Notes, id: notes }
|
|
134
|
+
\`\`\`
|
|
135
|
+
|
|
136
|
+
Only declare precision hints on date fields where the contract actually matters. Leaving them unset is fully backward-compatible (pre-0.6.7 lenient behavior).
|
|
137
|
+
|
|
138
|
+
### ID rules (critical — do not skip)
|
|
139
|
+
- \`id_prefix\` in the registry MUST be 2-5 lowercase alphanumeric characters (e.g. \`cli\`, \`usr\`, \`cas\`, \`note\`, \`te\`)
|
|
140
|
+
- Single characters (C, U, N), uppercase (CS, TE), and symbols are rejected
|
|
141
|
+
- MAAD generates its own IDs: \`<prefix>-<sequence>\` (e.g. \`cli-001\`, \`usr-012\`)
|
|
142
|
+
- **Source data IDs are input data, not MAAD IDs.** Do not change the registry to match source IDs. Map source IDs to MAAD format during import (e.g. C001 → cli-001, U005 → usr-005)
|
|
143
|
+
- Store the original source ID in a field (e.g. \`source_id\`) if you need to cross-reference back
|
|
144
|
+
|
|
145
|
+
## Design Process
|
|
146
|
+
|
|
147
|
+
Once you have enough information:
|
|
148
|
+
|
|
149
|
+
### 1. Classify types
|
|
150
|
+
For each entity, determine: master or transaction. Use the >1K/year rule.
|
|
151
|
+
|
|
152
|
+
### 2. Map relationships
|
|
153
|
+
Draw the refs: what points to what. A job refs a customer and a technician. A note appends to a job.
|
|
154
|
+
|
|
155
|
+
### 3. Define fields
|
|
156
|
+
For each type: name, type, required, indexed, enum values, ref targets. Use domain knowledge for sensible defaults.
|
|
157
|
+
|
|
158
|
+
### 4. Estimate volume
|
|
159
|
+
Rough annual record count per type. This validates master vs transaction decisions.
|
|
160
|
+
|
|
161
|
+
### 5. Present the plan
|
|
162
|
+
Output a clear summary:
|
|
163
|
+
|
|
164
|
+
\`\`\`
|
|
165
|
+
Proposed MAAD Structure:
|
|
166
|
+
|
|
167
|
+
Master types (one file per record):
|
|
168
|
+
- customer: name, phone, email, address, type [residential, commercial], since. ~500/yr
|
|
169
|
+
- technician: name, phone, certifications, hire_date. ~20 total
|
|
170
|
+
- job: customer→, technician→, service_type, scheduled, status [scheduled, in_progress, completed, cancelled], amount. ~3000/yr
|
|
171
|
+
|
|
172
|
+
Transaction types (append to parent file):
|
|
173
|
+
- job_note: appended to job file. date, author, note text. ~15000/yr
|
|
174
|
+
|
|
175
|
+
Relationships:
|
|
176
|
+
job → customer (ref)
|
|
177
|
+
job → technician (ref)
|
|
178
|
+
job_note → job (appended to file)
|
|
179
|
+
\`\`\`
|
|
180
|
+
|
|
181
|
+
If operating agent-to-agent with full spec: skip presentation, build immediately.
|
|
182
|
+
If operating with partial spec or interactively: present and wait for confirmation.
|
|
183
|
+
|
|
184
|
+
## Build Sequence
|
|
185
|
+
|
|
186
|
+
After design is confirmed (or in autonomous mode):
|
|
187
|
+
|
|
188
|
+
1. Write \`_registry/object_types.yaml\` with all types
|
|
189
|
+
2. Write \`_schema/<type>.v1.yaml\` for each type
|
|
190
|
+
3. Call \`maad_reload\` to pick up new config
|
|
191
|
+
4. Call \`maad_summary\` to verify engine loaded the types
|
|
192
|
+
5. Optionally create 1-2 sample records per type to validate the schema
|
|
193
|
+
6. Inspect \`_meta.warnings[]\` on sample-record responses — if intended-coarse values trip precision warnings, tighten the schema or adjust the sample input before proceeding
|
|
194
|
+
7. Call \`maad_reindex\` if sample records were created
|
|
195
|
+
8. Report: "Database deployed. X types, Y fields. Ready for data."
|
|
196
|
+
9. **Register your own identity** as an agent record. Use the existence-check-then-create pattern — do **not** call \`maad_create\` blindly, it will collide on re-runs against an already-bootstrapped project:
|
|
197
|
+
|
|
198
|
+
\`\`\`
|
|
199
|
+
maad_get agt-architect
|
|
200
|
+
→ if not found:
|
|
201
|
+
maad_create agent {
|
|
202
|
+
docId: "agt-architect",
|
|
203
|
+
name: "architect",
|
|
204
|
+
role: "MAAD Architect — bootstrapped this project's schema",
|
|
205
|
+
description: "Designed registry + schemas on <ISO date>",
|
|
206
|
+
status: "active",
|
|
207
|
+
created_at: <now ISO>
|
|
208
|
+
}
|
|
209
|
+
→ if already exists:
|
|
210
|
+
You're re-running against a bootstrapped project. Skip the
|
|
211
|
+
create; optionally \`maad_update\` to refresh \`description\`
|
|
212
|
+
if you're reorganizing schemas.
|
|
213
|
+
\`\`\`
|
|
214
|
+
|
|
215
|
+
This persists provenance — queryable later as "which agent bootstrapped this project." Load-bearing once multiple architect instances operate (e.g., hosted deployments where each tenant brain gets its own bootstrap) or when compliance audits need design-time attribution.
|
|
216
|
+
|
|
217
|
+
## Bulk Data Import
|
|
218
|
+
|
|
219
|
+
For importing large datasets, use \`maad_bulk_create\` instead of individual creates:
|
|
220
|
+
|
|
221
|
+
- Accepts an array of records, returns per-record success/failure
|
|
222
|
+
- One bad record doesn't block others
|
|
223
|
+
- Single git commit for all successful records
|
|
224
|
+
- Import parent types first (clients, contacts), then dependent types (cases, notes)
|
|
225
|
+
- For updates, use \`maad_bulk_update\` with the same pattern
|
|
226
|
+
- \`maad_aggregate\` is useful for verifying counts after import
|
|
227
|
+
|
|
228
|
+
## Troubleshooting
|
|
229
|
+
|
|
230
|
+
| Problem | Cause | Fix |
|
|
231
|
+
|---------|-------|-----|
|
|
232
|
+
| reload fails | Registry YAML syntax error | Check YAML formatting, fix, reload again |
|
|
233
|
+
| create fails validation | Field value doesn't match schema | Check \`maad_schema <type>\` for expected types/enums |
|
|
234
|
+
| missing type error | Registry has type but reload wasn't called | Call \`maad_reload\` |
|
|
235
|
+
| search returns too many results | Missing query/value param | Use \`query\` (substring) or \`value\` (exact) param to filter |
|
|
236
|
+
| writes queue under contention | Engine serializes mutating ops via FIFO write mutex (since 0.4.1) | Writes don't fail — they queue. If they hang, check \`maad_health\` for \`writeQueueDepth\` and \`lastWriteOp\`. Still: never issue parallel writes from one caller. |
|
|
237
|
+
| write rejected with \`RATE_LIMITED\` | Session exceeded the per-session token bucket | Honor \`retryAfterMs\` from the error details; use exponential backoff |
|
|
238
|
+
| write response includes \`_meta.warnings[]\` | Value tripped a soft-validation check (e.g. precision coarser than declared) | Write succeeded. Decide whether to re-issue with the declared precision or tighten the schema |
|
|
239
|
+
|
|
240
|
+
## Handoff
|
|
241
|
+
|
|
242
|
+
After deployment, report to the requesting agent or user:
|
|
243
|
+
- What types were created
|
|
244
|
+
- How many fields per type
|
|
245
|
+
- Key relationships
|
|
246
|
+
- What MCP tools are available for this structure
|
|
247
|
+
- Any limitations or notes (e.g., "notes are appended to job files, use get warm to read individual notes")
|
|
248
|
+
|
|
249
|
+
Then transition to MAAD User mode for day-to-day operations, or hand control back to the upstream agent.
|
|
250
|
+
|
|
251
|
+
## Change Propagation
|
|
252
|
+
|
|
253
|
+
If the project will involve multiple agents, a hosted deployment, or scheduled workers, point the user at \`docs/change-feed.md\` in the engine repo. Key calls: \`maad_changes_since\` is the polling delta tool (shipped); cursor must be persisted between calls; in HTTP deployments polling belongs in the gateway, not the agent's reasoning loop; push via \`maad_subscribe\` is roadmapped for 0.6.5. Do not invent custom polling cadence in skill files — follow the patterns in the reference doc.
|
|
254
|
+
|
|
255
|
+
## What MAAD Is and Is Not
|
|
256
|
+
|
|
257
|
+
**Good fit:**
|
|
258
|
+
- Narrative + structured data (cases, notes, reports, customer records)
|
|
259
|
+
- Relationship-heavy data (who connects to what)
|
|
260
|
+
- Data that needs to be queried AND read in full context
|
|
261
|
+
- LLM-native workflows where agents read/write/search data
|
|
262
|
+
- Audit trail requirements (git-backed, every write tracked)
|
|
263
|
+
|
|
264
|
+
**Not a fit (yet):**
|
|
265
|
+
- Real-time transactional systems (stock trading, live telemetry)
|
|
266
|
+
- Binary data (images, videos — only metadata refs)
|
|
267
|
+
- >100K writes/day (SQLite single-writer constraint)
|
|
268
|
+
- Multi-tenant SaaS (one project = one tenant currently)
|
|
269
|
+
|
|
270
|
+
Be honest about limitations when asked. Recommend alternatives when MAAD isn't the right tool.
|
|
271
|
+
`;
|
|
272
|
+
}
|
|
273
|
+
//# sourceMappingURL=architect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"architect.js","sourceRoot":"","sources":["../src/architect.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,2CAA2C;AAC3C,4EAA4E;AAC5E,2DAA2D;AAC3D,+EAA+E;AAE/E,MAAM,UAAU,sBAAsB;IACpC,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAwQR,CAAC;AACF,CAAC"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { Role } from '../mcp/roles.js';
|
|
2
|
+
import type { TokenRecord } from './types.js';
|
|
3
|
+
export type CapResolution = {
|
|
4
|
+
allowed: true;
|
|
5
|
+
role: Role;
|
|
6
|
+
} | {
|
|
7
|
+
allowed: false;
|
|
8
|
+
reason: 'TOKEN_PROJECT_FORBIDDEN';
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* Find the per-project role cap for a token. Explicit entry > wildcard >
|
|
12
|
+
* forbidden. Per-project role downgrades are capped at the token's global
|
|
13
|
+
* role (lock #4) — an entry that claims higher is silently clamped rather
|
|
14
|
+
* than rejected, which is safe because the outer three-cap composition will
|
|
15
|
+
* clamp again against the project ceiling.
|
|
16
|
+
*/
|
|
17
|
+
export declare function resolveTokenCap(token: TokenRecord, projectName: string): CapResolution;
|
|
18
|
+
export type ThreeCapResolution = {
|
|
19
|
+
ok: true;
|
|
20
|
+
role: Role;
|
|
21
|
+
} | {
|
|
22
|
+
ok: false;
|
|
23
|
+
code: 'TOKEN_PROJECT_FORBIDDEN' | 'ROLE_UPGRADE_DENIED';
|
|
24
|
+
message: string;
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* Three-cap composition. Used in HTTP/registry mode at bind time.
|
|
28
|
+
*
|
|
29
|
+
* Returns the lowest of (instance-project ceiling, token cap, requested).
|
|
30
|
+
* Fails if the token forbids the project, or if the requested role exceeds
|
|
31
|
+
* what the ceilings allow.
|
|
32
|
+
*
|
|
33
|
+
* `requested` of undefined means "whatever the caps give me."
|
|
34
|
+
*/
|
|
35
|
+
export declare function composeEffectiveRole(projectRole: Role, token: TokenRecord, projectName: string, requested?: Role): ThreeCapResolution;
|
|
36
|
+
//# sourceMappingURL=resolve.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolve.d.ts","sourceRoot":"","sources":["../../src/auth/resolve.ts"],"names":[],"mappings":"AAuBA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAE5C,OAAO,KAAK,EAAE,WAAW,EAAc,MAAM,YAAY,CAAC;AAE1D,MAAM,MAAM,aAAa,GACrB;IAAE,OAAO,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,IAAI,CAAA;CAAE,GAC7B;IAAE,OAAO,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,yBAAyB,CAAA;CAAE,CAAC;AAE1D;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,GAAG,aAAa,CAQtF;AAQD,MAAM,MAAM,kBAAkB,GAC1B;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,IAAI,CAAA;CAAE,GACxB;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,IAAI,EAAE,yBAAyB,GAAG,qBAAqB,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAE5F;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAClC,WAAW,EAAE,IAAI,EACjB,KAAK,EAAE,WAAW,EAClB,WAAW,EAAE,MAAM,EACnB,SAAS,CAAC,EAAE,IAAI,GACf,kBAAkB,CAwBpB"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
// ============================================================================
|
|
2
|
+
// Auth resolution — token → project cap → three-cap effective role
|
|
3
|
+
//
|
|
4
|
+
// Pure functions, no I/O. Composed by SessionRegistry.bindSingle/bindMulti
|
|
5
|
+
// (HTTP + registry mode) and bypassed entirely in stdio/synthetic mode
|
|
6
|
+
// (which has no token channel and uses the two-cap model from 0.4.0).
|
|
7
|
+
//
|
|
8
|
+
// THREE-CAP RULE (dec-maadb-069 lock #7):
|
|
9
|
+
// effectiveRole(project) = min(
|
|
10
|
+
// instance.projects[project].role, // Cap 1: project ceiling
|
|
11
|
+
// token.cap-for-project, // Cap 2: token allowlist role
|
|
12
|
+
// requestedRole // Cap 3: voluntary downgrade
|
|
13
|
+
// )
|
|
14
|
+
//
|
|
15
|
+
// CAP 2 RESOLUTION (dec-maadb-069 lock #4):
|
|
16
|
+
// 1. Explicit entry for the project name wins, regardless of list order.
|
|
17
|
+
// 2. Wildcard '*' entry applies if no explicit entry matches.
|
|
18
|
+
// 3. Otherwise the project is forbidden → TOKEN_PROJECT_FORBIDDEN.
|
|
19
|
+
// Entries with no `role` field inherit the token's global role; entries
|
|
20
|
+
// with `role` downgrade to that role (never exceeds global — enforced at
|
|
21
|
+
// load time would be defensive but lock #4 intent is resolver-side).
|
|
22
|
+
// ============================================================================
|
|
23
|
+
import { minRole, roleSatisfies } from '../mcp/roles.js';
|
|
24
|
+
/**
|
|
25
|
+
* Find the per-project role cap for a token. Explicit entry > wildcard >
|
|
26
|
+
* forbidden. Per-project role downgrades are capped at the token's global
|
|
27
|
+
* role (lock #4) — an entry that claims higher is silently clamped rather
|
|
28
|
+
* than rejected, which is safe because the outer three-cap composition will
|
|
29
|
+
* clamp again against the project ceiling.
|
|
30
|
+
*/
|
|
31
|
+
export function resolveTokenCap(token, projectName) {
|
|
32
|
+
const explicit = token.projects.find(p => p.name === projectName);
|
|
33
|
+
if (explicit)
|
|
34
|
+
return { allowed: true, role: capFor(explicit, token.role) };
|
|
35
|
+
const wildcard = token.projects.find(p => p.name === '*');
|
|
36
|
+
if (wildcard)
|
|
37
|
+
return { allowed: true, role: capFor(wildcard, token.role) };
|
|
38
|
+
return { allowed: false, reason: 'TOKEN_PROJECT_FORBIDDEN' };
|
|
39
|
+
}
|
|
40
|
+
function capFor(entry, tokenGlobalRole) {
|
|
41
|
+
const requested = entry.role ?? tokenGlobalRole;
|
|
42
|
+
// Clamp: per-project cap never exceeds the token's global role.
|
|
43
|
+
return minRole(tokenGlobalRole, requested);
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Three-cap composition. Used in HTTP/registry mode at bind time.
|
|
47
|
+
*
|
|
48
|
+
* Returns the lowest of (instance-project ceiling, token cap, requested).
|
|
49
|
+
* Fails if the token forbids the project, or if the requested role exceeds
|
|
50
|
+
* what the ceilings allow.
|
|
51
|
+
*
|
|
52
|
+
* `requested` of undefined means "whatever the caps give me."
|
|
53
|
+
*/
|
|
54
|
+
export function composeEffectiveRole(projectRole, token, projectName, requested) {
|
|
55
|
+
const cap = resolveTokenCap(token, projectName);
|
|
56
|
+
if (!cap.allowed) {
|
|
57
|
+
return {
|
|
58
|
+
ok: false,
|
|
59
|
+
code: 'TOKEN_PROJECT_FORBIDDEN',
|
|
60
|
+
message: `Token does not allow project "${projectName}"`,
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
// Cap 1 × Cap 2: lowest of project ceiling and token cap.
|
|
64
|
+
const ceiling = minRole(projectRole, cap.role);
|
|
65
|
+
if (requested === undefined)
|
|
66
|
+
return { ok: true, role: ceiling };
|
|
67
|
+
// Cap 3: caller's requested role must be within the ceiling.
|
|
68
|
+
if (!roleSatisfies(ceiling, requested)) {
|
|
69
|
+
return {
|
|
70
|
+
ok: false,
|
|
71
|
+
code: 'ROLE_UPGRADE_DENIED',
|
|
72
|
+
message: `Cannot bind as ${requested} — token+project ceiling is ${ceiling}`,
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
return { ok: true, role: minRole(ceiling, requested) };
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=resolve.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolve.js","sourceRoot":"","sources":["../../src/auth/resolve.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,mEAAmE;AACnE,EAAE;AACF,2EAA2E;AAC3E,uEAAuE;AACvE,sEAAsE;AACtE,EAAE;AACF,0CAA0C;AAC1C,kCAAkC;AAClC,mEAAmE;AACnE,yEAAyE;AACzE,wEAAwE;AACxE,MAAM;AACN,EAAE;AACF,4CAA4C;AAC5C,2EAA2E;AAC3E,gEAAgE;AAChE,qEAAqE;AACrE,0EAA0E;AAC1E,2EAA2E;AAC3E,uEAAuE;AACvE,+EAA+E;AAG/E,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAOzD;;;;;;GAMG;AACH,MAAM,UAAU,eAAe,CAAC,KAAkB,EAAE,WAAmB;IACrE,MAAM,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,WAAW,CAAC,CAAC;IAClE,IAAI,QAAQ;QAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,QAAQ,EAAE,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;IAE3E,MAAM,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,GAAG,CAAC,CAAC;IAC1D,IAAI,QAAQ;QAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,QAAQ,EAAE,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;IAE3E,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,yBAAyB,EAAE,CAAC;AAC/D,CAAC;AAED,SAAS,MAAM,CAAC,KAAiB,EAAE,eAAqB;IACtD,MAAM,SAAS,GAAG,KAAK,CAAC,IAAI,IAAI,eAAe,CAAC;IAChD,gEAAgE;IAChE,OAAO,OAAO,CAAC,eAAe,EAAE,SAAS,CAAC,CAAC;AAC7C,CAAC;AAMD;;;;;;;;GAQG;AACH,MAAM,UAAU,oBAAoB,CAClC,WAAiB,EACjB,KAAkB,EAClB,WAAmB,EACnB,SAAgB;IAEhB,MAAM,GAAG,GAAG,eAAe,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC;IAChD,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC;QACjB,OAAO;YACL,EAAE,EAAE,KAAK;YACT,IAAI,EAAE,yBAAyB;YAC/B,OAAO,EAAE,iCAAiC,WAAW,GAAG;SACzD,CAAC;IACJ,CAAC;IAED,0DAA0D;IAC1D,MAAM,OAAO,GAAG,OAAO,CAAC,WAAW,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC;IAE/C,IAAI,SAAS,KAAK,SAAS;QAAE,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;IAEhE,6DAA6D;IAC7D,IAAI,CAAC,aAAa,CAAC,OAAO,EAAE,SAAS,CAAC,EAAE,CAAC;QACvC,OAAO;YACL,EAAE,EAAE,KAAK;YACT,IAAI,EAAE,qBAAqB;YAC3B,OAAO,EAAE,kBAAkB,SAAS,+BAA+B,OAAO,EAAE;SAC7E,CAAC;IACJ,CAAC;IACD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,CAAC,OAAO,EAAE,SAAS,CAAC,EAAE,CAAC;AACzD,CAAC"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { type Result } from '../errors.js';
|
|
2
|
+
import { type TokenId, type TokenHash, type TokenRecord, type IssueSpec, type IssuedToken } from './types.js';
|
|
3
|
+
export declare const TOKENS_FILE_RELATIVE: string;
|
|
4
|
+
/**
|
|
5
|
+
* Generate a new plaintext bearer in the locked format: maad_pat_<32hex>.
|
|
6
|
+
* Shell-safe (hex only), 128 bits random, prefix visible in logs / scanners.
|
|
7
|
+
*/
|
|
8
|
+
export declare function generatePlaintext(): string;
|
|
9
|
+
/** Plaintext → SHA-256 hex. The sole lookup key that persists. */
|
|
10
|
+
export declare function hashPlaintext(plaintext: string): TokenHash;
|
|
11
|
+
/** Format check — cheap defensive filter before hashing arbitrary bearers. */
|
|
12
|
+
export declare function looksLikeToken(bearer: string): boolean;
|
|
13
|
+
export declare class TokenStore {
|
|
14
|
+
private filePath;
|
|
15
|
+
private registryName;
|
|
16
|
+
private byHash;
|
|
17
|
+
private byId;
|
|
18
|
+
private records;
|
|
19
|
+
private constructor();
|
|
20
|
+
/**
|
|
21
|
+
* Load tokens.yaml from `<instanceRoot>/_auth/tokens.yaml`. Returns an empty
|
|
22
|
+
* store if the file is absent — caller decides whether HTTP mode can boot
|
|
23
|
+
* against that state (the HTTP boot-mode matrix in the 0.7.0 spec).
|
|
24
|
+
*
|
|
25
|
+
* Parse errors are NOT silent: TOKENS_FILE_INVALID is returned with the
|
|
26
|
+
* file path + js-yaml message so operators can fix the file without
|
|
27
|
+
* guessing.
|
|
28
|
+
*/
|
|
29
|
+
static load(instanceRoot: string): Promise<Result<TokenStore>>;
|
|
30
|
+
/** Absolute path to the backing file. */
|
|
31
|
+
path(): string;
|
|
32
|
+
/**
|
|
33
|
+
* 0.7.0 — Re-read tokens.yaml from disk and swap the in-memory indexes
|
|
34
|
+
* in-place. Captures of the TokenStore reference stay valid (so the HTTP
|
|
35
|
+
* transport doesn't need a getter). Parse errors leave the existing
|
|
36
|
+
* in-memory state untouched. Called by the SIGHUP handler alongside
|
|
37
|
+
* instance reload.
|
|
38
|
+
*/
|
|
39
|
+
reload(): Promise<Result<{
|
|
40
|
+
total: number;
|
|
41
|
+
active: number;
|
|
42
|
+
}>>;
|
|
43
|
+
/** Optional human label recorded at the top of tokens.yaml. */
|
|
44
|
+
name(): string | undefined;
|
|
45
|
+
/** Total records including revoked. */
|
|
46
|
+
size(): number;
|
|
47
|
+
/** Records with no revokedAt and no expiresAt-in-the-past. */
|
|
48
|
+
activeCount(now?: Date): number;
|
|
49
|
+
/** O(1) lookup by hash. Returns undefined for unknown bearers. */
|
|
50
|
+
lookupByHash(hash: TokenHash): TokenRecord | undefined;
|
|
51
|
+
/** Secondary lookup by readable id (CLI / admin paths). */
|
|
52
|
+
lookupById(id: TokenId): TokenRecord | undefined;
|
|
53
|
+
/** Snapshot of all records. Caller receives a shallow copy. */
|
|
54
|
+
list(): TokenRecord[];
|
|
55
|
+
/**
|
|
56
|
+
* Issue a new token. Generates plaintext + hash, appends the record,
|
|
57
|
+
* persists the file atomically. Returns both the record and the plaintext —
|
|
58
|
+
* plaintext is never recoverable after this call.
|
|
59
|
+
*/
|
|
60
|
+
issue(spec: IssueSpec): Promise<Result<IssuedToken>>;
|
|
61
|
+
/**
|
|
62
|
+
* Mark a token as revoked. Sets revokedAt; the record stays in the registry
|
|
63
|
+
* so audit queries can resolve historic token IDs. Idempotent — revoking
|
|
64
|
+
* an already-revoked record is a no-op and returns the existing record.
|
|
65
|
+
*/
|
|
66
|
+
revoke(id: TokenId): Promise<Result<TokenRecord>>;
|
|
67
|
+
/**
|
|
68
|
+
* Rotate a token: issue a new token with the SAME capabilities (role,
|
|
69
|
+
* projects, agentId, userId, expiresAt, name) and revoke the old one.
|
|
70
|
+
* Immediate cutover — no grace window (deferred per dec-maadb-069 lock #10).
|
|
71
|
+
* Returns the new record + plaintext; old record retains its id with
|
|
72
|
+
* revokedAt set.
|
|
73
|
+
*/
|
|
74
|
+
rotate(id: TokenId): Promise<Result<IssuedToken>>;
|
|
75
|
+
/**
|
|
76
|
+
* Atomic write via `<path>.tmp` + rename. Creates `_auth/` if missing.
|
|
77
|
+
* Errors don't leak partial state because writeFile+rename is atomic on
|
|
78
|
+
* both POSIX and Windows.
|
|
79
|
+
*/
|
|
80
|
+
private persist;
|
|
81
|
+
}
|
|
82
|
+
//# sourceMappingURL=token-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"token-store.d.ts","sourceRoot":"","sources":["../../src/auth/token-store.ts"],"names":[],"mappings":"AA0BA,OAAO,EAAiB,KAAK,MAAM,EAAE,MAAM,cAAc,CAAC;AAC1D,OAAO,EAGL,KAAK,OAAO,EACZ,KAAK,SAAS,EACd,KAAK,WAAW,EAChB,KAAK,SAAS,EACd,KAAK,WAAW,EAGjB,MAAM,YAAY,CAAC;AAMpB,eAAO,MAAM,oBAAoB,QAAoC,CAAC;AAEtE;;;GAGG;AACH,wBAAgB,iBAAiB,IAAI,MAAM,CAG1C;AAED,kEAAkE;AAClE,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,CAE1D;AAED,8EAA8E;AAC9E,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAItD;AAMD,qBAAa,UAAU;IAMnB,OAAO,CAAC,QAAQ;IAChB,OAAO,CAAC,YAAY;IANtB,OAAO,CAAC,MAAM,CAAqC;IACnD,OAAO,CAAC,IAAI,CAAmC;IAC/C,OAAO,CAAC,OAAO,CAAqB;IAEpC,OAAO;IAKP;;;;;;;;OAQG;WACU,IAAI,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;IAmCpE,yCAAyC;IACzC,IAAI,IAAI,MAAM;IAEd;;;;;;OAMG;IACG,MAAM,IAAI,OAAO,CAAC,MAAM,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IA0ClE,+DAA+D;IAC/D,IAAI,IAAI,MAAM,GAAG,SAAS;IAE1B,uCAAuC;IACvC,IAAI,IAAI,MAAM;IAEd,8DAA8D;IAC9D,WAAW,CAAC,GAAG,GAAE,IAAiB,GAAG,MAAM;IAM3C,kEAAkE;IAClE,YAAY,CAAC,IAAI,EAAE,SAAS,GAAG,WAAW,GAAG,SAAS;IAItD,2DAA2D;IAC3D,UAAU,CAAC,EAAE,EAAE,OAAO,GAAG,WAAW,GAAG,SAAS;IAIhD,+DAA+D;IAC/D,IAAI,IAAI,WAAW,EAAE;IAErB;;;;OAIG;IACG,KAAK,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;IAsC1D;;;;OAIG;IACG,MAAM,CAAC,EAAE,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;IAcvD;;;;;;OAMG;IACG,MAAM,CAAC,EAAE,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;IAiCvD;;;;OAIG;YACW,OAAO;CA4BtB"}
|