feat: port opensoft/oh-my-opencode as learn-only external project review
This commit is contained in:
parent
73b55e1684
commit
78667dd93c
|
|
@ -388,6 +388,8 @@ fable-agent plinius godmode "improve explanation quality"
|
|||
- `--output <path>`
|
||||
- `fable5 opencoven-review`
|
||||
- `--output <path>`
|
||||
- `fable5 opencode-review`
|
||||
- `--output <path>`
|
||||
- `fable5 permission-posture`
|
||||
- `--mode <mode>`
|
||||
- `--output <path>`
|
||||
|
|
|
|||
|
|
@ -47,6 +47,14 @@ describe("external project review receipts", () => {
|
|||
expect(receipt.risks).toContain("security findings need local repro receipts");
|
||||
});
|
||||
|
||||
it("records oh-my-opencode as learn-only OpenCode config research", () => {
|
||||
const receipt = createSkillsRepoReviewReceipt("opensoft/oh-my-opencode", new Date("2026-07-03T00:00:00.000Z"));
|
||||
|
||||
expect(receipt).toMatchObject({ repo: "opensoft/oh-my-opencode", license: "NOASSERTION", safeToVendor: false, decision: "learn-only", deployAttempted: false });
|
||||
expect(receipt.patternsLearned).toContain("OpenCode workflow/config packaging");
|
||||
expect(receipt.risks).toContain("OpenCode config must not become deploy authority");
|
||||
});
|
||||
|
||||
it("records deploy-gated permission posture without opening 8098", () => {
|
||||
const receipt = createPermissionPostureReceipt("deploy-gated", new Date("2026-07-01T00:00:00.000Z"));
|
||||
|
||||
|
|
|
|||
|
|
@ -60,8 +60,10 @@ export function createOpenCovenReviewReceipt(now = new Date()): ExternalProjectR
|
|||
}
|
||||
|
||||
|
||||
export function createSkillsRepoReviewReceipt(repo: "mattpocock/skills" | "AI-Builder-Club/skills" | "affaan-m/ECC" | "ashp15205/scankii", now = new Date()): ExternalProjectReviewReceipt {
|
||||
const rows: Record<typeof repo, Omit<ExternalProjectReviewReceipt, "schema" | "createdAt" | "repo" | "deployAttempted">> = {
|
||||
export type ReviewedExternalRepo = "mattpocock/skills" | "AI-Builder-Club/skills" | "affaan-m/ECC" | "ashp15205/scankii" | "opensoft/oh-my-opencode";
|
||||
|
||||
export function createSkillsRepoReviewReceipt(repo: ReviewedExternalRepo, now = new Date()): ExternalProjectReviewReceipt {
|
||||
const rows: Record<ReviewedExternalRepo, Omit<ExternalProjectReviewReceipt, "schema" | "createdAt" | "repo" | "deployAttempted">> = {
|
||||
"mattpocock/skills": {
|
||||
url: "https://github.com/mattpocock/skills",
|
||||
license: "MIT",
|
||||
|
|
@ -102,6 +104,16 @@ export function createSkillsRepoReviewReceipt(repo: "mattpocock/skills" | "AI-Bu
|
|||
decision: "learn-only",
|
||||
policy: "learn-patterns-no-vendored-code",
|
||||
},
|
||||
"opensoft/oh-my-opencode": {
|
||||
url: "https://github.com/opensoft/oh-my-opencode",
|
||||
license: "NOASSERTION",
|
||||
safeToVendor: false,
|
||||
patternsLearned: ["OpenCode workflow/config packaging", "agent CLI ergonomics", "portable local agent defaults"],
|
||||
adaptations: ["keep OpenCode behind existing CLI executor seams", "record repo as advisory until contents/license are verified", "rewrite useful config patterns locally with tests"],
|
||||
risks: ["repository content was not fetched or verified", "license is not asserted so vendoring stays blocked", "OpenCode config must not become deploy authority"],
|
||||
decision: "learn-only",
|
||||
policy: "learn-patterns-no-vendored-code",
|
||||
},
|
||||
};
|
||||
return { schema: "fable.external_project.review.v1", createdAt: now.toISOString(), repo, ...rows[repo], deployAttempted: false };
|
||||
}
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ export { createExternalToolAuditReceipt, DICKLESWORTHSTONE_TOOL_ROWS, writeExter
|
|||
export type { ExternalToolAuditReceipt, ExternalToolAuditRow, ExternalToolAuditStatus } from "./external-tool-audit.js";
|
||||
|
||||
export { createOpenCovenReviewReceipt, createPermissionPostureReceipt, createSkillsRepoReviewReceipt, writeExternalProjectReviewReceipt } from "./external-project-review.js";
|
||||
export type { ExternalProjectDecision, ExternalProjectReviewReceipt, PermissionMode, PermissionPostureReceipt } from "./external-project-review.js";
|
||||
export type { ExternalProjectDecision, ExternalProjectReviewReceipt, PermissionMode, PermissionPostureReceipt, ReviewedExternalRepo } from "./external-project-review.js";
|
||||
|
||||
export { createFactoryMemoryQuarantineReceipt, createStaleMemoryQuarantineReceipt, writeStaleMemoryQuarantineReceipt } from "./stale-memory-quarantine.js";
|
||||
export type { StaleMemoryClaim, StaleMemoryQuarantineReceipt, StaleMemorySeverity } from "./stale-memory-quarantine.js";
|
||||
|
|
|
|||
15
src/index.ts
15
src/index.ts
|
|
@ -2287,6 +2287,21 @@ fable
|
|||
`);
|
||||
});
|
||||
|
||||
fable
|
||||
.command("opencode-review")
|
||||
.description("Write a learn-only opensoft/oh-my-opencode external project review receipt")
|
||||
.option("--output <path>", "Receipt output path", path.join(".fable", "research", "opencode-review-live.json"))
|
||||
.action(async (opts: { output?: string }) => {
|
||||
const { createSkillsRepoReviewReceipt, writeExternalProjectReviewReceipt } = await import("./fable5/external-project-review.js");
|
||||
const receipt = createSkillsRepoReviewReceipt("opensoft/oh-my-opencode");
|
||||
const out = opts.output ?? path.join(".fable", "research", "opencode-review-live.json");
|
||||
writeExternalProjectReviewReceipt(out, receipt);
|
||||
console.log(JSON.stringify(receipt, null, 2));
|
||||
console.log(`
|
||||
Receipt: ${out}
|
||||
`);
|
||||
});
|
||||
|
||||
fable
|
||||
.command("permission-posture")
|
||||
.description("Write an explicit permission posture receipt")
|
||||
|
|
|
|||
Loading…
Reference in New Issue