@ryuenn3123/agentic-senior-core 3.0.25 → 3.0.27
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/.agent-context/prompts/bootstrap-design.md +3 -3
- package/.agent-context/prompts/refactor.md +2 -0
- package/.agent-context/prompts/review-code.md +2 -2
- package/.agent-context/review-checklists/architecture-review.md +12 -0
- package/.agent-context/review-checklists/pr-checklist.md +10 -2
- package/.agent-context/rules/api-docs.md +4 -0
- package/.agent-context/rules/architecture.md +3 -3
- package/.agent-context/rules/database-design.md +9 -0
- package/.agent-context/rules/error-handling.md +8 -0
- package/.agent-context/rules/event-driven.md +3 -0
- package/.agent-context/rules/frontend-architecture.md +2 -2
- package/.agent-context/rules/microservices.md +2 -0
- package/.agent-context/rules/security.md +11 -0
- package/.agent-context/rules/testing.md +8 -0
- package/.agent-context/state/memory-continuity-benchmark.json +1 -1
- package/.agent-context/state/weekly-governance-report.json +234 -31
- package/.cursorrules +1 -1
- package/.gemini/instructions.md +3 -2
- package/.github/copilot-instructions.md +3 -2
- package/.instructions.md +16 -1
- package/.windsurfrules +1 -1
- package/AGENTS.md +4 -3
- package/README.md +6 -5
- package/lib/cli/commands/init.mjs +6 -0
- package/lib/cli/commands/upgrade.mjs +13 -0
- package/lib/cli/compiler.mjs +9 -8
- package/lib/cli/memory-continuity.mjs +137 -0
- package/lib/cli/project-scaffolder/design-contract.mjs +3 -3
- package/lib/cli/project-scaffolder/prompt-builders.mjs +2 -2
- package/lib/cli/token-optimization.mjs +56 -0
- package/package.json +1 -1
- package/scripts/governance-weekly-report.mjs +138 -1
- package/scripts/release-gate/audit-checks.mjs +1 -1
- package/scripts/release-gate/constants.mjs +11 -0
- package/scripts/rules-guardian-audit.mjs +1 -1
- package/scripts/single-source-lazy-loading-audit.mjs +10 -8
- package/scripts/sync-thin-adapters.mjs +7 -4
- package/scripts/ui-design-judge/prompting.mjs +1 -1
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Adapter Mode: thin
|
|
4
4
|
Adapter Source: .instructions.md
|
|
5
|
-
Canonical Snapshot SHA256:
|
|
5
|
+
Canonical Snapshot SHA256: 11eeafb3ff6a0977785e3668a704c6bba543b515d2828c02de8276f6cf1c391c
|
|
6
6
|
|
|
7
7
|
The canonical policy source for this repository is [.instructions.md](../.instructions.md).
|
|
8
8
|
|
|
@@ -10,6 +10,7 @@ If your host stops at this file, follow this minimum floor:
|
|
|
10
10
|
- Read `.agent-instructions.md` next when it exists.
|
|
11
11
|
- For UI or redesign requests, load [.agent-context/prompts/bootstrap-design.md](../.agent-context/prompts/bootstrap-design.md) and [.agent-context/rules/frontend-architecture.md](../.agent-context/rules/frontend-architecture.md) before coding.
|
|
12
12
|
- If UI scope and `docs/DESIGN.md` or `docs/design-intent.json` is missing, materialize them before UI implementation.
|
|
13
|
+
- For backend/API/data/auth/event requests, load relevant global rules from [.agent-context/rules/](../.agent-context/rules) and do not create stack-specific governance adapters.
|
|
13
14
|
- Memory continuity is host-dependent project memory and does not replace bootstrap loading.
|
|
14
15
|
|
|
15
16
|
## Required Load Order
|
|
@@ -20,7 +21,7 @@ If your host stops at this file, follow this minimum floor:
|
|
|
20
21
|
4. Load request templates from [.agent-context/prompts/](../.agent-context/prompts).
|
|
21
22
|
5. Apply review contracts from [.agent-context/review-checklists/](../.agent-context/review-checklists).
|
|
22
23
|
6. Apply state awareness from [.agent-context/state/](../.agent-context/state) and thresholds from [.agent-context/policies/](../.agent-context/policies).
|
|
23
|
-
7. Resolve
|
|
24
|
+
7. Resolve runtime, structure, and dependency choices from project context docs plus live evidence.
|
|
24
25
|
|
|
25
26
|
## Completion Gate
|
|
26
27
|
|
package/.instructions.md
CHANGED
|
@@ -40,12 +40,27 @@ Available engineering rule files:
|
|
|
40
40
|
|
|
41
41
|
**What to do**: Resolve only the rule files relevant to the current task. Do not read the entire rule directory by default. For UI-only work, start with `bootstrap-design.md` and `frontend-architecture.md` and keep backend or DevOps rules unloaded unless the task explicitly crosses those boundaries. For Docker or Compose work, load `docker-runtime.md` and verify the latest official Docker docs before authoring container assets. For framework or package setup work, use the latest stable compatible dependency set and official setup flow unless a documented compatibility constraint blocks it.
|
|
42
42
|
|
|
43
|
+
### Global Backend/API Governance Routing
|
|
44
|
+
|
|
45
|
+
This is global governance, not a stack-specific adapter system. Do not create Nest, Laravel, FastAPI, Express, Go, Ruby, PHP, Java, or framework-specific baseline adapters from this repository. The LLM may use its general knowledge and current official docs when a concrete project already uses a tool, but the governance layer stays architecture- and runtime-agnostic.
|
|
46
|
+
|
|
47
|
+
When backend/API work is in scope, load only the relevant global rule files:
|
|
48
|
+
|
|
49
|
+
- Data, schema, repository, ORM, query, transaction, migration, pagination, or persistence scope: load `architecture.md`, `database-design.md`, `performance.md`, and `testing.md`.
|
|
50
|
+
- Endpoint, controller, route handler, public API, request/response contract, validation failure, or API error scope: load `architecture.md`, `api-docs.md`, `error-handling.md`, `security.md`, and `testing.md`.
|
|
51
|
+
- Authentication, authorization, secrets, user input, webhook, upload, session, token, or permission scope: load `security.md`, `error-handling.md`, and `testing.md`.
|
|
52
|
+
- Queue, worker, cron, event stream, message broker, async workflow, retry, or cross-system mutation scope: load `event-driven.md`, `database-design.md`, `error-handling.md`, `performance.md`, and `testing.md`.
|
|
53
|
+
- Multi-service, distributed consistency, service boundary, or cross-domain data ownership scope: load `microservices.md`, `event-driven.md`, `database-design.md`, `api-docs.md`, and `architecture.md`.
|
|
54
|
+
|
|
55
|
+
If multiple bullets match, load the union once, then implement against the project framework already present. Do not expand into unrelated stack guides just because a runtime name appears.
|
|
56
|
+
|
|
43
57
|
### Layer 2: Runtime Decision Signals (Dynamic)
|
|
44
58
|
|
|
45
59
|
**Location**: dynamic runtime intelligence from project context, repository evidence, and live research.
|
|
46
60
|
|
|
47
61
|
Runtime signals are evidence gates, not style cues or popularity rankings.
|
|
48
62
|
Do not force the project into a listed stack when repository evidence, delivery constraints, or ecosystem reality require another shape.
|
|
63
|
+
Runtime evidence must not become per-stack governance. Use it to understand the project that already exists, not to choose or inject framework-specific rule adapters.
|
|
49
64
|
|
|
50
65
|
**What to do**: For fresh projects, recommend the runtime/framework from the first brief, current constraints, and live official documentation before coding. For existing projects, inspect repo evidence directly and treat detected markers as evidence only, not migration or design direction. Ignore pattern frequency, external rankings, and remembered defaults.
|
|
51
66
|
|
|
@@ -203,7 +218,7 @@ Why Required: [why the boundary protects the project]
|
|
|
203
218
|
Verify that all nine layers are reachable:
|
|
204
219
|
|
|
205
220
|
- Layer 1: Rules
|
|
206
|
-
- Layer 2:
|
|
221
|
+
- Layer 2: Runtime Decision Signals
|
|
207
222
|
- Layer 3: Structural Planning Signals
|
|
208
223
|
- Layer 4: Execution Contracts
|
|
209
224
|
- Layer 5: Prompts
|
package/.windsurfrules
CHANGED
package/AGENTS.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Adapter Mode: thin
|
|
4
4
|
Adapter Source: .instructions.md
|
|
5
|
-
Canonical Snapshot SHA256:
|
|
5
|
+
Canonical Snapshot SHA256: 11eeafb3ff6a0977785e3668a704c6bba543b515d2828c02de8276f6cf1c391c
|
|
6
6
|
|
|
7
7
|
This file is an adapter entrypoint for agent discovery.
|
|
8
8
|
The canonical policy source is [.instructions.md](.instructions.md).
|
|
@@ -15,8 +15,9 @@ If your host stops at this file instead of following the full chain, obey the Cr
|
|
|
15
15
|
- Memory continuity does not replace bootstrap loading. It is host-dependent project memory, not a guarantee that instructions were reloaded for this session.
|
|
16
16
|
- For UI, UX, layout, screen, tailwind, frontend, or redesign requests: load [.agent-context/prompts/bootstrap-design.md](.agent-context/prompts/bootstrap-design.md) and [.agent-context/rules/frontend-architecture.md](.agent-context/rules/frontend-architecture.md) before editing code.
|
|
17
17
|
- For UI scope: if `docs/DESIGN.md` or `docs/design-intent.json` is missing, materialize or refine them before implementing UI changes.
|
|
18
|
+
- For backend, API, data, auth, error, event, queue, worker, or distributed-system requests: load the relevant global rules from [.agent-context/rules/](.agent-context/rules); do not create stack-specific governance adapters.
|
|
18
19
|
- For refactor, improve, clean up, or fix requests: inspect the active rules and propose a plan before editing.
|
|
19
|
-
- For new project or module requests: clarify constraints,
|
|
20
|
+
- For new project or module requests: clarify constraints, runtime decisions, and required docs before generating code.
|
|
20
21
|
- For ecosystem, framework, dependency, or Docker claims: perform live web research instead of relying on stale local heuristics.
|
|
21
22
|
|
|
22
23
|
## Mandatory Bootstrap Chain
|
|
@@ -28,7 +29,7 @@ If your host stops at this file instead of following the full chain, obey the Cr
|
|
|
28
29
|
5. Enforce review contracts from [.agent-context/review-checklists/](.agent-context/review-checklists).
|
|
29
30
|
6. Read change-risk maps and continuity state from [.agent-context/state/](.agent-context/state).
|
|
30
31
|
7. Enforce policy thresholds from [.agent-context/policies/](.agent-context/policies).
|
|
31
|
-
8. Use
|
|
32
|
+
8. Use runtime evidence, structure, and live research signals from project context docs.
|
|
32
33
|
|
|
33
34
|
## Trigger Rules
|
|
34
35
|
|
package/README.md
CHANGED
|
@@ -10,13 +10,14 @@
|
|
|
10
10
|
**Production-grade Rules Engine (Governance Engine) for AI coding agents.**
|
|
11
11
|
Works with Cursor, Windsurf, GitHub Copilot, Claude Code, Gemini, and other LLM-powered IDE workflows.
|
|
12
12
|
|
|
13
|
-
Latest release: 3.0.
|
|
13
|
+
Latest release: 3.0.26 (2026-04-25).
|
|
14
14
|
|
|
15
|
-
Highlights in 3.0.
|
|
16
|
-
-
|
|
15
|
+
Highlights in 3.0.26:
|
|
16
|
+
- Memory continuity now seeds `.agent-context/state/active-memory.json` once, so new sessions have a compact project-focus snapshot without overwriting active work during upgrade.
|
|
17
|
+
- Token optimization now exposes an output folding strategy that preserves failures, file/line details, and actionable warnings while folding repetitive shell noise.
|
|
18
|
+
- UI design guidance now treats expressive motion as a first-class default for modern interfaces instead of letting safety wording become an excuse for static screens.
|
|
17
19
|
- Agents must use live/current-year research for ecosystem, framework, dependency, Docker, and modern UI/library claims instead of offline repository guesses.
|
|
18
|
-
- Frontend guidance
|
|
19
|
-
- Generated design-intent seeds are more compact, leaving the LLM room to synthesize project-specific visual direction instead of inheriting verbose scaffold bias.
|
|
20
|
+
- Frontend guidance rejects safe dashboard/admin-panel defaults and requires responsive recomposition.
|
|
20
21
|
|
|
21
22
|
</div>
|
|
22
23
|
|
|
@@ -67,6 +67,7 @@ import {
|
|
|
67
67
|
} from '../token-optimization.mjs';
|
|
68
68
|
import {
|
|
69
69
|
createMemoryContinuityState,
|
|
70
|
+
ensureActiveMemorySnapshot,
|
|
70
71
|
writeMemoryContinuityState,
|
|
71
72
|
} from '../memory-continuity.mjs';
|
|
72
73
|
|
|
@@ -428,6 +429,7 @@ export async function runInitCommand(targetDirectoryArgument, initOptions = {})
|
|
|
428
429
|
'.github/copilot-instructions.md',
|
|
429
430
|
],
|
|
430
431
|
stackLoadingMode: 'lazy',
|
|
432
|
+
domainRuleLoadingMode: 'lazy',
|
|
431
433
|
selectedProfile: selectedPolicyProfileName,
|
|
432
434
|
selectedProfileDisplayName: selectedPolicyProfile.displayName,
|
|
433
435
|
blockingSeverities: selectedPolicyProfile.blockingSeverities,
|
|
@@ -603,6 +605,9 @@ export async function runInitCommand(targetDirectoryArgument, initOptions = {})
|
|
|
603
605
|
});
|
|
604
606
|
|
|
605
607
|
await writeMemoryContinuityState(resolvedTargetDirectoryPath, memoryContinuityState);
|
|
608
|
+
await ensureActiveMemorySnapshot(resolvedTargetDirectoryPath, {
|
|
609
|
+
projectName: path.basename(resolvedTargetDirectoryPath),
|
|
610
|
+
});
|
|
606
611
|
console.log(`Project memory continuity metadata enabled (${memoryContinuityState.hydrationMode}, host-supported).`);
|
|
607
612
|
}
|
|
608
613
|
|
|
@@ -748,6 +753,7 @@ export async function runInitCommand(targetDirectoryArgument, initOptions = {})
|
|
|
748
753
|
hydrationMode: memoryContinuityState?.hydrationMode || null,
|
|
749
754
|
adapters: memoryContinuityState?.adapters || [],
|
|
750
755
|
stateFile: isMemoryContinuityEnabled ? '.agent-context/state/memory-continuity.json' : null,
|
|
756
|
+
activeSnapshotFile: isMemoryContinuityEnabled ? '.agent-context/state/active-memory.json' : null,
|
|
751
757
|
},
|
|
752
758
|
detectionTransparency,
|
|
753
759
|
uiScopeSignals: existingProjectUiScopeSignals,
|
|
@@ -47,6 +47,7 @@ import {
|
|
|
47
47
|
detectProjectDocTemplateStaleness,
|
|
48
48
|
buildDesignIntentSeedFromSignals,
|
|
49
49
|
} from '../project-scaffolder.mjs';
|
|
50
|
+
import { ensureActiveMemorySnapshot } from '../memory-continuity.mjs';
|
|
50
51
|
|
|
51
52
|
export function parseUpgradeArguments(commandArguments) {
|
|
52
53
|
const parsedUpgradeOptions = {
|
|
@@ -252,6 +253,7 @@ export async function runUpgradeCommand(targetDirectoryArgument, upgradeOptions
|
|
|
252
253
|
canonicalSource: '.instructions.md',
|
|
253
254
|
compiledEntrypoints: ['.cursorrules', '.windsurfrules'],
|
|
254
255
|
stackLoadingMode: 'lazy',
|
|
256
|
+
domainRuleLoadingMode: 'lazy',
|
|
255
257
|
selectedProfile: selectedProfileName,
|
|
256
258
|
selectedProfileDisplayName: toTitleCase(selectedProfileName),
|
|
257
259
|
blockingSeverities: PROFILE_PRESETS[selectedProfileName]?.blockingSeverities || [],
|
|
@@ -401,6 +403,7 @@ export async function runUpgradeCommand(targetDirectoryArgument, upgradeOptions
|
|
|
401
403
|
managedSurfacePlan,
|
|
402
404
|
});
|
|
403
405
|
const supplementalCreatedFileNames = [];
|
|
406
|
+
const shouldEnsureActiveMemorySnapshot = existingOnboardingReport?.memoryContinuity?.enabled !== false;
|
|
404
407
|
|
|
405
408
|
if (shouldSeedDesignIntentOnApply && designIntentSeedContent) {
|
|
406
409
|
const docsDirectoryPath = path.join(resolvedTargetDirectoryPath, 'docs');
|
|
@@ -410,6 +413,16 @@ export async function runUpgradeCommand(targetDirectoryArgument, upgradeOptions
|
|
|
410
413
|
supplementalCreatedFileNames.push('docs/design-intent.json');
|
|
411
414
|
}
|
|
412
415
|
|
|
416
|
+
if (shouldEnsureActiveMemorySnapshot) {
|
|
417
|
+
const activeMemoryResult = await ensureActiveMemorySnapshot(resolvedTargetDirectoryPath, {
|
|
418
|
+
projectName: packageManifest?.name || path.basename(resolvedTargetDirectoryPath),
|
|
419
|
+
});
|
|
420
|
+
|
|
421
|
+
if (activeMemoryResult.created) {
|
|
422
|
+
supplementalCreatedFileNames.push('.agent-context/state/active-memory.json');
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
|
|
413
426
|
await compileDynamicContext({
|
|
414
427
|
targetDirectoryPath: resolvedTargetDirectoryPath,
|
|
415
428
|
selectedStackFileName,
|
package/lib/cli/compiler.mjs
CHANGED
|
@@ -88,6 +88,7 @@ export async function writeOnboardingReport({
|
|
|
88
88
|
ruleLoadingPolicy: {
|
|
89
89
|
canonicalSource: '.instructions.md',
|
|
90
90
|
stackLoadingMode: 'lazy',
|
|
91
|
+
domainRuleLoadingMode: 'lazy',
|
|
91
92
|
loadedOnDemand: true,
|
|
92
93
|
primaryStack: hasExplicitRuntimeDecision ? selectedStackFileName : null,
|
|
93
94
|
additionalStacks: hasExplicitRuntimeDecision ? selectedAdditionalStackFileNames : [],
|
|
@@ -241,14 +242,14 @@ export async function buildCompiledRulesContent({
|
|
|
241
242
|
if (hasExplicitRuntimeDecision && normalizedAdditionalStackFileNames.length > 0) {
|
|
242
243
|
contextBlocks.push(
|
|
243
244
|
[
|
|
244
|
-
'## LAYER 2B: ADDITIONAL
|
|
245
|
-
'This project
|
|
245
|
+
'## LAYER 2B: ADDITIONAL RUNTIME EVIDENCE',
|
|
246
|
+
'This project has multiple runtime constraints. Load additional runtime evidence below only when the task touches that runtime:',
|
|
246
247
|
...normalizedAdditionalStackFileNames.map((stackFileName, stackIndex) => {
|
|
247
248
|
if (availableStackProfileFileNames.has(stackFileName)) {
|
|
248
249
|
return `${stackIndex + 1}. stack-profile:${stackFileName}`;
|
|
249
250
|
}
|
|
250
251
|
|
|
251
|
-
return `${stackIndex + 1}. ${stackFileName} (
|
|
252
|
+
return `${stackIndex + 1}. ${stackFileName} (runtime evidence signal)`;
|
|
252
253
|
}),
|
|
253
254
|
].join('\n')
|
|
254
255
|
);
|
|
@@ -261,16 +262,16 @@ export async function buildCompiledRulesContent({
|
|
|
261
262
|
? `Primary runtime constraint: ${selectedStackFileName}`
|
|
262
263
|
: 'Primary runtime constraint: unresolved until agent recommendation is approved',
|
|
263
264
|
normalizedAdditionalStackFileNames.length > 0
|
|
264
|
-
? `Additional
|
|
265
|
+
? `Additional runtime evidence loads on demand: ${normalizedAdditionalStackFileNames.map((stackFileName) => {
|
|
265
266
|
if (availableStackProfileFileNames.has(stackFileName)) {
|
|
266
267
|
return `stack-profile:${stackFileName}`;
|
|
267
268
|
}
|
|
268
269
|
|
|
269
|
-
return `${stackFileName} (
|
|
270
|
+
return `${stackFileName} (runtime evidence signal)`;
|
|
270
271
|
}).join(', ')}`
|
|
271
|
-
: '
|
|
272
|
-
'Load
|
|
273
|
-
'Avoid eager loading unrelated runtime guidance to prevent instruction conflicts.',
|
|
272
|
+
: 'No stack-specific governance adapter is loaded by default.',
|
|
273
|
+
'Load global domain rules only when task scope touches that domain.',
|
|
274
|
+
'Avoid eager loading unrelated runtime or domain guidance to prevent instruction conflicts.',
|
|
274
275
|
].join('\n')
|
|
275
276
|
);
|
|
276
277
|
|
|
@@ -36,8 +36,10 @@ const INLINE_SENSITIVE_PATTERNS = [
|
|
|
36
36
|
|
|
37
37
|
export const MEMORY_SCHEMA_VERSION = '1.0.0';
|
|
38
38
|
export const MEMORY_CONTINUITY_STATE_FILE_NAME = 'memory-continuity.json';
|
|
39
|
+
export const ACTIVE_MEMORY_STATE_FILE_NAME = 'active-memory.json';
|
|
39
40
|
|
|
40
41
|
const MEMORY_CONTINUITY_STATE_SCHEMA_VERSION = 'memory-continuity-v1';
|
|
42
|
+
const ACTIVE_MEMORY_STATE_SCHEMA_VERSION = 'active-memory-v1';
|
|
41
43
|
|
|
42
44
|
export const SUPPORTED_MEMORY_ADAPTER_IDS = Object.freeze([
|
|
43
45
|
'claude-code',
|
|
@@ -359,6 +361,138 @@ export async function writeMemoryContinuityState(targetDirectoryPath, memoryCont
|
|
|
359
361
|
await fs.writeFile(stateFilePath, JSON.stringify(memoryContinuityState, null, 2) + '\n', 'utf8');
|
|
360
362
|
}
|
|
361
363
|
|
|
364
|
+
export function createActiveMemorySnapshot(options = {}) {
|
|
365
|
+
return {
|
|
366
|
+
schemaVersion: ACTIVE_MEMORY_STATE_SCHEMA_VERSION,
|
|
367
|
+
snapshotPurpose: 'compact-cross-session-continuity',
|
|
368
|
+
updatePolicy: {
|
|
369
|
+
writeWhen: 'natural-task-boundary',
|
|
370
|
+
overwriteOnlyWithCurrentRepoEvidence: true,
|
|
371
|
+
preserveUserOwnedContent: true,
|
|
372
|
+
},
|
|
373
|
+
project: {
|
|
374
|
+
name: toNonEmptyString(options.projectName, ''),
|
|
375
|
+
currentFocus: '',
|
|
376
|
+
durableFacts: [],
|
|
377
|
+
},
|
|
378
|
+
progress: {
|
|
379
|
+
lastAchievements: [],
|
|
380
|
+
pendingIssues: [],
|
|
381
|
+
nextBestActions: [],
|
|
382
|
+
validationState: [],
|
|
383
|
+
},
|
|
384
|
+
designContinuity: {
|
|
385
|
+
visualLanguageContinuity: 'opt-in-only',
|
|
386
|
+
currentConceptualAnchor: '',
|
|
387
|
+
forbiddenCarryover: [
|
|
388
|
+
'prior-project-style-memory',
|
|
389
|
+
'old-ui-visual-dna-without-user-approval',
|
|
390
|
+
'generic-dashboard-defaults',
|
|
391
|
+
],
|
|
392
|
+
},
|
|
393
|
+
privacy: {
|
|
394
|
+
storeSecrets: false,
|
|
395
|
+
storeRawChatLogs: false,
|
|
396
|
+
redactSensitiveTextBeforeWriting: true,
|
|
397
|
+
},
|
|
398
|
+
generatedAt: new Date().toISOString(),
|
|
399
|
+
lastUpdatedAt: null,
|
|
400
|
+
};
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
export function validateActiveMemorySnapshot(activeMemorySnapshot) {
|
|
404
|
+
const validationErrors = [];
|
|
405
|
+
|
|
406
|
+
if (!activeMemorySnapshot || typeof activeMemorySnapshot !== 'object') {
|
|
407
|
+
return ['active-memory snapshot must be an object.'];
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
if (activeMemorySnapshot.schemaVersion !== ACTIVE_MEMORY_STATE_SCHEMA_VERSION) {
|
|
411
|
+
validationErrors.push(`active-memory.schemaVersion must equal "${ACTIVE_MEMORY_STATE_SCHEMA_VERSION}".`);
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
if (activeMemorySnapshot.snapshotPurpose !== 'compact-cross-session-continuity') {
|
|
415
|
+
validationErrors.push('active-memory.snapshotPurpose must equal "compact-cross-session-continuity".');
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
const serializedSnapshot = JSON.stringify(activeMemorySnapshot);
|
|
419
|
+
if (estimateTokenUsage(serializedSnapshot) > 3000) {
|
|
420
|
+
validationErrors.push('active-memory snapshot must stay compact enough for session-start hydration.');
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
const redactionProbe = redactSensitiveMemoryText(serializedSnapshot);
|
|
424
|
+
if (redactionProbe.wasRedacted) {
|
|
425
|
+
validationErrors.push('active-memory snapshot must not contain secret-like fields, bearer tokens, or private blocks.');
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
if (activeMemorySnapshot.privacy?.storeSecrets !== false) {
|
|
429
|
+
validationErrors.push('active-memory.privacy.storeSecrets must equal false.');
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
if (activeMemorySnapshot.privacy?.storeRawChatLogs !== false) {
|
|
433
|
+
validationErrors.push('active-memory.privacy.storeRawChatLogs must equal false.');
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
if (activeMemorySnapshot.privacy?.redactSensitiveTextBeforeWriting !== true) {
|
|
437
|
+
validationErrors.push('active-memory.privacy.redactSensitiveTextBeforeWriting must equal true.');
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
for (const arrayPath of [
|
|
441
|
+
['project', 'durableFacts'],
|
|
442
|
+
['progress', 'lastAchievements'],
|
|
443
|
+
['progress', 'pendingIssues'],
|
|
444
|
+
['progress', 'nextBestActions'],
|
|
445
|
+
['progress', 'validationState'],
|
|
446
|
+
]) {
|
|
447
|
+
const arrayValue = arrayPath.reduce((currentValue, pathSegment) => currentValue?.[pathSegment], activeMemorySnapshot);
|
|
448
|
+
const pathLabel = `active-memory.${arrayPath.join('.')}`;
|
|
449
|
+
if (!Array.isArray(arrayValue)) {
|
|
450
|
+
validationErrors.push(`${pathLabel} must be an array.`);
|
|
451
|
+
continue;
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
if (arrayValue.length > 12) {
|
|
455
|
+
validationErrors.push(`${pathLabel} must stay compact and contain at most 12 entries.`);
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
if (activeMemorySnapshot.designContinuity?.visualLanguageContinuity !== 'opt-in-only') {
|
|
460
|
+
validationErrors.push('active-memory.designContinuity.visualLanguageContinuity must equal "opt-in-only".');
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
return validationErrors;
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
export async function ensureActiveMemorySnapshot(targetDirectoryPath, options = {}) {
|
|
467
|
+
const stateDirectoryPath = path.join(targetDirectoryPath, '.agent-context', 'state');
|
|
468
|
+
const stateFilePath = path.join(stateDirectoryPath, ACTIVE_MEMORY_STATE_FILE_NAME);
|
|
469
|
+
|
|
470
|
+
if (await pathExists(stateFilePath)) {
|
|
471
|
+
return {
|
|
472
|
+
created: false,
|
|
473
|
+
filePath: stateFilePath,
|
|
474
|
+
};
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
await fs.mkdir(stateDirectoryPath, { recursive: true });
|
|
478
|
+
const activeMemorySnapshot = createActiveMemorySnapshot(options);
|
|
479
|
+
const validationErrors = validateActiveMemorySnapshot(activeMemorySnapshot);
|
|
480
|
+
if (validationErrors.length > 0) {
|
|
481
|
+
throw new Error(`Invalid active memory snapshot seed: ${validationErrors.join(' ')}`);
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
await fs.writeFile(
|
|
485
|
+
stateFilePath,
|
|
486
|
+
JSON.stringify(activeMemorySnapshot, null, 2) + '\n',
|
|
487
|
+
'utf8'
|
|
488
|
+
);
|
|
489
|
+
|
|
490
|
+
return {
|
|
491
|
+
created: true,
|
|
492
|
+
filePath: stateFilePath,
|
|
493
|
+
};
|
|
494
|
+
}
|
|
495
|
+
|
|
362
496
|
export function buildMemoryContinuityGuidanceBlock(memoryContinuityState) {
|
|
363
497
|
if (!memoryContinuityState?.enabled) {
|
|
364
498
|
return [
|
|
@@ -384,9 +518,12 @@ export function buildMemoryContinuityGuidanceBlock(memoryContinuityState) {
|
|
|
384
518
|
adapterGuidanceLine,
|
|
385
519
|
'',
|
|
386
520
|
'Session-start retrieval policy:',
|
|
521
|
+
'- Read `.agent-context/state/active-memory.json` first when it exists; it is the compact project-focus snapshot.',
|
|
387
522
|
`- Load compact index first (limit: ${sessionStartIndexLimit} entries).`,
|
|
388
523
|
`- Hydrate full detail only for highest-value entries (limit: ${fullHydrationLimit}).`,
|
|
389
524
|
'- Always redact sensitive text before persistence (<private> blocks and inline secret-like fields).',
|
|
525
|
+
'- Refresh `active-memory.json` at natural task boundaries, but never store secrets, raw chat logs, or stale visual taste.',
|
|
526
|
+
'- Current repo evidence, current user brief, and live research override active-memory when they conflict.',
|
|
390
527
|
'',
|
|
391
528
|
'Host compatibility scope:',
|
|
392
529
|
'- This memory layer does not replace reading bootstrap instruction files at the start of a session.',
|
|
@@ -60,7 +60,7 @@ function buildStructureFirstSeedSignals({
|
|
|
60
60
|
distinctiveMoves: [
|
|
61
61
|
'Choose one recognizable design move from product task, audience, content, repo evidence, and current docs; do not inherit a scaffold preset.',
|
|
62
62
|
],
|
|
63
|
-
motionPurpose: '
|
|
63
|
+
motionPurpose: 'Default to a modern motion plan for UI work: use expressive transitions, spatial choreography, micro-interactions, and motion libraries when they strengthen hierarchy, continuity, feedback, memorability, or perceived product quality. If implementation needs a motion library, the LLM must choose a current compatible option from official docs instead of relying on an offline default.',
|
|
64
64
|
componentMorphology: {
|
|
65
65
|
mobile: 'Recompose the experience for touch, task priority, and constrained attention. Mobile should be a deliberate mobile design, not a shrunken desktop.',
|
|
66
66
|
tablet: 'Regroup surfaces for medium-width use, preserving task clarity without cloning either desktop or mobile blindly.',
|
|
@@ -439,7 +439,7 @@ function buildDesignIntentContractObject({
|
|
|
439
439
|
{
|
|
440
440
|
key: 'motionDiscipline',
|
|
441
441
|
blockingByDefault: false,
|
|
442
|
-
question: '
|
|
442
|
+
question: 'Does motion act as part of the design language while staying purposeful, performant, reduced-motion-safe, and consistent with the product tone?',
|
|
443
443
|
},
|
|
444
444
|
],
|
|
445
445
|
genericitySignals: [
|
|
@@ -495,7 +495,7 @@ function buildDesignIntentContractObject({
|
|
|
495
495
|
'Accessibility, responsiveness, and implementation realism are non-negotiable.',
|
|
496
496
|
'Cross-viewport behavior must reorganize tasks and navigation, not just scale the desktop layout down.',
|
|
497
497
|
'A single agent-chosen conceptual anchor must unify typography, spacing, morphology, motion, and responsive composition when user research is absent.',
|
|
498
|
-
'Expressive motion and spatial interaction are
|
|
498
|
+
'Expressive motion and spatial interaction are expected for modern UI work when they support the anchor; keep them accessible and performant instead of suppressing them by default.',
|
|
499
499
|
'When the user asks for a zero-based redesign, existing UI becomes content and behavior evidence only; prior visual DNA must be discarded unless explicitly approved.',
|
|
500
500
|
],
|
|
501
501
|
forbiddenPatterns: [
|
|
@@ -156,7 +156,7 @@ export function buildDesignBootstrapPrompt({
|
|
|
156
156
|
'10. Do not let repeated surfaces, component-kit defaults, or safe typography become the final direction without explicit product rationale.',
|
|
157
157
|
'11. The LLM must choose color, type, spacing, density, morphology, and motion dynamically from the active project context instead of copying this seed.',
|
|
158
158
|
'12. Viewport mutation must be operation-based. For each viewport, define the primary mutation operation, required surface actions, and forbidden responsive fallback patterns.',
|
|
159
|
-
'13. Motion can be bold, cinematic, or highly expressive when it improves memorability, hierarchy, feedback, or product confidence. If a motion library is
|
|
159
|
+
'13. Default to a rich motion plan for modern UI work. Motion can be bold, cinematic, spatial, scroll-linked, or highly expressive when it improves memorability, hierarchy, feedback, or product confidence. If a motion library is useful, research current official docs and select the latest stable compatible option instead of using an offline default. Solve clarity, accessibility, and runtime risks without falling back to a static interface by habit.',
|
|
160
160
|
'14. Define component morphology across interaction states and viewports so cards, forms, nav, and feedback surfaces adapt coherently instead of only resizing.',
|
|
161
161
|
'15. Keep UI-only requests context-isolated. Load frontend design rules first and do not eagerly load backend-only or workflow-only rules unless the task explicitly crosses those boundaries.',
|
|
162
162
|
'16. Treat WCAG 2.2 AA as the hard accessibility floor. Use APCA only as advisory perceptual tuning, never as a reason to waive a WCAG failure.',
|
|
@@ -178,7 +178,7 @@ export function buildDesignBootstrapPrompt({
|
|
|
178
178
|
'32. If the user supplies research files, library lists, screenshots, articles, or benchmark notes, read them as candidate evidence, summarize the useful signals, filter by project fit, and verify technology claims against current official docs before implementation.',
|
|
179
179
|
'33. If no user-supplied research or reference is supplied for UI work, activate the Dynamic Avant-Garde Anchor Engine before coding. User-supplied research means current-task evidence from the user; this scaffold, prior UI, and old design docs do not count as research.',
|
|
180
180
|
'34. In Dynamic Avant-Garde mode, perform agent-led research when available, then internally consider at least three high-variance conceptual anchors, discard the two safest or most predictable options, output only the chosen anchor and rationale, and forbid final anchors named dashboard, portal, cards, admin panel, SaaS shell, web app shell, or minimalist interface.',
|
|
181
|
-
'35. The chosen anchor must drive typography, spacing, density, color behavior, morphology, motion, and responsive composition.
|
|
181
|
+
'35. The chosen anchor must drive typography, spacing, density, color behavior, morphology, motion, and responsive composition. Treat expressive motion, spatial transitions, micro-interactions, and modern animation libraries as first-class options; include performance notes and reduced-motion fallbacks instead of suppressing motion to look safe.',
|
|
182
182
|
'',
|
|
183
183
|
'## Project Inputs',
|
|
184
184
|
`- Project name: ${discoveryAnswers.projectName}`,
|
|
@@ -89,6 +89,43 @@ const COMMAND_REWRITE_MAPPINGS = [
|
|
|
89
89
|
},
|
|
90
90
|
];
|
|
91
91
|
|
|
92
|
+
const OUTPUT_FOLDING_STRATEGY = {
|
|
93
|
+
mode: 'compact-high-signal-output',
|
|
94
|
+
appliesTo: [
|
|
95
|
+
'shell-command-output',
|
|
96
|
+
'test-output',
|
|
97
|
+
'build-output',
|
|
98
|
+
'diff-output',
|
|
99
|
+
'log-output',
|
|
100
|
+
],
|
|
101
|
+
preserveAlways: [
|
|
102
|
+
'exit-code',
|
|
103
|
+
'failing-command',
|
|
104
|
+
'file-and-line',
|
|
105
|
+
'error-message',
|
|
106
|
+
'actionable-warning',
|
|
107
|
+
],
|
|
108
|
+
foldByDefault: [
|
|
109
|
+
'repeated-success-lines',
|
|
110
|
+
'large-unchanged-diff-context',
|
|
111
|
+
'verbose-install-progress',
|
|
112
|
+
'duplicated-stack-frames',
|
|
113
|
+
'low-signal-directory-noise',
|
|
114
|
+
],
|
|
115
|
+
nativeFallback: [
|
|
116
|
+
'prefer --stat or --name-only before full diff',
|
|
117
|
+
'prefer focused rg queries before broad file dumps',
|
|
118
|
+
'prefer failure-focused test reporters when available',
|
|
119
|
+
'summarize long logs before hydrating full detail',
|
|
120
|
+
],
|
|
121
|
+
safetyBoundary: [
|
|
122
|
+
'never hide failing checks',
|
|
123
|
+
'never drop the command that produced output',
|
|
124
|
+
'never persist secrets into summaries',
|
|
125
|
+
'hydrate full output only when the compact summary is insufficient',
|
|
126
|
+
],
|
|
127
|
+
};
|
|
128
|
+
|
|
92
129
|
function parseRtkVersion(versionOutput) {
|
|
93
130
|
const versionMatch = versionOutput.match(/\d+\.\d+\.\d+/);
|
|
94
131
|
return versionMatch ? versionMatch[0] : null;
|
|
@@ -204,6 +241,14 @@ export function createTokenOptimizationState({
|
|
|
204
241
|
detectionError: rtkDetection.detectionError,
|
|
205
242
|
},
|
|
206
243
|
commandRewriteMappings: COMMAND_REWRITE_MAPPINGS.map((mapping) => ({ ...mapping })),
|
|
244
|
+
outputFoldingStrategy: {
|
|
245
|
+
...OUTPUT_FOLDING_STRATEGY,
|
|
246
|
+
appliesTo: [...OUTPUT_FOLDING_STRATEGY.appliesTo],
|
|
247
|
+
preserveAlways: [...OUTPUT_FOLDING_STRATEGY.preserveAlways],
|
|
248
|
+
foldByDefault: [...OUTPUT_FOLDING_STRATEGY.foldByDefault],
|
|
249
|
+
nativeFallback: [...OUTPUT_FOLDING_STRATEGY.nativeFallback],
|
|
250
|
+
safetyBoundary: [...OUTPUT_FOLDING_STRATEGY.safetyBoundary],
|
|
251
|
+
},
|
|
207
252
|
generatedAt: new Date().toISOString(),
|
|
208
253
|
};
|
|
209
254
|
}
|
|
@@ -258,6 +303,14 @@ export function buildTokenOptimizationGuidanceBlock(tokenOptimizationState) {
|
|
|
258
303
|
'- If shell output is still large, summarize and continue iteratively instead of dumping full logs.',
|
|
259
304
|
];
|
|
260
305
|
|
|
306
|
+
const outputFoldingStrategy = tokenOptimizationState.outputFoldingStrategy || OUTPUT_FOLDING_STRATEGY;
|
|
307
|
+
const outputFoldingLines = [
|
|
308
|
+
`- Mode: ${outputFoldingStrategy.mode || OUTPUT_FOLDING_STRATEGY.mode}.`,
|
|
309
|
+
`- Preserve always: ${(outputFoldingStrategy.preserveAlways || OUTPUT_FOLDING_STRATEGY.preserveAlways).join(', ')}.`,
|
|
310
|
+
`- Fold by default: ${(outputFoldingStrategy.foldByDefault || OUTPUT_FOLDING_STRATEGY.foldByDefault).join(', ')}.`,
|
|
311
|
+
`- Safety boundary: ${(outputFoldingStrategy.safetyBoundary || OUTPUT_FOLDING_STRATEGY.safetyBoundary).join(', ')}.`,
|
|
312
|
+
];
|
|
313
|
+
|
|
261
314
|
return [
|
|
262
315
|
`Token optimization mode is enabled for agent: ${tokenOptimizationState.selectedAgent}.`,
|
|
263
316
|
`Preferred shell proxy: ${tokenOptimizationState.preferredShellProxy}.`,
|
|
@@ -269,6 +322,9 @@ export function buildTokenOptimizationGuidanceBlock(tokenOptimizationState) {
|
|
|
269
322
|
'- Shell rewrite hooks affect shell tool calls only.',
|
|
270
323
|
'- Built-in read/grep/glob style tools may bypass shell rewrites, so explicit compact shell commands should be preferred in high-volume sessions.',
|
|
271
324
|
'',
|
|
325
|
+
'Output folding policy:',
|
|
326
|
+
...outputFoldingLines,
|
|
327
|
+
'',
|
|
272
328
|
'Fallback behavior when external proxy is unavailable:',
|
|
273
329
|
...fallbackGuidance,
|
|
274
330
|
].join('\n');
|