ai-collab-open-system 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.aict/START_HERE.md +127 -0
- package/.aict/WORKSPACE_MANIFEST.json +91 -0
- package/.aict/acceptance/EXAMPLE.synthetic.md +49 -0
- package/.aict/acceptance/FAILURE_MODES.md +40 -0
- package/.aict/acceptance/PROMPT.md +47 -0
- package/.aict/acceptance/README.md +44 -0
- package/.aict/acceptance/TEMPLATE.md +57 -0
- package/.aict/adapters/SHARED_CORE_CONTRACT.md +106 -0
- package/.aict/adapters/claude-code/ADAPTER.md +28 -0
- package/.aict/adapters/cline/ADAPTER.md +28 -0
- package/.aict/adapters/codex/ADAPTER.md +28 -0
- package/.aict/adapters/copilot/ADAPTER.md +28 -0
- package/.aict/adapters/cursor/ADAPTER.md +28 -0
- package/.aict/adapters/windsurf/ADAPTER.md +28 -0
- package/.aict/context/EXAMPLE.synthetic.md +53 -0
- package/.aict/context/FAILURE_MODES.md +40 -0
- package/.aict/context/PROMPT.md +47 -0
- package/.aict/context/README.md +44 -0
- package/.aict/context/TEMPLATE.md +63 -0
- package/.aict/cookbook/README.md +8 -0
- package/.aict/cookbook/bridge-to-a-second-family.md +103 -0
- package/.aict/cookbook/connect-a-tool.md +67 -0
- package/.aict/cookbook/review-a-half-product.md +79 -0
- package/.aict/cookbook/run-a-first-loop.md +81 -0
- package/.aict/examples/README.md +21 -0
- package/.aict/examples/ai-coding-long-task/CASE.md +161 -0
- package/.aict/examples/ai-coding-long-task/artifacts/acceptance-card.md +36 -0
- package/.aict/examples/ai-coding-long-task/artifacts/context-package.md +30 -0
- package/.aict/examples/ai-coding-long-task/artifacts/execution-prompt.md +30 -0
- package/.aict/examples/ai-coding-long-task/artifacts/first-ai-output.md +109 -0
- package/.aict/examples/ai-coding-long-task/artifacts/guard-review.md +40 -0
- package/.aict/examples/ai-coding-long-task/artifacts/handoff-note.md +28 -0
- package/.aict/examples/ai-coding-long-task/artifacts/harvest-seed.md +28 -0
- package/.aict/examples/ai-coding-long-task/artifacts/revised-output.md +62 -0
- package/.aict/examples/content-production-harvest/CASE.md +87 -0
- package/.aict/examples/content-production-harvest/artifacts/acceptance-card.md +28 -0
- package/.aict/examples/content-production-harvest/artifacts/context-package.md +28 -0
- package/.aict/examples/content-production-harvest/artifacts/execution-prompt.md +30 -0
- package/.aict/examples/content-production-harvest/artifacts/guard-review.md +28 -0
- package/.aict/examples/content-production-harvest/artifacts/handoff-note.md +28 -0
- package/.aict/examples/content-production-harvest/artifacts/harvest-seed.md +28 -0
- package/.aict/examples/multi-tool-collaboration/CASE.md +87 -0
- package/.aict/examples/multi-tool-collaboration/artifacts/acceptance-card.md +28 -0
- package/.aict/examples/multi-tool-collaboration/artifacts/context-package.md +28 -0
- package/.aict/examples/multi-tool-collaboration/artifacts/execution-prompt.md +30 -0
- package/.aict/examples/multi-tool-collaboration/artifacts/guard-review.md +28 -0
- package/.aict/examples/multi-tool-collaboration/artifacts/handoff-note.md +28 -0
- package/.aict/examples/multi-tool-collaboration/artifacts/harvest-seed.md +28 -0
- package/.aict/examples/personal-judgment-growth-assistant/CASE.md +87 -0
- package/.aict/examples/personal-judgment-growth-assistant/artifacts/acceptance-card.md +28 -0
- package/.aict/examples/personal-judgment-growth-assistant/artifacts/context-package.md +28 -0
- package/.aict/examples/personal-judgment-growth-assistant/artifacts/execution-prompt.md +30 -0
- package/.aict/examples/personal-judgment-growth-assistant/artifacts/guard-review.md +28 -0
- package/.aict/examples/personal-judgment-growth-assistant/artifacts/handoff-note.md +28 -0
- package/.aict/examples/personal-judgment-growth-assistant/artifacts/harvest-seed.md +28 -0
- package/.aict/examples/research-knowledge-synthesis/CASE.md +87 -0
- package/.aict/examples/research-knowledge-synthesis/artifacts/acceptance-card.md +28 -0
- package/.aict/examples/research-knowledge-synthesis/artifacts/context-package.md +28 -0
- package/.aict/examples/research-knowledge-synthesis/artifacts/execution-prompt.md +30 -0
- package/.aict/examples/research-knowledge-synthesis/artifacts/guard-review.md +28 -0
- package/.aict/examples/research-knowledge-synthesis/artifacts/handoff-note.md +28 -0
- package/.aict/examples/research-knowledge-synthesis/artifacts/harvest-seed.md +28 -0
- package/.aict/guard/EXAMPLE.synthetic.md +51 -0
- package/.aict/guard/FAILURE_MODES.md +40 -0
- package/.aict/guard/PROMPT.md +47 -0
- package/.aict/guard/README.md +44 -0
- package/.aict/guard/TEMPLATE.md +60 -0
- package/.aict/handoff/EXAMPLE.synthetic.md +51 -0
- package/.aict/handoff/FAILURE_MODES.md +40 -0
- package/.aict/handoff/PROMPT.md +47 -0
- package/.aict/handoff/README.md +44 -0
- package/.aict/handoff/TEMPLATE.md +60 -0
- package/.aict/harvest/EXAMPLE.synthetic.md +51 -0
- package/.aict/harvest/FAILURE_MODES.md +40 -0
- package/.aict/harvest/PROMPT.md +47 -0
- package/.aict/harvest/README.md +44 -0
- package/.aict/harvest/TEMPLATE.md +60 -0
- package/.aict/mechanisms/README.md +34 -0
- package/.aict/mechanisms/anti-drift-partner/EXAMPLE.synthetic.md +46 -0
- package/.aict/mechanisms/anti-drift-partner/FAILURE_MODES.md +25 -0
- package/.aict/mechanisms/anti-drift-partner/PROMPT.md +75 -0
- package/.aict/mechanisms/anti-drift-partner/README.md +82 -0
- package/.aict/mechanisms/anti-drift-partner/TEMPLATE.md +74 -0
- package/.aict/mechanisms/blind-spot-scan/EXAMPLE.synthetic.md +39 -0
- package/.aict/mechanisms/blind-spot-scan/FAILURE_MODES.md +25 -0
- package/.aict/mechanisms/blind-spot-scan/PROMPT.md +72 -0
- package/.aict/mechanisms/blind-spot-scan/README.md +79 -0
- package/.aict/mechanisms/blind-spot-scan/TEMPLATE.md +70 -0
- package/.aict/mechanisms/collaboration-coach/EXAMPLE.synthetic.md +40 -0
- package/.aict/mechanisms/collaboration-coach/FAILURE_MODES.md +25 -0
- package/.aict/mechanisms/collaboration-coach/PROMPT.md +72 -0
- package/.aict/mechanisms/collaboration-coach/README.md +79 -0
- package/.aict/mechanisms/collaboration-coach/TEMPLATE.md +61 -0
- package/.aict/mechanisms/do-not-handle-yet/EXAMPLE.synthetic.md +15 -0
- package/.aict/mechanisms/do-not-handle-yet/FAILURE_MODES.md +16 -0
- package/.aict/mechanisms/do-not-handle-yet/PROMPT.md +41 -0
- package/.aict/mechanisms/do-not-handle-yet/README.md +30 -0
- package/.aict/mechanisms/do-not-handle-yet/TEMPLATE.md +38 -0
- package/.aict/mechanisms/dual-guard/EXAMPLE.synthetic.md +54 -0
- package/.aict/mechanisms/dual-guard/FAILURE_MODES.md +25 -0
- package/.aict/mechanisms/dual-guard/PROMPT.md +76 -0
- package/.aict/mechanisms/dual-guard/README.md +81 -0
- package/.aict/mechanisms/dual-guard/TEMPLATE.md +73 -0
- package/.aict/mechanisms/feedback-absorption-ledger/EXAMPLE.synthetic.md +49 -0
- package/.aict/mechanisms/feedback-absorption-ledger/FAILURE_MODES.md +25 -0
- package/.aict/mechanisms/feedback-absorption-ledger/PROMPT.md +74 -0
- package/.aict/mechanisms/feedback-absorption-ledger/README.md +81 -0
- package/.aict/mechanisms/feedback-absorption-ledger/TEMPLATE.md +69 -0
- package/.aict/mechanisms/half-product-review/EXAMPLE.synthetic.md +15 -0
- package/.aict/mechanisms/half-product-review/FAILURE_MODES.md +16 -0
- package/.aict/mechanisms/half-product-review/PROMPT.md +41 -0
- package/.aict/mechanisms/half-product-review/README.md +30 -0
- package/.aict/mechanisms/half-product-review/TEMPLATE.md +38 -0
- package/.aict/mechanisms/handoff-abc/EXAMPLE.synthetic.md +47 -0
- package/.aict/mechanisms/handoff-abc/FAILURE_MODES.md +25 -0
- package/.aict/mechanisms/handoff-abc/PROMPT.md +75 -0
- package/.aict/mechanisms/handoff-abc/README.md +82 -0
- package/.aict/mechanisms/handoff-abc/TEMPLATE.md +60 -0
- package/.aict/mechanisms/harvest-and-erc/EXAMPLE.synthetic.md +43 -0
- package/.aict/mechanisms/harvest-and-erc/FAILURE_MODES.md +25 -0
- package/.aict/mechanisms/harvest-and-erc/PROMPT.md +74 -0
- package/.aict/mechanisms/harvest-and-erc/README.md +81 -0
- package/.aict/mechanisms/harvest-and-erc/TEMPLATE.md +60 -0
- package/.aict/mechanisms/honest-calibration/EXAMPLE.synthetic.md +43 -0
- package/.aict/mechanisms/honest-calibration/FAILURE_MODES.md +25 -0
- package/.aict/mechanisms/honest-calibration/PROMPT.md +74 -0
- package/.aict/mechanisms/honest-calibration/README.md +81 -0
- package/.aict/mechanisms/honest-calibration/TEMPLATE.md +66 -0
- package/.aict/mechanisms/one-click-dispatch/EXAMPLE.synthetic.md +15 -0
- package/.aict/mechanisms/one-click-dispatch/FAILURE_MODES.md +16 -0
- package/.aict/mechanisms/one-click-dispatch/PROMPT.md +41 -0
- package/.aict/mechanisms/one-click-dispatch/README.md +30 -0
- package/.aict/mechanisms/one-click-dispatch/TEMPLATE.md +38 -0
- package/.aict/mechanisms/plain-language-first-screen/EXAMPLE.synthetic.md +15 -0
- package/.aict/mechanisms/plain-language-first-screen/FAILURE_MODES.md +16 -0
- package/.aict/mechanisms/plain-language-first-screen/PROMPT.md +41 -0
- package/.aict/mechanisms/plain-language-first-screen/README.md +30 -0
- package/.aict/mechanisms/plain-language-first-screen/TEMPLATE.md +38 -0
- package/.aict/mechanisms/root-cause-brake/EXAMPLE.synthetic.md +55 -0
- package/.aict/mechanisms/root-cause-brake/FAILURE_MODES.md +25 -0
- package/.aict/mechanisms/root-cause-brake/PROMPT.md +73 -0
- package/.aict/mechanisms/root-cause-brake/README.md +79 -0
- package/.aict/mechanisms/root-cause-brake/TEMPLATE.md +74 -0
- package/.aict/mechanisms/scout-review-controller/EXAMPLE.synthetic.md +15 -0
- package/.aict/mechanisms/scout-review-controller/FAILURE_MODES.md +16 -0
- package/.aict/mechanisms/scout-review-controller/PROMPT.md +41 -0
- package/.aict/mechanisms/scout-review-controller/README.md +30 -0
- package/.aict/mechanisms/scout-review-controller/TEMPLATE.md +38 -0
- package/.aict/mechanisms/single-tool-guard/EXAMPLE.synthetic.md +54 -0
- package/.aict/mechanisms/single-tool-guard/FAILURE_MODES.md +25 -0
- package/.aict/mechanisms/single-tool-guard/PROMPT.md +76 -0
- package/.aict/mechanisms/single-tool-guard/README.md +83 -0
- package/.aict/mechanisms/single-tool-guard/TEMPLATE.md +75 -0
- package/.aict/mechanisms/task-splitting/EXAMPLE.synthetic.md +53 -0
- package/.aict/mechanisms/task-splitting/FAILURE_MODES.md +25 -0
- package/.aict/mechanisms/task-splitting/PROMPT.md +72 -0
- package/.aict/mechanisms/task-splitting/README.md +79 -0
- package/.aict/mechanisms/task-splitting/TEMPLATE.md +76 -0
- package/.aict/modes/README.md +11 -0
- package/.aict/modes/execute.md +31 -0
- package/.aict/modes/handoff.md +29 -0
- package/.aict/modes/harvest.md +30 -0
- package/.aict/modes/review.md +28 -0
- package/.aict/modes/shape.md +34 -0
- package/.aict/privacy/COMMERCIAL_BOUNDARY.md +34 -0
- package/.aict/privacy/PRIVACY.md +36 -0
- package/.aict/privacy/REDACTION_CHECKLIST.md +12 -0
- package/.aict/profile/CANDIDATES.md +44 -0
- package/.aict/profile/EXAMPLE.synthetic.md +49 -0
- package/.aict/profile/FAILURE_MODES.md +40 -0
- package/.aict/profile/PROMPT.md +47 -0
- package/.aict/profile/README.md +44 -0
- package/.aict/profile/TEMPLATE.md +57 -0
- package/.aict/prompts/acceptance-definition.md +109 -0
- package/.aict/prompts/guard-review.md +116 -0
- package/.aict/prompts/handoff-generation.md +110 -0
- package/.aict/prompts/harvest-extraction.md +110 -0
- package/.aict/prompts/mode-switching.md +66 -0
- package/.aict/prompts/profile-creation.md +66 -0
- package/.aict/prompts/profile-refinement.md +66 -0
- package/.aict/prompts/project-context-packaging.md +113 -0
- package/.aict/prompts/red-team-challenge.md +106 -0
- package/.aict/prompts/rule-update-proposal.md +114 -0
- package/.aict/prompts/workflow-reset.md +109 -0
- package/.aict/roles/README.md +18 -0
- package/.aict/roles/executor.md +34 -0
- package/.aict/roles/harvester.md +33 -0
- package/.aict/roles/owner-controller.md +38 -0
- package/.aict/roles/scout.md +33 -0
- package/.aict/roles/supervisor.md +34 -0
- package/.aict/roles/system-guardian.md +34 -0
- package/.aict/skills/acceptance/SKILL.md +43 -0
- package/.aict/skills/context/SKILL.md +44 -0
- package/.aict/skills/evidence-pack/SKILL.md +42 -0
- package/.aict/skills/guard/SKILL.md +46 -0
- package/.aict/skills/handoff/SKILL.md +44 -0
- package/.aict/skills/harvest/SKILL.md +44 -0
- package/.aict/skills/mode-switch/SKILL.md +42 -0
- package/.aict/skills/profile/SKILL.md +42 -0
- package/.aict/skills/red-team/SKILL.md +42 -0
- package/.aict/skills/single-tool-guard/SKILL.md +42 -0
- package/.aict/state/CURRENT_STATE.md +13 -0
- package/.aict/state/DECISIONS.md +7 -0
- package/.aict/state/TASK_LOG.md +7 -0
- package/.aict/state/evidence.jsonl +2 -0
- package/.aict/state/learning-ledger.jsonl +1 -0
- package/.aict/state/receipts.jsonl +1 -0
- package/.aict/state/runs.jsonl +1 -0
- package/.aict/state/tasks.jsonl +1 -0
- package/.aict/walkthroughs/10-minute-your-task.md +107 -0
- package/.aict/walkthroughs/10-minute.md +43 -0
- package/.aict/walkthroughs/30-minute.md +22 -0
- package/.aict/walkthroughs/60-minute.md +27 -0
- package/.aict/walkthroughs/synthetic-loop-transcript.md +43 -0
- package/CHANGELOG.md +23 -0
- package/CODE_OF_CONDUCT.md +20 -0
- package/CONTRIBUTING.md +30 -0
- package/KNOWN_LIMITATIONS.md +54 -0
- package/LICENSE +199 -0
- package/PRODUCT_CONTRACT.md +446 -0
- package/README.md +245 -0
- package/RELEASE_CHECKLIST.md +78 -0
- package/SECURITY.md +56 -0
- package/START_HERE.md +89 -0
- package/bin/ai-collab.js +2 -0
- package/docs/DOGFOOD.md +85 -0
- package/docs/FEEDBACK.md +61 -0
- package/docs/FIRST_EXPERIENCE_SPEC.md +32 -0
- package/docs/FREE_VS_PAID.md +53 -0
- package/docs/PUBLIC_BOUNDARY.md +36 -0
- package/docs/PUBLIC_MAPPING.md +178 -0
- package/docs/RELEASE_PRIORITY.md +23 -0
- package/docs/WHY_THIS_EXISTS.md +36 -0
- package/docs/open-system/00-start-here.md +60 -0
- package/docs/open-system/01-ai-collaboration-os.md +33 -0
- package/docs/open-system/02-six-layer-architecture.md +45 -0
- package/docs/open-system/03-role-system.md +33 -0
- package/docs/open-system/04-core-mechanisms.md +34 -0
- package/docs/open-system/05-failure-patterns.md +31 -0
- package/docs/open-system/06-how-to-adapt-to-your-workflow.md +31 -0
- package/package.json +69 -0
- package/privacy-manifest.json +78 -0
- package/privacy-scan.local.json.example +18 -0
- package/scripts/lib/forbidden-in-pack.js +55 -0
- package/scripts/pack-check.js +154 -0
- package/scripts/privacy-scan.js +487 -0
- package/scripts/validate-contract.js +160 -0
- package/src/adapters.js +590 -0
- package/src/bootstrap.js +1184 -0
- package/src/catalog.js +2723 -0
- package/src/cli.js +2899 -0
- package/src/dialogue.js +470 -0
- package/src/i18n.js +1034 -0
- package/src/ledger.js +2011 -0
- package/src/render.js +1381 -0
- package/src/sendmodel.js +452 -0
- package/src/validate.js +1307 -0
- package/src/workspace.js +1679 -0
- package/tests/contract.test.js +8514 -0
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# 04 Core Mechanisms
|
|
2
|
+
|
|
3
|
+
The AI Collaboration Open System ships local-first mechanism packages in `.aict/mechanisms/`. Each package has README, prompt, template, synthetic example, and failure modes.
|
|
4
|
+
|
|
5
|
+
## Mechanisms
|
|
6
|
+
|
|
7
|
+
- Dual Guard: a cross-family guard is the binding gate and a same-family guard is a non-binding reference, so a fluent answer is not trusted just because it reads well; passes merge by strictness, where one evidence-grounded blocker outweighs fluent approval.
|
|
8
|
+
- SCOUT Review Controller: exploration, challenge, and controller decision stay separate.
|
|
9
|
+
- One-Click Dispatch: compact work packet for another AI tool.
|
|
10
|
+
- Task Splitting: a five-question pre-dispatch self-check; if any answer is yes, split the task by topic or deliverable (not line count) into self-contained sub-packets so an oversized prompt does not stall or degrade.
|
|
11
|
+
- Anti-Drift Partner: a long thinking conversation with an AI that pushes back instead of agreeing — it surfaces blind spots, probes at most two rounds, then commits to a judgment, so the talk never drifts into fluent confirmation.
|
|
12
|
+
- Blind-Spot Scan: borrows an outside viewpoint (customer, competitor, expert, opponent, your-future-self), re-reads the decision through that seat, and returns the concrete dead angles you cannot see from your own plus the one counter-question most worth sitting with — and the borrowed viewpoint must genuinely challenge, never flatter from a costume.
|
|
13
|
+
- Root-Cause Brake: when the same artifact is rejected twice in a row, the brake trips — no more patches until four diagnostic questions are answered, the real cause is named, and the next version is rebuilt around it.
|
|
14
|
+
- Half-Product Review: blocks release claims when docs outrun runnable proof.
|
|
15
|
+
- Handoff A/B/C: three handoff modes for three situations - A high-interaction (lightweight same-tool resume), B programmatic (a defined task an executor drives to completion), C delivery overview (a human-facing account of a finished phase) - all carrying the same load-bearing fields.
|
|
16
|
+
- Harvest and External Recap: a conversation is swept into harvest cards (one per decision, lesson, method, or stable preference), the human confirms them, and redaction runs before filing; External Recap is a separate role that recaps many conversations at once, gated by a double lock (a fresh session plus an explicit human declaration).
|
|
17
|
+
- Do Not Handle Yet: parks tempting adjacent work without losing it.
|
|
18
|
+
- Plain-Language First Screen: makes the first user view runnable before theoretical.
|
|
19
|
+
- Honest Calibration: leads every ask for a rating or recommendation with a short candor prefix (be candid, do not inflate, do not over-hedge) that offsets the model's pull to please and re-aims the baseline from make-you-happy to tell-the-truth.
|
|
20
|
+
- Feedback-Absorption Ledger: when merging feedback from several sources, scores each item across five tiers (absorb fully / refine / add a boundary / partly absorb / reject with a reason) so independent judgment is kept instead of rubber-stamping — the absorb/reject ratio is an outcome, not a target.
|
|
21
|
+
- Collaboration Coach: the assistant proactively reminds the user of the matching collaboration step at six recurring moments (define done, review a completion claim, hand off, harvest, update the profile), restrained by default — once per moment, never every turn, because over-prompting is the fastest way to get the system uninstalled.
|
|
22
|
+
- Single-Tool Guard: the default starting guard for a one-model-family user — a new conversation plus an adversarial reviewer prompt — whose verdict is always labeled single-family-only with the residual risk named, honestly capped at L2 and never recorded as a passed cross-family binding gate, which is the upgrade ceiling.
|
|
23
|
+
|
|
24
|
+
## How to use a mechanism
|
|
25
|
+
|
|
26
|
+
1. Open the mechanism package.
|
|
27
|
+
2. Fill the template with redacted local material.
|
|
28
|
+
3. Paste the prompt plus context and acceptance into your AI tool.
|
|
29
|
+
4. Save the result into handoff or harvest.
|
|
30
|
+
5. Run guard review if the result will be trusted by another session.
|
|
31
|
+
|
|
32
|
+
## Why mechanisms are public-safe
|
|
33
|
+
|
|
34
|
+
They preserve the workflow shape without exposing private profiles, source conversations, non-public routes, or account material.
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# 05 Failure Patterns
|
|
2
|
+
|
|
3
|
+
AI Collaboration Open System exists because local-first AI work fails in repeatable ways when everything stays inside a single chat.
|
|
4
|
+
|
|
5
|
+
## Smooth wrong answer
|
|
6
|
+
|
|
7
|
+
The assistant gives a confident answer before acceptance exists. Fix: write acceptance first and run guard review after the artifact.
|
|
8
|
+
|
|
9
|
+
## Scope drift
|
|
10
|
+
|
|
11
|
+
A coding task becomes design, research, and release work in one response. Fix: use task splitting and do-not-handle-yet.
|
|
12
|
+
|
|
13
|
+
## Half product
|
|
14
|
+
|
|
15
|
+
README, architecture, or launch copy claims more than the runnable files prove. Fix: run half-product review and package smoke checks.
|
|
16
|
+
|
|
17
|
+
## Lost handoff
|
|
18
|
+
|
|
19
|
+
A later session restarts because the previous chat never separated done, pending, blocked, and unverified. Fix: write handoff before stopping.
|
|
20
|
+
|
|
21
|
+
## No harvest
|
|
22
|
+
|
|
23
|
+
The same lesson is rediscovered every week. Fix: extract one reusable harvest seed after each meaningful loop.
|
|
24
|
+
|
|
25
|
+
## Privacy erosion
|
|
26
|
+
|
|
27
|
+
Useful examples slowly accumulate private details. Fix: rewrite cases as synthetic labs and run the privacy scan before packaging.
|
|
28
|
+
|
|
29
|
+
## Human judgment replaced
|
|
30
|
+
|
|
31
|
+
The AI starts deciding values, risk tolerance, or product direction. Fix: keep controller and guardian roles separate and mark decisions that need the user.
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# 06 How to Adapt to Your Workflow
|
|
2
|
+
|
|
3
|
+
AI Collaboration Open System is local-first and tool-agnostic. You adapt it by copying files into the AI tools you already use.
|
|
4
|
+
|
|
5
|
+
## Codex
|
|
6
|
+
|
|
7
|
+
Paste the shared contract, context package, and acceptance card into the task. Ask Codex to return changed files, checks run, failures, and unverified areas.
|
|
8
|
+
|
|
9
|
+
## Claude Code
|
|
10
|
+
|
|
11
|
+
Use the same context and acceptance files. For review work, ask Claude Code to act as system guardian and lead with findings.
|
|
12
|
+
|
|
13
|
+
## Cursor or Copilot
|
|
14
|
+
|
|
15
|
+
Keep the shared contract in project instructions. For each task, attach context and acceptance, then save a handoff note before stopping.
|
|
16
|
+
|
|
17
|
+
## Cline or Windsurf
|
|
18
|
+
|
|
19
|
+
Use adapter guidance as a thin pointer to `.aict/`. Do not maintain a second rule system inside the tool.
|
|
20
|
+
|
|
21
|
+
## Team workflow
|
|
22
|
+
|
|
23
|
+
1. Keep `.aict/` in a repo or local folder.
|
|
24
|
+
2. Redact before sharing.
|
|
25
|
+
3. Make every long task produce context, acceptance, guard, handoff, and harvest.
|
|
26
|
+
4. Use mechanisms only when they reduce real risk or drift.
|
|
27
|
+
5. Run `ai-collab check --workspace <dir>` before trusting a generated workspace.
|
|
28
|
+
|
|
29
|
+
## Adaptation rule
|
|
30
|
+
|
|
31
|
+
Change examples and language freely, but keep the loop: context before execution, acceptance before completion, guard before trust, handoff before switching, harvest after learning.
|
package/package.json
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "ai-collab-open-system",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Local-first open-source AI collaboration workspace with profile, context, acceptance, guard, handoff, and harvest structure.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"ai-collab": "./bin/ai-collab.js"
|
|
8
|
+
},
|
|
9
|
+
"scripts": {
|
|
10
|
+
"test": "node --test",
|
|
11
|
+
"contract:check": "node scripts/validate-contract.js",
|
|
12
|
+
"privacy:scan": "node scripts/privacy-scan.js",
|
|
13
|
+
"pack:check": "node scripts/pack-check.js",
|
|
14
|
+
"check": "node --test && node scripts/validate-contract.js && node scripts/privacy-scan.js && node scripts/pack-check.js",
|
|
15
|
+
"prepublishOnly": "npm run check"
|
|
16
|
+
},
|
|
17
|
+
"keywords": [
|
|
18
|
+
"ai",
|
|
19
|
+
"collaboration",
|
|
20
|
+
"local-first",
|
|
21
|
+
"workspace",
|
|
22
|
+
"codex",
|
|
23
|
+
"claude-code",
|
|
24
|
+
"cursor",
|
|
25
|
+
"agents",
|
|
26
|
+
"handoff",
|
|
27
|
+
"guard-review"
|
|
28
|
+
],
|
|
29
|
+
"author": {
|
|
30
|
+
"name": "Aaron Yi",
|
|
31
|
+
"email": "yi19970319@gmail.com",
|
|
32
|
+
"url": "https://x.com/AaronYiaazw"
|
|
33
|
+
},
|
|
34
|
+
"license": "Apache-2.0",
|
|
35
|
+
"repository": {
|
|
36
|
+
"type": "git",
|
|
37
|
+
"url": "git+https://github.com/aaronyi97/ai-collab-open-system.git"
|
|
38
|
+
},
|
|
39
|
+
"bugs": {
|
|
40
|
+
"url": "https://github.com/aaronyi97/ai-collab-open-system/issues"
|
|
41
|
+
},
|
|
42
|
+
"homepage": "https://github.com/aaronyi97/ai-collab-open-system#readme",
|
|
43
|
+
"files": [
|
|
44
|
+
".aict",
|
|
45
|
+
"bin",
|
|
46
|
+
"docs",
|
|
47
|
+
"scripts",
|
|
48
|
+
"src",
|
|
49
|
+
"tests",
|
|
50
|
+
"README.md",
|
|
51
|
+
"START_HERE.md",
|
|
52
|
+
"PRODUCT_CONTRACT.md",
|
|
53
|
+
"CHANGELOG.md",
|
|
54
|
+
"KNOWN_LIMITATIONS.md",
|
|
55
|
+
"RELEASE_CHECKLIST.md",
|
|
56
|
+
"privacy-manifest.json",
|
|
57
|
+
"privacy-scan.local.json.example",
|
|
58
|
+
"LICENSE",
|
|
59
|
+
"CONTRIBUTING.md",
|
|
60
|
+
"SECURITY.md",
|
|
61
|
+
"CODE_OF_CONDUCT.md"
|
|
62
|
+
],
|
|
63
|
+
"engines": {
|
|
64
|
+
"node": ">=18"
|
|
65
|
+
},
|
|
66
|
+
"publishConfig": {
|
|
67
|
+
"access": "public"
|
|
68
|
+
}
|
|
69
|
+
}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
{
|
|
2
|
+
"localFirst": true,
|
|
3
|
+
"defaultNetworkUse": "none",
|
|
4
|
+
"publicAllowed": [
|
|
5
|
+
"generic architecture",
|
|
6
|
+
"generic prompts",
|
|
7
|
+
"generic templates",
|
|
8
|
+
"thin tool adapters",
|
|
9
|
+
"synthetic examples",
|
|
10
|
+
"privacy docs",
|
|
11
|
+
"setup docs",
|
|
12
|
+
"self-build guide",
|
|
13
|
+
"known limitations"
|
|
14
|
+
],
|
|
15
|
+
"publicForbidden": [
|
|
16
|
+
"real private governance contents",
|
|
17
|
+
"private knowledge-base source material",
|
|
18
|
+
"real personal profile",
|
|
19
|
+
"actual client material",
|
|
20
|
+
"raw private conversations",
|
|
21
|
+
"non-public automation details",
|
|
22
|
+
"non-public routing details",
|
|
23
|
+
"internal calibration thresholds",
|
|
24
|
+
"internal scoring weights",
|
|
25
|
+
"account-specific habits",
|
|
26
|
+
"local machine paths",
|
|
27
|
+
"tokens, keys, cookies, credentials",
|
|
28
|
+
"unredacted screenshots",
|
|
29
|
+
"full internal service SOP"
|
|
30
|
+
],
|
|
31
|
+
"scanner": "scripts/privacy-scan.js",
|
|
32
|
+
"publicContactsComment": "EXACT-string allowlist for the privacy scanner's email rule. The scanner blocks EVERY email address EXCEPT one that exactly matches an entry here — this is a narrow, explainable exemption for the project's PUBLISHED public contact only, NOT a domain or category allowlist (a different address, even at the same domain, still fails the scan). Keep this to the maintainer's intentionally-public contact email; never add a customer/private address here.",
|
|
33
|
+
"publicContacts": [
|
|
34
|
+
"yi19970319@gmail.com"
|
|
35
|
+
],
|
|
36
|
+
"scanDenylist": {
|
|
37
|
+
"comment": "Maintainable central denylist consumed by scripts/privacy-scan.js. Extend these arrays to harden the gate without touching scanner code. Keep entries PUBLIC-SAFE and GENERIC (anyone-applies): list generic markers and placeholders, never paste a real secret/customer/path or your OWN private directory name here (this manifest ships in the public package and is itself scanned). For YOUR personal private dir names / terms, use the gitignored local override instead — copy privacy-scan.local.json.example to privacy-scan.local.json; the scanner merges it on top of this list.",
|
|
38
|
+
"paths": [
|
|
39
|
+
".claude/hooks"
|
|
40
|
+
],
|
|
41
|
+
"pathsComment": ".claude/hooks is the standard Claude Code hooks directory every Claude Code user has, kept as a GENERIC marker so a user does not paste their own private hook contents. Add your personal private dirs via privacy-scan.local.json, not here.",
|
|
42
|
+
"terms": [],
|
|
43
|
+
"chineseTerms": [
|
|
44
|
+
"真实客户",
|
|
45
|
+
"真实项目",
|
|
46
|
+
"客户名单",
|
|
47
|
+
"原始对话",
|
|
48
|
+
"内部路由",
|
|
49
|
+
"内部阈值",
|
|
50
|
+
"内部权重",
|
|
51
|
+
"私有治理",
|
|
52
|
+
"私有体系",
|
|
53
|
+
"知识库源料"
|
|
54
|
+
]
|
|
55
|
+
},
|
|
56
|
+
"bilingual": {
|
|
57
|
+
"comment": "The repo is intentionally bilingual: it ships a sanctioned Chinese onboarding surface alongside English. These rules tell the Chinese-leak heuristic which Chinese is allowed, so legitimate bilingual UX does not trip the gate while stray (unmarked) Chinese — a likely sign of pasted private material — still fails. sectionMarkers open a sanctioned bilingual block for the next contextWindow lines; lineAllow exempts a single line; zhKeyAllowed exempts localized `zh:` strings; sanctionedFiles names whole-file bilingual SOURCES (the i18n message catalog + its tests) where the unmarked-run heuristic is relaxed — the token/key/local-path/email rules and the chineseTerms denylist still apply to them.",
|
|
58
|
+
"sectionMarkers": [
|
|
59
|
+
"中文",
|
|
60
|
+
"Chinese positioning",
|
|
61
|
+
"Chinese path",
|
|
62
|
+
"Keyword-triggered modes"
|
|
63
|
+
],
|
|
64
|
+
"lineAllow": [
|
|
65
|
+
"AI \\u534f\\u4f5c",
|
|
66
|
+
"\\u672c\\u5730\\u4f18\\u5148"
|
|
67
|
+
],
|
|
68
|
+
"sanctionedFiles": [
|
|
69
|
+
"src/i18n.js",
|
|
70
|
+
"src/dialogue.js",
|
|
71
|
+
"tests/contract.test.js"
|
|
72
|
+
],
|
|
73
|
+
"sanctionedFilesComment": "src/i18n.js is the bilingual message catalog (EN canonical + ZH faithful) — it is densely Chinese BY DESIGN, so the unmarked-run heuristic only produces noise there. src/dialogue.js is the dialogue-scan module: it ships Chinese completion/correction MARKER WORD TABLES (e.g. 已完成 / 搞定 / 不对) it must match against a user's bilingual chat export, so it carries sanctioned product Chinese by design. tests/contract.test.js asserts the localized ZH output (the honesty translations), so it too carries sanctioned product Chinese. All three remain subject to the hard token/key/local-path/email rules and the chineseTerms private-term denylist.",
|
|
74
|
+
"zhKeyAllowed": true,
|
|
75
|
+
"contextWindow": 12,
|
|
76
|
+
"minRun": 4
|
|
77
|
+
}
|
|
78
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"_comment": "OPTIONAL local override for the privacy scanner. Copy this file to `privacy-scan.local.json` (which is gitignored and never published) and add YOUR OWN private identifiers. The public package intentionally ships only GENERIC markers (emails, API keys, phone numbers, absolute /Users paths, .env, .pem/.key, .claude config) that apply to everyone. Your personal private directory names and private terms do not belong in the public manifest, so list them here instead. The scanner merges this file on top of privacy-manifest.json's scanDenylist when present.",
|
|
3
|
+
|
|
4
|
+
"_worked_example_comment": "WORKED EXAMPLE (this is exactly how THIS project's maintainer uses the override; the names are shown here only as a pattern to copy — the active arrays below stay as placeholders so the published .example file does not itself bake in any private dir name). The maintainer keeps a personal governance directory and a personal knowledge base on disk; their REAL gitignored privacy-scan.local.json adds both names to `paths`, e.g. paths: [\"<your-private-governance-dir>\", \"<your-knowledge-base-dir>\"]. With those entries present, any file the scanner reads that mentions either folder name FAILS the scan (reported as a denylisted path) and is also blocked from the npm tarball — so a stray reference to your private governance/knowledge dirs can never ship. Copy this file, then replace the two placeholders below with your own real folder names.",
|
|
5
|
+
|
|
6
|
+
"paths": [
|
|
7
|
+
"<your-private-governance-dir>",
|
|
8
|
+
"<your-knowledge-base-dir>"
|
|
9
|
+
],
|
|
10
|
+
|
|
11
|
+
"_paths_comment": "Substring path markers to forbid in scanned file CONTENT, and to block from the npm tarball. Replace the placeholders with the names of your own private dirs (e.g. a personal governance folder or knowledge base — see the worked example above). Leave empty if you have none.",
|
|
12
|
+
|
|
13
|
+
"terms": [],
|
|
14
|
+
"_terms_comment": "Plain (English/ASCII) private terms to forbid in scanned content (e.g. an internal codename).",
|
|
15
|
+
|
|
16
|
+
"chineseTerms": [],
|
|
17
|
+
"_chineseTerms_comment": "Chinese private terms to forbid in scanned content."
|
|
18
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
// Single source of truth for the "must never ship in the npm tarball" rules.
|
|
2
|
+
//
|
|
3
|
+
// Both scripts/privacy-scan.js (which scans `npm pack --dry-run` output as one of
|
|
4
|
+
// its surfaces) and scripts/pack-check.js (the standalone release-safety gate)
|
|
5
|
+
// enforce this list. Keeping it in one module prevents the two copies from
|
|
6
|
+
// drifting apart — a divergence would mean one gate blocks a private file while
|
|
7
|
+
// the other silently ships it.
|
|
8
|
+
//
|
|
9
|
+
// Each entry is [RegExp, humanLabel]. The regex is tested against a pack file
|
|
10
|
+
// path (POSIX-style, as npm reports it). `.git/` and `node_modules/` are included
|
|
11
|
+
// here as regexes so a single shared list fully covers the forbidden surface.
|
|
12
|
+
//
|
|
13
|
+
// Only GENERIC, anyone-applies markers live here as literals (a `.env`, a
|
|
14
|
+
// `.claude/` config dir, a backup file, a secret/key). A maintainer's OWN private
|
|
15
|
+
// directory names are NOT hard-coded here (that would ship the maintainer's
|
|
16
|
+
// private dir name inside the public package). Instead, callers pass their own
|
|
17
|
+
// private dir names via `extraPrivateDirs` — sourced from a gitignored local
|
|
18
|
+
// config (see privacy-scan.local.json.example) — so the protection stays
|
|
19
|
+
// configurable while the shipped code stays generic.
|
|
20
|
+
|
|
21
|
+
export const FORBIDDEN_IN_PACK = [
|
|
22
|
+
[/(^|\/)\.env(\.|$)/i, ".env file"],
|
|
23
|
+
[/(^|\/)\.claude(\/|$)/i, "private Claude config dir"],
|
|
24
|
+
[/\.aict-backup-/i, "adapter backup file"],
|
|
25
|
+
[/\.aict\.backup-/i, "workspace backup file"],
|
|
26
|
+
[/(^|\/)(secrets?|credentials?)(\.|\/|$)/i, "secrets/credentials file"],
|
|
27
|
+
[/\.(pem|key|p12|pfx)$/i, "private key material"],
|
|
28
|
+
[/(^|\/)node_modules\//i, "node_modules"],
|
|
29
|
+
[/(^|\/)\.git\//i, ".git internals"]
|
|
30
|
+
];
|
|
31
|
+
|
|
32
|
+
// Build a pack rule that blocks a user-configured private directory (matched as a
|
|
33
|
+
// path segment, the same way the literal rules above match `.claude/`). The dir
|
|
34
|
+
// name is escaped so it is treated literally, not as a regex.
|
|
35
|
+
function privateDirRule(dir) {
|
|
36
|
+
const safe = String(dir).replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
37
|
+
return [new RegExp(`(^|/)${safe}(/|$)`, "i"), `configured private dir (${dir})`];
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// Return the list of "{label}: {file}" violations for a set of pack file paths.
|
|
41
|
+
// `extraPrivateDirs` lets a caller add their own private dir names (from a local,
|
|
42
|
+
// gitignored config) without those names ever being baked into this shipped file.
|
|
43
|
+
export function findForbiddenPackFiles(files, extraPrivateDirs = []) {
|
|
44
|
+
const rules = [
|
|
45
|
+
...FORBIDDEN_IN_PACK,
|
|
46
|
+
...(extraPrivateDirs ?? []).filter(Boolean).map(privateDirRule)
|
|
47
|
+
];
|
|
48
|
+
const violations = [];
|
|
49
|
+
for (const file of files) {
|
|
50
|
+
for (const [regex, label] of rules) {
|
|
51
|
+
if (regex.test(file)) violations.push({ file, label });
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return violations;
|
|
55
|
+
}
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { execFileSync } from "node:child_process";
|
|
3
|
+
import { existsSync, mkdtempSync, readFileSync } from "node:fs";
|
|
4
|
+
import { tmpdir } from "node:os";
|
|
5
|
+
import path from "node:path";
|
|
6
|
+
import { findForbiddenPackFiles } from "./lib/forbidden-in-pack.js";
|
|
7
|
+
|
|
8
|
+
const repoRoot = path.resolve(new URL("..", import.meta.url).pathname);
|
|
9
|
+
|
|
10
|
+
// Private dir names to also block from the tarball, sourced exactly like the
|
|
11
|
+
// privacy scanner: generic markers live in the shared forbidden-in-pack rules,
|
|
12
|
+
// while a maintainer's OWN private dir names come from the (shipped, generic)
|
|
13
|
+
// manifest denylist plus an optional gitignored local override — never baked
|
|
14
|
+
// into the shared shipped module. Keeps both gates aligned with no drift.
|
|
15
|
+
function readJsonIfPresent(file) {
|
|
16
|
+
if (!existsSync(file)) return null;
|
|
17
|
+
try {
|
|
18
|
+
return JSON.parse(readFileSync(file, "utf8"));
|
|
19
|
+
} catch {
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function resolveConfiguredPrivateDirs() {
|
|
25
|
+
const manifest = readJsonIfPresent(path.join(repoRoot, "privacy-manifest.json"));
|
|
26
|
+
const local = readJsonIfPresent(path.join(repoRoot, "privacy-scan.local.json"));
|
|
27
|
+
const dirs = [
|
|
28
|
+
...(manifest?.scanDenylist?.paths ?? []),
|
|
29
|
+
...(local?.paths ?? [])
|
|
30
|
+
];
|
|
31
|
+
return [...new Set(dirs.filter((entry) => typeof entry === "string" && entry.length > 0))];
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const configuredPrivateDirs = resolveConfiguredPrivateDirs();
|
|
35
|
+
|
|
36
|
+
function parseArgs(argv) {
|
|
37
|
+
const args = {};
|
|
38
|
+
for (let index = 0; index < argv.length; index += 1) {
|
|
39
|
+
if (argv[index] === "--cache") {
|
|
40
|
+
args.cache = argv[index + 1];
|
|
41
|
+
index += 1;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
return args;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function fail(errors) {
|
|
48
|
+
console.error(`Pack check failed:\n${errors.map((error) => `- ${error}`).join("\n")}`);
|
|
49
|
+
process.exit(1);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// `npm pack` wants to write logs to npm's cache dir (~/.npm/_logs by default). In a
|
|
53
|
+
// strict read-only sandbox that is not writable and npm dies with a cryptic ENOENT
|
|
54
|
+
// mkdir on the log dir. Point npm at a writable cache: an explicit --cache, an
|
|
55
|
+
// existing npm_config_cache, or a fresh temp dir we create. If even the temp dir is
|
|
56
|
+
// unwritable, surface a clear hint instead of the raw EPERM.
|
|
57
|
+
function resolveCache(args) {
|
|
58
|
+
if (args.cache) return { cache: path.resolve(args.cache), created: false };
|
|
59
|
+
if (process.env.npm_config_cache) return { cache: process.env.npm_config_cache, created: false };
|
|
60
|
+
try {
|
|
61
|
+
return { cache: mkdtempSync(path.join(tmpdir(), "aicos-npm-cache-")), created: true };
|
|
62
|
+
} catch (error) {
|
|
63
|
+
return { cache: null, error };
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const args = parseArgs(process.argv.slice(2));
|
|
68
|
+
const { cache, error: cacheError } = resolveCache(args);
|
|
69
|
+
|
|
70
|
+
if (!cache) {
|
|
71
|
+
fail([
|
|
72
|
+
`cannot create a writable npm cache (${cacheError?.code || cacheError?.message}).`,
|
|
73
|
+
`In a read-only sandbox, point npm at a writable dir and re-run:`,
|
|
74
|
+
` node scripts/pack-check.js --cache <writable-dir>`,
|
|
75
|
+
` (or: npm_config_cache=<writable-dir> node scripts/pack-check.js)`
|
|
76
|
+
]);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
let output;
|
|
80
|
+
try {
|
|
81
|
+
output = execFileSync("npm", ["pack", "--dry-run", "--json", "--cache", cache], {
|
|
82
|
+
cwd: repoRoot,
|
|
83
|
+
encoding: "utf8",
|
|
84
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
85
|
+
env: { ...process.env, npm_config_cache: cache }
|
|
86
|
+
});
|
|
87
|
+
} catch (error) {
|
|
88
|
+
fail([
|
|
89
|
+
`npm pack --dry-run failed (${error.code || "error"}).`,
|
|
90
|
+
`If this is an EPERM/ENOENT writing npm logs in a read-only sandbox, pass a writable cache:`,
|
|
91
|
+
` node scripts/pack-check.js --cache <writable-dir>`,
|
|
92
|
+
error.stderr ? `npm said: ${String(error.stderr).trim().split("\n").slice(-3).join(" | ")}` : `(${error.message})`
|
|
93
|
+
]);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const [pack] = JSON.parse(output);
|
|
97
|
+
const files = new Set(pack.files.map((file) => file.path));
|
|
98
|
+
const errors = [];
|
|
99
|
+
|
|
100
|
+
for (const required of [
|
|
101
|
+
"README.md",
|
|
102
|
+
"START_HERE.md",
|
|
103
|
+
"PRODUCT_CONTRACT.md",
|
|
104
|
+
"CHANGELOG.md",
|
|
105
|
+
"RELEASE_CHECKLIST.md",
|
|
106
|
+
"privacy-manifest.json",
|
|
107
|
+
"CONTRIBUTING.md",
|
|
108
|
+
"SECURITY.md",
|
|
109
|
+
"CODE_OF_CONDUCT.md",
|
|
110
|
+
"bin/ai-collab.js",
|
|
111
|
+
"src/cli.js",
|
|
112
|
+
"scripts/validate-contract.js",
|
|
113
|
+
"docs/WHY_THIS_EXISTS.md",
|
|
114
|
+
"docs/PUBLIC_MAPPING.md",
|
|
115
|
+
"docs/open-system/00-start-here.md",
|
|
116
|
+
".aict/START_HERE.md",
|
|
117
|
+
".aict/adapters/SHARED_CORE_CONTRACT.md",
|
|
118
|
+
".aict/examples/ai-coding-long-task/CASE.md",
|
|
119
|
+
".aict/mechanisms/dual-guard/README.md",
|
|
120
|
+
".aict/roles/README.md",
|
|
121
|
+
".aict/modes/README.md",
|
|
122
|
+
".aict/cookbook/README.md",
|
|
123
|
+
".aict/state/CURRENT_STATE.md",
|
|
124
|
+
".aict/state/tasks.jsonl",
|
|
125
|
+
".aict/state/evidence.jsonl",
|
|
126
|
+
".aict/state/runs.jsonl",
|
|
127
|
+
".aict/state/receipts.jsonl",
|
|
128
|
+
".aict/state/learning-ledger.jsonl",
|
|
129
|
+
".aict/privacy/PRIVACY.md"
|
|
130
|
+
]) {
|
|
131
|
+
if (!files.has(required)) errors.push(`package missing ${required}`);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// Defense in depth: the privacy scanner also checks the pack file list, but keep a
|
|
135
|
+
// hard block here so a private file can never ship even if the scanner is skipped.
|
|
136
|
+
// The forbidden-file rules (including .git/ and node_modules/) live in the shared
|
|
137
|
+
// scripts/lib/forbidden-in-pack.js so this gate and the privacy scanner never drift.
|
|
138
|
+
for (const { label, file } of findForbiddenPackFiles([...files], configuredPrivateDirs)) {
|
|
139
|
+
errors.push(`package would ship ${label}: ${file}`);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
if (pack.size <= 0 || pack.unpackedSize <= 0) {
|
|
143
|
+
errors.push("package size metadata is empty");
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
if (errors.length > 0) {
|
|
147
|
+
fail(errors);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
console.log(`Pack check passed.
|
|
151
|
+
Files packed: ${pack.entryCount}
|
|
152
|
+
Package: ${pack.filename}
|
|
153
|
+
Cache: ${cache}
|
|
154
|
+
`);
|