Skip to content

chore(architecture): domain manifest, boundary guardrail, single agent contract, knowledge map - #31

Open
div0rce wants to merge 1 commit into
mainfrom
chore/agentic-architecture
Open

div0rce wants to merge 1 commit into
mainfrom
chore/agentic-architecture

Conversation

@div0rce

@div0rce div0rce commented Sep 22, 2026 •

Copy link
Copy Markdown
Owner

Summary

Architecture-only change to make Cherry navigable and safely modifiable by coding agents. No runtime, engine, schema, or product behavior changes.

  • Domain manifest + guardrail. scripts/guardrails/domains.manifest.json declares 24 domains in 4 layers (core → runtime → service → surface) with owned paths, allowed imports, tests, docs, invariants. New check:domain-boundaries (in npm run check) enforces total, exclusive ownership and downward value-import direction; four pre-existing edges are allowlisted with reasons and must be removed when fixed. Self-test with fixture.
  • check:engine-prisma fixed. Its @prisma/client / lib/prisma import regexes ran after string literals were blanked and could never match; only prisma. usage was caught. Import patterns now run on raw source (type-only imports allowed). Self-test added. Existing engine/authority code passes.
  • Targeted verification. npm run report:domain-impact -- <paths> prints owner domain, allowed imports, dependents, tests, docs, invariants. --filter=<globs> on check:tests:node / check:tests:next (output labelled FILTERED, never authoritative).
  • One instruction authority. AGENTS.md rewritten as a 113-line navigation + execution contract (what never changes, where things live, bootstrap, FAST/DOMAIN/FULL/DB verification, schema changes, workflow, parallel-agent rules, done/handoff). CLAUDE.md and .github/copilot-instructions.md are pointers; CONTRIBUTING.md keeps human-only content. Scoped AGENTS.md in lib/engine/, app/api/, scripts/.
  • Knowledge map. docs/architecture/{index,domains,dependency-rules,data-flow,testing}.md, ADRs 0001/0002, and audit-2026-09-22.md (baseline, verified findings, risks, ordered next work).
  • Doc corrections (docs said things the code does not do): no @/ alias; withUser on 9 of 35 routes; CI steps; check runs tests; .js specifiers are the norm; fromLegacy may not use time/DB; guardrail-runtime allowlist; /dev gating is proxy.ts; /signin has no page; legacy test paths; duplicate guardrail numbers; getServerSession. Five self-declared-deprecated docs and DOC_REWRITE_TASK.md removed.
  • Hygiene. .gitignore: ignore .evidence/latest.json, stop ignoring the tracked scripts/audit/full-checkout-audit.mts, drop duplicate *.pem. docs/config-snapshot.md regenerated for package.json, .gitignore, both registries.

Testing

Node 24.15.0 (nvm), npm ci, CHERRY_TMP_ROOT set, CHERRY_VINE_SIGNATURE_MODE=enforce.

Command Result
npm run check pass, 2m02s (run on the working tree before commit; see blocker below)
npm test pass, 242 files, 2m23s
npm run build pass, 21s
npm run check:domain-boundaries ok (361 files, 876 edges, 24 domains)
tests/node/guardrails/{domain-boundaries,engine-prisma-import}.test.ts ok

Baseline on main (19ec86d): check 2m32s pass, test 2m58s pass (240 files), build pass only with CHERRY_VINE_SIGNATURE_MODE=enforce.

Blocker, pre-existing, not introduced here. check:side-effects:diff compares expiresBy dates in scripts/side-effects.allowlist.json against the HEAD commit date. All ten legacy-combo entries expired on 2026-06-01, so any commit dated after that fails npm run check (verified on this branch after committing: Legacy-combo entry expired (2026-06-01): lib/autopilot/engineDecisionId.ts). main still passes only because its HEAD is dated 2026-04-29. CI on this PR will be red at that guardrail. I did not extend the dates or weaken the check; that is a policy decision. Options: (a) remediate the ten files (remove time+persistence combos), or (b) set a new expiresBy with an owner in a separate guardrails: commit. Everything else in the gate passed.

Risk

  • Domains touched: guardrails/scripts, docs, test runners (filter is opt-in; default path unchanged). No runtime code under lib/, app/, or components/ changed; lib/engine/AGENTS.md and app/api/AGENTS.md are documentation.
  • check:domain-boundaries fails on any new file under lib/, app/, components/, types/ that no domain owns. Cost: one line in the manifest. Intentional.
  • check:engine-prisma is stricter than before (value imports of @prisma/client / lib/prisma in lib/engine/**, lib/authority/** now fail). Current code passes.
  • Not changed on purpose: engine barrel Prisma leak (engine-freeze protocol), 110 duplicate legacy tests (needs guardrail repointing; separate PR), withUser normalization, dead-module deletion, bank CSV history. See docs/architecture/audit-2026-09-22.md "Recommended next work".

Engine Impact

  • This PR does not modify engine behavior (no changes under lib/engine, lib/vine, engine APIs, or engine-adjacent files). lib/engine/AGENTS.md is documentation only.

…t contract, knowledge map

- Add scripts/guardrails/domains.manifest.json (24 domains, 4 layers) and
  check:domain-boundaries enforcing exclusive ownership and downward imports;
  four pre-existing edges allowlisted with reasons.
- Fix check:engine-prisma import patterns (ran on string-blanked text and could
  never match); add self-tests for both guardrails.
- Add report:domain-impact and --filter= on check:tests:node/next for
  DOMAIN-level verification (labelled, non-authoritative).
- Rewrite AGENTS.md as the single operating contract; CLAUDE.md, copilot
  instructions become pointers; CONTRIBUTING.md keeps human-only content;
  scoped AGENTS.md for lib/engine, app/api, scripts.
- Add docs/architecture (index, domains, dependency-rules, data-flow, testing,
  ADRs 0001-0002, audit-2026-09-22) and correct stale claims in existing docs;
  remove self-declared deprecated docs.
- .gitignore hygiene; regenerate docs/config-snapshot.md blocks.

No engine, schema, or runtime behavior changes.
@vercel

vercel Bot commented Sep 22, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
cherry Ready Ready Preview Sep 22, 2026 9:00pm UTC

@coderabbitai

coderabbitai Bot commented Sep 22, 2026

Copy link
Copy Markdown

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Advanced

Run ID: 5dbcc337-eccc-4dc4-8f0b-10bbc348af76


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your trial has ended. Reactivate Greptile to resume code reviews.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 132449f9d7

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +30 to 34
{
message: "value-imports '@prisma/client'",
regex: /^\s*(?:import|export)\s+(?!type\b)[^;]*?\bfrom\s+['"]@prisma\/client['"]/m,
},
{ message: "requires '@prisma/client'", regex: /\brequire\s*\(\s*['"]@prisma\/client['"]\s*\)/ },

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Detect side-effect and dynamic Prisma imports

When a file under lib/authority uses import '@prisma/client' or await import('@prisma/client'), neither this from-only expression nor the require expression matches it. The domain checker ignores external packages, and the repository backstop scans lib/engine but not lib/authority, so such an import can pass the full guardrail suite despite the authority purity invariant; add patterns and fixtures for these ESM forms.

AGENTS.md reference: AGENTS.md:L37-L40

Useful? React with 👍 / 👎.

Comment thread scripts/domain-impact.mts
Comment on lines +64 to +67
const ownerByFile = new Map<string, string>();
for (const [id, domain] of Object.entries(manifest.data.domains)) {
for (const file of fg.sync(domain.owns, { cwd: ROOT, onlyFiles: true })) {
ownerByFile.set(normalize(file), id);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve domain ownership for deleted files

When a change only deletes a mapped source file, changedFiles() returns its old path, but this map is populated by globbing only files that still exist. The deleted path is consequently reported as outside the domain map, its owning domain is omitted, and the report does not recommend that domain's tests or invariants even though it promises impact information for everything changed versus main; ownership for deleted paths should be matched from the manifest patterns or the base revision.

AGENTS.md reference: AGENTS.md:L26-L28

Useful? React with 👍 / 👎.

Comment on lines +133 to +137
while ((match = IMPORT_FROM_REGEX.exec(stripped)) !== null) {
const isTypeOnly = match[2] !== undefined;
const specifier = match[3];
if (isTypeOnly || specifier === undefined) continue;
specifiers.push(specifier);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Exclude inline type-only imports from boundary edges

For valid TypeScript such as import { type Foo } from '../other-domain.js' or export { type Foo } from ..., match[2] is undefined because type occurs inside the specifier list, so the guardrail records a runtime edge and can reject an import that is erased during compilation. The repository already uses this inline type syntax, so the parser should distinguish an all-type specifier list from mixed/value imports.

Useful? React with 👍 / 👎.

Comment on lines +212 to +214
"buckets",
"config",
"observability"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Prevent runtime domains from importing service domains

The adapters-runtime domain is in the runtime layer, but this allowlist grants it blanket access to the service-layer buckets and observability domains, so isAllowedEdge accepts imports in the opposite direction from the declared surface → service → runtime → core flow. Existing bucket dependencies should be represented as exact legacy exceptions or moved to a lower layer rather than permitting every current and future runtime file to import these service domains.

AGENTS.md reference: AGENTS.md:L31-L35

Useful? React with 👍 / 👎.

This branch was successfully deployed

1 active deployment
Preview — 132449f9 Deployed Sep 22, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant