Documentation
¶
Overview ¶
Package launch is abcd's transport-agnostic launch engine: it assembles the release bundle under a default-deny taxonomy, runs the native secret+PII scan, checks manifest lockstep, and previews newest-per-line retention — all as a dry-run that renders decisions without writing an artefact or touching the network. It performs no printing and no os.Exit, so it is fully testable and reusable across surfaces.
The load-bearing invariant (adr-18/adr-28): the .abcd/** namespace and every other denied namespace can NEVER enter the bundle. This is a STRUCTURAL deny, not an allowlist toggle — no include pattern can promote a denied path.
Index ¶
- Variables
- func BumpTier(prev, next Semver) string
- func CoreGreater(a, b Semver) bool
- func IsStrictSemver(value string) bool
- func LoadIncludes(repoRoot string) ([]string, error)
- type Bundle
- type ChangelogEntry
- type CitationPreflight
- type ClosureFn
- type DryRunReport
- type DryRunRequest
- type ExcludedFile
- type ExcludedReason
- type GateSummary
- type IncludedFile
- type InstallSurface
- type LockstepResult
- type LockstepTree
- type MarketplaceEntry
- type PayloadPrecheck
- type PayloadRenderRequest
- type PayloadRenderResult
- type PayloadTree
- type PreflightError
- type ReceiptPreflight
- type RejectedFile
- type RejectedReason
- type RetentionPlan
- type Semver
- type ShipReport
- type ShipRequest
- type SmokeFinding
- type SmokeReport
- type SmokeTier
- type SourceKind
- type SurfaceEntry
- type SurfaceKind
- type SurfaceOrigin
- type SurfaceRequirement
Constants ¶
This section is empty.
Variables ¶
var DenyNamespaces = map[string]struct{}{
".git": {}, ".abcd": {}, ".flow": {}, ".work": {}, ".specstory": {}, "memory": {},
}
DenyNamespaces are namespace names that never ship. The structural deny (adr-18) binds EVERY path component case-insensitively (see pathContainsDeniedSegment), not just the first segment: a denied name nested under an included tree, or spelled in a different case, is denied all the same (GHSA-g2v7-wfmv-v28r, #335). NOT overridable by any allowlist. Mirrors launch_resolve DENY_NAMESPACES.
var ErrPayloadDrift = errors.New("the rendered payload failed the public lockstep check")
ErrPayloadDrift reports that the rendered payload failed the public lockstep check. It is its own error because it means the render itself is wrong (a pinned location was missed), not that the caller's input was.
var ErrPayloadScanRefused = errors.New("the payload failed the secret/PII scan gate")
ErrPayloadScanRefused reports that the payload the render would materialise carries a secret/PII hard-fail, an unscannable coverage gap, or was scanned by an unavailable scanner — the fail-closed secret/PII gate the materialising path must pass before any write (gh-328). It is the render's twin of the ship gate's scan refusal: DryRun runs the scan advisory-only and Ship (the gated path) has no production caller, so the live `launch ship --payload-dir` render was the sole materialising door that never invoked the scanner.
var ErrPayloadUninstallable = errors.New("the rendered payload failed the installability smoke")
ErrPayloadUninstallable reports that the rendered payload declares a surface it does not carry. It is distinct from ErrPayloadDrift because the fault is the payload's CONTENTS, not the version stamp: the manifests agree perfectly and the plugin still would not install.
var ErrShipBlocked = errors.New("ship blocked by a launch gate")
ErrShipBlocked is returned when any gate hard-fails.
Functions ¶
func BumpTier ¶
BumpTier names the SemVer component that moved from prev to next: "major", "minor", "patch", or "" when the two cores are equal.
It reads the actual version delta rather than mapping an impact, because the mapping is not fixed: pre-1.0, changelog.DeriveNext turns a breaking impact into a MINOR bump and an additive one into a PATCH. A tier derived from the impact would therefore mislabel every pre-1.0 release in the published manifest, while the delta is true at any point on the 0.x/1.x boundary.
func CoreGreater ¶
CoreGreater reports whether a is strictly newer than b by core version. It is exported because release ordering is decided in more than one place — the retention plan here and the tag anchor the changelog derivation resolves — and a second hand-rolled field comparison would be a second, silently divergent definition of "newer".
func IsStrictSemver ¶
IsStrictSemver reports whether value is a strict SemVer 2.0.0 string.
func LoadIncludes ¶
LoadIncludes reads .abcd/config/launch-payload.json, hand-validates its shape (no schema dependency — see §1.1), and returns the normalised, de-duplicated include patterns. A missing/malformed config, or an absolute / ".." / denied-rooted include, is a PreflightError.
Types ¶
type Bundle ¶
type Bundle struct {
Included []IncludedFile `json:"files"`
Excluded []ExcludedFile `json:"excluded"`
Rejected []RejectedFile `json:"rejected"`
Warnings []string `json:"warnings"`
}
Bundle is the classified resolution outcome.
func ResolveBundle ¶
ResolveBundle walks repoRoot, matches candidates against includes, and classifies each into Included / Excluded / Rejected under the ordered algorithm. includes==nil loads the committed config via LoadIncludes (a preflight fault is returned as an error).
func (Bundle) HasViolation ¶
HasViolation reports whether any rejected[] entry exists. ship hard-fails on true; dry-run reports it but still exits 0.
type ChangelogEntry ¶
type ChangelogEntry struct {
// Tier is the SemVer component the cut moved: patch, minor or major.
Tier string
// Reason is the human sentence explaining the bump, e.g. "additive itd-67 shipped".
Reason string
// Date is the release date; only its calendar day is recorded.
Date time.Time
// SourceSHA is the commit the release was cut from.
SourceSHA string
}
ChangelogEntry is the marketplace plugin entry's per-release record (adr-20 R3), minus its version.
The version is deliberately NOT a field: the render writes the one derived version into this entry and into both version pointers from a single input, so the entry cannot disagree with the manifest it travels in. Everything here is supplied by the caller — a core that read the clock or the git HEAD itself would put two unpinnable inputs inside a durable release artefact.
type CitationPreflight ¶
type CitationPreflight struct {
// Unreadable, when non-empty, means the measurement could not be taken at
// all — a docs-lint config that arms the rule but does not parse, or a
// baseline the loader refuses. It is a separate state from "not armed"
// because reporting a broken gate as an absent one is a false statement
// about a real requirement, and it refuses.
Unreadable string
// Present reports whether a baseline exists at all.
Present bool
// Cited, Recorded and Missing describe coverage.
Cited int
Recorded int
Missing int
// Broken counts citations recorded as dead.
Broken int
// Approaching counts entries inside the nag window before the blocking
// threshold; Overdue counts those past it.
Approaching int
Overdue int
// ApproachingURLs and OverdueURLs name them, so a nag and a refusal tell an
// operator WHICH links to deal with rather than only how many.
ApproachingURLs []string
OverdueURLs []string
}
CitationPreflight is the citation baseline's state, measured by the caller. A nil pointer means the repo has not armed the citation gate, and the gate reports itself as not run rather than silently passing.
type ClosureFn ¶
ClosureFn returns the runtime-closure set (repo-relative POSIX paths) for the scripts/ include — the AST-reachable set the shipped plugin ships, never the whole dev tree. Since the Go payload layout is not yet settled, the default reads a pinned closure list from config rather than re-deriving via Python AST (spec §1 step 10 — the single open dependency). A nil map means no closure scoping is applied (scripts/ then behaves like any other include).
type DryRunReport ¶
type DryRunReport struct {
Version string `json:"version"`
Bundle Bundle `json:"bundle"`
Scan scanner.ScanResult `json:"scan"`
Lockstep LockstepResult `json:"lockstep"`
Retention RetentionPlan `json:"retention"`
Smoke SmokeReport `json:"smoke"`
Gates []GateSummary `json:"gates"`
WouldPublish bool `json:"would_publish"` // always false in dry-run
WouldRefuseOn []string `json:"would_refuse_on,omitempty"`
}
DryRunReport is the full dry-run preview. No artefact is written.
func DryRun ¶
func DryRun(req DryRunRequest) (DryRunReport, error)
DryRun assembles the bundle, scans it, checks lockstep and previews retention, then reports what a real ship WOULD refuse on. It ALWAYS returns exit-0 semantics: an error is returned only for a preflight fault (bad include config) that makes a report impossible — never on a finding.
type DryRunRequest ¶
type DryRunRequest struct {
RepoRoot string
// Version is the release version this launch would publish, SUPPLIED by the
// caller. adr-19 leaves no version key in the source tree, so there is
// nothing here for the core to read: the version is a fact about the release
// cut, and the front door that knows the cut injects it. Empty is honest —
// it means the caller could not name one, and retention says so.
Version string
ExistingTags []Semver // injected; nil → default `git tag -l v*` provider
// Citations is the citation baseline's state, MEASURED by the caller.
// Grading it needs internal/core/lint, which imports this package for its
// semver — so the front door that holds both hands the result in as data
// rather than this package reaching back. Nil means the repo has not armed
// the citation gate.
Citations *CitationPreflight
// Receipts is the semantic-pass receipts' state, MEASURED by the caller for
// the same reason as Citations: it needs a git rev-parse and a directory
// read, and this package does not reach back through the front door. Nil
// means the measurement was not taken, which the gate reports as such rather
// than as an absence of receipts.
Receipts *ReceiptPreflight
}
DryRunRequest is the input to a dry-run.
type ExcludedFile ¶
type ExcludedFile struct {
LogicalPath string `json:"logical_path"`
Reason ExcludedReason `json:"reason"`
}
ExcludedFile is a benign exclusion.
type ExcludedReason ¶
type ExcludedReason string
ExcludedReason is why a candidate was benignly excluded (never fails a ship).
const ( ExcludedGitignored ExcludedReason = "gitignored" ExcludedUnmatchedGlob ExcludedReason = "unmatched_glob" ExcludedDeniedNamespace ExcludedReason = "denied_namespace" )
type GateSummary ¶
type GateSummary struct {
Name string `json:"name"`
Status string `json:"status"` // "ran" | "not_implemented" | "host-run"
Detail string `json:"detail"`
}
GateSummary records one gate's dry-run disposition.
type IncludedFile ¶
type IncludedFile struct {
LogicalPath string `json:"logical_path"`
ResolvedPath string `json:"resolved_path"`
GitMode string `json:"git_mode"` // "100644" | "100755"
}
IncludedFile is a resolved payload file. Paths are repo-relative POSIX; ResolvedPath is the absolute on-disk (dereferenced) path.
type InstallSurface ¶
type InstallSurface struct {
PluginName string `json:"plugin_name"`
Marketplace []MarketplaceEntry `json:"marketplace"`
Entries []SurfaceEntry `json:"entries"`
}
InstallSurface is everything a payload declares about what installing it would register.
func ResolveInstallSurface ¶
func ResolveInstallSurface(tree PayloadTree) (InstallSurface, error)
ResolveInstallSurface returns everything tree declares: the plugin's name, the marketplace listings with their sources resolved, and the union of the convention and manifest surface entries.
It returns an error only when a manifest cannot be read or parsed at all — a payload whose declarations cannot even be enumerated. Everything else, including a declaration pointing at nothing, is DATA: it becomes an entry, and judging it is the assertion tier's job, not resolution's.
type LockstepResult ¶
type LockstepResult struct {
Tree LockstepTree `json:"tree"`
OK bool `json:"ok"`
Drifts []string `json:"drifts,omitempty"`
Unreadable bool `json:"unreadable,omitempty"`
Detail string `json:"detail,omitempty"`
ExitCode int `json:"exit_code"` // 0 ok, 1 drift, 2 unreadable
}
LockstepResult is the outcome of a manifest lockstep check.
func CheckLockstep ¶
func CheckLockstep(tree LockstepTree, repoRoot, versionLocationPath string) LockstepResult
CheckLockstep proves the two manifests plus the version-location contract describe one release consistently.
PUBLIC: the primary version (manifest_path + json_pointer from version-location.json) must be a present, non-null strict-SemVer string and every pinned secondary must AGREE. DEV: those keys must all be ABSENT. present-null is distinguished from absent via an explicit sentinel. A blocked:true contract, or any unreadable pinned input, yields exit 2.
type LockstepTree ¶
type LockstepTree string
LockstepTree is the polarity the lockstep check runs under.
const ( // TreeDev requires the version keys ABSENT (adr-19 dev-stays-unversioned). TreeDev LockstepTree = "dev" // TreePublic requires the primary present and every secondary to agree. TreePublic LockstepTree = "public" )
type MarketplaceEntry ¶
type MarketplaceEntry struct {
Name string `json:"name"`
Source string `json:"source,omitempty"`
SourceKind SourceKind `json:"source_kind"`
// Root is the payload-relative plugin root a local source resolves to; the
// empty string is the payload root itself (adr-28: the single repo is its
// own marketplace, so the canonical source is "./").
Root string `json:"root"`
}
MarketplaceEntry is one plugin listing in the marketplace manifest.
type PayloadPrecheck ¶
type PayloadPrecheck struct {
// Root is the symlink-resolved source tree.
Root string
// Dest is the symlink-resolved staging directory. Nothing is created here.
Dest string
// VersionLocationPath is the absolute path to the adr-19 contract.
VersionLocationPath string
// PrimaryPath and PrimaryPointer are the pinned primary version location the
// contract selected, repo-relative and RFC-6901.
PrimaryPath, PrimaryPointer string
// Bundle is the payload resolution the render would write from.
Bundle Bundle
// Smoke is the light installability tier over the RESOLVED bundle — the same
// assertions the render makes over its written output, made early enough to
// refuse before any durable write.
Smoke SmokeReport
}
PayloadPrecheck is everything a render refuses on WITHOUT knowing the version: the resolved locations, the payload the render would write, and the light installability verdict over it.
It exists as a named result because the ship verb writes a durable release record (the dated CHANGELOG heading) before it has a version to stamp, and a render that refuses after that write leaves a release in flight that can never be retried. Separating the version-free half lets the caller prove the render will be ACCEPTED before it writes anything.
func PrecheckPayload ¶
func PrecheckPayload(repoRoot, dest string) (PayloadPrecheck, error)
PrecheckPayload resolves the release payload and runs every refusal a render makes that does not depend on the version.
It performs ZERO writes — not even the destination directory — so a caller may run it speculatively and a refused cut leaves the filesystem exactly as it found it. RenderPayload runs it as its own first step, so the two can never disagree about what is refusable.
It refuses when: dest overlaps repoRoot or is already populated; the version-location contract is unreadable or blocked (adr-19 — a blocked decision has no schema-valid place to write); the bundle carries a violation; either manifest is not in the payload at all; or the payload declares a surface it does not carry.
type PayloadRenderRequest ¶
type PayloadRenderRequest struct {
// RepoRoot is the source tree the payload is cut from. It is read only.
RepoRoot string
// Dest is the staging directory the payload is written to. It must live
// OUTSIDE RepoRoot and be empty or absent.
Dest string
// Version is the derived release version, strict SemVer with no leading "v".
// It is an input rather than something read back out of the tree — the tree
// has no version to read, which is the whole point of adr-19.
Version string
// Entry is the marketplace changelog record for this release.
Entry ChangelogEntry
}
PayloadRenderRequest is the input to RenderPayload.
type PayloadRenderResult ¶
type PayloadRenderResult struct {
// Dest is the staging directory the payload was written to.
Dest string `json:"dest"`
// Version is the version stamped at every pinned location.
Version string `json:"version"`
// Bundle is the resolution the payload was written from, so a caller can
// render the same file classification a dry-run would.
Bundle Bundle `json:"bundle"`
// Files counts the payload files written.
Files int `json:"files"`
// Manifests names the manifests that were version-stamped, repo-relative.
Manifests []string `json:"manifests"`
// Lockstep is the public check over the rendered payload — the proof that
// what was written is internally consistent.
Lockstep LockstepResult `json:"lockstep"`
// Smoke is the light installability check over the rendered payload — the
// proof that what was written would actually install.
Smoke SmokeReport `json:"smoke"`
}
PayloadRenderResult is a completed render.
func RenderPayload ¶
func RenderPayload(req PayloadRenderRequest) (PayloadRenderResult, error)
RenderPayload writes the release payload to req.Dest with the derived version stamped into its manifests, and proves the result with CheckLockstep.
It resolves the payload through the SAME ResolveBundle/LoadIncludes machinery the dry-run and ship gates use, so there is exactly one notion of "what ships"; the render adds only the version stamp on the way out. It never touches the source tree: every write lands under Dest.
Everything refusable that does not need the version is delegated to PrecheckPayload, so a caller may run those refusals FIRST; on top of them this refuses when the version is not strict SemVer or the changelog entry is incomplete.
type PayloadTree ¶
type PayloadTree interface {
// Has reports whether a FILE exists at rel, a payload-relative,
// slash-separated path. A path escaping the payload is never present.
Has(rel string) bool
// Read returns the bytes at rel, guarded against oversized input.
Read(rel string) ([]byte, error)
// List returns every file at or beneath the directory dirRel, sorted, as
// payload-relative slash paths. An empty result means "no such directory".
List(dirRel string) []string
}
PayloadTree is the read side of a payload: the only thing surface resolution needs from "the thing that would ship". Two implementations satisfy it — a resolved bundle (nothing materialised) and a rendered directory — so the same resolver serves the light tier and itd-66's deep tier unchanged.
func NewBundleTree ¶
func NewBundleTree(b Bundle) PayloadTree
NewBundleTree views a resolved bundle as a payload tree, so the light tier can assert against WHAT WOULD SHIP without writing anything. A file present in the working tree but excluded from the payload is absent here — which is exactly the bug this gate catches.
func NewDirTree ¶
func NewDirTree(root string) PayloadTree
NewDirTree views a rendered payload directory as a payload tree.
type PreflightError ¶
type PreflightError struct {
// contains filtered or unexported fields
}
PreflightError is a payload-preflight config fault: a missing/malformed include config, or an absolute / ".." / denied-rooted include. The caller writes NO manifest and reports the diagnostic (dry-run returns it as its only error case).
func (*PreflightError) Error ¶
func (e *PreflightError) Error() string
type ReceiptPreflight ¶
type ReceiptPreflight struct {
// Unreadable, when non-empty, means the measurement could not be taken —
// the candidate commit would not resolve, or the receipts directory could
// not be read. A broken measurement is a distinct state from "none found",
// because reporting the first as the second is a false statement about a
// real requirement.
Unreadable string
// Commit is the candidate commit the receipts would have to name. At preview
// time this is the working tree's HEAD; the commit release.yml actually arms
// against is derived from the merge (`<merge>^2^`), so this is indicative,
// not authoritative — the detail text says so.
Commit string
// Recorded names the detectors that have a receipt for Commit, in the order
// found. It counts receipts present, not receipts valid: validity (PROMOTE,
// judge model, detector binding, manifest hash) is receipt_gate's to judge,
// and duplicating that verdict here would be the second trust root this row
// exists to avoid.
Recorded []string
}
ReceiptPreflight is the state of the semantic-pass receipts, measured by the caller. A nil pointer means the measurement was not taken, and the gate says so rather than reporting an absence it never looked for.
type RejectedFile ¶
type RejectedFile struct {
LogicalPath string `json:"logical_path"`
Reason RejectedReason `json:"reason"`
Details map[string]string `json:"details,omitempty"`
}
RejectedFile is a violation.
type RejectedReason ¶
type RejectedReason string
RejectedReason is why a candidate was rejected (any entry fails a ship).
const ( RejectedDeny RejectedReason = "deny" RejectedSymlinkEscape RejectedReason = "symlink_escape" RejectedSymlinkCycle RejectedReason = "symlink_cycle" RejectedHardlinkDenied RejectedReason = "hardlink_denied" RejectedHardlinkOffrepo RejectedReason = "hardlink_offrepo" RejectedDuplicate RejectedReason = "duplicate" RejectedControlChar RejectedReason = "control_char" RejectedPlatformBinary RejectedReason = "platform_binary" RejectedMissingLiteral RejectedReason = "missing_literal" RejectedFSError RejectedReason = "fs_error" )
type RetentionPlan ¶
type RetentionPlan struct {
Published string `json:"published"`
Line string `json:"line"`
Kept []string `json:"kept"`
Pruned []string `json:"pruned"`
Refused bool `json:"refused"`
RefusalReason string `json:"refusal_reason,omitempty"`
}
RetentionPlan is the newest-per-line prune preview for a release cut.
func ComputeRetention ¶
func ComputeRetention(published Semver, existing []Semver) RetentionPlan
ComputeRetention decides newest-per-line retention (brief §3). It is pure and deletes nothing — it renders the prune decision only.
Rules:
- Each MAJOR.MINOR line keeps only its newest (max-Patch) release.
- The just-published release is NEVER pruned.
- If ANY existing release is strictly NEWER than published, refuse and prune nothing (an out-of-order ship the operator must resolve manually).
- Comparison is core (Major, Minor, Patch) only. Tag string = "v"+version.
type Semver ¶
Semver is a parsed strict SemVer 2.0.0 version.
func GitExistingTags ¶
GitExistingTags is the default provider for the existing-release list: it runs `git tag --list v*` under repoRoot and parses the strict-SemVer core of each tag. Non-SemVer tags AND prerelease/build tags are ignored — retention decides newest-per-line over RELEASES (core versions), and Tag()/String() render the core only, so admitting a "v1.2.3-rc1" would surface a phantom "v1.2.3" in the plan and collapse it against the real "v1.2.3". It is best-effort — an error yields no tags.
func ParseSemver ¶
ParseSemver parses a strict SemVer string into its components. It returns an error for any non-conforming input (the boundary validator).
type ShipReport ¶
type ShipReport struct {
Version string `json:"version"`
Bundle Bundle `json:"bundle"`
Scan scanner.ScanResult `json:"scan"`
Lockstep LockstepResult `json:"lockstep"`
Retention RetentionPlan `json:"retention"`
Smoke SmokeReport `json:"smoke"`
Blocked bool `json:"blocked"`
BlockReasons []string `json:"block_reasons,omitempty"`
WouldPublish bool `json:"would_publish"` // true iff all gates pass
}
ShipReport is the outcome of a ship run. It stops at WouldPublish before any network/publish (no GitHub Release, SLSA, tag push, or retention execution).
func Ship ¶
func Ship(req ShipRequest) (ShipReport, error)
Ship runs the SAME gates as DryRun but HARD-FAILS: a scanner hard-fail, any bundle rejected[] entry, a lockstep drift/unreadable contract, or a retention refusal sets Blocked=true and returns ErrShipBlocked. If every gate passes it stops HERE and returns WouldPublish=true with NO network call — the real GitHub Release + SLSA + tag push + retention prune are a later phase. --allow-dirty must NOT bypass lockstep (adr-20); it is carried but never consulted by the lockstep gate.
type ShipRequest ¶
type ShipRequest struct {
RepoRoot string
// Version is the release version, supplied by the caller for the reason
// DryRunRequest.Version states: adr-19 leaves nothing in the tree to read.
Version string
AllowDirty bool
ExistingTags []Semver
}
ShipRequest is the input to a ship run.
type SmokeFinding ¶
type SmokeFinding struct {
Kind string `json:"kind"`
Path string `json:"path,omitempty"`
Detail string `json:"detail"`
}
SmokeFinding is one reason the payload would not install.
type SmokeReport ¶
type SmokeReport struct {
Tier SmokeTier `json:"tier"`
OK bool `json:"ok"`
Surface InstallSurface `json:"surface"`
// Checked counts the assertions actually made, so a pass over a payload that
// declared nothing is visibly vacuous rather than reassuring.
Checked int `json:"checked"`
Findings []SmokeFinding `json:"findings,omitempty"`
}
SmokeReport is one installability check.
func SmokeLight ¶
func SmokeLight(tree PayloadTree) SmokeReport
SmokeLight runs the light installability tier over a payload.
It never returns an error: an unreadable manifest is the most serious FINDING it can make, and reporting it as a finding keeps the gate's output shape the same whether the payload is perfect or unparseable — the dry-run preview depends on always having a report to render.
type SmokeTier ¶
type SmokeTier string
SmokeTier names how deep an installability check went, so a report never implies more assurance than it earned.
const SmokeTierLight SmokeTier = "light"
SmokeTierLight is manifest-parse + source-resolve + declared-path-exists.
type SourceKind ¶
type SourceKind string
SourceKind classifies a marketplace entry's source.
const ( // SourceLocal — a path inside the payload; resolvable offline. SourceLocal SourceKind = "local" // SourceExternal — a remote or non-path source; resolving it needs the // network, so no offline gate asserts against it. SourceExternal SourceKind = "external" // SourceMissing — the entry declares no source at all. SourceMissing SourceKind = "missing" )
type SurfaceEntry ¶
type SurfaceEntry struct {
Kind SurfaceKind `json:"kind"`
Path string `json:"path"`
Origin SurfaceOrigin `json:"origin"`
Requirement SurfaceRequirement `json:"requirement"`
// DeclaredAs is the raw declaration this entry was expanded from, when it
// differs from Path (a directory declaration, a hook command string).
DeclaredAs string `json:"declared_as,omitempty"`
// Reason explains a requirement other than RequirePayload.
Reason string `json:"reason,omitempty"`
}
SurfaceEntry is one declared piece of the installable surface.
type SurfaceKind ¶
type SurfaceKind string
SurfaceKind is one register of the installable surface.
const ( SurfaceCommand SurfaceKind = "command" SurfaceAgent SurfaceKind = "agent" SurfaceSkill SurfaceKind = "skill" SurfaceHook SurfaceKind = "hook" )
type SurfaceOrigin ¶
type SurfaceOrigin string
SurfaceOrigin records HOW an entry came to be declared. It is carried on every entry so a stricter tier can weigh the registers differently without re-resolving them.
const ( // OriginConvention — found by auto-discovery under a well-known directory. OriginConvention SurfaceOrigin = "convention" // OriginManifest — named by an explicit plugin.json key. OriginManifest SurfaceOrigin = "manifest" // OriginHookCommand — referenced by a hook's command string. OriginHookCommand SurfaceOrigin = "hook-command" )
type SurfaceRequirement ¶
type SurfaceRequirement string
SurfaceRequirement says who is expected to supply an entry's path.
const ( // RequirePayload — the payload must carry it; absence is a failed install. RequirePayload SurfaceRequirement = "payload" // RequireInstalled — the install supplies it, so the payload never carries // it and its absence proves nothing. RequireInstalled SurfaceRequirement = "installed" )
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
Package scaffold renders and writes the changelog-driven release machinery — release.yml, auto-release.yml, and the adr-37 runbook — into a managed repo that lacks it (itd-93, spc-14).
|
Package scaffold renders and writes the changelog-driven release machinery — release.yml, auto-release.yml, and the adr-37 runbook — into a managed repo that lacks it (itd-93, spc-14). |